ert 20.0.0b0__py3-none-any.whl → 20.0.0b1__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/cli/main.py CHANGED
@@ -59,7 +59,7 @@ def run_cli(args: Namespace, runtime_plugins: ErtRuntimePlugins | None = None) -
59
59
  f"Config contains forward model step {fm_step_name} {count} time(s)",
60
60
  )
61
61
 
62
- if not ert_config.observations and args.mode not in {
62
+ if not ert_config.observation_declarations and args.mode not in {
63
63
  ENSEMBLE_EXPERIMENT_MODE,
64
64
  TEST_RUN_MODE,
65
65
  WORKFLOW_MODE,
@@ -133,7 +133,6 @@ def run_cli(args: Namespace, runtime_plugins: ErtRuntimePlugins | None = None) -
133
133
  if args.port_range is None
134
134
  else (min(args.port_range), max(args.port_range) + 1),
135
135
  use_ipc_protocol=using_local_queuesystem,
136
- prioritize_private_ip_address=ert_config.prioritize_private_ip_address,
137
136
  )
138
137
 
139
138
  if model.check_if_runpath_exists():
@@ -188,6 +188,7 @@ def _handle_rft_observation(
188
188
  "east": pl.Series([location[0]], dtype=pl.Float32),
189
189
  "north": pl.Series([location[1]], dtype=pl.Float32),
190
190
  "tvd": pl.Series([location[2]], dtype=pl.Float32),
191
+ "zone": pl.Series([rft_observation.zone], dtype=pl.String),
191
192
  "observations": pl.Series([rft_observation.value], dtype=pl.Float32),
192
193
  "std": pl.Series([rft_observation.error], dtype=pl.Float32),
193
194
  "radius": pl.Series([None], dtype=pl.Float32),
@@ -329,6 +329,12 @@ class GeneralObservation(_GeneralObservation):
329
329
 
330
330
 
331
331
  class RFTObservation(BaseModel):
332
+ """Represents an RFT (Repeat Formation Tester) observation.
333
+
334
+ RFT observations are used to condition on pressure, saturation, or other
335
+ properties measured at specific well locations and times.
336
+ """
337
+
332
338
  type: Literal["rft_observation"] = "rft_observation"
333
339
  name: str
334
340
  well: str
@@ -349,6 +355,26 @@ class RFTObservation(BaseModel):
349
355
  filename: str,
350
356
  observed_property: str = "PRESSURE",
351
357
  ) -> list[Self]:
358
+ """Create RFT observations from a CSV file.
359
+
360
+ The CSV file must contain the following columns: WELL_NAME, DATE,
361
+ ERROR, NORTH, EAST, TVD, and a column for the observed property
362
+ (e.g., PRESSURE, SWAT). An optional ZONE column may also be present.
363
+
364
+ Args:
365
+ directory: Base directory for resolving relative file paths.
366
+ observation_dict: Dictionary containing the observation configuration.
367
+ filename: Path to the CSV file containing RFT observations.
368
+ observed_property: Property to observe (default: PRESSURE).
369
+
370
+ Returns:
371
+ List of RFTObservation instances created from the CSV file.
372
+
373
+ Raises:
374
+ ObservationConfigError: If the file is missing, inaccessible,
375
+ lacks required columns, or contains invalid observation values
376
+ (value=-1 and error=0).
377
+ """
352
378
  if not os.path.isabs(filename):
353
379
  filename = os.path.join(directory, filename)
354
380
  if not os.path.exists(filename):
@@ -425,6 +451,24 @@ class RFTObservation(BaseModel):
425
451
  def from_obs_dict(
426
452
  cls, directory: str, observation_dict: ObservationDict
427
453
  ) -> list[Self]:
454
+ """Create RFT observations from an observation dictionary.
455
+
456
+ Supports two modes:
457
+ 1. CSV mode: Load observations from a CSV file specified by the CSV key.
458
+ 2. Direct mode: Create a single observation from individual keys
459
+ (WELL, PROPERTY, VALUE, ERROR, DATE, NORTH, EAST, TVD, ZONE).
460
+
461
+ Args:
462
+ directory: Base directory for resolving relative file paths.
463
+ observation_dict: Dictionary containing the observation configuration.
464
+
465
+ Returns:
466
+ List of RFTObservation instances. Returns multiple observations when
467
+ loading from CSV, or a single observation when using direct mode.
468
+
469
+ Raises:
470
+ ObservationConfigError: If required keys are missing or invalid.
471
+ """
428
472
  csv_filename = None
429
473
  well = None
430
474
  observed_property = None
ert/config/ert_config.py CHANGED
@@ -12,14 +12,13 @@ from os import path
12
12
  from pathlib import Path
13
13
  from typing import TYPE_CHECKING, Any, ClassVar, Self, cast, overload
14
14
 
15
- import polars as pl
16
15
  from numpy.random import SeedSequence
17
- from pydantic import BaseModel, Field, PrivateAttr, model_validator
16
+ from pydantic import BaseModel, Field, model_validator
18
17
  from pydantic import ValidationError as PydanticValidationError
19
18
 
19
+ from ert.config._create_observation_dataframes import create_observation_dataframes
20
20
  from ert.substitutions import Substitutions
21
21
 
22
- from ._create_observation_dataframes import create_observation_dataframes
23
22
  from ._design_matrix_validator import DesignMatrixValidator
24
23
  from ._observations import (
25
24
  GeneralObservation,
@@ -689,7 +688,6 @@ class ErtConfig(BaseModel):
689
688
  QUEUE_OPTIONS: ClassVar[KnownQueueOptions | None] = None
690
689
  RESERVED_KEYWORDS: ClassVar[list[str]] = RESERVED_KEYWORDS
691
690
  ENV_VARS: ClassVar[dict[str, str]] = {}
692
- PRIORITIZE_PRIVATE_IP_ADDRESS: ClassVar[bool] = False
693
691
 
694
692
  substitutions: dict[str, str] = Field(default_factory=dict)
695
693
  ensemble_config: EnsembleConfig = Field(default_factory=EnsembleConfig)
@@ -704,7 +702,6 @@ class ErtConfig(BaseModel):
704
702
  default_factory=lambda: defaultdict(lambda: cast(list[Workflow], []))
705
703
  )
706
704
  runpath_file: Path = Path(DEFAULT_RUNPATH_FILE)
707
- prioritize_private_ip_address: bool = False
708
705
 
709
706
  ert_templates: list[tuple[str, str]] = Field(default_factory=list)
710
707
 
@@ -714,32 +711,6 @@ class ErtConfig(BaseModel):
714
711
  config_path: str = Field(init=False, default="")
715
712
  observation_declarations: list[Observation] = Field(default_factory=list)
716
713
  zonemap: dict[int, list[str]] = Field(default_factory=dict)
717
- _observations: dict[str, pl.DataFrame] | None = PrivateAttr(None)
718
-
719
- @property
720
- def observations(self) -> dict[str, pl.DataFrame]:
721
- if self._observations is None:
722
- has_rft_observations = any(
723
- isinstance(o, RFTObservation) for o in self.observation_declarations
724
- )
725
- if (
726
- has_rft_observations
727
- and "rft" not in self.ensemble_config.response_configs
728
- ):
729
- self.ensemble_config.response_configs["rft"] = RFTConfig(
730
- input_files=[self.runpath_config.eclbase_format_string],
731
- data_to_read={},
732
- locations=[],
733
- zonemap=self.zonemap,
734
- )
735
- self._observations = create_observation_dataframes(
736
- self.observation_declarations,
737
- cast(
738
- RFTConfig | None,
739
- self.ensemble_config.response_configs.get("rft", None),
740
- ),
741
- )
742
- return self._observations
743
714
 
744
715
  @model_validator(mode="after")
745
716
  def set_fields(self) -> Self:
@@ -834,28 +805,6 @@ class ErtConfig(BaseModel):
834
805
 
835
806
  return self
836
807
 
837
- def __eq__(self, other: object) -> bool:
838
- if not isinstance(other, ErtConfig):
839
- return False
840
-
841
- for attr in vars(self):
842
- if attr == "observations":
843
- if self.observations.keys() != other.observations.keys():
844
- return False
845
-
846
- if not all(
847
- self.observations[k].equals(other.observations[k])
848
- for k in self.observations
849
- ):
850
- return False
851
-
852
- continue
853
-
854
- if getattr(self, attr) != getattr(other, attr):
855
- return False
856
-
857
- return True
858
-
859
808
  @staticmethod
860
809
  def with_plugins(runtime_plugins: ErtRuntimePlugins) -> type[ErtConfig]:
861
810
  class ErtConfigWithPlugins(ErtConfig):
@@ -870,9 +819,6 @@ class ErtConfig(BaseModel):
870
819
  )
871
820
  ENV_VARS = dict(runtime_plugins.environment_variables)
872
821
  QUEUE_OPTIONS = runtime_plugins.queue_options
873
- PRIORITIZE_PRIVATE_IP_ADDRESS = (
874
- runtime_plugins.prioritize_private_ip_address
875
- )
876
822
 
877
823
  ErtConfigWithPlugins.model_rebuild()
878
824
  assert issubclass(ErtConfigWithPlugins, ErtConfig)
@@ -1137,7 +1083,6 @@ class ErtConfig(BaseModel):
1137
1083
  runpath_config=model_config,
1138
1084
  user_config_file=config_file_path,
1139
1085
  observation_declarations=list(obs_configs),
1140
- prioritize_private_ip_address=cls.PRIORITIZE_PRIVATE_IP_ADDRESS,
1141
1086
  zonemap=config_dict.get(ConfigKeys.ZONEMAP, ("", {}))[1],
1142
1087
  )
1143
1088
 
@@ -1157,12 +1102,10 @@ class ErtConfig(BaseModel):
1157
1102
 
1158
1103
  # PS:
1159
1104
  # This mutates the rft config and is necessary for the moment
1160
- cls_config._observations = create_observation_dataframes(
1105
+ # Consider changing this pattern
1106
+ _ = create_observation_dataframes(
1161
1107
  obs_configs,
1162
- cast(
1163
- RFTConfig | None,
1164
- ensemble_config.response_configs.get("rft", None),
1165
- ),
1108
+ cast(RFTConfig | None, ensemble_config.response_configs.get("rft")),
1166
1109
  )
1167
1110
  except PydanticValidationError as err:
1168
1111
  raise ConfigValidationError.from_pydantic(err) from err
@@ -79,8 +79,8 @@ class EverestResponse(ResponseConfig):
79
79
  class EverestConstraintsConfig(EverestResponse):
80
80
  type: Literal["everest_constraints"] = "everest_constraints"
81
81
  targets: list[float | None]
82
- upper_bounds: list[float]
83
- lower_bounds: list[float]
82
+ upper_bounds: list[float | None]
83
+ lower_bounds: list[float | None]
84
84
 
85
85
 
86
86
  responses_index.add_response_type(EverestConstraintsConfig)
ert/config/field.py CHANGED
@@ -70,10 +70,10 @@ class Field(ParameterConfig):
70
70
  dimensionality: Literal[3] = 3
71
71
  ertbox_params: ErtboxParameters
72
72
  file_format: FieldFileFormat
73
- output_transformation: str | None
74
- input_transformation: str | None
75
- truncation_min: float | None
76
- truncation_max: float | None
73
+ output_transformation: str | None = None
74
+ input_transformation: str | None = None
75
+ truncation_min: float | None = None
76
+ truncation_max: float | None = None
77
77
  forward_init_file: str
78
78
  output_file: Path
79
79
  grid_file: str
ert/config/rft_config.py CHANGED
@@ -7,7 +7,8 @@ import os
7
7
  import re
8
8
  import warnings
9
9
  from collections import defaultdict
10
- from typing import IO, Any, Literal, TypeAlias
10
+ from dataclasses import dataclass
11
+ from typing import IO, Any, Literal, TypeAlias, cast
11
12
 
12
13
  import numpy as np
13
14
  import numpy.typing as npt
@@ -25,19 +26,60 @@ from .responses_index import responses_index
25
26
  logger = logging.getLogger(__name__)
26
27
 
27
28
 
29
+ # A Point in UTM/TVD coordinates
28
30
  Point: TypeAlias = tuple[float, float, float]
31
+ # Index to a cell in a grid
29
32
  GridIndex: TypeAlias = tuple[int, int, int]
30
33
  ZoneName: TypeAlias = str
34
+ WellName: TypeAlias = str
35
+ DateString: TypeAlias = str
36
+ RFTProperty: TypeAlias = str
37
+
38
+
39
+ @dataclass(frozen=True)
40
+ class _ZonedPoint:
41
+ """A point optionally constrained to be in a given zone."""
42
+
43
+ point: tuple[float | None, float | None, float | None] = (None, None, None)
44
+ zone_name: ZoneName | None = None
45
+
46
+ def has_zone(self) -> bool:
47
+ return self.zone_name is not None
31
48
 
32
49
 
33
50
  class RFTConfig(ResponseConfig):
51
+ """:term:`RFT` response from a :term:`reservoir simulator`.
52
+
53
+ RFTConfig is the configuration of responses in the <RUNPATH>/<ECLBASE>.RFT
54
+ file which may be generated from a reservoir simulator forward model step.
55
+
56
+ The file contains values for grid cells along a wellpath (see RFTReader for
57
+ details). RFTConfig will match the values against the given :term:`UTM`/:term:`TVD`
58
+ locations.
59
+
60
+ Parameters:
61
+ data_to_read: dictionary of the values that should be read from the rft file.
62
+ loations: list of optionally zone constrained points that the rft values should
63
+ be labeled with.
64
+ zonemap: The mapping from grid layer index to zone name.
65
+ """
66
+
34
67
  type: Literal["rft"] = "rft"
35
68
  name: str = "rft"
36
69
  has_finalized_keys: bool = False
37
- data_to_read: dict[str, dict[str, list[str]]] = Field(default_factory=dict)
70
+ data_to_read: dict[WellName, dict[DateString, list[RFTProperty]]] = Field(
71
+ default_factory=dict
72
+ )
38
73
  locations: list[Point | tuple[Point, ZoneName]] = Field(default_factory=list)
39
74
  zonemap: dict[int, list[ZoneName]] = Field(default_factory=dict)
40
75
 
76
+ @property
77
+ def _zoned_locations(self) -> list[_ZonedPoint]:
78
+ return [
79
+ _ZonedPoint(*p) if isinstance(p[1], ZoneName) else _ZonedPoint(p)
80
+ for p in self.locations
81
+ ]
82
+
41
83
  @property
42
84
  def expected_input_files(self) -> list[str]:
43
85
  base = self.input_files[0]
@@ -51,13 +93,13 @@ class RFTConfig(ResponseConfig):
51
93
 
52
94
  def _find_indices(
53
95
  self, egrid_file: str | os.PathLike[str] | IO[Any]
54
- ) -> dict[GridIndex | None, set[Point | tuple[Point, ZoneName]]]:
96
+ ) -> dict[GridIndex | None, set[_ZonedPoint]]:
55
97
  indices = defaultdict(set)
56
98
  for a, b in zip(
57
99
  CornerpointGrid.read_egrid(egrid_file).find_cell_containing_point(
58
- [loc[0] if isinstance(loc[1], str) else loc for loc in self.locations]
100
+ [cast(Point, loc.point) for loc in self._zoned_locations]
59
101
  ),
60
- self.locations,
102
+ self._zoned_locations,
61
103
  strict=True,
62
104
  ):
63
105
  indices[a].add(b)
@@ -65,20 +107,20 @@ class RFTConfig(ResponseConfig):
65
107
 
66
108
  def _filter_zones(
67
109
  self,
68
- indices: dict[GridIndex | None, set[Point | tuple[Point, ZoneName]]],
110
+ indices: dict[GridIndex | None, set[_ZonedPoint]],
69
111
  iens: int,
70
112
  iter_: int,
71
- ) -> dict[GridIndex | None, set[Point]]:
113
+ ) -> dict[GridIndex | None, set[_ZonedPoint]]:
72
114
  for idx, locs in indices.items():
73
115
  if idx is not None:
74
116
  for loc in list(locs):
75
- if isinstance(loc[1], str):
76
- zone = loc[1]
117
+ if loc.has_zone():
118
+ zone = cast(ZoneName, loc.zone_name)
77
119
  # zonemap is 1-indexed so +1
78
120
  if zone not in self.zonemap.get(idx[-1] + 1, []):
79
121
  warnings.warn(
80
122
  PostSimulationWarning(
81
- f"An RFT observation with location {loc[0]}, "
123
+ f"An RFT observation with location {loc.point}, "
82
124
  f"in iteration {iter_}, realization {iens} did "
83
125
  f"not match expected zone {zone}. The observation "
84
126
  "was deactivated",
@@ -86,12 +128,21 @@ class RFTConfig(ResponseConfig):
86
128
  stacklevel=2,
87
129
  )
88
130
  locs.remove(loc)
89
- return {
90
- k: {v[0] if isinstance(v[1], str) else v for v in vs}
91
- for k, vs in indices.items()
92
- }
131
+ return indices
93
132
 
94
133
  def read_from_file(self, run_path: str, iens: int, iter_: int) -> pl.DataFrame:
134
+ """Reads the RFT values from <RUNPATH>/<ECLBASE>.RFT
135
+
136
+ Also labels those values by which optionally zone constrained point
137
+ it belongs to.
138
+
139
+ The columns east, north, tvd is none when the value does not belong to
140
+ any point, otherwise it is the x,y,z values of that point. If the point
141
+ is constrained to be in a certain zone then the zone column is also populated.
142
+
143
+ Points which were constrained to be in a given zone, but were not contained
144
+ in that zone, is not labeled, and instead a warning is emitted.
145
+ """
95
146
  filename = substitute_runpath_name(self.input_files[0], iens, iter_)
96
147
  if filename.upper().endswith(".DATA"):
97
148
  # For backwards compatibility, it is
@@ -102,9 +153,9 @@ class RFTConfig(ResponseConfig):
102
153
  if grid_filename.upper().endswith(".RFT"):
103
154
  grid_filename = grid_filename[:-4]
104
155
  grid_filename += ".EGRID"
105
- fetched: dict[tuple[str, datetime.date], dict[str, npt.NDArray[np.float32]]] = (
106
- defaultdict(dict)
107
- )
156
+ fetched: dict[
157
+ tuple[WellName, datetime.date], dict[RFTProperty, npt.NDArray[np.float32]]
158
+ ] = defaultdict(dict)
108
159
  indices = {}
109
160
  if self.locations:
110
161
  indices = self._filter_zones(self._find_indices(grid_filename), iens, iter_)
@@ -123,7 +174,10 @@ class RFTConfig(ResponseConfig):
123
174
  "time": [],
124
175
  "depth": [],
125
176
  "values": [],
126
- "location": [],
177
+ "east": [],
178
+ "north": [],
179
+ "tvd": [],
180
+ "zone": [],
127
181
  }
128
182
  )
129
183
 
@@ -170,7 +224,7 @@ class RFTConfig(ResponseConfig):
170
224
  list(
171
225
  indices.get(
172
226
  (c[0] - 1, c[1] - 1, c[2] - 1),
173
- [(None, None, None)],
227
+ [_ZonedPoint()],
174
228
  )
175
229
  )
176
230
  for c in entry.connections
@@ -189,7 +243,10 @@ class RFTConfig(ResponseConfig):
189
243
  "time": [],
190
244
  "depth": [],
191
245
  "values": [],
192
- "location": [],
246
+ "east": [],
247
+ "north": [],
248
+ "tvd": [],
249
+ "zone": [],
193
250
  }
194
251
  )
195
252
 
@@ -204,18 +261,34 @@ class RFTConfig(ResponseConfig):
204
261
  "values": [vals],
205
262
  "location": pl.Series(
206
263
  [
207
- locations.get(
208
- (well, time), [(None, None, None)] * len(vals)
209
- )
264
+ [
265
+ [loc.point for loc in locs]
266
+ for locs in locations.get(
267
+ (well, time),
268
+ [[_ZonedPoint()]] * len(vals),
269
+ )
270
+ ]
210
271
  ],
211
272
  dtype=pl.Array(
212
273
  pl.List(pl.Array(pl.Float32, 3)), len(vals)
213
274
  ),
214
275
  ),
276
+ "zone": pl.Series(
277
+ [
278
+ [
279
+ [loc.zone_name for loc in locs]
280
+ for locs in locations.get(
281
+ (well, time),
282
+ [[_ZonedPoint()]] * len(vals),
283
+ )
284
+ ]
285
+ ],
286
+ dtype=pl.Array(pl.List(pl.String), len(vals)),
287
+ ),
215
288
  }
216
289
  )
217
- .explode("depth", "values", "location")
218
- .explode("location")
290
+ .explode("depth", "values", "location", "zone")
291
+ .explode("location", "zone")
219
292
  for (well, time), inner_dict in fetched.items()
220
293
  for prop, vals in inner_dict.items()
221
294
  if prop != "DEPTH" and len(vals) > 0
@@ -238,7 +311,7 @@ class RFTConfig(ResponseConfig):
238
311
 
239
312
  @property
240
313
  def primary_key(self) -> list[str]:
241
- return ["east", "north", "tvd"]
314
+ return ["east", "north", "tvd", "zone"]
242
315
 
243
316
  @classmethod
244
317
  def from_config_dict(cls, config_dict: ConfigDict) -> RFTConfig | None:
@@ -260,8 +333,8 @@ class RFTConfig(ResponseConfig):
260
333
  "step known to generate rft files"
261
334
  )
262
335
 
263
- declared_data: dict[str, dict[datetime.date, list[str]]] = defaultdict(
264
- lambda: defaultdict(list)
336
+ declared_data: dict[WellName, dict[datetime.date, list[RFTProperty]]] = (
337
+ defaultdict(lambda: defaultdict(list))
265
338
  )
266
339
  for rft in rfts:
267
340
  for expected in ["WELL", "DATE", "PROPERTIES"]:
@@ -317,11 +317,9 @@ class ExperimentRunner:
317
317
  simulation_future = loop.run_in_executor(
318
318
  None,
319
319
  lambda: run_model.start_simulations_thread(
320
- EvaluatorServerConfig(
321
- use_ipc_protocol=run_model.queue_config.queue_system
322
- == QueueSystem.LOCAL,
323
- prioritize_private_ip_address=site_plugins.prioritize_private_ip_address,
324
- )
320
+ EvaluatorServerConfig()
321
+ if run_model.queue_config.queue_system == QueueSystem.LOCAL
322
+ else EvaluatorServerConfig(use_ipc_protocol=False)
325
323
  ),
326
324
  )
327
325
  while True:
@@ -27,7 +27,6 @@ class EvaluatorServerConfig:
27
27
  use_token: bool = True,
28
28
  host: str | None = None,
29
29
  use_ipc_protocol: bool = True,
30
- prioritize_private_ip_address: bool = False,
31
30
  ) -> None:
32
31
  self.host: str | None = host
33
32
  self.router_port: int | None = None
@@ -51,7 +50,7 @@ class EvaluatorServerConfig:
51
50
  if use_ipc_protocol:
52
51
  self.uri = f"ipc:///tmp/socket-{uuid.uuid4().hex[:8]}"
53
52
  elif self.host is None:
54
- self.host = get_ip_address(prioritize_private_ip_address)
53
+ self.host = get_ip_address()
55
54
 
56
55
  if use_token:
57
56
  self.server_public_key, self.server_secret_key = zmq.curve_keypair()
@@ -55,15 +55,9 @@ def create_md_table(kv: dict[str, str], output: str) -> str:
55
55
 
56
56
 
57
57
  def get_simulation_thread(
58
- model: Any,
59
- rerun_failed_realizations: bool = False,
60
- use_ipc_protocol: bool = False,
61
- prioritize_private_ip_address: bool = False,
58
+ model: Any, rerun_failed_realizations: bool = False, use_ipc_protocol: bool = False
62
59
  ) -> ErtThread:
63
- evaluator_server_config = EvaluatorServerConfig(
64
- use_ipc_protocol=use_ipc_protocol,
65
- prioritize_private_ip_address=prioritize_private_ip_address,
66
- )
60
+ evaluator_server_config = EvaluatorServerConfig(use_ipc_protocol=use_ipc_protocol)
67
61
 
68
62
  def run() -> None:
69
63
  model.api.start_simulations_thread(
@@ -387,7 +381,6 @@ class ExperimentPanel(QWidget):
387
381
  rerun_failed_realizations,
388
382
  use_ipc_protocol=self.config.queue_config.queue_system
389
383
  == QueueSystem.LOCAL,
390
- prioritize_private_ip_address=self.config.prioritize_private_ip_address,
391
384
  )
392
385
  self._dialog.setup_event_monitoring(rerun_failed_realizations)
393
386
  simulation_thread.start()
@@ -22,8 +22,7 @@ from PyQt6.QtWidgets import (
22
22
  QWidget,
23
23
  )
24
24
 
25
- from ert.config import ErrorInfo, ErtConfig, RFTConfig
26
- from ert.config._create_observation_dataframes import create_observation_dataframes
25
+ from ert.config import ErrorInfo, ErtConfig
27
26
  from ert.gui.ertnotifier import ErtNotifier
28
27
  from ert.gui.ertwidgets import CreateExperimentDialog, Suggestor
29
28
  from ert.storage import Ensemble, Experiment
@@ -170,26 +169,29 @@ class StorageWidget(QWidget):
170
169
  if create_experiment_dialog.exec():
171
170
  try:
172
171
  with self._notifier.write_storage() as storage:
173
- response_configs = (
174
- self._ert_config.ensemble_config.response_configuration
172
+ parameter_configuration = (
173
+ self._ert_config.parameter_configurations_with_design_matrix
175
174
  )
176
-
177
- rft_config = next(
178
- (r for r in response_configs if r.type == "rft"),
179
- None,
175
+ response_configuration = (
176
+ self._ert_config.ensemble_config.response_configuration
180
177
  )
181
- if rft_config is not None:
182
- rft_config = cast(RFTConfig, rft_config)
183
-
184
178
  ensemble = storage.create_experiment(
185
- parameters=self._ert_config.parameter_configurations_with_design_matrix,
186
- responses=response_configs,
187
- observations=create_observation_dataframes(
188
- observations=self._ert_config.observation_declarations,
189
- rft_config=rft_config,
190
- ),
179
+ experiment_config={
180
+ "parameter_configuration": [
181
+ c.model_dump(mode="json")
182
+ for c in parameter_configuration
183
+ ],
184
+ "response_configuration": [
185
+ c.model_dump(mode="json")
186
+ for c in response_configuration
187
+ ],
188
+ "observations": [
189
+ d.model_dump(mode="json")
190
+ for d in self._ert_config.observation_declarations
191
+ ],
192
+ "ert_templates": self._ert_config.ert_templates,
193
+ },
191
194
  name=create_experiment_dialog.experiment_name,
192
- templates=self._ert_config.ert_templates,
193
195
  ).create_ensemble(
194
196
  name=create_experiment_dialog.ensemble_name,
195
197
  ensemble_size=self._ensemble_size,
@@ -338,7 +338,6 @@ class ErtRuntimePlugins(BaseModel):
338
338
  environment_variables: Mapping[str, str] = Field(default_factory=dict)
339
339
  env_pr_fm_step: Mapping[str, Mapping[str, Any]] = Field(default_factory=dict)
340
340
  help_links: dict[str, str] = Field(default_factory=dict)
341
- prioritize_private_ip_address: bool = False
342
341
 
343
342
 
344
343
  def get_site_plugins(
@@ -387,9 +386,6 @@ def get_site_plugins(
387
386
  ),
388
387
  env_pr_fm_step=plugin_manager.get_forward_model_configuration(),
389
388
  help_links=plugin_manager.get_help_links(),
390
- prioritize_private_ip_address=site_configurations.prioritize_private_ip_address
391
- if site_configurations
392
- else False,
393
389
  )
394
390
 
395
391
  return runtime_plugins
@@ -1,16 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from typing import ClassVar, cast
4
+ from typing import ClassVar
5
5
  from uuid import UUID
6
6
 
7
7
  from pydantic import PrivateAttr
8
8
 
9
9
  from ert.config import (
10
- ParameterConfig,
11
10
  PostExperimentFixtures,
12
11
  PreExperimentFixtures,
13
- ResponseConfig,
14
12
  )
15
13
  from ert.ensemble_evaluator import EvaluatorServerConfig
16
14
  from ert.run_models.initial_ensemble_run_model import (
@@ -54,11 +52,8 @@ class EnsembleExperiment(InitialEnsembleRunModel, EnsembleExperimentConfig):
54
52
  self.run_workflows(fixtures=PreExperimentFixtures(random_seed=self.random_seed))
55
53
 
56
54
  experiment_storage = self._storage.create_experiment(
57
- parameters=cast(list[ParameterConfig], self.parameter_configuration),
58
- observations=self.observation_dataframes(),
59
- responses=cast(list[ResponseConfig], self.response_configuration),
55
+ experiment_config=self.model_dump(mode="json"),
60
56
  name=self.experiment_name,
61
- templates=self.ert_templates,
62
57
  )
63
58
 
64
59
  ensemble_storage = self._storage.create_ensemble(