diff --git a/src/ophyd_async/fastcs/eiger/_eiger.py b/src/ophyd_async/fastcs/eiger/_eiger.py index 5b49101edf..051b516826 100644 --- a/src/ophyd_async/fastcs/eiger/_eiger.py +++ b/src/ophyd_async/fastcs/eiger/_eiger.py @@ -1,8 +1,6 @@ from ophyd_async.core import ( - AsyncStatus, PathProvider, StandardDetector, - TriggerInfo, ) from ophyd_async.epics.odin import Odin, OdinWriter @@ -29,7 +27,7 @@ def __init__( self.odin = Odin(prefix + hdf_suffix, nodes=odin_nodes) super().__init__( - EigerController(self.drv), + EigerController(self.drv, self.odin), OdinWriter( path_provider, self.odin, @@ -37,7 +35,3 @@ def __init__( ), name=name, ) - - @AsyncStatus.wrap - async def prepare(self, value: TriggerInfo) -> None: - await super().prepare(value) diff --git a/src/ophyd_async/fastcs/eiger/_eiger_controller.py b/src/ophyd_async/fastcs/eiger/_eiger_controller.py index b36641ff51..37401a9c86 100644 --- a/src/ophyd_async/fastcs/eiger/_eiger_controller.py +++ b/src/ophyd_async/fastcs/eiger/_eiger_controller.py @@ -7,6 +7,7 @@ TriggerInfo, wait_for_value, ) +from ophyd_async.epics.odin import Odin from ._eiger_io import EigerDriverIO, EigerTriggerMode @@ -19,11 +20,9 @@ class EigerController(DetectorController): - def __init__( - self, - driver: EigerDriverIO, - ) -> None: + def __init__(self, driver: EigerDriverIO, odin: Odin) -> None: self._drv = driver + self._odin = odin def get_deadtime(self, exposure: float | None) -> float: # See https://media.dectris.com/filer_public/30/14/3014704e-5f3b-43ba-8ccf-8ef720e60d2a/240202_usermanual_eiger2.pdf @@ -60,6 +59,8 @@ async def arm(self): # but will return after the Eiger has completed arming in 0.9.0. # https://github.com/DiamondLightSource/FastCS/pull/141 await self._drv.detector.arm.trigger(timeout=DEFAULT_TIMEOUT) + # Wait for Odin fan to be ready after arming Eiger + await wait_for_value(self._odin.fan_ready, 1, DEFAULT_TIMEOUT) async def wait_for_idle(self): await wait_for_value(self._drv.detector.state, "idle", timeout=DEFAULT_TIMEOUT) diff --git a/tests/unit_tests/fastcs/eiger/test_eiger_controller.py b/tests/unit_tests/fastcs/eiger/test_eiger_controller.py index 892fb236fb..d728ecdd81 100644 --- a/tests/unit_tests/fastcs/eiger/test_eiger_controller.py +++ b/tests/unit_tests/fastcs/eiger/test_eiger_controller.py @@ -6,6 +6,7 @@ TriggerInfo, init_devices, ) +from ophyd_async.epics.odin import Odin from ophyd_async.fastcs.eiger import EigerController, EigerDriverIO from ophyd_async.testing import ( callback_on_mock_put, @@ -21,13 +22,16 @@ def eiger_driver_and_controller_no_arm(RE) -> DriverAndController: with init_devices(mock=True): driver = EigerDriverIO("") - controller = EigerController(driver) + odin = Odin("") + controller = EigerController(driver, odin) - def become_idle_after_arm(*args, **kwargs): + def complete_arming(*args, **kwargs): + # Mocking that Odin fan is ready + set_mock_value(odin.fan_ready, True) # Mocking that eiger has armed and finished taking frames. set_mock_value(driver.detector.state, "idle") - callback_on_mock_put(driver.detector.arm, become_idle_after_arm) + callback_on_mock_put(driver.detector.arm, complete_arming) return driver, controller diff --git a/tests/unit_tests/fastcs/eiger/test_eiger_detector.py b/tests/unit_tests/fastcs/eiger/test_eiger_detector.py index 3ed0f4e513..24ada1bafa 100644 --- a/tests/unit_tests/fastcs/eiger/test_eiger_detector.py +++ b/tests/unit_tests/fastcs/eiger/test_eiger_detector.py @@ -18,6 +18,11 @@ def set_meta_filename_and_id(value, *args, **kwargs): callback_on_mock_put(detector.odin.file_name, set_meta_filename_and_id) + def set_odin_fan_ready(value, *args, **kwargs): + set_mock_value(detector.odin.fan_ready, 1) + + callback_on_mock_put(detector.drv.detector.arm, set_odin_fan_ready) + detector._writer._path_provider.return_value.filename = "filename.h5" # type: ignore set_mock_value(detector.odin.meta_active, "Active") @@ -43,3 +48,17 @@ async def test_when_prepared_eiger_bit_depth_is_passed_and_set_in_odin(detector) get_mock_put(detector.odin.data_type).assert_called_once_with( f"UInt{expected_datatype}", wait=True ) + + +async def test_when_kickoff_called_odin_fan_waited_for( + detector, +): + await detector.prepare( + TriggerInfo( + exposure_timeout=None, + number_of_events=1, + trigger=DetectorTrigger.INTERNAL, + ) + ) + await detector.kickoff() + assert await detector.odin.fan_ready.get_value() == 1