Skip to content

Commit

Permalink
Improve experiment name validation
Browse files Browse the repository at this point in the history
  • Loading branch information
larsevj committed Sep 16, 2024
1 parent 9dcd437 commit dbf2ae6
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 31 deletions.
29 changes: 20 additions & 9 deletions src/ert/gui/ertwidgets/create_experiment_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
QDialogButtonBox,
QGridLayout,
QLabel,
QLineEdit,
QWidget,
)

from ert.gui.ertnotifier import ErtNotifier
from ert.gui.ertwidgets import StringBox, TextModel
from ert.validation.proper_name_argument import ExperimentValidation
from ert.validation.proper_name_argument import (
ExperimentValidation,
ProperNameArgument,
)


class CreateExperimentDialog(QDialog):
Expand All @@ -41,9 +43,10 @@ def __init__(
self._experiment_edit.setValidator(ExperimentValidation(notifier.storage))

ensemble_label = QLabel("Ensemble name:")
self._ensemble_edit = QLineEdit()
self._ensemble_edit.setMinimumWidth(200)
self._ensemble_edit.setPlaceholderText("My ensemble")
self._ensemble_edit = StringBox(
TextModel(""), placeholder_text="My_ensemble", minimum_width=200
)
self._ensemble_edit.setValidator(ProperNameArgument())

buttons = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
Expand All @@ -64,10 +67,7 @@ def __init__(
self._ok_button.setEnabled(False)

def enableOkButton() -> None:
self._ok_button.setEnabled(
len(self._experiment_edit.text()) != 0
and len(self._ensemble_edit.text()) != 0
)
self._ok_button.setEnabled(self.isConfigurationValid())

self._experiment_edit.textChanged.connect(enableOkButton)
self._ensemble_edit.textChanged.connect(enableOkButton)
Expand All @@ -80,6 +80,14 @@ def enableOkButton() -> None:

self.setLayout(layout)

self._experiment_edit.getValidationSupport().validationChanged.connect(
enableOkButton
)

self._ensemble_edit.getValidationSupport().validationChanged.connect(
enableOkButton
)

self._experiment_edit.setFocus()

@property
Expand All @@ -89,3 +97,6 @@ def experiment_name(self) -> str:
@property
def ensemble_name(self) -> str:
return self._ensemble_edit.text()

def isConfigurationValid(self) -> bool:
return self._experiment_edit.isValid() and self._ensemble_edit.isValid()
9 changes: 7 additions & 2 deletions src/ert/gui/simulation/ensemble_experiment_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
from ert.mode_definitions import ENSEMBLE_EXPERIMENT_MODE
from ert.run_models import EnsembleExperiment
from ert.validation import RangeStringArgument
from ert.validation.proper_name_argument import ExperimentValidation
from ert.validation.proper_name_argument import (
ExperimentValidation,
ProperNameArgument,
)

from .experiment_config_panel import ExperimentConfigPanel

Expand Down Expand Up @@ -46,14 +49,16 @@ def __init__(self, ensemble_size: int, run_path: str, notifier: ErtNotifier):
),
)
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)
self._experiment_name_field.setValidator(
ExperimentValidation(self.notifier.storage)
)
self._experiment_name_field.setObjectName("experiment_field")
layout.addRow("Experiment name:", self._experiment_name_field)

self._ensemble_name_field = StringBox(
TextModel(""), placeholder_text="ensemble"
)
self._ensemble_name_field.setValidator(ProperNameArgument())
self._ensemble_name_field.setMinimumWidth(250)

layout.addRow("Ensemble name:", self._ensemble_name_field)
Expand Down
13 changes: 9 additions & 4 deletions src/ert/gui/simulation/ensemble_smoother_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ def __init__(
),
)
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)
self._experiment_name_field.setValidator(
ExperimentValidation(self.notifier.storage)
)
self._experiment_name_field.setObjectName("experiment_field")
layout.addRow("Experiment name:", self._experiment_name_field)

runpath_label = CopyableLabel(text=run_path)
layout.addRow("Runpath:", runpath_label)
Expand Down Expand Up @@ -90,10 +91,13 @@ def __init__(

self.setLayout(layout)

self._ensemble_format_field.getValidationSupport().validationChanged.connect( # noqa
self._experiment_name_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self._ensemble_format_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self._active_realizations_field.getValidationSupport().validationChanged.connect( # noqa
self._active_realizations_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)

Expand All @@ -111,7 +115,8 @@ def _update_experiment_name_placeholder(self) -> None:

def isConfigurationValid(self) -> bool:
return (
self._ensemble_format_field.isValid()
self._experiment_name_field.isValid()
and self._ensemble_format_field.isValid()
and self._active_realizations_field.isValid()
)

Expand Down
14 changes: 10 additions & 4 deletions src/ert/gui/simulation/iterated_ensemble_smoother_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(
ExperimentConfigPanel.__init__(self, IteratedEnsembleSmoother)
self.analysis_config = analysis_config
layout = QFormLayout()
self.setObjectName("iterated_ensemble_smoother_panel")

self._experiment_name_field = StringBox(
TextModel(""),
Expand All @@ -55,10 +56,11 @@ def __init__(
),
)
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)
self._experiment_name_field.setValidator(
ExperimentValidation(self.notifier.storage)
)
self._experiment_name_field.setObjectName("experiment_field")
layout.addRow("Experiment name:", self._experiment_name_field)

runpath_label = CopyableLabel(text=run_path)
layout.addRow("Runpath:", runpath_label)
Expand Down Expand Up @@ -103,10 +105,13 @@ def __init__(
self._active_realizations_field.setValidator(RangeStringArgument(ensemble_size))
layout.addRow("Active realizations", self._active_realizations_field)

self._iterated_target_ensemble_format_field.getValidationSupport().validationChanged.connect( # noqa
self._experiment_name_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self._iterated_target_ensemble_format_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self._active_realizations_field.getValidationSupport().validationChanged.connect( # noqa
self._active_realizations_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self.setLayout(layout)
Expand All @@ -127,7 +132,8 @@ def _update_experiment_name_placeholder(self) -> None:

def isConfigurationValid(self) -> bool:
return (
self._iterated_target_ensemble_format_field.isValid()
self._experiment_name_field.isValid()
and self._iterated_target_ensemble_format_field.isValid()
and self._active_realizations_field.isValid()
)

Expand Down
25 changes: 15 additions & 10 deletions src/ert/gui/simulation/multiple_data_assimilation_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ def __init__(
),
)
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)
self._experiment_name_field.setValidator(
ExperimentValidation(self.notifier.storage)
)
self._experiment_name_field.setObjectName("experiment_field")
layout.addRow("Experiment name:", self._experiment_name_field)

runpath_label = CopyableLabel(text=run_path)
layout.addRow("Runpath:", runpath_label)

Expand Down Expand Up @@ -119,13 +121,16 @@ def __init__(
self._ensemble_selector.currentIndexChanged.connect(self.update_experiment_name)
layout.addRow("Restart from:", self._ensemble_selector)

self._target_ensemble_format_field.getValidationSupport().validationChanged.connect( # noqa
self._experiment_name_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self._target_ensemble_format_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self._active_realizations_field.getValidationSupport().validationChanged.connect( # noqa
self._active_realizations_field.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)
self._relative_iteration_weights_box.getValidationSupport().validationChanged.connect( # noqa
self._relative_iteration_weights_box.getValidationSupport().validationChanged.connect(
self.simulationConfigurationChanged
)

Expand Down Expand Up @@ -158,15 +163,14 @@ def update_experiment_name(self) -> None:

@Slot(bool)
def update_experiment_edit(self, checked: bool) -> None:
self._experiment_name_field.clear()
self._experiment_name_field.enable_validation(not checked)
self._experiment_name_field.setEnabled(not checked)
if checked:
self._experiment_name_field.setText(
self._ensemble_selector.selected_ensemble.experiment.name
)
else:
self._experiment_name_field.clear()

self._experiment_name_field.enable_validation(not checked)
self._experiment_name_field.setEnabled(not checked)
self._evaluate_weights_box_enabled()

def _evaluate_weights_box_enabled(self) -> None:
Expand Down Expand Up @@ -219,15 +223,16 @@ def updateVisualizationOfNormalizedWeights() -> None:
else:
normalized_weights_model.setValue("The weights are invalid!")

self._relative_iteration_weights_box.getValidationSupport().validationChanged.connect( # noqa
self._relative_iteration_weights_box.getValidationSupport().validationChanged.connect(
updateVisualizationOfNormalizedWeights
)

updateVisualizationOfNormalizedWeights() # To normalize the default weights

def isConfigurationValid(self) -> bool:
return (
self._target_ensemble_format_field.isValid()
self._experiment_name_field.isValid()
and self._target_ensemble_format_field.isValid()
and self._active_realizations_field.isValid()
and self._relative_iteration_weights_box.isValid()
and self.weights_valid
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests/gui/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ def handle_popup_dialog():


def add_experiment_manually(
qtbot, gui, experiment_name="My experiment", ensemble_name="default"
qtbot, gui, experiment_name="My_experiment", ensemble_name="default"
):
manage_tool = gui.tools["Manage experiments"]
manage_tool.trigger()
Expand Down
53 changes: 52 additions & 1 deletion tests/unit_tests/gui/test_main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import ert.gui
from ert.config import ErtConfig
from ert.gui.about_dialog import AboutDialog
from ert.gui.ertwidgets import StringBox
from ert.gui.ertwidgets.analysismodulevariablespanel import AnalysisModuleVariablesPanel
from ert.gui.ertwidgets.create_experiment_dialog import CreateExperimentDialog
from ert.gui.ertwidgets.ensembleselector import EnsembleSelector
Expand All @@ -42,7 +43,13 @@
)
from ert.gui.tools.plot.plot_window import PlotApi, PlotWindow
from ert.plugins import ErtPluginManager
from ert.run_models import SingleTestRun
from ert.run_models import (
EnsembleExperiment,
EnsembleSmoother,
IteratedEnsembleSmoother,
MultipleDataAssimilation,
SingleTestRun,
)
from ert.services import StorageService

from .conftest import (
Expand Down Expand Up @@ -434,8 +441,19 @@ def test_that_the_manage_experiments_tool_can_be_used(

def handle_add_dialog():
dialog = wait_for_child(current_tab, qtbot, CreateExperimentDialog)

dialog._experiment_edit.setText("es_mda")
assert not dialog._ok_button.isEnabled()
dialog._experiment_edit.setText(" @not_v alid")
assert not dialog._ok_button.isEnabled()
dialog._experiment_edit.setText("my-experiment")
assert dialog._ok_button.isEnabled()

dialog._ensemble_edit.setText(" @not_v alid")
assert not dialog._ok_button.isEnabled()
dialog._ensemble_edit.setText("_new_ensemble_")
assert dialog._ok_button.isEnabled()

qtbot.mouseClick(dialog._ok_button, Qt.MouseButton.LeftButton)

QTimer.singleShot(1000, handle_add_dialog)
Expand Down Expand Up @@ -682,3 +700,36 @@ def test_help_menu(qtbot):
qtbot.mouseClick(
get_child(about_dialog, QPushButton, name="close_button"), Qt.LeftButton
)


def test_validation_of_experiment_names_in_run_models(
ensemble_experiment_has_run_no_failure, qtbot
):
gui = ensemble_experiment_has_run_no_failure
experiment_panel = get_child(gui, ExperimentPanel)
experiment_types = get_child(experiment_panel, QComboBox, name="experiment_type")
run_experiment = get_child(experiment_panel, QWidget, name="run_experiment")

experiment_types_to_test = (
(EnsembleExperiment.name(), "Ensemble_experiment_panel"),
(EnsembleSmoother.name(), "ensemble_smoother_panel"),
(MultipleDataAssimilation.name(), "ES_MDA_panel"),
(IteratedEnsembleSmoother.name(), "iterated_ensemble_smoother_panel"),
)
for exp_type, panel_name in experiment_types_to_test:
print(f"{exp_type}")
experiment_types.setCurrentText(exp_type)

experiment_config_panel = get_child(gui, QWidget, name=panel_name)
experiment_field = get_child(
experiment_config_panel, StringBox, name="experiment_field"
)
print(f"{experiment_field.get_text=}")
experiment_field.setText(" @not val id")
assert not run_experiment.isEnabled()

experiment_field.setText("valid_")
assert run_experiment.isEnabled()

experiment_field.setText("ensemble_experiment")
assert not run_experiment.isEnabled()

0 comments on commit dbf2ae6

Please sign in to comment.