From fae7b938058f3c4d9d62552632b23e33c48f3301 Mon Sep 17 00:00:00 2001 From: appel_c Date: Tue, 11 Mar 2025 10:14:54 +0100 Subject: [PATCH] tests (mo1_bragg): fix fests after update of trigger settings on IOC --- debye_bec/devices/mo1_bragg.py | 59 +++++++++++++-------------- tests/tests_devices/test_mo1_bragg.py | 52 ++++++++--------------- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/debye_bec/devices/mo1_bragg.py b/debye_bec/devices/mo1_bragg.py index da5e3be..d8fabb0 100644 --- a/debye_bec/devices/mo1_bragg.py +++ b/debye_bec/devices/mo1_bragg.py @@ -1,6 +1,6 @@ -""" Module for the Mo1 Bragg positioner of the Debye beamline. +"""Module for the Mo1 Bragg positioner of the Debye beamline. The softIOC is reachable via the EPICS prefix X01DA-OP-MO1:BRAGG: and connected -to a motor controller via web sockets. The Mo1 Bragg positioner is not only a +to a motor controller via web sockets. The Mo1 Bragg positioner is not only a positioner, but also a scan controller to setup XAS and XRD scans. A few scan modes are programmed in the controller, e.g. simple and advanced XAS scans + XRD triggering mode. @@ -28,26 +28,30 @@ from ophyd import ( Signal, Staged, ) -from typeguard import typechecked from ophyd.utils import LimitError from ophyd_devices.utils import bec_scaninfo_mixin, bec_utils from ophyd_devices.utils.errors import DeviceStopError, DeviceTimeoutError +from typeguard import typechecked + from debye_bec.devices.utils.mo1_bragg_utils import compute_spline logger = bec_logger.logger + class TriggerControlSource(int, enum.Enum): """Enum class for the trigger control source of the trigger generator""" EPICS = 0 INPOS = 1 + class TriggerControlMode(int, enum.Enum): """Enum class for the trigger control mode of the trigger generator""" PULSE = 0 CONDITION = 1 + class ScanControlScanStatus(int, enum.Enum): """Enum class for the scan status of the Bragg positioner""" @@ -179,8 +183,10 @@ class Mo1BraggScanSettings(Device): a_scan_vel = Cpt(EpicsSignalWithRBV, suffix="a_scan_vel", kind="config", auto_monitor=True) a_scan_time = Cpt(EpicsSignalWithRBV, suffix="a_scan_time", kind="config", auto_monitor=True) + class Mo1TriggerSettings(Device): """Mo1 Trigger settings""" + settle_time = Cpt(EpicsSignalWithRBV, suffix="settle_time", kind="config") max_dev = Cpt(EpicsSignalWithRBV, suffix="max_dev", kind="config") @@ -204,6 +210,7 @@ class Mo1TriggerSettings(Device): univ2_trig_len = Cpt(EpicsSignalWithRBV, suffix="univ2_trig_len", kind="config") univ2_trig_req = Cpt(EpicsSignal, suffix="univ2_trig_req", kind="config") + class Mo1BraggCalculator(Device): """Mo1 Bragg PVs to convert angle to energy or vice-versa.""" @@ -212,6 +219,7 @@ class Mo1BraggCalculator(Device): calc_energy = Cpt(EpicsSignalWithRBV, suffix="calc_energy", kind="config") calc_angle = Cpt(EpicsSignalWithRBV, suffix="calc_angle", kind="config") + class Mo1BraggScanControl(Device): """Mo1 Bragg PVs to control the scan after setting the parameters.""" @@ -224,9 +232,7 @@ class Mo1BraggScanControl(Device): scan_start_infinite = Cpt( EpicsSignal, suffix="scan_start_infinite", kind="config", put_complete=True ) - scan_start_timer = Cpt( - EpicsSignal, suffix="scan_start_timer", kind="config", put_complete=True - ) + scan_start_timer = Cpt(EpicsSignal, suffix="scan_start_timer", kind="config", put_complete=True) scan_stop = Cpt(EpicsSignal, suffix="scan_stop", kind="config", put_complete=True) scan_status = Cpt( EpicsSignalRO, suffix="scan_status_ENUM_RBV", kind="config", auto_monitor=True @@ -235,9 +241,7 @@ class Mo1BraggScanControl(Device): EpicsSignalRO, suffix="scan_time_left_RBV", kind="config", auto_monitor=True ) scan_done = Cpt(EpicsSignalRO, suffix="scan_done_RBV", kind="config", auto_monitor=True) - scan_val_reset = Cpt( - EpicsSignal, suffix="scan_val_reset", kind="config", put_complete=True - ) + scan_val_reset = Cpt(EpicsSignal, suffix="scan_val_reset", kind="config", put_complete=True) scan_progress = Cpt(EpicsSignalRO, suffix="scan_progress_RBV", kind="config", auto_monitor=True) scan_spectra_done = Cpt( EpicsSignalRO, suffix="scan_n_osc_RBV", kind="config", auto_monitor=True @@ -256,8 +260,8 @@ class ScanParameter: scan_time: float = None scan_duration: float = None - trig_enable_low: bool = None - trig_enable_high: bool = None + xrd_enable_low: bool = None # trig_enable_low: bool = None + xrd_enable_high: bool = None # trig_enable_high: bool = None exp_time_low: float = None exp_time_high: float = None cycle_low: int = None @@ -578,16 +582,14 @@ class Mo1Bragg(Device, PositionerBase): @typechecked def convert_angle_energy( - self, - mode:Literal["AngleToEnergy", "EnergyToAngle"], - inp:float + self, mode: Literal["AngleToEnergy", "EnergyToAngle"], inp: float ) -> float: """Calculate energy to angle or vice versa Args: mode (Literal["AngleToEnergy", "EnergyToAngle"]): Mode of calculation input (float): Either angle or energy - + Returns: output (float): Converted angle or energy """ @@ -615,19 +617,14 @@ class Mo1Bragg(Device, PositionerBase): raise TimeoutError( f"Timeout after {self.timeout_for_pvwait} while waiting for calc done," ) - time.sleep(0.25) # Needed due to update frequency of softIOC + time.sleep(0.25) # Needed due to update frequency of softIOC if mode == "AngleToEnergy": return self.calculator.calc_energy.get() elif mode == "EnergyToAngle": return self.calculator.calc_angle.get() def set_advanced_xas_settings( - self, - low: float, - high:float, - scan_time: float, - p_kink: float, - e_kink: float + self, low: float, high: float, scan_time: float, p_kink: float, e_kink: float ) -> None: """Set Advanced XAS parameters for upcoming scan. @@ -654,8 +651,8 @@ class Mo1Bragg(Device, PositionerBase): pos, vel, dt = compute_spline( low_deg=low_deg, high_deg=high_deg, - p_kink =p_kink, - e_kink_deg = e_kink_deg, + p_kink=p_kink, + e_kink_deg=e_kink_deg, scan_time=scan_time, ) @@ -715,7 +712,7 @@ class Mo1Bragg(Device, PositionerBase): def kickoff(self): """Kickoff the device, called from BEC.""" scan_duration = self.scan_control.scan_duration.get() - #TODO implement better logic for infinite scans, at least bring it up with Debye + # TODO implement better logic for infinite scans, at least bring it up with Debye start_func = ( self.scan_control.scan_start_infinite.put if scan_duration < 0.1 @@ -797,15 +794,15 @@ class Mo1Bragg(Device, PositionerBase): self.set_scan_control_settings( mode=ScanControlMode.SIMPLE, scan_duration=self.scan_parameter.scan_duration ) - elif scan_name == "xas_simple_scan_with_trig": + elif scan_name == "xas_simple_scan_with_xrd": self.set_xas_settings( low=self.scan_parameter.start, high=self.scan_parameter.stop, scan_time=self.scan_parameter.scan_time, ) self.set_trig_settings( - enable_low=self.scan_parameter.trig_enable_low, - enable_high=self.scan_parameter.trig_enable_high, + enable_low=self.scan_parameter.xrd_enable_low, # enable_low=self.scan_parameter.trig_enable_low, + enable_high=self.scan_parameter.xrd_enable_high, # enable_high=self.scan_parameter.trig_enable_high, exp_time_low=self.scan_parameter.exp_time_low, exp_time_high=self.scan_parameter.exp_time_high, cycle_low=self.scan_parameter.cycle_low, @@ -833,7 +830,7 @@ class Mo1Bragg(Device, PositionerBase): self.set_scan_control_settings( mode=ScanControlMode.ADVANCED, scan_duration=self.scan_parameter.scan_duration ) - elif scan_name == "xas_advanced_scan_with_trig": + elif scan_name == "xas_advanced_scan_with_xrd": self.set_advanced_xas_settings( low=self.scan_parameter.start, high=self.scan_parameter.stop, @@ -842,8 +839,8 @@ class Mo1Bragg(Device, PositionerBase): e_kink=self.scan_parameter.e_kink, ) self.set_trig_settings( - enable_low=self.scan_parameter.trig_enable_low, - enable_high=self.scan_parameter.trig_enable_high, + enable_low=self.scan_parameter.xrd_enable_low, # enable_low=self.scan_parameter.trig_enable_low, + enable_high=self.scan_parameter.xrd_enable_high, # enable_high=self.scan_parameter.trig_enable_high, exp_time_low=self.scan_parameter.exp_time_low, exp_time_high=self.scan_parameter.exp_time_high, cycle_low=self.scan_parameter.cycle_low, diff --git a/tests/tests_devices/test_mo1_bragg.py b/tests/tests_devices/test_mo1_bragg.py index 174c463..9cb9d80 100644 --- a/tests/tests_devices/test_mo1_bragg.py +++ b/tests/tests_devices/test_mo1_bragg.py @@ -150,26 +150,22 @@ def test_set_xas_settings(mock_bragg): assert dev.scan_settings.s_scan_scantime.get() == 1 -def test_set_xrd_settings(mock_bragg): +def test_set_trig_settings(mock_bragg): dev = mock_bragg - dev.set_xrd_settings( + dev.set_trig_settings( enable_low=True, enable_high=False, - num_trigger_low=1, - num_trigger_high=7, - exp_time_low=1, - exp_time_high=3, + exp_time_high=0.1, + exp_time_low=0.01, cycle_low=1, - cycle_high=5, + cycle_high=3, ) - assert dev.scan_settings.xrd_enable_lo_enum.get() == True - assert dev.scan_settings.xrd_enable_hi_enum.get() == False - assert dev.scan_settings.xrd_n_trigger_lo.get() == 1 - assert dev.scan_settings.xrd_n_trigger_hi.get() == 7 - assert dev.scan_settings.xrd_time_lo.get() == 1 - assert dev.scan_settings.xrd_time_hi.get() == 3 - assert dev.scan_settings.xrd_every_n_lo.get() == 1 - assert dev.scan_settings.xrd_every_n_hi.get() == 5 + assert dev.scan_settings.trig_ena_lo_enum.get() == True + assert dev.scan_settings.trig_ena_hi_enum.get() == False + assert dev.scan_settings.trig_every_n_lo.get() == 1 + assert dev.scan_settings.trig_every_n_hi.get() == 3 + assert dev.scan_settings.trig_time_lo.get() == 0.01 + assert dev.scan_settings.trig_time_hi.get() == 0.1 def test_set_control_settings(mock_bragg): @@ -437,7 +433,7 @@ def test_stage(mock_bragg, scan_worker_mock, msg): mock.patch.object( mock_bragg, "set_advanced_xas_settings" ) as mock_advanced_xas_settings, - mock.patch.object(mock_bragg, "set_xrd_settings") as mock_xrd_settings, + mock.patch.object(mock_bragg, "set_trig_settings") as mock_trig_settings, mock.patch.object( mock_bragg, "set_scan_control_settings" ) as mock_set_scan_control_settings, @@ -450,11 +446,9 @@ def test_stage(mock_bragg, scan_worker_mock, msg): high=scan_status_msg.content["info"]["kwargs"]["stop"], scan_time=scan_status_msg.content["info"]["kwargs"]["scan_time"], ) - assert mock_xrd_settings.call_args == mock.call( + assert mock_trig_settings.call_args == mock.call( enable_low=False, enable_high=False, - num_trigger_low=0, - num_trigger_high=0, exp_time_low=0, exp_time_high=0, cycle_low=0, @@ -474,17 +468,11 @@ def test_stage(mock_bragg, scan_worker_mock, msg): high=scan_status_msg.content["info"]["kwargs"]["stop"], scan_time=scan_status_msg.content["info"]["kwargs"]["scan_time"], ) - assert mock_xrd_settings.call_args == mock.call( + assert mock_trig_settings.call_args == mock.call( enable_low=scan_status_msg.content["info"]["kwargs"]["xrd_enable_low"], enable_high=scan_status_msg.content["info"]["kwargs"][ "xrd_enable_high" ], - num_trigger_low=scan_status_msg.content["info"]["kwargs"][ - "num_trigger_low" - ], - num_trigger_high=scan_status_msg.content["info"]["kwargs"][ - "num_trigger_high" - ], exp_time_low=scan_status_msg.content["info"]["kwargs"]["exp_time_low"], exp_time_high=scan_status_msg.content["info"]["kwargs"][ "exp_time_high" @@ -508,11 +496,9 @@ def test_stage(mock_bragg, scan_worker_mock, msg): p_kink=scan_status_msg.content["info"]["kwargs"]["p_kink"], e_kink=scan_status_msg.content["info"]["kwargs"]["e_kink"], ) - assert mock_xrd_settings.call_args == mock.call( + assert mock_trig_settings.call_args == mock.call( enable_low=False, enable_high=False, - num_trigger_low=0, - num_trigger_high=0, exp_time_low=0, exp_time_high=0, cycle_low=0, @@ -534,17 +520,11 @@ def test_stage(mock_bragg, scan_worker_mock, msg): p_kink=scan_status_msg.content["info"]["kwargs"]["p_kink"], e_kink=scan_status_msg.content["info"]["kwargs"]["e_kink"], ) - assert mock_xrd_settings.call_args == mock.call( + assert mock_trig_settings.call_args == mock.call( enable_low=scan_status_msg.content["info"]["kwargs"]["xrd_enable_low"], enable_high=scan_status_msg.content["info"]["kwargs"][ "xrd_enable_high" ], - num_trigger_low=scan_status_msg.content["info"]["kwargs"][ - "num_trigger_low" - ], - num_trigger_high=scan_status_msg.content["info"]["kwargs"][ - "num_trigger_high" - ], exp_time_low=scan_status_msg.content["info"]["kwargs"]["exp_time_low"], exp_time_high=scan_status_msg.content["info"]["kwargs"][ "exp_time_high"