diff --git a/csaxs_bec/devices/npoint/npoint.py b/csaxs_bec/devices/npoint/npoint.py index 58f9c50..6148aa7 100644 --- a/csaxs_bec/devices/npoint/npoint.py +++ b/csaxs_bec/devices/npoint/npoint.py @@ -412,10 +412,11 @@ class NPointAxis(Device, PositionerBase): sign=1, socket_cls=SocketIO, tolerance: float = 0.05, + device_manager=None, **kwargs, ): self.controller = NPointController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.axis_Id = axis_Id self.sign = sign diff --git a/csaxs_bec/devices/omny/galil/fgalil_ophyd.py b/csaxs_bec/devices/omny/galil/fgalil_ophyd.py index de5a1f0..5faaffc 100644 --- a/csaxs_bec/devices/omny/galil/fgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/fgalil_ophyd.py @@ -175,7 +175,7 @@ class FlomniGalilMotor(Device, PositionerBase): **kwargs, ): self.controller = FlomniGalilController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.axis_Id = axis_Id self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) @@ -342,10 +342,10 @@ class FlomniGalilMotor(Device, PositionerBase): Drive an axis to the limit in a specified direction. Args: - direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'. + direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'. """ self.controller.drive_axis_to_limit(self.axis_Id_numeric, direction) - #now force position read to cache + # now force position read to cache val = self.readback.read() self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time()) diff --git a/csaxs_bec/devices/omny/galil/fupr_ophyd.py b/csaxs_bec/devices/omny/galil/fupr_ophyd.py index 23b75db..d673537 100644 --- a/csaxs_bec/devices/omny/galil/fupr_ophyd.py +++ b/csaxs_bec/devices/omny/galil/fupr_ophyd.py @@ -149,7 +149,7 @@ class FuprGalilMotor(Device, PositionerBase): **kwargs, ): self.controller = FuprGalilController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.axis_Id = axis_Id self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) diff --git a/csaxs_bec/devices/omny/galil/lgalil_ophyd.py b/csaxs_bec/devices/omny/galil/lgalil_ophyd.py index 05f12be..d560bca 100644 --- a/csaxs_bec/devices/omny/galil/lgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/lgalil_ophyd.py @@ -73,6 +73,7 @@ class LamniGalilController(GalilController): air_off = bool(self.socket_put_and_receive("MG@OUT[13]")) return rt_not_blocked_by_galil and air_off + class LamniGalilReadbackSignal(GalilSignalRO): @retry_once @threadlocked @@ -99,6 +100,7 @@ class LamniGalilReadbackSignal(GalilSignalRO): logger.warning("Failed to set RT value during readback.") return val + class LamniGalilMotor(Device, PositionerBase): USER_ACCESS = ["controller", "drive_axis_to_limit", "find_reference"] readback = Cpt(LamniGalilReadbackSignal, signal_name="readback", kind="hinted") @@ -132,7 +134,7 @@ class LamniGalilMotor(Device, PositionerBase): **kwargs, ): self.controller = LamniGalilController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.axis_Id = axis_Id self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) @@ -292,7 +294,7 @@ class LamniGalilMotor(Device, PositionerBase): Find the reference of the axis. """ self.controller.find_reference(self.axis_Id_numeric) - #now force position read to cache + # now force position read to cache val = self.readback.read() self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time()) @@ -301,10 +303,10 @@ class LamniGalilMotor(Device, PositionerBase): Drive an axis to the limit in a specified direction. Args: - direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'. + direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'. """ self.controller.drive_axis_to_limit(self.axis_Id_numeric, direction) - #now force position read to cache + # now force position read to cache val = self.readback.read() self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time()) diff --git a/csaxs_bec/devices/omny/galil/ogalil_ophyd.py b/csaxs_bec/devices/omny/galil/ogalil_ophyd.py index 527ae18..9f31cf9 100644 --- a/csaxs_bec/devices/omny/galil/ogalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/ogalil_ophyd.py @@ -46,7 +46,7 @@ class GalilMotorResolution(GalilSignalRO): @threadlocked def _socket_get(self): if self.controller.sock.port == 8083 and self.parent.axis_Id_numeric == 2: - # rotation stage + # rotation stage return 89565.8666667 else: return 51200 @@ -69,37 +69,43 @@ class OMNYGalilReadbackSignal(GalilSignalRO): current_pos = float(self.controller.socket_put_and_receive(f"TP{self.parent.axis_Id}")) current_pos *= self.parent.sign step_mm = self.parent.motor_resolution.get() - #here we introduce an offset of 25 to the rotation axis - #when setting a position this is taken into account in the controller - #that way we just do tomography from 0 to 180 degrees + # here we introduce an offset of 25 to the rotation axis + # when setting a position this is taken into account in the controller + # that way we just do tomography from 0 to 180 degrees if self.parent.axis_Id_numeric == 2 and self.controller.sock.port == 8083: - return (current_pos / step_mm)+25 + return (current_pos / step_mm) + 25 else: return current_pos / step_mm def read(self): self._metadata["timestamp"] = time.time() val = super().read() - - #if reading rotation stage angle + + # if reading rotation stage angle if self.parent.axis_Id_numeric == 2 and self.controller.sock.port == 8083: current_readback_value = val[self.parent.name]["value"] - #print (f"previous rotation angle {self.previous_rotation_angle}, current readback {current_readback_value}.") + # print (f"previous rotation angle {self.previous_rotation_angle}, current readback {current_readback_value}.") - if np.fabs((self.previous_rotation_angle-current_readback_value)>10): + if np.fabs((self.previous_rotation_angle - current_readback_value) > 10): message = f"Glitch detected in rotation stage. Previous rotation angle {self.previous_rotation_angle}, current readback {current_readback_value}." print(message) - self.parent.device_manager.connector.send_client_info(message, scope="glitch detector", show_asap=True) - + self.parent.device_manager.connector.send_client_info( + message, scope="glitch detector", show_asap=True + ) + val = super().read() current_readback_value = val[self.parent.name]["value"] - if np.fabs((self.previous_rotation_angle-current_readback_value)>10): + if np.fabs((self.previous_rotation_angle - current_readback_value) > 10): message = f"Glitch detected in rotation stage second read. Previous rotation angle {self.previous_rotation_angle}, current readback {current_readback_value}. Disabling the controller." print(message) - self.parent.device_manager.connector.send_client_info(message, scope="glitch detector", show_asap=True) - - self.parent.device_manager.devices["osamroy"].obj.controller.socket_put_confirmed("allaxref=0") + self.parent.device_manager.connector.send_client_info( + message, scope="glitch detector", show_asap=True + ) + + self.parent.device_manager.devices["osamroy"].obj.controller.socket_put_confirmed( + "allaxref=0" + ) self.parent.device_manager.devices["osamroy"].obj.enabled = False return val @@ -108,13 +114,12 @@ class OMNYGalilReadbackSignal(GalilSignalRO): try: rt = self.parent.device_manager.devices["rtx"] if rt.enabled: - rt.obj.controller.set_rotation_angle(val[self.parent.name]["value"]-25+54) + rt.obj.controller.set_rotation_angle(val[self.parent.name]["value"] - 25 + 54) except KeyError: - logger.warning("Failed to set RT value during ogalil readback.") + logger.warning("Failed to set RT value during ogalil readback.") return val - class OMNYGalilController(GalilController): USER_ACCESS = [ "describe", @@ -132,13 +137,13 @@ class OMNYGalilController(GalilController): "_ogalil_folerr_not_ignore", ] - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - + OKBLUE = "\033[94m" + OKCYAN = "\033[96m" + OKGREEN = "\033[92m" + WARNING = "\033[93m" + FAIL = "\033[91m" + ENDC = "\033[0m" + def on(self) -> None: """Open a new socket connection to the controller""" self._ogalil_switchsocket_switch_all_on() @@ -185,15 +190,16 @@ class OMNYGalilController(GalilController): self.socket_put_confirmed("IgNoFol=1") self.socket_put_confirmed("XQ#STOP,1") - - def _ogalil_set_axis_to_pos_wo_reference_search(self, axis_id_numeric, axis_id, pos_mm, motor_resolution, motor_sign): + def _ogalil_set_axis_to_pos_wo_reference_search( + self, axis_id_numeric, axis_id, pos_mm, motor_resolution, motor_sign + ): self.socket_put_confirmed("IgNoFol=1") # pos_mm = pos_encoder / motor_resolution pos_encoder = pos_mm * motor_resolution * motor_sign - #print(motor_resolution) - + # print(motor_resolution) + self.socket_put_confirmed(f"DE{axis_id}={pos_encoder:.0f}") self.socket_put_confirmed(f"DP{axis_id}=_TP{axis_id}*ratio[{axis_id_numeric:.0f}]") @@ -203,7 +209,6 @@ class OMNYGalilController(GalilController): self._ogalil_folerr_not_ignore() - def _ogalil_folerr_not_ignore(self): self.socket_put_confirmed("IgNoFol=0") @@ -240,7 +245,18 @@ class OMNYGalilController(GalilController): class OMNYGalilMotor(Device, PositionerBase): - USER_ACCESS = ["controller", "find_reference", "omny_osamx_to_scan_center", "drive_axis_to_limit", "_ogalil_folerr_reset_and_ignore", "_ogalil_set_axis_to_pos_wo_reference_search", "get_motor_limit_switch", "axis_is_referenced", "get_motor_temperature", "folerr_status"] + USER_ACCESS = [ + "controller", + "find_reference", + "omny_osamx_to_scan_center", + "drive_axis_to_limit", + "_ogalil_folerr_reset_and_ignore", + "_ogalil_set_axis_to_pos_wo_reference_search", + "get_motor_limit_switch", + "axis_is_referenced", + "get_motor_temperature", + "folerr_status", + ] readback = Cpt(OMNYGalilReadbackSignal, signal_name="readback", kind="hinted") user_setpoint = Cpt(GalilSetpointSignal, signal_name="setpoint") motor_resolution = Cpt(GalilMotorResolution, signal_name="resolution", kind="config") @@ -272,7 +288,7 @@ class OMNYGalilMotor(Device, PositionerBase): **kwargs, ): self.controller = OMNYGalilController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.axis_Id = axis_Id self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) @@ -433,8 +449,10 @@ class OMNYGalilMotor(Device, PositionerBase): def _ogalil_set_axis_to_pos_wo_reference_search(self, pos_mm): motor_resolution = self.motor_resolution.get() - self.controller._ogalil_set_axis_to_pos_wo_reference_search(self.axis_Id_numeric, self.axis_Id, pos_mm, motor_resolution, self.sign) - #now force position read to cache + self.controller._ogalil_set_axis_to_pos_wo_reference_search( + self.axis_Id_numeric, self.axis_Id, pos_mm, motor_resolution, self.sign + ) + # now force position read to cache val = self.readback.read() self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time()) @@ -442,9 +460,9 @@ class OMNYGalilMotor(Device, PositionerBase): """ Find the reference of the axis. """ - verbose=1 + verbose = 1 self.controller.find_reference(self.axis_Id_numeric, verbose, raise_error) - #now force position read to cache + # now force position read to cache val = self.readback.read() self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time()) @@ -453,10 +471,10 @@ class OMNYGalilMotor(Device, PositionerBase): Drive an axis to the limit in a specified direction. Args: - direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'. + direction (str): Direction in which the axis should be driven to the limit. Either 'forward' or 'reverse'. """ self.controller.drive_axis_to_limit(self.axis_Id_numeric, direction, verbose=1) - #now force position read to cache + # now force position read to cache val = self.readback.read() self._run_subs(sub_type=self.SUB_READBACK, value=val, timestamp=time.time()) @@ -487,29 +505,31 @@ class OMNYGalilMotor(Device, PositionerBase): def omny_osamx_to_scan_center(self, cenx): if self.controller.sock.port == 8082 and self.axis_Id_numeric == 0: # get last setpoint - osamx = self.device_manager.devices["osamx"] - osamx_current_setpoint = osamx.obj.readback.get() - omny_samx_in = self._get_user_param_safe("osamx","in") - if np.fabs(osamx_current_setpoint-(omny_samx_in+cenx/1000)) > 0.025: - message=f"Moving osamx to scan center. new osamx target {omny_samx_in+cenx/1000:.3f}." - logger.info(message) + osamx = self.device_manager.devices["osamx"] + osamx_current_setpoint = osamx.obj.readback.get() + omny_samx_in = self._get_user_param_safe("osamx", "in") + if np.fabs(osamx_current_setpoint - (omny_samx_in + cenx / 1000)) > 0.025: + message = ( + f"Moving osamx to scan center. new osamx target {omny_samx_in+cenx/1000:.3f}." + ) + logger.info(message) - osamx.read_only = False - #osamx.controller.("osamx", "controller.socket_put_confirmed('axspeed[0]=1000')") - osamx.set(omny_samx_in+cenx/1000) - time.sleep(0.1) - while(osamx.motor_is_moving.get()): - time.sleep(0.05) - osamx.read_only = True - time.sleep(2) - rt = self.device_manager.devices["rtx"] - if rt.enabled: - rt.obj.controller.laser_tracker_on() - rt.obj.controller.laser_tracker_check_and_wait_for_signalstrength() + osamx.read_only = False + # osamx.controller.("osamx", "controller.socket_put_confirmed('axspeed[0]=1000')") + osamx.set(omny_samx_in + cenx / 1000) + time.sleep(0.1) + while osamx.motor_is_moving.get(): + time.sleep(0.05) + osamx.read_only = True + time.sleep(2) + rt = self.device_manager.devices["rtx"] + if rt.enabled: + rt.obj.controller.laser_tracker_on() + rt.obj.controller.laser_tracker_check_and_wait_for_signalstrength() def folerr_status(self) -> bool: return self.controller.folerr_status(self.axis_Id_numeric) - + def stop(self, *, success=False): self.controller.stop_all_axes() return super().stop(success=success) diff --git a/csaxs_bec/devices/omny/galil/sgalil_ophyd.py b/csaxs_bec/devices/omny/galil/sgalil_ophyd.py index d88b191..4493bd7 100644 --- a/csaxs_bec/devices/omny/galil/sgalil_ophyd.py +++ b/csaxs_bec/devices/omny/galil/sgalil_ophyd.py @@ -52,28 +52,7 @@ class GalilController(Controller): "fly_grid_scan", "read_encoder_position", ] - - def __init__( - self, - *, - name="GalilController", - kind=None, - parent=None, - socket=None, - attr_name="", - labels=None, - ): - if not hasattr(self, "_initialized") or not self._initialized: - self._galil_axis_per_controller = 8 - self._axis = [None for axis_num in range(self._galil_axis_per_controller)] - super().__init__( - name=name, - socket=socket, - attr_name=attr_name, - parent=parent, - labels=labels, - kind=kind, - ) + _axes_per_controller = 8 def on(self, controller_num=0) -> None: """Open a new socket connection to the controller""" @@ -165,11 +144,11 @@ class GalilController(Controller): def show_running_threads(self) -> None: t = PrettyTable() t.title = f"Threads on {self.sock.host}:{self.sock.port}" - t.field_names = [str(ax) for ax in range(self._galil_axis_per_controller)] + t.field_names = [str(ax) for ax in range(self._axes_per_controller)] t.add_row( [ "active" if self.is_thread_active(t) else "inactive" - for t in range(self._galil_axis_per_controller) + for t in range(self._axes_per_controller) ] ) print(t) @@ -199,7 +178,7 @@ class GalilController(Controller): "Limits", "Position", ] - for ax in range(self._galil_axis_per_controller): + for ax in range(self._axes_per_controller): axis = self._axis[ax] if axis is not None: t.add_row( @@ -516,7 +495,9 @@ class SGalilMotor(Device, PositionerBase): ): self.axis_Id = axis_Id self.sign = sign - self.controller = GalilController(socket=socket_cls(host=host, port=port)) + self.controller = GalilController( + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager + ) self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) self.tolerance = kwargs.pop("tolerance", 0.5) self.device_mapping = kwargs.pop("device_mapping", {}) diff --git a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py index 116ae10..28c0d25 100644 --- a/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_flomni_ophyd.py @@ -57,6 +57,7 @@ class RtFlomniController(Controller): socket_cls=None, socket_host=None, socket_port=None, + device_manager=None, attr_name="", parent=None, labels=None, @@ -67,6 +68,7 @@ class RtFlomniController(Controller): socket_cls=socket_cls, socket_host=socket_host, socket_port=socket_port, + device_manager=device_manager, attr_name=attr_name, parent=parent, labels=labels, @@ -658,7 +660,7 @@ class RtFlomniMotor(Device, PositionerBase): self.axis_Id = axis_Id self.sign = sign self.controller = RtFlomniController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) self.device_manager = device_manager @@ -813,7 +815,7 @@ class RtFlomniMotor(Device, PositionerBase): if __name__ == "__main__": rtcontroller = RtFlomniController( - socket_cls=SocketIO, socket_host="mpc2844.psi.ch", socket_port=2222 + socket_cls=SocketIO, socket_host="mpc2844.psi.ch", socket_port=2222, device_manager=None ) rtcontroller.on() rtcontroller.laser_tracker_on() diff --git a/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py b/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py index 1d50e6e..78f54e4 100644 --- a/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_lamni_ophyd.py @@ -71,6 +71,7 @@ class RtLamniController(Controller): socket_cls=None, socket_host=None, socket_port=None, + device_manager=None, attr_name="", parent=None, labels=None, @@ -81,6 +82,7 @@ class RtLamniController(Controller): socket_cls=socket_cls, socket_host=socket_host, socket_port=socket_port, + device_manager=device_manager, attr_name=attr_name, parent=parent, labels=labels, @@ -559,7 +561,7 @@ class RtLamniMotor(Device, PositionerBase): self.axis_Id = axis_Id self.sign = sign self.controller = RtLamniController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) self.device_manager = device_manager diff --git a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py index 5160f9f..35f2e65 100644 --- a/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py +++ b/csaxs_bec/devices/omny/rt/rt_omny_ophyd.py @@ -1,8 +1,8 @@ +import builtins +import socket import threading import time from typing import List -import builtins -import socket import numpy as np from bec_lib import bec_logger, messages @@ -34,12 +34,15 @@ from csaxs_bec.devices.omny.rt.rt_ophyd import ( logger = bec_logger.logger + class RtOMNY_mirror_switchbox_Error(Exception): pass + class RtOMNY_Error(Exception): pass + class RtOMNYController(Controller): _axes_per_controller = 3 red = "\x1b[91m" @@ -87,6 +90,7 @@ class RtOMNYController(Controller): socket_cls=None, socket_host=None, socket_port=None, + device_manager=None, attr_name="", parent=None, labels=None, @@ -97,6 +101,7 @@ class RtOMNYController(Controller): socket_cls=socket_cls, socket_host=socket_host, socket_port=socket_port, + device_manager=device_manager, attr_name=attr_name, parent=parent, labels=labels, @@ -234,7 +239,7 @@ class RtOMNYController(Controller): "opt_amplitude1_neg": 3000, "opt_amplitude2_pos": 3000, "opt_amplitude2_neg": 3000, - } + }, } # def is_axis_moving(self, axis_Id) -> bool: @@ -261,42 +266,60 @@ class RtOMNYController(Controller): threading.Thread(target=send_positions, args=(self, positions), daemon=True).start() - def get_mirror_parameters(self,channel): + def get_mirror_parameters(self, channel): return self.mirror_parameters[channel] - def laser_tracker_check_and_wait_for_signalstrength(self): - self.get_device_manager().connector.send_client_info("Checking laser tracker...", scope="", show_asap=True) + self.get_device_manager().connector.send_client_info( + "Checking laser tracker...", scope="", show_asap=True + ) if not self.laser_tracker_check_enabled(): - print("laser_tracker_check_and_wait_for_signalstrength: The laser tracker is not even enabled.") + print( + "laser_tracker_check_and_wait_for_signalstrength: The laser tracker is not even enabled." + ) return - #first check on target + # first check on target self.laser_tracker_wait_on_target() - #when on target, check interferometer signal - signal = self._omny_interferometer_get_signalsample("ssi_4",0.1) + # when on target, check interferometer signal + signal = self._omny_interferometer_get_signalsample("ssi_4", 0.1) rtx = self.get_device_manager().devices.rtx min_signal = rtx.user_parameter.get("min_signal") low_signal = rtx.user_parameter.get("low_signal") wait_counter = 0 - while signal < min_signal and wait_counter<10: - self.get_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) + while signal < min_signal and wait_counter < 10: + self.get_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, + ) - wait_counter+=1 + wait_counter += 1 time.sleep(0.2) - signal = self._omny_interferometer_get_signalsample("ssi_4",0.1) + signal = self._omny_interferometer_get_signalsample("ssi_4", 0.1) if signal < low_signal: - self.get_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) + self.get_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, + ) - self.omny_interferometer_align_tracking() - self.get_device_manager().connector.send_client_info("Checking laser tracker completed.", scope="", show_asap=True) + self.omny_interferometer_align_tracking() + self.get_device_manager().connector.send_client_info( + "Checking laser tracker completed.", scope="", show_asap=True + ) def omny_interferometer_align_tracking(self): - mirror_channel=6 - signal = self._omny_interferometer_get_signalsample(self.mirror_parameters[mirror_channel]["opt_signalchannel"], self.mirror_parameters[mirror_channel]["opt_averaging_time"]) + mirror_channel = 6 + signal = self._omny_interferometer_get_signalsample( + self.mirror_parameters[mirror_channel]["opt_signalchannel"], + self.mirror_parameters[mirror_channel]["opt_averaging_time"], + ) if signal > self.mirror_parameters[mirror_channel]["opt_signal_stop"]: - print(f"Interferometer signal of axis {self.mirror_parameters[mirror_channel]['opt_mirrorname']} is good, no alignment needed.") + print( + f"Interferometer signal of axis {self.mirror_parameters[mirror_channel]['opt_mirrorname']} is good, no alignment needed." + ) else: self._omny_interferometer_switch_channel(mirror_channel) time.sleep(0.1) @@ -307,16 +330,19 @@ class RtOMNYController(Controller): self._omny_interferometer_switch_alloff() self.show_signal_strength_interferometer() - mirror_channel=-1 - - + mirror_channel = -1 def omny_interferometer_align_incoupling_angle(self): - mirror_channel=1 - signal = self._omny_interferometer_get_signalsample(self.mirror_parameters[mirror_channel]["opt_signalchannel"], self.mirror_parameters[mirror_channel]["opt_averaging_time"]) + mirror_channel = 1 + signal = self._omny_interferometer_get_signalsample( + self.mirror_parameters[mirror_channel]["opt_signalchannel"], + self.mirror_parameters[mirror_channel]["opt_averaging_time"], + ) if signal > self.mirror_parameters[mirror_channel]["opt_signal_stop"]: - print(f"Interferometer signal of axis {self.mirror_parameters[mirror_channel]['opt_mirrorname']} is good, no alignment needed.") + print( + f"Interferometer signal of axis {self.mirror_parameters[mirror_channel]['opt_mirrorname']} is good, no alignment needed." + ) else: self._omny_interferometer_switch_channel(mirror_channel) time.sleep(0.1) @@ -327,18 +353,17 @@ class RtOMNYController(Controller): self._omny_interferometer_switch_alloff() self.show_signal_strength_interferometer() - mirror_channel=-1 - + mirror_channel = -1 def _omny_interferometer_openloop_steps(self, channel, steps, amplitude): - if channel not in range(3,5): + if channel not in range(3, 5): raise RtOMNY_Error(f"invalid channel number {channel}.") if amplitude > 4090: amplitude = 4090 elif amplitude < 10: amplitude = 10 - + oshield = self.get_device_manager().devices.oshield oshield.obj.controller.move_open_loop_steps( @@ -351,7 +376,7 @@ class RtOMNYController(Controller): def _omny_interferometer_optimize(self, mirror_channel, channel): if mirror_channel == -1: raise RtOMNY_Error("no mirror channel selected") - #mirror channel is mirror number and channel is smaract channel, i.e. axis of the mirror + # mirror channel is mirror number and channel is smaract channel, i.e. axis of the mirror if channel == 3: steps_pos = self.mirror_parameters[mirror_channel]["opt_steps1_pos"] steps_neg = self.mirror_parameters[mirror_channel]["opt_steps1_neg"] @@ -365,67 +390,80 @@ class RtOMNYController(Controller): else: raise RtOMNY_Error(f"invalid channel number {channel}.") - previous_signal = self._omny_interferometer_get_signalsample(self.mirror_parameters[mirror_channel]["opt_signalchannel"], self.mirror_parameters[mirror_channel]["opt_averaging_time"]) + previous_signal = self._omny_interferometer_get_signalsample( + self.mirror_parameters[mirror_channel]["opt_signalchannel"], + self.mirror_parameters[mirror_channel]["opt_averaging_time"], + ) - min_begin = self.mirror_parameters[mirror_channel]["opt_signal_min_begin"] + min_begin = self.mirror_parameters[mirror_channel]["opt_signal_min_begin"] if previous_signal < min_begin: - #raise OMNY_rt_clientError("error1") #(f"Minimum signal of axis {self.mirror_parameters[mirror_channel]["opt_mirrorname"]} to start alignment not present.") + # raise OMNY_rt_clientError("error1") #(f"Minimum signal of axis {self.mirror_parameters[mirror_channel]["opt_mirrorname"]} to start alignment not present.") print(f"\rMinimum signal for auto alignment {min_begin} not reached.") return elif previous_signal > self.mirror_parameters[mirror_channel]["opt_signal_stop"]: - print(f"\rInterferometer signal of axis is good") # {self.mirror_parameters[mirror_channel]["opt_mirrorname"]} is good.") - return + print( + f"\rInterferometer signal of axis is good" + ) # {self.mirror_parameters[mirror_channel]["opt_mirrorname"]} is good.") + return else: direction = 1 - cycle_counter=0 - cycle_max=20 - reversal_counter=0 - reversal_max=4 - self.mirror_amplitutde_increase=0 + cycle_counter = 0 + cycle_max = 20 + reversal_counter = 0 + reversal_max = 4 + self.mirror_amplitutde_increase = 0 - current_sample = self._omny_interferometer_get_signalsample(self.mirror_parameters[mirror_channel]["opt_signalchannel"], self.mirror_parameters[mirror_channel]["opt_averaging_time"]) - max=current_sample + current_sample = self._omny_interferometer_get_signalsample( + self.mirror_parameters[mirror_channel]["opt_signalchannel"], + self.mirror_parameters[mirror_channel]["opt_averaging_time"], + ) + max = current_sample - while current_sample < self.mirror_parameters[mirror_channel]["opt_signal_stop"] and cycle_counter0: + if direction > 0: self._omny_interferometer_openloop_steps(channel, steps_pos, opt_amplitude_pos) verbose_str = f"channel {channel}, steps {steps_pos}" else: self._omny_interferometer_openloop_steps(channel, -steps_neg, opt_amplitude_neg) verbose_str = f"auto action {channel}, steps {-steps_pos}" - #print(f"Aligning axis ") #{self.mirror_parameters[mirror_channel]["opt_mirrorname"]}. Target: {self.mirror_parameters[mirror_channel]["opt_signal_stop"]}, current {current_sample}") + # print(f"Aligning axis ") #{self.mirror_parameters[mirror_channel]["opt_mirrorname"]}. Target: {self.mirror_parameters[mirror_channel]["opt_signal_stop"]}, current {current_sample}") - current_sample = self._omny_interferometer_get_signalsample(self.mirror_parameters[mirror_channel]["opt_signalchannel"], self.mirror_parameters[mirror_channel]["opt_averaging_time"]) + current_sample = self._omny_interferometer_get_signalsample( + self.mirror_parameters[mirror_channel]["opt_signalchannel"], + self.mirror_parameters[mirror_channel]["opt_averaging_time"], + ) opt_mirrorname = self.mirror_parameters[mirror_channel]["opt_mirrorname"] info_str = f"\rAuto aligning Channel {mirror_channel}, {opt_mirrorname}, Current signal: {current_sample:.0f}" - message=info_str +" (q)uit \r" - self.get_device_manager().connector.send_client_info(message, scope="_omny_interferometer_optimize", show_asap=True) - - - - if previous_signal>current_sample: - if direction<0: - steps_pos=int(steps_pos/2) - steps_neg=int(steps_neg/2) - if steps_pos<1: - steps_pos=1 - if steps_neg<1: - steps_neg=1 - direction=direction*(-1) - reversal_counter+=1 - previous_signal=current_sample - cycle_counter+=1 - - print(f"\r\nFinished aligning channel {channel} of mirror {mirror_channel}\n\r") # {self.mirror_parameters[mirror_channel]["opt_mirrorname"]}. Target: {self.mirror_parameters[mirror_channel]["opt_signal_stop"]}, current {current_sample}") - - + message = info_str + " (q)uit \r" + self.get_device_manager().connector.send_client_info( + message, scope="_omny_interferometer_optimize", show_asap=True + ) + if previous_signal > current_sample: + if direction < 0: + steps_pos = int(steps_pos / 2) + steps_neg = int(steps_neg / 2) + if steps_pos < 1: + steps_pos = 1 + if steps_neg < 1: + steps_neg = 1 + direction = direction * (-1) + reversal_counter += 1 + previous_signal = current_sample + cycle_counter += 1 + print( + f"\r\nFinished aligning channel {channel} of mirror {mirror_channel}\n\r" + ) # {self.mirror_parameters[mirror_channel]["opt_mirrorname"]}. Target: {self.mirror_parameters[mirror_channel]["opt_signal_stop"]}, current {current_sample}") def move_to_zero(self): self.socket_put("pa0,0") @@ -457,7 +495,7 @@ class RtOMNYController(Controller): if ret == 1: return True return False - + def feedback_is_running(self) -> bool: self.feedback_get_status_and_ssi() interferometer_feedback_not_running = int(self.ssi["feedback_error"]) @@ -466,7 +504,9 @@ class RtOMNYController(Controller): return True def feedback_enable_with_reset(self): - self.get_device_manager().connector.send_client_info(f"Enabling the feedback...", scope="", show_asap=True) + self.get_device_manager().connector.send_client_info( + f"Enabling the feedback...", scope="", show_asap=True + ) self.socket_put("J0") # disable feedback time.sleep(0.01) @@ -488,8 +528,10 @@ class RtOMNYController(Controller): osamroy = self.get_device_manager().devices.osamroy # the following read will also upate the angle in rt during readout readback = osamroy.obj.readback.get() - if (np.fabs(readback) > 0.1): - self.get_device_manager().connector.send_client_info(f"Rotating to zero", scope="feedback enable", show_asap=True) + if np.fabs(readback) > 0.1: + self.get_device_manager().connector.send_client_info( + f"Rotating to zero", scope="feedback enable", show_asap=True + ) osamroy.obj.move(0, wait=True) osamx = self.get_device_manager().devices.osamx @@ -523,7 +565,6 @@ class RtOMNYController(Controller): print("Feedback is running.") - @threadlocked def clear_trajectory_generator(self): self.socket_put("sc") @@ -543,7 +584,6 @@ class RtOMNYController(Controller): print("rt feedback is now disabled.") - def set_rotation_angle(self, val: float) -> None: self.socket_put(f"a{val/180*np.pi}") @@ -578,12 +618,13 @@ class RtOMNYController(Controller): "enabled_z": bool(tracker_values[10]), } - def laser_tracker_on(self): - #update variables and enable if not yet active + # update variables and enable if not yet active if not self.laser_tracker_check_enabled(): logger.info("Enabling the laser tracker. Please wait...") - self.get_device_manager().connector.send_client_info(f"Enabling the laser tracker. Please wait...", scope="", show_asap=True) + self.get_device_manager().connector.send_client_info( + f"Enabling the laser tracker. Please wait...", scope="", show_asap=True + ) tracker_intensity = self.tracker_info["tracker_intensity"] if ( @@ -609,7 +650,6 @@ class RtOMNYController(Controller): logger.info("Laser tracker running!") print("Laser tracker running!") - def laser_tracker_check_enabled(self) -> bool: self.laser_update_tracker_info() if self.tracker_info["enabled_z"] and self.tracker_info["enabled_y"]: @@ -628,11 +668,10 @@ class RtOMNYController(Controller): return True return False - def laser_tracker_wait_on_target(self): max_repeat = 15 count = 0 - while not self.laser_tracker_check_on_target() and count dict: self.average_stdeviations_x_st_fzp += float(return_table[16]) self.average_stdeviations_y_st_fzp += float(return_table[18]) @@ -831,7 +866,6 @@ class RtOMNYController(Controller): "stdev_x_st_fzp": {"value": float(return_table[16])}, "average_y_st_fzp": {"value": float(return_table[17])}, "stdev_y_st_fzp": {"value": float(return_table[18])}, - "average_stdeviations_x_st_fzp": { "value": self.average_stdeviations_x_st_fzp / (int(return_table[0]) + 1) }, @@ -840,7 +874,7 @@ class RtOMNYController(Controller): }, } return signals - + @threadlocked def start_scan(self): if not self.feedback_is_running(): @@ -862,7 +896,6 @@ class RtOMNYController(Controller): # start a point-by-point scan (for cont scan in flomni it would be "sa") self.socket_put_and_receive("sd") - @retry_once @threadlocked def get_scan_status(self): @@ -881,7 +914,6 @@ class RtOMNYController(Controller): current_position_in_scan = int(float(return_table[2])) return (mode, number_of_positions_planned, current_position_in_scan) - def get_device_manager(self): for axis in self._axis: if hasattr(axis, "device_manager") and axis.device_manager: @@ -953,8 +985,9 @@ class RtOMNYController(Controller): "OMNY statistics: Average of all standard deviations [nm]: x" f" {self.average_stdeviations_x_st_fzp/read_counter*1000:.1f}, y" f" {self.average_stdeviations_y_st_fzp/read_counter*1000:.1f}.", - scope="", show_asap=True) - + scope="", + show_asap=True, + ) def publish_device_data(self, signals, point_id): self.get_device_manager().connector.set_and_publish( @@ -1068,7 +1101,7 @@ class RtOMNYMotor(Device, PositionerBase): self.axis_Id = axis_Id self.sign = sign self.controller = RtOMNYController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.controller.set_axis(axis=self, axis_nr=self.axis_Id_numeric) self.device_manager = device_manager @@ -1182,7 +1215,6 @@ class RtOMNYMotor(Device, PositionerBase): return status - @property def axis_Id(self): return self._axis_Id_alpha @@ -1227,7 +1259,7 @@ class RtOMNYMotor(Device, PositionerBase): if __name__ == "__main__": rtcontroller = RtOMNYController( - socket_cls=SocketIO, socket_host="mpc2844.psi.ch", socket_port=2222 + socket_cls=SocketIO, socket_host="mpc2844.psi.ch", socket_port=2222, device_manager=None ) rtcontroller.on() rtcontroller.laser_tracker_on() diff --git a/csaxs_bec/devices/smaract/smaract_controller.py b/csaxs_bec/devices/smaract/smaract_controller.py index 772b678..8b2e513 100644 --- a/csaxs_bec/devices/smaract/smaract_controller.py +++ b/csaxs_bec/devices/smaract/smaract_controller.py @@ -93,6 +93,7 @@ class SmaractController(Controller): socket_cls=None, socket_host=None, socket_port=None, + device_manager=None, attr_name="", labels=None, ): @@ -102,6 +103,7 @@ class SmaractController(Controller): socket_cls=socket_cls, socket_host=socket_host, socket_port=socket_port, + device_manager=device_manager, attr_name=attr_name, parent=parent, labels=labels, diff --git a/csaxs_bec/devices/smaract/smaract_ophyd.py b/csaxs_bec/devices/smaract/smaract_ophyd.py index ff088ac..0e810c2 100644 --- a/csaxs_bec/devices/smaract/smaract_ophyd.py +++ b/csaxs_bec/devices/smaract/smaract_ophyd.py @@ -123,10 +123,11 @@ class SmaractMotor(Device, PositionerBase): limits=None, sign=1, socket_cls=SocketIO, + device_manager=None, **kwargs, ): self.controller = SmaractController( - socket_cls=socket_cls, socket_host=host, socket_port=port + socket_cls=socket_cls, socket_host=host, socket_port=port, device_manager=device_manager ) self.axis_Id = axis_Id self.sign = sign diff --git a/tests/tests_devices/test_npoint_piezo.py b/tests/tests_devices/test_npoint_piezo.py index a8157d7..a58677d 100644 --- a/tests/tests_devices/test_npoint_piezo.py +++ b/tests/tests_devices/test_npoint_piezo.py @@ -16,7 +16,10 @@ def controller(): """ with mock.patch("ophyd_devices.utils.socket.SocketIO") as socket_cls: controller = NPointController( - socket_cls=socket_cls, socket_host="localhost", socket_port=1234 + socket_cls=socket_cls, + socket_host="localhost", + socket_port=1234, + device_manager=mock.MagicMock(), ) controller.on() controller.sock.reset_mock() diff --git a/tests/tests_devices/test_rt_flomni.py b/tests/tests_devices/test_rt_flomni.py index e6f7ae8..4100c6e 100644 --- a/tests/tests_devices/test_rt_flomni.py +++ b/tests/tests_devices/test_rt_flomni.py @@ -11,7 +11,11 @@ from csaxs_bec.devices.omny.rt.rt_ophyd import RtError def rt_flomni(): RtFlomniController._reset_controller() rt_flomni = RtFlomniController( - name="rt_flomni", socket_cls=SocketMock, socket_host="localhost", socket_port=8081 + name="rt_flomni", + socket_cls=SocketMock, + socket_host="localhost", + socket_port=8081, + device_manager=mock.MagicMock(), ) with mock.patch.object(rt_flomni, "get_device_manager"): with mock.patch.object(rt_flomni, "sock"): diff --git a/tests/tests_devices/test_smaract.py b/tests/tests_devices/test_smaract.py index f4ef4de..badd33a 100644 --- a/tests/tests_devices/test_smaract.py +++ b/tests/tests_devices/test_smaract.py @@ -12,7 +12,9 @@ from csaxs_bec.devices.smaract.smaract_ophyd import SmaractMotor @pytest.fixture def controller(): SmaractController._reset_controller() - controller = SmaractController(socket_cls=SocketMock, socket_host="dummy", socket_port=123) + controller = SmaractController( + socket_cls=SocketMock, socket_host="dummy", socket_port=123, device_manager=mock.MagicMock() + ) controller.on() controller.sock.flush_buffer() yield controller