ert 16.0.2__py3-none-any.whl → 17.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. _ert/forward_model_runner/fm_dispatch.py +9 -6
  2. _ert/forward_model_runner/reporting/event.py +1 -0
  3. _ert/forward_model_runner/runner.py +1 -2
  4. _ert/utils.py +12 -0
  5. ert/__main__.py +30 -25
  6. ert/base_model_context.py +1 -1
  7. ert/cli/main.py +4 -6
  8. ert/config/__init__.py +2 -0
  9. ert/config/_create_observation_dataframes.py +1 -1
  10. ert/config/_read_summary.py +65 -321
  11. ert/config/design_matrix.py +12 -0
  12. ert/config/ert_config.py +52 -39
  13. ert/config/everest_objective_config.py +3 -0
  14. ert/config/ext_param_config.py +1 -2
  15. ert/config/field.py +33 -44
  16. ert/config/gen_kw_config.py +16 -22
  17. ert/config/parameter_config.py +1 -17
  18. ert/config/parsing/config_errors.py +1 -1
  19. ert/config/parsing/config_keywords.py +0 -1
  20. ert/config/parsing/config_schema.py +0 -8
  21. ert/config/parsing/config_schema_deprecations.py +21 -23
  22. ert/config/queue_config.py +38 -45
  23. ert/config/surface_config.py +32 -41
  24. ert/config/workflow_job.py +135 -54
  25. ert/dark_storage/common.py +21 -2
  26. ert/dark_storage/endpoints/__init__.py +2 -0
  27. ert/dark_storage/endpoints/ensembles.py +4 -0
  28. ert/dark_storage/endpoints/experiment_server.py +18 -15
  29. ert/dark_storage/endpoints/parameters.py +8 -0
  30. ert/dark_storage/endpoints/version.py +16 -0
  31. ert/dark_storage/json_schema/ensemble.py +3 -0
  32. ert/field_utils/field_utils.py +16 -12
  33. ert/field_utils/grdecl_io.py +1 -1
  34. ert/gui/ertwidgets/closabledialog.py +2 -0
  35. ert/gui/ertwidgets/copyablelabel.py +2 -0
  36. ert/gui/ertwidgets/listeditbox.py +2 -0
  37. ert/gui/ertwidgets/models/activerealizationsmodel.py +3 -0
  38. ert/gui/ertwidgets/models/ertsummary.py +5 -8
  39. ert/gui/ertwidgets/models/targetensemblemodel.py +3 -0
  40. ert/gui/ertwidgets/models/text_model.py +3 -0
  41. ert/gui/ertwidgets/searchbox.py +4 -0
  42. ert/gui/ertwidgets/stringbox.py +2 -0
  43. ert/gui/main.py +4 -5
  44. ert/gui/main_window.py +3 -2
  45. ert/gui/model/fm_step_list.py +3 -0
  46. ert/gui/model/real_list.py +1 -0
  47. ert/gui/model/snapshot.py +1 -0
  48. ert/gui/simulation/combobox_with_description.py +3 -0
  49. ert/gui/simulation/ensemble_experiment_panel.py +7 -1
  50. ert/gui/simulation/ensemble_information_filter_panel.py +6 -1
  51. ert/gui/simulation/ensemble_smoother_panel.py +7 -1
  52. ert/gui/simulation/evaluate_ensemble_panel.py +16 -6
  53. ert/gui/simulation/experiment_panel.py +2 -3
  54. ert/gui/simulation/manual_update_panel.py +4 -2
  55. ert/gui/simulation/multiple_data_assimilation_panel.py +6 -2
  56. ert/gui/simulation/run_dialog.py +21 -0
  57. ert/gui/simulation/single_test_run_panel.py +4 -1
  58. ert/gui/simulation/view/progress_widget.py +2 -0
  59. ert/gui/simulation/view/realization.py +5 -1
  60. ert/gui/simulation/view/update.py +2 -0
  61. ert/gui/summarypanel.py +1 -1
  62. ert/gui/tools/event_viewer/panel.py +3 -4
  63. ert/gui/tools/event_viewer/tool.py +2 -0
  64. ert/gui/tools/export/export_tool.py +2 -0
  65. ert/gui/tools/file/file_dialog.py +6 -2
  66. ert/gui/tools/load_results/load_results_tool.py +2 -0
  67. ert/gui/tools/manage_experiments/manage_experiments_panel.py +2 -0
  68. ert/gui/tools/manage_experiments/storage_widget.py +3 -1
  69. ert/gui/tools/plot/customize/color_chooser.py +5 -2
  70. ert/gui/tools/plot/customize/customize_plot_dialog.py +2 -0
  71. ert/gui/tools/plot/customize/default_customization_view.py +4 -0
  72. ert/gui/tools/plot/customize/limits_customization_view.py +3 -0
  73. ert/gui/tools/plot/customize/statistics_customization_view.py +3 -0
  74. ert/gui/tools/plot/customize/style_chooser.py +2 -0
  75. ert/gui/tools/plot/customize/style_customization_view.py +3 -0
  76. ert/gui/tools/plot/data_type_keys_widget.py +2 -0
  77. ert/gui/tools/plot/data_type_proxy_model.py +3 -0
  78. ert/gui/tools/plot/plot_api.py +26 -3
  79. ert/gui/tools/plot/plot_ensemble_selection_widget.py +17 -10
  80. ert/gui/tools/plot/plot_widget.py +41 -2
  81. ert/gui/tools/plot/plot_window.py +116 -76
  82. ert/gui/tools/plot/plottery/plot_context.py +9 -0
  83. ert/gui/tools/plot/plottery/plots/ensemble.py +1 -2
  84. ert/gui/tools/plot/plottery/plots/histogram.py +34 -5
  85. ert/gui/tools/plot/widgets/clearable_line_edit.py +9 -0
  86. ert/gui/tools/plot/widgets/filter_popup.py +2 -0
  87. ert/gui/tools/plot/widgets/filterable_kw_list_model.py +3 -0
  88. ert/gui/tools/plugins/plugin.py +1 -1
  89. ert/gui/tools/plugins/plugins_tool.py +2 -0
  90. ert/gui/tools/plugins/process_job_dialog.py +3 -0
  91. ert/gui/tools/workflows/workflow_dialog.py +2 -0
  92. ert/gui/tools/workflows/workflows_tool.py +2 -0
  93. ert/libres_facade.py +5 -7
  94. ert/logging/__init__.py +4 -1
  95. ert/plugins/__init__.py +4 -5
  96. ert/plugins/hook_specifications/__init__.py +0 -8
  97. ert/plugins/plugin_manager.py +52 -96
  98. ert/resources/forward_models/run_reservoirsimulator.py +0 -1
  99. ert/resources/forward_models/template_render.py +10 -10
  100. ert/run_models/__init__.py +6 -1
  101. ert/run_models/_create_run_path.py +2 -1
  102. ert/run_models/everest_run_model.py +182 -71
  103. ert/run_models/run_model.py +9 -19
  104. ert/scheduler/__init__.py +10 -5
  105. ert/scheduler/driver.py +3 -0
  106. ert/scheduler/lsf_driver.py +9 -3
  107. ert/scheduler/openpbs_driver.py +3 -3
  108. ert/scheduler/slurm_driver.py +14 -3
  109. ert/services/_storage_main.py +20 -18
  110. ert/shared/net_utils.py +16 -29
  111. ert/shared/version.py +3 -3
  112. ert/storage/__init__.py +12 -1
  113. ert/storage/local_ensemble.py +6 -1
  114. ert/storage/local_experiment.py +46 -18
  115. ert/storage/local_storage.py +23 -17
  116. ert/storage/migration/to10.py +3 -2
  117. ert/storage/migration/to11.py +8 -9
  118. ert/storage/migration/to12.py +19 -20
  119. ert/storage/migration/to13.py +28 -27
  120. ert/storage/migration/to14.py +3 -3
  121. ert/storage/migration/to15.py +25 -0
  122. ert/storage/migration/to6.py +3 -2
  123. ert/storage/migration/to7.py +12 -13
  124. ert/storage/migration/to8.py +5 -7
  125. ert/storage/migration/to9.py +5 -4
  126. ert/storage/realization_storage_state.py +7 -7
  127. ert/validation/ensemble_realizations_argument.py +4 -2
  128. ert/workflow_runner.py +4 -2
  129. {ert-16.0.2.dist-info → ert-17.0.0.dist-info}/METADATA +16 -11
  130. {ert-16.0.2.dist-info → ert-17.0.0.dist-info}/RECORD +160 -159
  131. everest/assets/everest_logo.svg +406 -0
  132. everest/bin/config_branch_script.py +28 -9
  133. everest/bin/everconfigdump_script.py +1 -1
  134. everest/bin/everest_script.py +32 -22
  135. everest/bin/everlint_script.py +3 -3
  136. everest/bin/kill_script.py +5 -3
  137. everest/bin/main.py +11 -24
  138. everest/bin/monitor_script.py +63 -34
  139. everest/bin/utils.py +50 -39
  140. everest/bin/visualization_script.py +19 -2
  141. everest/config/everest_config.py +28 -38
  142. everest/config/install_job_config.py +39 -1
  143. everest/config/server_config.py +0 -6
  144. everest/config/simulator_config.py +62 -17
  145. everest/config/validation_utils.py +17 -4
  146. everest/config_file_loader.py +17 -17
  147. everest/detached/__init__.py +0 -6
  148. everest/detached/client.py +4 -49
  149. everest/detached/everserver.py +13 -38
  150. everest/everest_storage.py +19 -29
  151. everest/optimizer/everest2ropt.py +10 -11
  152. everest/optimizer/opt_model_transforms.py +4 -8
  153. everest/plugins/hook_specs.py +0 -24
  154. everest/simulator/everest_to_ert.py +1 -202
  155. everest/strings.py +1 -1
  156. everest/util/__init__.py +3 -1
  157. ert/plugins/hook_specifications/ecl_config.py +0 -29
  158. ert/summary_key_type.py +0 -234
  159. everest/bin/everexport_script.py +0 -53
  160. {ert-16.0.2.dist-info → ert-17.0.0.dist-info}/WHEEL +0 -0
  161. {ert-16.0.2.dist-info → ert-17.0.0.dist-info}/entry_points.txt +0 -0
  162. {ert-16.0.2.dist-info → ert-17.0.0.dist-info}/licenses/COPYING +0 -0
  163. {ert-16.0.2.dist-info → ert-17.0.0.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,7 @@ import sys
8
8
  import time
9
9
  from collections.abc import Generator, Iterable
10
10
  from datetime import datetime
11
+ from pathlib import Path
11
12
  from typing import TYPE_CHECKING, Any
12
13
 
13
14
  from _ert.forward_model_runner import reporting
@@ -19,6 +20,7 @@ from _ert.forward_model_runner.reporting.message import (
19
20
  ProcessTreeStatus,
20
21
  )
21
22
  from _ert.forward_model_runner.runner import ForwardModelRunner
23
+ from _ert.utils import file_safe_timestamp
22
24
 
23
25
  if TYPE_CHECKING:
24
26
  from ert.config.forward_model_step import ForwardModelJSON
@@ -81,10 +83,10 @@ def _setup_logging(directory: str = "logs") -> None:
81
83
  "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
82
84
  )
83
85
 
84
- filename = (
85
- f"forward-model-runner-log-{datetime.now().isoformat(timespec='minutes')}.txt"
86
- )
87
- csv_filename = f"memory-profile-{datetime.now().isoformat(timespec='minutes')}.csv"
86
+ timestamp = file_safe_timestamp(datetime.now().isoformat(timespec="minutes"))
87
+
88
+ filename = f"forward-model-runner-log-{timestamp}.txt"
89
+ csv_filename = f"memory-profile-{timestamp}.csv"
88
90
 
89
91
  handler = logging.FileHandler(filename=directory + "/" + filename)
90
92
  handler.setFormatter(formatter)
@@ -107,8 +109,9 @@ def _wait_for_retry() -> None:
107
109
 
108
110
  def _read_fm_description_file(retry: bool = True) -> "ForwardModelDescriptionJSON":
109
111
  try:
110
- with open(FORWARD_MODEL_DESCRIPTION_FILE, encoding="utf-8") as json_file:
111
- return json.load(json_file)
112
+ return json.loads(
113
+ Path(FORWARD_MODEL_DESCRIPTION_FILE).read_text(encoding="utf-8")
114
+ )
112
115
  except json.JSONDecodeError as e:
113
116
  raise OSError(
114
117
  "fm_dispatch failed to load JSON-file describing the forward model."
@@ -137,6 +137,7 @@ class Event(Reporter):
137
137
  return
138
138
  except ClientConnectionError as exc:
139
139
  logger.error(f"Failed to send event: {exc}")
140
+ self._reporter_exception = exc
140
141
  return
141
142
  except queue.Empty:
142
143
  await asyncio.sleep(0)
@@ -40,8 +40,7 @@ class ForwardModelRunner:
40
40
  def _read_manifest(self) -> dict[str, Manifest] | None:
41
41
  if not Path("manifest.json").exists():
42
42
  return None
43
- with open("manifest.json", encoding="utf-8") as f:
44
- data = json.load(f)
43
+ data = json.loads(Path("manifest.json").read_text(encoding="utf-8"))
45
44
  return {
46
45
  name: {"type": "file", "path": str(Path(file).absolute())}
47
46
  for name, file in data.items()
_ert/utils.py ADDED
@@ -0,0 +1,12 @@
1
+ def file_safe_timestamp(timestamp: str) -> str:
2
+ """
3
+ Convert an ISO timestamp string to a file-safe version
4
+
5
+ Keeps the date in the extended format (YYYY-MM-DD) and converts the time
6
+ to the basic format (HHMMSS) by removing colons. This mix is not strictly
7
+ ISO 8601 compliant, but it can still be parsed.
8
+
9
+ Example:
10
+ 2025-10-10T14:30:00 -> 2025-10-10T143000
11
+ """
12
+ return str(timestamp).replace(":", "")
ert/__main__.py CHANGED
@@ -12,6 +12,7 @@ import sys
12
12
  import warnings
13
13
  from argparse import ArgumentParser, ArgumentTypeError
14
14
  from collections.abc import Sequence
15
+ from pathlib import Path
15
16
  from typing import Any
16
17
  from uuid import UUID
17
18
 
@@ -20,6 +21,7 @@ from opentelemetry.trace import Status, StatusCode
20
21
 
21
22
  import ert.shared
22
23
  from _ert.threading import set_signal_handler
24
+ from ert.base_model_context import use_runtime_plugins
23
25
  from ert.cli.main import ErtCliError, run_cli
24
26
  from ert.config import ConfigValidationError, ErtConfig, lint_file
25
27
  from ert.logging import LOGGING_CONFIG
@@ -32,11 +34,11 @@ from ert.mode_definitions import (
32
34
  WORKFLOW_MODE,
33
35
  )
34
36
  from ert.namespace import Namespace
35
- from ert.plugins import ErtPluginContext, ErtRuntimePlugins
37
+ from ert.plugins import ErtRuntimePlugins, get_site_plugins, setup_site_logging
36
38
  from ert.run_models.multiple_data_assimilation import MultipleDataAssimilation
37
39
  from ert.services import StorageService, WebvizErt
38
40
  from ert.shared.storage.command import add_parser_options as ert_api_add_parser_options
39
- from ert.storage import ErtStorageException
41
+ from ert.storage import ErtStorageException, ErtStoragePermissionError
40
42
  from ert.trace import trace, tracer
41
43
  from ert.validation import (
42
44
  IntegerArgument,
@@ -68,8 +70,7 @@ def run_webviz_ert(args: Namespace, _: ErtRuntimePlugins | None = None) -> None:
68
70
  ) from err
69
71
 
70
72
  kwargs: dict[str, Any] = {"verbose": args.verbose}
71
- with ErtPluginContext() as runtime_plugins:
72
- ert_config = ErtConfig.with_plugins(runtime_plugins).from_file(args.config)
73
+ ert_config = ErtConfig.with_plugins(get_site_plugins()).from_file(args.config)
73
74
 
74
75
  os.chdir(ert_config.config_path)
75
76
  ens_path = ert_config.ens_path
@@ -636,25 +637,24 @@ def main() -> None:
636
637
 
637
638
  os.environ["ERT_LOG_DIR"] = log_dir
638
639
 
639
- with open(LOGGING_CONFIG, encoding="utf-8") as conf_file:
640
- config_dict = yaml.safe_load(conf_file)
641
- for handler_name, handler_config in config_dict["handlers"].items():
642
- if handler_name == "file":
643
- handler_config["filename"] = "ert-log.txt"
644
- if "ert.logging.TimestampedFileHandler" in handler_config.values():
645
- handler_config["config_filename"] = args.config
646
- try:
647
- logging.config.dictConfig(config_dict)
648
- except ValueError as err:
649
- if "handler 'file'" in str(err):
650
- exit_msg = (
651
- f"Could not configure log handler for files. "
652
- f"Check if you have write-access to the logs-directory ({log_dir})."
653
- )
654
- else:
655
- exit_msg = str(err)
656
- os.environ.pop("ERT_LOG_DIR")
657
- sys.exit(exit_msg)
640
+ config_dict = yaml.safe_load(Path(LOGGING_CONFIG).read_text(encoding="utf-8"))
641
+ for handler_name, handler_config in config_dict["handlers"].items():
642
+ if handler_name == "file":
643
+ handler_config["filename"] = "ert-log.txt"
644
+ if "ert.logging.TimestampedFileHandler" in handler_config.values():
645
+ handler_config["config_filename"] = args.config
646
+ try:
647
+ logging.config.dictConfig(config_dict)
648
+ except ValueError as err:
649
+ if "handler 'file'" in str(err):
650
+ exit_msg = (
651
+ f"Could not configure log handler for files. "
652
+ f"Check if you have write-access to the logs-directory ({log_dir})."
653
+ )
654
+ else:
655
+ exit_msg = str(err)
656
+ os.environ.pop("ERT_LOG_DIR")
657
+ sys.exit(exit_msg)
658
658
 
659
659
  logger = logging.getLogger(__name__)
660
660
  if args.verbose:
@@ -663,9 +663,14 @@ def main() -> None:
663
663
  handler.setLevel(logging.INFO)
664
664
  root_logger.addHandler(handler)
665
665
  try:
666
- with ErtPluginContext(logger=logging.getLogger()) as runtime_plugins:
666
+ site_plugins = get_site_plugins()
667
+ setup_site_logging(logging.getLogger())
668
+ with use_runtime_plugins(site_plugins):
667
669
  logger.info(f"Running ert with {args} in {os.getcwd()}")
668
- args.func(args, runtime_plugins)
670
+ args.func(args, site_plugins)
671
+ except ErtStoragePermissionError as err:
672
+ logger.error(str(err))
673
+ sys.exit(str(err))
669
674
  except (ErtCliError, ErtStorageException) as err:
670
675
  span.set_status(Status(StatusCode.ERROR))
671
676
  span.record_exception(err)
ert/base_model_context.py CHANGED
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
14
14
 
15
15
 
16
16
  @contextmanager
17
- def init_context(value: ErtRuntimePlugins) -> Iterator[None]:
17
+ def use_runtime_plugins(value: ErtRuntimePlugins) -> Iterator[None]:
18
18
  token = init_context_var.set(value) # type: ignore
19
19
  try:
20
20
  yield
ert/cli/main.py CHANGED
@@ -10,6 +10,7 @@ from collections import Counter
10
10
  from typing import TextIO
11
11
 
12
12
  from _ert.threading import ErtThread
13
+ from ert.base_model_context import use_runtime_plugins
13
14
  from ert.cli.monitor import Monitor
14
15
  from ert.cli.workflow import execute_workflow
15
16
  from ert.config import ErtConfig, QueueSystem
@@ -23,7 +24,7 @@ from ert.mode_definitions import (
23
24
  WORKFLOW_MODE,
24
25
  )
25
26
  from ert.namespace import Namespace
26
- from ert.plugins import ErtPluginContext, ErtRuntimePlugins
27
+ from ert.plugins import ErtRuntimePlugins, get_site_plugins
27
28
  from ert.run_models.event import StatusEvents
28
29
  from ert.run_models.model_factory import create_model
29
30
  from ert.storage import open_storage
@@ -45,10 +46,7 @@ def run_cli(args: Namespace, runtime_plugins: ErtRuntimePlugins | None = None) -
45
46
  if runtime_plugins is not None:
46
47
  ert_config = ErtConfig.with_plugins(runtime_plugins).from_file(args.config)
47
48
  else:
48
- with ErtPluginContext() as default_runtime_plugins:
49
- ert_config = ErtConfig.with_plugins(default_runtime_plugins).from_file(
50
- args.config
51
- )
49
+ ert_config = ErtConfig.with_plugins(get_site_plugins()).from_file(args.config)
52
50
 
53
51
  local_storage_set_ert_config(ert_config)
54
52
  counter_fm_steps = Counter(fms.name for fms in ert_config.forward_model_steps)
@@ -96,7 +94,7 @@ def run_cli(args: Namespace, runtime_plugins: ErtRuntimePlugins | None = None) -
96
94
 
97
95
  status_queue: queue.SimpleQueue[StatusEvents] = queue.SimpleQueue()
98
96
  try:
99
- with ErtPluginContext():
97
+ with use_runtime_plugins(get_site_plugins()):
100
98
  model = create_model(
101
99
  ert_config,
102
100
  args,
ert/config/__init__.py CHANGED
@@ -63,6 +63,7 @@ from .workflow_fixtures import (
63
63
  fixtures_per_hook,
64
64
  )
65
65
  from .workflow_job import (
66
+ BaseErtScriptWorkflow,
66
67
  ErtScriptWorkflow,
67
68
  ExecutableWorkflow,
68
69
  WorkflowJob,
@@ -72,6 +73,7 @@ from .workflow_job import (
72
73
  __all__ = [
73
74
  "AnalysisConfig",
74
75
  "AnalysisModule",
76
+ "BaseErtScriptWorkflow",
75
77
  "ConfigValidationError",
76
78
  "ConfigWarning",
77
79
  "DataSource",
@@ -7,8 +7,8 @@ from typing import TYPE_CHECKING, Any, assert_never
7
7
 
8
8
  import numpy as np
9
9
  import polars as pl
10
+ from resfo_utilities import history_key
10
11
 
11
- from ert.summary_key_type import history_key
12
12
  from ert.validation import rangestring_to_list
13
13
 
14
14
  from ._observations import (