From cfca527395795c94cb4ef01ff00305e81a1f5584 Mon Sep 17 00:00:00 2001 From: "Ware, Joseph (DLSLtd,RAL,LSCI)" Date: Thu, 11 Apr 2024 11:02:19 +0100 Subject: [PATCH] Make AravisDetector facility generic --- src/ophyd_async/epics/areadetector/aravis.py | 10 +++-- .../controllers/aravis_controller.py | 8 +--- .../areadetector/drivers/aravis_driver.py | 5 ++- tests/conftest.py | 7 ++++ tests/epics/areadetector/test_aravis.py | 40 +++++++++++-------- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/ophyd_async/epics/areadetector/aravis.py b/src/ophyd_async/epics/areadetector/aravis.py index 051c8fa49e..a2edbed8b0 100644 --- a/src/ophyd_async/epics/areadetector/aravis.py +++ b/src/ophyd_async/epics/areadetector/aravis.py @@ -27,14 +27,16 @@ class ADAravisDetector(StandardDetector, HasHints): def __init__( self, prefix: str, - directory_provider: DirectoryProvider, name: str, + directory_provider: DirectoryProvider, + driver: ADAravisDriver, + hdf: NDFileHDF, gpio_number: ADAravisController.GPIO_NUMBER = 1, **scalar_sigs: str, ): # Must be child of Detector to pick up connect() - self.drv = ADAravisDriver(prefix + "DET:") - self.hdf = NDFileHDF(prefix + "HDF5:") + self.drv = driver + self.hdf = hdf super().__init__( ADAravisController(self.drv, gpio_number=gpio_number), @@ -50,7 +52,7 @@ def __init__( ) async def _prepare(self, value: TriggerInfo) -> None: - await self._controller._fetch_deadtime() + await self.drv._fetch_deadtime() await super()._prepare(value) def get_external_trigger_gpio(self): diff --git a/src/ophyd_async/epics/areadetector/controllers/aravis_controller.py b/src/ophyd_async/epics/areadetector/controllers/aravis_controller.py index 27de15d253..4175a16df6 100644 --- a/src/ophyd_async/epics/areadetector/controllers/aravis_controller.py +++ b/src/ophyd_async/epics/areadetector/controllers/aravis_controller.py @@ -24,13 +24,9 @@ class ADAravisController(DetectorControl): def __init__(self, driver: ADAravisDriver, gpio_number: GPIO_NUMBER) -> None: self._drv = driver self.gpio_number = gpio_number - self.dead_time: Optional[float] = None def get_deadtime(self, exposure: float) -> float: - return self.dead_time or 0 - - async def _fetch_deadtime(self) -> None: - self.dead_time = await self._drv._fetch_deadtime() + return self._drv.dead_time or 0 async def arm( self, @@ -76,7 +72,7 @@ def _get_trigger_info( else: return ( ADAravisTriggerMode.on, - ADAravisTriggerSource(f"line_{self.gpio_number}"), + ADAravisTriggerSource[f"line_{self.gpio_number}"], ) async def disarm(self): diff --git a/src/ophyd_async/epics/areadetector/drivers/aravis_driver.py b/src/ophyd_async/epics/areadetector/drivers/aravis_driver.py index be402e1272..9b3a9fa6de 100644 --- a/src/ophyd_async/epics/areadetector/drivers/aravis_driver.py +++ b/src/ophyd_async/epics/areadetector/drivers/aravis_driver.py @@ -1,6 +1,6 @@ from enum import Enum from math import nan -from typing import Callable, Dict, Tuple +from typing import Callable, Dict, Optional, Tuple from ophyd_async.epics.areadetector.drivers import ADBase from ophyd_async.epics.areadetector.utils import ( @@ -147,10 +147,11 @@ def __init__(self, prefix: str, name: str = "") -> None: self.trigger_source = ad_rw(ADAravisTriggerSource, prefix + "TriggerSource") self.model = ad_r(str, prefix + "Model") self.pixel_format = ad_rw(str, prefix + "PixelFormat") + self.dead_time: Optional[float] = None super().__init__(prefix, name=name) async def _fetch_deadtime(self) -> float: # All known in-use version B/C have same deadtime as non-B/C model: str = (await self.model.get_value()).removesuffix("B").removesuffix("C") pixel_format: str = await self.pixel_format.get_value() - return _deadtimes.get(model, lambda _: nan)(pixel_format) + self.dead_time = _deadtimes.get(model, lambda _: nan)(pixel_format) diff --git a/tests/conftest.py b/tests/conftest.py index f21d0094e1..8ad22d6a9f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,8 @@ from pathlib import Path from typing import Any, Callable +from ophyd_async.core import StaticDirectoryProvider + import pytest from bluesky.run_engine import RunEngine, TransitionError @@ -89,3 +91,8 @@ async def inner_coroutine(): raise ValueError() return inner_coroutine + + +@pytest.fixture +def static_directory_provider(tmp_path: Path): + return StaticDirectoryProvider(directory_path=tmp_path) diff --git a/tests/epics/areadetector/test_aravis.py b/tests/epics/areadetector/test_aravis.py index af43b86f37..aded79ac21 100644 --- a/tests/epics/areadetector/test_aravis.py +++ b/tests/epics/areadetector/test_aravis.py @@ -10,8 +10,12 @@ set_sim_value, ) from ophyd_async.epics.areadetector.aravis import ADAravisDetector -from ophyd_async.epics.areadetector.controllers.aravis_controller import ADAravisController -from ophyd_async.epics.areadetector.drivers.aravis_driver import ADAravisDriver, ADAravisTriggerSource +from ophyd_async.epics.areadetector.drivers.aravis_driver import ( + ADAravisDriver, + ADAravisTriggerSource, +) +from ophyd_async.epics.areadetector.writers.nd_file_hdf import NDFileHDF + @pytest.fixture async def adaravis_driver(RE: RunEngine) -> ADAravisDriver: @@ -22,24 +26,27 @@ async def adaravis_driver(RE: RunEngine) -> ADAravisDriver: @pytest.fixture -async def adaravis_controller( - RE: RunEngine, adaravis_driver: ADAravisDriver -) -> ADAravisController: +async def hdf(RE: RunEngine) -> NDFileHDF: async with DeviceCollector(sim=True): - controller = ADAravisController(adaravis_driver, gpio_number=1) + hdf = NDFileHDF("HDF:") - return controller + return hdf @pytest.fixture async def adaravis( - RE: RunEngine, static_directory_provider: DirectoryProvider + RE: RunEngine, + static_directory_provider: DirectoryProvider, + adaravis_driver: ADAravisDriver, + hdf: NDFileHDF, ) -> ADAravisDetector: async with DeviceCollector(sim=True): adaravis = ADAravisDetector( "ADARAVIS:", + "adaravis", static_directory_provider, - name="adaravis", + driver=adaravis_driver, + hdf=hdf, ) return adaravis @@ -65,16 +72,15 @@ async def test_deadtime_read_from_file( model: str, pixel_format: str, deadtime: float, - adaravis_controller: ADAravisController, + adaravis: ADAravisDetector, ): - set_sim_value(adaravis_controller._drv.model, model) - set_sim_value(adaravis_controller._drv.pixel_format, pixel_format) + set_sim_value(adaravis.drv.model, model) + set_sim_value(adaravis.drv.pixel_format, pixel_format) + await adaravis.drv._fetch_deadtime() # deadtime invariant with exposure time - await adaravis_controller._fetch_deadtime() - assert adaravis_controller.get_deadtime(0) == deadtime - await adaravis_controller._fetch_deadtime() - assert adaravis_controller.get_deadtime(500) == deadtime + assert adaravis.controller.get_deadtime(0) == deadtime + assert adaravis.controller.get_deadtime(500) == deadtime async def test_trigger_source_set_to_gpio_line(adaravis: ADAravisDetector): @@ -126,6 +132,8 @@ async def test_hints_from_hdf_writer(adaravis: ADAravisDetector): async def test_unsupported_trigger_excepts(adaravis: ADAravisDetector): + set_sim_value(adaravis.drv.model, "Manta G-125") + set_sim_value(adaravis.drv.pixel_format, "Mono12Packed") with pytest.raises( ValueError, # str(EnumClass.value) handling changed in Python 3.11