ert 18.0.9__py3-none-any.whl → 19.0.0rc0__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 (117) hide show
  1. _ert/forward_model_runner/client.py +6 -2
  2. ert/__main__.py +20 -6
  3. ert/analysis/_es_update.py +6 -19
  4. ert/cli/main.py +7 -3
  5. ert/config/__init__.py +3 -4
  6. ert/config/_create_observation_dataframes.py +57 -8
  7. ert/config/_get_num_cpu.py +1 -1
  8. ert/config/_observations.py +77 -1
  9. ert/config/distribution.py +1 -1
  10. ert/config/ensemble_config.py +3 -3
  11. ert/config/ert_config.py +50 -8
  12. ert/config/{ext_param_config.py → everest_control.py} +8 -12
  13. ert/config/everest_response.py +3 -5
  14. ert/config/field.py +76 -14
  15. ert/config/forward_model_step.py +12 -9
  16. ert/config/gen_data_config.py +3 -4
  17. ert/config/gen_kw_config.py +2 -12
  18. ert/config/parameter_config.py +1 -16
  19. ert/config/parsing/_option_dict.py +10 -2
  20. ert/config/parsing/config_keywords.py +1 -0
  21. ert/config/parsing/config_schema.py +8 -0
  22. ert/config/parsing/config_schema_deprecations.py +14 -3
  23. ert/config/parsing/config_schema_item.py +12 -3
  24. ert/config/parsing/context_values.py +3 -3
  25. ert/config/parsing/file_context_token.py +1 -1
  26. ert/config/parsing/observations_parser.py +6 -2
  27. ert/config/parsing/queue_system.py +9 -0
  28. ert/config/queue_config.py +0 -1
  29. ert/config/response_config.py +0 -1
  30. ert/config/rft_config.py +78 -33
  31. ert/config/summary_config.py +1 -2
  32. ert/config/surface_config.py +59 -16
  33. ert/dark_storage/common.py +1 -1
  34. ert/dark_storage/compute/misfits.py +4 -1
  35. ert/dark_storage/endpoints/compute/misfits.py +4 -2
  36. ert/dark_storage/endpoints/experiment_server.py +12 -9
  37. ert/dark_storage/endpoints/experiments.py +2 -2
  38. ert/dark_storage/endpoints/observations.py +4 -2
  39. ert/dark_storage/endpoints/parameters.py +2 -18
  40. ert/dark_storage/endpoints/responses.py +10 -5
  41. ert/dark_storage/json_schema/experiment.py +1 -1
  42. ert/data/_measured_data.py +6 -5
  43. ert/ensemble_evaluator/config.py +2 -1
  44. ert/field_utils/field_utils.py +1 -1
  45. ert/field_utils/grdecl_io.py +9 -26
  46. ert/field_utils/roff_io.py +1 -1
  47. ert/gui/__init__.py +5 -2
  48. ert/gui/ertnotifier.py +1 -1
  49. ert/gui/ertwidgets/pathchooser.py +0 -3
  50. ert/gui/ertwidgets/suggestor/suggestor.py +63 -30
  51. ert/gui/main.py +27 -5
  52. ert/gui/main_window.py +0 -5
  53. ert/gui/simulation/experiment_panel.py +12 -7
  54. ert/gui/simulation/run_dialog.py +2 -16
  55. ert/gui/summarypanel.py +0 -19
  56. ert/gui/tools/manage_experiments/export_dialog.py +136 -0
  57. ert/gui/tools/manage_experiments/storage_info_widget.py +110 -9
  58. ert/gui/tools/plot/plot_api.py +24 -15
  59. ert/gui/tools/plot/plot_widget.py +10 -2
  60. ert/gui/tools/plot/plot_window.py +26 -18
  61. ert/gui/tools/plot/plottery/plots/__init__.py +2 -0
  62. ert/gui/tools/plot/plottery/plots/cesp.py +3 -1
  63. ert/gui/tools/plot/plottery/plots/distribution.py +6 -1
  64. ert/gui/tools/plot/plottery/plots/ensemble.py +3 -1
  65. ert/gui/tools/plot/plottery/plots/gaussian_kde.py +12 -2
  66. ert/gui/tools/plot/plottery/plots/histogram.py +3 -1
  67. ert/gui/tools/plot/plottery/plots/misfits.py +436 -0
  68. ert/gui/tools/plot/plottery/plots/observations.py +18 -4
  69. ert/gui/tools/plot/plottery/plots/statistics.py +3 -1
  70. ert/gui/tools/plot/plottery/plots/std_dev.py +3 -1
  71. ert/plugins/hook_implementations/workflows/csv_export.py +2 -3
  72. ert/plugins/plugin_manager.py +4 -0
  73. ert/resources/forward_models/run_reservoirsimulator.py +8 -3
  74. ert/run_models/_create_run_path.py +3 -3
  75. ert/run_models/everest_run_model.py +13 -11
  76. ert/run_models/initial_ensemble_run_model.py +2 -2
  77. ert/run_models/run_model.py +30 -1
  78. ert/services/_base_service.py +6 -5
  79. ert/services/ert_server.py +4 -4
  80. ert/shared/_doc_utils/__init__.py +4 -2
  81. ert/shared/net_utils.py +43 -18
  82. ert/shared/version.py +3 -3
  83. ert/storage/__init__.py +2 -0
  84. ert/storage/local_ensemble.py +13 -7
  85. ert/storage/local_experiment.py +2 -2
  86. ert/storage/local_storage.py +41 -25
  87. ert/storage/migration/to11.py +1 -1
  88. ert/storage/migration/to18.py +0 -1
  89. ert/storage/migration/to19.py +34 -0
  90. ert/storage/migration/to20.py +23 -0
  91. ert/storage/migration/to21.py +25 -0
  92. ert/workflow_runner.py +2 -1
  93. {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/METADATA +1 -1
  94. {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/RECORD +112 -112
  95. {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/WHEEL +1 -1
  96. everest/bin/everlint_script.py +0 -2
  97. everest/bin/utils.py +2 -1
  98. everest/bin/visualization_script.py +4 -11
  99. everest/config/control_config.py +4 -4
  100. everest/config/control_variable_config.py +2 -2
  101. everest/config/everest_config.py +9 -0
  102. everest/config/utils.py +2 -2
  103. everest/config/validation_utils.py +7 -1
  104. everest/config_file_loader.py +0 -2
  105. everest/detached/client.py +3 -3
  106. everest/everest_storage.py +0 -2
  107. everest/gui/everest_client.py +2 -2
  108. everest/optimizer/everest2ropt.py +4 -4
  109. everest/optimizer/opt_model_transforms.py +2 -2
  110. ert/config/violations.py +0 -0
  111. ert/gui/tools/export/__init__.py +0 -3
  112. ert/gui/tools/export/export_panel.py +0 -83
  113. ert/gui/tools/export/export_tool.py +0 -69
  114. ert/gui/tools/export/exporter.py +0 -36
  115. {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/entry_points.txt +0 -0
  116. {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/licenses/COPYING +0 -0
  117. {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/top_level.txt +0 -0
@@ -201,7 +201,7 @@ class ControlVariableConfig(_ControlVariable):
201
201
  def __hash__(self) -> int:
202
202
  return hash(self.name) + hash(self.index)
203
203
 
204
- def __eq__(self, other: Any) -> bool:
204
+ def __eq__(self, other: object) -> bool:
205
205
  return (
206
206
  isinstance(other, self.__class__)
207
207
  and other.name == self.name
@@ -234,7 +234,7 @@ class ControlVariableGuessListConfig(_ControlVariable):
234
234
  def __hash__(self) -> int:
235
235
  return hash(self.name)
236
236
 
237
- def __eq__(self, other: Any) -> bool:
237
+ def __eq__(self, other: object) -> bool:
238
238
  return isinstance(other, self.__class__) and other.name == self.name
239
239
 
240
240
  @property
@@ -2,6 +2,7 @@ import logging
2
2
  import os
3
3
  from argparse import ArgumentParser
4
4
  from copy import copy
5
+ from enum import StrEnum
5
6
  from itertools import chain
6
7
  from pathlib import Path
7
8
  from sys import float_info
@@ -28,6 +29,8 @@ from pydantic.json_schema import SkipJsonSchema
28
29
  from pydantic_core import ErrorDetails
29
30
  from pydantic_core.core_schema import ValidationInfo
30
31
  from ruamel.yaml import YAML, YAMLError
32
+ from ruamel.yaml.nodes import ScalarNode
33
+ from ruamel.yaml.representer import Representer
31
34
 
32
35
  from ert.base_model_context import BaseModelWithContextSupport, use_runtime_plugins
33
36
  from ert.config import (
@@ -1100,6 +1103,12 @@ to read summary data from forward model, do:
1100
1103
  yaml = YAML(typ="safe", pure=True) if safe_and_pure else YAML()
1101
1104
  yaml.indent(mapping=2, sequence=4, offset=2)
1102
1105
  yaml.preserve_quotes = True
1106
+
1107
+ def strenum_representer(dumper: Representer, data: StrEnum) -> ScalarNode:
1108
+ return dumper.represent_str(data.value)
1109
+
1110
+ yaml.representer.add_multi_representer(StrEnum, strenum_representer)
1111
+
1103
1112
  yaml.default_flow_style = False
1104
1113
  yaml.dump(config, output_file)
1105
1114
 
everest/config/utils.py CHANGED
@@ -1,8 +1,8 @@
1
- from ert.config import ExtParamConfig, SamplerConfig
1
+ from ert.config import EverestControl, SamplerConfig
2
2
 
3
3
 
4
4
  def get_samplers(
5
- controls: list[ExtParamConfig],
5
+ controls: list[EverestControl],
6
6
  ) -> tuple[list[SamplerConfig | None], list[int]]:
7
7
  """
8
8
  Create a list of unique samplers, and a list mapping variable index
@@ -1,6 +1,7 @@
1
1
  import errno
2
2
  import os
3
3
  import tempfile
4
+ import types
4
5
  from collections import Counter
5
6
  from collections.abc import Sequence
6
7
  from pathlib import Path
@@ -104,7 +105,12 @@ class InstallDataContext:
104
105
  if data.source is not None and "<REALIZATION_ID>" in data.source:
105
106
  self._set_symlink(data.source, data.target, realization)
106
107
 
107
- def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None:
108
+ def __exit__(
109
+ self,
110
+ exc_type: type[BaseException] | None,
111
+ exc_value: BaseException | None,
112
+ exc_tb: types.TracebackType | None,
113
+ ) -> None:
108
114
  if self._temp_dir:
109
115
  self._temp_dir.cleanup()
110
116
  os.chdir(self._cwd)
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env python
2
-
3
1
  import logging
4
2
  import os
5
3
  import re
@@ -81,7 +81,7 @@ def stop_server(
81
81
  for retry in range(retries):
82
82
  try:
83
83
  url, cert, auth = server_context
84
- stop_endpoint = "/".join([url, EverEndpoints.stop])
84
+ stop_endpoint = f"{url}/{EverEndpoints.stop}"
85
85
  response = requests.post(
86
86
  stop_endpoint,
87
87
  verify=cert,
@@ -105,7 +105,7 @@ def start_experiment(
105
105
  for retry in range(retries):
106
106
  try:
107
107
  url, cert, auth = server_context
108
- start_endpoint = "/".join([url, EverEndpoints.start_experiment])
108
+ start_endpoint = f"{url}/{EverEndpoints.start_experiment}"
109
109
  response = requests.post(
110
110
  start_endpoint,
111
111
  verify=cert,
@@ -126,7 +126,7 @@ def extract_errors_from_file(path: str) -> list[str]:
126
126
  return re.findall(r"(Error \w+.*)", Path(path).read_text(encoding="utf-8"))
127
127
 
128
128
 
129
- def wait_for_server(client: Client, timeout: int | float) -> None:
129
+ def wait_for_server(client: Client, timeout: float) -> None:
130
130
  """
131
131
  Waits until the everest server has started. Polls every second
132
132
  for server availability until timeout (measured in seconds).
@@ -540,8 +540,6 @@ class EverestStorage:
540
540
  }
541
541
  )
542
542
 
543
- # TODO: The weight and normalization keys are only used by the everest api,
544
- # with everviz. They should be removed in the long run.
545
543
  weights = np.fromiter(
546
544
  (
547
545
  1.0 if weight is None else weight
@@ -44,7 +44,7 @@ class EverestClient:
44
44
 
45
45
  def _http_get(self, endpoint: EverEndpoints) -> requests.Response:
46
46
  return requests.get(
47
- "/".join([self._url, endpoint]),
47
+ f"{self._url}/{endpoint}",
48
48
  verify=self._cert,
49
49
  auth=(self._username, self._password),
50
50
  proxies={"http": None, "https": None}, # type: ignore
@@ -52,7 +52,7 @@ class EverestClient:
52
52
 
53
53
  def _http_post(self, endpoint: EverEndpoints) -> requests.Response:
54
54
  return requests.post(
55
- "/".join([self._url, endpoint]),
55
+ f"{self._url}/{endpoint}",
56
56
  verify=self._cert,
57
57
  auth=(self._username, self._password),
58
58
  proxies={"http": None, "https": None}, # type: ignore
@@ -3,7 +3,7 @@ from typing import Any
3
3
 
4
4
  from ropt.enums import PerturbationType, VariableType
5
5
 
6
- from ert.config import EverestConstraintsConfig, EverestObjectivesConfig, ExtParamConfig
6
+ from ert.config import EverestConstraintsConfig, EverestControl, EverestObjectivesConfig
7
7
  from everest.config import (
8
8
  InputConstraintConfig,
9
9
  ModelConfig,
@@ -14,7 +14,7 @@ from everest.config.utils import get_samplers
14
14
 
15
15
 
16
16
  def _parse_controls(
17
- controls: list[ExtParamConfig], random_seed: int
17
+ controls: list[EverestControl], random_seed: int
18
18
  ) -> tuple[dict[str, Any], list[dict[str, Any]] | None]:
19
19
  control_types = [
20
20
  VariableType[type_.upper()]
@@ -116,7 +116,7 @@ def _get_bounds(
116
116
 
117
117
  def _parse_input_constraints(
118
118
  input_constraints: list[InputConstraintConfig],
119
- controls: list[ExtParamConfig],
119
+ controls: list[EverestControl],
120
120
  ) -> dict[str, Any]:
121
121
  formatted_control_names = [
122
122
  name for config in controls for name in config.input_keys
@@ -275,7 +275,7 @@ def _parse_optimization(
275
275
 
276
276
 
277
277
  def everest2ropt(
278
- controls: list[ExtParamConfig],
278
+ controls: list[EverestControl],
279
279
  objective_functions: EverestObjectivesConfig,
280
280
  input_constraints: list[InputConstraintConfig],
281
281
  output_constraints: EverestConstraintsConfig | None,
@@ -11,7 +11,7 @@ from ropt.transforms.base import (
11
11
  VariableTransform,
12
12
  )
13
13
 
14
- from ert.config import EverestConstraintsConfig, EverestObjectivesConfig, ExtParamConfig
14
+ from ert.config import EverestConstraintsConfig, EverestControl, EverestObjectivesConfig
15
15
  from everest.config import (
16
16
  InputConstraintConfig,
17
17
  ModelConfig,
@@ -426,7 +426,7 @@ class ConstraintScaler(NonLinearConstraintTransform):
426
426
 
427
427
 
428
428
  def get_optimization_domain_transforms(
429
- controls: list[ExtParamConfig],
429
+ controls: list[EverestControl],
430
430
  objectives: EverestObjectivesConfig,
431
431
  input_constraints: list[InputConstraintConfig] | None,
432
432
  output_constraints: EverestConstraintsConfig | None,
ert/config/violations.py DELETED
File without changes
@@ -1,3 +0,0 @@
1
- from .export_tool import ExportTool
2
-
3
- __all__ = ["ExportTool"]
@@ -1,83 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- from typing import TYPE_CHECKING
5
-
6
- from PyQt6.QtWidgets import QCheckBox, QWidget
7
-
8
- from ert.gui.ertwidgets import CustomDialog, ListEditBox, PathChooser, PathModel
9
-
10
- if TYPE_CHECKING:
11
- from ert.config import ErtConfig
12
- from ert.storage import LocalStorage
13
-
14
-
15
- class ExportDialog(CustomDialog):
16
- def __init__(
17
- self,
18
- ert_config: ErtConfig,
19
- storage: LocalStorage,
20
- parent: QWidget | None = None,
21
- ) -> None:
22
- self.storage = storage
23
- description = "The CSV export requires some information before it starts:"
24
- super().__init__("export", description, parent)
25
-
26
- subs_list = ert_config.substitutions
27
- default_csv_output_path = subs_list.get("<CSV_OUTPUT_PATH>", "output.csv")
28
- self.output_path_model = PathModel(default_csv_output_path)
29
- output_path_chooser = PathChooser(self.output_path_model)
30
-
31
- design_matrix_default = subs_list.get("<DESIGN_MATRIX_PATH>", "")
32
- self.design_matrix_path_model = PathModel(
33
- design_matrix_default, is_required=False, must_exist=True
34
- )
35
- design_matrix_path_chooser = PathChooser(self.design_matrix_path_model)
36
-
37
- ensemble_with_data_dict = {
38
- ensemble.id: ensemble.name
39
- for ensemble in storage.ensembles
40
- if ensemble.has_data()
41
- }
42
- self.list_edit = ListEditBox(ensemble_with_data_dict)
43
-
44
- self.drop_const_columns_check = QCheckBox()
45
- self.drop_const_columns_check.setChecked(False)
46
- self.drop_const_columns_check.setToolTip(
47
- "If checked, exclude columns whose value is the same for every entry"
48
- )
49
-
50
- self.addLabeledOption("Output file path", output_path_chooser)
51
- self.addLabeledOption("Design matrix path", design_matrix_path_chooser)
52
- self.addLabeledOption("List of ensembles to export", self.list_edit)
53
- self.addLabeledOption("Drop constant columns", self.drop_const_columns_check)
54
-
55
- self.addButtons()
56
-
57
- @property
58
- def output_path(self) -> str | None:
59
- return self.output_path_model.getPath()
60
-
61
- @property
62
- def ensemble_data_as_json(self) -> str:
63
- ensembles = {
64
- str(ensemble.id): {
65
- "ensemble_name": ensemble.name,
66
- "experiment_name": ensemble.experiment.name,
67
- }
68
- for ensemble in self.storage.ensembles
69
- if ensemble.name in self.list_edit.getItems().values()
70
- }
71
-
72
- return json.dumps(ensembles)
73
-
74
- @property
75
- def design_matrix_path(self) -> str | None:
76
- path = self.design_matrix_path_model.getPath()
77
- if not path or not path.strip():
78
- path = None
79
- return path
80
-
81
- @property
82
- def drop_const_columns(self) -> bool:
83
- return self.drop_const_columns_check.isChecked()
@@ -1,69 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import logging
4
- from typing import TYPE_CHECKING, Any, cast, no_type_check
5
-
6
- from PyQt6.QtGui import QIcon
7
- from PyQt6.QtWidgets import QMessageBox, QWidget
8
- from typing_extensions import override
9
-
10
- if TYPE_CHECKING:
11
- from ert.config import ErtConfig
12
-
13
- from ert.gui.ertnotifier import ErtNotifier
14
- from ert.gui.tools import Tool
15
- from ert.gui.tools.export.export_panel import ExportDialog
16
-
17
- from .exporter import Exporter
18
-
19
- logger = logging.getLogger(__name__)
20
-
21
-
22
- class ExportTool(Tool):
23
- def __init__(self, config: ErtConfig, notifier: ErtNotifier) -> None:
24
- super().__init__("Export data", QIcon("img:share.svg"))
25
- export_job = config.workflow_jobs.get("CSV_EXPORT")
26
- self.setEnabled(export_job is not None)
27
- self.__exporter = Exporter(
28
- export_job,
29
- notifier,
30
- config,
31
- )
32
- self.config = config
33
- self.notifier = notifier
34
-
35
- @override
36
- @no_type_check
37
- def trigger(self) -> None:
38
- dialog = ExportDialog(self.config, self.notifier.storage, self.parent())
39
- success = dialog.showAndTell()
40
-
41
- if success:
42
- logger.info("Gui utility: Export CSV tool was used")
43
- self._run_export(
44
- [
45
- dialog.output_path,
46
- dialog.ensemble_data_as_json,
47
- dialog.design_matrix_path,
48
- True,
49
- dialog.drop_const_columns,
50
- ]
51
- )
52
-
53
- def _run_export(self, params: list[Any]) -> None:
54
- try:
55
- self.__exporter.run_export(params)
56
- QMessageBox.information(
57
- cast(QWidget, self.parent()),
58
- "Success",
59
- """Export completed!""",
60
- QMessageBox.StandardButton.Ok,
61
- )
62
- except UserWarning as usrwarning:
63
- logger.error(str(usrwarning))
64
- QMessageBox.warning(
65
- cast(QWidget, self.parent()),
66
- "Failure",
67
- f"Export failed with the following message:\n{usrwarning}",
68
- QMessageBox.StandardButton.Ok,
69
- )
@@ -1,36 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import logging
4
- from typing import TYPE_CHECKING, Any
5
-
6
- if TYPE_CHECKING:
7
- from ert.config import ErtConfig, WorkflowJob
8
-
9
- from ert.gui.ertnotifier import ErtNotifier
10
- from ert.workflow_runner import WorkflowJobRunner
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
-
15
- class Exporter:
16
- def __init__(
17
- self,
18
- export_job: WorkflowJob | None,
19
- notifier: ErtNotifier,
20
- config: ErtConfig,
21
- ) -> None:
22
- self.config = config
23
- self.export_job = export_job
24
- self._notifier = notifier
25
-
26
- def run_export(self, parameters: list[Any]) -> None:
27
- if self.export_job is None:
28
- raise UserWarning("Could not find export_job job")
29
-
30
- export_job_runner = WorkflowJobRunner(self.export_job)
31
- user_warn = export_job_runner.run(
32
- fixtures={"storage": self._notifier.storage},
33
- arguments=parameters,
34
- )
35
- if export_job_runner.hasFailed():
36
- raise UserWarning(f"Failed to execute {self.export_job.name}\n{user_warn}")