ert 17.1.7__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/_enif_update.py +8 -4
- ert/analysis/_update_commons.py +16 -6
- 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 +56 -23
- 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.7.dist-info → ert-18.0.0.dist-info}/METADATA +8 -7
- {ert-17.1.7.dist-info → ert-18.0.0.dist-info}/RECORD +160 -159
- 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.7.dist-info → ert-18.0.0.dist-info}/WHEEL +0 -0
- {ert-17.1.7.dist-info → ert-18.0.0.dist-info}/entry_points.txt +0 -0
- {ert-17.1.7.dist-info → ert-18.0.0.dist-info}/licenses/COPYING +0 -0
- {ert-17.1.7.dist-info → ert-18.0.0.dist-info}/top_level.txt +0 -0
|
@@ -5,8 +5,6 @@ from pathlib import Path
|
|
|
5
5
|
from textwrap import dedent
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
|
-
from ruamel.yaml import YAML
|
|
9
|
-
|
|
10
8
|
from everest.bin.utils import setup_logging
|
|
11
9
|
from everest.config import EverestConfig
|
|
12
10
|
from everest.config_file_loader import load_yaml
|
|
@@ -139,10 +137,9 @@ def config_branch_entry(args: list[str] | None = None) -> None:
|
|
|
139
137
|
conf_controls=yml_config["controls"], opt_controls=opt_controls
|
|
140
138
|
)
|
|
141
139
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
yaml.dump(yml_config, Path(options.output_config))
|
|
140
|
+
EverestConfig.write_dict_to_file(
|
|
141
|
+
yml_config, Path(options.output_config), safe_and_pure=False
|
|
142
|
+
)
|
|
146
143
|
print(f"New config file {options.output_config} created.")
|
|
147
144
|
|
|
148
145
|
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import argparse
|
|
4
4
|
import sys
|
|
5
5
|
|
|
6
|
-
from ruamel.yaml import YAML
|
|
7
|
-
|
|
8
6
|
from everest.config import EverestConfig
|
|
9
7
|
|
|
10
8
|
|
|
@@ -26,13 +24,7 @@ def _build_args_parser() -> argparse.ArgumentParser:
|
|
|
26
24
|
def config_dump_entry(args: list[str] | None = None) -> None:
|
|
27
25
|
parser = _build_args_parser()
|
|
28
26
|
options = parser.parse_args(args)
|
|
29
|
-
|
|
30
|
-
config = EverestConfig.load_file(options.config_file)
|
|
31
|
-
|
|
32
|
-
yaml = YAML(typ="safe", pure=True)
|
|
33
|
-
yaml.indent = 2
|
|
34
|
-
yaml.default_flow_style = False
|
|
35
|
-
yaml.dump(config.to_dict(), sys.stdout)
|
|
27
|
+
EverestConfig.load_file(options.config_file).write_to_file(sys.stdout)
|
|
36
28
|
|
|
37
29
|
|
|
38
30
|
if __name__ == "__main__":
|
everest/bin/everest_script.py
CHANGED
|
@@ -3,7 +3,6 @@ import argparse
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
|
-
import os
|
|
7
6
|
import signal
|
|
8
7
|
import socket
|
|
9
8
|
import threading
|
|
@@ -11,9 +10,11 @@ from functools import partial
|
|
|
11
10
|
from pathlib import Path
|
|
12
11
|
from textwrap import dedent
|
|
13
12
|
|
|
13
|
+
import anyio
|
|
14
|
+
|
|
14
15
|
from _ert.threading import ErtThread
|
|
15
16
|
from ert.config import QueueSystem
|
|
16
|
-
from ert.services import
|
|
17
|
+
from ert.services import ErtServer
|
|
17
18
|
from ert.storage.local_experiment import ExperimentState
|
|
18
19
|
from everest.config import EverestConfig, ServerConfig
|
|
19
20
|
from everest.detached import (
|
|
@@ -168,7 +169,7 @@ async def run_everest(options: argparse.Namespace) -> None:
|
|
|
168
169
|
)
|
|
169
170
|
|
|
170
171
|
try:
|
|
171
|
-
|
|
172
|
+
ErtServer.session(
|
|
172
173
|
Path(ServerConfig.get_session_dir(options.config.output_dir)), timeout=1
|
|
173
174
|
)
|
|
174
175
|
server_running = True
|
|
@@ -193,18 +194,27 @@ async def run_everest(options: argparse.Namespace) -> None:
|
|
|
193
194
|
job_name = fm_job.split()[0]
|
|
194
195
|
logger.info(f"Everest forward model contains job {job_name}")
|
|
195
196
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
async def directory_is_nonempty(path: Path) -> bool:
|
|
198
|
+
try:
|
|
199
|
+
async for _ in anyio.Path(path).iterdir():
|
|
200
|
+
return True
|
|
201
|
+
except OSError: # Raised if the directory is empty
|
|
202
|
+
return False
|
|
203
|
+
else:
|
|
204
|
+
return False
|
|
205
|
+
|
|
206
|
+
if await anyio.Path(
|
|
207
|
+
options.config.simulation_dir
|
|
208
|
+
).exists() and await directory_is_nonempty(options.config.simulation_dir):
|
|
199
209
|
warn_user_that_runpath_is_nonempty()
|
|
200
210
|
if not options.skip_prompt:
|
|
201
211
|
show_scaled_controls_warning()
|
|
202
212
|
|
|
203
213
|
try:
|
|
204
|
-
output_dir = options.config.output_dir
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
214
|
+
output_dir = Path(options.config.output_dir)
|
|
215
|
+
options.config.write_to_file(
|
|
216
|
+
output_dir / options.config.config_file, drop_config_path=True
|
|
217
|
+
)
|
|
208
218
|
except (OSError, LookupError) as e:
|
|
209
219
|
logger.error(f"Failed to save optimization config: {e}")
|
|
210
220
|
|
|
@@ -223,7 +233,7 @@ async def run_everest(options: argparse.Namespace) -> None:
|
|
|
223
233
|
|
|
224
234
|
print("Waiting for server ...")
|
|
225
235
|
logger.debug("Waiting for response from everserver")
|
|
226
|
-
client =
|
|
236
|
+
client = ErtServer.session(
|
|
227
237
|
Path(ServerConfig.get_session_dir(options.config.output_dir))
|
|
228
238
|
)
|
|
229
239
|
wait_for_server(client, timeout=600)
|
everest/bin/kill_script.py
CHANGED
|
@@ -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
|
|
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
|
|
@@ -74,7 +74,7 @@ def _handle_keyboard_interrupt(signal: int, _: Any, after: bool = False) -> None
|
|
|
74
74
|
|
|
75
75
|
def kill_everest(options: argparse.Namespace) -> None:
|
|
76
76
|
try:
|
|
77
|
-
client =
|
|
77
|
+
client = ErtServer.session(
|
|
78
78
|
Path(ServerConfig.get_session_dir(options.config.output_dir)), timeout=1
|
|
79
79
|
)
|
|
80
80
|
server_context = ServerConfig.get_server_context_from_conn_info(
|
everest/bin/monitor_script.py
CHANGED
|
@@ -7,7 +7,7 @@ from functools import partial
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from textwrap import dedent
|
|
9
9
|
|
|
10
|
-
from ert.services import
|
|
10
|
+
from ert.services import ErtServer
|
|
11
11
|
from ert.storage import ErtStorageException, ExperimentState
|
|
12
12
|
from everest.config import EverestConfig, ServerConfig
|
|
13
13
|
from everest.everest_storage import EverestStorage
|
|
@@ -82,7 +82,7 @@ def _build_args_parser() -> argparse.ArgumentParser:
|
|
|
82
82
|
def monitor_everest(options: argparse.Namespace) -> None:
|
|
83
83
|
config: EverestConfig = options.config
|
|
84
84
|
try:
|
|
85
|
-
with
|
|
85
|
+
with ErtServer.session(
|
|
86
86
|
Path(ServerConfig.get_session_dir(config.output_dir)), timeout=1
|
|
87
87
|
) as client:
|
|
88
88
|
server_context = ServerConfig.get_server_context_from_conn_info(
|
everest/bin/utils.py
CHANGED
|
@@ -26,7 +26,7 @@ from ert.ensemble_evaluator import (
|
|
|
26
26
|
from ert.ensemble_evaluator.event import EndEvent
|
|
27
27
|
from ert.logging import LOGGING_CONFIG
|
|
28
28
|
from ert.plugins.plugin_manager import ErtPluginManager
|
|
29
|
-
from ert.services import
|
|
29
|
+
from ert.services import ErtServer
|
|
30
30
|
from ert.storage import (
|
|
31
31
|
ExperimentStatus,
|
|
32
32
|
open_storage,
|
|
@@ -39,10 +39,13 @@ from everest.detached import (
|
|
|
39
39
|
stop_server,
|
|
40
40
|
wait_for_server_to_stop,
|
|
41
41
|
)
|
|
42
|
-
from everest.simulator import JOB_FAILURE, JOB_RUNNING, JOB_SUCCESS
|
|
43
42
|
from everest.strings import EVEREST, OPT_PROGRESS_ID, SIM_PROGRESS_ID
|
|
44
43
|
from everest.util import makedirs_if_needed
|
|
45
44
|
|
|
45
|
+
JOB_SUCCESS = "Finished"
|
|
46
|
+
JOB_RUNNING = "Running"
|
|
47
|
+
JOB_FAILURE = "Failed"
|
|
48
|
+
|
|
46
49
|
|
|
47
50
|
def cleanup_logging() -> None:
|
|
48
51
|
os.environ.pop("ERT_LOG_DIR", None)
|
|
@@ -103,7 +106,7 @@ def handle_keyboard_interrupt(signum: int, _: Any, options: argparse.Namespace)
|
|
|
103
106
|
"The optimization will be stopped and the program will exit..."
|
|
104
107
|
)
|
|
105
108
|
try:
|
|
106
|
-
client =
|
|
109
|
+
client = ErtServer.session(
|
|
107
110
|
Path(ServerConfig.get_session_dir(options.config.output_dir))
|
|
108
111
|
)
|
|
109
112
|
server_context = ServerConfig.get_server_context_from_conn_info(
|
everest/config/__init__.py
CHANGED
|
@@ -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",
|
everest/config/control_config.py
CHANGED
|
@@ -12,13 +12,12 @@ from typing import (
|
|
|
12
12
|
from pydantic import AfterValidator, BaseModel, ConfigDict, Field, model_validator
|
|
13
13
|
from ropt.enums import PerturbationType, VariableType
|
|
14
14
|
|
|
15
|
-
from ert.config import ExtParamConfig
|
|
15
|
+
from ert.config import ExtParamConfig, SamplerConfig
|
|
16
16
|
|
|
17
17
|
from .control_variable_config import (
|
|
18
18
|
ControlVariableConfig,
|
|
19
19
|
ControlVariableGuessListConfig,
|
|
20
20
|
)
|
|
21
|
-
from .sampler_config import SamplerConfig
|
|
22
21
|
from .validation_utils import (
|
|
23
22
|
control_variables_validation,
|
|
24
23
|
no_dots_in_string,
|
|
@@ -314,8 +313,68 @@ class ControlConfig(BaseModel):
|
|
|
314
313
|
)
|
|
315
314
|
|
|
316
315
|
def to_ert_parameter_config(self) -> ExtParamConfig:
|
|
316
|
+
types = []
|
|
317
|
+
initial_guesses = []
|
|
318
|
+
control_types = []
|
|
319
|
+
enabled = []
|
|
320
|
+
mins = []
|
|
321
|
+
maxs = []
|
|
322
|
+
perturbation_types = []
|
|
323
|
+
perturbation_magnitudes = []
|
|
324
|
+
scaled_ranges = []
|
|
325
|
+
samplers = []
|
|
326
|
+
|
|
327
|
+
def _parse_variable(
|
|
328
|
+
variable: ControlVariableConfig | ControlVariableGuessListConfig,
|
|
329
|
+
initial_guess: float | None = None,
|
|
330
|
+
) -> None:
|
|
331
|
+
types.append(self.type)
|
|
332
|
+
initial_guesses.append(
|
|
333
|
+
initial_guess
|
|
334
|
+
if initial_guess is not None
|
|
335
|
+
else variable.initial_guess
|
|
336
|
+
if variable.initial_guess is not None
|
|
337
|
+
else self.initial_guess
|
|
338
|
+
)
|
|
339
|
+
control_types.append(self.control_type)
|
|
340
|
+
enabled.append(
|
|
341
|
+
variable.enabled if variable.enabled is not None else self.enabled
|
|
342
|
+
)
|
|
343
|
+
mins.append(variable.min if variable.min is not None else self.min)
|
|
344
|
+
maxs.append(variable.max if variable.max is not None else self.max)
|
|
345
|
+
perturbation_types.append(variable.perturbation_type)
|
|
346
|
+
perturbation_magnitudes.append(
|
|
347
|
+
variable.perturbation_magnitude
|
|
348
|
+
if variable.perturbation_magnitude is not None
|
|
349
|
+
else self.perturbation_magnitude
|
|
350
|
+
)
|
|
351
|
+
scaled_ranges.append(
|
|
352
|
+
variable.scaled_range
|
|
353
|
+
if variable.scaled_range is not None
|
|
354
|
+
else self.scaled_range
|
|
355
|
+
)
|
|
356
|
+
samplers.append(variable.sampler or self.sampler)
|
|
357
|
+
|
|
358
|
+
for variable in self.variables:
|
|
359
|
+
if isinstance(variable, ControlVariableConfig):
|
|
360
|
+
_parse_variable(variable)
|
|
361
|
+
else:
|
|
362
|
+
for initial_guess in variable.initial_guess:
|
|
363
|
+
_parse_variable(variable, initial_guess=initial_guess)
|
|
364
|
+
|
|
317
365
|
return ExtParamConfig(
|
|
318
366
|
name=self.name,
|
|
319
367
|
input_keys=self.formatted_control_names,
|
|
368
|
+
input_keys_dotdash=self.formatted_control_names_dotdash,
|
|
320
369
|
output_file=self.name + ".json",
|
|
370
|
+
types=types,
|
|
371
|
+
initial_guesses=initial_guesses,
|
|
372
|
+
control_types=control_types,
|
|
373
|
+
enabled=enabled,
|
|
374
|
+
min=mins,
|
|
375
|
+
max=maxs,
|
|
376
|
+
perturbation_types=perturbation_types,
|
|
377
|
+
perturbation_magnitudes=perturbation_magnitudes,
|
|
378
|
+
scaled_ranges=scaled_ranges,
|
|
379
|
+
samplers=samplers,
|
|
321
380
|
)
|
everest/config/everest_config.py
CHANGED
|
@@ -2,7 +2,6 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
from argparse import ArgumentParser
|
|
4
4
|
from copy import copy
|
|
5
|
-
from io import StringIO
|
|
6
5
|
from itertools import chain
|
|
7
6
|
from pathlib import Path
|
|
8
7
|
from sys import float_info
|
|
@@ -12,6 +11,7 @@ from typing import (
|
|
|
12
11
|
Any,
|
|
13
12
|
Optional,
|
|
14
13
|
Self,
|
|
14
|
+
TextIO,
|
|
15
15
|
TypeVar,
|
|
16
16
|
no_type_check,
|
|
17
17
|
)
|
|
@@ -30,7 +30,12 @@ from pydantic_core.core_schema import ValidationInfo
|
|
|
30
30
|
from ruamel.yaml import YAML, YAMLError
|
|
31
31
|
|
|
32
32
|
from ert.base_model_context import BaseModelWithContextSupport, use_runtime_plugins
|
|
33
|
-
from ert.config import
|
|
33
|
+
from ert.config import (
|
|
34
|
+
ConfigWarning,
|
|
35
|
+
EverestConstraintsConfig,
|
|
36
|
+
EverestObjectivesConfig,
|
|
37
|
+
QueueSystem,
|
|
38
|
+
)
|
|
34
39
|
from ert.plugins import get_site_plugins
|
|
35
40
|
from everest.config.install_template_config import InstallTemplateConfig
|
|
36
41
|
from everest.config.server_config import ServerConfig
|
|
@@ -1076,22 +1081,25 @@ to read summary data from forward model, do:
|
|
|
1076
1081
|
except ValueError as e:
|
|
1077
1082
|
parser.error(f"Loading config file <{config_path}> failed with: {e}")
|
|
1078
1083
|
|
|
1079
|
-
def
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
+
def write_to_file(
|
|
1085
|
+
self, output_file: str | Path | TextIO, drop_config_path: bool = False
|
|
1086
|
+
) -> None:
|
|
1087
|
+
dictconf = self.to_dict()
|
|
1088
|
+
if drop_config_path:
|
|
1089
|
+
del dictconf["config_path"]
|
|
1090
|
+
if isinstance(output_file, str):
|
|
1091
|
+
output_file = Path(output_file)
|
|
1092
|
+
self.write_dict_to_file(dictconf, output_file)
|
|
1084
1093
|
|
|
1085
|
-
|
|
1094
|
+
@staticmethod
|
|
1095
|
+
def write_dict_to_file(
|
|
1096
|
+
config: dict[str, Any], output_file: Path | TextIO, safe_and_pure: bool = True
|
|
1097
|
+
) -> None:
|
|
1098
|
+
yaml = YAML(typ="safe", pure=True) if safe_and_pure else YAML()
|
|
1099
|
+
yaml.indent(mapping=2, sequence=4, offset=2)
|
|
1100
|
+
yaml.preserve_quotes = True
|
|
1086
1101
|
yaml.default_flow_style = False
|
|
1087
|
-
|
|
1088
|
-
with StringIO() as sio:
|
|
1089
|
-
yaml.dump(stripped_conf, sio)
|
|
1090
|
-
return sio.getvalue()
|
|
1091
|
-
|
|
1092
|
-
yaml.dump(stripped_conf, Path(fname))
|
|
1093
|
-
|
|
1094
|
-
return None
|
|
1102
|
+
yaml.dump(config, output_file)
|
|
1095
1103
|
|
|
1096
1104
|
@property
|
|
1097
1105
|
def server_queue_system(self) -> QueueSystem:
|
|
@@ -1108,3 +1116,17 @@ to read summary data from forward model, do:
|
|
|
1108
1116
|
scales=[o.scale for o in self.objective_functions],
|
|
1109
1117
|
objective_types=[o.type for o in self.objective_functions],
|
|
1110
1118
|
)
|
|
1119
|
+
|
|
1120
|
+
def create_ert_output_constraints_config(self) -> EverestConstraintsConfig | None:
|
|
1121
|
+
if len(self.output_constraints) == 0:
|
|
1122
|
+
return None
|
|
1123
|
+
|
|
1124
|
+
constraint_names = [c.name for c in self.output_constraints]
|
|
1125
|
+
return EverestConstraintsConfig(
|
|
1126
|
+
keys=constraint_names,
|
|
1127
|
+
input_files=constraint_names,
|
|
1128
|
+
scales=[c.scale for c in self.output_constraints],
|
|
1129
|
+
targets=[c.target for c in self.output_constraints],
|
|
1130
|
+
upper_bounds=[c.upper_bound for c in self.output_constraints],
|
|
1131
|
+
lower_bounds=[c.lower_bound for c in self.output_constraints],
|
|
1132
|
+
)
|
|
@@ -9,7 +9,9 @@ from pydantic import (
|
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
from ert.base_model_context import BaseModelWithContextSupport
|
|
12
|
-
from ert.config import
|
|
12
|
+
from ert.config import (
|
|
13
|
+
SiteOrUserForwardModelStep,
|
|
14
|
+
)
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class ForwardModelResult(BaseModelWithContextSupport):
|
|
@@ -74,8 +76,8 @@ class ForwardModelStepConfig(BaseModelWithContextSupport):
|
|
|
74
76
|
return values
|
|
75
77
|
|
|
76
78
|
def to_ert_forward_model_step(
|
|
77
|
-
self, installed_fm_steps: dict[str,
|
|
78
|
-
) ->
|
|
79
|
+
self, installed_fm_steps: dict[str, SiteOrUserForwardModelStep]
|
|
80
|
+
) -> SiteOrUserForwardModelStep:
|
|
79
81
|
fm_name, *arglist = self.job.split()
|
|
80
82
|
match fm_name:
|
|
81
83
|
# All three reservoir simulator fm_steps map to
|
|
@@ -9,11 +9,13 @@ from typing import Any
|
|
|
9
9
|
|
|
10
10
|
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
11
11
|
|
|
12
|
-
from ert.config import
|
|
12
|
+
from ert.config.forward_model_step import (
|
|
13
|
+
SiteOrUserForwardModelStep,
|
|
14
|
+
)
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
def _is_dir_all_model(source: str, model_realizations: list[int]) -> bool:
|
|
16
|
-
"""Expands <
|
|
18
|
+
"""Expands <REALIZATION_ID> for all realizations and if:
|
|
17
19
|
- all are directories, returns True,
|
|
18
20
|
- all are files, returns False,
|
|
19
21
|
- some are non-existing, raises an AssertionError
|
|
@@ -21,7 +23,7 @@ def _is_dir_all_model(source: str, model_realizations: list[int]) -> bool:
|
|
|
21
23
|
|
|
22
24
|
is_dir = []
|
|
23
25
|
for model_realization in model_realizations:
|
|
24
|
-
model_source = source.replace("<
|
|
26
|
+
model_source = source.replace("<REALIZATION_ID>", str(model_realization))
|
|
25
27
|
if not os.path.exists(model_source):
|
|
26
28
|
msg = (
|
|
27
29
|
"Expected source to exist for data installation, "
|
|
@@ -126,8 +128,8 @@ class InstallDataConfig(BaseModel):
|
|
|
126
128
|
config_directory: str,
|
|
127
129
|
output_directory: str,
|
|
128
130
|
model_realizations: list[int],
|
|
129
|
-
installed_fm_steps: dict[str,
|
|
130
|
-
) ->
|
|
131
|
+
installed_fm_steps: dict[str, SiteOrUserForwardModelStep],
|
|
132
|
+
) -> SiteOrUserForwardModelStep:
|
|
131
133
|
target = self.target
|
|
132
134
|
|
|
133
135
|
def _missing_fm_msg(fm_name: str) -> str:
|
|
@@ -7,7 +7,7 @@ from pydantic import BaseModel, Field, model_validator
|
|
|
7
7
|
|
|
8
8
|
from ert.config import (
|
|
9
9
|
ExecutableWorkflow,
|
|
10
|
-
|
|
10
|
+
UserInstalledForwardModelStep,
|
|
11
11
|
forward_model_step_from_config_contents,
|
|
12
12
|
workflow_job_from_file,
|
|
13
13
|
)
|
|
@@ -57,12 +57,16 @@ class InstallJobConfig(BaseModel, extra="forbid"):
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
class InstallForwardModelStepConfig(InstallJobConfig):
|
|
60
|
-
def to_ert_forward_model_step(
|
|
60
|
+
def to_ert_forward_model_step(
|
|
61
|
+
self, config_directory: str
|
|
62
|
+
) -> UserInstalledForwardModelStep:
|
|
61
63
|
if self.executable is not None:
|
|
62
64
|
executable = Path(self.executable)
|
|
63
65
|
if not executable.is_absolute():
|
|
64
66
|
executable = Path(config_directory) / executable
|
|
65
|
-
return
|
|
67
|
+
return UserInstalledForwardModelStep(
|
|
68
|
+
name=self.name, executable=str(executable)
|
|
69
|
+
)
|
|
66
70
|
else:
|
|
67
71
|
assert (
|
|
68
72
|
self.source is not None
|
|
@@ -4,7 +4,7 @@ from textwrap import dedent
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel, Field
|
|
6
6
|
|
|
7
|
-
from ert.config import
|
|
7
|
+
from ert.config import SiteOrUserForwardModelStep
|
|
8
8
|
from everest.strings import EVEREST
|
|
9
9
|
|
|
10
10
|
|
|
@@ -38,9 +38,9 @@ class InstallTemplateConfig(BaseModel, extra="forbid"):
|
|
|
38
38
|
def to_ert_forward_model_step(
|
|
39
39
|
self,
|
|
40
40
|
control_names: list[str],
|
|
41
|
-
installed_fm_steps: dict[str,
|
|
41
|
+
installed_fm_steps: dict[str, SiteOrUserForwardModelStep],
|
|
42
42
|
well_path: str,
|
|
43
|
-
) ->
|
|
43
|
+
) -> SiteOrUserForwardModelStep:
|
|
44
44
|
fm_step_instance = copy.deepcopy(installed_fm_steps.get("template_render"))
|
|
45
45
|
if fm_step_instance is None:
|
|
46
46
|
raise KeyError(
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import importlib
|
|
1
2
|
import logging
|
|
2
3
|
from textwrap import dedent
|
|
3
4
|
from typing import Any, Self
|
|
4
5
|
|
|
5
6
|
from pydantic import BaseModel, Field, model_validator
|
|
7
|
+
from ropt.workflow import find_optimizer_plugin, validate_optimizer_options
|
|
6
8
|
|
|
7
9
|
from everest.config.cvar_config import CVaRConfig
|
|
8
|
-
from everest.optimizer.utils import get_ropt_plugin_manager
|
|
9
10
|
from everest.strings import EVEREST
|
|
10
11
|
|
|
11
12
|
|
|
@@ -346,15 +347,27 @@ class OptimizationConfig(BaseModel, extra="forbid"):
|
|
|
346
347
|
else f"{self.backend}/{self.algorithm}"
|
|
347
348
|
)
|
|
348
349
|
|
|
349
|
-
|
|
350
|
-
|
|
350
|
+
try:
|
|
351
|
+
plugin_name = find_optimizer_plugin(algorithm)
|
|
352
|
+
except ValueError:
|
|
353
|
+
raise
|
|
354
|
+
except Exception as exc:
|
|
355
|
+
ert_version = importlib.metadata.version("ert")
|
|
356
|
+
ropt_version = importlib.metadata.version("ropt")
|
|
357
|
+
msg = (
|
|
358
|
+
f"Error while initializing ropt:\n\n{exc}.\n\n"
|
|
359
|
+
"There may a be version mismatch between "
|
|
360
|
+
f"ERT ({ert_version}) and ropt ({ropt_version})\n"
|
|
361
|
+
"If the installation is correct, please report this as a bug."
|
|
362
|
+
)
|
|
363
|
+
raise RuntimeError(msg) from exc
|
|
351
364
|
if plugin_name is None:
|
|
352
365
|
raise ValueError(f"Optimizer algorithm '{algorithm}' not found")
|
|
353
366
|
self._optimization_plugin_name = plugin_name
|
|
354
367
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
368
|
+
options = self.options or self.backend_options
|
|
369
|
+
if options:
|
|
370
|
+
validate_optimizer_options(algorithm, options)
|
|
358
371
|
|
|
359
372
|
self.backend = None
|
|
360
373
|
self.algorithm = algorithm
|
|
@@ -74,10 +74,16 @@ class OutputConstraintConfig(BaseModel, extra="forbid"):
|
|
|
74
74
|
@model_validator(mode="before")
|
|
75
75
|
@classmethod
|
|
76
76
|
def validate_target_or_bounds(cls, values: dict[str, Any]) -> dict[str, Any]:
|
|
77
|
-
if "target"
|
|
77
|
+
if (values.get("target") is not None) and (
|
|
78
|
+
"lower_bound" in values or "upper_bound" in values
|
|
79
|
+
):
|
|
78
80
|
raise ValueError("Can not combine target and bounds")
|
|
79
81
|
elif not any(
|
|
80
|
-
(
|
|
82
|
+
(
|
|
83
|
+
(values.get("target") is not None),
|
|
84
|
+
"lower_bound" in values,
|
|
85
|
+
"upper_bound" in values,
|
|
86
|
+
)
|
|
81
87
|
):
|
|
82
88
|
raise ValueError("Must provide target or lower_bound/upper_bound")
|
|
83
89
|
return values
|
everest/config/server_config.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import os
|
|
3
|
-
from pathlib import Path
|
|
4
2
|
from textwrap import dedent
|
|
5
3
|
from typing import Any
|
|
6
4
|
|
|
@@ -12,14 +10,9 @@ from ert.config.queue_config import (
|
|
|
12
10
|
SlurmQueueOptions,
|
|
13
11
|
TorqueQueueOptions,
|
|
14
12
|
)
|
|
15
|
-
from ert.dark_storage.client import
|
|
13
|
+
from ert.dark_storage.client import ErtClientConnectionInfo
|
|
16
14
|
|
|
17
|
-
from ..strings import
|
|
18
|
-
CERTIFICATE_DIR,
|
|
19
|
-
DETACHED_NODE_DIR,
|
|
20
|
-
HOSTFILE_NAME,
|
|
21
|
-
SESSION_DIR,
|
|
22
|
-
)
|
|
15
|
+
from ..strings import SESSION_DIR
|
|
23
16
|
from .simulator_config import check_removed_config
|
|
24
17
|
|
|
25
18
|
|
|
@@ -59,21 +52,11 @@ class ServerConfig(BaseModel):
|
|
|
59
52
|
check_removed_config(data.get("queue_system"))
|
|
60
53
|
return data
|
|
61
54
|
|
|
62
|
-
@staticmethod
|
|
63
|
-
def get_server_url(output_dir: str) -> str:
|
|
64
|
-
"""Return the url of the server.
|
|
65
|
-
|
|
66
|
-
If server_info are given, the url is generated using that info. Otherwise
|
|
67
|
-
server information are retrieved from the hostfile
|
|
68
|
-
"""
|
|
69
|
-
server_info = ServerConfig.get_server_info(output_dir)
|
|
70
|
-
return f"https://{server_info['host']}:{server_info['port']}/experiment_server"
|
|
71
|
-
|
|
72
55
|
@staticmethod
|
|
73
56
|
def get_server_context_from_conn_info(
|
|
74
|
-
conn_info:
|
|
57
|
+
conn_info: ErtClientConnectionInfo,
|
|
75
58
|
) -> tuple[str, str, tuple[str, str]]:
|
|
76
|
-
"""Get server connection context information from a
|
|
59
|
+
"""Get server connection context information from a ErtClientConnectionInfo.
|
|
77
60
|
|
|
78
61
|
Returns a tuple containing the server URL, certificate file path,
|
|
79
62
|
and authentication credentials.
|
|
@@ -83,7 +66,7 @@ class ServerConfig(BaseModel):
|
|
|
83
66
|
This should be refactored to use the ERT Storage Client class directly instead.
|
|
84
67
|
|
|
85
68
|
Args:
|
|
86
|
-
conn_info: An instance of the
|
|
69
|
+
conn_info: An instance of the ErtClientConnectionInfo
|
|
87
70
|
|
|
88
71
|
Returns:
|
|
89
72
|
tuple: A tuple containing:
|
|
@@ -102,34 +85,8 @@ class ServerConfig(BaseModel):
|
|
|
102
85
|
|
|
103
86
|
return url, cert_file, auth
|
|
104
87
|
|
|
105
|
-
@staticmethod
|
|
106
|
-
def get_server_info(output_dir: str) -> dict[str, Any]:
|
|
107
|
-
"""Load server information from the hostfile"""
|
|
108
|
-
host_file_path = Path(ServerConfig.get_hostfile_path(output_dir))
|
|
109
|
-
if not host_file_path.exists():
|
|
110
|
-
return {"host": None, "port": None, "cert": None, "auth": None}
|
|
111
|
-
|
|
112
|
-
data = json.loads(host_file_path.read_text(encoding="utf-8"))
|
|
113
|
-
|
|
114
|
-
if not all(k in data for k in ("host", "port", "cert", "auth")):
|
|
115
|
-
raise RuntimeError("Malformed hostfile")
|
|
116
|
-
return data
|
|
117
|
-
|
|
118
|
-
@staticmethod
|
|
119
|
-
def get_detached_node_dir(output_dir: str) -> str:
|
|
120
|
-
return os.path.join(os.path.abspath(output_dir), DETACHED_NODE_DIR)
|
|
121
|
-
|
|
122
|
-
@staticmethod
|
|
123
|
-
def get_hostfile_path(output_dir: str) -> str:
|
|
124
|
-
return os.path.join(ServerConfig.get_session_dir(output_dir), HOSTFILE_NAME)
|
|
125
|
-
|
|
126
88
|
@staticmethod
|
|
127
89
|
def get_session_dir(output_dir: str) -> str:
|
|
128
90
|
"""Return path to the session directory containing information about the
|
|
129
91
|
certificates and host information"""
|
|
130
|
-
return os.path.join(
|
|
131
|
-
|
|
132
|
-
@staticmethod
|
|
133
|
-
def get_certificate_dir(output_dir: str) -> str:
|
|
134
|
-
"""Return the path to certificate folder"""
|
|
135
|
-
return os.path.join(ServerConfig.get_session_dir(output_dir), CERTIFICATE_DIR)
|
|
92
|
+
return os.path.join(os.path.abspath(output_dir), SESSION_DIR)
|