From e0213697bcf9c0e2c02af4966b9808f8a2c1944e Mon Sep 17 00:00:00 2001 From: x01dc Date: Wed, 2 Sep 2026 12:15:42 +0200 Subject: [PATCH] fix(omny): quiet laser tracker check, drop redundant call laser_tracker_check_and_wait_for_signalstrength() used send_client_info() for its "Checking laser tracker..."/"...completed." messages, which queues onto the scan's client-message list -- exposing it to a bec_lib bug (QueueItem.get_client_messages() mutates its list while iterating, so it skips and later re-delivers leftover messages on an unrelated call; see OPEN_ISSUES.md, reported upstream). flomni's equivalent, laser_tracker_check_signalstrength(), has always used plain print() instead, which never queues and so never hits that bug. Switched omny's version to match exactly (Mirko's call). Both check functions run once per RT axis set (via Rt*SetpointSignal._socket_set()), so a single scan setup (rtx+rtz set together) already triggered 2 checks; omny_fermat_scan.py's prepare_setup_part2() had an additional explicit third call, pure duplication of the same check. Removed it -- one less redundant laser-tracker wait per scan setup, no loss of the actual safety check (rtx/rtz are still individually checked via their own set() calls). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01QLrD7sVYGLAzsQjLVJpCgt --- .../plugins/omny/AI_docs/OPEN_ISSUES.md | 25 +++++++++++++++++ csaxs_bec/devices/omny/rt/rt_omny_ophyd.py | 28 +++++++++---------- csaxs_bec/scans/omny_fermat_scan.py | 6 ++-- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/OPEN_ISSUES.md b/csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/OPEN_ISSUES.md index 390c5689..69553586 100644 --- a/csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/OPEN_ISSUES.md +++ b/csaxs_bec/bec_ipython_client/plugins/omny/AI_docs/OPEN_ISSUES.md @@ -197,6 +197,31 @@ continuously logged into every scan) now that it's not strictly needed; he chose read back in any scan code, so continuous per-scan logging was likely never useful. Not reverted; this is a deliberate choice, not leftover cruft. +## laser_tracker_check_and_wait_for_signalstrength() was chatty (fixed) + +Live testing of the first successful omny scan surfaced two odd things at once: a "Summary of +client messages" printout Mirko had never seen, and client-info messages ("Checking laser +tracker...") getting reprinted on a later, unrelated call (`tomo_parameters()`). Root cause of the +*reprint*, live-diagnosed: a genuine `bec_lib` bug (`QueueItem.get_client_messages()` mutates its +list while iterating -- reported upstream). But the reason it was even *noticeable* is +omny-specific: `laser_tracker_check_and_wait_for_signalstrength()` +(`csaxs_bec/devices/omny/rt/rt_omny_ophyd.py`) used `send_client_info()` for its +"Checking..."/"...completed." pair, which queues onto the scan's client-message list (and is thus +exposed to the `get_client_messages()` bug), whereas flomni's equivalent, +`laser_tracker_check_signalstrength()` (`rt_flomni_ophyd.py`), has always used plain `print()` +(server-side only, never queued, never exposed to that bug). Both mirror each other structurally +in one other way too: `RtOMNYSetpointSignal._socket_set()`/`RtFlomniSetpointSignal._socket_set()` +each run this check once per RT axis set -- so a single scan setup (rtx + rtz set together, plus, +until this fix, an extra explicit call in `omny_fermat_scan.py`'s `prepare_setup_part2()`) +triggered the check 2-3 times, each producing 2 messages on omny's chatty version vs 0 visible +output on flomni's silent one. + +**Fixed**: switched `laser_tracker_check_and_wait_for_signalstrength()` to plain `print()` +throughout (matching flomni exactly -- Mirko's explicit call), and removed the now-redundant +explicit `laser_tracker_check_and_wait_for_signalstrength()` call in `prepare_setup_part2()` +(pure duplication of the per-axis checks the rtx/rtz `set()` calls already trigger). Net effect: +quieter output, one less redundant tracker-check wait per scan setup, same safety behavior. + ## Environment note (not code, but will bite again if forgotten) Both `csaxs_bec` and `bec_widgets` were pip-installed editable pointing at pre-repo- diff --git a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py index ba69da8f..c9cfba05 100644 --- a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py @@ -268,9 +268,15 @@ class RtOMNYController(Controller): return self.mirror_parameters[channel] def laser_tracker_check_and_wait_for_signalstrength(self): - self.device_manager.connector.send_client_info( - "Checking laser tracker...", scope="", show_asap=True - ) + # Plain print(), not send_client_info(): this runs on every RT setpoint move + # (RtOMNYSetpointSignal._socket_set()), so send_client_info() queued a "Checking + # laser tracker..."/"...completed." pair per move into the scan's client-message + # queue -- multiple times per scan setup -- which is both noisy for the user and + # triggers a bec_lib get_client_messages() bug that reprints leftover queued + # messages on a later, unrelated call (see omny/AI_docs/OPEN_ISSUES.md). Mirrors + # flomni's laser_tracker_check_signalstrength() (rt_flomni_ophyd.py), which has + # always used plain print() for this. + print("Checking laser tracker...") if not self.laser_tracker_check_enabled(): print( "laser_tracker_check_and_wait_for_signalstrength: The laser tracker is not even enabled." @@ -285,10 +291,8 @@ class RtOMNYController(Controller): low_signal = rtx.user_parameter.get("low_signal") wait_counter = 0 while signal < min_signal and wait_counter < 10: - self.device_manager.connector.send_client_info( - f"The signal of the tracker {signal} is below the minimum required signal of {min_signal}. Waiting...", - scope="laser_tracker_check_and_wait_for_signalstrength", - show_asap=True, + print( + f"The signal of the tracker {signal} is below the minimum required signal of {min_signal}. Waiting..." ) wait_counter += 1 @@ -296,16 +300,12 @@ class RtOMNYController(Controller): signal = self._omny_interferometer_get_signalsample("ssi_4", 0.1) if signal < low_signal: - self.device_manager.connector.send_client_info( - f"\x1b[91mThe signal of the tracker {signal} is below the low limit of {low_signal}. Auto readjustment...\x1b[0m", - scope="laser_tracker_check_and_wait_for_signalstrength", - show_asap=True, + print( + f"\x1b[91mThe signal of the tracker {signal} is below the low limit of {low_signal}. Auto readjustment...\x1b[0m" ) self.omny_interferometer_align_tracking() - self.device_manager.connector.send_client_info( - "Checking laser tracker completed.", scope="", show_asap=True - ) + print("Checking laser tracker completed.") def omny_interferometer_align_tracking(self): mirror_channel = 6 diff --git a/csaxs_bec/scans/omny_fermat_scan.py b/csaxs_bec/scans/omny_fermat_scan.py index 660bd588..11f84007 100644 --- a/csaxs_bec/scans/omny_fermat_scan.py +++ b/csaxs_bec/scans/omny_fermat_scan.py @@ -397,12 +397,14 @@ class OmnyFermatScan(ScanBase): if self.omny_rotation_status is not None: self.omny_rotation_status.wait() + # No separate laser_tracker_check_and_wait_for_signalstrength() call here: setting + # rtx/rtz below already runs it once per axis via + # RtOMNYSetpointSignal._socket_set() -- an explicit third call here was pure + # duplication (same check, same signal), not an extra safety margin. rt_move_status = self.actions.set( device=["rtx", "rtz"], value=[self.positions[0][0], self.positions[0][2]], wait=False ) - self.dev.rtx.controller.laser_tracker_check_and_wait_for_signalstrength() - rt_move_status.wait() self.dev.rtx.controller.add_pos_to_scan(self.positions.tolist())