ert 17.1.9__py3-none-any.whl → 18.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.
- _ert/events.py +19 -2
- ert/__main__.py +8 -7
- ert/analysis/_update_commons.py +12 -3
- ert/cli/main.py +6 -3
- ert/cli/monitor.py +7 -0
- ert/config/__init__.py +13 -3
- ert/config/_create_observation_dataframes.py +60 -12
- ert/config/_observations.py +14 -1
- ert/config/_read_summary.py +8 -6
- ert/config/ensemble_config.py +6 -14
- ert/config/ert_config.py +19 -13
- ert/config/{everest_objective_config.py → everest_response.py} +23 -12
- ert/config/ext_param_config.py +133 -1
- ert/config/field.py +12 -8
- ert/config/forward_model_step.py +108 -6
- ert/config/gen_data_config.py +2 -6
- ert/config/gen_kw_config.py +0 -9
- ert/config/known_response_types.py +14 -0
- ert/config/parameter_config.py +0 -17
- ert/config/parsing/config_keywords.py +1 -0
- ert/config/parsing/config_schema.py +12 -0
- ert/config/parsing/config_schema_deprecations.py +11 -0
- ert/config/parsing/config_schema_item.py +1 -1
- ert/config/queue_config.py +4 -4
- ert/config/response_config.py +0 -7
- ert/config/rft_config.py +230 -0
- ert/config/summary_config.py +2 -6
- ert/config/violations.py +0 -0
- ert/config/workflow_fixtures.py +2 -1
- ert/dark_storage/client/__init__.py +2 -2
- ert/dark_storage/client/_session.py +4 -4
- ert/dark_storage/client/client.py +2 -2
- ert/dark_storage/compute/misfits.py +7 -6
- ert/dark_storage/endpoints/compute/misfits.py +2 -2
- ert/dark_storage/endpoints/observations.py +4 -4
- ert/dark_storage/endpoints/responses.py +15 -1
- ert/ensemble_evaluator/__init__.py +8 -1
- ert/ensemble_evaluator/evaluator.py +81 -29
- ert/ensemble_evaluator/event.py +6 -0
- ert/ensemble_evaluator/snapshot.py +3 -1
- ert/ensemble_evaluator/state.py +1 -0
- ert/field_utils/__init__.py +8 -0
- ert/field_utils/field_utils.py +211 -1
- ert/gui/ertwidgets/__init__.py +23 -16
- ert/gui/ertwidgets/analysismoduleedit.py +2 -2
- ert/gui/ertwidgets/checklist.py +1 -1
- ert/gui/ertwidgets/create_experiment_dialog.py +3 -1
- ert/gui/ertwidgets/ensembleselector.py +2 -2
- ert/gui/ertwidgets/models/__init__.py +2 -0
- ert/gui/ertwidgets/models/activerealizationsmodel.py +2 -1
- ert/gui/ertwidgets/models/path_model.py +1 -1
- ert/gui/ertwidgets/models/targetensemblemodel.py +2 -1
- ert/gui/ertwidgets/models/text_model.py +1 -1
- ert/gui/ertwidgets/searchbox.py +13 -4
- ert/gui/{suggestor → ertwidgets/suggestor}/_suggestor_message.py +13 -4
- ert/gui/main.py +11 -6
- ert/gui/main_window.py +1 -2
- ert/gui/simulation/ensemble_experiment_panel.py +1 -1
- ert/gui/simulation/ensemble_information_filter_panel.py +1 -1
- ert/gui/simulation/ensemble_smoother_panel.py +1 -1
- ert/gui/simulation/evaluate_ensemble_panel.py +1 -1
- ert/gui/simulation/experiment_panel.py +1 -1
- ert/gui/simulation/manual_update_panel.py +31 -8
- ert/gui/simulation/multiple_data_assimilation_panel.py +12 -8
- ert/gui/simulation/run_dialog.py +25 -4
- ert/gui/simulation/single_test_run_panel.py +2 -2
- ert/gui/summarypanel.py +1 -1
- ert/gui/tools/load_results/load_results_panel.py +1 -1
- ert/gui/tools/manage_experiments/storage_info_widget.py +7 -7
- ert/gui/tools/manage_experiments/storage_widget.py +1 -2
- ert/gui/tools/plot/plot_api.py +13 -10
- ert/gui/tools/plot/plot_window.py +12 -0
- ert/gui/tools/plot/plottery/plot_config.py +2 -0
- ert/gui/tools/plot/plottery/plot_context.py +14 -0
- ert/gui/tools/plot/plottery/plots/ensemble.py +9 -2
- ert/gui/tools/plot/plottery/plots/statistics.py +59 -19
- ert/mode_definitions.py +2 -0
- ert/plugins/__init__.py +0 -1
- ert/plugins/hook_implementations/workflows/gen_data_rft_export.py +10 -2
- ert/plugins/hook_specifications/__init__.py +0 -2
- ert/plugins/hook_specifications/jobs.py +0 -9
- ert/plugins/plugin_manager.py +2 -33
- ert/resources/shell_scripts/delete_directory.py +2 -2
- ert/run_models/__init__.py +18 -5
- ert/run_models/_create_run_path.py +33 -21
- ert/run_models/ensemble_experiment.py +10 -4
- ert/run_models/ensemble_information_filter.py +8 -1
- ert/run_models/ensemble_smoother.py +9 -3
- ert/run_models/evaluate_ensemble.py +8 -6
- ert/run_models/event.py +7 -3
- ert/run_models/everest_run_model.py +155 -44
- ert/run_models/initial_ensemble_run_model.py +23 -22
- ert/run_models/manual_update.py +4 -2
- ert/run_models/manual_update_enif.py +37 -0
- ert/run_models/model_factory.py +81 -22
- ert/run_models/multiple_data_assimilation.py +21 -10
- ert/run_models/run_model.py +54 -34
- ert/run_models/single_test_run.py +7 -4
- ert/run_models/update_run_model.py +4 -2
- ert/runpaths.py +5 -6
- ert/sample_prior.py +9 -4
- ert/scheduler/driver.py +37 -0
- ert/scheduler/event.py +3 -1
- ert/scheduler/job.py +23 -13
- ert/scheduler/lsf_driver.py +6 -2
- ert/scheduler/openpbs_driver.py +7 -1
- ert/scheduler/scheduler.py +5 -0
- ert/scheduler/slurm_driver.py +6 -2
- ert/services/__init__.py +2 -2
- ert/services/_base_service.py +31 -15
- ert/services/ert_server.py +317 -0
- ert/shared/_doc_utils/ert_jobs.py +1 -4
- ert/shared/storage/connection.py +3 -3
- ert/shared/version.py +3 -3
- ert/storage/local_ensemble.py +25 -5
- ert/storage/local_experiment.py +6 -14
- ert/storage/local_storage.py +35 -30
- ert/storage/migration/to18.py +12 -0
- ert/storage/migration/to8.py +4 -4
- ert/substitutions.py +12 -28
- ert/validation/active_range.py +7 -7
- ert/validation/rangestring.py +16 -16
- {ert-17.1.9.dist-info → ert-18.0.0.dist-info}/METADATA +8 -7
- {ert-17.1.9.dist-info → ert-18.0.0.dist-info}/RECORD +160 -159
- everest/api/everest_data_api.py +1 -14
- everest/bin/config_branch_script.py +3 -6
- everest/bin/everconfigdump_script.py +1 -9
- everest/bin/everest_script.py +21 -11
- everest/bin/kill_script.py +2 -2
- everest/bin/monitor_script.py +2 -2
- everest/bin/utils.py +6 -3
- everest/config/__init__.py +4 -1
- everest/config/control_config.py +61 -2
- everest/config/control_variable_config.py +2 -1
- everest/config/everest_config.py +38 -16
- everest/config/forward_model_config.py +5 -3
- everest/config/install_data_config.py +7 -5
- everest/config/install_job_config.py +7 -3
- everest/config/install_template_config.py +3 -3
- everest/config/optimization_config.py +19 -6
- everest/config/output_constraint_config.py +8 -2
- everest/config/server_config.py +6 -49
- everest/config/utils.py +25 -105
- everest/config/validation_utils.py +10 -10
- everest/config_file_loader.py +13 -2
- everest/detached/everserver.py +7 -8
- everest/everest_storage.py +6 -10
- everest/gui/everest_client.py +0 -1
- everest/gui/main_window.py +2 -2
- everest/optimizer/everest2ropt.py +59 -32
- everest/optimizer/opt_model_transforms.py +12 -13
- everest/optimizer/utils.py +0 -29
- everest/strings.py +0 -5
- ert/config/everest_constraints_config.py +0 -95
- ert/services/storage_service.py +0 -127
- everest/config/sampler_config.py +0 -103
- everest/simulator/__init__.py +0 -88
- everest/simulator/everest_to_ert.py +0 -51
- /ert/gui/{suggestor → ertwidgets/suggestor}/__init__.py +0 -0
- /ert/gui/{suggestor → ertwidgets/suggestor}/_colors.py +0 -0
- /ert/gui/{suggestor → ertwidgets/suggestor}/suggestor.py +0 -0
- {ert-17.1.9.dist-info → ert-18.0.0.dist-info}/WHEEL +0 -0
- {ert-17.1.9.dist-info → ert-18.0.0.dist-info}/entry_points.txt +0 -0
- {ert-17.1.9.dist-info → ert-18.0.0.dist-info}/licenses/COPYING +0 -0
- {ert-17.1.9.dist-info → ert-18.0.0.dist-info}/top_level.txt +0 -0
|
@@ -17,21 +17,22 @@ from enum import IntEnum, auto
|
|
|
17
17
|
from functools import cached_property
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from types import TracebackType
|
|
20
|
-
from typing import TYPE_CHECKING, Any, Protocol
|
|
20
|
+
from typing import TYPE_CHECKING, Any, Protocol, cast
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
from numpy.typing import NDArray
|
|
24
24
|
from pydantic import PrivateAttr, ValidationError
|
|
25
25
|
from ropt.enums import ExitCode as RoptExitCode
|
|
26
26
|
from ropt.evaluator import EvaluatorContext, EvaluatorResult
|
|
27
|
-
from ropt.plan import BasicOptimizer
|
|
28
27
|
from ropt.results import FunctionResults, Results
|
|
29
28
|
from ropt.transforms import OptModelTransforms
|
|
29
|
+
from ropt.workflow import BasicOptimizer
|
|
30
30
|
from typing_extensions import TypedDict
|
|
31
31
|
|
|
32
32
|
from ert.config import (
|
|
33
33
|
EverestConstraintsConfig,
|
|
34
34
|
EverestObjectivesConfig,
|
|
35
|
+
ExtParamConfig,
|
|
35
36
|
GenDataConfig,
|
|
36
37
|
HookRuntime,
|
|
37
38
|
KnownQueueOptionsAdapter,
|
|
@@ -57,18 +58,14 @@ from everest.config import (
|
|
|
57
58
|
InputConstraintConfig,
|
|
58
59
|
ModelConfig,
|
|
59
60
|
OptimizationConfig,
|
|
60
|
-
OutputConstraintConfig,
|
|
61
61
|
)
|
|
62
|
-
from everest.config.forward_model_config import SummaryResults
|
|
62
|
+
from everest.config.forward_model_config import ForwardModelStepConfig, SummaryResults
|
|
63
63
|
from everest.everest_storage import EverestStorage
|
|
64
64
|
from everest.optimizer.everest2ropt import everest2ropt
|
|
65
65
|
from everest.optimizer.opt_model_transforms import (
|
|
66
66
|
EverestOptModelTransforms,
|
|
67
67
|
get_optimization_domain_transforms,
|
|
68
68
|
)
|
|
69
|
-
from everest.simulator.everest_to_ert import (
|
|
70
|
-
extract_summary_keys,
|
|
71
|
-
)
|
|
72
69
|
from everest.strings import EVEREST
|
|
73
70
|
|
|
74
71
|
from ..run_arg import RunArg, create_run_arguments
|
|
@@ -76,7 +73,7 @@ from ..storage import ExperimentState, ExperimentStatus
|
|
|
76
73
|
from ..storage.local_ensemble import EverestRealizationInfo
|
|
77
74
|
from ..substitutions import Substitutions
|
|
78
75
|
from .event import EverestBatchResultEvent, EverestStatusEvent
|
|
79
|
-
from .run_model import RunModel, StatusEvents
|
|
76
|
+
from .run_model import RunModel, RunModelConfig, StatusEvents
|
|
80
77
|
|
|
81
78
|
if TYPE_CHECKING:
|
|
82
79
|
from ert.storage import Ensemble, Experiment
|
|
@@ -225,24 +222,22 @@ def _get_workflows(
|
|
|
225
222
|
return res_hooks, res_workflows
|
|
226
223
|
|
|
227
224
|
|
|
228
|
-
class
|
|
225
|
+
class EverestRunModelConfig(RunModelConfig):
|
|
229
226
|
optimization_output_dir: str
|
|
230
227
|
simulation_dir: str
|
|
231
228
|
|
|
232
229
|
parameter_configuration: list[ParameterConfig]
|
|
233
230
|
response_configuration: list[ResponseConfig]
|
|
234
|
-
controls: list[ControlConfig]
|
|
235
231
|
|
|
236
232
|
input_constraints: list[InputConstraintConfig]
|
|
237
|
-
|
|
238
|
-
output_constraints: list[OutputConstraintConfig]
|
|
239
|
-
|
|
240
233
|
optimization: OptimizationConfig
|
|
241
234
|
model: ModelConfig
|
|
242
235
|
keep_run_path: bool
|
|
243
236
|
experiment_name: str
|
|
244
237
|
target_ensemble: str
|
|
245
238
|
|
|
239
|
+
|
|
240
|
+
class EverestRunModel(RunModel, EverestRunModelConfig):
|
|
246
241
|
_exit_code: EverestExitCode | None = PrivateAttr(default=None)
|
|
247
242
|
_experiment: Experiment | None = PrivateAttr(default=None)
|
|
248
243
|
_eval_server_cfg: EvaluatorServerConfig | None = PrivateAttr(default=None)
|
|
@@ -297,15 +292,9 @@ class EverestRunModel(RunModel):
|
|
|
297
292
|
|
|
298
293
|
response_configs.append(everest_config.create_ert_objectives_config())
|
|
299
294
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
response_configs.append(
|
|
304
|
-
EverestConstraintsConfig(
|
|
305
|
-
keys=constraint_names,
|
|
306
|
-
input_files=constraint_names,
|
|
307
|
-
)
|
|
308
|
-
)
|
|
295
|
+
constraints_config = everest_config.create_ert_output_constraints_config()
|
|
296
|
+
if constraints_config is not None:
|
|
297
|
+
response_configs.append(constraints_config)
|
|
309
298
|
|
|
310
299
|
gen_data_keys = [
|
|
311
300
|
fm.results.file_name
|
|
@@ -327,7 +316,7 @@ class EverestRunModel(RunModel):
|
|
|
327
316
|
eclbase = summary_fm.results.file_name
|
|
328
317
|
response_configs.append(
|
|
329
318
|
SummaryConfig(
|
|
330
|
-
keys=
|
|
319
|
+
keys=_extract_summary_keys(everest_config), input_files=[eclbase]
|
|
331
320
|
)
|
|
332
321
|
)
|
|
333
322
|
else:
|
|
@@ -340,7 +329,7 @@ class EverestRunModel(RunModel):
|
|
|
340
329
|
runpath_format_string=str(
|
|
341
330
|
Path(everest_config.simulation_dir)
|
|
342
331
|
/ "batch_<ITER>"
|
|
343
|
-
/ "realization_<
|
|
332
|
+
/ "realization_<REALIZATION_ID>"
|
|
344
333
|
/ "<SIM_DIR>"
|
|
345
334
|
),
|
|
346
335
|
eclbase_format_string=eclbase
|
|
@@ -382,7 +371,7 @@ class EverestRunModel(RunModel):
|
|
|
382
371
|
# Only take into account site queue options
|
|
383
372
|
# if and only if they exist and are of same type as user
|
|
384
373
|
# specified queue system
|
|
385
|
-
|
|
374
|
+
site_queue_options_to_apply = (
|
|
386
375
|
runtime_plugins.queue_options.model_dump(exclude_unset=True)
|
|
387
376
|
if (
|
|
388
377
|
runtime_plugins is not None
|
|
@@ -393,7 +382,7 @@ class EverestRunModel(RunModel):
|
|
|
393
382
|
else {}
|
|
394
383
|
)
|
|
395
384
|
|
|
396
|
-
queue_options_dict =
|
|
385
|
+
queue_options_dict = site_queue_options_to_apply | queue_options_from_everconfig
|
|
397
386
|
|
|
398
387
|
queue_options = KnownQueueOptionsAdapter.validate_python(queue_options_dict)
|
|
399
388
|
|
|
@@ -521,7 +510,6 @@ class EverestRunModel(RunModel):
|
|
|
521
510
|
objective_names=everest_config.objective_names,
|
|
522
511
|
objective_functions=everest_config.objective_functions,
|
|
523
512
|
input_constraints=everest_config.input_constraints,
|
|
524
|
-
output_constraints=everest_config.output_constraints,
|
|
525
513
|
optimization=everest_config.optimization,
|
|
526
514
|
model=everest_config.model,
|
|
527
515
|
optimization_output_dir=everest_config.optimization_output_dir,
|
|
@@ -546,13 +534,23 @@ class EverestRunModel(RunModel):
|
|
|
546
534
|
optimization_callback=optimization_callback,
|
|
547
535
|
)
|
|
548
536
|
|
|
537
|
+
@property
|
|
538
|
+
def ext_param_configs(self) -> list[ExtParamConfig]:
|
|
539
|
+
ext_params = [
|
|
540
|
+
c for c in self.parameter_configuration if c.type == "everest_parameters"
|
|
541
|
+
]
|
|
542
|
+
|
|
543
|
+
# There will and must always be one extparam config for an
|
|
544
|
+
# Everest optimization.
|
|
545
|
+
return cast(list[ExtParamConfig], ext_params)
|
|
546
|
+
|
|
549
547
|
@cached_property
|
|
550
548
|
def _transforms(self) -> EverestOptModelTransforms:
|
|
551
549
|
return get_optimization_domain_transforms(
|
|
552
|
-
self.
|
|
550
|
+
self.ext_param_configs,
|
|
553
551
|
self.objectives_config,
|
|
554
552
|
self.input_constraints,
|
|
555
|
-
self.
|
|
553
|
+
self.output_constraints_config,
|
|
556
554
|
self.model,
|
|
557
555
|
self.optimization.auto_scale,
|
|
558
556
|
)
|
|
@@ -646,6 +644,19 @@ class EverestRunModel(RunModel):
|
|
|
646
644
|
)
|
|
647
645
|
)
|
|
648
646
|
|
|
647
|
+
@property
|
|
648
|
+
def output_constraints_config(self) -> EverestConstraintsConfig | None:
|
|
649
|
+
constraints_config = next(
|
|
650
|
+
(c for c in self.response_configuration if c.type == "everest_constraints"),
|
|
651
|
+
None,
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
if constraints_config is None:
|
|
655
|
+
return None
|
|
656
|
+
|
|
657
|
+
assert isinstance(constraints_config, EverestConstraintsConfig)
|
|
658
|
+
return constraints_config
|
|
659
|
+
|
|
649
660
|
@property
|
|
650
661
|
def objectives_config(self) -> EverestObjectivesConfig:
|
|
651
662
|
obj_config = next(
|
|
@@ -682,18 +693,18 @@ class EverestRunModel(RunModel):
|
|
|
682
693
|
)
|
|
683
694
|
|
|
684
695
|
formatted_control_names = [
|
|
685
|
-
name for config in self.
|
|
696
|
+
name for config in self.ext_param_configs for name in config.input_keys
|
|
686
697
|
]
|
|
687
698
|
self._ever_storage.init(
|
|
688
699
|
formatted_control_names=formatted_control_names,
|
|
689
700
|
objective_functions=self.objectives_config,
|
|
690
|
-
output_constraints=self.
|
|
701
|
+
output_constraints=self.output_constraints_config,
|
|
691
702
|
realizations=self.model.realizations,
|
|
692
703
|
)
|
|
693
704
|
optimizer.set_results_callback(self._handle_optimizer_results)
|
|
694
705
|
|
|
695
706
|
# Run the optimization:
|
|
696
|
-
optimizer_exit_code = optimizer.run(initial_guesses)
|
|
707
|
+
optimizer_exit_code = optimizer.run(initial_guesses)
|
|
697
708
|
|
|
698
709
|
# Store some final results.
|
|
699
710
|
self._ever_storage.on_optimization_finished()
|
|
@@ -751,10 +762,10 @@ class EverestRunModel(RunModel):
|
|
|
751
762
|
|
|
752
763
|
def _create_optimizer(self) -> tuple[BasicOptimizer, list[float]]:
|
|
753
764
|
enopt_config, initial_guesses = everest2ropt(
|
|
754
|
-
self.
|
|
765
|
+
cast(list[ExtParamConfig], self.parameter_configuration),
|
|
755
766
|
self.objectives_config,
|
|
756
767
|
self.input_constraints,
|
|
757
|
-
self.
|
|
768
|
+
self.output_constraints_config,
|
|
758
769
|
self.optimization,
|
|
759
770
|
self.model,
|
|
760
771
|
self.random_seed,
|
|
@@ -821,12 +832,7 @@ class EverestRunModel(RunModel):
|
|
|
821
832
|
for sim_id in range(sim_to_control_vector.shape[0]):
|
|
822
833
|
sim_controls = sim_to_control_vector[sim_id]
|
|
823
834
|
offset = 0
|
|
824
|
-
for
|
|
825
|
-
ext_param_config = next(
|
|
826
|
-
c
|
|
827
|
-
for c in self.parameter_configuration
|
|
828
|
-
if c.name == control_config.name
|
|
829
|
-
)
|
|
835
|
+
for ext_param_config in self.ext_param_configs:
|
|
830
836
|
n_param_keys = len(ext_param_config.parameter_keys)
|
|
831
837
|
|
|
832
838
|
# Save controls to ensemble
|
|
@@ -1004,10 +1010,10 @@ class EverestRunModel(RunModel):
|
|
|
1004
1010
|
)
|
|
1005
1011
|
constraints = (
|
|
1006
1012
|
np.zeros(
|
|
1007
|
-
(num_all_simulations, len(self.
|
|
1013
|
+
(num_all_simulations, len(self.output_constraints_config.keys)),
|
|
1008
1014
|
dtype=np.float64,
|
|
1009
1015
|
)
|
|
1010
|
-
if self.
|
|
1016
|
+
if self.output_constraints_config
|
|
1011
1017
|
else None
|
|
1012
1018
|
)
|
|
1013
1019
|
sim_ids = np.array([-1] * num_all_simulations, dtype=np.int32)
|
|
@@ -1070,7 +1076,7 @@ class EverestRunModel(RunModel):
|
|
|
1070
1076
|
for sim_id, (model_realization, perturbation) in enumerate(
|
|
1071
1077
|
zip(sim_to_model_realization, sim_to_perturbation, strict=True)
|
|
1072
1078
|
):
|
|
1073
|
-
substitutions[f"<
|
|
1079
|
+
substitutions[f"<REALIZATION_ID_{sim_id}_{ensemble.iteration}>"] = str(
|
|
1074
1080
|
int(model_realization)
|
|
1075
1081
|
)
|
|
1076
1082
|
if perturbation >= 0:
|
|
@@ -1120,7 +1126,11 @@ class EverestRunModel(RunModel):
|
|
|
1120
1126
|
objective_names = self.objectives_config.keys
|
|
1121
1127
|
objectives = np.zeros((ensemble.ensemble_size, len(objective_names)))
|
|
1122
1128
|
|
|
1123
|
-
constraint_names =
|
|
1129
|
+
constraint_names = (
|
|
1130
|
+
self.output_constraints_config.keys
|
|
1131
|
+
if self.output_constraints_config is not None
|
|
1132
|
+
else []
|
|
1133
|
+
)
|
|
1124
1134
|
constraints = np.zeros((ensemble.ensemble_size, len(constraint_names)))
|
|
1125
1135
|
|
|
1126
1136
|
if not any(self.active_realizations):
|
|
@@ -1157,3 +1167,104 @@ class EverestRunModel(RunModel):
|
|
|
1157
1167
|
return os.path.exists(self.simulation_dir) and any(
|
|
1158
1168
|
os.listdir(self.simulation_dir)
|
|
1159
1169
|
)
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
def _extract_summary_keys(ever_config: EverestConfig) -> list[str]:
|
|
1173
|
+
DEFAULT_DATA_SUMMARY_KEYS = ["YEAR", "YEARS", "TCPU", "TCPUDAY", "MONTH", "DAY"]
|
|
1174
|
+
|
|
1175
|
+
DEFAULT_FIELD_SUMMARY_KEYS = [
|
|
1176
|
+
"FOPR",
|
|
1177
|
+
"FOPT",
|
|
1178
|
+
"FOIR",
|
|
1179
|
+
"FOIT",
|
|
1180
|
+
"FWPR",
|
|
1181
|
+
"FWPT",
|
|
1182
|
+
"FWIR",
|
|
1183
|
+
"FWIT",
|
|
1184
|
+
"FGPR",
|
|
1185
|
+
"FGPT",
|
|
1186
|
+
"FGIR",
|
|
1187
|
+
"FGIT",
|
|
1188
|
+
"FVPR",
|
|
1189
|
+
"FVPT",
|
|
1190
|
+
"FVIR",
|
|
1191
|
+
"FVIT",
|
|
1192
|
+
"FWCT",
|
|
1193
|
+
"FGOR",
|
|
1194
|
+
"FOIP",
|
|
1195
|
+
"FOIPL",
|
|
1196
|
+
"FOIPG",
|
|
1197
|
+
"FWIP",
|
|
1198
|
+
"FGIP",
|
|
1199
|
+
"FGIPL",
|
|
1200
|
+
"FGIPG",
|
|
1201
|
+
"FPR",
|
|
1202
|
+
"FAQR",
|
|
1203
|
+
"FAQRG",
|
|
1204
|
+
"FAQT",
|
|
1205
|
+
"FAQTG",
|
|
1206
|
+
"FWGR",
|
|
1207
|
+
]
|
|
1208
|
+
|
|
1209
|
+
DEFAULT_WELL_SUMMARY_KEYS = [
|
|
1210
|
+
"WOPR",
|
|
1211
|
+
"WOPT",
|
|
1212
|
+
"WOIR",
|
|
1213
|
+
"WOIT",
|
|
1214
|
+
"WWPR",
|
|
1215
|
+
"WWPT",
|
|
1216
|
+
"WWIR",
|
|
1217
|
+
"WWIT",
|
|
1218
|
+
"WGPR",
|
|
1219
|
+
"WGPT",
|
|
1220
|
+
"WGIR",
|
|
1221
|
+
"WGIT",
|
|
1222
|
+
"WVPR",
|
|
1223
|
+
"WVPT",
|
|
1224
|
+
"WVIR",
|
|
1225
|
+
"WVIT",
|
|
1226
|
+
"WWCT",
|
|
1227
|
+
"WGOR",
|
|
1228
|
+
"WWGR",
|
|
1229
|
+
"WBHP",
|
|
1230
|
+
"WTHP",
|
|
1231
|
+
"WPI",
|
|
1232
|
+
]
|
|
1233
|
+
|
|
1234
|
+
DEFAULT_WELL_TARGET_SUMMARY_KEYS = [
|
|
1235
|
+
well_key + "T"
|
|
1236
|
+
for well_key in DEFAULT_WELL_SUMMARY_KEYS
|
|
1237
|
+
if well_key.endswith("R") and well_key != "WGOR"
|
|
1238
|
+
]
|
|
1239
|
+
|
|
1240
|
+
summary_fms: list[ForwardModelStepConfig] = [
|
|
1241
|
+
fm
|
|
1242
|
+
for fm in ever_config.forward_model
|
|
1243
|
+
if fm.results is not None and fm.results.type == "summary"
|
|
1244
|
+
]
|
|
1245
|
+
|
|
1246
|
+
if not summary_fms:
|
|
1247
|
+
return []
|
|
1248
|
+
|
|
1249
|
+
smry_results = summary_fms[0].results
|
|
1250
|
+
assert isinstance(smry_results, SummaryResults)
|
|
1251
|
+
|
|
1252
|
+
requested_keys: list[str] = ["*"] if smry_results.keys == "*" else smry_results.keys
|
|
1253
|
+
|
|
1254
|
+
well_keys = [
|
|
1255
|
+
f"{sum_key}:*"
|
|
1256
|
+
for sum_key in DEFAULT_WELL_SUMMARY_KEYS + DEFAULT_WELL_TARGET_SUMMARY_KEYS
|
|
1257
|
+
]
|
|
1258
|
+
deprecated_user_specified_keys = (
|
|
1259
|
+
[] if ever_config.export is None else ever_config.export.keywords
|
|
1260
|
+
)
|
|
1261
|
+
|
|
1262
|
+
return list(
|
|
1263
|
+
set(
|
|
1264
|
+
requested_keys
|
|
1265
|
+
+ DEFAULT_DATA_SUMMARY_KEYS
|
|
1266
|
+
+ DEFAULT_FIELD_SUMMARY_KEYS
|
|
1267
|
+
+ well_keys
|
|
1268
|
+
+ deprecated_user_specified_keys
|
|
1269
|
+
)
|
|
1270
|
+
)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from abc import ABC
|
|
2
1
|
from typing import Annotated, Any, Literal, Self
|
|
3
2
|
|
|
4
3
|
import numpy as np
|
|
@@ -7,26 +6,24 @@ from polars.datatypes import DataTypeClass
|
|
|
7
6
|
from pydantic import BaseModel, Field, field_validator
|
|
8
7
|
|
|
9
8
|
from ert.config import (
|
|
10
|
-
EverestConstraintsConfig,
|
|
11
|
-
EverestObjectivesConfig,
|
|
12
9
|
ExtParamConfig,
|
|
13
|
-
GenDataConfig,
|
|
14
10
|
GenKwConfig,
|
|
15
|
-
|
|
11
|
+
KnownResponseTypes,
|
|
16
12
|
SurfaceConfig,
|
|
17
13
|
)
|
|
18
14
|
from ert.config import Field as FieldConfig
|
|
19
15
|
from ert.ensemble_evaluator.config import EvaluatorServerConfig
|
|
20
16
|
from ert.run_arg import create_run_arguments
|
|
21
|
-
from ert.run_models.run_model import RunModel
|
|
17
|
+
from ert.run_models.run_model import RunModel, RunModelConfig
|
|
22
18
|
from ert.sample_prior import sample_prior
|
|
23
19
|
from ert.storage.local_ensemble import LocalEnsemble
|
|
24
20
|
|
|
25
|
-
|
|
26
21
|
# https://github.com/pola-rs/polars/issues/13152#issuecomment-1864600078
|
|
27
22
|
# PS: Serializing/deserializing schema is scheduled to be added to polars core,
|
|
28
23
|
# ref https://github.com/pola-rs/polars/issues/20426
|
|
29
24
|
# then this workaround can be omitted.
|
|
25
|
+
|
|
26
|
+
|
|
30
27
|
def str_to_dtype(dtype_str: str) -> pl.DataType:
|
|
31
28
|
dtype = eval(f"pl.{dtype_str}")
|
|
32
29
|
if isinstance(dtype, DataTypeClass):
|
|
@@ -54,7 +51,7 @@ class DictEncodedDataFrame(BaseModel):
|
|
|
54
51
|
)
|
|
55
52
|
|
|
56
53
|
|
|
57
|
-
class
|
|
54
|
+
class InitialEnsembleRunModelConfig(RunModelConfig):
|
|
58
55
|
experiment_name: str
|
|
59
56
|
design_matrix: DictEncodedDataFrame | None
|
|
60
57
|
parameter_configuration: list[
|
|
@@ -65,31 +62,35 @@ class InitialEnsembleRunModel(RunModel, ABC):
|
|
|
65
62
|
]
|
|
66
63
|
response_configuration: list[
|
|
67
64
|
Annotated[
|
|
68
|
-
(
|
|
69
|
-
GenDataConfig
|
|
70
|
-
| SummaryConfig
|
|
71
|
-
| EverestConstraintsConfig
|
|
72
|
-
| EverestObjectivesConfig
|
|
73
|
-
),
|
|
65
|
+
(KnownResponseTypes),
|
|
74
66
|
Field(discriminator="type"),
|
|
75
67
|
]
|
|
76
68
|
]
|
|
77
69
|
ert_templates: list[tuple[str, str]]
|
|
78
|
-
observations: dict[str, DictEncodedDataFrame] | None
|
|
70
|
+
observations: dict[str, DictEncodedDataFrame] | None = None
|
|
79
71
|
|
|
80
72
|
@field_validator("observations", mode="before")
|
|
73
|
+
@classmethod
|
|
81
74
|
def make_dict_encoded_observations(
|
|
82
|
-
cls, v: dict[str, pl.DataFrame | DictEncodedDataFrame] | None
|
|
75
|
+
cls, v: dict[str, pl.DataFrame | DictEncodedDataFrame | dict[str, Any]] | None
|
|
83
76
|
) -> dict[str, DictEncodedDataFrame] | None:
|
|
84
77
|
if v is None:
|
|
85
78
|
return None
|
|
86
|
-
return {
|
|
87
|
-
k: df
|
|
88
|
-
if isinstance(df, DictEncodedDataFrame)
|
|
89
|
-
else DictEncodedDataFrame.from_polars(df)
|
|
90
|
-
for k, df in v.items()
|
|
91
|
-
}
|
|
92
79
|
|
|
80
|
+
encoded = {}
|
|
81
|
+
for k, df in v.items():
|
|
82
|
+
match df:
|
|
83
|
+
case DictEncodedDataFrame():
|
|
84
|
+
encoded[k] = df
|
|
85
|
+
case pl.DataFrame():
|
|
86
|
+
encoded[k] = DictEncodedDataFrame.from_polars(df)
|
|
87
|
+
case dict():
|
|
88
|
+
encoded[k] = DictEncodedDataFrame.model_validate(df)
|
|
89
|
+
|
|
90
|
+
return encoded
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class InitialEnsembleRunModel(RunModel, InitialEnsembleRunModelConfig):
|
|
93
94
|
def _sample_and_evaluate_ensemble(
|
|
94
95
|
self,
|
|
95
96
|
evaluator_server_config: EvaluatorServerConfig,
|
ert/run_models/manual_update.py
CHANGED
|
@@ -8,7 +8,7 @@ from uuid import UUID
|
|
|
8
8
|
from pydantic import PrivateAttr
|
|
9
9
|
|
|
10
10
|
from ert.ensemble_evaluator import EvaluatorServerConfig
|
|
11
|
-
from ert.run_models.update_run_model import UpdateRunModel
|
|
11
|
+
from ert.run_models.update_run_model import UpdateRunModel, UpdateRunModelConfig
|
|
12
12
|
from ert.storage import Ensemble
|
|
13
13
|
|
|
14
14
|
from ..analysis import smoother_update
|
|
@@ -17,10 +17,12 @@ from .run_model import ErtRunError
|
|
|
17
17
|
logger = logging.getLogger(__name__)
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class
|
|
20
|
+
class ManualUpdateConfig(UpdateRunModelConfig):
|
|
21
21
|
ensemble_id: str
|
|
22
22
|
ert_templates: list[tuple[str, str]]
|
|
23
23
|
|
|
24
|
+
|
|
25
|
+
class ManualUpdate(UpdateRunModel, ManualUpdateConfig):
|
|
24
26
|
_prior: Ensemble = PrivateAttr()
|
|
25
27
|
|
|
26
28
|
def model_post_init(self, ctx: Any) -> None:
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import functools
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
from ert.storage import Ensemble
|
|
7
|
+
|
|
8
|
+
from ..analysis import enif_update
|
|
9
|
+
from .manual_update import ManualUpdate
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ManualUpdateEnIF(ManualUpdate):
|
|
15
|
+
@classmethod
|
|
16
|
+
def name(cls) -> str:
|
|
17
|
+
return "Manual EnIF update (Experimental)"
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def description(cls) -> str:
|
|
21
|
+
return "Load parameters and responses from existing → EnIF update"
|
|
22
|
+
|
|
23
|
+
def update_ensemble_parameters(
|
|
24
|
+
self, prior: Ensemble, posterior: Ensemble, weight: float
|
|
25
|
+
) -> None:
|
|
26
|
+
enif_update(
|
|
27
|
+
prior,
|
|
28
|
+
posterior,
|
|
29
|
+
parameters=prior.experiment.update_parameters,
|
|
30
|
+
observations=prior.experiment.observation_keys,
|
|
31
|
+
random_seed=self.random_seed,
|
|
32
|
+
progress_callback=functools.partial(
|
|
33
|
+
self.send_smoother_event,
|
|
34
|
+
prior.iteration,
|
|
35
|
+
prior.id,
|
|
36
|
+
),
|
|
37
|
+
)
|