ert 19.0.0__py3-none-any.whl → 19.0.0rc1__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/__main__.py +94 -63
- ert/analysis/_es_update.py +11 -14
- ert/config/_create_observation_dataframes.py +12 -228
- ert/config/_observations.py +164 -152
- ert/config/_read_summary.py +4 -5
- ert/config/ert_config.py +1 -56
- ert/config/observation_config_migrations.py +793 -0
- ert/config/rft_config.py +1 -1
- ert/dark_storage/compute/misfits.py +0 -42
- ert/dark_storage/endpoints/__init__.py +0 -2
- ert/dark_storage/endpoints/experiments.py +0 -3
- ert/dark_storage/json_schema/experiment.py +0 -1
- ert/field_utils/grdecl_io.py +9 -26
- ert/gui/main_window.py +2 -0
- ert/gui/tools/manage_experiments/export_dialog.py +4 -0
- ert/gui/tools/manage_experiments/storage_info_widget.py +1 -5
- ert/gui/tools/plot/plot_api.py +10 -10
- ert/gui/tools/plot/plot_widget.py +12 -14
- ert/gui/tools/plot/plot_window.py +1 -10
- ert/services/__init__.py +7 -3
- ert/services/_storage_main.py +59 -22
- ert/services/ert_server.py +186 -24
- ert/shared/version.py +3 -3
- ert/storage/local_ensemble.py +3 -107
- ert/storage/local_experiment.py +0 -16
- ert/storage/local_storage.py +1 -3
- ert/utils/__init__.py +20 -0
- {ert-19.0.0.dist-info → ert-19.0.0rc1.dist-info}/METADATA +2 -2
- {ert-19.0.0.dist-info → ert-19.0.0rc1.dist-info}/RECORD +40 -47
- {ert-19.0.0.dist-info → ert-19.0.0rc1.dist-info}/WHEEL +1 -1
- everest/bin/everest_script.py +5 -5
- everest/bin/kill_script.py +2 -2
- everest/bin/monitor_script.py +2 -2
- everest/bin/utils.py +4 -4
- everest/detached/everserver.py +6 -6
- everest/gui/main_window.py +2 -2
- everest/util/__init__.py +1 -19
- ert/dark_storage/compute/__init__.py +0 -0
- ert/dark_storage/endpoints/compute/__init__.py +0 -0
- ert/dark_storage/endpoints/compute/misfits.py +0 -95
- ert/services/_base_service.py +0 -387
- ert/services/webviz_ert_service.py +0 -20
- ert/shared/storage/command.py +0 -38
- ert/shared/storage/extraction.py +0 -42
- ert/storage/migration/to23.py +0 -49
- {ert-19.0.0.dist-info → ert-19.0.0rc1.dist-info}/entry_points.txt +0 -0
- {ert-19.0.0.dist-info → ert-19.0.0rc1.dist-info}/licenses/COPYING +0 -0
- {ert-19.0.0.dist-info → ert-19.0.0rc1.dist-info}/top_level.txt +0 -0
ert/config/_observations.py
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
1
4
|
import os
|
|
2
5
|
from collections.abc import Sequence
|
|
3
6
|
from dataclasses import dataclass
|
|
4
7
|
from enum import StrEnum
|
|
5
|
-
from itertools import starmap
|
|
6
8
|
from typing import Any, Self
|
|
7
9
|
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
8
12
|
from .parsing import (
|
|
9
13
|
ErrorInfo,
|
|
10
14
|
ObservationConfigError,
|
|
@@ -12,6 +16,8 @@ from .parsing import (
|
|
|
12
16
|
ObservationType,
|
|
13
17
|
)
|
|
14
18
|
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
15
21
|
|
|
16
22
|
class ErrorModes(StrEnum):
|
|
17
23
|
REL = "REL"
|
|
@@ -19,102 +25,52 @@ class ErrorModes(StrEnum):
|
|
|
19
25
|
RELMIN = "RELMIN"
|
|
20
26
|
|
|
21
27
|
|
|
22
|
-
@dataclass
|
|
23
|
-
class ObservationError:
|
|
24
|
-
error_mode: ErrorModes
|
|
25
|
-
error: float
|
|
26
|
-
error_min: float
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@dataclass
|
|
30
|
-
class Segment(ObservationError):
|
|
31
|
-
name: str
|
|
32
|
-
start: int
|
|
33
|
-
stop: int
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@dataclass
|
|
37
|
-
class HistoryObservation(ObservationError):
|
|
38
|
-
name: str
|
|
39
|
-
segments: list[Segment]
|
|
40
|
-
|
|
41
|
-
@property
|
|
42
|
-
def key(self) -> str:
|
|
43
|
-
"""The :term:`summary key` to be fetched from :ref:`refcase`."""
|
|
44
|
-
# For history observations the key is also the name, ie.
|
|
45
|
-
# "HISTORY_OBSERVATION FOPR" means to add the values from
|
|
46
|
-
# the summary vector FOPRH in refcase as observations.
|
|
47
|
-
return self.name
|
|
48
|
-
|
|
49
|
-
@classmethod
|
|
50
|
-
def from_obs_dict(cls, directory: str, observation_dict: ObservationDict) -> Self:
|
|
51
|
-
error_mode = ErrorModes.RELMIN
|
|
52
|
-
error = 0.1
|
|
53
|
-
error_min = 0.1
|
|
54
|
-
segments = []
|
|
55
|
-
for key, value in observation_dict.items():
|
|
56
|
-
match key:
|
|
57
|
-
case "type" | "name":
|
|
58
|
-
pass
|
|
59
|
-
case "ERROR":
|
|
60
|
-
error = validate_positive_float(value, key)
|
|
61
|
-
case "ERROR_MIN":
|
|
62
|
-
error_min = validate_positive_float(value, key)
|
|
63
|
-
case "ERROR_MODE":
|
|
64
|
-
error_mode = validate_error_mode(value)
|
|
65
|
-
case "segments":
|
|
66
|
-
segments = list(starmap(_validate_segment_dict, value))
|
|
67
|
-
case _:
|
|
68
|
-
raise _unknown_key_error(str(key), observation_dict["name"])
|
|
69
|
-
|
|
70
|
-
return cls(
|
|
71
|
-
name=observation_dict["name"],
|
|
72
|
-
error_mode=error_mode,
|
|
73
|
-
error=error,
|
|
74
|
-
error_min=error_min,
|
|
75
|
-
segments=segments,
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@dataclass
|
|
80
|
-
class ObservationDate:
|
|
81
|
-
days: float | None = None
|
|
82
|
-
hours: float | None = None
|
|
83
|
-
date: str | None = None
|
|
84
|
-
restart: int | None = None
|
|
85
|
-
|
|
86
|
-
|
|
87
28
|
@dataclass
|
|
88
29
|
class _SummaryValues:
|
|
89
30
|
name: str
|
|
90
31
|
value: float
|
|
91
32
|
key: str #: The :term:`summary key` in the summary response
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
33
|
+
date: str
|
|
34
|
+
location_x: float | None = None
|
|
35
|
+
location_y: float | None = None
|
|
36
|
+
location_range: float | None = None
|
|
95
37
|
|
|
96
38
|
|
|
97
39
|
@dataclass
|
|
98
|
-
class
|
|
40
|
+
class ObservationError:
|
|
41
|
+
error_mode: ErrorModes
|
|
42
|
+
error: float
|
|
43
|
+
error_min: float
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class SummaryObservation(_SummaryValues, ObservationError):
|
|
99
48
|
@classmethod
|
|
100
|
-
def from_obs_dict(
|
|
49
|
+
def from_obs_dict(
|
|
50
|
+
cls, directory: str, observation_dict: ObservationDict
|
|
51
|
+
) -> list[Self]:
|
|
101
52
|
error_mode = ErrorModes.ABS
|
|
102
53
|
summary_key = None
|
|
103
54
|
|
|
104
|
-
|
|
55
|
+
date: str | None = None
|
|
105
56
|
float_values: dict[str, float] = {"ERROR_MIN": 0.1}
|
|
106
57
|
localization_values: dict[str, float | None] = {}
|
|
107
58
|
for key, value in observation_dict.items():
|
|
108
59
|
match key:
|
|
109
60
|
case "type" | "name":
|
|
110
61
|
pass
|
|
111
|
-
case "RESTART":
|
|
112
|
-
date_dict.restart = validate_positive_int(value, key)
|
|
113
62
|
case "ERROR" | "ERROR_MIN":
|
|
114
63
|
float_values[str(key)] = validate_positive_float(value, key)
|
|
115
|
-
case "DAYS" | "HOURS":
|
|
116
|
-
|
|
117
|
-
|
|
64
|
+
case "DAYS" | "HOURS" | "RESTART":
|
|
65
|
+
raise ObservationConfigError.with_context(
|
|
66
|
+
(
|
|
67
|
+
"SUMMARY_OBSERVATION must use DATE to specify "
|
|
68
|
+
"date, DAYS | HOURS is no longer allowed. "
|
|
69
|
+
"Please run:\n ert convert_observations "
|
|
70
|
+
"<your_ert_config.ert>\nto migrate the observation config "
|
|
71
|
+
"to use the correct format."
|
|
72
|
+
),
|
|
73
|
+
key,
|
|
118
74
|
)
|
|
119
75
|
case "VALUE":
|
|
120
76
|
float_values[str(key)] = validate_float(value, key)
|
|
@@ -123,12 +79,12 @@ class SummaryObservation(ObservationDate, _SummaryValues, ObservationError):
|
|
|
123
79
|
case "KEY":
|
|
124
80
|
summary_key = value
|
|
125
81
|
case "DATE":
|
|
126
|
-
|
|
82
|
+
date = value
|
|
127
83
|
case "LOCALIZATION":
|
|
128
84
|
validate_localization(value, observation_dict["name"])
|
|
129
|
-
localization_values["
|
|
130
|
-
localization_values["
|
|
131
|
-
localization_values["
|
|
85
|
+
localization_values["x"] = validate_float(value["EAST"], key)
|
|
86
|
+
localization_values["y"] = validate_float(value["NORTH"], key)
|
|
87
|
+
localization_values["range"] = (
|
|
132
88
|
validate_float(value["RADIUS"], key)
|
|
133
89
|
if "RADIUS" in value
|
|
134
90
|
else None
|
|
@@ -142,18 +98,21 @@ class SummaryObservation(ObservationDate, _SummaryValues, ObservationError):
|
|
|
142
98
|
if "ERROR" not in float_values:
|
|
143
99
|
raise _missing_value_error(observation_dict["name"], "ERROR")
|
|
144
100
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
101
|
+
assert date is not None
|
|
102
|
+
return [
|
|
103
|
+
cls(
|
|
104
|
+
name=observation_dict["name"],
|
|
105
|
+
error_mode=error_mode,
|
|
106
|
+
error=float_values["ERROR"],
|
|
107
|
+
error_min=float_values["ERROR_MIN"],
|
|
108
|
+
key=summary_key,
|
|
109
|
+
value=float_values["VALUE"],
|
|
110
|
+
location_x=localization_values.get("x"),
|
|
111
|
+
location_y=localization_values.get("y"),
|
|
112
|
+
location_range=localization_values.get("range"),
|
|
113
|
+
date=date,
|
|
114
|
+
)
|
|
115
|
+
]
|
|
157
116
|
|
|
158
117
|
|
|
159
118
|
@dataclass
|
|
@@ -165,12 +124,15 @@ class _GeneralObservation:
|
|
|
165
124
|
index_list: str | None = None
|
|
166
125
|
index_file: str | None = None
|
|
167
126
|
obs_file: str | None = None
|
|
127
|
+
restart: int | None = None
|
|
168
128
|
|
|
169
129
|
|
|
170
130
|
@dataclass
|
|
171
|
-
class GeneralObservation(
|
|
131
|
+
class GeneralObservation(_GeneralObservation):
|
|
172
132
|
@classmethod
|
|
173
|
-
def from_obs_dict(
|
|
133
|
+
def from_obs_dict(
|
|
134
|
+
cls, directory: str, observation_dict: ObservationDict
|
|
135
|
+
) -> list[Self]:
|
|
174
136
|
try:
|
|
175
137
|
data = observation_dict["DATA"]
|
|
176
138
|
except KeyError as err:
|
|
@@ -185,12 +147,22 @@ class GeneralObservation(ObservationDate, _GeneralObservation):
|
|
|
185
147
|
output.restart = validate_positive_int(value, key)
|
|
186
148
|
case "VALUE":
|
|
187
149
|
output.value = validate_float(value, key)
|
|
188
|
-
case "ERROR"
|
|
150
|
+
case "ERROR":
|
|
189
151
|
setattr(
|
|
190
152
|
output, str(key).lower(), validate_positive_float(value, key)
|
|
191
153
|
)
|
|
192
|
-
case "DATE" | "
|
|
193
|
-
|
|
154
|
+
case "DATE" | "DAYS" | "HOURS":
|
|
155
|
+
raise ObservationConfigError.with_context(
|
|
156
|
+
(
|
|
157
|
+
"GENERAL_OBSERVATION must use RESTART to specify "
|
|
158
|
+
"report step. Please run:\n ert convert_observations "
|
|
159
|
+
"<your_ert_config.ert>\nto migrate the observation config "
|
|
160
|
+
"to use the correct format."
|
|
161
|
+
),
|
|
162
|
+
key,
|
|
163
|
+
)
|
|
164
|
+
case "INDEX_LIST":
|
|
165
|
+
output.index_list = value
|
|
194
166
|
case "OBS_FILE" | "INDEX_FILE":
|
|
195
167
|
assert not isinstance(key, tuple)
|
|
196
168
|
filename = value
|
|
@@ -213,7 +185,8 @@ class GeneralObservation(ObservationDate, _GeneralObservation):
|
|
|
213
185
|
f" VALUE = {output.value}, ERROR must also be given.",
|
|
214
186
|
observation_dict["name"],
|
|
215
187
|
)
|
|
216
|
-
|
|
188
|
+
|
|
189
|
+
return [output]
|
|
217
190
|
|
|
218
191
|
|
|
219
192
|
@dataclass
|
|
@@ -229,7 +202,63 @@ class RFTObservation:
|
|
|
229
202
|
tvd: float
|
|
230
203
|
|
|
231
204
|
@classmethod
|
|
232
|
-
def
|
|
205
|
+
def from_csv(
|
|
206
|
+
cls,
|
|
207
|
+
directory: str,
|
|
208
|
+
observation_dict: ObservationDict,
|
|
209
|
+
filename: str,
|
|
210
|
+
observed_property: str = "PRESSURE",
|
|
211
|
+
) -> list[Self]:
|
|
212
|
+
if not os.path.isabs(filename):
|
|
213
|
+
filename = os.path.join(directory, filename)
|
|
214
|
+
if not os.path.exists(filename):
|
|
215
|
+
raise ObservationConfigError.with_context(
|
|
216
|
+
f"The CSV file ({filename}) does not exist or is not accessible.",
|
|
217
|
+
filename,
|
|
218
|
+
)
|
|
219
|
+
csv_file = pd.read_csv(
|
|
220
|
+
filename,
|
|
221
|
+
encoding="utf-8",
|
|
222
|
+
on_bad_lines="error",
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
required_columns = {
|
|
226
|
+
"WELL_NAME",
|
|
227
|
+
"DATE",
|
|
228
|
+
observed_property,
|
|
229
|
+
"ERROR",
|
|
230
|
+
"NORTH",
|
|
231
|
+
"EAST",
|
|
232
|
+
"TVD",
|
|
233
|
+
}
|
|
234
|
+
missing_required_columns = required_columns - set(csv_file.keys())
|
|
235
|
+
if missing_required_columns:
|
|
236
|
+
raise ObservationConfigError.with_context(
|
|
237
|
+
f"The rft observations file {filename} is missing required column(s) "
|
|
238
|
+
f"{', '.join(sorted(missing_required_columns))}.",
|
|
239
|
+
filename,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
return [
|
|
243
|
+
cls(
|
|
244
|
+
f"{observation_dict['name']}[{row.Index}]",
|
|
245
|
+
str(row.WELL_NAME),
|
|
246
|
+
str(row.DATE),
|
|
247
|
+
observed_property,
|
|
248
|
+
validate_float(str(getattr(row, observed_property)), observed_property),
|
|
249
|
+
validate_float(str(row.ERROR), "ERROR"),
|
|
250
|
+
validate_float(str(row.NORTH), "NORTH"),
|
|
251
|
+
validate_float(str(row.EAST), "EAST"),
|
|
252
|
+
validate_float(str(row.TVD), "TVD"),
|
|
253
|
+
)
|
|
254
|
+
for row in csv_file.itertuples(index=True)
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
@classmethod
|
|
258
|
+
def from_obs_dict(
|
|
259
|
+
cls, directory: str, observation_dict: ObservationDict
|
|
260
|
+
) -> list[Self]:
|
|
261
|
+
csv_filename = None
|
|
233
262
|
well = None
|
|
234
263
|
observed_property = None
|
|
235
264
|
observed_value = None
|
|
@@ -258,8 +287,17 @@ class RFTObservation:
|
|
|
258
287
|
east = validate_float(value, key)
|
|
259
288
|
case "TVD":
|
|
260
289
|
tvd = validate_float(value, key)
|
|
290
|
+
case "CSV":
|
|
291
|
+
csv_filename = value
|
|
261
292
|
case _:
|
|
262
293
|
raise _unknown_key_error(str(key), observation_dict["name"])
|
|
294
|
+
if csv_filename is not None:
|
|
295
|
+
return cls.from_csv(
|
|
296
|
+
directory,
|
|
297
|
+
observation_dict,
|
|
298
|
+
csv_filename,
|
|
299
|
+
observed_property or "PRESSURE",
|
|
300
|
+
)
|
|
263
301
|
if well is None:
|
|
264
302
|
raise _missing_value_error(observation_dict["name"], "WELL")
|
|
265
303
|
if observed_value is None:
|
|
@@ -276,25 +314,24 @@ class RFTObservation:
|
|
|
276
314
|
raise _missing_value_error(observation_dict["name"], "EAST")
|
|
277
315
|
if tvd is None:
|
|
278
316
|
raise _missing_value_error(observation_dict["name"], "TVD")
|
|
279
|
-
return
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
317
|
+
return [
|
|
318
|
+
cls(
|
|
319
|
+
observation_dict["name"],
|
|
320
|
+
well,
|
|
321
|
+
date,
|
|
322
|
+
observed_property,
|
|
323
|
+
observed_value,
|
|
324
|
+
error,
|
|
325
|
+
north,
|
|
326
|
+
east,
|
|
327
|
+
tvd,
|
|
328
|
+
)
|
|
329
|
+
]
|
|
290
330
|
|
|
291
331
|
|
|
292
|
-
Observation =
|
|
293
|
-
HistoryObservation | SummaryObservation | GeneralObservation | RFTObservation
|
|
294
|
-
)
|
|
332
|
+
Observation = SummaryObservation | GeneralObservation | RFTObservation
|
|
295
333
|
|
|
296
334
|
_TYPE_TO_CLASS: dict[ObservationType, type[Observation]] = {
|
|
297
|
-
ObservationType.HISTORY: HistoryObservation,
|
|
298
335
|
ObservationType.SUMMARY: SummaryObservation,
|
|
299
336
|
ObservationType.GENERAL: GeneralObservation,
|
|
300
337
|
ObservationType.RFT: RFTObservation,
|
|
@@ -312,10 +349,20 @@ def make_observations(
|
|
|
312
349
|
inp: The collection of statements to validate.
|
|
313
350
|
"""
|
|
314
351
|
result: list[Observation] = []
|
|
315
|
-
error_list: list[ErrorInfo] = []
|
|
352
|
+
error_list: list[ErrorInfo | ObservationConfigError] = []
|
|
316
353
|
for obs_dict in observation_dicts:
|
|
354
|
+
if obs_dict["type"] == ObservationType.HISTORY:
|
|
355
|
+
msg = (
|
|
356
|
+
"HISTORY_OBSERVATION is deprecated, and must be specified "
|
|
357
|
+
"as SUMMARY_OBSERVATION. Run"
|
|
358
|
+
" ert convert_observations <ert_config.ert> to convert your "
|
|
359
|
+
"observations automatically"
|
|
360
|
+
)
|
|
361
|
+
logger.error(msg)
|
|
362
|
+
error_list.append(ObservationConfigError(msg))
|
|
363
|
+
continue
|
|
317
364
|
try:
|
|
318
|
-
result.
|
|
365
|
+
result.extend(
|
|
319
366
|
_TYPE_TO_CLASS[obs_dict["type"]].from_obs_dict(directory, obs_dict)
|
|
320
367
|
)
|
|
321
368
|
except KeyError as err:
|
|
@@ -329,41 +376,6 @@ def make_observations(
|
|
|
329
376
|
return result
|
|
330
377
|
|
|
331
378
|
|
|
332
|
-
def _validate_segment_dict(name_token: str, inp: dict[str, Any]) -> Segment:
|
|
333
|
-
start = None
|
|
334
|
-
stop = None
|
|
335
|
-
error_mode = ErrorModes.RELMIN
|
|
336
|
-
error = 0.1
|
|
337
|
-
error_min = 0.1
|
|
338
|
-
for key, value in inp.items():
|
|
339
|
-
match key:
|
|
340
|
-
case "START":
|
|
341
|
-
start = validate_int(value, key)
|
|
342
|
-
case "STOP":
|
|
343
|
-
stop = validate_int(value, key)
|
|
344
|
-
case "ERROR":
|
|
345
|
-
error = validate_positive_float(value, key)
|
|
346
|
-
case "ERROR_MIN":
|
|
347
|
-
error_min = validate_positive_float(value, key)
|
|
348
|
-
case "ERROR_MODE":
|
|
349
|
-
error_mode = validate_error_mode(value)
|
|
350
|
-
case _:
|
|
351
|
-
raise _unknown_key_error(key, name_token)
|
|
352
|
-
|
|
353
|
-
if start is None:
|
|
354
|
-
raise _missing_value_error(name_token, "START")
|
|
355
|
-
if stop is None:
|
|
356
|
-
raise _missing_value_error(name_token, "STOP")
|
|
357
|
-
return Segment(
|
|
358
|
-
name=name_token,
|
|
359
|
-
start=start,
|
|
360
|
-
stop=stop,
|
|
361
|
-
error_mode=error_mode,
|
|
362
|
-
error=error,
|
|
363
|
-
error_min=error_min,
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
|
|
367
379
|
def validate_error_mode(inp: str) -> ErrorModes:
|
|
368
380
|
if inp == "REL":
|
|
369
381
|
return ErrorModes.REL
|
ert/config/_read_summary.py
CHANGED
|
@@ -8,7 +8,6 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
import fnmatch
|
|
10
10
|
import re
|
|
11
|
-
import warnings
|
|
12
11
|
from collections.abc import Callable, Sequence
|
|
13
12
|
from datetime import datetime, timedelta
|
|
14
13
|
from enum import Enum, auto
|
|
@@ -158,10 +157,10 @@ def _read_spec(
|
|
|
158
157
|
if kw.summary_variable == "TIME":
|
|
159
158
|
date_index = i
|
|
160
159
|
date_unit_str = kw.unit
|
|
161
|
-
except InvalidSummaryKeyError
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
except InvalidSummaryKeyError:
|
|
161
|
+
# InvalidSummaryKeyError will happen under normal conditions when
|
|
162
|
+
# the the number of wells set for WELLDIMS in the .DATA file is
|
|
163
|
+
# larger than the number of declared wells/groups/etc. These are skipped.
|
|
165
164
|
continue
|
|
166
165
|
|
|
167
166
|
if should_load_key(key):
|
ert/config/ert_config.py
CHANGED
|
@@ -7,7 +7,6 @@ import pprint
|
|
|
7
7
|
import re
|
|
8
8
|
from collections import Counter, defaultdict
|
|
9
9
|
from collections.abc import Mapping
|
|
10
|
-
from datetime import datetime
|
|
11
10
|
from functools import cached_property
|
|
12
11
|
from os import path
|
|
13
12
|
from pathlib import Path
|
|
@@ -23,7 +22,6 @@ from ert.substitutions import Substitutions
|
|
|
23
22
|
from ._create_observation_dataframes import create_observation_dataframes
|
|
24
23
|
from ._design_matrix_validator import DesignMatrixValidator
|
|
25
24
|
from ._observations import (
|
|
26
|
-
HistoryObservation,
|
|
27
25
|
Observation,
|
|
28
26
|
RFTObservation,
|
|
29
27
|
SummaryObservation,
|
|
@@ -52,7 +50,6 @@ from .parsing import (
|
|
|
52
50
|
ConfigWarning,
|
|
53
51
|
ErrorInfo,
|
|
54
52
|
ForwardModelStepKeys,
|
|
55
|
-
HistorySource,
|
|
56
53
|
HookRuntime,
|
|
57
54
|
ObservationConfigError,
|
|
58
55
|
init_forward_model_schema,
|
|
@@ -62,7 +59,6 @@ from .parsing import (
|
|
|
62
59
|
)
|
|
63
60
|
from .parsing.observations_parser import ObservationDict
|
|
64
61
|
from .queue_config import KnownQueueOptions, QueueConfig
|
|
65
|
-
from .refcase import Refcase
|
|
66
62
|
from .rft_config import RFTConfig
|
|
67
63
|
from .workflow import Workflow
|
|
68
64
|
from .workflow_fixtures import fixtures_per_hook
|
|
@@ -104,23 +100,6 @@ def _seed_sequence(seed: int | None) -> int:
|
|
|
104
100
|
return int_seed
|
|
105
101
|
|
|
106
102
|
|
|
107
|
-
def _read_time_map(file_contents: str) -> list[datetime]:
|
|
108
|
-
def str_to_datetime(date_str: str) -> datetime:
|
|
109
|
-
try:
|
|
110
|
-
return datetime.fromisoformat(date_str)
|
|
111
|
-
except ValueError:
|
|
112
|
-
logger.warning(
|
|
113
|
-
"DD/MM/YYYY date format is deprecated"
|
|
114
|
-
", please use ISO date format YYYY-MM-DD."
|
|
115
|
-
)
|
|
116
|
-
return datetime.strptime(date_str, "%d/%m/%Y")
|
|
117
|
-
|
|
118
|
-
dates = []
|
|
119
|
-
for line in file_contents.splitlines():
|
|
120
|
-
dates.append(str_to_datetime(line.strip()))
|
|
121
|
-
return dates
|
|
122
|
-
|
|
123
|
-
|
|
124
103
|
def create_forward_model_json(
|
|
125
104
|
context: dict[str, str],
|
|
126
105
|
forward_model_steps: list[ForwardModelStep],
|
|
@@ -688,14 +667,6 @@ def log_observation_keys(
|
|
|
688
667
|
if key not in {"name", "type"}
|
|
689
668
|
)
|
|
690
669
|
|
|
691
|
-
if "HISTORY_OBSERVATION" in observation_type_counts:
|
|
692
|
-
msg = (
|
|
693
|
-
"HISTORY_OBSERVATION is deprecated and will be removed. "
|
|
694
|
-
"Please use SUMMARY_OBSERVATION instead."
|
|
695
|
-
)
|
|
696
|
-
ConfigWarning.warn(msg)
|
|
697
|
-
logger.warning(msg)
|
|
698
|
-
|
|
699
670
|
logger.info(
|
|
700
671
|
f"Count of observation types:\n\t{dict(observation_type_counts)}\n"
|
|
701
672
|
f"Count of observation keywords:\n\t{dict(observation_keyword_counts)}"
|
|
@@ -741,9 +712,6 @@ class ErtConfig(BaseModel):
|
|
|
741
712
|
user_config_file: str = "no_config"
|
|
742
713
|
config_path: str = Field(init=False, default="")
|
|
743
714
|
observation_declarations: list[Observation] = Field(default_factory=list)
|
|
744
|
-
time_map: list[datetime] | None = None
|
|
745
|
-
history_source: HistorySource = HistorySource.REFCASE_HISTORY
|
|
746
|
-
refcase: Refcase | None = None
|
|
747
715
|
_observations: dict[str, pl.DataFrame] | None = PrivateAttr(None)
|
|
748
716
|
|
|
749
717
|
@property
|
|
@@ -763,7 +731,6 @@ class ErtConfig(BaseModel):
|
|
|
763
731
|
)
|
|
764
732
|
computed = create_observation_dataframes(
|
|
765
733
|
self.observation_declarations,
|
|
766
|
-
self.refcase,
|
|
767
734
|
cast(
|
|
768
735
|
GenDataConfig | None,
|
|
769
736
|
self.ensemble_config.response_configs.get("gen_data", None),
|
|
@@ -772,8 +739,6 @@ class ErtConfig(BaseModel):
|
|
|
772
739
|
RFTConfig | None,
|
|
773
740
|
self.ensemble_config.response_configs.get("rft", None),
|
|
774
741
|
),
|
|
775
|
-
self.time_map,
|
|
776
|
-
self.history_source,
|
|
777
742
|
)
|
|
778
743
|
self._observations = computed
|
|
779
744
|
return computed
|
|
@@ -1029,7 +994,7 @@ class ErtConfig(BaseModel):
|
|
|
1029
994
|
summary_obs = {
|
|
1030
995
|
obs.key
|
|
1031
996
|
for obs in obs_configs
|
|
1032
|
-
if isinstance(obs,
|
|
997
|
+
if isinstance(obs, SummaryObservation)
|
|
1033
998
|
}
|
|
1034
999
|
if summary_obs:
|
|
1035
1000
|
summary_keys = ErtConfig._read_summary_keys(config_dict)
|
|
@@ -1037,16 +1002,6 @@ class ErtConfig(BaseModel):
|
|
|
1037
1002
|
[key] for key in summary_obs if key not in summary_keys
|
|
1038
1003
|
]
|
|
1039
1004
|
ensemble_config = EnsembleConfig.from_dict(config_dict=config_dict)
|
|
1040
|
-
time_map = None
|
|
1041
|
-
if time_map_args := config_dict.get(ConfigKeys.TIME_MAP):
|
|
1042
|
-
time_map_file, time_map_contents = time_map_args
|
|
1043
|
-
try:
|
|
1044
|
-
time_map = _read_time_map(time_map_contents)
|
|
1045
|
-
except ValueError as err:
|
|
1046
|
-
raise ConfigValidationError.with_context(
|
|
1047
|
-
f"Could not read timemap file {time_map_file}: {err}",
|
|
1048
|
-
time_map_file,
|
|
1049
|
-
) from err
|
|
1050
1005
|
except ConfigValidationError as err:
|
|
1051
1006
|
errors.append(err)
|
|
1052
1007
|
except PydanticValidationError as err:
|
|
@@ -1099,9 +1054,6 @@ class ErtConfig(BaseModel):
|
|
|
1099
1054
|
|
|
1100
1055
|
env_vars = {}
|
|
1101
1056
|
substituter = Substitutions(substitutions)
|
|
1102
|
-
history_source = config_dict.get(
|
|
1103
|
-
ConfigKeys.HISTORY_SOURCE, HistorySource.REFCASE_HISTORY
|
|
1104
|
-
)
|
|
1105
1057
|
|
|
1106
1058
|
# Insert env vars from plugins/site config
|
|
1107
1059
|
for key, val in cls.ENV_VARS.items():
|
|
@@ -1137,7 +1089,6 @@ class ErtConfig(BaseModel):
|
|
|
1137
1089
|
prioritize_private_ip_address = user_prioritize_private_ip_address
|
|
1138
1090
|
|
|
1139
1091
|
try:
|
|
1140
|
-
refcase = Refcase.from_config_dict(config_dict)
|
|
1141
1092
|
cls_config = cls(
|
|
1142
1093
|
substitutions=substitutions,
|
|
1143
1094
|
ensemble_config=ensemble_config,
|
|
@@ -1159,9 +1110,6 @@ class ErtConfig(BaseModel):
|
|
|
1159
1110
|
runpath_config=model_config,
|
|
1160
1111
|
user_config_file=config_file_path,
|
|
1161
1112
|
observation_declarations=list(obs_configs),
|
|
1162
|
-
time_map=time_map,
|
|
1163
|
-
history_source=history_source,
|
|
1164
|
-
refcase=refcase,
|
|
1165
1113
|
prioritize_private_ip_address=prioritize_private_ip_address,
|
|
1166
1114
|
)
|
|
1167
1115
|
|
|
@@ -1179,7 +1127,6 @@ class ErtConfig(BaseModel):
|
|
|
1179
1127
|
)
|
|
1180
1128
|
cls_config._observations = create_observation_dataframes(
|
|
1181
1129
|
obs_configs,
|
|
1182
|
-
refcase,
|
|
1183
1130
|
cast(
|
|
1184
1131
|
GenDataConfig | None,
|
|
1185
1132
|
ensemble_config.response_configs.get("gen_data", None),
|
|
@@ -1188,8 +1135,6 @@ class ErtConfig(BaseModel):
|
|
|
1188
1135
|
RFTConfig | None,
|
|
1189
1136
|
ensemble_config.response_configs.get("rft", None),
|
|
1190
1137
|
),
|
|
1191
|
-
time_map,
|
|
1192
|
-
history_source,
|
|
1193
1138
|
)
|
|
1194
1139
|
except PydanticValidationError as err:
|
|
1195
1140
|
raise ConfigValidationError.from_pydantic(err) from err
|