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
ert/config/everest_response.py
CHANGED
|
@@ -25,7 +25,7 @@ class EverestResponse(ResponseConfig):
|
|
|
25
25
|
def metadata(self) -> list[ResponseMetadata]:
|
|
26
26
|
return [
|
|
27
27
|
ResponseMetadata(
|
|
28
|
-
response_type=self.
|
|
28
|
+
response_type=self.type,
|
|
29
29
|
response_key=response_key,
|
|
30
30
|
finalized=self.has_finalized_keys,
|
|
31
31
|
filter_on=None,
|
|
@@ -76,12 +76,12 @@ class EverestResponse(ResponseConfig):
|
|
|
76
76
|
if all(isinstance(err, FileNotFoundError) for err in errors):
|
|
77
77
|
raise FileNotFoundError(
|
|
78
78
|
"Could not find one or more files/directories while reading "
|
|
79
|
-
f"{self.
|
|
79
|
+
f"{self.type}: {','.join([str(err) for err in errors])}"
|
|
80
80
|
)
|
|
81
81
|
else:
|
|
82
82
|
raise InvalidResponseFile(
|
|
83
83
|
"Error reading "
|
|
84
|
-
f"{self.
|
|
84
|
+
f"{self.type}, errors: {','.join([str(err) for err in errors])}"
|
|
85
85
|
)
|
|
86
86
|
|
|
87
87
|
combined = pl.concat(datasets_per_name)
|
|
@@ -90,7 +90,6 @@ class EverestResponse(ResponseConfig):
|
|
|
90
90
|
|
|
91
91
|
class EverestConstraintsConfig(EverestResponse):
|
|
92
92
|
type: Literal["everest_constraints"] = "everest_constraints"
|
|
93
|
-
name: str = "everest_constraints"
|
|
94
93
|
targets: list[float | None]
|
|
95
94
|
upper_bounds: list[float]
|
|
96
95
|
lower_bounds: list[float]
|
|
@@ -101,7 +100,6 @@ responses_index.add_response_type(EverestConstraintsConfig)
|
|
|
101
100
|
|
|
102
101
|
class EverestObjectivesConfig(EverestResponse):
|
|
103
102
|
type: Literal["everest_objectives"] = "everest_objectives"
|
|
104
|
-
name: str = "everest_objectives"
|
|
105
103
|
weights: list[float | None]
|
|
106
104
|
objective_types: list[Literal["mean", "stddev"]]
|
|
107
105
|
|
ert/config/field.py
CHANGED
|
@@ -17,16 +17,19 @@ from ert.field_utils import (
|
|
|
17
17
|
ErtboxParameters,
|
|
18
18
|
FieldFileFormat,
|
|
19
19
|
Shape,
|
|
20
|
+
calc_rho_for_2d_grid_layer,
|
|
20
21
|
calculate_ertbox_parameters,
|
|
21
22
|
get_shape,
|
|
22
23
|
read_field,
|
|
23
24
|
save_field,
|
|
25
|
+
transform_local_ellipse_angle_to_local_coords,
|
|
26
|
+
transform_positions_to_local_field_coordinates,
|
|
24
27
|
)
|
|
25
28
|
from ert.substitutions import substitute_runpath_name
|
|
26
29
|
from ert.utils import log_duration
|
|
27
30
|
|
|
28
31
|
from ._str_to_bool import str_to_bool
|
|
29
|
-
from .parameter_config import ParameterConfig
|
|
32
|
+
from .parameter_config import ParameterConfig
|
|
30
33
|
from .parsing import ConfigValidationError, ConfigWarning
|
|
31
34
|
|
|
32
35
|
if TYPE_CHECKING:
|
|
@@ -67,6 +70,7 @@ def create_flattened_cube_graph(px: int, py: int, pz: int) -> nx.Graph[int]:
|
|
|
67
70
|
|
|
68
71
|
class Field(ParameterConfig):
|
|
69
72
|
type: Literal["field"] = "field"
|
|
73
|
+
dimensionality: Literal[3] = 3
|
|
70
74
|
ertbox_params: ErtboxParameters
|
|
71
75
|
file_format: FieldFileFormat
|
|
72
76
|
output_transformation: str | None
|
|
@@ -85,17 +89,6 @@ class Field(ParameterConfig):
|
|
|
85
89
|
def parameter_keys(self) -> list[str]:
|
|
86
90
|
return []
|
|
87
91
|
|
|
88
|
-
@property
|
|
89
|
-
def metadata(self) -> list[ParameterMetadata]:
|
|
90
|
-
return [
|
|
91
|
-
ParameterMetadata(
|
|
92
|
-
key=self.name,
|
|
93
|
-
transformation=self.output_transformation,
|
|
94
|
-
dimensionality=3,
|
|
95
|
-
userdata={"data_origin": "FIELD", "ertbox_params": self.ertbox_params},
|
|
96
|
-
)
|
|
97
|
-
]
|
|
98
|
-
|
|
99
92
|
@classmethod
|
|
100
93
|
def from_config_list(
|
|
101
94
|
cls,
|
|
@@ -277,7 +270,7 @@ class Field(ParameterConfig):
|
|
|
277
270
|
ensemble_size = len(ds.realizations)
|
|
278
271
|
da = xr.DataArray(
|
|
279
272
|
[
|
|
280
|
-
np.ma.MaskedArray(data=d).compressed()
|
|
273
|
+
np.ma.MaskedArray(data=d).compressed()
|
|
281
274
|
for d in ds["values"].values.reshape(ensemble_size, -1)
|
|
282
275
|
]
|
|
283
276
|
)
|
|
@@ -291,7 +284,7 @@ class Field(ParameterConfig):
|
|
|
291
284
|
def _transform_data(
|
|
292
285
|
self, data_array: xr.DataArray
|
|
293
286
|
) -> np.ma.MaskedArray[Any, np.dtype[np.float32]]:
|
|
294
|
-
return np.ma.MaskedArray(
|
|
287
|
+
return np.ma.MaskedArray(
|
|
295
288
|
_field_truncate(
|
|
296
289
|
field_transform(
|
|
297
290
|
data_array,
|
|
@@ -325,6 +318,75 @@ class Field(ParameterConfig):
|
|
|
325
318
|
def nz(self) -> int:
|
|
326
319
|
return self.ertbox_params.nz
|
|
327
320
|
|
|
321
|
+
def calc_rho_for_2d_grid_layer(
|
|
322
|
+
self,
|
|
323
|
+
obs_xpos: npt.NDArray[np.float64],
|
|
324
|
+
obs_ypos: npt.NDArray[np.float64],
|
|
325
|
+
obs_main_range: npt.NDArray[np.float64],
|
|
326
|
+
obs_perp_range: npt.NDArray[np.float64],
|
|
327
|
+
obs_anisotropy_angle: npt.NDArray[np.float64],
|
|
328
|
+
right_handed_grid_indexing: bool = True,
|
|
329
|
+
) -> npt.NDArray[np.float64]:
|
|
330
|
+
"""Function to calculate scaling values to be used in the RHO matrix
|
|
331
|
+
for distance-based localization.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
obs_xpos: x-coordinates in global coordinates of observations
|
|
335
|
+
obs_ypos: y-coordinates in global coordinates of observations
|
|
336
|
+
obs_main_range: Size of influence ellipse main principal direction.
|
|
337
|
+
obs_perp_range: Size of influence ellipse second principal direction.
|
|
338
|
+
obs_anisotropy_angle: Rotation angle anticlock wise of main principal
|
|
339
|
+
direction of influence ellipse relative to global coordinate
|
|
340
|
+
system's x-axis.
|
|
341
|
+
right_handed_grid_indexing: When this is True the field parameters
|
|
342
|
+
grid index order counts J-index down from ny-1 to 0.
|
|
343
|
+
If the value is False, the grid index order is to count J index
|
|
344
|
+
from 0 to ny-1. As standard for 3D field parameters,
|
|
345
|
+
the grid index order follows the right_handed grid indexing.
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
Scaling values (elements of the RHO matrix) as a numpy array
|
|
349
|
+
of shape=(nx,ny,nobservations)
|
|
350
|
+
|
|
351
|
+
"""
|
|
352
|
+
# Can only be used if ertbox coordinate system is defined
|
|
353
|
+
assert self.ertbox_params.xinc is not None, (
|
|
354
|
+
"Parameter for grid resolution must be defined"
|
|
355
|
+
)
|
|
356
|
+
assert self.ertbox_params.yinc is not None, (
|
|
357
|
+
"Parameter for grid resolution must be defined"
|
|
358
|
+
)
|
|
359
|
+
assert self.ertbox_params.origin is not None, (
|
|
360
|
+
"Parameter for grid origin must be defined"
|
|
361
|
+
)
|
|
362
|
+
assert self.ertbox_params.rotation_angle is not None, (
|
|
363
|
+
"Parameter for grid rotation must be defined"
|
|
364
|
+
)
|
|
365
|
+
# Transform positions of observations into local coordinates
|
|
366
|
+
xpos, ypos = transform_positions_to_local_field_coordinates(
|
|
367
|
+
self.ertbox_params.origin,
|
|
368
|
+
self.ertbox_params.rotation_angle,
|
|
369
|
+
obs_xpos,
|
|
370
|
+
obs_ypos,
|
|
371
|
+
)
|
|
372
|
+
# Transform localization ellipse orientation to local coordinates
|
|
373
|
+
ellipse_rotation = transform_local_ellipse_angle_to_local_coords(
|
|
374
|
+
self.ertbox_params.rotation_angle, obs_anisotropy_angle
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
return calc_rho_for_2d_grid_layer(
|
|
378
|
+
self.ertbox_params.nx,
|
|
379
|
+
self.ertbox_params.ny,
|
|
380
|
+
self.ertbox_params.xinc,
|
|
381
|
+
self.ertbox_params.yinc,
|
|
382
|
+
xpos,
|
|
383
|
+
ypos,
|
|
384
|
+
obs_main_range,
|
|
385
|
+
obs_perp_range,
|
|
386
|
+
ellipse_rotation,
|
|
387
|
+
right_handed_grid_indexing=right_handed_grid_indexing,
|
|
388
|
+
)
|
|
389
|
+
|
|
328
390
|
|
|
329
391
|
TRANSFORM_FUNCTIONS: Final[dict[str, Callable[[Any], Any]]] = {
|
|
330
392
|
"LN": np.log,
|
ert/config/forward_model_step.py
CHANGED
|
@@ -101,15 +101,18 @@ class ForwardModelStepDocumentation(BaseModel):
|
|
|
101
101
|
source_function_name: str = Field(default="ert")
|
|
102
102
|
description: str = Field(default="No description")
|
|
103
103
|
examples: str = Field(default="No examples")
|
|
104
|
-
category:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
"
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
104
|
+
category: Annotated[
|
|
105
|
+
str,
|
|
106
|
+
Field(
|
|
107
|
+
default="Uncategorized",
|
|
108
|
+
examples=[
|
|
109
|
+
"utility.file_system",
|
|
110
|
+
"simulators.reservoir",
|
|
111
|
+
"modelling.reservoir",
|
|
112
|
+
"utility.templating",
|
|
113
|
+
],
|
|
114
|
+
),
|
|
115
|
+
]
|
|
113
116
|
|
|
114
117
|
|
|
115
118
|
class ForwardModelStep(BaseModelWithContextSupport):
|
ert/config/gen_data_config.py
CHANGED
|
@@ -21,7 +21,6 @@ from .responses_index import responses_index
|
|
|
21
21
|
|
|
22
22
|
class GenDataConfig(ResponseConfig):
|
|
23
23
|
type: Literal["gen_data"] = "gen_data"
|
|
24
|
-
name: str = "gen_data"
|
|
25
24
|
report_steps_list: list[list[int] | None] = Field(default_factory=list)
|
|
26
25
|
has_finalized_keys: bool = True
|
|
27
26
|
|
|
@@ -29,7 +28,7 @@ class GenDataConfig(ResponseConfig):
|
|
|
29
28
|
def metadata(self) -> list[ResponseMetadata]:
|
|
30
29
|
return [
|
|
31
30
|
ResponseMetadata(
|
|
32
|
-
response_type=self.
|
|
31
|
+
response_type=self.type,
|
|
33
32
|
response_key=response_key,
|
|
34
33
|
finalized=self.has_finalized_keys,
|
|
35
34
|
filter_on={"report_step": report_steps}
|
|
@@ -198,12 +197,12 @@ class GenDataConfig(ResponseConfig):
|
|
|
198
197
|
if all(isinstance(err, FileNotFoundError) for err in errors):
|
|
199
198
|
raise FileNotFoundError(
|
|
200
199
|
"Could not find one or more files/directories while reading "
|
|
201
|
-
f"GEN_DATA
|
|
200
|
+
f"GEN_DATA: {','.join([str(err) for err in errors])}"
|
|
202
201
|
)
|
|
203
202
|
else:
|
|
204
203
|
raise InvalidResponseFile(
|
|
205
204
|
"Error reading GEN_DATA "
|
|
206
|
-
f"{self.
|
|
205
|
+
f"{self.type}, errors: {','.join([str(err) for err in errors])}"
|
|
207
206
|
)
|
|
208
207
|
|
|
209
208
|
combined = pl.concat(datasets_per_name)
|
ert/config/gen_kw_config.py
CHANGED
|
@@ -15,7 +15,7 @@ from typing_extensions import TypedDict
|
|
|
15
15
|
|
|
16
16
|
from ._str_to_bool import str_to_bool
|
|
17
17
|
from .distribution import DISTRIBUTION_CLASSES, DistributionSettings, get_distribution
|
|
18
|
-
from .parameter_config import ParameterCardinality, ParameterConfig
|
|
18
|
+
from .parameter_config import ParameterCardinality, ParameterConfig
|
|
19
19
|
from .parsing import ConfigValidationError, ConfigWarning
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING:
|
|
@@ -53,6 +53,7 @@ class DataSource(StrEnum):
|
|
|
53
53
|
|
|
54
54
|
class GenKwConfig(ParameterConfig):
|
|
55
55
|
type: Literal["gen_kw"] = "gen_kw"
|
|
56
|
+
dimensionality: Literal[1] = 1
|
|
56
57
|
distribution: DistributionSettings
|
|
57
58
|
forward_init: bool = False
|
|
58
59
|
update: bool = True
|
|
@@ -73,17 +74,6 @@ class GenKwConfig(ParameterConfig):
|
|
|
73
74
|
def cardinality(self) -> ParameterCardinality:
|
|
74
75
|
return ParameterCardinality.multiple_configs_per_ensemble_dataset
|
|
75
76
|
|
|
76
|
-
@property
|
|
77
|
-
def metadata(self) -> list[ParameterMetadata]:
|
|
78
|
-
return [
|
|
79
|
-
ParameterMetadata(
|
|
80
|
-
key=f"{self.group}:{self.name}",
|
|
81
|
-
transformation=self.distribution.name.upper(),
|
|
82
|
-
dimensionality=1,
|
|
83
|
-
userdata={"data_origin": "GEN_KW"},
|
|
84
|
-
)
|
|
85
|
-
]
|
|
86
|
-
|
|
87
77
|
@classmethod
|
|
88
78
|
def templates_from_config(
|
|
89
79
|
cls, gen_kw: list[str | dict[str, str]]
|
ert/config/parameter_config.py
CHANGED
|
@@ -5,7 +5,7 @@ from collections.abc import Callable, Iterator
|
|
|
5
5
|
from enum import StrEnum, auto
|
|
6
6
|
from hashlib import sha256
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
9
|
|
|
10
10
|
import networkx as nx
|
|
11
11
|
import numpy as np
|
|
@@ -39,13 +39,6 @@ class ParameterCardinality(StrEnum):
|
|
|
39
39
|
one_config_per_realization_dataset = auto()
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class ParameterMetadata(BaseModel):
|
|
43
|
-
key: str
|
|
44
|
-
transformation: str | None
|
|
45
|
-
dimensionality: Literal[1, 2, 3] = 1
|
|
46
|
-
userdata: dict[str, Any]
|
|
47
|
-
|
|
48
|
-
|
|
49
42
|
class ParameterConfig(BaseModel):
|
|
50
43
|
type: str
|
|
51
44
|
name: str
|
|
@@ -59,14 +52,6 @@ class ParameterConfig(BaseModel):
|
|
|
59
52
|
Returns a list of parameter keys within this parameter group
|
|
60
53
|
"""
|
|
61
54
|
|
|
62
|
-
@property
|
|
63
|
-
@abstractmethod
|
|
64
|
-
def metadata(self) -> list[ParameterMetadata]:
|
|
65
|
-
"""
|
|
66
|
-
Returns metadata describing this parameter
|
|
67
|
-
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
55
|
@abstractmethod
|
|
71
56
|
def __len__(self) -> int:
|
|
72
57
|
"""Number of parameters"""
|
|
@@ -48,13 +48,21 @@ def option_dict(option_list: Sequence[str], offset: int) -> dict[str, str]:
|
|
|
48
48
|
if len(option_pair.split(":")) == 2:
|
|
49
49
|
key, val = option_pair.split(":")
|
|
50
50
|
if val and key:
|
|
51
|
+
if key in result:
|
|
52
|
+
raise ConfigValidationError.with_context(
|
|
53
|
+
f"Option {key} occured multiple times.", option_pair
|
|
54
|
+
)
|
|
51
55
|
result[key] = val
|
|
52
56
|
else:
|
|
53
57
|
raise ConfigValidationError.with_context(
|
|
54
|
-
|
|
58
|
+
"Option argument should be of the form 'key':'value', "
|
|
59
|
+
f"got {option_pair!r}",
|
|
60
|
+
option_pair,
|
|
55
61
|
)
|
|
56
62
|
else:
|
|
57
63
|
raise ConfigValidationError.with_context(
|
|
58
|
-
|
|
64
|
+
"Option argument should be of the form 'key':'value', "
|
|
65
|
+
f"got {option_pair!r}",
|
|
66
|
+
option_pair,
|
|
59
67
|
)
|
|
60
68
|
return result
|
|
@@ -56,6 +56,7 @@ class ConfigKeys(StrEnum):
|
|
|
56
56
|
REALIZATION_MEMORY = "REALIZATION_MEMORY"
|
|
57
57
|
SUBMIT_SLEEP = "SUBMIT_SLEEP"
|
|
58
58
|
MAX_RUNNING = "MAX_RUNNING"
|
|
59
|
+
PRIORITIZE_PRIVATE_IP_ADDRESS = "PRIORITIZE_PRIVATE_IP_ADDRESS"
|
|
59
60
|
|
|
60
61
|
def __repr__(self) -> str:
|
|
61
62
|
return f"{self.value!r}"
|
|
@@ -126,6 +126,13 @@ def hook_workflow_keyword() -> SchemaItem:
|
|
|
126
126
|
)
|
|
127
127
|
|
|
128
128
|
|
|
129
|
+
def prioritize_private_ip_address_keyword() -> SchemaItem:
|
|
130
|
+
return SchemaItem(
|
|
131
|
+
kw=ConfigKeys.PRIORITIZE_PRIVATE_IP_ADDRESS,
|
|
132
|
+
type_map=[SchemaItemType.BOOL],
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
129
136
|
def set_env_keyword() -> SchemaItem:
|
|
130
137
|
# You can set environment variables which will be applied to the run-time
|
|
131
138
|
# environment.
|
|
@@ -349,6 +356,7 @@ def init_user_config_schema() -> ConfigSchemaDict:
|
|
|
349
356
|
install_job_keyword(),
|
|
350
357
|
install_job_directory_keyword(),
|
|
351
358
|
hook_workflow_keyword(),
|
|
359
|
+
prioritize_private_ip_address_keyword(),
|
|
352
360
|
]:
|
|
353
361
|
schema[item.kw] = item
|
|
354
362
|
if item.kw in ConfigAliases:
|
|
@@ -39,9 +39,9 @@ deprecated_keywords_list = [
|
|
|
39
39
|
keyword=kw,
|
|
40
40
|
message=partial(
|
|
41
41
|
lambda line, kw: f"Using {kw} with substitution strings "
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
"that are not of the form '<KEY>' is deprecated. "
|
|
43
|
+
f"Please change {line[0]} to "
|
|
44
|
+
f"<{line[0].replace('<', '').replace('>', '')}>",
|
|
45
45
|
kw=kw,
|
|
46
46
|
),
|
|
47
47
|
check=lambda line: not DeprecationInfo.is_angle_bracketed(str(line[0])),
|
|
@@ -217,4 +217,15 @@ deprecated_keywords_list = [
|
|
|
217
217
|
),
|
|
218
218
|
check=lambda line: line[0] == "DESIGN2PARAMS",
|
|
219
219
|
),
|
|
220
|
+
DeprecationInfo(
|
|
221
|
+
keyword="FORWARD_MODEL",
|
|
222
|
+
message=(
|
|
223
|
+
"FORWARD_MODEL DESIGN_KW will be replaced with RUN_TEMPLATE. "
|
|
224
|
+
"DESIGN2PARAMS has been replaced by DESIGN_MATRIX, so the "
|
|
225
|
+
"parameters are already available for magic string replacement "
|
|
226
|
+
"with the RUN_TEMPLATE keyword. Please use this format: "
|
|
227
|
+
"'RUN_TEMPLATE my_text_file_template.txt my_text_output_file.txt'"
|
|
228
|
+
),
|
|
229
|
+
check=lambda line: line[0] == "DESIGN_KW",
|
|
230
|
+
),
|
|
220
231
|
]
|
|
@@ -37,25 +37,34 @@ class SchemaItem:
|
|
|
37
37
|
|
|
38
38
|
# The minimum number of arguments
|
|
39
39
|
argc_min: NonNegativeInt = 1
|
|
40
|
+
|
|
40
41
|
# The maximum number of arguments: None means no upper limit
|
|
41
42
|
argc_max: NonNegativeInt | None = 1
|
|
43
|
+
|
|
42
44
|
# A list of types for the items. Set along with argc_minmax()
|
|
43
45
|
type_map: list[SchemaItemType | EnumType | None] = Field(default_factory=list)
|
|
46
|
+
|
|
44
47
|
# A list of item's which must also be set (if this item is set). (can be NULL)
|
|
45
48
|
required_children: list[str] = Field(default_factory=list)
|
|
49
|
+
|
|
46
50
|
# Information about the deprecation if deprecated
|
|
47
51
|
deprecation_info: list[DeprecationInfo] = Field(default_factory=list)
|
|
48
|
-
|
|
52
|
+
|
|
53
|
+
# If positive, arguments after this count will be concatenated with a " " between
|
|
49
54
|
join_after: PositiveInt | None = None
|
|
50
|
-
|
|
55
|
+
|
|
56
|
+
# If positive, arguments after this count will be interpreted as options
|
|
51
57
|
options_after: NonNegativeInt | Varies | None = None
|
|
52
|
-
|
|
58
|
+
|
|
59
|
+
# If true, will accumulate many values set for key, otherwise each entry will
|
|
53
60
|
# overwrite any previous value set
|
|
54
61
|
multi_occurrence: bool = False
|
|
62
|
+
|
|
55
63
|
# Only applies to SchemaItemType.EXISTING_PATH_INLINE where
|
|
56
64
|
# the contents is then parsed
|
|
57
65
|
parser: Callable[[str, str], Any] = lambda x, y: y
|
|
58
66
|
expand_envvar: bool = True
|
|
67
|
+
|
|
59
68
|
# Index of tokens to do substitution from until end
|
|
60
69
|
substitute_from: NonNegativeInt = 1
|
|
61
70
|
required_set: bool = False
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from json import JSONEncoder
|
|
4
|
-
from typing import Any, TypeVar, no_type_check
|
|
4
|
+
from typing import Any, Self, TypeVar, no_type_check
|
|
5
5
|
|
|
6
6
|
from .file_context_token import FileContextToken
|
|
7
7
|
|
|
@@ -37,7 +37,7 @@ class ContextBool:
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class ContextInt(int):
|
|
40
|
-
def __new__(cls, val: int, token: FileContextToken) ->
|
|
40
|
+
def __new__(cls, val: int, token: FileContextToken) -> Self:
|
|
41
41
|
obj = super().__new__(cls, val)
|
|
42
42
|
obj.token = token
|
|
43
43
|
return obj
|
|
@@ -50,7 +50,7 @@ class ContextInt(int):
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
class ContextFloat(float):
|
|
53
|
-
def __new__(cls, val: float, token: FileContextToken) ->
|
|
53
|
+
def __new__(cls, val: float, token: FileContextToken) -> Self:
|
|
54
54
|
obj = super().__new__(cls, val)
|
|
55
55
|
obj.token = token
|
|
56
56
|
return obj
|
|
@@ -18,6 +18,7 @@ class ObservationType(StrEnum):
|
|
|
18
18
|
HISTORY = "HISTORY_OBSERVATION"
|
|
19
19
|
SUMMARY = "SUMMARY_OBSERVATION"
|
|
20
20
|
GENERAL = "GENERAL_OBSERVATION"
|
|
21
|
+
RFT = "RFT_OBSERVATION"
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
ObservationDict = dict[str, Any]
|
|
@@ -92,7 +93,7 @@ def parse_observations(content: str, filename: str) -> list[ObservationDict]:
|
|
|
92
93
|
), ["TYPE"]:
|
|
93
94
|
message = (
|
|
94
95
|
f"Unknown observation type '{unexpected_token}', "
|
|
95
|
-
f"expected either 'GENERAL_OBSERVATION', "
|
|
96
|
+
f"expected either 'RFT_OBSERVATION', 'GENERAL_OBSERVATION', "
|
|
96
97
|
f"'SUMMARY_OBSERVATION' or 'HISTORY_OBSERVATION'."
|
|
97
98
|
)
|
|
98
99
|
case UnexpectedToken(token=unexpected_char, expected=allowed_chars), _:
|
|
@@ -122,7 +123,10 @@ observations_parser = Lark(
|
|
|
122
123
|
r"""
|
|
123
124
|
start: observation*
|
|
124
125
|
?observation: type OBSERVATION_NAME object? ";"
|
|
125
|
-
TYPE: "HISTORY_OBSERVATION"
|
|
126
|
+
TYPE: "HISTORY_OBSERVATION"
|
|
127
|
+
| "SUMMARY_OBSERVATION"
|
|
128
|
+
| "GENERAL_OBSERVATION"
|
|
129
|
+
| "RFT_OBSERVATION"
|
|
126
130
|
type: TYPE
|
|
127
131
|
?value: object
|
|
128
132
|
| STRING
|
|
@@ -23,3 +23,12 @@ class QueueSystem(StrEnum):
|
|
|
23
23
|
@staticmethod
|
|
24
24
|
def ert_config_case() -> str:
|
|
25
25
|
return "upper"
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def formatted_name(self) -> str:
|
|
29
|
+
return {
|
|
30
|
+
self.LSF: "LSF",
|
|
31
|
+
self.LOCAL: "Local",
|
|
32
|
+
self.TORQUE: "Torque/OpenPBS",
|
|
33
|
+
self.SLURM: "Slurm",
|
|
34
|
+
}[self]
|
ert/config/queue_config.py
CHANGED
ert/config/response_config.py
CHANGED