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
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env python
2
-
3
1
  import argparse
4
2
  import warnings
5
3
  from functools import partial
@@ -11,19 +9,19 @@ from everest.config import EverestConfig
11
9
  def _build_args_parser() -> argparse.ArgumentParser:
12
10
  """Build arg parser"""
13
11
  arg_parser = argparse.ArgumentParser(
14
- description="Check if a config file is valid",
12
+ description="Check if a configuration file is valid.",
15
13
  usage="""everest lint <config_file>""",
16
14
  )
17
15
  arg_parser.add_argument(
18
16
  "config",
19
17
  type=partial(EverestConfig.load_file_with_argparser, parser=arg_parser),
20
- help="The path to the everest configuration file",
18
+ help="The path to the everest configuration file.",
21
19
  )
22
20
  arg_parser.add_argument(
23
21
  "-v",
24
22
  "--verbose",
25
23
  action="store_true",
26
- help="Display verbose errors and warnings",
24
+ help="Display verbose errors and warnings.",
27
25
  )
28
26
  return arg_parser
29
27
 
@@ -12,7 +12,7 @@ from functools import partial
12
12
  from pathlib import Path
13
13
  from typing import Any
14
14
 
15
- from ert.services import StorageService
15
+ from ert.services import ErtServer
16
16
  from everest.bin.utils import setup_logging
17
17
  from everest.config import EverestConfig, ServerConfig
18
18
  from everest.detached import stop_server, wait_for_server_to_stop
@@ -39,16 +39,18 @@ def _build_args_parser() -> argparse.ArgumentParser:
39
39
  """Build arg parser"""
40
40
 
41
41
  arg_parser = argparse.ArgumentParser(
42
- description="Kill a running optimization case based on a given config file",
42
+ description="Kill a running optimization process.",
43
43
  usage="everest kill <config_file>",
44
44
  )
45
45
  arg_parser.add_argument(
46
46
  "config",
47
47
  type=partial(EverestConfig.load_file_with_argparser, parser=arg_parser),
48
- help="The path to the everest configuration file",
48
+ help="The path to the everest configuration file.",
49
49
  )
50
50
  arg_parser.add_argument(
51
- "--debug", action="store_true", help="Display debug information in the terminal"
51
+ "--debug",
52
+ action="store_true",
53
+ help="Display debug information in the terminal.",
52
54
  )
53
55
 
54
56
  return arg_parser
@@ -72,7 +74,7 @@ def _handle_keyboard_interrupt(signal: int, _: Any, after: bool = False) -> None
72
74
 
73
75
  def kill_everest(options: argparse.Namespace) -> None:
74
76
  try:
75
- client = StorageService.session(
77
+ client = ErtServer.session(
76
78
  Path(ServerConfig.get_session_dir(options.config.output_dir)), timeout=1
77
79
  )
78
80
  server_context = ServerConfig.get_server_context_from_conn_info(
everest/bin/main.py CHANGED
@@ -9,7 +9,6 @@ from ert.trace import tracer
9
9
  from everest.bin.config_branch_script import config_branch_entry
10
10
  from everest.bin.everconfigdump_script import config_dump_entry
11
11
  from everest.bin.everest_script import everest_entry
12
- from everest.bin.everexport_script import everexport_entry
13
12
  from everest.bin.everlint_script import lint_entry
14
13
  from everest.bin.kill_script import kill_entry
15
14
  from everest.bin.monitor_script import monitor_entry
@@ -19,10 +18,10 @@ from everest.bin.visualization_script import visualization_entry
19
18
  def _build_args_parser() -> argparse.ArgumentParser:
20
19
  """Build arg parser"""
21
20
  arg_parser = argparse.ArgumentParser(
22
- description="Tool for performing reservoir management optimization",
21
+ description="Tool for performing reservoir management optimization.",
23
22
  usage=(
24
23
  "everest <command> [<args>]\n\n"
25
- "The most commonly used everest commands are:\n"
24
+ "Supported commands:\n"
26
25
  f"{EverestMain.methods_help()}\n\n"
27
26
  "Run everest <command> --help for more information on a command"
28
27
  ),
@@ -51,52 +50,40 @@ class EverestMain:
51
50
  @classmethod
52
51
  def methods_help(cls) -> str:
53
52
  """Return documentation of the public methods in this class"""
54
- pubmets = [m for m in dir(cls) if not m.startswith("_")]
55
- pubmets.remove("methods_help") # Current method should not show up in desc
53
+ pubmets = ["run", "monitor", "kill", "lint", "render", "branch", "results"]
56
54
  maxlen = max(len(m) for m in pubmets)
57
55
  docstrs = [getattr(cls, m).__doc__ for m in pubmets]
58
56
  doclist = [
59
- m.ljust(maxlen + 1) + d for m, d in zip(pubmets, docstrs, strict=False)
57
+ m.ljust(maxlen + 2) + d for m, d in zip(pubmets, docstrs, strict=False)
60
58
  ]
61
59
  return "\n".join(doclist)
62
60
 
63
61
  def run(self, args: list[str]) -> None:
64
- """Start an optimization case base on given config file"""
62
+ """Start an optimization run"""
65
63
  everest_entry(args)
66
64
 
67
65
  def monitor(self, args: list[str]) -> None:
68
- """Monitor a running optimization case base on given config file"""
66
+ """Monitor a running optimization"""
69
67
  monitor_entry(args)
70
68
 
71
69
  def kill(self, args: list[str]) -> None:
72
- """Kill a running optimization case base on given config file"""
70
+ """Kill a running optimization"""
73
71
  kill_entry(args)
74
72
 
75
- def gui(self, _: list[str]) -> None:
76
- """Start the graphical user interface (Removed)"""
77
- print(
78
- "The gui command has been removed. "
79
- "Please use the run command with the --gui option instead."
80
- )
81
-
82
- def export(self, args: list[str]) -> None:
83
- """Export data from a completed optimization case"""
84
- everexport_entry(args)
85
-
86
73
  def lint(self, args: list[str]) -> None:
87
- """Validate a config file"""
74
+ """Validate the configuration file"""
88
75
  lint_entry(args)
89
76
 
90
77
  def render(self, args: list[str]) -> None:
91
- """Display the configuration data loaded from a config file"""
78
+ """Display the configuration data"""
92
79
  config_dump_entry(args)
93
80
 
94
81
  def branch(self, args: list[str]) -> None:
95
- """Construct possible restart config file"""
82
+ """Construct a new configuration file from a given batch"""
96
83
  config_branch_entry(args)
97
84
 
98
85
  def results(self, args: list[str]) -> None:
99
- """Start everest visualization plugin"""
86
+ """Start the everest visualization plugin"""
100
87
  visualization_entry(args)
101
88
 
102
89
 
@@ -5,15 +5,17 @@ import signal
5
5
  import threading
6
6
  from functools import partial
7
7
  from pathlib import Path
8
+ from textwrap import dedent
8
9
 
9
- from ert.services import StorageService
10
+ from ert.services import ErtServer
11
+ from ert.storage import ErtStorageException, ExperimentState
10
12
  from everest.config import EverestConfig, ServerConfig
11
- from everest.detached import ExperimentState, everserver_status
12
13
  from everest.everest_storage import EverestStorage
13
14
 
14
15
  from .utils import (
16
+ ArgParseFormatter,
17
+ get_experiment_status,
15
18
  handle_keyboard_interrupt,
16
- report_on_previous_run,
17
19
  run_detached_monitor,
18
20
  setup_logging,
19
21
  )
@@ -42,25 +44,35 @@ def _build_args_parser() -> argparse.ArgumentParser:
42
44
  """Build arg parser"""
43
45
 
44
46
  arg_parser = argparse.ArgumentParser(
45
- description=(
46
- "Everest console monitor a running optimization case based on a config file"
47
+ description=dedent(
48
+ """
49
+ Monitor a running optimization process.
50
+
51
+ Closing the console or interrupting the `everest run` process does
52
+ not terminate the optimization process. To continue monitoring the
53
+ running optimization, use `everest monitor config_file.yml`. To stop
54
+ a running optimization, use `everest kill config_file.yml`.
55
+ """
47
56
  ),
57
+ formatter_class=ArgParseFormatter,
48
58
  usage="everest monitor <config_file>",
49
59
  )
50
60
  arg_parser.add_argument(
51
61
  "config",
52
62
  type=partial(EverestConfig.load_file_with_argparser, parser=arg_parser),
53
- help="The path to the everest configuration file",
63
+ help="The path to the everest configuration file.",
54
64
  )
55
65
  arg_parser.add_argument(
56
- "--debug", action="store_true", help="Display debug information in the terminal"
66
+ "--debug",
67
+ action="store_true",
68
+ help="Display debug information in the terminal.",
57
69
  )
58
70
  arg_parser.add_argument(
59
71
  "--show-all-jobs",
60
72
  action="store_true",
61
73
  help=(
62
74
  "This option no longer has an effect, "
63
- "and will be removed in a future version"
75
+ "and will be removed in a future version."
64
76
  ),
65
77
  )
66
78
 
@@ -69,37 +81,54 @@ def _build_args_parser() -> argparse.ArgumentParser:
69
81
 
70
82
  def monitor_everest(options: argparse.Namespace) -> None:
71
83
  config: EverestConfig = options.config
72
- status_path = ServerConfig.get_everserver_status_path(config.output_dir)
73
- server_state = everserver_status(status_path)
74
-
75
84
  try:
76
- client = StorageService.session(
85
+ with ErtServer.session(
77
86
  Path(ServerConfig.get_session_dir(config.output_dir)), timeout=1
78
- )
79
- server_context = ServerConfig.get_server_context_from_conn_info(
80
- client.conn_info
81
- )
82
- run_detached_monitor(server_context=server_context)
83
- server_state = everserver_status(status_path)
84
- if server_state["status"] == ExperimentState.failed:
85
- raise SystemExit(server_state["message"])
86
- if server_state["message"] is not None:
87
- print(server_state["message"])
87
+ ) as client:
88
+ server_context = ServerConfig.get_server_context_from_conn_info(
89
+ client.conn_info
90
+ )
91
+ run_detached_monitor(server_context=server_context)
92
+
93
+ try:
94
+ experiment_status = get_experiment_status(config.storage_dir)
95
+ if (
96
+ experiment_status
97
+ and experiment_status.status == ExperimentState.failed
98
+ ):
99
+ raise SystemExit(experiment_status.message or "Optimization failed")
100
+ if experiment_status:
101
+ print(
102
+ experiment_status.message
103
+ or "Optimization completed successfully"
104
+ )
105
+ except ErtStorageException as err:
106
+ print(f"Error reading experiment status: {err}")
88
107
 
89
108
  except TimeoutError:
90
- if server_state["status"] == ExperimentState.never_run:
91
- config_file = config.config_file
92
- print(
93
- "The optimization has not run yet.\n"
94
- "To run the optimization use command:\n"
95
- f" `everest run {config_file}`"
96
- )
97
- else:
98
- report_on_previous_run(
99
- config_file=config.config_file,
100
- everserver_status_path=status_path,
101
- optimization_output_dir=config.optimization_output_dir,
102
- )
109
+ try:
110
+ experiment_status = get_experiment_status(config.storage_dir)
111
+ if (
112
+ experiment_status is None
113
+ or experiment_status.status == ExperimentState.never_run
114
+ ):
115
+ print(
116
+ "The optimization has not run yet.\n"
117
+ "To run the optimization use command:\n"
118
+ f" `everest run {config.config_file}`"
119
+ )
120
+ elif experiment_status.status == ExperimentState.failed:
121
+ print(
122
+ "Optimization run failed, with error: "
123
+ f"{experiment_status.message}\n"
124
+ )
125
+ else:
126
+ print(
127
+ "Optimization already completed.\n"
128
+ f"Results are stored in {config.optimization_output_dir}"
129
+ )
130
+ except ErtStorageException as err:
131
+ print(f"Error reading experiment status: {err}")
103
132
 
104
133
 
105
134
  if __name__ == "__main__":
everest/bin/utils.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import argparse
2
2
  import json
3
- import logging
3
+ import logging.config
4
4
  import os
5
5
  import sys
6
6
  import traceback
@@ -23,23 +23,29 @@ from ert.ensemble_evaluator import (
23
23
  FullSnapshotEvent,
24
24
  SnapshotUpdateEvent,
25
25
  )
26
+ from ert.ensemble_evaluator.event import EndEvent
26
27
  from ert.logging import LOGGING_CONFIG
27
28
  from ert.plugins.plugin_manager import ErtPluginManager
28
- from ert.services import StorageService
29
+ from ert.services import ErtServer
30
+ from ert.storage import (
31
+ ExperimentStatus,
32
+ open_storage,
33
+ )
29
34
  from everest.config import EverestConfig
30
35
  from everest.config.server_config import ServerConfig
31
36
  from everest.detached import (
32
- ExperimentState,
33
- everserver_status,
34
37
  server_is_running,
35
38
  start_monitor,
36
39
  stop_server,
37
40
  wait_for_server_to_stop,
38
41
  )
39
- from everest.simulator import JOB_FAILURE, JOB_RUNNING, JOB_SUCCESS
40
42
  from everest.strings import EVEREST, OPT_PROGRESS_ID, SIM_PROGRESS_ID
41
43
  from everest.util import makedirs_if_needed
42
44
 
45
+ JOB_SUCCESS = "Finished"
46
+ JOB_RUNNING = "Running"
47
+ JOB_FAILURE = "Failed"
48
+
43
49
 
44
50
  def cleanup_logging() -> None:
45
51
  os.environ.pop("ERT_LOG_DIR", None)
@@ -61,22 +67,21 @@ def setup_logging(options: argparse.Namespace) -> Generator[None, None, None]:
61
67
  try:
62
68
  os.environ["ERT_LOG_DIR"] = str(log_dir)
63
69
 
64
- with open(LOGGING_CONFIG, encoding="utf-8") as log_conf_file:
65
- config_dict = yaml.safe_load(log_conf_file)
66
- if config_dict:
67
- for handler_name, handler_config in config_dict["handlers"].items():
68
- if handler_name == "file":
69
- handler_config["filename"] = "everest-log.txt"
70
- if "ert.logging.TimestampedFileHandler" in handler_config.values():
71
- handler_config["config_filename"] = ""
72
- if isinstance(options.config, EverestConfig):
73
- handler_config["config_filename"] = (
74
- options.config.config_path.name
75
- )
76
- else:
77
- # `everest branch`
78
- handler_config["config_filename"] = options.config[0]
79
- logging.config.dictConfig(config_dict)
70
+ config_dict = yaml.safe_load(LOGGING_CONFIG.read_text(encoding="utf-8"))
71
+ if config_dict:
72
+ for handler_name, handler_config in config_dict["handlers"].items():
73
+ if handler_name == "file":
74
+ handler_config["filename"] = "everest-log.txt"
75
+ if "ert.logging.TimestampedFileHandler" in handler_config.values():
76
+ handler_config["config_filename"] = ""
77
+ if isinstance(options.config, EverestConfig):
78
+ handler_config["config_filename"] = (
79
+ options.config.config_path.name
80
+ )
81
+ else:
82
+ # `everest branch`
83
+ handler_config["config_filename"] = options.config[0]
84
+ logging.config.dictConfig(config_dict)
80
85
 
81
86
  if "debug" in options and options.debug:
82
87
  root_logger = logging.getLogger()
@@ -101,7 +106,7 @@ def handle_keyboard_interrupt(signum: int, _: Any, options: argparse.Namespace)
101
106
  "The optimization will be stopped and the program will exit..."
102
107
  )
103
108
  try:
104
- client = StorageService.session(
109
+ client = ErtServer.session(
105
110
  Path(ServerConfig.get_session_dir(options.config.output_dir))
106
111
  )
107
112
  server_context = ServerConfig.get_server_context_from_conn_info(
@@ -216,6 +221,8 @@ class _DetachedMonitor:
216
221
  self._clear_lines = 0
217
222
  if SIM_PROGRESS_ID in status:
218
223
  match status[SIM_PROGRESS_ID]:
224
+ case EndEvent(msg=msg):
225
+ return
219
226
  case FullSnapshotEvent(snapshot=snapshot, iteration=batch):
220
227
  if snapshot is not None:
221
228
  self._snapshots[batch] = snapshot
@@ -372,7 +379,8 @@ class _DetachedMonitor:
372
379
  def _get_jobs_status(snapshot: EnsembleSnapshot) -> list[JobProgress]:
373
380
  job_progress = {}
374
381
  for (realization, job_idx), job in snapshot.get_all_fm_steps().items():
375
- assert "name" in job and job["name"] is not None, "job name is missing"
382
+ assert "name" in job, "job name is missing"
383
+ assert job["name"] is not None, "job name is None"
376
384
  name = job["name"]
377
385
  if job_idx not in job_progress:
378
386
  job_progress[job_idx] = JobProgress(name=name)
@@ -406,7 +414,9 @@ class _DetachedMonitor:
406
414
  print(colorama.Cursor.UP(), end=colorama.ansi.clear_line())
407
415
 
408
416
 
409
- def run_detached_monitor(server_context: tuple[str, str, tuple[str, str]]) -> None:
417
+ def run_detached_monitor(
418
+ server_context: tuple[str, str, tuple[str, str]],
419
+ ) -> None:
410
420
  monitor = _DetachedMonitor()
411
421
  start_monitor(server_context, callback=monitor.update)
412
422
 
@@ -417,30 +427,15 @@ def run_empty_detached_monitor(
417
427
  start_monitor(server_context, callback=lambda _: None)
418
428
 
419
429
 
420
- def report_on_previous_run(
421
- config_file: str,
422
- everserver_status_path: str,
423
- optimization_output_dir: str,
424
- ) -> None:
425
- server_state = everserver_status(everserver_status_path)
426
- if server_state["status"] == ExperimentState.failed:
427
- error_msg = server_state["message"]
428
- print(f"Optimization run failed, with error: {error_msg}\n")
429
- else:
430
- print(
431
- f"Optimization completed.\nResults are stored in {optimization_output_dir}"
432
- )
433
-
434
-
435
430
  def _read_user_preferences(user_info_path: Path) -> dict[str, dict[str, Any]]:
436
431
  try:
437
432
  if user_info_path.exists():
438
- with open(user_info_path, encoding="utf-8") as f:
439
- return json.load(f)
433
+ return json.loads(user_info_path.read_text(encoding="utf-8"))
440
434
 
441
435
  user_info = {EVEREST: {"show_scaling_warning": True}}
442
- with open(user_info_path, mode="w", encoding="utf-8") as f:
443
- json.dump(user_info, f, ensure_ascii=False, indent=4)
436
+ user_info_path.write_text(
437
+ json.dumps(user_info, ensure_ascii=False, indent=4), encoding="utf-8"
438
+ )
444
439
  except json.decoder.JSONDecodeError:
445
440
  return {EVEREST: {}}
446
441
  else:
@@ -477,3 +472,23 @@ def show_scaled_controls_warning() -> None:
477
472
  logging.getLogger(EVEREST).error(str(e))
478
473
  case "n":
479
474
  raise SystemExit(0)
475
+
476
+
477
+ def get_experiment_status(storage_dir: str) -> ExperimentStatus | None:
478
+ """
479
+ Reads the experiment status from storage. We assume that there is
480
+ only one experiment for each everest run in storage.
481
+ """
482
+ with open_storage(storage_dir, "r") as storage:
483
+ experiments = list(storage.experiments)
484
+ return None if not experiments else experiments[0].status
485
+
486
+
487
+ class ArgParseFormatter(argparse.HelpFormatter):
488
+ def _fill_text(self, text: str, width: int, indent: str) -> str:
489
+ return "\n\n".join(
490
+ [
491
+ argparse.HelpFormatter._fill_text(self, p, width, indent)
492
+ for p in text.split("\n\n")
493
+ ]
494
+ )
@@ -1,28 +1,43 @@
1
- #!/usr/bin/env python
2
-
3
1
  import argparse
4
2
  import logging
5
3
  import sys
6
4
  from functools import partial
7
5
  from pathlib import Path
6
+ from textwrap import dedent
8
7
 
9
- from ert.storage import ErtStorageException, open_storage
8
+ from ert.storage import LocalStorage
10
9
  from everest.api import EverestDataAPI
11
10
  from everest.bin.utils import setup_logging
12
11
  from everest.config import EverestConfig
13
12
  from everest.everest_storage import EverestStorage
14
13
  from everest.plugins.everest_plugin_manager import EverestPluginManager
15
14
 
15
+ from .utils import ArgParseFormatter
16
+
16
17
 
17
18
  def _build_args_parser() -> argparse.ArgumentParser:
18
19
  arg_parser = argparse.ArgumentParser(
19
- description="Start possible plugin containing everest visualization",
20
+ description=dedent(
21
+ """
22
+ Start an everest visualization plugin.
23
+
24
+ If no visualization plugin is installed the message: ``No
25
+ visualization plugin installed!`` will be displayed in the console.
26
+
27
+ The recommended open-source everest visualization plugin is Everviz:
28
+
29
+ https://github.com/equinor/everviz
30
+
31
+ It can be installed using ``pip install everviz``.
32
+ """
33
+ ),
34
+ formatter_class=ArgParseFormatter,
20
35
  usage="""everest results <config_file>""",
21
36
  )
22
37
  arg_parser.add_argument(
23
38
  "config",
24
39
  type=partial(EverestConfig.load_file_with_argparser, parser=arg_parser),
25
- help="The path to the everest configuration file",
40
+ help="The path to the everest configuration file.",
26
41
  )
27
42
  return arg_parser
28
43
 
@@ -38,14 +53,9 @@ def visualization_entry(args: list[str] | None = None) -> None:
38
53
  ever_config.optimization_output_dir
39
54
  )
40
55
 
41
- try:
42
- # If successful, no need to migrate
43
- open_storage(ever_config.storage_dir, mode="r").close()
44
- except ErtStorageException as err:
45
- if "too old" in str(err):
46
- # Open write storage to do a migration
47
- logger.info("Migrating ERT storage from everviz entrypoint")
48
- open_storage(ever_config.storage_dir, mode="w").close()
56
+ if LocalStorage.check_migration_needed(Path(ever_config.storage_dir)):
57
+ logger.info("Migrating ERT storage from everviz entrypoint")
58
+ LocalStorage.perform_migration(Path(ever_config.storage_dir))
49
59
 
50
60
  storage = EverestStorage(output_dir=Path(ever_config.optimization_output_dir))
51
61
  storage.read_from_output_dir()
@@ -1,3 +1,5 @@
1
+ from ert.config import SamplerConfig
2
+
1
3
  from .control_config import ControlConfig
2
4
  from .control_variable_config import (
3
5
  ControlVariableConfig,
@@ -6,6 +8,7 @@ from .control_variable_config import (
6
8
  from .cvar_config import CVaRConfig
7
9
  from .environment_config import EnvironmentConfig
8
10
  from .everest_config import EverestConfig, EverestValidationError
11
+ from .forward_model_config import ForwardModelStepConfig
9
12
  from .input_constraint_config import InputConstraintConfig
10
13
  from .install_data_config import InstallDataConfig
11
14
  from .install_job_config import InstallJobConfig
@@ -14,7 +17,6 @@ from .model_config import ModelConfig
14
17
  from .objective_function_config import ObjectiveFunctionConfig
15
18
  from .optimization_config import OptimizationConfig
16
19
  from .output_constraint_config import OutputConstraintConfig
17
- from .sampler_config import SamplerConfig
18
20
  from .server_config import ServerConfig
19
21
  from .simulator_config import SimulatorConfig
20
22
  from .well_config import WellConfig
@@ -28,6 +30,7 @@ __all__ = [
28
30
  "EnvironmentConfig",
29
31
  "EverestConfig",
30
32
  "EverestValidationError",
33
+ "ForwardModelStepConfig",
31
34
  "InputConstraintConfig",
32
35
  "InstallDataConfig",
33
36
  "InstallJobConfig",