From a7d713b50d7b65f39f4975cfecb2159cb6a87a6c Mon Sep 17 00:00:00 2001 From: appel_c Date: Sun, 12 Nov 2023 16:41:08 +0100 Subject: [PATCH] refactor: add configurable timeout and ClassInitError --- ophyd_devices/epics/devices/eiger9m_csaxs.py | 23 ++++++++++---------- ophyd_devices/epics/devices/falcon_csaxs.py | 12 +++++----- ophyd_devices/epics/devices/pilatus_csaxs.py | 8 +++---- tests/test_eiger9m_csaxs.py | 5 +++++ tests/test_falcon_csaxs.py | 2 ++ tests/test_pilatus_csaxs.py | 4 ++++ 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/ophyd_devices/epics/devices/eiger9m_csaxs.py b/ophyd_devices/epics/devices/eiger9m_csaxs.py index 812486d..09651dc 100644 --- a/ophyd_devices/epics/devices/eiger9m_csaxs.py +++ b/ophyd_devices/epics/devices/eiger9m_csaxs.py @@ -38,7 +38,7 @@ class EigerTimeoutError(EigerError): pass -class DeviceClassInitError(EigerError): +class EigerInitError(EigerError): """Raised when initiation of the device class fails, due to missing device manager or not started in sim_mode.""" @@ -141,7 +141,7 @@ class Eiger9McSAXS(DetectorBase): **kwargs, ) if device_manager is None and not sim_mode: - raise DeviceClassInitError( + raise EigerInitError( f"No device manager for device: {name}, and not started sim_mode: {sim_mode}. Add DeviceManager to initialization or init with sim_mode=True" ) self.sim_mode = sim_mode @@ -158,6 +158,7 @@ class Eiger9McSAXS(DetectorBase): kwargs["file_writer_url"] if "file_writer_url" in kwargs else "http://xbl-daq-29:5000" ) self.wait_for_connection(all_signals=True) + self.timeout = 5 if not sim_mode: self._update_service_config() self.device_manager = device_manager @@ -223,16 +224,16 @@ class Eiger9McSAXS(DetectorBase): """ self.std_client = StdDaqClient(url_base=self.std_rest_server_url) self.std_client.stop_writer() - timeout = 0 + timer = 0 # TODO put back change of e-account! and check with Leo which status to wait for eacc = self.scaninfo.username self._update_std_cfg("writer_user_id", int(eacc.strip(" e"))) time.sleep(5) while not self.std_client.get_status()["state"] == "READY": time.sleep(0.1) - timeout = timeout + 0.1 + timer = timer + 0.1 logger.info("Waiting for std_daq init.") - if timeout > 5: + if timer > self.timeout: if not self.std_client.get_status()["state"] == "READY": raise EigerError( f"Std client not in READY state, returns: {self.std_client.get_status()}" @@ -296,7 +297,7 @@ class Eiger9McSAXS(DetectorBase): while not os.path.exists(os.path.dirname(self.filepath)): timer = time + 0.1 time.sleep(0.1) - if timer > 3: + if timer > self.timeout: raise EigerError(f"Timeout of 3s reached for filepath {self.filepath}") # TODO function for abstract class? @@ -331,7 +332,7 @@ class Eiger9McSAXS(DetectorBase): if det_ctrl == "WAITING_IMAGES": break time.sleep(0.01) - if timer > 5: + if timer > self.timeout: self._close_file_writer() raise EigerError( f"Timeout of 5s reached for std_daq start_writer_async with std_daq client status {det_ctrl}" @@ -479,7 +480,6 @@ class Eiger9McSAXS(DetectorBase): - _stop_file_writer """ sleep_time = 0.1 - timeout = 5 timer = 0 # Check status with timeout, break out if _stopped=True while True: @@ -494,7 +494,7 @@ class Eiger9McSAXS(DetectorBase): break time.sleep(sleep_time) timer += sleep_time - if timer > timeout: + if timer > self.timeout: self._stopped == True self._stop_det() self._stop_file_writer() @@ -508,7 +508,6 @@ class Eiger9McSAXS(DetectorBase): """Stop the detector and wait for the proper status message""" elapsed_time = 0 sleep_time = 0.01 - timeout = 5 # Stop acquisition self.cam.acquire.put(0) retry = False @@ -521,11 +520,11 @@ class Eiger9McSAXS(DetectorBase): break time.sleep(sleep_time) elapsed_time += sleep_time - if elapsed_time > timeout // 2 and not retry: + if elapsed_time > self.timeout // 2 and not retry: retry = True # Retry to stop acquisition self.cam.acquire.put(0) - if elapsed_time > timeout: + if elapsed_time > self.timeout: raise EigerTimeoutError("Failed to stop the acquisition. IOC did not update.") def stop(self, *, success=False) -> None: diff --git a/ophyd_devices/epics/devices/falcon_csaxs.py b/ophyd_devices/epics/devices/falcon_csaxs.py index 5477f85..49dd5d4 100644 --- a/ophyd_devices/epics/devices/falcon_csaxs.py +++ b/ophyd_devices/epics/devices/falcon_csaxs.py @@ -35,7 +35,7 @@ class FalconTimeoutError(FalconError): pass -class DeviceClassInitError(FalconError): +class FalconInitError(FalconError): """Raised when initiation of the device class fails, due to missing device manager or not started in sim_mode.""" @@ -193,7 +193,7 @@ class FalconcSAXS(Device): **kwargs, ) if device_manager is None and not sim_mode: - raise DeviceClassInitError( + raise FalconInitError( f"No device manager for device: {name}, and not started sim_mode: {sim_mode}. Add DeviceManager to initialization or init with sim_mode=True" ) self.sim_mode = sim_mode @@ -205,6 +205,7 @@ class FalconcSAXS(Device): self.readout_time_min = FALCON_MIN_READOUT self._value_pixel_per_buffer = None self.readout_time = None + self.timeout = 5 self.wait_for_connection(all_signals=True) if not sim_mode: self._update_service_config() @@ -269,7 +270,7 @@ class FalconcSAXS(Device): break time.sleep(0.01) timer += 0.01 - if timer > 5: + if timer > self.timeout: raise FalconTimeoutError("Failed to stop the detector. IOC did not update.") def _stop_file_writer(self) -> None: @@ -412,7 +413,7 @@ class FalconcSAXS(Device): break time.sleep(0.01) timer += 0.01 - if timer > 5: + if timer > self.timeout: self.stop() raise FalconTimeoutError("Failed to arm the acquisition. IOC did not update.") @@ -465,7 +466,6 @@ class FalconcSAXS(Device): - _stop_file_writer """ sleep_time = 0.1 - timeout = 5 timer = 0 while True: det_ctrl = self.state.read()[self.state.name]["value"] @@ -480,7 +480,7 @@ class FalconcSAXS(Device): break time.sleep(sleep_time) timer += sleep_time - if timer > timeout: + if timer > self.timeout: # self._stop_det() # self._stop_file_writer() logger.info( diff --git a/ophyd_devices/epics/devices/pilatus_csaxs.py b/ophyd_devices/epics/devices/pilatus_csaxs.py index 228e1d9..098d9f1 100644 --- a/ophyd_devices/epics/devices/pilatus_csaxs.py +++ b/ophyd_devices/epics/devices/pilatus_csaxs.py @@ -37,7 +37,7 @@ class PilatusTimeoutError(PilatusError): pass -class DeviceClassInitError(PilatusError): +class PilatusInitError(PilatusError): """Raised when initiation of the device class fails, due to missing device manager or not started in sim_mode.""" @@ -134,7 +134,7 @@ class PilatuscSAXS(DetectorBase): **kwargs, ) if device_manager is None and not sim_mode: - raise DeviceClassInitError( + raise PilatusInitError( f"No device manager for device: {name}, and not started sim_mode: {sim_mode}. Add DeviceManager to initialization or init with sim_mode=True" ) self.sim_mode = sim_mode @@ -145,7 +145,7 @@ class PilatuscSAXS(DetectorBase): self.scaninfo = None self.filewriter = None self.readout_time_min = PILATUS_MIN_READOUT - # TODO move url from data backend up here? + self.timeout = 5 self.wait_for_connection(all_signals=True) if not sim_mode: self._update_service_config() @@ -523,7 +523,7 @@ class PilatuscSAXS(DetectorBase): break time.sleep(sleep_time) timer = timer + sleep_time - if timer > 5: + if timer > self.timeout: self._stopped == True self._stop_det() self._stop_file_writer() diff --git a/tests/test_eiger9m_csaxs.py b/tests/test_eiger9m_csaxs.py index a7edeef..4616fab 100644 --- a/tests/test_eiger9m_csaxs.py +++ b/tests/test_eiger9m_csaxs.py @@ -105,6 +105,7 @@ def test_init_detector( mock_det.cam.detector_state._read_pv.mock_data = detector_state if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det._init_detector() else: mock_det._init_detector() # call the method you want to test @@ -183,6 +184,7 @@ def test_init_filewriter(mock_det, eacc, exp_url, daq_status, daq_cfg, expected_ # scaninfo.username.return_value = eacc if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det._init_filewriter() else: mock_det._init_filewriter() @@ -270,6 +272,7 @@ def test_stage( mock_det.filepath = scaninfo["filepath"] if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det.stage() else: mock_det.stage() @@ -340,6 +343,7 @@ def test_prep_file_writer(mock_det, scaninfo, daq_status, expected_exception): if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det._prep_file_writer() mock_file_path_exists.assert_called_once() assert mock_stop_file_writer.call_count == 2 @@ -494,6 +498,7 @@ def test_finished(mock_det, stopped, cam_state, daq_status, scaninfo, expected_e mock_det.scaninfo.frames_per_trigger = scaninfo["frames_per_trigger"] if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det._finished() assert mock_det._stopped == stopped mock_stop_file_friter.assert_called() diff --git a/tests/test_falcon_csaxs.py b/tests/test_falcon_csaxs.py index ed4da8e..29c6ee2 100644 --- a/tests/test_falcon_csaxs.py +++ b/tests/test_falcon_csaxs.py @@ -75,6 +75,7 @@ def test_init_detector( mock_det.state._read_pv.mock_data = detector_state if expected_exception: with pytest.raises(FalconTimeoutError): + mock_det.timeout = 0.1 mock_det._init_detector() else: mock_det._init_detector() # call the method you want to test @@ -241,6 +242,7 @@ def test_arm_acquisition(mock_det, detector_state, expected_exception): mock_det.state._read_pv.mock_data = detector_state if expected_exception: with pytest.raises(FalconTimeoutError): + mock_det.timeout = 0.1 mock_det._arm_acquisition() mock_stop.assert_called_once() else: diff --git a/tests/test_pilatus_csaxs.py b/tests/test_pilatus_csaxs.py index cc5e55e..1854d12 100644 --- a/tests/test_pilatus_csaxs.py +++ b/tests/test_pilatus_csaxs.py @@ -120,6 +120,7 @@ def test_stage( mock_det.filepath = scaninfo["filepath"] if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det.stage() else: mock_det.stage() @@ -241,6 +242,7 @@ def test_stop_file_writer(mock_det, requests_state, expected_exception, url): instance.raise_for_status.side_effect = Exception if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det._stop_file_writer() mock_send_requests_put.assert_called_once_with(url=url) instance.raise_for_status.called_once() @@ -376,6 +378,7 @@ def test_prep_file_writer(mock_det, scaninfo, data_msgs, urls, requests_state, e if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det._prep_file_writer() mock_close_file_writer.assert_called_once() mock_stop_file_writer.assert_called_once() @@ -490,6 +493,7 @@ def test_finished(mock_det, stopped, mcs_stage_state, expected_exception): mock_det._stopped = stopped if expected_exception: with pytest.raises(Exception): + mock_det.timeout = 0.1 mock_det._finished() assert mock_det._stopped == stopped mock_stop_file_friter.assert_called()