0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 03:31:50 +02:00

feat: add move to position button to lmfit dialog

This commit is contained in:
2024-09-10 17:42:54 +02:00
parent 5c740371d8
commit 281cb27d8b
2 changed files with 185 additions and 25 deletions

View File

@ -3,7 +3,7 @@ import os
from bec_lib.endpoints import MessageEndpoints
from bec_lib.logger import bec_logger
from qtpy.QtCore import Property, Signal, Slot
from qtpy.QtWidgets import QTreeWidgetItem, QVBoxLayout, QWidget
from qtpy.QtWidgets import QPushButton, QTreeWidgetItem, QVBoxLayout, QWidget
from bec_widgets.utils import UILoader
from bec_widgets.utils.bec_widget import BECWidget
@ -15,7 +15,10 @@ class LMFitDialog(BECWidget, QWidget):
"""Dialog for displaying the fit summary and params for LMFit DAP processes"""
ICON_NAME = "monitoring"
# Signal to emit the currently selected fit curve_id
selected_fit = Signal(str)
# Signal to emit a position to move to.
move_to_position = Signal(float)
def __init__(
self,
@ -49,9 +52,66 @@ class LMFitDialog(BECWidget, QWidget):
self.summary_data = {}
self._fit_curve_id = None
self._deci_precision = 3
self._always_show_latest = False
self._activated_buttons_for_move_action = []
self.ui.curve_list.currentItemChanged.connect(self.display_fit_details)
self.layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.layout)
self._enable_move_to_buttons = False
self._move_buttons = []
@Property(bool)
def enable_move_to_buttons(self):
"""Property to enable the move to buttons."""
return self._enable_move_to_buttons
@enable_move_to_buttons.setter
def enable_move_to_buttons(self, enable: bool):
self._enable_move_to_buttons = enable
for button in self._move_buttons:
if button.text().split(" ")[-1] in self.activated_buttons_for_move_action:
button.setEnabled(enable)
@Slot(bool)
def set_enable_move_to_buttons(self, enable: bool):
"""Slot to enable the move to buttons.
Args:
enable (bool): Whether to enable the move to buttons.
"""
self.enable_move_to_buttons = enable
@Property(list)
def activated_buttons_for_move_action(self) -> list:
"""Property for the buttons that should be activated for the move action in the parameter list."""
return self._activated_buttons_for_move_action
@activated_buttons_for_move_action.setter
def activated_buttons_for_move_action(self, buttons: list):
"""Setter for the buttons that should be activated for the move action.
Args:
buttons (list): The buttons that should be activated for the move action.
"""
self._activated_buttons_for_move_action = buttons
@Slot(list)
def update_activated_button_list(self, names: list) -> None:
"""Update the list of activated buttons for the move action.
Args:
names (list): List of button names to be activated.
"""
self.activated_buttons_for_move_action = names
@Property(bool)
def always_show_latest(self):
"""Property to indicate if always the latest DAP update is displayed."""
return self._always_show_latest
@always_show_latest.setter
def always_show_latest(self, show: bool):
self._always_show_latest = show
@Property(bool)
def hide_curve_selection(self):
@ -67,6 +127,34 @@ class LMFitDialog(BECWidget, QWidget):
"""
self.ui.group_curve_selection.setVisible(not show)
@Property(bool)
def hide_summary(self):
"""Property for showing the summary."""
return not self.ui.group_summary.isVisible()
@hide_summary.setter
def hide_summary(self, show: bool):
"""Setter for showing the summary.
Args:
show (bool): Whether to show the summary.
"""
self.ui.group_summary.setVisible(not show)
@Property(bool)
def hide_parameters(self):
"""Property for showing the parameters."""
return not self.ui.group_parameters.isVisible()
@hide_parameters.setter
def hide_parameters(self, show: bool):
"""Setter for showing the parameters.
Args:
show (bool): Whether to show the parameters.
"""
self.ui.group_parameters.setVisible(not show)
@property
def fit_curve_id(self):
"""Property for the currently displayed fit curve_id."""
@ -112,19 +200,34 @@ class LMFitDialog(BECWidget, QWidget):
curve_id = metadata.get("curve_id", "")
self.summary_data.update({curve_id: data})
self.refresh_curve_list()
if self.fit_curve_id is None:
if self.fit_curve_id is None or self.always_show_latest is True:
self.fit_curve_id = curve_id
if curve_id != self.fit_curve_id:
return
if data is None:
return
self.ui.summary_tree.clear()
chi_squared = data.get("chisqr", 0.0)
if isinstance(chi_squared, float) or isinstance(chi_squared, int):
chi_squared = f"{chi_squared:.{self._deci_precision}f}"
else:
chi_squared = "None"
reduced_chi_squared = data.get("redchi", 0.0)
if isinstance(reduced_chi_squared, float) or isinstance(reduced_chi_squared, int):
reduced_chi_squared = f"{reduced_chi_squared:.{self._deci_precision}f}"
else:
reduced_chi_squared = "None"
r_squared = data.get("rsquared", 0.0)
if isinstance(r_squared, float) or isinstance(r_squared, int):
r_squared = f"{r_squared:.{self._deci_precision}f}"
else:
r_squared = "None"
properties = [
("Model", data.get("model", "")),
("Method", data.get("method", "")),
("Chi-Squared", f"{data.get('chisqr', 0.0):.{self._deci_precision}f}"),
("Reduced Chi-Squared", f"{data.get('redchi', 0.0):.{self._deci_precision}f}"),
("R-Squared", f"{data.get('rsquared', 0.0):.{self._deci_precision}f}"),
("Chi-Squared", chi_squared),
("Reduced Chi-Squared", reduced_chi_squared),
("R-Squared", r_squared),
("Message", data.get("message", "")),
]
for prop, val in properties:
@ -149,14 +252,38 @@ class LMFitDialog(BECWidget, QWidget):
Args:
params (list): List of LMFit parameters for the fit curve.
"""
self._move_buttons = []
self.ui.param_tree.clear()
for param in params:
param_name, param_value, param_std = (
param[0],
f"{param[1]:.{self._deci_precision}f}",
f"{param[7]:.{self._deci_precision}f}",
)
QTreeWidgetItem(self.ui.param_tree, [param_name, param_value, param_std])
param_name = param[0]
param_value = param[1]
if isinstance(param_value, float) or isinstance(param_value, int):
param_value = f"{param_value:.{self._deci_precision}f}"
else:
param_value = "None"
param_std = param[7]
if isinstance(param_std, float) or isinstance(param_std, int):
param_std = f"{param_std:.{self._deci_precision}f}"
else:
param_std = "None"
# Create a push button to move the motor to a specific position
# Per default, this feature is deactivated
widget = QWidget()
layout = QVBoxLayout(widget)
push_button = QPushButton(f"Move to {param_name}")
if param_name in self.activated_buttons_for_move_action:
push_button.setEnabled(True)
push_button.clicked.connect(
lambda _, value=param[1]: self.move_to_position.emit(float(value))
)
else:
push_button.setEnabled(False)
self._move_buttons.append(push_button)
layout.addWidget(push_button)
layout.setContentsMargins(0, 0, 0, 0)
tree_item = QTreeWidgetItem(self.ui.param_tree, [param_name, param_value, param_std])
self.ui.param_tree.setItemWidget(tree_item, 3, widget)
def populate_curve_list(self):
"""Populate the curve list with the available fit curves."""

View File

@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>274</width>
<height>568</height>
<width>303</width>
<height>457</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -19,15 +19,40 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,0">
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="1,2,2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="group_curve_selection">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Select Curve</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="3">
<item>
<widget class="QListWidget" name="curve_list"/>
<widget class="QListWidget" name="curve_list">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
@ -35,15 +60,15 @@
<item>
<widget class="QGroupBox" name="group_summary">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>200</height>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
@ -53,7 +78,7 @@
<item>
<widget class="QTreeWidget" name="summary_tree">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -88,15 +113,15 @@
<item>
<widget class="QGroupBox" name="group_parameters">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>200</height>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
@ -106,7 +131,7 @@
<item>
<widget class="QTreeWidget" name="param_tree">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -117,8 +142,11 @@
<height>0</height>
</size>
</property>
<property name="columnCount">
<number>4</number>
</property>
<attribute name="headerDefaultSectionSize">
<number>80</number>
<number>70</number>
</attribute>
<column>
<property name="text">
@ -135,6 +163,11 @@
<string>Std</string>
</property>
</column>
<column>
<property name="text">
<string>Action</string>
</property>
</column>
</widget>
</item>
</layout>