ert 18.0.9__py3-none-any.whl → 19.0.0rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- _ert/forward_model_runner/client.py +6 -2
- ert/__main__.py +20 -6
- ert/analysis/_es_update.py +6 -19
- ert/cli/main.py +7 -3
- ert/config/__init__.py +3 -4
- ert/config/_create_observation_dataframes.py +57 -8
- ert/config/_get_num_cpu.py +1 -1
- ert/config/_observations.py +77 -1
- ert/config/distribution.py +1 -1
- ert/config/ensemble_config.py +3 -3
- ert/config/ert_config.py +50 -8
- ert/config/{ext_param_config.py → everest_control.py} +8 -12
- ert/config/everest_response.py +3 -5
- ert/config/field.py +76 -14
- ert/config/forward_model_step.py +12 -9
- ert/config/gen_data_config.py +3 -4
- ert/config/gen_kw_config.py +2 -12
- ert/config/parameter_config.py +1 -16
- ert/config/parsing/_option_dict.py +10 -2
- ert/config/parsing/config_keywords.py +1 -0
- ert/config/parsing/config_schema.py +8 -0
- ert/config/parsing/config_schema_deprecations.py +14 -3
- ert/config/parsing/config_schema_item.py +12 -3
- ert/config/parsing/context_values.py +3 -3
- ert/config/parsing/file_context_token.py +1 -1
- ert/config/parsing/observations_parser.py +6 -2
- ert/config/parsing/queue_system.py +9 -0
- ert/config/queue_config.py +0 -1
- ert/config/response_config.py +0 -1
- ert/config/rft_config.py +78 -33
- ert/config/summary_config.py +1 -2
- ert/config/surface_config.py +59 -16
- ert/dark_storage/common.py +1 -1
- ert/dark_storage/compute/misfits.py +4 -1
- ert/dark_storage/endpoints/compute/misfits.py +4 -2
- ert/dark_storage/endpoints/experiment_server.py +12 -9
- ert/dark_storage/endpoints/experiments.py +2 -2
- ert/dark_storage/endpoints/observations.py +4 -2
- ert/dark_storage/endpoints/parameters.py +2 -18
- ert/dark_storage/endpoints/responses.py +10 -5
- ert/dark_storage/json_schema/experiment.py +1 -1
- ert/data/_measured_data.py +6 -5
- ert/ensemble_evaluator/config.py +2 -1
- ert/field_utils/field_utils.py +1 -1
- ert/field_utils/grdecl_io.py +9 -26
- ert/field_utils/roff_io.py +1 -1
- ert/gui/__init__.py +5 -2
- ert/gui/ertnotifier.py +1 -1
- ert/gui/ertwidgets/pathchooser.py +0 -3
- ert/gui/ertwidgets/suggestor/suggestor.py +63 -30
- ert/gui/main.py +27 -5
- ert/gui/main_window.py +0 -5
- ert/gui/simulation/experiment_panel.py +12 -7
- ert/gui/simulation/run_dialog.py +2 -16
- ert/gui/summarypanel.py +0 -19
- ert/gui/tools/manage_experiments/export_dialog.py +136 -0
- ert/gui/tools/manage_experiments/storage_info_widget.py +110 -9
- ert/gui/tools/plot/plot_api.py +24 -15
- ert/gui/tools/plot/plot_widget.py +10 -2
- ert/gui/tools/plot/plot_window.py +26 -18
- ert/gui/tools/plot/plottery/plots/__init__.py +2 -0
- ert/gui/tools/plot/plottery/plots/cesp.py +3 -1
- ert/gui/tools/plot/plottery/plots/distribution.py +6 -1
- ert/gui/tools/plot/plottery/plots/ensemble.py +3 -1
- ert/gui/tools/plot/plottery/plots/gaussian_kde.py +12 -2
- ert/gui/tools/plot/plottery/plots/histogram.py +3 -1
- ert/gui/tools/plot/plottery/plots/misfits.py +436 -0
- ert/gui/tools/plot/plottery/plots/observations.py +18 -4
- ert/gui/tools/plot/plottery/plots/statistics.py +3 -1
- ert/gui/tools/plot/plottery/plots/std_dev.py +3 -1
- ert/plugins/hook_implementations/workflows/csv_export.py +2 -3
- ert/plugins/plugin_manager.py +4 -0
- ert/resources/forward_models/run_reservoirsimulator.py +8 -3
- ert/run_models/_create_run_path.py +3 -3
- ert/run_models/everest_run_model.py +13 -11
- ert/run_models/initial_ensemble_run_model.py +2 -2
- ert/run_models/run_model.py +30 -1
- ert/services/_base_service.py +6 -5
- ert/services/ert_server.py +4 -4
- ert/shared/_doc_utils/__init__.py +4 -2
- ert/shared/net_utils.py +43 -18
- ert/shared/version.py +3 -3
- ert/storage/__init__.py +2 -0
- ert/storage/local_ensemble.py +13 -7
- ert/storage/local_experiment.py +2 -2
- ert/storage/local_storage.py +41 -25
- ert/storage/migration/to11.py +1 -1
- ert/storage/migration/to18.py +0 -1
- ert/storage/migration/to19.py +34 -0
- ert/storage/migration/to20.py +23 -0
- ert/storage/migration/to21.py +25 -0
- ert/workflow_runner.py +2 -1
- {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/METADATA +1 -1
- {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/RECORD +112 -112
- {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/WHEEL +1 -1
- everest/bin/everlint_script.py +0 -2
- everest/bin/utils.py +2 -1
- everest/bin/visualization_script.py +4 -11
- everest/config/control_config.py +4 -4
- everest/config/control_variable_config.py +2 -2
- everest/config/everest_config.py +9 -0
- everest/config/utils.py +2 -2
- everest/config/validation_utils.py +7 -1
- everest/config_file_loader.py +0 -2
- everest/detached/client.py +3 -3
- everest/everest_storage.py +0 -2
- everest/gui/everest_client.py +2 -2
- everest/optimizer/everest2ropt.py +4 -4
- everest/optimizer/opt_model_transforms.py +2 -2
- ert/config/violations.py +0 -0
- ert/gui/tools/export/__init__.py +0 -3
- ert/gui/tools/export/export_panel.py +0 -83
- ert/gui/tools/export/export_tool.py +0 -69
- ert/gui/tools/export/exporter.py +0 -36
- {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/entry_points.txt +0 -0
- {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/licenses/COPYING +0 -0
- {ert-18.0.9.dist-info → ert-19.0.0rc0.dist-info}/top_level.txt +0 -0
|
@@ -2,8 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
+
import types
|
|
5
6
|
import uuid
|
|
6
|
-
from typing import
|
|
7
|
+
from typing import Self
|
|
7
8
|
|
|
8
9
|
import zmq
|
|
9
10
|
import zmq.asyncio
|
|
@@ -67,7 +68,10 @@ class Client:
|
|
|
67
68
|
return self
|
|
68
69
|
|
|
69
70
|
async def __aexit__(
|
|
70
|
-
self,
|
|
71
|
+
self,
|
|
72
|
+
exc_type: type[BaseException] | None,
|
|
73
|
+
exc_value: BaseException | None,
|
|
74
|
+
exc_traceback: types.TracebackType | None,
|
|
71
75
|
) -> None:
|
|
72
76
|
try:
|
|
73
77
|
await self.send(DISCONNECT_MSG)
|
ert/__main__.py
CHANGED
|
@@ -80,18 +80,32 @@ def run_webviz_ert(args: Namespace, _: ErtRuntimePlugins | None = None) -> None:
|
|
|
80
80
|
# only use the base name of the config file path
|
|
81
81
|
kwargs["ert_config"] = os.path.basename(args.config)
|
|
82
82
|
kwargs["project"] = os.path.abspath(ens_path)
|
|
83
|
+
|
|
84
|
+
yellow = "\x1b[33m"
|
|
85
|
+
green = "\x1b[32m"
|
|
86
|
+
bold = "\x1b[1m"
|
|
87
|
+
reset = "\x1b[0m"
|
|
88
|
+
|
|
83
89
|
try:
|
|
84
90
|
with ErtServer.init_service(project=Path(ens_path).absolute()) as storage:
|
|
85
91
|
storage.wait_until_ready()
|
|
86
92
|
print(
|
|
87
|
-
"""
|
|
88
|
-
|
|
93
|
+
f"""
|
|
94
|
+
---------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
{yellow}{bold}Webviz-ERT is deprecated and will be removed in the near future{reset}
|
|
97
|
+
|
|
98
|
+
{green}{bold}Plotting capabilities provided by Webviz-ERT are now available
|
|
99
|
+
using the ERT plotter{reset}
|
|
100
|
+
|
|
101
|
+
---------------------------------------------------------------
|
|
89
102
|
|
|
90
103
|
Starting up Webviz-ERT. This might take more than a minute.
|
|
91
104
|
|
|
92
|
-
|
|
105
|
+
---------------------------------------------------------------
|
|
93
106
|
"""
|
|
94
107
|
)
|
|
108
|
+
logger.info("Show Webviz-ert deprecation warning")
|
|
95
109
|
webviz_kwargs = {
|
|
96
110
|
"experimental_mode": args.experimental_mode,
|
|
97
111
|
"verbose": args.verbose,
|
|
@@ -567,15 +581,15 @@ def get_ert_parser(parser: ArgumentParser | None = None) -> ArgumentParser:
|
|
|
567
581
|
"--color-always",
|
|
568
582
|
action="store_true",
|
|
569
583
|
help="Force coloring of monitor output, which is automatically"
|
|
570
|
-
|
|
584
|
+
" disabled if the output stream is not a terminal.",
|
|
571
585
|
default=False,
|
|
572
586
|
)
|
|
573
587
|
cli_parser.add_argument(
|
|
574
588
|
"--disable-monitoring",
|
|
575
589
|
action="store_true",
|
|
576
590
|
help="Monitoring will continuously print the status of the realisations"
|
|
577
|
-
|
|
578
|
-
|
|
591
|
+
" classified into Waiting, Pending, Running, Failed, Finished"
|
|
592
|
+
" and Unknown.",
|
|
579
593
|
default=False,
|
|
580
594
|
)
|
|
581
595
|
cli_parser.add_argument(
|
ert/analysis/_es_update.py
CHANGED
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import functools
|
|
4
4
|
import logging
|
|
5
|
-
import re
|
|
6
5
|
import time
|
|
7
6
|
import warnings
|
|
8
7
|
from collections.abc import Callable, Iterable, Sequence
|
|
@@ -442,12 +441,6 @@ def smoother_update(
|
|
|
442
441
|
with warnings.catch_warnings():
|
|
443
442
|
original_showwarning = warnings.showwarning
|
|
444
443
|
|
|
445
|
-
ILL_CONDITIONED_RE = re.compile(
|
|
446
|
-
r"^LinAlgWarning:.*ill[- ]?conditioned\s+matrix", re.IGNORECASE
|
|
447
|
-
)
|
|
448
|
-
LIMIT_ILL_CONDITIONED_WARNING = 1000
|
|
449
|
-
illconditioned_warn_counter = 0
|
|
450
|
-
|
|
451
444
|
def log_warning(
|
|
452
445
|
message: Warning | str,
|
|
453
446
|
category: type[Warning],
|
|
@@ -456,18 +449,12 @@ def smoother_update(
|
|
|
456
449
|
file: TextIO | None = None,
|
|
457
450
|
line: str | None = None,
|
|
458
451
|
) -> None:
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
logger.warning(
|
|
466
|
-
f"{category.__name__}: {message} (from {filename}:{lineno})"
|
|
467
|
-
)
|
|
468
|
-
original_showwarning(
|
|
469
|
-
message, category, filename, lineno, file=file, line=line
|
|
470
|
-
)
|
|
452
|
+
logger.warning(
|
|
453
|
+
f"{category.__name__}: {message} (from {filename}:{lineno})"
|
|
454
|
+
)
|
|
455
|
+
original_showwarning(
|
|
456
|
+
message, category, filename, lineno, file=file, line=line
|
|
457
|
+
)
|
|
471
458
|
|
|
472
459
|
warnings.showwarning = log_warning
|
|
473
460
|
analysis_ES(
|
ert/cli/main.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
1
|
from __future__ import annotations
|
|
3
2
|
|
|
4
3
|
import contextlib
|
|
@@ -7,6 +6,7 @@ import os
|
|
|
7
6
|
import queue
|
|
8
7
|
import sys
|
|
9
8
|
from collections import Counter
|
|
9
|
+
from pathlib import Path
|
|
10
10
|
from typing import TextIO
|
|
11
11
|
|
|
12
12
|
from _ert.threading import ErtThread
|
|
@@ -27,7 +27,7 @@ from ert.namespace import Namespace
|
|
|
27
27
|
from ert.plugins import ErtRuntimePlugins, get_site_plugins
|
|
28
28
|
from ert.run_models.event import StatusEvents
|
|
29
29
|
from ert.run_models.model_factory import create_model
|
|
30
|
-
from ert.storage import open_storage
|
|
30
|
+
from ert.storage import LocalStorage, open_storage
|
|
31
31
|
from ert.storage.local_storage import local_storage_set_ert_config
|
|
32
32
|
|
|
33
33
|
|
|
@@ -88,7 +88,10 @@ def run_cli(args: Namespace, runtime_plugins: ErtRuntimePlugins | None = None) -
|
|
|
88
88
|
)
|
|
89
89
|
|
|
90
90
|
if args.mode == WORKFLOW_MODE:
|
|
91
|
-
|
|
91
|
+
path = Path(ert_config.ens_path)
|
|
92
|
+
if LocalStorage.check_migration_needed(path):
|
|
93
|
+
LocalStorage.perform_migration(path)
|
|
94
|
+
with open_storage(path, "w") as storage:
|
|
92
95
|
execute_workflow(ert_config, storage, args.name)
|
|
93
96
|
return
|
|
94
97
|
|
|
@@ -130,6 +133,7 @@ def run_cli(args: Namespace, runtime_plugins: ErtRuntimePlugins | None = None) -
|
|
|
130
133
|
if args.port_range is None
|
|
131
134
|
else (min(args.port_range), max(args.port_range) + 1),
|
|
132
135
|
use_ipc_protocol=using_local_queuesystem,
|
|
136
|
+
prioritize_private_ip_address=ert_config.prioritize_private_ip_address,
|
|
133
137
|
)
|
|
134
138
|
|
|
135
139
|
if model.check_if_runpath_exists():
|
ert/config/__init__.py
CHANGED
|
@@ -11,8 +11,8 @@ from .ensemble_config import EnsembleConfig
|
|
|
11
11
|
from .ert_config import ErtConfig, forward_model_step_from_config_contents
|
|
12
12
|
from .ert_plugin import ErtPlugin
|
|
13
13
|
from .ert_script import ErtScript
|
|
14
|
+
from .everest_control import EverestControl, SamplerConfig
|
|
14
15
|
from .everest_response import EverestConstraintsConfig, EverestObjectivesConfig
|
|
15
|
-
from .ext_param_config import ExtParamConfig, SamplerConfig
|
|
16
16
|
from .external_ert_script import ExternalErtScript
|
|
17
17
|
from .field import Field, field_transform
|
|
18
18
|
from .forward_model_step import (
|
|
@@ -31,7 +31,7 @@ from .gen_kw_config import DataSource, GenKwConfig, PriorDict
|
|
|
31
31
|
from .known_response_types import KnownResponseTypes
|
|
32
32
|
from .lint_file import lint_file
|
|
33
33
|
from .model_config import ModelConfig
|
|
34
|
-
from .parameter_config import ParameterCardinality, ParameterConfig
|
|
34
|
+
from .parameter_config import ParameterCardinality, ParameterConfig
|
|
35
35
|
from .parsing import (
|
|
36
36
|
ConfigValidationError,
|
|
37
37
|
ConfigWarning,
|
|
@@ -90,9 +90,9 @@ __all__ = [
|
|
|
90
90
|
"ErtScript",
|
|
91
91
|
"ErtScriptWorkflow",
|
|
92
92
|
"EverestConstraintsConfig",
|
|
93
|
+
"EverestControl",
|
|
93
94
|
"EverestObjectivesConfig",
|
|
94
95
|
"ExecutableWorkflow",
|
|
95
|
-
"ExtParamConfig",
|
|
96
96
|
"ExternalErtScript",
|
|
97
97
|
"Field",
|
|
98
98
|
"ForwardModelStep",
|
|
@@ -119,7 +119,6 @@ __all__ = [
|
|
|
119
119
|
"OutlierSettings",
|
|
120
120
|
"ParameterCardinality",
|
|
121
121
|
"ParameterConfig",
|
|
122
|
-
"ParameterMetadata",
|
|
123
122
|
"PostExperimentFixtures",
|
|
124
123
|
"PostSimulationFixtures",
|
|
125
124
|
"PostUpdateFixtures",
|
|
@@ -18,6 +18,7 @@ from ._observations import (
|
|
|
18
18
|
Observation,
|
|
19
19
|
ObservationDate,
|
|
20
20
|
ObservationError,
|
|
21
|
+
RFTObservation,
|
|
21
22
|
SummaryObservation,
|
|
22
23
|
)
|
|
23
24
|
from .gen_data_config import GenDataConfig
|
|
@@ -28,6 +29,7 @@ from .parsing import (
|
|
|
28
29
|
ObservationConfigError,
|
|
29
30
|
)
|
|
30
31
|
from .refcase import Refcase
|
|
32
|
+
from .rft_config import RFTConfig
|
|
31
33
|
|
|
32
34
|
if TYPE_CHECKING:
|
|
33
35
|
import numpy.typing as npt
|
|
@@ -41,6 +43,7 @@ def create_observation_dataframes(
|
|
|
41
43
|
observations: Sequence[Observation],
|
|
42
44
|
refcase: Refcase | None,
|
|
43
45
|
gen_data_config: GenDataConfig | None,
|
|
46
|
+
rft_config: RFTConfig | None,
|
|
44
47
|
time_map: list[datetime] | None,
|
|
45
48
|
history: HistorySource,
|
|
46
49
|
) -> dict[str, pl.DataFrame]:
|
|
@@ -56,7 +59,6 @@ def create_observation_dataframes(
|
|
|
56
59
|
config_errors: list[ErrorInfo] = []
|
|
57
60
|
grouped: dict[str, list[pl.DataFrame]] = defaultdict(list)
|
|
58
61
|
for obs in observations:
|
|
59
|
-
obs_name = obs.name
|
|
60
62
|
try:
|
|
61
63
|
match obs:
|
|
62
64
|
case HistoryObservation():
|
|
@@ -64,7 +66,7 @@ def create_observation_dataframes(
|
|
|
64
66
|
_handle_history_observation(
|
|
65
67
|
refcase,
|
|
66
68
|
obs,
|
|
67
|
-
|
|
69
|
+
obs.name,
|
|
68
70
|
history,
|
|
69
71
|
time_len,
|
|
70
72
|
)
|
|
@@ -73,7 +75,7 @@ def create_observation_dataframes(
|
|
|
73
75
|
grouped["summary"].append(
|
|
74
76
|
_handle_summary_observation(
|
|
75
77
|
obs,
|
|
76
|
-
|
|
78
|
+
obs.name,
|
|
77
79
|
obs_time_list,
|
|
78
80
|
bool(refcase),
|
|
79
81
|
)
|
|
@@ -83,11 +85,18 @@ def create_observation_dataframes(
|
|
|
83
85
|
_handle_general_observation(
|
|
84
86
|
gen_data_config,
|
|
85
87
|
obs,
|
|
86
|
-
|
|
88
|
+
obs.name,
|
|
87
89
|
obs_time_list,
|
|
88
90
|
bool(refcase),
|
|
89
91
|
)
|
|
90
92
|
)
|
|
93
|
+
case RFTObservation():
|
|
94
|
+
if rft_config is None:
|
|
95
|
+
raise TypeError(
|
|
96
|
+
"create_observation_dataframes requires "
|
|
97
|
+
"rft_config is not None when using RFTObservation"
|
|
98
|
+
)
|
|
99
|
+
grouped["rft"].append(_handle_rft_observation(rft_config, obs))
|
|
91
100
|
case default:
|
|
92
101
|
assert_never(default)
|
|
93
102
|
except ObservationConfigError as err:
|
|
@@ -460,10 +469,8 @@ def _handle_general_observation(
|
|
|
460
469
|
stds = file_values[1::2]
|
|
461
470
|
|
|
462
471
|
else:
|
|
463
|
-
assert
|
|
464
|
-
|
|
465
|
-
and general_observation.error is not None
|
|
466
|
-
)
|
|
472
|
+
assert general_observation.value is not None
|
|
473
|
+
assert general_observation.error is not None
|
|
467
474
|
values = np.array([general_observation.value])
|
|
468
475
|
stds = np.array([general_observation.error])
|
|
469
476
|
|
|
@@ -509,3 +516,45 @@ def _handle_general_observation(
|
|
|
509
516
|
"std": pl.Series(stds, dtype=pl.Float32),
|
|
510
517
|
}
|
|
511
518
|
)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
def _handle_rft_observation(
|
|
522
|
+
rft_config: RFTConfig,
|
|
523
|
+
rft_observation: RFTObservation,
|
|
524
|
+
) -> pl.DataFrame:
|
|
525
|
+
location = (rft_observation.east, rft_observation.north, rft_observation.tvd)
|
|
526
|
+
if location not in rft_config.locations:
|
|
527
|
+
rft_config.locations.append(location)
|
|
528
|
+
|
|
529
|
+
data_to_read = rft_config.data_to_read
|
|
530
|
+
if rft_observation.well not in data_to_read:
|
|
531
|
+
rft_config.data_to_read[rft_observation.well] = {}
|
|
532
|
+
|
|
533
|
+
well_dict = data_to_read[rft_observation.well]
|
|
534
|
+
if rft_observation.date not in well_dict:
|
|
535
|
+
well_dict[rft_observation.date] = []
|
|
536
|
+
|
|
537
|
+
property_list = well_dict[rft_observation.date]
|
|
538
|
+
if rft_observation.property not in property_list:
|
|
539
|
+
property_list.append(rft_observation.property)
|
|
540
|
+
|
|
541
|
+
if rft_observation.error <= 0.0:
|
|
542
|
+
raise ObservationConfigError.with_context(
|
|
543
|
+
"Observation uncertainty must be strictly > 0", rft_observation.well
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
return pl.DataFrame(
|
|
547
|
+
{
|
|
548
|
+
"response_key": (
|
|
549
|
+
f"{rft_observation.well}:"
|
|
550
|
+
f"{rft_observation.date}:"
|
|
551
|
+
f"{rft_observation.property}"
|
|
552
|
+
),
|
|
553
|
+
"observation_key": rft_observation.name,
|
|
554
|
+
"east": pl.Series([location[0]], dtype=pl.Float32),
|
|
555
|
+
"north": pl.Series([location[1]], dtype=pl.Float32),
|
|
556
|
+
"tvd": pl.Series([location[2]], dtype=pl.Float32),
|
|
557
|
+
"observations": pl.Series([rft_observation.value], dtype=pl.Float32),
|
|
558
|
+
"std": pl.Series([rft_observation.error], dtype=pl.Float32),
|
|
559
|
+
}
|
|
560
|
+
)
|
ert/config/_get_num_cpu.py
CHANGED
|
@@ -156,7 +156,7 @@ class _Parser:
|
|
|
156
156
|
def next_line(self) -> Iterator[str]: ...
|
|
157
157
|
|
|
158
158
|
@overload
|
|
159
|
-
def next_line(self, __default: T) -> Iterator[str] | T: ...
|
|
159
|
+
def next_line(self, __default: T, /) -> Iterator[str] | T: ...
|
|
160
160
|
|
|
161
161
|
def next_line(self, *args: T) -> Iterator[str] | T:
|
|
162
162
|
self.line_number += 1
|
ert/config/_observations.py
CHANGED
|
@@ -214,12 +214,88 @@ class GeneralObservation(ObservationDate, _GeneralObservation):
|
|
|
214
214
|
return output
|
|
215
215
|
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
@dataclass
|
|
218
|
+
class RFTObservation:
|
|
219
|
+
name: str
|
|
220
|
+
well: str
|
|
221
|
+
date: str
|
|
222
|
+
property: str
|
|
223
|
+
value: float
|
|
224
|
+
error: float
|
|
225
|
+
north: float
|
|
226
|
+
east: float
|
|
227
|
+
tvd: float
|
|
228
|
+
|
|
229
|
+
@classmethod
|
|
230
|
+
def from_obs_dict(cls, directory: str, observation_dict: ObservationDict) -> Self:
|
|
231
|
+
well = None
|
|
232
|
+
observed_property = None
|
|
233
|
+
observed_value = None
|
|
234
|
+
error = None
|
|
235
|
+
date = None
|
|
236
|
+
north = None
|
|
237
|
+
east = None
|
|
238
|
+
tvd = None
|
|
239
|
+
for key, value in observation_dict.items():
|
|
240
|
+
match key:
|
|
241
|
+
case "type" | "name":
|
|
242
|
+
pass
|
|
243
|
+
case "WELL":
|
|
244
|
+
well = value
|
|
245
|
+
case "PROPERTY":
|
|
246
|
+
observed_property = value
|
|
247
|
+
case "VALUE":
|
|
248
|
+
observed_value = validate_float(value, key)
|
|
249
|
+
case "ERROR":
|
|
250
|
+
error = validate_float(value, key)
|
|
251
|
+
case "DATE":
|
|
252
|
+
date = value
|
|
253
|
+
case "NORTH":
|
|
254
|
+
north = validate_float(value, key)
|
|
255
|
+
case "EAST":
|
|
256
|
+
east = validate_float(value, key)
|
|
257
|
+
case "TVD":
|
|
258
|
+
tvd = validate_float(value, key)
|
|
259
|
+
case _:
|
|
260
|
+
raise _unknown_key_error(str(key), observation_dict["name"])
|
|
261
|
+
if well is None:
|
|
262
|
+
raise _missing_value_error(observation_dict["name"], "WELL")
|
|
263
|
+
if observed_value is None:
|
|
264
|
+
raise _missing_value_error(observation_dict["name"], "VALUE")
|
|
265
|
+
if observed_property is None:
|
|
266
|
+
raise _missing_value_error(observation_dict["name"], "PROPERTY")
|
|
267
|
+
if error is None:
|
|
268
|
+
raise _missing_value_error(observation_dict["name"], "ERROR")
|
|
269
|
+
if date is None:
|
|
270
|
+
raise _missing_value_error(observation_dict["name"], "DATE")
|
|
271
|
+
if north is None:
|
|
272
|
+
raise _missing_value_error(observation_dict["name"], "NORTH")
|
|
273
|
+
if east is None:
|
|
274
|
+
raise _missing_value_error(observation_dict["name"], "EAST")
|
|
275
|
+
if tvd is None:
|
|
276
|
+
raise _missing_value_error(observation_dict["name"], "TVD")
|
|
277
|
+
return cls(
|
|
278
|
+
observation_dict["name"],
|
|
279
|
+
well,
|
|
280
|
+
date,
|
|
281
|
+
observed_property,
|
|
282
|
+
observed_value,
|
|
283
|
+
error,
|
|
284
|
+
north,
|
|
285
|
+
east,
|
|
286
|
+
tvd,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
Observation = (
|
|
291
|
+
HistoryObservation | SummaryObservation | GeneralObservation | RFTObservation
|
|
292
|
+
)
|
|
218
293
|
|
|
219
294
|
_TYPE_TO_CLASS: dict[ObservationType, type[Observation]] = {
|
|
220
295
|
ObservationType.HISTORY: HistoryObservation,
|
|
221
296
|
ObservationType.SUMMARY: SummaryObservation,
|
|
222
297
|
ObservationType.GENERAL: GeneralObservation,
|
|
298
|
+
ObservationType.RFT: RFTObservation,
|
|
223
299
|
}
|
|
224
300
|
|
|
225
301
|
|
ert/config/distribution.py
CHANGED
|
@@ -17,7 +17,7 @@ class TransSettingsValidation(BaseModel):
|
|
|
17
17
|
model_config = {"extra": "forbid"}
|
|
18
18
|
|
|
19
19
|
@classmethod
|
|
20
|
-
def create(cls
|
|
20
|
+
def create(cls, *args: Any, **kwargs: Any) -> Self:
|
|
21
21
|
return cls(*args, **kwargs)
|
|
22
22
|
|
|
23
23
|
@classmethod
|
ert/config/ensemble_config.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import Self
|
|
|
7
7
|
|
|
8
8
|
from pydantic import BaseModel, Field, model_validator
|
|
9
9
|
|
|
10
|
-
from .
|
|
10
|
+
from .everest_control import EverestControl
|
|
11
11
|
from .field import Field as FieldConfig
|
|
12
12
|
from .gen_kw_config import GenKwConfig
|
|
13
13
|
from .known_response_types import KNOWN_ERT_RESPONSE_TYPES, KnownErtResponseTypes
|
|
@@ -22,7 +22,7 @@ logger = logging.getLogger(__name__)
|
|
|
22
22
|
class EnsembleConfig(BaseModel):
|
|
23
23
|
response_configs: dict[str, KnownErtResponseTypes] = Field(default_factory=dict)
|
|
24
24
|
parameter_configs: dict[
|
|
25
|
-
str, GenKwConfig | FieldConfig | SurfaceConfig |
|
|
25
|
+
str, GenKwConfig | FieldConfig | SurfaceConfig | EverestControl
|
|
26
26
|
] = Field(default_factory=dict)
|
|
27
27
|
|
|
28
28
|
@model_validator(mode="after")
|
|
@@ -132,7 +132,7 @@ class EnsembleConfig(BaseModel):
|
|
|
132
132
|
response_configs.append(instance)
|
|
133
133
|
|
|
134
134
|
return cls(
|
|
135
|
-
response_configs={response.
|
|
135
|
+
response_configs={response.type: response for response in response_configs},
|
|
136
136
|
parameter_configs={
|
|
137
137
|
parameter.name: parameter for parameter in parameter_configs
|
|
138
138
|
},
|
ert/config/ert_config.py
CHANGED
|
@@ -25,6 +25,7 @@ from ._design_matrix_validator import DesignMatrixValidator
|
|
|
25
25
|
from ._observations import (
|
|
26
26
|
HistoryObservation,
|
|
27
27
|
Observation,
|
|
28
|
+
RFTObservation,
|
|
28
29
|
SummaryObservation,
|
|
29
30
|
make_observations,
|
|
30
31
|
)
|
|
@@ -62,6 +63,7 @@ from .parsing import (
|
|
|
62
63
|
from .parsing.observations_parser import ObservationDict
|
|
63
64
|
from .queue_config import KnownQueueOptions, QueueConfig
|
|
64
65
|
from .refcase import Refcase
|
|
66
|
+
from .rft_config import RFTConfig
|
|
65
67
|
from .workflow import Workflow
|
|
66
68
|
from .workflow_fixtures import fixtures_per_hook
|
|
67
69
|
from .workflow_job import (
|
|
@@ -686,14 +688,6 @@ def log_observation_keys(
|
|
|
686
688
|
if key not in {"name", "type"}
|
|
687
689
|
)
|
|
688
690
|
|
|
689
|
-
if "HISTORY_OBSERVATION" in observation_type_counts:
|
|
690
|
-
msg = (
|
|
691
|
-
"HISTORY_OBSERVATION is deprecated and will be removed. "
|
|
692
|
-
"Please use SUMMARY_OBSERVATION instead."
|
|
693
|
-
)
|
|
694
|
-
ConfigWarning.warn(msg)
|
|
695
|
-
logger.warning(msg)
|
|
696
|
-
|
|
697
691
|
logger.info(
|
|
698
692
|
f"Count of observation types:\n\t{dict(observation_type_counts)}\n"
|
|
699
693
|
f"Count of observation keywords:\n\t{dict(observation_keyword_counts)}"
|
|
@@ -715,6 +709,7 @@ class ErtConfig(BaseModel):
|
|
|
715
709
|
QUEUE_OPTIONS: ClassVar[KnownQueueOptions | None] = None
|
|
716
710
|
RESERVED_KEYWORDS: ClassVar[list[str]] = RESERVED_KEYWORDS
|
|
717
711
|
ENV_VARS: ClassVar[dict[str, str]] = {}
|
|
712
|
+
PRIORITIZE_PRIVATE_IP_ADDRESS: ClassVar[bool] = False
|
|
718
713
|
|
|
719
714
|
substitutions: dict[str, str] = Field(default_factory=dict)
|
|
720
715
|
ensemble_config: EnsembleConfig = Field(default_factory=EnsembleConfig)
|
|
@@ -729,6 +724,7 @@ class ErtConfig(BaseModel):
|
|
|
729
724
|
default_factory=lambda: defaultdict(lambda: cast(list[Workflow], []))
|
|
730
725
|
)
|
|
731
726
|
runpath_file: Path = Path(DEFAULT_RUNPATH_FILE)
|
|
727
|
+
prioritize_private_ip_address: bool = False
|
|
732
728
|
|
|
733
729
|
ert_templates: list[tuple[str, str]] = Field(default_factory=list)
|
|
734
730
|
|
|
@@ -745,6 +741,18 @@ class ErtConfig(BaseModel):
|
|
|
745
741
|
@property
|
|
746
742
|
def observations(self) -> dict[str, pl.DataFrame]:
|
|
747
743
|
if self._observations is None:
|
|
744
|
+
has_rft_observations = any(
|
|
745
|
+
isinstance(o, RFTObservation) for o in self.observation_declarations
|
|
746
|
+
)
|
|
747
|
+
if (
|
|
748
|
+
has_rft_observations
|
|
749
|
+
and "rft" not in self.ensemble_config.response_configs
|
|
750
|
+
):
|
|
751
|
+
self.ensemble_config.response_configs["rft"] = RFTConfig(
|
|
752
|
+
input_files=[self.runpath_config.eclbase_format_string],
|
|
753
|
+
data_to_read={},
|
|
754
|
+
locations=[],
|
|
755
|
+
)
|
|
748
756
|
computed = create_observation_dataframes(
|
|
749
757
|
self.observation_declarations,
|
|
750
758
|
self.refcase,
|
|
@@ -752,6 +760,10 @@ class ErtConfig(BaseModel):
|
|
|
752
760
|
GenDataConfig | None,
|
|
753
761
|
self.ensemble_config.response_configs.get("gen_data", None),
|
|
754
762
|
),
|
|
763
|
+
cast(
|
|
764
|
+
RFTConfig | None,
|
|
765
|
+
self.ensemble_config.response_configs.get("rft", None),
|
|
766
|
+
),
|
|
755
767
|
self.time_map,
|
|
756
768
|
self.history_source,
|
|
757
769
|
)
|
|
@@ -848,6 +860,9 @@ class ErtConfig(BaseModel):
|
|
|
848
860
|
)
|
|
849
861
|
ENV_VARS = dict(runtime_plugins.environment_variables)
|
|
850
862
|
QUEUE_OPTIONS = runtime_plugins.queue_options
|
|
863
|
+
PRIORITIZE_PRIVATE_IP_ADDRESS = (
|
|
864
|
+
runtime_plugins.prioritize_private_ip_address
|
|
865
|
+
)
|
|
851
866
|
|
|
852
867
|
ErtConfigWithPlugins.model_rebuild()
|
|
853
868
|
assert issubclass(ErtConfigWithPlugins, ErtConfig)
|
|
@@ -1100,6 +1115,19 @@ class ErtConfig(BaseModel):
|
|
|
1100
1115
|
user_configured_.add(key)
|
|
1101
1116
|
env_vars[key] = substituter.substitute(val)
|
|
1102
1117
|
|
|
1118
|
+
prioritize_private_ip_address: bool = cls.PRIORITIZE_PRIVATE_IP_ADDRESS
|
|
1119
|
+
if ConfigKeys.PRIORITIZE_PRIVATE_IP_ADDRESS in config_dict:
|
|
1120
|
+
user_prioritize_private_ip_address = bool(
|
|
1121
|
+
config_dict[ConfigKeys.PRIORITIZE_PRIVATE_IP_ADDRESS]
|
|
1122
|
+
)
|
|
1123
|
+
if prioritize_private_ip_address != user_prioritize_private_ip_address:
|
|
1124
|
+
logger.warning(
|
|
1125
|
+
"PRIORITIZE_PRIVATE_IP_ADDRESS was overwritten by user: "
|
|
1126
|
+
f"{prioritize_private_ip_address} -> "
|
|
1127
|
+
f"{user_prioritize_private_ip_address}"
|
|
1128
|
+
)
|
|
1129
|
+
prioritize_private_ip_address = user_prioritize_private_ip_address
|
|
1130
|
+
|
|
1103
1131
|
try:
|
|
1104
1132
|
refcase = Refcase.from_config_dict(config_dict)
|
|
1105
1133
|
cls_config = cls(
|
|
@@ -1126,11 +1154,21 @@ class ErtConfig(BaseModel):
|
|
|
1126
1154
|
time_map=time_map,
|
|
1127
1155
|
history_source=history_source,
|
|
1128
1156
|
refcase=refcase,
|
|
1157
|
+
prioritize_private_ip_address=prioritize_private_ip_address,
|
|
1129
1158
|
)
|
|
1130
1159
|
|
|
1131
1160
|
# The observations are created here because create_observation_dataframes
|
|
1132
1161
|
# will perform additonal validation which needs the context in
|
|
1133
1162
|
# obs_configs which is stripped by pydantic
|
|
1163
|
+
has_rft_observations = any(
|
|
1164
|
+
isinstance(o, RFTObservation) for o in obs_configs
|
|
1165
|
+
)
|
|
1166
|
+
if has_rft_observations and "rft" not in ensemble_config.response_configs:
|
|
1167
|
+
ensemble_config.response_configs["rft"] = RFTConfig(
|
|
1168
|
+
input_files=[eclbase],
|
|
1169
|
+
data_to_read={},
|
|
1170
|
+
locations=[],
|
|
1171
|
+
)
|
|
1134
1172
|
cls_config._observations = create_observation_dataframes(
|
|
1135
1173
|
obs_configs,
|
|
1136
1174
|
refcase,
|
|
@@ -1138,6 +1176,10 @@ class ErtConfig(BaseModel):
|
|
|
1138
1176
|
GenDataConfig | None,
|
|
1139
1177
|
ensemble_config.response_configs.get("gen_data", None),
|
|
1140
1178
|
),
|
|
1179
|
+
cast(
|
|
1180
|
+
RFTConfig | None,
|
|
1181
|
+
ensemble_config.response_configs.get("rft", None),
|
|
1182
|
+
),
|
|
1141
1183
|
time_map,
|
|
1142
1184
|
history_source,
|
|
1143
1185
|
)
|
|
@@ -17,7 +17,7 @@ from ropt.workflow import find_sampler_plugin
|
|
|
17
17
|
|
|
18
18
|
from ert.substitutions import substitute_runpath_name
|
|
19
19
|
|
|
20
|
-
from .parameter_config import ParameterConfig
|
|
20
|
+
from .parameter_config import ParameterConfig
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
23
|
import numpy.typing as npt
|
|
@@ -106,7 +106,7 @@ class SamplerConfig(BaseModel):
|
|
|
106
106
|
# from "everest" here as per old behavior.
|
|
107
107
|
# Can consider logging this as if from ERT,
|
|
108
108
|
# which is valid if we store SamplerConfig as part of
|
|
109
|
-
#
|
|
109
|
+
# EverestControl configs.
|
|
110
110
|
logging.getLogger("everest").warning(message)
|
|
111
111
|
|
|
112
112
|
# Update the default for backends that are not scipy:
|
|
@@ -142,22 +142,14 @@ class SamplerConfig(BaseModel):
|
|
|
142
142
|
return self
|
|
143
143
|
|
|
144
144
|
|
|
145
|
-
class
|
|
146
|
-
"""Create an
|
|
145
|
+
class EverestControl(ParameterConfig):
|
|
146
|
+
"""Create an EverestControl for @key with the given @input_keys
|
|
147
147
|
|
|
148
148
|
@input_keys can be either a list of keys as strings or a dict with
|
|
149
149
|
keys as strings and a list of suffixes for each key.
|
|
150
150
|
If a list of strings is given, the order is preserved.
|
|
151
151
|
"""
|
|
152
152
|
|
|
153
|
-
@property
|
|
154
|
-
def parameter_keys(self) -> list[str]:
|
|
155
|
-
return self.input_keys
|
|
156
|
-
|
|
157
|
-
@property
|
|
158
|
-
def metadata(self) -> list[ParameterMetadata]:
|
|
159
|
-
return []
|
|
160
|
-
|
|
161
153
|
type: Literal["everest_parameters"] = "everest_parameters"
|
|
162
154
|
input_keys: list[str] = field(default_factory=list)
|
|
163
155
|
forward_init: bool = False
|
|
@@ -179,6 +171,10 @@ class ExtParamConfig(ParameterConfig):
|
|
|
179
171
|
# "dotdash" notation is removed for everest controls via everest config.
|
|
180
172
|
input_keys_dotdash: list[str] = field(default_factory=list)
|
|
181
173
|
|
|
174
|
+
@property
|
|
175
|
+
def parameter_keys(self) -> list[str]:
|
|
176
|
+
return self.input_keys
|
|
177
|
+
|
|
182
178
|
def read_from_runpath(
|
|
183
179
|
self, run_path: Path, real_nr: int, iteration: int
|
|
184
180
|
) -> xr.Dataset:
|