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 24, 2024
1 parent 67b0e46 commit 06412db
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 61 deletions.
14 changes: 12 additions & 2 deletions src/ert/gui/ertwidgets/create_experiment_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@
QWidget,
)

from ert.gui.ertnotifier import ErtNotifier
from ert.gui.ertwidgets import StringBox, TextModel
from ert.validation.range_string_argument import NotInStorage


class CreateExperimentDialog(QDialog):
onDone = Signal(str, str)

def __init__(
self,
notifier: ErtNotifier,
title: str = "Create new experiment",
parent: Optional[QWidget] = None,
) -> None:
Expand All @@ -30,8 +35,13 @@ def __init__(
layout = QGridLayout()

experiment_label = QLabel("Experiment name:")
self._experiment_edit = QLineEdit()
self._experiment_edit.setPlaceholderText("My experiment")
self._experiment_edit = StringBox(
TextModel(""),
placeholder_text="My experiment",
)
self._experiment_edit.setValidator(
NotInStorage(notifier.storage, "experiments")
)

ensemble_label = QLabel("Ensemble name:")
self._ensemble_edit = QLineEdit()
Expand Down
2 changes: 1 addition & 1 deletion src/ert/gui/ertwidgets/storage_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def _currentChanged(self, selected: QModelIndex, previous: QModelIndex) -> None:
self.onSelectRealization.emit(ensemble, cls.realization)

def _addItem(self) -> None:
create_experiment_dialog = CreateExperimentDialog(parent=self)
create_experiment_dialog = CreateExperimentDialog(self._notifier, parent=self)
create_experiment_dialog.show()
if create_experiment_dialog.exec_():
ensemble = self._notifier.storage.create_experiment(
Expand Down
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 @@ -43,10 +44,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 @@ -84,6 +92,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 @@ -95,10 +115,6 @@ def get_experiment_arguments(self) -> Arguments:
mode=ENSEMBLE_SMOOTHER_MODE,
target_ensemble=self._ensemble_format_model.getValue(),
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,
)
Loading

0 comments on commit 06412db

Please sign in to comment.