Skip to content

Commit 37559fd

Browse files
committed
Add EnIF to GUI
1 parent 21a8f11 commit 37559fd

File tree

3 files changed

+160
-4
lines changed

3 files changed

+160
-4
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
from __future__ import annotations
2+
3+
from dataclasses import dataclass
4+
from typing import TYPE_CHECKING
5+
6+
from PyQt6.QtCore import pyqtSlot as Slot
7+
from PyQt6.QtWidgets import QFormLayout, QLabel, QWidget
8+
9+
from ert.gui.ertnotifier import ErtNotifier
10+
from ert.gui.ertwidgets import (
11+
ActiveRealizationsModel,
12+
AnalysisModuleEdit,
13+
CopyableLabel,
14+
StringBox,
15+
TargetEnsembleModel,
16+
TextModel,
17+
)
18+
from ert.mode_definitions import ENIF_MODE
19+
from ert.run_models import EnsembleInformationFilter
20+
from ert.validation import (
21+
ExperimentValidation,
22+
ProperNameFormatArgument,
23+
RangeStringArgument,
24+
)
25+
26+
from ._design_matrix_panel import DesignMatrixPanel
27+
from .experiment_config_panel import ExperimentConfigPanel
28+
29+
if TYPE_CHECKING:
30+
from ert.config import AnalysisConfig
31+
32+
33+
@dataclass
34+
class Arguments:
35+
mode: str
36+
target_ensemble: str
37+
realizations: str
38+
experiment_name: str
39+
40+
41+
class EnsembleInformationFilterPanel(ExperimentConfigPanel):
42+
def __init__(
43+
self,
44+
analysis_config: AnalysisConfig,
45+
run_path: str,
46+
notifier: ErtNotifier,
47+
ensemble_size: int,
48+
) -> None:
49+
super().__init__(EnsembleInformationFilter)
50+
self.notifier = notifier
51+
52+
layout = QFormLayout()
53+
self.setObjectName("enif_panel")
54+
55+
self._experiment_name_field = StringBox(
56+
TextModel(""),
57+
placeholder_text=self.notifier.storage.get_unique_experiment_name(
58+
ENIF_MODE
59+
),
60+
)
61+
self._experiment_name_field.setMinimumWidth(250)
62+
self._experiment_name_field.setValidator(
63+
ExperimentValidation(self.notifier.storage)
64+
)
65+
self._experiment_name_field.setObjectName("experiment_field")
66+
layout.addRow("Experiment name:", self._experiment_name_field)
67+
68+
runpath_label = CopyableLabel(text=run_path)
69+
layout.addRow("Runpath:", runpath_label)
70+
71+
number_of_realizations_label = QLabel(f"<b>{ensemble_size}</b>")
72+
layout.addRow(QLabel("Number of realizations:"), number_of_realizations_label)
73+
74+
self._ensemble_format_model = TargetEnsembleModel(analysis_config, notifier)
75+
self._ensemble_format_field = StringBox(
76+
self._ensemble_format_model, # type: ignore
77+
self._ensemble_format_model.getDefaultValue(), # type: ignore
78+
continuous_update=True,
79+
)
80+
self._ensemble_format_field.setValidator(ProperNameFormatArgument())
81+
layout.addRow("Ensemble format:", self._ensemble_format_field)
82+
83+
self._analysis_module_edit = AnalysisModuleEdit(
84+
analysis_config.es_module, ensemble_size
85+
)
86+
self._analysis_module_edit.setObjectName("enif_edit")
87+
layout.addRow("Analysis module:", self._analysis_module_edit)
88+
89+
active_realizations_model = ActiveRealizationsModel(ensemble_size)
90+
self._active_realizations_field = StringBox(
91+
active_realizations_model, # type: ignore
92+
"config/simulation/active_realizations",
93+
)
94+
self._active_realizations_field.setValidator(RangeStringArgument(ensemble_size))
95+
layout.addRow("Active realizations", self._active_realizations_field)
96+
97+
design_matrix = analysis_config.design_matrix
98+
if design_matrix is not None:
99+
layout.addRow(
100+
"Design Matrix",
101+
DesignMatrixPanel.get_design_matrix_button(
102+
self._active_realizations_field,
103+
design_matrix,
104+
number_of_realizations_label,
105+
ensemble_size,
106+
),
107+
)
108+
109+
self.setLayout(layout)
110+
111+
self._experiment_name_field.getValidationSupport().validationChanged.connect(
112+
self.simulationConfigurationChanged
113+
)
114+
self._ensemble_format_field.getValidationSupport().validationChanged.connect(
115+
self.simulationConfigurationChanged
116+
)
117+
self._active_realizations_field.getValidationSupport().validationChanged.connect(
118+
self.simulationConfigurationChanged
119+
)
120+
121+
self.notifier.ertChanged.connect(self._update_experiment_name_placeholder)
122+
123+
@Slot(QWidget)
124+
def experimentTypeChanged(self, w: QWidget) -> None:
125+
if isinstance(w, EnsembleInformationFilterPanel):
126+
self._update_experiment_name_placeholder()
127+
128+
def _update_experiment_name_placeholder(self) -> None:
129+
self._experiment_name_field.setPlaceholderText(
130+
self.notifier.storage.get_unique_experiment_name(ENIF_MODE)
131+
)
132+
133+
def isConfigurationValid(self) -> bool:
134+
return (
135+
self._experiment_name_field.isValid()
136+
and self._ensemble_format_field.isValid()
137+
and self._active_realizations_field.isValid()
138+
)
139+
140+
def get_experiment_arguments(self) -> Arguments:
141+
arguments = Arguments(
142+
mode=ENIF_MODE,
143+
target_ensemble=self._ensemble_format_model.getValue(), # type: ignore
144+
realizations=self._active_realizations_field.text(),
145+
experiment_name=self._experiment_name_field.get_text,
146+
)
147+
return arguments

src/ert/gui/simulation/experiment_panel.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from ..summarypanel import SummaryPanel
3131
from .combobox_with_description import QComboBoxWithDescription
3232
from .ensemble_experiment_panel import EnsembleExperimentPanel
33+
from .ensemble_information_filter_panel import EnsembleInformationFilterPanel
3334
from .ensemble_smoother_panel import EnsembleSmootherPanel
3435
from .evaluate_ensemble_panel import EvaluateEnsemblePanel
3536
from .experiment_config_panel import ExperimentConfigPanel
@@ -174,6 +175,12 @@ def __init__(
174175
EnsembleSmootherPanel(analysis_config, run_path, notifier, ensemble_size),
175176
experiment_type_valid,
176177
)
178+
self.addExperimentConfigPanel(
179+
EnsembleInformationFilterPanel(
180+
analysis_config, run_path, notifier, ensemble_size
181+
),
182+
experiment_type_valid,
183+
)
177184
self.addExperimentConfigPanel(
178185
ManualUpdatePanel(ensemble_size, run_path, notifier, analysis_config),
179186
experiment_type_valid,

tests/ert/ui_tests/gui/test_main_window.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
from ert.plugins import ErtPluginManager
5454
from ert.run_models import (
5555
EnsembleExperiment,
56+
EnsembleInformationFilter,
5657
EnsembleSmoother,
5758
MultipleDataAssimilation,
5859
SingleTestRun,
@@ -111,7 +112,7 @@ def test_that_the_ui_show_no_errors_and_enables_update_for_poly_example(qapp):
111112
with add_gui_log_handler() as log_handler:
112113
gui, *_ = ert.gui.main._start_initial_gui_window(args, log_handler)
113114
combo_box = get_child(gui, QComboBox, name="experiment_type")
114-
assert combo_box.count() == 6
115+
assert combo_box.count() == 7
115116

116117
for i in range(combo_box.count()):
117118
assert combo_box.model().item(i).isEnabled()
@@ -131,7 +132,7 @@ def test_gui_shows_a_warning_and_disables_update_when_there_are_no_observations(
131132
with add_gui_log_handler() as log_handler:
132133
gui, *_ = ert.gui.main._start_initial_gui_window(args, log_handler)
133134
combo_box = get_child(gui, QComboBox, name="experiment_type")
134-
assert combo_box.count() == 6
135+
assert combo_box.count() == 7
135136

136137
for i in range(3):
137138
assert combo_box.model().item(i).isEnabled()
@@ -159,7 +160,7 @@ def test_gui_shows_a_warning_and_disables_update_when_parameters_are_missing(
159160
with add_gui_log_handler() as log_handler:
160161
gui, *_ = ert.gui.main._start_initial_gui_window(args, log_handler)
161162
combo_box = get_child(gui, QComboBox, name="experiment_type")
162-
assert combo_box.count() == 6
163+
assert combo_box.count() == 7
163164

164165
for i in range(3):
165166
assert combo_box.model().item(i).isEnabled()
@@ -699,7 +700,7 @@ def test_that_es_mda_restart_run_box_is_disabled_when_there_are_no_cases(qtbot):
699700

700701
combo_box = get_child(gui, QComboBox, name="experiment_type")
701702
qtbot.mouseClick(combo_box, Qt.MouseButton.LeftButton)
702-
assert combo_box.count() == 6
703+
assert combo_box.count() == 7
703704
combo_box.setCurrentIndex(3)
704705

705706
assert combo_box.currentText() == MultipleDataAssimilation.display_name()
@@ -749,6 +750,7 @@ def test_validation_of_experiment_names_in_run_models(
749750
experiment_types_to_test = (
750751
(EnsembleExperiment.display_name(), "Ensemble_experiment_panel"),
751752
(EnsembleSmoother.display_name(), "ensemble_smoother_panel"),
753+
(EnsembleInformationFilter.display_name(), "enif_panel"),
752754
(
753755
MultipleDataAssimilation.display_name(),
754756
"ES_MDA_panel",

0 commit comments

Comments
 (0)