From b3233c443ef9ef7cf8a6ef5f92c37f59acf653fa Mon Sep 17 00:00:00 2001 From: xjules Date: Fri, 5 Dec 2025 14:40:14 +0100 Subject: [PATCH] Replace parameter metadata by parameter config directly Since all parameters are pydantic now we don't need metadata class. This adds dimensionality attribute to parameters, which previously was part of the metadata. Additionally we remove group from the dark storage API. Add storage migration to account for dimensionality attribute --- src/ert/config/__init__.py | 3 +- src/ert/config/ext_param_config.py | 6 +-- src/ert/config/field.py | 14 +----- src/ert/config/gen_kw_config.py | 14 +----- src/ert/config/parameter_config.py | 17 +------ src/ert/config/surface_config.py | 18 +------ src/ert/dark_storage/endpoints/experiments.py | 4 +- src/ert/dark_storage/endpoints/parameters.py | 20 +------- src/ert/gui/tools/plot/plot_api.py | 15 ++++-- src/ert/gui/tools/plot/plot_window.py | 13 ++--- src/ert/storage/local_ensemble.py | 3 ++ src/ert/storage/local_storage.py | 2 + src/ert/storage/migration/to19.py | 34 +++++++++++++ .../test_dark_storage_performance.py | 2 +- .../dark_storage/test_http_endpoints.py | 48 ++++++++++++++----- .../dark_storage/test_parameters.py | 16 +------ .../ert/unit_tests/gui/tools/plot/conftest.py | 30 ++++++++---- .../gui/tools/plot/test_plot_api.py | 31 ++++++------ .../heat_equationconfig.ert/config.json | 3 ++ .../poly_examplepoly.ert/poly.json | 3 ++ .../snake_oilsnake_oil.ert/snake_oil.json | 10 ++++ .../heat_equationconfig.ert/config.json | 3 ++ .../poly_examplepoly.ert/poly.json | 3 ++ .../snake_oilsnake_oil.ert/snake_oil.json | 10 ++++ .../heat_equationconfig.ert/config.json | 3 ++ .../poly_examplepoly.ert/poly.json | 3 ++ .../snake_oilsnake_oil.ert/snake_oil.json | 10 ++++ .../heat_equationconfig.ert/config.json | 3 ++ .../poly_examplepoly.ert/poly.json | 3 ++ .../snake_oilsnake_oil.ert/snake_oil.json | 10 ++++ .../test_that_storage_matches/parameters | 3 ++ .../storage/test_storage_migration.py | 3 ++ 32 files changed, 216 insertions(+), 144 deletions(-) create mode 100644 src/ert/storage/migration/to19.py diff --git a/src/ert/config/__init__.py b/src/ert/config/__init__.py index 78e13c05aa6..96f2bb9730c 100644 --- a/src/ert/config/__init__.py +++ b/src/ert/config/__init__.py @@ -31,7 +31,7 @@ from .known_response_types import KnownResponseTypes from .lint_file import lint_file from .model_config import ModelConfig -from .parameter_config import ParameterCardinality, ParameterConfig, ParameterMetadata +from .parameter_config import ParameterCardinality, ParameterConfig from .parsing import ( ConfigValidationError, ConfigWarning, @@ -119,7 +119,6 @@ "OutlierSettings", "ParameterCardinality", "ParameterConfig", - "ParameterMetadata", "PostExperimentFixtures", "PostSimulationFixtures", "PostUpdateFixtures", diff --git a/src/ert/config/ext_param_config.py b/src/ert/config/ext_param_config.py index 6e422e650c4..b4df3e51c2a 100644 --- a/src/ert/config/ext_param_config.py +++ b/src/ert/config/ext_param_config.py @@ -17,7 +17,7 @@ from ert.substitutions import substitute_runpath_name -from .parameter_config import ParameterConfig, ParameterMetadata +from .parameter_config import ParameterConfig if TYPE_CHECKING: import numpy.typing as npt @@ -154,10 +154,6 @@ class ExtParamConfig(ParameterConfig): def parameter_keys(self) -> list[str]: return self.input_keys - @property - def metadata(self) -> list[ParameterMetadata]: - return [] - type: Literal["everest_parameters"] = "everest_parameters" input_keys: list[str] = field(default_factory=list) forward_init: bool = False diff --git a/src/ert/config/field.py b/src/ert/config/field.py index ef57aa1283a..f3b82c683fd 100644 --- a/src/ert/config/field.py +++ b/src/ert/config/field.py @@ -29,7 +29,7 @@ from ert.utils import log_duration from ._str_to_bool import str_to_bool -from .parameter_config import ParameterConfig, ParameterMetadata +from .parameter_config import ParameterConfig from .parsing import ConfigValidationError, ConfigWarning if TYPE_CHECKING: @@ -70,6 +70,7 @@ def create_flattened_cube_graph(px: int, py: int, pz: int) -> nx.Graph[int]: class Field(ParameterConfig): type: Literal["field"] = "field" + dimensionality: Literal[3] = 3 ertbox_params: ErtboxParameters file_format: FieldFileFormat output_transformation: str | None @@ -88,17 +89,6 @@ def serialize_output_file(self, path: Path) -> str: def parameter_keys(self) -> list[str]: return [] - @property - def metadata(self) -> list[ParameterMetadata]: - return [ - ParameterMetadata( - key=self.name, - transformation=self.output_transformation, - dimensionality=3, - userdata={"data_origin": "FIELD", "ertbox_params": self.ertbox_params}, - ) - ] - @classmethod def from_config_list( cls, diff --git a/src/ert/config/gen_kw_config.py b/src/ert/config/gen_kw_config.py index 9ffc205404d..893ef61ce9e 100644 --- a/src/ert/config/gen_kw_config.py +++ b/src/ert/config/gen_kw_config.py @@ -15,7 +15,7 @@ from ._str_to_bool import str_to_bool from .distribution import DISTRIBUTION_CLASSES, DistributionSettings, get_distribution -from .parameter_config import ParameterCardinality, ParameterConfig, ParameterMetadata +from .parameter_config import ParameterCardinality, ParameterConfig from .parsing import ConfigValidationError, ConfigWarning if TYPE_CHECKING: @@ -53,6 +53,7 @@ class DataSource(StrEnum): class GenKwConfig(ParameterConfig): type: Literal["gen_kw"] = "gen_kw" + dimensionality: Literal[1] = 1 distribution: DistributionSettings forward_init: bool = False update: bool = True @@ -73,17 +74,6 @@ def parameter_keys(self) -> list[str]: def cardinality(self) -> ParameterCardinality: return ParameterCardinality.multiple_configs_per_ensemble_dataset - @property - def metadata(self) -> list[ParameterMetadata]: - return [ - ParameterMetadata( - key=f"{self.group}:{self.name}", - transformation=self.distribution.name.upper(), - dimensionality=1, - userdata={"data_origin": "GEN_KW"}, - ) - ] - @classmethod def templates_from_config( cls, gen_kw: list[str | dict[str, str]] diff --git a/src/ert/config/parameter_config.py b/src/ert/config/parameter_config.py index 5525de2c5dc..e78b7e0b96b 100644 --- a/src/ert/config/parameter_config.py +++ b/src/ert/config/parameter_config.py @@ -5,7 +5,7 @@ from enum import StrEnum, auto from hashlib import sha256 from pathlib import Path -from typing import TYPE_CHECKING, Any, Literal +from typing import TYPE_CHECKING import networkx as nx import numpy as np @@ -39,13 +39,6 @@ class ParameterCardinality(StrEnum): one_config_per_realization_dataset = auto() -class ParameterMetadata(BaseModel): - key: str - transformation: str | None - dimensionality: Literal[1, 2, 3] = 1 - userdata: dict[str, Any] - - class ParameterConfig(BaseModel): type: str name: str @@ -59,14 +52,6 @@ def parameter_keys(self) -> list[str]: Returns a list of parameter keys within this parameter group """ - @property - @abstractmethod - def metadata(self) -> list[ParameterMetadata]: - """ - Returns metadata describing this parameter - - """ - @abstractmethod def __len__(self) -> int: """Number of parameters""" diff --git a/src/ert/config/surface_config.py b/src/ert/config/surface_config.py index 7a3ed73cf51..8c737f743a0 100644 --- a/src/ert/config/surface_config.py +++ b/src/ert/config/surface_config.py @@ -19,7 +19,7 @@ from ._str_to_bool import str_to_bool from .field import create_flattened_cube_graph -from .parameter_config import InvalidParameterFile, ParameterConfig, ParameterMetadata +from .parameter_config import InvalidParameterFile, ParameterConfig from .parsing import ConfigValidationError, ErrorInfo if TYPE_CHECKING: @@ -51,6 +51,7 @@ def __init__( class SurfaceConfig(ParameterConfig): type: Literal["surface"] = "surface" + dimensionality: Literal[2] = 2 ncol: int nrow: int xori: float @@ -75,21 +76,6 @@ def serialize_base_surface_path(self, base_surface_path: Path) -> str: def parameter_keys(self) -> list[str]: return [] - @property - def metadata(self) -> list[ParameterMetadata]: - return [ - ParameterMetadata( - key=self.name, - dimensionality=2, - transformation=None, - userdata={ - "data_origin": "SURFACE", - "nx": self.ncol, - "ny": self.nrow, - }, - ) - ] - @classmethod def from_config_list(cls, config_list: list[str | dict[str, str]]) -> Self: name = cast(str, config_list[0]) diff --git a/src/ert/dark_storage/endpoints/experiments.py b/src/ert/dark_storage/endpoints/experiments.py index 4346531c0bf..2f39c502327 100644 --- a/src/ert/dark_storage/endpoints/experiments.py +++ b/src/ert/dark_storage/endpoints/experiments.py @@ -29,7 +29,7 @@ def get_experiments( priors=create_priors(experiment), userdata={}, parameters={ - group: [m.model_dump() for m in config.metadata] + group: [config.model_dump()] for group, config in experiment.parameter_configuration.items() if not isinstance(config, SurfaceConfig) }, @@ -65,7 +65,7 @@ def get_experiment_by_id( priors=create_priors(experiment), userdata={}, parameters={ - group: [m.model_dump() for m in config.metadata] + group: [config.model_dump()] for group, config in experiment.parameter_configuration.items() }, responses={ diff --git a/src/ert/dark_storage/endpoints/parameters.py b/src/ert/dark_storage/endpoints/parameters.py index e28e2566803..b79437d88fe 100644 --- a/src/ert/dark_storage/endpoints/parameters.py +++ b/src/ert/dark_storage/endpoints/parameters.py @@ -113,27 +113,11 @@ def get_parameter_std_dev( return Response(content=buffer.getvalue(), media_type="application/octet-stream") -def _extract_parameter_group_and_key(key: str) -> tuple[str, str] | tuple[None, None]: - key = key.removeprefix("LOG10_") - if ":" not in key: - # Assume all incoming keys are in format group:key for now - return None, None - - param_group, param_key = key.split(":", maxsplit=1) - return param_group, param_key - - def data_for_parameter(ensemble: Ensemble, key: str) -> pd.DataFrame: - group, _ = _extract_parameter_group_and_key(key) - if group is None: - logger.warning( - f"Parameter with key '{key}' does not have a group, " - "fetching data for all parameters" - ) try: - df = ensemble.load_scalars(group) + df = ensemble.load_scalar_keys([key], transformed=True) if df.is_empty(): - logger.warning(f"No data found for parameter '{group}:{key}'") + logger.warning(f"No data found for parameter '{key}'") return pd.DataFrame() except KeyError as e: logger.error(e) diff --git a/src/ert/gui/tools/plot/plot_api.py b/src/ert/gui/tools/plot/plot_api.py index 8e3f0e0b55a..2f747a13409 100644 --- a/src/ert/gui/tools/plot/plot_api.py +++ b/src/ert/gui/tools/plot/plot_api.py @@ -18,8 +18,9 @@ from pandas.errors import ParserError from resfo_utilities import history_key -from ert.config import ParameterMetadata, ResponseMetadata +from ert.config import ParameterConfig, ResponseMetadata from ert.services import ErtServer +from ert.storage.local_experiment import _parameters_adapter as parameter_config_adapter from ert.storage.realization_storage_state import RealizationStorageState logger = logging.getLogger(__name__) @@ -44,7 +45,7 @@ class PlotApiKeyDefinition(NamedTuple): dimensionality: int metadata: dict[Any, Any] filter_on: dict[Any, Any] | None = None - parameter_metadata: ParameterMetadata | None = None + parameter: ParameterConfig | None = None response_metadata: ResponseMetadata | None = None @@ -145,14 +146,18 @@ def parameters_api_key_defs(self) -> list[PlotApiKeyDefinition]: for experiment in response.json(): for param_metadatas in experiment["parameters"].values(): for metadata in param_metadatas: - param_key = metadata["key"] + param_cfg = parameter_config_adapter.validate_python(metadata) + if group := metadata.get("group"): + param_key = f"{group}:{metadata['name']}" + else: + param_key = metadata["name"] all_keys[param_key] = PlotApiKeyDefinition( key=param_key, index_type=None, observations=False, dimensionality=metadata["dimensionality"], - metadata=metadata["userdata"], - parameter_metadata=ParameterMetadata(**metadata), + metadata={"data_origin": metadata["type"]}, + parameter=param_cfg, ) all_params[param_key] = all_keys[param_key] diff --git a/src/ert/gui/tools/plot/plot_window.py b/src/ert/gui/tools/plot/plot_window.py index a621359c20b..114ec0df494 100644 --- a/src/ert/gui/tools/plot/plot_window.py +++ b/src/ert/gui/tools/plot/plot_window.py @@ -22,6 +22,7 @@ QWidget, ) +from ert.config.field import Field from ert.dark_storage.common import get_storage_api_version from ert.gui.ertwidgets import CopyButton, showWaitCursorWhileWaiting from ert.services._base_service import ServerBootFail @@ -270,12 +271,12 @@ def updatePlot(self, layer: int | None = None) -> None: filter_on=key_def.filter_on, ) elif ( - key_def.parameter_metadata is not None - and "GEN_KW" in key_def.metadata["data_origin"] + key_def.parameter is not None + and key_def.parameter.type == "gen_kw" ): ensemble_to_data_map[ensemble] = self._api.data_for_parameter( ensemble_id=ensemble.id, - parameter_key=key_def.parameter_metadata.key, + parameter_key=key_def.parameter.name, ) except BaseException as e: handle_exception(e) @@ -290,10 +291,10 @@ def updatePlot(self, layer: int | None = None) -> None: handle_exception(e) std_dev_images: dict[str, npt.NDArray[np.float32]] = {} - if "FIELD" in key_def.metadata["data_origin"]: - plot_widget.showLayerWidget.emit(True) - layers = key_def.metadata["ertbox_params"]["nz"] + if isinstance(key_def.parameter, Field): + plot_widget.showLayerWidget.emit(True) + layers = key_def.parameter.ertbox_params.nz plot_widget.updateLayerWidget.emit(layers) if layer is None: diff --git a/src/ert/storage/local_ensemble.py b/src/ert/storage/local_ensemble.py index 5fd7ae03d8b..a242aecefe0 100644 --- a/src/ert/storage/local_ensemble.py +++ b/src/ert/storage/local_ensemble.py @@ -570,6 +570,9 @@ def load_scalar_keys( ) -> pl.DataFrame: if keys is None: keys = self.experiment.parameter_keys + elif set(keys) - set(self.experiment.parameter_keys): + missing = set(keys) - set(self.experiment.parameter_keys) + raise KeyError(f"Parameters not registered to the experiment: {missing}") df_lazy = self._load_parameters_lazy(SCALAR_FILENAME) df_lazy = df_lazy.select(["realization", *keys]) diff --git a/src/ert/storage/local_storage.py b/src/ert/storage/local_storage.py index f7f37d865c3..af6560c7f98 100644 --- a/src/ert/storage/local_storage.py +++ b/src/ert/storage/local_storage.py @@ -504,6 +504,7 @@ def _migrate(self, version: int) -> None: to16, to17, to18, + to19, ) try: @@ -551,6 +552,7 @@ def _migrate(self, version: int) -> None: 15: to16, 16: to17, 17: to18, + 18: to19, } for from_version in range(version, _LOCAL_STORAGE_VERSION): migrations[from_version].migrate(self.path) diff --git a/src/ert/storage/migration/to19.py b/src/ert/storage/migration/to19.py new file mode 100644 index 00000000000..dfe436de1f9 --- /dev/null +++ b/src/ert/storage/migration/to19.py @@ -0,0 +1,34 @@ +import json +from pathlib import Path +from typing import Any + +info = "Add dimensionality attribute to parameters" + + +def migrate_param(parameters_json: dict[str, Any]) -> dict[str, Any]: + new_configs = {} + for param_config in parameters_json.values(): + if param_config["type"] == "surface": + param_config["dimensionality"] = 2 + elif param_config["type"] == "field": + param_config["dimensionality"] = 3 + else: + param_config["dimensionality"] = 1 + + new_configs[param_config["name"]] = param_config + return new_configs + + +def migrate_parameters_for_experiment(experiment: Path) -> None: + with open(experiment / "parameter.json", encoding="utf-8") as fin: + parameters_json = json.load(fin) + + new_parameter_configs = migrate_param(parameters_json) + Path(experiment / "parameter.json").write_text( + json.dumps(new_parameter_configs, indent=2), encoding="utf-8" + ) + + +def migrate(path: Path) -> None: + for experiment in path.glob("experiments/*"): + migrate_parameters_for_experiment(experiment) diff --git a/tests/ert/performance_tests/test_dark_storage_performance.py b/tests/ert/performance_tests/test_dark_storage_performance.py index 89ba68cb933..b956e76ad2c 100644 --- a/tests/ert/performance_tests/test_dark_storage_performance.py +++ b/tests/ert/performance_tests/test_dark_storage_performance.py @@ -335,7 +335,7 @@ def run(): for key_info in key_infos_params: for ensemble in all_ensembles: api.data_for_parameter( - ensemble_id=ensemble.id, parameter_key=key_info.key + ensemble_id=ensemble.id, parameter_key=key_info.parameter.name ) for key_info in key_infos_responses: diff --git a/tests/ert/unit_tests/dark_storage/test_http_endpoints.py b/tests/ert/unit_tests/dark_storage/test_http_endpoints.py index 62642a60a40..1022fd1d0a9 100644 --- a/tests/ert/unit_tests/dark_storage/test_http_endpoints.py +++ b/tests/ert/unit_tests/dark_storage/test_http_endpoints.py @@ -188,26 +188,50 @@ def test_get_ensemble_parameters(poly_example_tmp_dir, dark_storage_client): assert experiment_json["parameters"] == { "a": [ { - "key": "COEFFS:a", - "transformation": "UNIFORM", "dimensionality": 1, - "userdata": {"data_origin": "GEN_KW"}, + "distribution": { + "max": 1.0, + "min": 0.0, + "name": "uniform", + }, + "forward_init": False, + "group": "COEFFS", + "input_source": "sampled", + "name": "a", + "type": "gen_kw", + "update": True, } ], "b": [ { - "key": "COEFFS:b", - "transformation": "UNIFORM", "dimensionality": 1, - "userdata": {"data_origin": "GEN_KW"}, + "distribution": { + "max": 2.0, + "min": 0.0, + "name": "uniform", + }, + "forward_init": False, + "group": "COEFFS", + "input_source": "sampled", + "name": "b", + "type": "gen_kw", + "update": True, } ], "c": [ { - "key": "COEFFS:c", - "transformation": "UNIFORM", "dimensionality": 1, - "userdata": {"data_origin": "GEN_KW"}, + "distribution": { + "max": 5.0, + "min": 0.0, + "name": "uniform", + }, + "forward_init": False, + "group": "COEFFS", + "input_source": "sampled", + "name": "c", + "type": "gen_kw", + "update": True, } ], } @@ -281,9 +305,9 @@ def test_misfit_endpoint(poly_example_tmp_dir, dark_storage_client): @pytest.mark.parametrize( "coeffs", [ - "COEFFS:a", - "COEFFS:b", - "COEFFS:c", + "a", + "b", + "c", ], ) def test_get_coeffs_records(poly_example_tmp_dir, dark_storage_client, coeffs): diff --git a/tests/ert/unit_tests/dark_storage/test_parameters.py b/tests/ert/unit_tests/dark_storage/test_parameters.py index e3793787b90..fe5618aee36 100644 --- a/tests/ert/unit_tests/dark_storage/test_parameters.py +++ b/tests/ert/unit_tests/dark_storage/test_parameters.py @@ -13,19 +13,7 @@ def test_that_asking_for_non_existent_key_doesnt_raise( with open_storage(config.ens_path, mode="r") as storage: ensemble = next(storage.ensembles) assert "variable" not in ensemble.experiment.parameter_configuration - df = data_for_parameter(ensemble, "RANDOM:variable") - assert df.empty - - -@pytest.mark.integration_test -def test_that_asking_for_existing_key_without_group_returns_empty( - symlinked_heat_equation_storage_es, -): - config = ErtConfig.from_file("config.ert") - with open_storage(config.ens_path, mode="r") as storage: - ensemble = next(storage.ensembles) - assert ensemble.experiment.parameter_configuration["COND"] - df = data_for_parameter(ensemble, "COND") + df = data_for_parameter(ensemble, "variable") assert df.empty @@ -37,5 +25,5 @@ def test_that_asking_for_existing_key_with_group_returns_data( with open_storage(config.ens_path, mode="r") as storage: ensemble = next(storage.ensembles) assert "t" in ensemble.experiment.parameter_configuration - df = data_for_parameter(ensemble, "INIT_TEMP_SCALE:t") + df = data_for_parameter(ensemble, "t") assert not df.empty diff --git a/tests/ert/unit_tests/gui/tools/plot/conftest.py b/tests/ert/unit_tests/gui/tools/plot/conftest.py index 97b6d75cfbe..1c4c091f4ed 100644 --- a/tests/ert/unit_tests/gui/tools/plot/conftest.py +++ b/tests/ert/unit_tests/gui/tools/plot/conftest.py @@ -339,22 +339,34 @@ def mocked_requests_get(*args, **kwargs): "parameters": { "default": [ { - "key": "SNAKE_OIL_PARAM:BPR_138_PERSISTENCE", - "transformation": "NORMAL", + "type": "gen_kw", + "name": "BPR_138_PERSISTENCE", + "forward_init": False, + "update": True, "dimensionality": 1, - "userdata": {"data_origin": "GEN_KW"}, + "distribution": {"name": "uniform", "min": 0.2, "max": 0.7}, + "group": "SNAKE_OIL_PARAM", + "input_source": "sampled", }, { - "key": "SNAKE_OIL_PARAM:OP1_DIVERGENCE_SCALE", - "transformation": "NORMAL", + "type": "gen_kw", + "name": "OP1_DIVERGENCE_SCALE", + "forward_init": False, + "update": True, "dimensionality": 1, - "userdata": {"data_origin": "GEN_KW"}, + "distribution": {"name": "uniform", "min": 0.5, "max": 1.5}, + "group": "SNAKE_OIL_PARAM", + "input_source": "sampled", }, { - "key": "I_AM_A_PARAM", - "transformation": "NORMAL", + "type": "gen_kw", + "name": "I_AM_A_PARAM", + "forward_init": False, + "update": True, "dimensionality": 1, - "userdata": {"data_origin": "GEN_KW"}, + "distribution": {"name": "normal", "mean": 0.0, "std": 1.0}, + "group": "SNAKE_OIL_PARAM", + "input_source": "sampled", }, ] }, diff --git a/tests/ert/unit_tests/gui/tools/plot/test_plot_api.py b/tests/ert/unit_tests/gui/tools/plot/test_plot_api.py index fcb047915f1..a287e998361 100644 --- a/tests/ert/unit_tests/gui/tools/plot/test_plot_api.py +++ b/tests/ert/unit_tests/gui/tools/plot/test_plot_api.py @@ -14,7 +14,6 @@ from starlette.testclient import TestClient from ert.config import GenKwConfig, SummaryConfig -from ert.config.parameter_config import ParameterMetadata from ert.config.response_config import ResponseMetadata from ert.dark_storage import common from ert.dark_storage.app import app @@ -56,7 +55,7 @@ def test_key_def_structure(api): "key": "FOPR", "metadata": {"data_origin": "summary"}, "observations": True, - "parameter_metadata": None, + "parameter": None, "response_metadata": ResponseMetadata( response_type="summary", response_key="FOPR", @@ -73,7 +72,7 @@ def test_key_def_structure(api): "key": "BPR:1,3,8", "metadata": {"data_origin": "summary"}, "observations": False, - "parameter_metadata": None, + "parameter": None, "response_metadata": ResponseMetadata( response_type="summary", response_key="BPR:1,3,8", @@ -86,17 +85,23 @@ def test_key_def_structure(api): bpr_parameter = next( x for x in key_defs if x.key == "SNAKE_OIL_PARAM:BPR_138_PERSISTENCE" ) + bpr_parameter_expected = { "dimensionality": 1, "index_type": None, "key": "SNAKE_OIL_PARAM:BPR_138_PERSISTENCE", - "metadata": {"data_origin": "GEN_KW"}, + "metadata": {"data_origin": "gen_kw"}, "observations": False, - "parameter_metadata": ParameterMetadata( - key="SNAKE_OIL_PARAM:BPR_138_PERSISTENCE", - transformation="NORMAL", - dimensionality=1, - userdata={"data_origin": "GEN_KW"}, + "parameter": GenKwConfig.model_validate( + { + "name": "BPR_138_PERSISTENCE", + "forward_init": False, + "update": True, + "dimensionality": 1, + "distribution": {"name": "uniform", "min": 0.2, "max": 0.7}, + "group": "SNAKE_OIL_PARAM", + "input_source": "sampled", + } ), "response_metadata": None, } @@ -143,9 +148,9 @@ def test_all_data_type_keys(api): "FOPR", "SNAKE_OIL_WPR_DIFF@199", "SNAKE_OIL_PARAM:BPR_138_PERSISTENCE", + "SNAKE_OIL_PARAM:I_AM_A_PARAM", "SNAKE_OIL_PARAM:OP1_DIVERGENCE_SCALE", "WOPPER", - "I_AM_A_PARAM", ] ) @@ -297,9 +302,7 @@ def test_plot_api_handles_empty_gen_kw(api_and_storage): } ), ) - assert api.data_for_parameter( - str(ensemble.id), key + ":" + name - ).to_csv() == dedent( + assert api.data_for_parameter(str(ensemble.id), name).to_csv() == dedent( """\ Realization,0 1,0.1 @@ -348,7 +351,7 @@ def test_plot_api_handles_colons_in_parameter_keys(api_and_storage): } ), ) - test = api.data_for_parameter(str(ensemble.id), "group:subgroup:1:2:2") + test = api.data_for_parameter(str(ensemble.id), "subgroup:1:2:2") assert test.to_numpy() == np.array([[10]]) diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/heat_equationconfig.ert/config.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/heat_equationconfig.ert/config.json index 4778b05faa3..157597e4b78 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/heat_equationconfig.ert/config.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/heat_equationconfig.ert/config.json @@ -202,6 +202,7 @@ "name": "t", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -215,6 +216,7 @@ "name": "x", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "normal", "mean": 0.8, @@ -228,6 +230,7 @@ "name": "COND", "forward_init": true, "update": true, + "dimensionality": 3, "ertbox_params": { "nx": 10, "ny": 10, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/poly_examplepoly.ert/poly.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/poly_examplepoly.ert/poly.json index 3f7ddfbefcb..9dbc41d2b4e 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/poly_examplepoly.ert/poly.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/poly_examplepoly.ert/poly.json @@ -192,6 +192,7 @@ "name": "a", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -205,6 +206,7 @@ "name": "b", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -218,6 +220,7 @@ "name": "c", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json index 36a69e801af..a2a95e5b170 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_enif_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json @@ -164,6 +164,7 @@ "name": "OP1_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.01, @@ -177,6 +178,7 @@ "name": "OP1_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 3.0, @@ -190,6 +192,7 @@ "name": "OP1_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.25, @@ -203,6 +206,7 @@ "name": "OP1_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.1, @@ -216,6 +220,7 @@ "name": "OP2_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -229,6 +234,7 @@ "name": "OP2_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 5.0, @@ -242,6 +248,7 @@ "name": "OP2_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.5, @@ -255,6 +262,7 @@ "name": "OP2_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.2, @@ -268,6 +276,7 @@ "name": "BPR_555_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -281,6 +290,7 @@ "name": "BPR_138_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.2, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/heat_equationconfig.ert/config.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/heat_equationconfig.ert/config.json index 8c14af5a390..12432eb3d00 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/heat_equationconfig.ert/config.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/heat_equationconfig.ert/config.json @@ -188,6 +188,7 @@ "name": "t", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -201,6 +202,7 @@ "name": "x", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "normal", "mean": 0.8, @@ -214,6 +216,7 @@ "name": "COND", "forward_init": true, "update": true, + "dimensionality": 3, "ertbox_params": { "nx": 10, "ny": 10, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/poly_examplepoly.ert/poly.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/poly_examplepoly.ert/poly.json index 87320a8a93b..e8cd04b9c2d 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/poly_examplepoly.ert/poly.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/poly_examplepoly.ert/poly.json @@ -178,6 +178,7 @@ "name": "a", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -191,6 +192,7 @@ "name": "b", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -204,6 +206,7 @@ "name": "c", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json index 1b2305c90bd..ff4e40a102a 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_experiment_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json @@ -150,6 +150,7 @@ "name": "OP1_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.01, @@ -163,6 +164,7 @@ "name": "OP1_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 3.0, @@ -176,6 +178,7 @@ "name": "OP1_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.25, @@ -189,6 +192,7 @@ "name": "OP1_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.1, @@ -202,6 +206,7 @@ "name": "OP2_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -215,6 +220,7 @@ "name": "OP2_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 5.0, @@ -228,6 +234,7 @@ "name": "OP2_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.5, @@ -241,6 +248,7 @@ "name": "OP2_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.2, @@ -254,6 +262,7 @@ "name": "BPR_555_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -267,6 +276,7 @@ "name": "BPR_138_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.2, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/heat_equationconfig.ert/config.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/heat_equationconfig.ert/config.json index 4778b05faa3..157597e4b78 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/heat_equationconfig.ert/config.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/heat_equationconfig.ert/config.json @@ -202,6 +202,7 @@ "name": "t", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -215,6 +216,7 @@ "name": "x", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "normal", "mean": 0.8, @@ -228,6 +230,7 @@ "name": "COND", "forward_init": true, "update": true, + "dimensionality": 3, "ertbox_params": { "nx": 10, "ny": 10, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/poly_examplepoly.ert/poly.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/poly_examplepoly.ert/poly.json index 3f7ddfbefcb..9dbc41d2b4e 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/poly_examplepoly.ert/poly.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/poly_examplepoly.ert/poly.json @@ -192,6 +192,7 @@ "name": "a", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -205,6 +206,7 @@ "name": "b", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -218,6 +220,7 @@ "name": "c", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json index 36a69e801af..a2a95e5b170 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_ensemble_smoother_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json @@ -164,6 +164,7 @@ "name": "OP1_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.01, @@ -177,6 +178,7 @@ "name": "OP1_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 3.0, @@ -190,6 +192,7 @@ "name": "OP1_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.25, @@ -203,6 +206,7 @@ "name": "OP1_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.1, @@ -216,6 +220,7 @@ "name": "OP2_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -229,6 +234,7 @@ "name": "OP2_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 5.0, @@ -242,6 +248,7 @@ "name": "OP2_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.5, @@ -255,6 +262,7 @@ "name": "OP2_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.2, @@ -268,6 +276,7 @@ "name": "BPR_555_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -281,6 +290,7 @@ "name": "BPR_138_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.2, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/heat_equationconfig.ert/config.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/heat_equationconfig.ert/config.json index 59fcf295f2c..759e5fea0af 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/heat_equationconfig.ert/config.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/heat_equationconfig.ert/config.json @@ -202,6 +202,7 @@ "name": "t", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -215,6 +216,7 @@ "name": "x", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "normal", "mean": 0.8, @@ -228,6 +230,7 @@ "name": "COND", "forward_init": true, "update": true, + "dimensionality": 3, "ertbox_params": { "nx": 10, "ny": 10, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/poly_examplepoly.ert/poly.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/poly_examplepoly.ert/poly.json index ad70672fb6d..b0485410cda 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/poly_examplepoly.ert/poly.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/poly_examplepoly.ert/poly.json @@ -192,6 +192,7 @@ "name": "a", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -205,6 +206,7 @@ "name": "b", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, @@ -218,6 +220,7 @@ "name": "c", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.0, diff --git a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json index b85de757cea..aa99f4d3c50 100644 --- a/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json +++ b/tests/ert/unit_tests/run_models/snapshots/test_experiment_serialization/test_that_dumped_esmda_matches_snapshot/snake_oilsnake_oil.ert/snake_oil.json @@ -164,6 +164,7 @@ "name": "OP1_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.01, @@ -177,6 +178,7 @@ "name": "OP1_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 3.0, @@ -190,6 +192,7 @@ "name": "OP1_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.25, @@ -203,6 +206,7 @@ "name": "OP1_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.1, @@ -216,6 +220,7 @@ "name": "OP2_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -229,6 +234,7 @@ "name": "OP2_OCTAVES", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 5.0, @@ -242,6 +248,7 @@ "name": "OP2_DIVERGENCE_SCALE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.5, @@ -255,6 +262,7 @@ "name": "OP2_OFFSET", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": -0.2, @@ -268,6 +276,7 @@ "name": "BPR_555_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.1, @@ -281,6 +290,7 @@ "name": "BPR_138_PERSISTENCE", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "uniform", "min": 0.2, diff --git a/tests/ert/unit_tests/storage/snapshots/test_storage_migration/test_that_storage_matches/parameters b/tests/ert/unit_tests/storage/snapshots/test_storage_migration/test_that_storage_matches/parameters index 9338a8982f6..25398c2efc0 100644 --- a/tests/ert/unit_tests/storage/snapshots/test_storage_migration/test_that_storage_matches/parameters +++ b/tests/ert/unit_tests/storage/snapshots/test_storage_migration/test_that_storage_matches/parameters @@ -4,6 +4,7 @@ "name": "BPR", "forward_init": false, "update": true, + "dimensionality": 1, "distribution": { "name": "normal", "mean": 0.0, @@ -17,6 +18,7 @@ "name": "PORO", "forward_init": false, "update": true, + "dimensionality": 3, "ertbox_params": { "nx": 2, "ny": 3, @@ -42,6 +44,7 @@ "name": "TOP", "forward_init": false, "update": true, + "dimensionality": 2, "ncol": 2, "nrow": 3, "xori": 0.0, diff --git a/tests/ert/unit_tests/storage/test_storage_migration.py b/tests/ert/unit_tests/storage/test_storage_migration.py index 349987515c1..ba746f90ddf 100644 --- a/tests/ert/unit_tests/storage/test_storage_migration.py +++ b/tests/ert/unit_tests/storage/test_storage_migration.py @@ -150,6 +150,9 @@ def test_that_storage_matches( assert experiment.parameter_configuration["PORO"].ertbox_params.nx == 2 assert experiment.parameter_configuration["PORO"].ertbox_params.ny == 3 assert experiment.parameter_configuration["PORO"].ertbox_params.nz == 4 + assert experiment.parameter_configuration["PORO"].dimensionality == 3 + assert experiment.parameter_configuration["BPR"].dimensionality == 1 + assert experiment.parameter_configuration["TOP"].dimensionality == 2 assert experiment.templates_configuration == [("\nBPR:\n", "params.txt")] df = ensemble.load_parameters("BPR")