Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d820d5adb5 | |||
| dc6966ee31 | |||
| 6bce6f8907 |
@@ -183,7 +183,7 @@ def calc_positions(cfg: ConfigDict) -> dict[str, dict[str, float]]:
|
||||
if cfg["fm_stripe"] in ("Rh (toroid)", "Pt (toroid)"):
|
||||
|
||||
# TRY
|
||||
if cfg["fm_stripe"] in "Rh (toroid)":
|
||||
if cfg["fm_stripe"] == "Rh (toroid)":
|
||||
r = bl.fm.r[0]
|
||||
h_cyl = bl.fm.hToroid[0]
|
||||
else: # PT toroid
|
||||
@@ -199,7 +199,7 @@ def calc_positions(cfg: ConfigDict) -> dict[str, dict[str, float]]:
|
||||
pos["fm_try"] = {"value": fm_height}
|
||||
|
||||
# TRX
|
||||
if cfg["fm_stripe"] in "Rh (toroid)":
|
||||
if cfg["fm_stripe"] == "Rh (toroid)":
|
||||
x_cyl = -bl.fm.xToroid[0]
|
||||
else:
|
||||
x_cyl = -bl.fm.xToroid[1]
|
||||
@@ -213,7 +213,7 @@ def calc_positions(cfg: ConfigDict) -> dict[str, dict[str, float]]:
|
||||
pos["fm_try"] = {"value": fm_height}
|
||||
|
||||
# TRX
|
||||
if cfg["fm_stripe"] in "Rh (flat)":
|
||||
if cfg["fm_stripe"] == "Rh (flat)":
|
||||
x_flat = -bl.fm.xFlat[0]
|
||||
else:
|
||||
x_flat = -bl.fm.xFlat[1]
|
||||
|
||||
@@ -27,7 +27,7 @@ def calc_sideview(cfg: ConfigDict) -> DataDict:
|
||||
beam["y"].append(bl.sourceHeight)
|
||||
beam["x"].append(bl.cm.center[1]) # CM
|
||||
beam["y"].append(bl.sourceHeight)
|
||||
if cfg["mo1_mode"] in "Monochromatic":
|
||||
if cfg["mo1_mode"] == "Monochromatic":
|
||||
diag = bl.mo1.xtalGap[0] / np.sin(cfg["mo1_bragg"]) # Calculations for Mono
|
||||
dy = diag * np.sin(2 * (cfg["cm_pitch"] + cfg["mo1_bragg"]))
|
||||
dz = diag * np.cos(2 * (cfg["cm_pitch"] + cfg["mo1_bragg"]))
|
||||
|
||||
@@ -65,7 +65,7 @@ def calc_surfaces(cfg: ConfigDict) -> SurfaceDict:
|
||||
height_beam = 2 * bl.cm.center[1] * np.tan(cfg["v_acc"])
|
||||
w = height_beam / np.sin(cfg["mo1_bragg"])
|
||||
|
||||
if cfg["mo1_mode"] in "Monochromatic":
|
||||
if cfg["mo1_mode"] == "Monochromatic":
|
||||
out["mo1_1"]["x"] = [
|
||||
xtal_pos - width_beam / 2,
|
||||
xtal_pos + width_beam / 2,
|
||||
|
||||
@@ -258,7 +258,7 @@ def fm_ideal_pitch(
|
||||
"""
|
||||
p = bl.fm.center[1] # posFM
|
||||
q = smpl - bl.fm.center[1] # dist posFM to posEX
|
||||
if fm_focus in "Defocused":
|
||||
if fm_focus == "Defocused":
|
||||
assert sldi_hacc is not None, "sldi_hacc must be provided for Defocused mode"
|
||||
assert sldi_vacc is not None, "sldi_vacc must be provided for Defocused mode"
|
||||
assert fm_focx is not None, "fm_focx must be provided for Defocused mode"
|
||||
@@ -294,9 +294,9 @@ def cm_critical_angle(cm_stripe: Literal["Si", "Pt", "Rh"], energy) -> float:
|
||||
Returns:
|
||||
float: Critical angle in rad
|
||||
"""
|
||||
if cm_stripe in "Si":
|
||||
if cm_stripe == "Si":
|
||||
stripe = bl.stripeSi
|
||||
elif cm_stripe in "Pt":
|
||||
elif cm_stripe == "Pt":
|
||||
stripe = bl.stripePt
|
||||
else:
|
||||
stripe = bl.stripeRh
|
||||
@@ -320,15 +320,15 @@ def mirror_surface_geometries(
|
||||
dict[str, tuple[float, float, float, float]]: Dictionary mapping surface
|
||||
names to tuples of (x, y, width, height).
|
||||
"""
|
||||
if mirror in "cm":
|
||||
if mirror == "cm":
|
||||
surface = bl.cm.surface
|
||||
lim_opt_x = bl.cm.limOptX
|
||||
lim_opt_y = bl.cm.limOptY
|
||||
elif mirror in "fm_toroid":
|
||||
elif mirror == "fm_toroid":
|
||||
surface = bl.fm.surfaceToroid
|
||||
lim_opt_x = bl.fm.limOptXToroid
|
||||
lim_opt_y = bl.fm.limOptYToroid
|
||||
elif mirror in "fm_flat":
|
||||
elif mirror == "fm_flat":
|
||||
surface = bl.fm.surfaceFlat
|
||||
lim_opt_x = bl.fm.limOptXFlat
|
||||
lim_opt_y = bl.fm.limOptYFlat
|
||||
@@ -354,7 +354,7 @@ def mo_surface_geometries(
|
||||
dict[str, tuple[float, float, float, float]]: Dictionary mapping surface
|
||||
names to tuples of (x, y, width, height).
|
||||
"""
|
||||
if mo in "mo1":
|
||||
if mo == "mo1":
|
||||
xtal = bl.mo1.xtal
|
||||
xtal_width = bl.mo1.xtalWidth
|
||||
xtal_offset_x = bl.mo1.xtalOffsetX
|
||||
|
||||
@@ -22,10 +22,13 @@ from qtpy.QtWidgets import (
|
||||
QApplication,
|
||||
QDialog,
|
||||
QDialogButtonBox,
|
||||
QFrame,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QPlainTextEdit,
|
||||
QPushButton,
|
||||
QScrollArea,
|
||||
QSizePolicy,
|
||||
QStyle,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
@@ -55,7 +58,7 @@ from debye_bec.bec_widgets.widgets.digital_twin.types import ConfigDict
|
||||
|
||||
logger = bec_logger.logger
|
||||
|
||||
OFFSET_FILE = "debye_bec/debye_bec/bec_widgets/widgets/digital_twin/x01da_offsets.yaml"
|
||||
OFFSET_FILE = Path(__file__).with_name("x01da_offsets.yaml")
|
||||
|
||||
|
||||
class DigitalTwin(BECWidget, QWidget):
|
||||
@@ -74,32 +77,47 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
self.check_config()
|
||||
self.bec_dispatcher.connect_slot(self.check_config, MessageEndpoints.device_config_update())
|
||||
|
||||
central = QWidget()
|
||||
self.root_layout = QHBoxLayout(central)
|
||||
self.content_widget = QWidget(self)
|
||||
self.root_layout = QHBoxLayout(self.content_widget)
|
||||
self.root_layout.setContentsMargins(6, 6, 6, 6)
|
||||
self.root_layout.setSpacing(6)
|
||||
|
||||
self.input_widget = QWidget()
|
||||
self.input_layout = QVBoxLayout(self.input_widget)
|
||||
self.input_layout.setContentsMargins(4, 4, 4, 4)
|
||||
self.input_layout.setSpacing(6)
|
||||
self.input = InputPanel()
|
||||
self.settings = SettingsPanel()
|
||||
self.input_layout.addWidget(self.input)
|
||||
self.input_layout.addWidget(self.settings)
|
||||
self.input_layout.addStretch()
|
||||
|
||||
self.plot_widget = QWidget()
|
||||
self.plot_layout = QVBoxLayout(self.plot_widget)
|
||||
self.plot_layout.setContentsMargins(4, 4, 4, 4)
|
||||
self.plot_layout.setSpacing(6)
|
||||
self.sideview_plot = SideviewPlot()
|
||||
self.surface_plots = SurfacePlots()
|
||||
self.plot_layout.addWidget(self.sideview_plot)
|
||||
self.plot_layout.addWidget(self.surface_plots)
|
||||
self.plot_layout.addWidget(self.sideview_plot, stretch=1)
|
||||
self.plot_layout.addWidget(self.surface_plots, stretch=1)
|
||||
self.plot_widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
|
||||
self.mover = MoverPanel(self.dev)
|
||||
|
||||
self.root_layout.addWidget(self.input_widget, alignment=Qt.AlignmentFlag.AlignTop)
|
||||
self.root_layout.addWidget(self.plot_widget, alignment=Qt.AlignmentFlag.AlignTop)
|
||||
self.root_layout.addWidget(self.mover, alignment=Qt.AlignmentFlag.AlignTop)
|
||||
self.input_scroll = self._scroll_area(self.input_widget, min_width=320, max_width=360)
|
||||
self.mover_scroll = self._scroll_area(self.mover, min_width=380, max_width=460)
|
||||
|
||||
self.setLayout(self.root_layout)
|
||||
self.root_layout.addWidget(self.input_scroll)
|
||||
self.root_layout.addWidget(self.plot_widget, stretch=1)
|
||||
self.root_layout.addWidget(self.mover_scroll)
|
||||
widget_layout = self.layout()
|
||||
if widget_layout is None:
|
||||
widget_layout = QVBoxLayout(self)
|
||||
widget_layout.setContentsMargins(0, 0, 0, 0)
|
||||
widget_layout.setSpacing(0)
|
||||
widget_layout.addWidget(self.content_widget)
|
||||
self.setWindowTitle("Digital Twin")
|
||||
self.resize(1800, 800)
|
||||
self.resize(1450, 760)
|
||||
|
||||
self.input.energy.value_changed_connect(self.calc_assistant)
|
||||
self.input.sldi_hacc.value_changed_connect(self.calc_assistant)
|
||||
@@ -127,12 +145,26 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
self.load_offsets(recalculate=False)
|
||||
self.calc_assistant(identifier="init")
|
||||
|
||||
# Timer: update plots every 1 second
|
||||
# Timer: update reality plots every 1 second
|
||||
self._timer = QTimer(self)
|
||||
self._timer.setInterval(100)
|
||||
self._timer.setInterval(1000)
|
||||
self._timer.timeout.connect(self.calc_reality)
|
||||
self._timer.start()
|
||||
|
||||
@staticmethod
|
||||
def _scroll_area(widget: QWidget, min_width: int, max_width: int) -> QScrollArea:
|
||||
"""Wrap a side panel in a compact vertical scroll area."""
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.MinimumExpanding)
|
||||
scroll.setWidget(widget)
|
||||
scroll.setFrameShape(QFrame.Shape.NoFrame)
|
||||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
scroll.setMinimumWidth(min_width)
|
||||
scroll.setMaximumWidth(max_width)
|
||||
scroll.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Expanding)
|
||||
return scroll
|
||||
|
||||
def apply_theme(self, theme: Literal["dark", "light"]):
|
||||
"""
|
||||
Apply the theme
|
||||
@@ -152,8 +184,8 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
BEC dispatcher whenever there is a config update, stop the timer
|
||||
that updates the plot in the background.
|
||||
"""
|
||||
reload = (args[0] if args else {}).get("action") == "reload"
|
||||
if reload:
|
||||
reload_config = (args[0] if args else {}).get("action") == "reload"
|
||||
if reload_config:
|
||||
self._timer.stop()
|
||||
devices = [
|
||||
"abs",
|
||||
@@ -234,7 +266,7 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
running_app = QApplication.instance()
|
||||
if running_app is not None:
|
||||
running_app.exit(0)
|
||||
if reload:
|
||||
if reload_config:
|
||||
self._timer.start()
|
||||
|
||||
@SafeSlot()
|
||||
@@ -309,10 +341,10 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
ConfigDict: config of the assistant
|
||||
"""
|
||||
fm_focus = self.input.fm_focus.currentText()
|
||||
if fm_focus in "Manual":
|
||||
if fm_focus == "Manual":
|
||||
fm_rotx = self.input.fm_rotx.value()
|
||||
fm_qy = None
|
||||
elif fm_focus in "Focused":
|
||||
elif fm_focus == "Focused":
|
||||
fm_rotx = self.input.fm_rotx_ideal.value()
|
||||
fm_qy = None
|
||||
else: # Focused
|
||||
@@ -523,11 +555,10 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
|
||||
if self.offsets == {}:
|
||||
# Load offsets
|
||||
file = Path(OFFSET_FILE)
|
||||
if not file.exists():
|
||||
if not OFFSET_FILE.exists():
|
||||
raise FileNotFoundError(f"Offset file not found: {OFFSET_FILE}")
|
||||
|
||||
with file.open("r", encoding="utf-8") as f:
|
||||
with OFFSET_FILE.open("r", encoding="utf-8") as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
if not isinstance(data, dict):
|
||||
@@ -568,7 +599,7 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
intro_label.setWordWrap(True)
|
||||
layout.addWidget(intro_label)
|
||||
|
||||
file = QLabel(OFFSET_FILE)
|
||||
file = QLabel(str(OFFSET_FILE))
|
||||
file.setWordWrap(True)
|
||||
font = QFont()
|
||||
font.setItalic(True)
|
||||
@@ -600,13 +631,13 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
selection of the focus strategy.
|
||||
"""
|
||||
fm_focus = self.input.fm_focus.currentText()
|
||||
if fm_focus in "Manual":
|
||||
if fm_focus == "Manual":
|
||||
self.input.fm_rotx.setVisible(True)
|
||||
self.input.fm_rotx_ideal.setVisible(True)
|
||||
self.input.fm_focx.setVisible(False)
|
||||
self.input.fm_focy.setVisible(False)
|
||||
self.input.fm_rotx_ideal.setLabel("Incidence Angle for focused beam")
|
||||
elif fm_focus in "Focused":
|
||||
elif fm_focus == "Focused":
|
||||
self.input.fm_rotx.setVisible(False)
|
||||
self.input.fm_rotx_ideal.setVisible(True)
|
||||
self.input.fm_focx.setVisible(False)
|
||||
@@ -659,7 +690,7 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
"""
|
||||
fm_stripe = self.input.fm_stripe.currentText()
|
||||
fm_focus = self.input.fm_focus.currentText()
|
||||
if fm_focus in "Manual":
|
||||
if fm_focus == "Manual":
|
||||
fm_rotx = -self.input.fm_rotx.value() * 1e-3
|
||||
else:
|
||||
fm_rotx = -self.input.fm_rotx_ideal.value() * 1e-3
|
||||
@@ -745,11 +776,11 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
Calculates bragg angle in rad
|
||||
"""
|
||||
xtal = self.input.mo1_xtal.currentText()
|
||||
if xtal in "Si(111)":
|
||||
if xtal == "Si(111)":
|
||||
d_spacing = self.dev.mo1_bragg.crystal.d_spacing_si111.read(cached=True)[
|
||||
"mo1_bragg_crystal_d_spacing_si111"
|
||||
]["value"]
|
||||
elif xtal in "Si(311)":
|
||||
elif xtal == "Si(311)":
|
||||
d_spacing = self.dev.mo1_bragg.crystal.d_spacing_si311.read(cached=True)[
|
||||
"mo1_bragg_crystal_d_spacing_si311"
|
||||
]["value"]
|
||||
@@ -767,7 +798,7 @@ class DigitalTwin(BECWidget, QWidget):
|
||||
Updates the monochromator input group based on the
|
||||
selection of the mode.
|
||||
"""
|
||||
if self.input.mo1_mode.currentText() in "Monochromatic":
|
||||
if self.input.mo1_mode.currentText() == "Monochromatic":
|
||||
self.input.mo1_xtal.setVisible(True)
|
||||
self.input.mo1_bragg_angle.setVisible(True)
|
||||
self.input.mo1_eres.setVisible(True)
|
||||
|
||||
@@ -3,7 +3,7 @@ Panel for user inputs of the digital twin widget
|
||||
"""
|
||||
|
||||
# pylint: disable=E0611
|
||||
from qtpy.QtWidgets import QLayout, QVBoxLayout, QWidget
|
||||
from qtpy.QtWidgets import QVBoxLayout, QWidget
|
||||
|
||||
from debye_bec.bec_widgets.widgets.digital_twin.widgets.qt_widgets import (
|
||||
Button,
|
||||
@@ -20,7 +20,8 @@ class InputPanel(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._layout = QVBoxLayout(self)
|
||||
self._layout.setSizeConstraint(QLayout.SetFixedSize) # type: ignore
|
||||
self._layout.setContentsMargins(4, 4, 4, 4)
|
||||
self._layout.setSpacing(4)
|
||||
|
||||
# Adapt to reality
|
||||
self.adapt_reality = Button(label_button="Adapt to reality", enabled=True)
|
||||
|
||||
@@ -5,7 +5,7 @@ Panel to move an axis to a certain position
|
||||
from typing import Literal
|
||||
|
||||
# pylint: disable=E0611
|
||||
from qtpy.QtWidgets import QLayout, QVBoxLayout, QWidget
|
||||
from qtpy.QtWidgets import QVBoxLayout, QWidget
|
||||
|
||||
from debye_bec.bec_widgets.widgets.digital_twin.widgets.move_widget import (
|
||||
AbsorberWidget,
|
||||
@@ -20,7 +20,8 @@ class MoverPanel(QWidget):
|
||||
def __init__(self, dev, parent=None):
|
||||
super().__init__(parent)
|
||||
self._layout = QVBoxLayout(self)
|
||||
self._layout.setSizeConstraint(QLayout.SetFixedSize) # type: ignore
|
||||
self._layout.setContentsMargins(4, 4, 4, 4)
|
||||
self._layout.setSpacing(4)
|
||||
|
||||
self.mover_widgets = []
|
||||
|
||||
@@ -189,7 +190,7 @@ class MoverPanel(QWidget):
|
||||
)
|
||||
self.mover_widgets.append(self.es0wi_try)
|
||||
|
||||
self.es0_mov_group = Group("Expperimental Station 0", [self.es0wi_try])
|
||||
self.es0_mov_group = Group("Experimental Station 0", [self.es0wi_try])
|
||||
|
||||
# Experimental Station 1
|
||||
self.ot_es1_trz = MoveWidget(
|
||||
@@ -197,7 +198,7 @@ class MoverPanel(QWidget):
|
||||
)
|
||||
self.mover_widgets.append(self.ot_es1_trz)
|
||||
|
||||
self.es1_mov_group = Group("Expperimental Station 1", [self.ot_es1_trz])
|
||||
self.es1_mov_group = Group("Experimental Station 1", [self.ot_es1_trz])
|
||||
|
||||
# Assemble complete mover group
|
||||
self.mover_group = Group(
|
||||
|
||||
@@ -33,6 +33,8 @@ class SurfacePlots(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self._layout = QHBoxLayout(self)
|
||||
self._layout.setContentsMargins(4, 4, 4, 4)
|
||||
self._layout.setSpacing(6)
|
||||
|
||||
self.surfaces: dict[str, SurfaceDict] = {
|
||||
"assistant": {
|
||||
@@ -74,7 +76,7 @@ class SurfacePlots(QWidget):
|
||||
# Create surfaces
|
||||
for idx, scene in enumerate(self.surfaces):
|
||||
for name, _ in self.surfaces[scene].items():
|
||||
if scene in "assistant":
|
||||
if scene == "assistant":
|
||||
brush = QBrush(QColor(*self.colors[idx], 255), Qt.BrushStyle.DiagCrossPattern)
|
||||
pen = pg.mkPen(
|
||||
QColor(*self.colors[idx], 255), width=1, style=Qt.PenStyle.DashLine
|
||||
@@ -130,7 +132,7 @@ class SurfacePlots(QWidget):
|
||||
|
||||
for idx, scene in enumerate(self.surfaces):
|
||||
for name, _ in self.surfaces[scene].items():
|
||||
if scene in "assistant":
|
||||
if scene == "assistant":
|
||||
brush = QBrush(QColor(*self.colors[idx], 255), Qt.BrushStyle.DiagCrossPattern)
|
||||
pen = pg.mkPen(
|
||||
QColor(*self.colors[idx], 255), width=1, style=Qt.PenStyle.DashLine
|
||||
@@ -165,13 +167,13 @@ class SurfacePlots(QWidget):
|
||||
self.texts.append(text)
|
||||
|
||||
for name, plot in self.plots.items():
|
||||
if name in "cm":
|
||||
if name == "cm":
|
||||
plot_surface(plot["widget"], mirror_surface_geometries("cm"))
|
||||
elif name in "mo1_1":
|
||||
elif name == "mo1_1":
|
||||
plot_surface(plot["widget"], mo_surface_geometries("mo1", 0))
|
||||
elif name in "mo1_2":
|
||||
elif name == "mo1_2":
|
||||
plot_surface(plot["widget"], mo_surface_geometries("mo1", 1))
|
||||
elif name in "fm":
|
||||
elif name == "fm":
|
||||
plot_surface(plot["widget"], mirror_surface_geometries("fm_flat"))
|
||||
plot_surface(plot["widget"], mirror_surface_geometries("fm_toroid"))
|
||||
else:
|
||||
@@ -202,7 +204,8 @@ class SideviewPlot(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self._layout = QVBoxLayout(self)
|
||||
# self._layout.setSizeConstraint(QLayout.SetFixedSize) # type: ignore
|
||||
self._layout.setContentsMargins(4, 4, 4, 4)
|
||||
self._layout.setSpacing(0)
|
||||
|
||||
self.plot_widget = pg.PlotWidget()
|
||||
self.plot_widget.getAxis("bottom").enableAutoSIPrefix(False)
|
||||
@@ -223,7 +226,7 @@ class SideviewPlot(QWidget):
|
||||
self.walls = []
|
||||
|
||||
for idx, scene in enumerate(self.data.keys()):
|
||||
if scene in "assistant":
|
||||
if scene == "assistant":
|
||||
pen = pg.mkPen(color=self.colors[idx], width=2, style=Qt.PenStyle.DotLine)
|
||||
z_value = 2
|
||||
else:
|
||||
@@ -243,7 +246,6 @@ class SideviewPlot(QWidget):
|
||||
self.plot_widget.hideButtons()
|
||||
|
||||
self._layout.addWidget(self.plot_group)
|
||||
self._layout.addStretch()
|
||||
|
||||
self.plot_vacuum_pipes()
|
||||
self.plot_walls()
|
||||
@@ -281,7 +283,7 @@ class SideviewPlot(QWidget):
|
||||
self.text_color = (0, 0, 0)
|
||||
|
||||
for idx, scene in enumerate(self.data):
|
||||
if scene in "assistant":
|
||||
if scene == "assistant":
|
||||
brush = QBrush(QColor(*self.colors[idx], 255), Qt.BrushStyle.DiagCrossPattern)
|
||||
pen = pg.mkPen(QColor(*self.colors[idx], 255), width=3, style=Qt.PenStyle.DashLine)
|
||||
else:
|
||||
|
||||
@@ -3,7 +3,7 @@ Settings panel for the digital twin widget
|
||||
"""
|
||||
|
||||
# pylint: disable=E0611
|
||||
from qtpy.QtWidgets import QLayout, QVBoxLayout, QWidget
|
||||
from qtpy.QtWidgets import QVBoxLayout, QWidget
|
||||
|
||||
from debye_bec.bec_widgets.widgets.digital_twin.widgets.qt_widgets import (
|
||||
Button,
|
||||
@@ -18,7 +18,8 @@ class SettingsPanel(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._layout = QVBoxLayout(self)
|
||||
self._layout.setSizeConstraint(QLayout.SetFixedSize) # type: ignore
|
||||
self._layout.setContentsMargins(4, 4, 4, 4)
|
||||
self._layout.setSpacing(4)
|
||||
|
||||
# Reload offsets
|
||||
self.load_offsets = Button(label="Load Offsets", label_button="Load", enabled=True)
|
||||
|
||||
@@ -128,8 +128,8 @@ class MotionWorker(QObject):
|
||||
"""
|
||||
|
||||
position_changed = Signal(float)
|
||||
error = Signal(bool) # True = error
|
||||
finished = Signal(bool) # True = reached target, False = stopped
|
||||
error = Signal()
|
||||
finished = Signal()
|
||||
|
||||
def __init__(self, dev, motor, target_pos: float):
|
||||
super().__init__()
|
||||
@@ -284,7 +284,7 @@ class MotionWorker(QObject):
|
||||
fb = surv_ax["device"].read(cached=True)[surv_ax["name"]]["value"]
|
||||
if abs(fb - surv_ax["old_value"]) > surv_ax["abs_tol"]:
|
||||
self.dev[self.motor].stop()
|
||||
self.error.emit(1)
|
||||
self.error.emit()
|
||||
break
|
||||
self.finished.emit()
|
||||
|
||||
@@ -315,35 +315,33 @@ class MoveWidget(QWidget):
|
||||
self.decimals = decimals
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(4, 0, 4, 0)
|
||||
layout.setSpacing(4)
|
||||
|
||||
# Name
|
||||
self.label = QLabel(label)
|
||||
self.label.setFixedWidth(100)
|
||||
self.label.setContentsMargins(0, 0, 10, 0)
|
||||
self.label.setFixedWidth(76)
|
||||
self.label.setWordWrap(True)
|
||||
layout.addWidget(self.label)
|
||||
|
||||
# Target
|
||||
self.target_label = QLabel("-")
|
||||
self.target_label.setFixedWidth(100)
|
||||
self.target_label.setFixedWidth(84)
|
||||
layout.addWidget(self.target_label)
|
||||
|
||||
# Feedback
|
||||
self.fb_label = QLabel("-")
|
||||
self.fb_label.setFixedWidth(100)
|
||||
self.fb_label.setFixedWidth(84)
|
||||
layout.addWidget(self.fb_label)
|
||||
|
||||
# Status icon
|
||||
self.status_icon = StatusIcon()
|
||||
self.status_icon.setFixedWidth(30)
|
||||
self.status_icon.setContentsMargins(0, 0, 10, 0)
|
||||
self.status_icon.setFixedWidth(24)
|
||||
layout.addWidget(self.status_icon)
|
||||
|
||||
# Start / Stop button
|
||||
self.btn_action = QPushButton("Move")
|
||||
self.btn_action.setFixedWidth(90)
|
||||
self.btn_action.setFixedWidth(64)
|
||||
self.btn_action.setFixedHeight(20)
|
||||
self.btn_action.clicked.connect(self._on_button_clicked)
|
||||
layout.addWidget(self.btn_action)
|
||||
@@ -485,7 +483,7 @@ class MoveWidget(QWidget):
|
||||
def _on_motion_finished(self):
|
||||
"""Finished a movement"""
|
||||
target = self.target
|
||||
if self.status not in Status.ERROR:
|
||||
if self.status != Status.ERROR:
|
||||
if abs(self.fb - target) <= self.deadband:
|
||||
self._set_status(Status.IN_POSITION)
|
||||
else:
|
||||
@@ -522,35 +520,33 @@ class AbsorberWidget(QWidget):
|
||||
self.text_color = (0, 0, 0)
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(4, 0, 4, 0)
|
||||
layout.setSpacing(4)
|
||||
|
||||
# Name
|
||||
self.label = QLabel(label)
|
||||
self.label.setFixedWidth(100)
|
||||
self.label.setContentsMargins(0, 0, 10, 0)
|
||||
self.label.setFixedWidth(76)
|
||||
self.label.setWordWrap(True)
|
||||
layout.addWidget(self.label)
|
||||
|
||||
# Blank
|
||||
self.blank_label = QLabel("")
|
||||
self.blank_label.setFixedWidth(100)
|
||||
self.blank_label.setFixedWidth(84)
|
||||
layout.addWidget(self.blank_label)
|
||||
|
||||
# Feedback
|
||||
self.fb_label = QLabel("-")
|
||||
self.fb_label.setFixedWidth(100)
|
||||
self.fb_label.setFixedWidth(84)
|
||||
layout.addWidget(self.fb_label)
|
||||
|
||||
# Blank icon
|
||||
self.blank_icon = QLabel("")
|
||||
self.blank_icon.setFixedWidth(30)
|
||||
self.blank_icon.setContentsMargins(0, 0, 10, 0)
|
||||
self.blank_icon.setFixedWidth(24)
|
||||
layout.addWidget(self.blank_icon)
|
||||
|
||||
# Open
|
||||
self.btn_action = QPushButton("Open")
|
||||
self.btn_action.setFixedWidth(90)
|
||||
self.btn_action.setFixedWidth(64)
|
||||
self.btn_action.setFixedHeight(20)
|
||||
self.btn_action.clicked.connect(self._on_button_clicked)
|
||||
layout.addWidget(self.btn_action)
|
||||
|
||||
@@ -21,11 +21,17 @@ from qtpy.QtWidgets import (
|
||||
QWidget,
|
||||
)
|
||||
|
||||
LABEL_WIDTH = 118
|
||||
ROW_MARGINS = (4, 0, 4, 0)
|
||||
ROW_SPACING = 6
|
||||
|
||||
|
||||
class Group(QGroupBox):
|
||||
def __init__(self, label, widgets):
|
||||
super().__init__(label)
|
||||
self.layout = QVBoxLayout(self) # type: ignore
|
||||
self.layout.setContentsMargins(6, 6, 6, 6)
|
||||
self.layout.setSpacing(4)
|
||||
for widget in widgets:
|
||||
self.layout.addWidget(widget) # type: ignore
|
||||
|
||||
@@ -34,16 +40,14 @@ class NumberIndicator(QWidget):
|
||||
def __init__(self, label="", unit=None, highlight=False, decimals=3):
|
||||
super().__init__()
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(*ROW_MARGINS)
|
||||
layout.setSpacing(ROW_SPACING)
|
||||
self.label = QLabel(label)
|
||||
self.label.setFixedWidth(140)
|
||||
self.label.setContentsMargins(0, 0, 10, 0)
|
||||
self.label.setFixedWidth(LABEL_WIDTH)
|
||||
self.label.setWordWrap(True)
|
||||
layout.addWidget(self.label)
|
||||
self.val = QLabel("-")
|
||||
self.val.setAlignment(Qt.AlignTop) # type: ignore
|
||||
# self.val.setFixedWidth(140)
|
||||
layout.addWidget(self.val)
|
||||
self.unit = unit
|
||||
self.highlight = highlight
|
||||
@@ -85,12 +89,11 @@ class InputNumberField(QWidget):
|
||||
):
|
||||
super().__init__()
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(*ROW_MARGINS)
|
||||
layout.setSpacing(ROW_SPACING)
|
||||
self.identifier = identifier
|
||||
self.label = QLabel(label)
|
||||
self.label.setFixedWidth(140)
|
||||
self.label.setContentsMargins(0, 0, 10, 0)
|
||||
self.label.setFixedWidth(LABEL_WIDTH)
|
||||
self.label.setWordWrap(True)
|
||||
layout.addWidget(self.label)
|
||||
self.val = QDoubleSpinBox()
|
||||
@@ -102,7 +105,6 @@ class InputNumberField(QWidget):
|
||||
self.val.setSuffix(" " + unit)
|
||||
if prefix is not None:
|
||||
self.val.setPrefix(prefix + " ")
|
||||
# self.val.setFixedWidth(140)
|
||||
layout.addWidget(self.val)
|
||||
|
||||
def set_number(self, number):
|
||||
@@ -124,19 +126,18 @@ class InputNumberField(QWidget):
|
||||
|
||||
|
||||
class ComboBox(QWidget):
|
||||
def __init__(self, identifier="", label="", enums=[]):
|
||||
def __init__(self, identifier="", label="", enums=None):
|
||||
super().__init__()
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(*ROW_MARGINS)
|
||||
layout.setSpacing(ROW_SPACING)
|
||||
self.identifier = identifier
|
||||
self.label = QLabel(label)
|
||||
self.label.setFixedWidth(140)
|
||||
self.label.setContentsMargins(0, 0, 10, 0)
|
||||
self.label.setFixedWidth(LABEL_WIDTH)
|
||||
self.label.setWordWrap(True)
|
||||
layout.addWidget(self.label)
|
||||
self.value = QComboBox()
|
||||
for entry in enums:
|
||||
for entry in enums or []:
|
||||
self.value.addItem(entry)
|
||||
layout.addWidget(self.value)
|
||||
|
||||
@@ -168,15 +169,15 @@ class Button(QWidget):
|
||||
def __init__(self, label=None, label_button: str = "", enabled=False):
|
||||
super().__init__()
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(*ROW_MARGINS)
|
||||
layout.setSpacing(ROW_SPACING)
|
||||
if label is not None:
|
||||
self.label = QLabel(label)
|
||||
self.label.setFixedWidth(140)
|
||||
self.label.setFixedWidth(LABEL_WIDTH)
|
||||
layout.addWidget(self.label)
|
||||
self.button = QPushButton(label_button)
|
||||
if label is not None:
|
||||
self.button.setFixedWidth(160)
|
||||
self.button.setFixedWidth(130)
|
||||
self.enable_button(enabled)
|
||||
layout.addWidget(self.button)
|
||||
|
||||
@@ -204,11 +205,10 @@ class TextIndicator(QWidget):
|
||||
def __init__(self, label):
|
||||
super().__init__()
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(10, 0, 0, 0)
|
||||
layout.setSpacing(0)
|
||||
layout.setContentsMargins(*ROW_MARGINS)
|
||||
layout.setSpacing(ROW_SPACING)
|
||||
self.label = QLabel(label)
|
||||
self.label.setFixedWidth(140)
|
||||
self.label.setContentsMargins(0, 0, 10, 0)
|
||||
self.label.setFixedWidth(LABEL_WIDTH)
|
||||
self.label.setWordWrap(True)
|
||||
layout.addWidget(self.label)
|
||||
self.text = QLabel("-")
|
||||
@@ -223,84 +223,3 @@ class TextIndicator(QWidget):
|
||||
|
||||
def setColor(self, color: str):
|
||||
self.text.setStyleSheet(f"QLabel {{color:{color}}}")
|
||||
|
||||
|
||||
# class Button(QWidget):
|
||||
# def __init__(self, label, label_button):
|
||||
# super().__init__()
|
||||
# layout = QHBoxLayout(self)
|
||||
# layout.setContentsMargins(10, 0, 0, 0)
|
||||
# layout.setSpacing(0)
|
||||
# self.label = QLabel(label)
|
||||
# self.label.setFixedWidth(150)
|
||||
# layout.addWidget(self.label)
|
||||
# self.button = QPushButton(label_button)
|
||||
# self.button.setStyleSheet("color: black; background-color: dodgerblue;")
|
||||
# self.button.setFixedWidth(160)
|
||||
# layout.addWidget(self.button)
|
||||
|
||||
# def set_on_press(self, func):
|
||||
# """Connect a function to the button press."""
|
||||
# self.button.clicked.connect(func)
|
||||
|
||||
# def enable_button(self):
|
||||
# self.button.setEnabled(True)
|
||||
# self.button.setStyleSheet("color: black; background-color: dodgerblue;")
|
||||
|
||||
# def disable_button(self):
|
||||
# self.button.setEnabled(False)
|
||||
# self.button.setStyleSheet("color: black; background-color: grey;")
|
||||
|
||||
# def set_button_text(self, text):
|
||||
# self.button.setText(text)
|
||||
|
||||
# class LED(QWidget):
|
||||
# def __init__(self, states, colors, label):
|
||||
# super().__init__()
|
||||
# self.states = states
|
||||
# self.colors = colors
|
||||
# layout = QHBoxLayout(self)
|
||||
# layout.setContentsMargins(10, 0, 0, 0)
|
||||
# layout.setSpacing(0)
|
||||
# self.label = QLabel(label)
|
||||
# self.label.setFixedWidth(150)
|
||||
# layout.addWidget(self.label)
|
||||
# self.led = QLabel()
|
||||
# self.led.setFixedWidth(160)
|
||||
# layout.addWidget(self.led)
|
||||
|
||||
# def apply_color(self, val):
|
||||
# color = self.colors[self.states.index(val)]
|
||||
# self.led.setStyleSheet(f"background-color: {color}; border: 1px solid black;")
|
||||
|
||||
# class InputTextField(QWidget):
|
||||
# def __init__(self, topic, label):
|
||||
# super().__init__()
|
||||
# self.topic = topic
|
||||
# layout = QHBoxLayout(self)
|
||||
# layout.setContentsMargins(10, 0, 0, 0)
|
||||
# layout.setSpacing(0)
|
||||
# self.label = QLabel(label)
|
||||
# self.label.setFixedWidth(140)
|
||||
# self.label.setContentsMargins(0, 0, 10, 0)
|
||||
# self.label.setWordWrap(True)
|
||||
# layout.addWidget(self.label)
|
||||
# self.val = QLineEdit()
|
||||
# self.val.setPlaceholderText('0')
|
||||
# # self.val.setFixedWidth(140)
|
||||
# layout.addWidget(self.val)
|
||||
|
||||
# def set_text(self, text):
|
||||
# self.val.setText(text)
|
||||
|
||||
# def has_focus(self) -> bool:
|
||||
# return self.val.hasFocus()
|
||||
|
||||
# def text(self) -> str:
|
||||
# return self.val.text()
|
||||
|
||||
# def set_on_return(self, func):
|
||||
# """Connect a function to the Enter/Return key press."""
|
||||
# self.val.returnPressed.connect(
|
||||
# partial(func, self.val, self.topic, lambda: self.val.text())
|
||||
# )
|
||||
|
||||
Reference in New Issue
Block a user