ert 16.0.9__py3-none-any.whl → 19.0.0rc2__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 (286) hide show
  1. _ert/events.py +19 -2
  2. _ert/forward_model_runner/client.py +6 -2
  3. _ert/forward_model_runner/fm_dispatch.py +9 -6
  4. _ert/forward_model_runner/reporting/event.py +1 -0
  5. _ert/forward_model_runner/runner.py +1 -2
  6. _ert/utils.py +12 -0
  7. ert/__main__.py +58 -38
  8. ert/analysis/_enif_update.py +8 -4
  9. ert/analysis/_es_update.py +19 -6
  10. ert/analysis/_update_commons.py +16 -6
  11. ert/base_model_context.py +1 -1
  12. ert/cli/main.py +17 -12
  13. ert/cli/monitor.py +7 -0
  14. ert/config/__init__.py +17 -6
  15. ert/config/_create_observation_dataframes.py +118 -21
  16. ert/config/_get_num_cpu.py +1 -1
  17. ert/config/_observations.py +91 -2
  18. ert/config/_read_summary.py +74 -328
  19. ert/config/design_matrix.py +62 -23
  20. ert/config/distribution.py +1 -1
  21. ert/config/ensemble_config.py +9 -17
  22. ert/config/ert_config.py +155 -58
  23. ert/config/everest_control.py +234 -0
  24. ert/config/{everest_constraints_config.py → everest_response.py} +27 -15
  25. ert/config/field.py +99 -90
  26. ert/config/forward_model_step.py +122 -17
  27. ert/config/gen_data_config.py +5 -10
  28. ert/config/gen_kw_config.py +11 -41
  29. ert/config/known_response_types.py +14 -0
  30. ert/config/parameter_config.py +1 -33
  31. ert/config/parsing/_option_dict.py +10 -2
  32. ert/config/parsing/config_errors.py +1 -1
  33. ert/config/parsing/config_keywords.py +2 -1
  34. ert/config/parsing/config_schema.py +23 -11
  35. ert/config/parsing/config_schema_deprecations.py +3 -3
  36. ert/config/parsing/config_schema_item.py +26 -11
  37. ert/config/parsing/context_values.py +3 -3
  38. ert/config/parsing/file_context_token.py +1 -1
  39. ert/config/parsing/observations_parser.py +6 -2
  40. ert/config/parsing/queue_system.py +9 -0
  41. ert/config/parsing/schema_item_type.py +1 -0
  42. ert/config/queue_config.py +42 -50
  43. ert/config/response_config.py +0 -8
  44. ert/config/rft_config.py +275 -0
  45. ert/config/summary_config.py +3 -8
  46. ert/config/surface_config.py +73 -26
  47. ert/config/workflow_fixtures.py +2 -1
  48. ert/config/workflow_job.py +135 -54
  49. ert/dark_storage/client/__init__.py +2 -2
  50. ert/dark_storage/client/_session.py +4 -4
  51. ert/dark_storage/client/client.py +2 -2
  52. ert/dark_storage/common.py +12 -3
  53. ert/dark_storage/compute/misfits.py +11 -7
  54. ert/dark_storage/endpoints/compute/misfits.py +6 -4
  55. ert/dark_storage/endpoints/ensembles.py +4 -0
  56. ert/dark_storage/endpoints/experiment_server.py +30 -24
  57. ert/dark_storage/endpoints/experiments.py +2 -2
  58. ert/dark_storage/endpoints/observations.py +8 -6
  59. ert/dark_storage/endpoints/parameters.py +4 -12
  60. ert/dark_storage/endpoints/responses.py +24 -5
  61. ert/dark_storage/json_schema/ensemble.py +3 -0
  62. ert/dark_storage/json_schema/experiment.py +1 -1
  63. ert/data/_measured_data.py +6 -5
  64. ert/ensemble_evaluator/__init__.py +8 -1
  65. ert/ensemble_evaluator/config.py +2 -1
  66. ert/ensemble_evaluator/evaluator.py +81 -29
  67. ert/ensemble_evaluator/event.py +6 -0
  68. ert/ensemble_evaluator/snapshot.py +3 -1
  69. ert/ensemble_evaluator/state.py +1 -0
  70. ert/field_utils/__init__.py +8 -0
  71. ert/field_utils/field_utils.py +228 -15
  72. ert/field_utils/grdecl_io.py +1 -1
  73. ert/field_utils/roff_io.py +1 -1
  74. ert/gui/__init__.py +5 -2
  75. ert/gui/ertnotifier.py +1 -1
  76. ert/gui/ertwidgets/__init__.py +23 -16
  77. ert/gui/ertwidgets/analysismoduleedit.py +2 -2
  78. ert/gui/ertwidgets/checklist.py +1 -1
  79. ert/gui/ertwidgets/closabledialog.py +2 -0
  80. ert/gui/ertwidgets/copyablelabel.py +2 -0
  81. ert/gui/ertwidgets/create_experiment_dialog.py +3 -1
  82. ert/gui/ertwidgets/ensembleselector.py +2 -2
  83. ert/gui/ertwidgets/listeditbox.py +2 -0
  84. ert/gui/ertwidgets/models/__init__.py +2 -0
  85. ert/gui/ertwidgets/models/activerealizationsmodel.py +5 -1
  86. ert/gui/ertwidgets/models/path_model.py +1 -1
  87. ert/gui/ertwidgets/models/targetensemblemodel.py +5 -1
  88. ert/gui/ertwidgets/models/text_model.py +4 -1
  89. ert/gui/ertwidgets/pathchooser.py +0 -3
  90. ert/gui/ertwidgets/searchbox.py +17 -4
  91. ert/gui/ertwidgets/stringbox.py +2 -0
  92. ert/gui/{suggestor → ertwidgets/suggestor}/_suggestor_message.py +13 -4
  93. ert/gui/{suggestor → ertwidgets/suggestor}/suggestor.py +63 -30
  94. ert/gui/main.py +41 -13
  95. ert/gui/main_window.py +3 -7
  96. ert/gui/model/fm_step_list.py +3 -0
  97. ert/gui/model/real_list.py +1 -0
  98. ert/gui/model/snapshot.py +1 -0
  99. ert/gui/simulation/combobox_with_description.py +3 -0
  100. ert/gui/simulation/ensemble_experiment_panel.py +8 -2
  101. ert/gui/simulation/ensemble_information_filter_panel.py +7 -2
  102. ert/gui/simulation/ensemble_smoother_panel.py +8 -2
  103. ert/gui/simulation/evaluate_ensemble_panel.py +17 -7
  104. ert/gui/simulation/experiment_panel.py +18 -6
  105. ert/gui/simulation/manual_update_panel.py +35 -10
  106. ert/gui/simulation/multiple_data_assimilation_panel.py +13 -9
  107. ert/gui/simulation/run_dialog.py +47 -20
  108. ert/gui/simulation/single_test_run_panel.py +6 -3
  109. ert/gui/simulation/view/progress_widget.py +2 -0
  110. ert/gui/simulation/view/realization.py +5 -1
  111. ert/gui/simulation/view/update.py +2 -0
  112. ert/gui/summarypanel.py +20 -1
  113. ert/gui/tools/event_viewer/panel.py +3 -4
  114. ert/gui/tools/event_viewer/tool.py +2 -0
  115. ert/gui/tools/load_results/load_results_panel.py +1 -1
  116. ert/gui/tools/load_results/load_results_tool.py +2 -0
  117. ert/gui/tools/manage_experiments/export_dialog.py +136 -0
  118. ert/gui/tools/manage_experiments/manage_experiments_panel.py +2 -0
  119. ert/gui/tools/manage_experiments/storage_info_widget.py +121 -16
  120. ert/gui/tools/manage_experiments/storage_widget.py +4 -3
  121. ert/gui/tools/plot/customize/color_chooser.py +5 -2
  122. ert/gui/tools/plot/customize/customize_plot_dialog.py +2 -0
  123. ert/gui/tools/plot/customize/default_customization_view.py +4 -0
  124. ert/gui/tools/plot/customize/limits_customization_view.py +3 -0
  125. ert/gui/tools/plot/customize/statistics_customization_view.py +3 -0
  126. ert/gui/tools/plot/customize/style_chooser.py +2 -0
  127. ert/gui/tools/plot/customize/style_customization_view.py +3 -0
  128. ert/gui/tools/plot/data_type_keys_widget.py +2 -0
  129. ert/gui/tools/plot/data_type_proxy_model.py +3 -0
  130. ert/gui/tools/plot/plot_api.py +50 -28
  131. ert/gui/tools/plot/plot_ensemble_selection_widget.py +17 -10
  132. ert/gui/tools/plot/plot_widget.py +15 -2
  133. ert/gui/tools/plot/plot_window.py +41 -19
  134. ert/gui/tools/plot/plottery/plot_config.py +2 -0
  135. ert/gui/tools/plot/plottery/plot_context.py +14 -0
  136. ert/gui/tools/plot/plottery/plots/__init__.py +2 -0
  137. ert/gui/tools/plot/plottery/plots/cesp.py +3 -1
  138. ert/gui/tools/plot/plottery/plots/distribution.py +6 -1
  139. ert/gui/tools/plot/plottery/plots/ensemble.py +13 -5
  140. ert/gui/tools/plot/plottery/plots/gaussian_kde.py +12 -2
  141. ert/gui/tools/plot/plottery/plots/histogram.py +3 -1
  142. ert/gui/tools/plot/plottery/plots/misfits.py +436 -0
  143. ert/gui/tools/plot/plottery/plots/observations.py +18 -4
  144. ert/gui/tools/plot/plottery/plots/statistics.py +62 -20
  145. ert/gui/tools/plot/plottery/plots/std_dev.py +3 -1
  146. ert/gui/tools/plot/widgets/clearable_line_edit.py +9 -0
  147. ert/gui/tools/plot/widgets/filter_popup.py +2 -0
  148. ert/gui/tools/plot/widgets/filterable_kw_list_model.py +3 -0
  149. ert/gui/tools/plugins/plugin.py +1 -1
  150. ert/gui/tools/plugins/plugins_tool.py +2 -0
  151. ert/gui/tools/plugins/process_job_dialog.py +3 -0
  152. ert/gui/tools/workflows/workflow_dialog.py +2 -0
  153. ert/gui/tools/workflows/workflows_tool.py +2 -0
  154. ert/libres_facade.py +5 -7
  155. ert/logging/__init__.py +4 -1
  156. ert/mode_definitions.py +2 -0
  157. ert/plugins/__init__.py +4 -6
  158. ert/plugins/hook_implementations/workflows/csv_export.py +2 -3
  159. ert/plugins/hook_implementations/workflows/gen_data_rft_export.py +10 -2
  160. ert/plugins/hook_specifications/__init__.py +0 -10
  161. ert/plugins/hook_specifications/jobs.py +0 -9
  162. ert/plugins/plugin_manager.py +53 -124
  163. ert/resources/forward_models/run_reservoirsimulator.py +8 -4
  164. ert/resources/forward_models/template_render.py +10 -10
  165. ert/resources/shell_scripts/delete_directory.py +2 -2
  166. ert/run_models/__init__.py +24 -6
  167. ert/run_models/_create_run_path.py +133 -38
  168. ert/run_models/ensemble_experiment.py +10 -4
  169. ert/run_models/ensemble_information_filter.py +8 -1
  170. ert/run_models/ensemble_smoother.py +9 -3
  171. ert/run_models/evaluate_ensemble.py +8 -6
  172. ert/run_models/event.py +7 -3
  173. ert/run_models/everest_run_model.py +337 -113
  174. ert/run_models/initial_ensemble_run_model.py +25 -24
  175. ert/run_models/manual_update.py +6 -3
  176. ert/run_models/manual_update_enif.py +37 -0
  177. ert/run_models/model_factory.py +78 -18
  178. ert/run_models/multiple_data_assimilation.py +22 -11
  179. ert/run_models/run_model.py +72 -73
  180. ert/run_models/single_test_run.py +7 -4
  181. ert/run_models/update_run_model.py +4 -2
  182. ert/runpaths.py +5 -6
  183. ert/sample_prior.py +9 -4
  184. ert/scheduler/__init__.py +10 -5
  185. ert/scheduler/driver.py +40 -0
  186. ert/scheduler/event.py +3 -1
  187. ert/scheduler/job.py +23 -13
  188. ert/scheduler/lsf_driver.py +15 -5
  189. ert/scheduler/openpbs_driver.py +10 -4
  190. ert/scheduler/scheduler.py +5 -0
  191. ert/scheduler/slurm_driver.py +20 -5
  192. ert/services/__init__.py +2 -2
  193. ert/services/_base_service.py +37 -20
  194. ert/services/_storage_main.py +20 -18
  195. ert/services/ert_server.py +317 -0
  196. ert/shared/_doc_utils/__init__.py +4 -2
  197. ert/shared/_doc_utils/ert_jobs.py +1 -4
  198. ert/shared/net_utils.py +43 -18
  199. ert/shared/storage/connection.py +3 -3
  200. ert/shared/version.py +3 -3
  201. ert/storage/__init__.py +14 -1
  202. ert/storage/local_ensemble.py +44 -13
  203. ert/storage/local_experiment.py +54 -34
  204. ert/storage/local_storage.py +90 -58
  205. ert/storage/migration/to10.py +3 -2
  206. ert/storage/migration/to11.py +9 -10
  207. ert/storage/migration/to12.py +19 -20
  208. ert/storage/migration/to13.py +28 -27
  209. ert/storage/migration/to14.py +3 -3
  210. ert/storage/migration/to15.py +25 -0
  211. ert/storage/migration/to16.py +38 -0
  212. ert/storage/migration/to17.py +42 -0
  213. ert/storage/migration/to18.py +11 -0
  214. ert/storage/migration/to19.py +34 -0
  215. ert/storage/migration/to20.py +23 -0
  216. ert/storage/migration/to21.py +25 -0
  217. ert/storage/migration/to6.py +3 -2
  218. ert/storage/migration/to7.py +12 -13
  219. ert/storage/migration/to8.py +9 -11
  220. ert/storage/migration/to9.py +5 -4
  221. ert/storage/realization_storage_state.py +7 -7
  222. ert/substitutions.py +12 -28
  223. ert/validation/active_range.py +7 -7
  224. ert/validation/ensemble_realizations_argument.py +4 -2
  225. ert/validation/rangestring.py +16 -16
  226. ert/workflow_runner.py +6 -3
  227. {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/METADATA +21 -15
  228. ert-19.0.0rc2.dist-info/RECORD +524 -0
  229. {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/WHEEL +1 -1
  230. everest/api/everest_data_api.py +14 -1
  231. everest/assets/everest_logo.svg +406 -0
  232. everest/bin/config_branch_script.py +30 -14
  233. everest/bin/everconfigdump_script.py +2 -10
  234. everest/bin/everest_script.py +53 -33
  235. everest/bin/everlint_script.py +3 -5
  236. everest/bin/kill_script.py +7 -5
  237. everest/bin/main.py +11 -24
  238. everest/bin/monitor_script.py +64 -35
  239. everest/bin/utils.py +58 -43
  240. everest/bin/visualization_script.py +23 -13
  241. everest/config/__init__.py +4 -1
  242. everest/config/control_config.py +81 -6
  243. everest/config/control_variable_config.py +4 -3
  244. everest/config/everest_config.py +102 -79
  245. everest/config/forward_model_config.py +5 -3
  246. everest/config/install_data_config.py +7 -5
  247. everest/config/install_job_config.py +45 -3
  248. everest/config/install_template_config.py +3 -3
  249. everest/config/optimization_config.py +19 -6
  250. everest/config/output_constraint_config.py +8 -2
  251. everest/config/server_config.py +6 -55
  252. everest/config/simulator_config.py +62 -17
  253. everest/config/utils.py +25 -105
  254. everest/config/validation_utils.py +34 -15
  255. everest/config_file_loader.py +30 -21
  256. everest/detached/__init__.py +0 -6
  257. everest/detached/client.py +7 -52
  258. everest/detached/everserver.py +19 -45
  259. everest/everest_storage.py +24 -40
  260. everest/gui/everest_client.py +2 -3
  261. everest/gui/main_window.py +2 -2
  262. everest/optimizer/everest2ropt.py +68 -42
  263. everest/optimizer/opt_model_transforms.py +15 -20
  264. everest/optimizer/utils.py +0 -29
  265. everest/plugins/hook_specs.py +0 -24
  266. everest/strings.py +1 -6
  267. everest/util/__init__.py +3 -1
  268. ert/config/everest_objective_config.py +0 -95
  269. ert/config/ext_param_config.py +0 -107
  270. ert/gui/tools/export/__init__.py +0 -3
  271. ert/gui/tools/export/export_panel.py +0 -83
  272. ert/gui/tools/export/export_tool.py +0 -67
  273. ert/gui/tools/export/exporter.py +0 -36
  274. ert/plugins/hook_specifications/ecl_config.py +0 -29
  275. ert/services/storage_service.py +0 -127
  276. ert/summary_key_type.py +0 -234
  277. ert-16.0.9.dist-info/RECORD +0 -521
  278. everest/bin/everexport_script.py +0 -53
  279. everest/config/sampler_config.py +0 -103
  280. everest/simulator/__init__.py +0 -88
  281. everest/simulator/everest_to_ert.py +0 -252
  282. /ert/gui/{suggestor → ertwidgets/suggestor}/__init__.py +0 -0
  283. /ert/gui/{suggestor → ertwidgets/suggestor}/_colors.py +0 -0
  284. {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/entry_points.txt +0 -0
  285. {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/licenses/COPYING +0 -0
  286. {ert-16.0.9.dist-info → ert-19.0.0rc2.dist-info}/top_level.txt +0 -0
@@ -11,14 +11,11 @@ from ropt.transforms.base import (
11
11
  VariableTransform,
12
12
  )
13
13
 
14
+ from ert.config import EverestConstraintsConfig, EverestControl, EverestObjectivesConfig
14
15
  from everest.config import (
15
- ControlConfig,
16
16
  InputConstraintConfig,
17
17
  ModelConfig,
18
- ObjectiveFunctionConfig,
19
- OutputConstraintConfig,
20
18
  )
21
- from everest.config.utils import FlattenedControls
22
19
 
23
20
 
24
21
  class EverestOptModelTransforms(TypedDict):
@@ -429,19 +426,22 @@ class ConstraintScaler(NonLinearConstraintTransform):
429
426
 
430
427
 
431
428
  def get_optimization_domain_transforms(
432
- controls: list[ControlConfig],
433
- objectives: list[ObjectiveFunctionConfig],
429
+ controls: list[EverestControl],
430
+ objectives: EverestObjectivesConfig,
434
431
  input_constraints: list[InputConstraintConfig] | None,
435
- output_constraints: list[OutputConstraintConfig] | None,
432
+ output_constraints: EverestConstraintsConfig | None,
436
433
  model: ModelConfig,
437
434
  auto_scale: bool,
438
435
  ) -> EverestOptModelTransforms:
439
- flattened_controls = FlattenedControls(controls)
440
436
  control_scaler = ControlScaler(
441
- flattened_controls.lower_bounds,
442
- flattened_controls.upper_bounds,
443
- flattened_controls.scaled_ranges,
444
- flattened_controls.types,
437
+ [min_ for control in controls for min_ in control.min],
438
+ [max_ for control in controls for max_ in control.max],
439
+ [
440
+ scaled_range
441
+ for control in controls
442
+ for scaled_range in control.scaled_ranges
443
+ ],
444
+ [type_ for control in controls for type_ in control.control_types],
445
445
  auto_scale_input_constraints=auto_scale,
446
446
  input_constraint_scales=(
447
447
  None
@@ -461,14 +461,10 @@ def get_optimization_domain_transforms(
461
461
 
462
462
  objective_scaler = ObjectiveScaler(
463
463
  auto_scale=auto_scale,
464
- scales=[
465
- 1.0 if objective.scale is None else objective.scale
466
- for objective in objectives
467
- ],
464
+ scales=[1.0 if scale is None else scale for scale in objectives.scales],
468
465
  realization_weights=realization_weights,
469
466
  objective_weights=[
470
- 1.0 if objective.weight is None else objective.weight
471
- for objective in objectives
467
+ 1.0 if weight is None else weight for weight in objectives.weights
472
468
  ],
473
469
  )
474
470
 
@@ -476,8 +472,7 @@ def get_optimization_domain_transforms(
476
472
  ConstraintScaler(
477
473
  auto_scale=auto_scale,
478
474
  scales=[
479
- 1.0 if constraint.scale is None else constraint.scale
480
- for constraint in output_constraints
475
+ 1.0 if scale is None else scale for scale in output_constraints.scales
481
476
  ],
482
477
  realization_weights=realization_weights,
483
478
  )
@@ -1,29 +0,0 @@
1
- import importlib
2
-
3
- from ropt.plugins import PluginManager
4
-
5
-
6
- def get_ropt_plugin_manager() -> PluginManager:
7
- # To check the validity of optimization and sampler backends and their
8
- # supported algorithms or methods, an instance of a ropt PluginManager is
9
- # needed. Everest also needs a ropt plugin manager at runtime which may add
10
- # additional optimization and/or sampler backends. To be sure that these
11
- # added backends are detected, all code should use this function to access
12
- # the plugin manager. Any optimizer/sampler plugins that need to be added at
13
- # runtime should be added in this function.
14
- #
15
- # Note: backends can also be added via the Python entrypoints mechanism,
16
- # these are detected by default and do not need to be added here.
17
-
18
- try:
19
- return PluginManager()
20
- except Exception as exc:
21
- ert_version = importlib.metadata.version("ert")
22
- ropt_version = importlib.metadata.version("ropt")
23
- msg = (
24
- f"Error while initializing ropt:\n\n{exc}.\n\n"
25
- "Check the everest installation, there may a be version mismatch.\n"
26
- f" (ERT: {ert_version}, ropt: {ropt_version})\n"
27
- "If the everest installation is correct, please report this as a bug."
28
- )
29
- raise RuntimeError(msg) from exc
@@ -21,30 +21,6 @@ def install_job_directories() -> list[str]: # type: ignore[empty-body]
21
21
  """
22
22
 
23
23
 
24
- @hookspec(firstresult=True)
25
- def ecl100_config_path() -> str: # type: ignore[empty-body]
26
- """
27
- :return: Path to ecl100 config file
28
- :rtype: PluginResponse with data as str
29
- """
30
-
31
-
32
- @hookspec(firstresult=True)
33
- def ecl300_config_path() -> str: # type: ignore[empty-body]
34
- """
35
- :return: Path to ecl300 config file
36
- :rtype: PluginResponse with data as str
37
- """
38
-
39
-
40
- @hookspec(firstresult=True)
41
- def flow_config_path() -> str: # type: ignore[empty-body]
42
- """
43
- :return: Path to flow config file
44
- :rtype: PluginResponse with data as str
45
- """
46
-
47
-
48
24
  @hookspec(firstresult=True)
49
25
  def lint_forward_model(job: str, args: Sequence[str]) -> list[str]: # type: ignore[empty-body]
50
26
  """
everest/strings.py CHANGED
@@ -1,15 +1,11 @@
1
1
  from enum import StrEnum
2
2
 
3
- CERTIFICATE_DIR = "cert"
4
-
5
- DETACHED_NODE_DIR = "detached_node_output"
6
3
  DEFAULT_OUTPUT_DIR = "everest_output"
7
4
  DEFAULT_LOGGING_FORMAT = "%(asctime)s %(name)s %(levelname)s: %(message)s"
8
5
 
9
6
  EVEREST = "everest"
10
7
  EVERSERVER = "everserver"
11
-
12
- HOSTFILE_NAME = "storage_server.json"
8
+ EXPERIMENT_SERVER = "experiment_server"
13
9
 
14
10
  NAME = "name"
15
11
 
@@ -22,7 +18,6 @@ OPT_FAILURE_REALIZATIONS = (
22
18
  OPT_FAILURE_ALL_REALIZATIONS = "Optimization failed: all realizations failed."
23
19
 
24
20
  SESSION_DIR = ".session"
25
- SERVER_STATUS = "status"
26
21
  SIMULATION = "simulation"
27
22
  SIMULATOR_START = "start"
28
23
  SIMULATOR_UPDATE = "update"
everest/util/__init__.py CHANGED
@@ -8,6 +8,7 @@ try:
8
8
  from ert.shared.version import version as ert_version
9
9
  except ImportError:
10
10
  ert_version = "0.0.0"
11
+ from _ert.utils import file_safe_timestamp
11
12
  from everest.strings import EVEREST
12
13
 
13
14
 
@@ -37,6 +38,7 @@ def warn_user_that_runpath_is_nonempty() -> None:
37
38
 
38
39
  def _roll_dir(old_name: str) -> None:
39
40
  old_name = os.path.realpath(old_name)
40
- new_name = f"{old_name}__{datetime.now(UTC).isoformat()}"
41
+ timestamp = file_safe_timestamp(datetime.now(UTC).isoformat())
42
+ new_name = f"{old_name}__{timestamp}"
41
43
  os.rename(old_name, new_name)
42
44
  logging.getLogger(EVEREST).info(f"renamed {old_name} to {new_name}")
@@ -1,95 +0,0 @@
1
- from pathlib import Path
2
- from typing import Literal, Self
3
-
4
- import numpy as np
5
- import polars as pl
6
-
7
- from ert.substitutions import substitute_runpath_name
8
-
9
- from .parsing import ConfigDict
10
- from .response_config import InvalidResponseFile, ResponseConfig, ResponseMetadata
11
- from .responses_index import responses_index
12
-
13
-
14
- class EverestObjectivesConfig(ResponseConfig):
15
- type: Literal["everest_objectives"] = "everest_objectives"
16
- name: str = "everest_objectives"
17
- has_finalized_keys: bool = True
18
-
19
- @property
20
- def metadata(self) -> list[ResponseMetadata]:
21
- return [
22
- ResponseMetadata(
23
- response_type=self.name,
24
- response_key=response_key,
25
- finalized=self.has_finalized_keys,
26
- filter_on=None,
27
- )
28
- for response_key in self.keys
29
- ]
30
-
31
- @property
32
- def expected_input_files(self) -> list[str]:
33
- return self.input_files
34
-
35
- @classmethod
36
- def from_config_dict(cls, config_dict: ConfigDict) -> Self:
37
- raise NotImplementedError("Should only be directly initialized")
38
-
39
- def read_from_file(self, run_path: str, iens: int, iter_: int) -> pl.DataFrame:
40
- def _read_file(filename: Path) -> pl.DataFrame:
41
- try:
42
- data = np.loadtxt(filename, ndmin=1)
43
- except ValueError as err:
44
- raise InvalidResponseFile(str(err)) from err
45
- return pl.DataFrame(
46
- {
47
- "values": pl.Series(data, dtype=pl.Float32),
48
- }
49
- )
50
-
51
- errors = []
52
-
53
- run_path_ = Path(run_path)
54
- datasets_per_name = []
55
-
56
- for name, input_file in zip(self.keys, self.input_files, strict=False):
57
- datasets = []
58
- try:
59
- filename = substitute_runpath_name(input_file, iens, iter_)
60
- datasets.append(_read_file(run_path_ / filename))
61
- except (InvalidResponseFile, FileNotFoundError) as err:
62
- errors.append(err)
63
-
64
- if len(datasets) > 0:
65
- combined_ds = pl.concat(datasets)
66
- combined_ds.insert_column(
67
- 0, pl.Series("response_key", [name] * len(combined_ds))
68
- )
69
- datasets_per_name.append(combined_ds)
70
-
71
- if errors:
72
- if all(isinstance(err, FileNotFoundError) for err in errors):
73
- raise FileNotFoundError(
74
- "Could not find one or more files/directories while reading "
75
- f"{self.name}: {','.join([str(err) for err in errors])}"
76
- )
77
- else:
78
- raise InvalidResponseFile(
79
- "Error reading "
80
- f"{self.name}, errors: {','.join([str(err) for err in errors])}"
81
- )
82
-
83
- combined = pl.concat(datasets_per_name)
84
- return combined
85
-
86
- @property
87
- def response_type(self) -> str:
88
- return "everest_objectives"
89
-
90
- @property
91
- def primary_key(self) -> list[str]:
92
- return []
93
-
94
-
95
- responses_index.add_response_type(EverestObjectivesConfig)
@@ -1,107 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- from collections.abc import Iterator, Mapping, MutableMapping
5
- from dataclasses import field
6
- from pathlib import Path
7
- from typing import TYPE_CHECKING, Literal
8
-
9
- import networkx as nx
10
- import numpy as np
11
- import xarray as xr
12
-
13
- from ert.substitutions import substitute_runpath_name
14
-
15
- from .parameter_config import ParameterConfig, ParameterMetadata
16
-
17
- if TYPE_CHECKING:
18
- import numpy.typing as npt
19
-
20
- from ert.storage import Ensemble
21
-
22
- Number = int | float
23
- DataType = Mapping[str, Number | Mapping[str, Number]]
24
- MutableDataType = MutableMapping[str, Number | MutableMapping[str, Number]]
25
-
26
-
27
- class ExtParamConfig(ParameterConfig):
28
- """Create an ExtParamConfig for @key with the given @input_keys
29
-
30
- @input_keys can be either a list of keys as strings or a dict with
31
- keys as strings and a list of suffixes for each key.
32
- If a list of strings is given, the order is preserved.
33
- """
34
-
35
- @property
36
- def parameter_keys(self) -> list[str]:
37
- return self.input_keys
38
-
39
- @property
40
- def metadata(self) -> list[ParameterMetadata]:
41
- return []
42
-
43
- type: Literal["everest_parameters"] = "everest_parameters"
44
- input_keys: list[str] = field(default_factory=list)
45
- forward_init: bool = False
46
- output_file: str = ""
47
- forward_init_file: str = ""
48
- update: bool = False
49
-
50
- def read_from_runpath(
51
- self, run_path: Path, real_nr: int, iteration: int
52
- ) -> xr.Dataset:
53
- raise NotImplementedError
54
-
55
- def write_to_runpath(
56
- self, run_path: Path, real_nr: int, ensemble: Ensemble
57
- ) -> None:
58
- file_path = run_path / substitute_runpath_name(
59
- self.output_file, real_nr, ensemble.iteration
60
- )
61
- Path.mkdir(file_path.parent, exist_ok=True, parents=True)
62
-
63
- data: MutableDataType = {}
64
- for da in ensemble.load_parameters(self.name, real_nr)["values"]:
65
- assert isinstance(da, xr.DataArray)
66
- name = str(da.names.values)
67
- try:
68
- outer, inner = name.split("\0")
69
-
70
- if outer not in data:
71
- data[outer] = {}
72
- data[outer][inner] = float(da) # type: ignore
73
- except ValueError:
74
- data[name] = float(da)
75
-
76
- with open(file_path, "w", encoding="utf-8") as f:
77
- json.dump(data, f)
78
-
79
- def create_storage_datasets(
80
- self,
81
- from_data: npt.NDArray[np.float64],
82
- iens_active_index: npt.NDArray[np.int_],
83
- ) -> Iterator[tuple[int, xr.Dataset]]:
84
- for i, realization in enumerate(iens_active_index):
85
- yield (
86
- int(realization),
87
- xr.Dataset(
88
- {
89
- "values": ("names", from_data[:, i]),
90
- "names": [
91
- x.split(f"{self.name}.")[1].replace(".", "\0")
92
- for x in self.parameter_keys
93
- ],
94
- }
95
- ),
96
- )
97
-
98
- def load_parameters(
99
- self, ensemble: Ensemble, realizations: npt.NDArray[np.int_]
100
- ) -> npt.NDArray[np.float64]:
101
- raise NotImplementedError
102
-
103
- def load_parameter_graph(self) -> nx.Graph[int]:
104
- raise NotImplementedError
105
-
106
- def __len__(self) -> int:
107
- return len(self.input_keys)
@@ -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,67 +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
-
9
- if TYPE_CHECKING:
10
- from ert.config import ErtConfig
11
-
12
- from ert.gui.ertnotifier import ErtNotifier
13
- from ert.gui.tools import Tool
14
- from ert.gui.tools.export.export_panel import ExportDialog
15
-
16
- from .exporter import Exporter
17
-
18
- logger = logging.getLogger(__name__)
19
-
20
-
21
- class ExportTool(Tool):
22
- def __init__(self, config: ErtConfig, notifier: ErtNotifier) -> None:
23
- super().__init__("Export data", QIcon("img:share.svg"))
24
- export_job = config.workflow_jobs.get("CSV_EXPORT")
25
- self.setEnabled(export_job is not None)
26
- self.__exporter = Exporter(
27
- export_job,
28
- notifier,
29
- config,
30
- )
31
- self.config = config
32
- self.notifier = notifier
33
-
34
- @no_type_check
35
- def trigger(self) -> None:
36
- dialog = ExportDialog(self.config, self.notifier.storage, self.parent())
37
- success = dialog.showAndTell()
38
-
39
- if success:
40
- logger.info("Gui utility: Export CSV tool was used")
41
- self._run_export(
42
- [
43
- dialog.output_path,
44
- dialog.ensemble_data_as_json,
45
- dialog.design_matrix_path,
46
- True,
47
- dialog.drop_const_columns,
48
- ]
49
- )
50
-
51
- def _run_export(self, params: list[Any]) -> None:
52
- try:
53
- self.__exporter.run_export(params)
54
- QMessageBox.information(
55
- cast(QWidget, self.parent()),
56
- "Success",
57
- """Export completed!""",
58
- QMessageBox.StandardButton.Ok,
59
- )
60
- except UserWarning as usrwarning:
61
- logger.error(str(usrwarning))
62
- QMessageBox.warning(
63
- cast(QWidget, self.parent()),
64
- "Failure",
65
- f"Export failed with the following message:\n{usrwarning}",
66
- QMessageBox.StandardButton.Ok,
67
- )
@@ -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}")
@@ -1,29 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- from ert.plugins.plugin_manager import hook_specification
6
-
7
- if TYPE_CHECKING:
8
- from ert.plugins.plugin_response import PluginResponse
9
-
10
-
11
- @hook_specification(firstresult=True)
12
- def ecl100_config_path() -> PluginResponse[str]: # type: ignore
13
- """
14
- :return: Path to ecl100 config file
15
- """
16
-
17
-
18
- @hook_specification(firstresult=True)
19
- def ecl300_config_path() -> PluginResponse[str]: # type: ignore
20
- """
21
- :return: Path to ecl300 config file
22
- """
23
-
24
-
25
- @hook_specification(firstresult=True)
26
- def flow_config_path() -> PluginResponse[str]: # type: ignore
27
- """
28
- :return: Path to flow config file
29
- """