From a45aa094ef0bc87c340a05f414661d00a97371a7 Mon Sep 17 00:00:00 2001 From: appel_c Date: Wed, 11 Feb 2026 08:52:38 +0100 Subject: [PATCH] refactor(ddg1): Use mcs acquiring status to resolve trigger of DDG1 --- .../epics/delay_generator_csaxs/ddg_1.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/csaxs_bec/devices/epics/delay_generator_csaxs/ddg_1.py b/csaxs_bec/devices/epics/delay_generator_csaxs/ddg_1.py index 6090454..994fd38 100644 --- a/csaxs_bec/devices/epics/delay_generator_csaxs/ddg_1.py +++ b/csaxs_bec/devices/epics/delay_generator_csaxs/ddg_1.py @@ -135,6 +135,7 @@ class DDG1(PSIDeviceBase, DelayGeneratorCSAXS): USER_ACCESS = ["keep_shutter_open_during_scan", "set_trigger"] + # TODO Consider using the 'fsh' device instead. fast_shutter_readback = Cpt( EpicsSignalRO, read_pv="X12SA-ES1-TTL:INP_01", @@ -513,14 +514,14 @@ class DDG1(PSIDeviceBase, DelayGeneratorCSAXS): """ self._stop_polling() self._poll_thread_poll_loop_done.wait(timeout=1) - time.sleep(0.02) - # TODO This may move to scan modifiers + + # NOTE If the trigger source is not SINGLE_SHOT, the DDG is triggered by an external source + # thus we can not expect that trigger signals are meant to be awaited for. In this case, + # we can directly return. if self.trigger_source.get() != TRIGGERSOURCE.SINGLE_SHOT.value: status = StatusBase(obj=self) status.set_finished() return status - # NOTE: This sleep is important to ensure that the HW is ready to process new commands. - # It has been empirically determined after long testing that this improves stability. # NOTE If the MCS card is present in the current session of BEC, # we prepare the card for the next trigger. The procedure is implemented @@ -536,11 +537,12 @@ class DDG1(PSIDeviceBase, DelayGeneratorCSAXS): # be investigated why the EPICS interface is slow to respond. status_mcs.wait(timeout=3) - if self.fast_shutter_control.get() == 0: - # Shutter is not kept open, we can rely on the shutter readback signal - status = TransitionStatus( - self.fast_shutter_readback, [1, 0] - ) # Wait for shutter to transition from open (1) to close (0) + # NOTE If the MCS card is present, we may also use its signal wait for the burst cycle to finish. + # This is True for any non-fly scans, as for fly scans the MCS card will not receive the additional + # trigger pulse from the ef delay pair, check on_stage. + if mcs is not None and mcs.enabled and self.scan_info.msg.scan_type != "fly": + # We can use the acquiring signal of the MCS card to check if the burst cycle is finished. + status = TransitionStatus(mcs.acquiring, [ACQUIRING.ACQUIRING, ACQUIRING.DONE]) else: # NOTE This sleep is needed for 20ms to make sure that the HW of the DDG is # again ready to process new commands. It was transferred from just after the