diff --git a/src/ert/config/analysis_module.py b/src/ert/config/analysis_module.py
index 65da352e4c1..63f0b17aa5a 100644
--- a/src/ert/config/analysis_module.py
+++ b/src/ert/config/analysis_module.py
@@ -265,6 +265,9 @@ def get_steplength(self, iteration_nr: int) -> float:
)
return step_length
+ def __str__(self) -> str:
+ return f"AnalysisModule: {self.name}"
+
def __repr__(self) -> str:
return f"AnalysisModule(name = {self.name})"
diff --git a/src/ert/gui/ertwidgets/analysismodulevariablespanel.py b/src/ert/gui/ertwidgets/analysismodulevariablespanel.py
index 5236b2ca5a8..7c0f21406f2 100644
--- a/src/ert/gui/ertwidgets/analysismodulevariablespanel.py
+++ b/src/ert/gui/ertwidgets/analysismodulevariablespanel.py
@@ -1,18 +1,20 @@
from functools import partial
+from qtpy.QtCore import Qt
from qtpy.QtWidgets import (
QButtonGroup,
QCheckBox,
QDoubleSpinBox,
QFormLayout,
+ QFrame,
QHBoxLayout,
QLabel,
- QLineEdit,
QRadioButton,
QWidget,
)
-from ert.config.analysis_module import AnalysisModule, correlation_threshold
+from ert.config import AnalysisMode
+from ert.config.analysis_module import AnalysisModule
from ert.gui.ertwidgets.models.analysismodulevariablesmodel import (
AnalysisModuleVariablesModel,
)
@@ -24,95 +26,102 @@ def __init__(self, analysis_module: AnalysisModule, ensemble_size: int):
self.analysis_module = analysis_module
layout = QFormLayout()
+ layout.setVerticalSpacing(5)
+ layout.setLabelAlignment(Qt.AlignLeft)
+ layout.setHorizontalSpacing(150)
variable_names = analysis_module.get_variable_names()
- if len(variable_names) == 0:
- label = QLabel("No variables found to edit")
- boxlayout = QHBoxLayout()
- layout.addRow(label, boxlayout)
-
- else:
- analysis_module_variables_model = AnalysisModuleVariablesModel
- self.blockSignals(True)
-
- for variable_name in variable_names:
- variable_type = analysis_module_variables_model.getVariableType(
- variable_name
+ analysis_module_variables_model = AnalysisModuleVariablesModel
+ self.blockSignals(True)
+
+ layout.addRow(QLabel(str(analysis_module)))
+ layout.addRow(self.create_horizontal_line())
+
+ if analysis_module.mode == AnalysisMode.ITERATED_ENSEMBLE_SMOOTHER:
+ for variable_name in (
+ name for name in variable_names if "STEPLENGTH" in name
+ ):
+ layout.addRow(
+ analysis_module_variables_model.getVariableLabelName(variable_name),
+ self.createDoubleSpinBox(
+ variable_name,
+ analysis_module.get_variable_value(variable_name),
+ analysis_module_variables_model,
+ ),
)
- variable_value = analysis_module.get_variable_value(variable_name)
-
- if variable_name == "LOCALIZATION_CORRELATION_THRESHOLD":
- variable_value = correlation_threshold(
- ensemble_size, variable_value
- )
- label_name = analysis_module_variables_model.getVariableLabelName(
- variable_name
+ for s in [
+ "A good start is max steplength of 0.6, min steplength of 0.3, and decline of 2.5",
+ "A steplength of 1.0 and one iteration results in ES update",
+ ]:
+ lab = QLabel(s)
+ lab.setStyleSheet(
+ "font-style: italic; font-size: 10pt; font-weight: 300"
)
- if variable_type == bool:
- layout.addRow(
- label_name,
- self.createCheckBox(
- variable_name, variable_value, variable_type
- ),
- )
-
- elif variable_type == float:
- layout.addRow(
- label_name,
- self.createDoubleSpinBox(
- variable_name,
- variable_value,
- variable_type,
- analysis_module_variables_model,
- ),
- )
-
- if variable_name == "IES_INVERSION":
- layout.addRow(QLabel("Inversion Algorithm"))
- bg = QButtonGroup(self)
- for button_id, s in enumerate(
- [
- "Exact inversion with diagonal R=I",
- "Subspace inversion with exact R",
- "Subspace inversion using R=EE'",
- "Subspace inversion using E",
- ],
- start=0,
- ):
- b = QRadioButton(s, self)
- b.setObjectName(variable_name + "_" + str(button_id))
- bg.addButton(b, button_id)
- layout.addRow(b)
-
- bg.buttons()[0].setChecked(True) # check the first option
- bg.idClicked.connect(self.update_inversion_algorithm)
-
- if variable_name == "IES_DEC_STEPLENGTH":
- for s in [
- "'
- "A good start is max steplength of 0.6, min steplength of 0.3, and decline of 2.5",
- "'
- "A steplength of 1.0 and one iteration results in ES update",
- ]:
- layout.addRow(QLabel(s))
-
- self.truncation_spinner = self.widget_from_layout(layout, "ENKF_TRUNCATION")
+ layout.addRow(lab)
+
+ layout.addRow(self.create_horizontal_line())
+
+ layout.addRow(QLabel("Inversion Algorithm"))
+ bg = QButtonGroup(self)
+ for button_id, s in enumerate(
+ [
+ "Exact inversion with diagonal R=I",
+ "Subspace inversion with exact R",
+ "Subspace inversion using R=EE'",
+ "Subspace inversion using E",
+ ],
+ start=0,
+ ):
+ b = QRadioButton(s, self)
+ b.setObjectName("IES_INVERSION_" + str(button_id))
+ bg.addButton(b, button_id)
+ layout.addRow(b)
+
+ self.truncation_spinner = self.createDoubleSpinBox(
+ "ENKF_TRUNCATION",
+ analysis_module.get_truncation(),
+ analysis_module_variables_model,
+ )
self.truncation_spinner.setEnabled(False)
+ layout.addRow("Singular value truncation", self.truncation_spinner)
- localization_checkbox = self.widget_from_layout(layout, "LOCALIZATION")
- localization_correlation_spinner = self.widget_from_layout(
- layout, "LOCALIZATION_CORRELATION_THRESHOLD"
- )
- localization_correlation_spinner.setEnabled(localization_checkbox.isChecked())
- localization_checkbox.stateChanged.connect(
- lambda localization_is_on: localization_correlation_spinner.setEnabled(
- localization_is_on
+ bg.idClicked.connect(self.update_inversion_algorithm)
+ bg.buttons()[analysis_module.inversion].click() # update the current value
+
+ layout.addRow(self.create_horizontal_line())
+ layout.addRow(QLabel("[EXPERIMENTAL]"))
+
+ localization_frame = QFrame()
+ localization_frame.setLayout(QHBoxLayout())
+ localization_frame.layout().setContentsMargins(0, 0, 0, 0)
+
+ local_checkbox = QCheckBox("Adaptive localization correlation threshold")
+ local_checkbox.clicked.connect(
+ partial(
+ self.valueChanged,
+ "LOCALIZATION",
+ bool,
+ local_checkbox,
)
)
+ self.local_spinner = self.createDoubleSpinBox(
+ "LOCALIZATION_CORRELATION_THRESHOLD",
+ analysis_module.localization_correlation_threshold(ensemble_size),
+ analysis_module_variables_model,
+ )
+ self.local_spinner.setEnabled(local_checkbox.isChecked())
+
+ localization_frame.layout().addWidget(local_checkbox)
+ localization_frame.layout().addWidget(self.local_spinner)
+ layout.addRow(localization_frame)
+
+ local_checkbox.stateChanged.connect(
+ lambda localization_is_on: self.local_spinner.setEnabled(localization_is_on)
+ )
+ local_checkbox.setChecked(analysis_module.localization())
+
self.setLayout(layout)
self.blockSignals(False)
@@ -120,46 +129,35 @@ def update_inversion_algorithm(self, button_id):
self.truncation_spinner.setEnabled(button_id != 0) # not for exact inversion
self.analysis_module.inversion = button_id
- def widget_from_layout(self, layout: QFormLayout, widget_name: str) -> QWidget:
- for i in range(layout.count()):
- widget = layout.itemAt(i).widget()
- if widget.objectName() == widget_name:
- return widget
-
- return None
-
- def createCheckBox(self, variable_name, variable_value, variable_type):
- spinner = QCheckBox()
- spinner.setChecked(variable_value)
- spinner.setObjectName(variable_name)
- spinner.clicked.connect(
- partial(self.valueChanged, variable_name, variable_type, spinner)
- )
- return spinner
+ def create_horizontal_line(self) -> QFrame:
+ hline = QFrame()
+ hline.setFrameShape(QFrame.HLine)
+ hline.setFrameShadow(QFrame.Sunken)
+ hline.setFixedHeight(20)
+ return hline
def createDoubleSpinBox(
self,
variable_name,
variable_value,
- variable_type,
analysis_module_variables_model,
):
spinner = QDoubleSpinBox()
spinner.setDecimals(6)
- spinner.setMinimumWidth(75)
- spinner.setMaximum(
- analysis_module_variables_model.getVariableMaximumValue(variable_name)
- )
- spinner.setMinimum(
- analysis_module_variables_model.getVariableMinimumValue(variable_name)
+ spinner.setFixedWidth(100)
+ spinner.setObjectName(variable_name)
+
+ spinner.setRange(
+ analysis_module_variables_model.getVariableMinimumValue(variable_name),
+ analysis_module_variables_model.getVariableMaximumValue(variable_name),
)
+
spinner.setSingleStep(
analysis_module_variables_model.getVariableStepValue(variable_name)
)
spinner.setValue(variable_value)
- spinner.setObjectName(variable_name)
spinner.valueChanged.connect(
- partial(self.valueChanged, variable_name, variable_type, spinner)
+ partial(self.valueChanged, variable_name, float, spinner)
)
return spinner
@@ -171,12 +169,6 @@ def valueChanged(self, variable_name, variable_type, variable_control):
elif variable_type == float:
assert isinstance(variable_control, QDoubleSpinBox)
value = variable_control.value()
- elif variable_type == str:
- assert isinstance(variable_control, QLineEdit)
- value = variable_control.text()
- value = str(value).strip()
- if len(value) == 0:
- value = None
if value is not None:
self.analysis_module.set_var(variable_name, value)