bluesky / ophyd

hardware abstraction in Python with an emphasis on EPICS
https://blueskyproject.io/ophyd
BSD 3-Clause "New" or "Revised" License
49 stars 78 forks source link

Make StandardReadable into generic PluggableDevice #1144

Open coretl opened 1 year ago

coretl commented 1 year ago

This means we can write more complicated "plugs" for things like areaDetector filewriting, and form our classes by composition. For instance I imagine something like:

class PilatusArmingLogic:
    def __init__(self, device: PluggableDevice, drv: PilatusDriver):
        self.drv = drv
        add_readable_signals(device, config=[drv.acquire_time])
        # so flyscans can find the right logic for a device
        register_det_logic(self, device)
        device.add_plug(stage=self.setup, trigger=self.arm)

    @AsyncStatus.wrap
    def setup(self) -> None:
        await self.drv.wait_for_plugins.set(True)

    @AsyncStatus.wrap
    def arm(self, num_images: Optional[int] = None):
        await arm_ad_driver(self.drv, num_images)

    async def get_deadtime(self, exposure: float) -> float:
        # Just for flyscans
        # Might need to prod the driver to do these calcs
        return calc_deadtime(exposure, readout_time=0.02, frequency_accuracy=50)

class MyDetector(PluggableDevice):
    def __init__(self, prefix: str, settings: Dict[str, Any], name: Optional[str] = None):      
        self.drv = PilatusDriver(prefix + ":DRV")
        PilatusArmingLogic(self, self.drv,)
        self.hdf = NDFileHDF(prefix + ":HDF")
        HDFStreamingLogic(self, self.hdf)
        self.stat = NDFileStats(prefix + ":STAT")
        add_readable_signals(self, read=[self.stat.min, self.stat.max, self.stat.mean])
        self.add_plug(stage=SettingsLoader(self, settings)
        super().__init__(name)
coretl commented 1 year ago

Linting won't pass until https://github.com/bluesky/bluesky/pull/1590