Skip to content

Commit

Permalink
Create unique experiment names for GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
frode-aarstad committed Jun 20, 2024
1 parent 4f363cc commit 16eacf1
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 57 deletions.
35 changes: 26 additions & 9 deletions src/ert/gui/simulation/ensemble_experiment_panel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import dataclass

from qtpy import QtCore
from qtpy.QtCore import Slot
from qtpy.QtWidgets import QFormLayout, QLabel

from ert.gui.ertnotifier import ErtNotifier
Expand Down Expand Up @@ -35,14 +36,18 @@ def __init__(self, ensemble_size: int, run_path: str, notifier: ErtNotifier):
lab.setAlignment(QtCore.Qt.AlignLeft)
layout.addRow(lab)

self._name_field = StringBox(
TextModel(""), placeholder_text="ensemble-experiment"
self._experiment_name_field = StringBox(
TextModel(""),
placeholder_text=self.notifier.storage.get_unique_experiment_name(
ENSEMBLE_EXPERIMENT_MODE
),
)
self._name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._name_field)
self._name_field.setValidator(
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)
self._experiment_name_field.setValidator(
NotInStorage(self.notifier.storage, "experiments")
)

self._ensemble_name_field = StringBox(
TextModel(""), placeholder_text="ensemble"
)
Expand Down Expand Up @@ -73,21 +78,33 @@ def __init__(self, ensemble_size: int, run_path: str, notifier: ErtNotifier):
self._active_realizations_field.getValidationSupport().validationChanged.connect( # noqa
self.simulationConfigurationChanged
)
self._name_field.getValidationSupport().validationChanged.connect( # noqa
self._experiment_name_field.getValidationSupport().validationChanged.connect( # noqa
self.simulationConfigurationChanged
)
self._ensemble_name_field.getValidationSupport().validationChanged.connect( # noqa
self.simulationConfigurationChanged
)

self.notifier.ertChanged.connect(self._update_experiment_name_placeholder)

@Slot(ExperimentConfigPanel)
def experimentTypeChanged(self, w: ExperimentConfigPanel) -> None:
if isinstance(w, EnsembleExperimentPanel):
self._update_experiment_name_placeholder()

def _update_experiment_name_placeholder(self) -> None:
self._experiment_name_field.setPlaceholderText(
self.notifier.storage.get_unique_experiment_name(ENSEMBLE_EXPERIMENT_MODE)
)

def isConfigurationValid(self) -> bool:
self.blockSignals(True)
self._name_field.validateString()
self._experiment_name_field.validateString()
self._ensemble_name_field.validateString()
self.blockSignals(False)
return (
self._active_realizations_field.isValid()
and self._name_field.isValid()
and self._experiment_name_field.isValid()
and self._ensemble_name_field.isValid()
)

Expand All @@ -96,5 +113,5 @@ def get_experiment_arguments(self) -> Arguments:
mode=ENSEMBLE_EXPERIMENT_MODE,
current_ensemble=self._ensemble_name_field.get_text,
realizations=self._active_realizations_field.text(),
experiment_name=self._name_field.get_text,
experiment_name=self._experiment_name_field.get_text,
)
40 changes: 28 additions & 12 deletions src/ert/gui/simulation/ensemble_smoother_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING

from qtpy.QtWidgets import QFormLayout, QLabel, QLineEdit
from qtpy.QtCore import Slot
from qtpy.QtWidgets import QFormLayout, QLabel

from ert.gui.ertnotifier import ErtNotifier
from ert.gui.ertwidgets import AnalysisModuleEdit
from ert.gui.ertwidgets import AnalysisModuleEdit, StringBox, TextModel
from ert.gui.ertwidgets.copyablelabel import CopyableLabel
from ert.gui.ertwidgets.models.activerealizationsmodel import ActiveRealizationsModel
from ert.gui.ertwidgets.models.targetensemblemodel import TargetEnsembleModel
from ert.gui.ertwidgets.stringbox import StringBox
from ert.mode_definitions import ENSEMBLE_SMOOTHER_MODE
from ert.run_models import EnsembleSmoother
from ert.validation import ProperNameFormatArgument, RangeStringArgument
from ert.validation.range_string_argument import NotInStorage

from .experiment_config_panel import ExperimentConfigPanel

Expand Down Expand Up @@ -44,10 +45,17 @@ def __init__(

self.setObjectName("ensemble_smoother_panel")

self._name_field = QLineEdit()
self._name_field.setPlaceholderText(ENSEMBLE_SMOOTHER_MODE)
self._name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._name_field)
self._experiment_name_field = StringBox(
TextModel(""),
placeholder_text=self.notifier.storage.get_unique_experiment_name(
ENSEMBLE_SMOOTHER_MODE
),
)
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)
self._experiment_name_field.setValidator(
NotInStorage(self.notifier.storage, "experiments")
)

runpath_label = CopyableLabel(text=run_path)
layout.addRow("Runpath:", runpath_label)
Expand Down Expand Up @@ -85,6 +93,18 @@ def __init__(
self.simulationConfigurationChanged
)

self.notifier.ertChanged.connect(self._update_experiment_name_placeholder)

@Slot(ExperimentConfigPanel)
def experimentTypeChanged(self, w: ExperimentConfigPanel) -> None:
if isinstance(w, EnsembleSmootherPanel):
self._update_experiment_name_placeholder()

def _update_experiment_name_placeholder(self) -> None:
self._experiment_name_field.setPlaceholderText(
self.notifier.storage.get_unique_experiment_name(ENSEMBLE_SMOOTHER_MODE)
)

def isConfigurationValid(self) -> bool:
return (
self._ensemble_format_field.isValid()
Expand All @@ -97,10 +117,6 @@ def get_experiment_arguments(self) -> Arguments:
current_ensemble=self._ensemble_format_model.getValue() % 0,
target_ensemble=self._ensemble_format_model.getValue() % 1,
realizations=self._active_realizations_field.text(),
experiment_name=(
self._name_field.text()
if self._name_field.text()
else self._name_field.placeholderText()
),
experiment_name=self._experiment_name_field.get_text,
)
return arguments
12 changes: 7 additions & 5 deletions src/ert/gui/simulation/experiment_config_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from typing import Any, Dict

from qtpy.QtCore import Signal
from qtpy.QtCore import Signal, Slot
from qtpy.QtWidgets import QWidget


Expand All @@ -17,10 +17,12 @@ def __init__(self, simulation_model):
def get_experiment_type(self):
return self.__simulation_model

@staticmethod
def isConfigurationValid() -> bool:
def isConfigurationValid(self) -> bool:
return True

@staticmethod
def get_experiment_arguments() -> Dict[str, Any]:
def get_experiment_arguments(self) -> Dict[str, Any]:
return {}

@Slot(QWidget)
def experimentTypeChanged(self, w: QWidget):
pass
14 changes: 10 additions & 4 deletions src/ert/gui/simulation/experiment_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from queue import SimpleQueue
from typing import Any, Dict, List

from qtpy.QtCore import QSize, Qt
from qtpy.QtCore import QSize, Qt, Signal
from qtpy.QtGui import QIcon
from qtpy.QtWidgets import (
QAction,
Expand Down Expand Up @@ -43,6 +43,8 @@


class ExperimentPanel(QWidget):
experiment_type_changed = Signal(ExperimentConfigPanel)

def __init__(
self,
config: ErtConfig,
Expand All @@ -68,9 +70,11 @@ def __init__(

experiment_type_layout = QHBoxLayout()
experiment_type_layout.addSpacing(10)
experiment_type_layout.addWidget(QLabel("Experiment type:"), 0, Qt.AlignVCenter)
experiment_type_layout.addWidget(
self._experiment_type_combo, 0, Qt.AlignVCenter
QLabel("Experiment type:"), 0, Qt.AlignmentFlag.AlignVCenter
)
experiment_type_layout.addWidget(
self._experiment_type_combo, 0, Qt.AlignmentFlag.AlignVCenter
)

experiment_type_layout.addSpacing(20)
Expand Down Expand Up @@ -148,14 +152,15 @@ def addExperimentConfigPanel(self, panel, mode_enabled: bool) -> None:
sim_item.setIcon(self.style().standardIcon(QStyle.SP_MessageBoxWarning))

panel.simulationConfigurationChanged.connect(self.validationStatusChanged)
self.experiment_type_changed.connect(panel.experimentTypeChanged)

@staticmethod
def getActions() -> List[QAction]:
return []

def get_current_experiment_type(self):
return self._experiment_type_combo.itemData(
self._experiment_type_combo.currentIndex(), Qt.UserRole
self._experiment_type_combo.currentIndex(), Qt.ItemDataRole.UserRole
)

def get_experiment_arguments(self) -> Dict[str, Any]:
Expand Down Expand Up @@ -308,6 +313,7 @@ def toggleExperimentType(self) -> None:
widget = self._experiment_widgets[self.get_current_experiment_type()]
self._experiment_stack.setCurrentWidget(widget)
self.validationStatusChanged()
self.experiment_type_changed.emit(widget)

def validationStatusChanged(self) -> None:
widget = self._experiment_widgets[self.get_current_experiment_type()]
Expand Down
42 changes: 30 additions & 12 deletions src/ert/gui/simulation/iterated_ensemble_smoother_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING

from qtpy.QtWidgets import QFormLayout, QLabel, QLineEdit, QSpinBox
from qtpy.QtCore import Slot
from qtpy.QtWidgets import QFormLayout, QLabel, QSpinBox

from ert.gui.ertnotifier import ErtNotifier
from ert.gui.ertwidgets import AnalysisModuleEdit
from ert.gui.ertwidgets import AnalysisModuleEdit, StringBox, TextModel
from ert.gui.ertwidgets.copyablelabel import CopyableLabel
from ert.gui.ertwidgets.models.activerealizationsmodel import ActiveRealizationsModel
from ert.gui.ertwidgets.models.targetensemblemodel import TargetEnsembleModel
from ert.gui.ertwidgets.stringbox import StringBox
from ert.mode_definitions import ITERATIVE_ENSEMBLE_SMOOTHER_MODE
from ert.run_models import IteratedEnsembleSmoother
from ert.validation import ProperNameFormatArgument, RangeStringArgument
from ert.validation.range_string_argument import NotInStorage

from .experiment_config_panel import ExperimentConfigPanel

Expand Down Expand Up @@ -43,10 +44,17 @@ def __init__(
self.analysis_config = analysis_config
layout = QFormLayout()

self._name_field = QLineEdit()
self._name_field.setPlaceholderText("iterated_ensemble_smoother")
self._name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._name_field)
self._experiment_name_field = StringBox(
TextModel(""),
placeholder_text=self.notifier.storage.get_unique_experiment_name(
ITERATIVE_ENSEMBLE_SMOOTHER_MODE
),
)
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)
self._experiment_name_field.setValidator(
NotInStorage(self.notifier.storage, "experiments")
)

runpath_label = CopyableLabel(text=run_path)
layout.addRow("Runpath:", runpath_label)
Expand Down Expand Up @@ -98,6 +106,20 @@ def __init__(
)
self.setLayout(layout)

self.notifier.ertChanged.connect(self._update_experiment_name_placeholder)

@Slot(ExperimentConfigPanel)
def experimentTypeChanged(self, w: ExperimentConfigPanel) -> None:
if isinstance(w, IteratedEnsembleSmootherPanel):
self._update_experiment_name_placeholder()

def _update_experiment_name_placeholder(self) -> None:
self._experiment_name_field.setPlaceholderText(
self.notifier.storage.get_unique_experiment_name(
ITERATIVE_ENSEMBLE_SMOOTHER_MODE
)
)

def setNumberIterations(self, iteration_count):
if iteration_count != self.analysis_config.num_iterations:
self.analysis_config.set_num_iterations(iteration_count)
Expand All @@ -115,9 +137,5 @@ def get_experiment_arguments(self) -> Arguments:
target_ensemble=self._iterated_target_ensemble_format_model.getValue(),
realizations=self._active_realizations_field.text(),
num_iterations=self._num_iterations_spinner.value(),
experiment_name=(
self._name_field.text()
if self._name_field.text()
else self._name_field.placeholderText()
),
experiment_name=self._experiment_name_field.get_text,
)
42 changes: 31 additions & 11 deletions src/ert/gui/simulation/multiple_data_assimilation_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,28 @@
from typing import TYPE_CHECKING, Any, List

from qtpy.QtCore import Slot
from qtpy.QtWidgets import QCheckBox, QFormLayout, QLabel, QLineEdit
from qtpy.QtWidgets import QCheckBox, QFormLayout, QLabel

from ert.gui.ertnotifier import ErtNotifier
from ert.gui.ertwidgets import ActiveLabel, AnalysisModuleEdit, EnsembleSelector
from ert.gui.ertwidgets import (
ActiveLabel,
AnalysisModuleEdit,
EnsembleSelector,
StringBox,
TextModel,
)
from ert.gui.ertwidgets.copyablelabel import CopyableLabel
from ert.gui.ertwidgets.models.activerealizationsmodel import ActiveRealizationsModel
from ert.gui.ertwidgets.models.targetensemblemodel import TargetEnsembleModel
from ert.gui.ertwidgets.models.valuemodel import ValueModel
from ert.gui.ertwidgets.stringbox import StringBox
from ert.mode_definitions import ES_MDA_MODE
from ert.run_models import MultipleDataAssimilation
from ert.validation import (
NumberListStringArgument,
ProperNameFormatArgument,
RangeStringArgument,
)
from ert.validation.range_string_argument import NotInStorage

from .experiment_config_panel import ExperimentConfigPanel

Expand Down Expand Up @@ -52,11 +58,17 @@ def __init__(
layout = QFormLayout()
self.setObjectName("ES_MDA_panel")

self._experiment_name_field = QLineEdit()
self._experiment_name_field.setPlaceholderText("es_mda")
self._experiment_name_field = StringBox(
TextModel(""),
placeholder_text=self.notifier.storage.get_unique_experiment_name(
ES_MDA_MODE
),
)
self._experiment_name_field.setMinimumWidth(250)
layout.addRow("Experiment name:", self._experiment_name_field)

self._experiment_name_field.setValidator(
NotInStorage(self.notifier.storage, "experiments")
)
runpath_label = CopyableLabel(text=run_path)
layout.addRow("Runpath:", runpath_label)

Expand Down Expand Up @@ -117,6 +129,18 @@ def __init__(

self.setLayout(layout)

self.notifier.ertChanged.connect(self._update_experiment_name_placeholder)

@Slot(ExperimentConfigPanel)
def experimentTypeChanged(self, w: ExperimentConfigPanel) -> None:
if isinstance(w, MultipleDataAssimilationPanel):
self._update_experiment_name_placeholder()

def _update_experiment_name_placeholder(self) -> None:
self._experiment_name_field.setPlaceholderText(
self.notifier.storage.get_unique_experiment_name(ES_MDA_MODE)
)

@Slot()
def update_experiment_name(self) -> None:
if not self._experiment_name_field.isEnabled():
Expand Down Expand Up @@ -199,11 +223,7 @@ def get_experiment_arguments(self) -> Arguments:
if self._restart_box.isChecked()
else ""
),
experiment_name=(
self._experiment_name_field.text()
if self._experiment_name_field.text()
else self._experiment_name_field.placeholderText()
),
experiment_name=self._experiment_name_field.get_text,
)

def setWeights(self, weights: Any) -> None:
Expand Down
Loading

0 comments on commit 16eacf1

Please sign in to comment.