From 6bce6f890785e48c966362d2eff389b8e72c4be5 Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Tue, 9 Jun 2026 15:41:10 +0200 Subject: [PATCH] fix(digital-twin): use exact string comparisons Replace substring membership checks with equality for modes, stripes, scene names, and plot identifiers so partial strings cannot select the wrong branch. --- .../digital_twin/calculations/calc_positions.py | 6 +++--- .../digital_twin/calculations/calc_sideview.py | 2 +- .../digital_twin/calculations/calc_surfaces.py | 2 +- .../digital_twin/calculations/calc_varia.py | 14 +++++++------- .../widgets/digital_twin/digital_twin.py | 16 ++++++++-------- .../widgets/digital_twin/panels/plots.py | 16 ++++++++-------- .../widgets/digital_twin/widgets/move_widget.py | 2 +- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_positions.py b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_positions.py index 79cb809..885dcb3 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_positions.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_positions.py @@ -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] diff --git a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_sideview.py b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_sideview.py index afa0b29..7ec677d 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_sideview.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_sideview.py @@ -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"])) diff --git a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_surfaces.py b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_surfaces.py index dcac3dd..0b90b93 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_surfaces.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_surfaces.py @@ -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, diff --git a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_varia.py b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_varia.py index 0cc43f0..e5911d8 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_varia.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/calculations/calc_varia.py @@ -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 diff --git a/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py b/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py index 7b7ee59..140efad 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/digital_twin.py @@ -309,10 +309,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 @@ -600,13 +600,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 +659,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 +745,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 +767,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) diff --git a/debye_bec/bec_widgets/widgets/digital_twin/panels/plots.py b/debye_bec/bec_widgets/widgets/digital_twin/panels/plots.py index 5e17c85..2eb0cf9 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/panels/plots.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/panels/plots.py @@ -74,7 +74,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 +130,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 +165,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: @@ -223,7 +223,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: @@ -281,7 +281,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: diff --git a/debye_bec/bec_widgets/widgets/digital_twin/widgets/move_widget.py b/debye_bec/bec_widgets/widgets/digital_twin/widgets/move_widget.py index 8266b58..08e87d5 100644 --- a/debye_bec/bec_widgets/widgets/digital_twin/widgets/move_widget.py +++ b/debye_bec/bec_widgets/widgets/digital_twin/widgets/move_widget.py @@ -485,7 +485,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: