From a8fb13ca96b84901e54d66816defb5a780372e9f Mon Sep 17 00:00:00 2001 From: x12sa Date: Sun, 5 Jul 2026 20:42:39 +0200 Subject: [PATCH] feat(flomni): guard umvr_fsamy_tracked against enabled rt feedback umvr_fsamy_tracked/umv_fsamy_tracked require feedback OFF but did not enforce it. Add an _internal flag; for user/CLI calls, warn that feedback must be off (active alignment may be lost), prompt (default yes), and disable feedback on confirm. Internal callers pass _internal=True since they already manage the feedback lifecycle (ftransfer_flomni_stage_out, x_ray_eye_align height-centering and mvy jog). --- .../plugins/flomni/flomni.py | 22 +++++++++++++++---- .../plugins/flomni/x_ray_eye_align.py | 4 ++-- docs/user/ptychography/flomni.md | 1 - 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py index d9f2f8b..c44ec45 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni.py @@ -465,7 +465,7 @@ class FlomniSampleTransferMixin: def laser_tracker_off(self): dev.rtx.controller.laser_tracker_off() - def umvr_fsamy_tracked(self, shift: float, step: float = 0.01): + def umvr_fsamy_tracked(self, shift: float, step: float = 0.01, _internal: bool = False): """ Relative move of fsamy by `shift` mm, broken into steps of at most `step` mm (default 0.01 mm = 10 um), calling laser_tracker_on() @@ -487,10 +487,22 @@ class FlomniSampleTransferMixin: other direction). step: maximum step size in mm per tracker re-acquisition. Must be positive. Default 0.01 mm (10 um). + _internal: set True by internal callers that already manage the + feedback lifecycle themselves, to skip the feedback guard + below. User/CLI calls leave this False. """ if step <= 0: raise ValueError("step must be a positive number of mm.") + if not _internal and dev.rtx.controller.feedback_is_running(): + print( + "\x1b[91mThis move requires rt feedback OFF; any active alignment " + "may be lost.\x1b[0m" + ) + if not self.OMNYTools.yesno("Disable feedback and continue?", "y"): + return + self.feedback_disable() + direction = 1 if shift >= 0 else -1 remaining = abs(shift) while remaining > 0: @@ -499,7 +511,7 @@ class FlomniSampleTransferMixin: dev.rtx.controller.laser_tracker_on() remaining -= this_step - def umv_fsamy_tracked(self, target: float, step: float = 0.01): + def umv_fsamy_tracked(self, target: float, step: float = 0.01, _internal: bool = False): """ Absolute move of fsamy to `target` mm (same units as dev.fsamy's readback / dev.fsamy.user_parameter.get("in")), broken into steps of @@ -510,10 +522,12 @@ class FlomniSampleTransferMixin: step: maximum step size in mm per tracker re-acquisition. Must be positive (validated in umvr_fsamy_tracked). Default 0.01 mm (10 um). + _internal: forwarded to umvr_fsamy_tracked() to skip the feedback + guard for callers that manage feedback themselves. """ current = dev.fsamy.readback.get() shift_mm = target - current - self.umvr_fsamy_tracked(shift_mm, step) + self.umvr_fsamy_tracked(shift_mm, step, _internal=_internal) def show_signal_strength_interferometer(self): dev.rtx.controller.show_signal_strength_interferometer() @@ -567,7 +581,7 @@ class FlomniSampleTransferMixin: "Could not find an 'IN' position for fsamy. Please check your config." ) - self.umv_fsamy_tracked(fsamy_in) + self.umv_fsamy_tracked(fsamy_in, _internal=True) time.sleep(0.05) self.laser_tracker_off() time.sleep(0.05) diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py b/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py index a1e2717..fe057f4 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/x_ray_eye_align.py @@ -307,7 +307,7 @@ class XrayEyeAlign: self.flomni.feedback_disable() if not self.test_wo_movements and delta_y_mm != 0: - self.flomni.umvr_fsamy_tracked(delta_y_mm) + self.flomni.umvr_fsamy_tracked(delta_y_mm, _internal=True) time.sleep(2) self.flomni.feedback_enable_with_reset() @@ -359,7 +359,7 @@ class XrayEyeAlign: if _xrayeyalignmvy != 0: self.flomni.feedback_disable() if not self.test_wo_movements: - self.flomni.umvr_fsamy_tracked(_xrayeyalignmvy / 1000) + self.flomni.umvr_fsamy_tracked(_xrayeyalignmvy / 1000, _internal=True) time.sleep(2) dev.omny_xray_gui.mvy.set(0) self.flomni.feedback_enable_with_reset() diff --git a/docs/user/ptychography/flomni.md b/docs/user/ptychography/flomni.md index a7d8970..7b365af 100644 --- a/docs/user/ptychography/flomni.md +++ b/docs/user/ptychography/flomni.md @@ -54,7 +54,6 @@ If you see your sample already at the approximately correct height: Otherwise adjust the height manually: -1. `flomni.feedback_disable()` disable the closed loop operation to allow movement of coarse stages 1. `umvr_fsamy_tracked(0.01)`, attention: unit , move the sample stage relative up (positive) or down (negative) until the sample is approximately vertically centered in xray eye screen 1. `flomni.xrayeye_update_frame()` will update the current image on the xray eye screen