Skip to content

Commit

Permalink
Refactor and align AnalysisModulePanel
Browse files Browse the repository at this point in the history
Use stylesheets instead of inline formatting
Refactored ui layout to align better
Refactor handling of elements
Add label with analysis mode in ui
Add hline divider
  • Loading branch information
andreas-el authored Nov 16, 2023
1 parent 26d478c commit f97bd63
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 112 deletions.
3 changes: 3 additions & 0 deletions src/ert/config/analysis_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -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})"

Expand Down
216 changes: 104 additions & 112 deletions src/ert/gui/ertwidgets/analysismodulevariablespanel.py
Original file line number Diff line number Diff line change
@@ -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,
)
Expand All @@ -24,142 +26,138 @@ 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 [
"<span style="
'"font-size:10pt; font-weight:300;font-style:italic;">'
"A good start is max steplength of 0.6, min steplength of 0.3, and decline of 2.5</span>",
"<span style="
'"font-size:10pt; font-weight:300;font-style:italic;">'
"A steplength of 1.0 and one iteration results in ES update</span>",
]:
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)

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

Expand All @@ -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)

0 comments on commit f97bd63

Please sign in to comment.