From 757c4e3dc16fed44f444d0cd658e1963315b0ba8 Mon Sep 17 00:00:00 2001 From: appel_c Date: Fri, 13 Mar 2026 14:02:07 +0100 Subject: [PATCH] fix(flomni): Fix logic for flomni scan, avoid resetting positions. --- csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py | 30 +++++++++++--------- csaxs_bec/scans/flomni_fermat_scan.py | 19 +++++++++---- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py index e769e14..ad2c638 100644 --- a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py @@ -92,7 +92,8 @@ class RtFlomniController(Controller): parent._min_scan_buffer_reached = False start_time = time.time() for pos_index, pos in enumerate(positions): - parent.socket_put_and_receive(f"s{pos[0]:.05f},{pos[1]:.05f},{pos[2]:.05f}") + cmd = f"s{pos[0]:.05f},{pos[1]:.05f},{pos[2]:.05f}" + parent.socket_put_and_receive(cmd) if pos_index > 100: parent._min_scan_buffer_reached = True parent._min_scan_buffer_reached = True @@ -174,11 +175,12 @@ class RtFlomniController(Controller): self.set_device_read_write("foptx", False) self.set_device_read_write("fopty", False) - def move_samx_to_scan_region(self, fovx: float, cenx: float): - #new routine not using fovx anymore - self.device_manager.devices.rtx.obj.move(cenx, wait=True) + def move_samx_to_scan_region(self, cenx: float, move_in_this_routine: bool = False): + # attention. a movement will clear all positions in the rt trajectory generator! + if move_in_this_routine == True: + self.device_manager.devices.rtx.obj.move(cenx, wait=True) time.sleep(0.05) - #at cenx we expect the PID to be close to zero for a good fsamx position + # at cenx we expect the PID to be close to zero for a good fsamx position if self.rt_pid_voltage is None: rtx = self.device_manager.devices.rtx self.rt_pid_voltage = rtx.user_parameter.get("rt_pid_voltage") @@ -188,29 +190,31 @@ class RtFlomniController(Controller): ) logger.info(f"Using PID voltage from rtx user parameter: {self.rt_pid_voltage}") expected_voltage = self.rt_pid_voltage - #logger.info(f"Expected PID voltage: {expected_voltage}") + # logger.info(f"Expected PID voltage: {expected_voltage}") logger.info(f"Current PID voltage: {self.get_pid_x()}") wait_on_exit = False - #we allow 2V range from center, this corresponds to 30 microns + # we allow 2V range from center, this corresponds to 30 microns if np.abs(self.get_pid_x() - expected_voltage) < 2: logger.info("No correction of fsamx needed") else: fsamx = self.device_manager.devices.fsamx fsamx.obj.controller.socket_put_confirmed("axspeed[4]=0.1*stppermm[4]") while True: - #when we correct, then to 1 V, within 15 microns + # when we correct, then to 1 V, within 15 microns if np.abs(self.get_pid_x() - expected_voltage) < 1: logger.info("No further correction needed") break wait_on_exit = True - #disable FZP piezo feedback + # disable FZP piezo feedback self.socket_put("v0") fsamx.read_only = False logger.info(f"Current PID voltage: {self.get_pid_x()}") - #here we accumulate the correction + # here we accumulate the correction fsamx.obj.pid_x_correction -= (self.get_pid_x() - expected_voltage) * 0.006 fsamx_in = fsamx.user_parameter.get("in") - logger.info(f"Moving fsamx to {cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction}, PID portion of that {fsamx.obj.pid_x_correction}") + logger.info( + f"Moving fsamx to {cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction}, PID portion of that {fsamx.obj.pid_x_correction}" + ) fsamx.obj.move(fsamx_in + cenx / 1000 * 0.7 + fsamx.obj.pid_x_correction, wait=True) fsamx.read_only = True time.sleep(0.1) @@ -219,7 +223,7 @@ class RtFlomniController(Controller): if wait_on_exit: time.sleep(1) - #enable fast FZP feedback again + # enable fast FZP feedback again self.socket_put("v1") @threadlocked @@ -510,7 +514,7 @@ class RtFlomniController(Controller): # while scan is running while mode > 0: - #TODO here?: scan abortion if no progress in scan *raise error + # TODO here?: scan abortion if no progress in scan *raise error # logger.info(f"Current scan position {current_position_in_scan} out of {number_of_positions_planned}") mode, number_of_positions_planned, current_position_in_scan = self.get_scan_status() diff --git a/csaxs_bec/scans/flomni_fermat_scan.py b/csaxs_bec/scans/flomni_fermat_scan.py index 0adc88a..bd5646d 100644 --- a/csaxs_bec/scans/flomni_fermat_scan.py +++ b/csaxs_bec/scans/flomni_fermat_scan.py @@ -159,7 +159,8 @@ class FlomniFermatScan(SyncFlyScanBase): if self.flomni_rotation_status: self.flomni_rotation_status.wait() - rtx_status = yield from self.stubs.set(device="rtx", value=self.positions[0][0], wait=False) + #rtx_status = yield from self.stubs.set(device="rtx", value=self.positions[0][0], wait=False) + rtx_status = yield from self.stubs.set(device="rtx", value=self.cenx, wait=False) rtz_status = yield from self.stubs.set(device="rtz", value=self.positions[0][2], wait=False) yield from self.stubs.send_rpc_and_wait("rtx", "controller.laser_tracker_on") @@ -167,13 +168,17 @@ class FlomniFermatScan(SyncFlyScanBase): rtx_status.wait() rtz_status.wait() + + + #status = yield from self.stubs.send_rpc("rtx", "move", self.cenx) + #status.wait() yield from self._transfer_positions_to_flomni() - yield from self.stubs.send_rpc_and_wait( - "rtx", "controller.move_samx_to_scan_region", self.fovx, self.cenx - ) tracker_signal_status = yield from self.stubs.send_rpc_and_wait( "rtx", "controller.laser_tracker_check_signalstrength" ) + yield from self.stubs.send_rpc_and_wait( + "rtx", "controller.move_samx_to_scan_region", self.cenx + ) #self.device_manager.connector.send_client_info(tracker_signal_status) if tracker_signal_status == "low": self.device_manager.connector.raise_alarm( @@ -307,7 +312,11 @@ class FlomniFermatScan(SyncFlyScanBase): # in flomni, we need to move to the start position of the next scan, which is the end position of the current scan # this method is called in finalize and overwrites the default move_to_start() if isinstance(self.positions, np.ndarray) and len(self.positions[-1]) == 3: - yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=self.positions[-1]) + #yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=self.positions[-1]) + #in x we move to cenx, then we avoid jumps in centering routine + value=self.positions[-1] + value[0]=self.cenx + yield from self.stubs.set(device=["rtx", "rty", "rtz"], value=value) return logger.warning("No positions found to return to start")