From 22e63c4976eb2c19acc3234ccb8296dbed1b3d22 Mon Sep 17 00:00:00 2001 From: Christian Appel Date: Fri, 20 Oct 2023 15:55:47 +0200 Subject: [PATCH] refactor: add documentation, clean up init function and unify classes --- ophyd_devices/epics/devices/eiger9m_csaxs.py | 32 +++++++++--- ophyd_devices/epics/devices/falcon_csaxs.py | 51 +++++++++++++++----- ophyd_devices/epics/devices/pilatus_csaxs.py | 27 +++++++++-- 3 files changed, 87 insertions(+), 23 deletions(-) diff --git a/ophyd_devices/epics/devices/eiger9m_csaxs.py b/ophyd_devices/epics/devices/eiger9m_csaxs.py index c4d01cd..049fdba 100644 --- a/ophyd_devices/epics/devices/eiger9m_csaxs.py +++ b/ophyd_devices/epics/devices/eiger9m_csaxs.py @@ -83,6 +83,7 @@ class Eiger9mCsaxs(DetectorBase): """ + # Specify which functions are revealed to the user in BEC client USER_ACCESS = [ "describe", ] @@ -102,6 +103,18 @@ class Eiger9mCsaxs(DetectorBase): sim_mode=False, **kwargs, ): + """Initialize the Eiger9M detector + Args: + #TODO add here the parameters for kind, read_attrs, configuration_attrs, parent + prefix (str): PV prefix (X12SA-ES-EIGER9M:) + name (str): 'eiger' + kind (str): + read_attrs (list): + configuration_attrs (list): + parent (object): + device_manager (object): BEC device manager + sim_mode (bool): simulation mode to start the detector without BEC, e.g. from ipython shell + """ super().__init__( prefix=prefix, name=name, @@ -111,13 +124,16 @@ class Eiger9mCsaxs(DetectorBase): parent=parent, **kwargs, ) - self._stopped = False - self._lock = threading.RLock() if device_manager is None and not sim_mode: raise EigerError("Add DeviceManager to initialization or init with sim_mode=True") - + + # Not sure if this is needed, comment it for now! + #self._lock = threading.RLock() + self._stopped = False self.name = name - self.wait_for_connection() # Make sure to be connected before talking to PVs + self.wait_for_connection() + # Spin up connections for simulation or BEC mode + # TODO check if sim_mode still works. Is it needed? I believe filewriting might be handled properly if not sim_mode: from bec_lib.core.bec_service import SERVICE_CONFIG @@ -125,17 +141,17 @@ class Eiger9mCsaxs(DetectorBase): self._producer = self.device_manager.producer self.service_cfg = SERVICE_CONFIG.config["service_config"]["file_writer"] else: + base_path = f"/sls/X12SA/data/{self.scaninfo.username}/Data10/" self._producer = bec_utils.MockProducer() self.device_manager = bec_utils.MockDeviceManager() self.scaninfo = BecScaninfoMixin(device_manager, sim_mode) self.scaninfo.load_scan_metadata() - self.service_cfg = {"base_path": f"/sls/X12SA/data/{self.scaninfo.username}/Data10/"} + self.service_cfg = {"base_path": base_path} + self.scaninfo = BecScaninfoMixin(device_manager, sim_mode) self.scaninfo.load_scan_metadata() - # TODO - self.filepath = "" - self.filewriter = FileWriterMixin(self.service_cfg) + self.reduce_readout = 1e-3 # 3 ms self.triggermode = 0 # 0 : internal, scan must set this if hardware triggered self._init_eiger9m() diff --git a/ophyd_devices/epics/devices/falcon_csaxs.py b/ophyd_devices/epics/devices/falcon_csaxs.py index a2748f8..f753110 100644 --- a/ophyd_devices/epics/devices/falcon_csaxs.py +++ b/ophyd_devices/epics/devices/falcon_csaxs.py @@ -77,29 +77,40 @@ class FalconHDF5Plugins(Device): class FalconCsaxs(Device): - """FalxonX1 with HDF5 writer""" + """Falcon Sitoro detector for CSAXS + + Parent class: Device + Device classes: EpicsDXPFalcon dxp1:, EpicsMCARecord mca1, FalconHDF5Plugins HDF1: + + Attributes: + name str: 'falcon' + prefix (str): PV prefix ("X12SA-SITORO:) + + """ + + # Specify which functions are revealed to the user in BEC client + USER_ACCESS = [ + "describe", + ] dxp = Cpt(EpicsDXPFalcon, "dxp1:") mca = Cpt(EpicsMCARecord, "mca1") hdf5 = Cpt(FalconHDF5Plugins, "HDF1:") - # Control + # specify Epics PVs for Falcon + # TODO consider moving this outside of this class! stop_all = Cpt(EpicsSignal, "StopAll") erase_all = Cpt(EpicsSignal, "EraseAll") start_all = Cpt(EpicsSignal, "StartAll") state = Cpt(EpicsSignal, "Acquiring") - # Preset options preset_mode = Cpt(EpicsSignal, "PresetMode") # 0 No preset 1 Real time 2 Events 3 Triggers preset_real = Cpt(EpicsSignal, "PresetReal") preset_events = Cpt(EpicsSignal, "PresetEvents") preset_triggers = Cpt(EpicsSignal, "PresetTriggers") - # read-only diagnostics triggers = Cpt(EpicsSignalRO, "MaxTriggers", lazy=True) events = Cpt(EpicsSignalRO, "MaxEvents", lazy=True) input_count_rate = Cpt(EpicsSignalRO, "MaxInputCountRate", lazy=True) output_count_rate = Cpt(EpicsSignalRO, "MaxOutputCountRate", lazy=True) - - # Mapping control collect_mode = Cpt(EpicsSignal, "CollectMode") # 0 MCA spectra, 1 MCA mapping pixel_advance_mode = Cpt(EpicsSignal, "PixelAdvanceMode") ignore_gate = Cpt(EpicsSignal, "IgnoreGate") @@ -109,8 +120,6 @@ class FalconCsaxs(Device): pixels_per_run = Cpt(EpicsSignal, "PixelsPerRun") nd_array_mode = Cpt(EpicsSignal, "NDArrayMode") - # HDF5 - def __init__( self, prefix="", @@ -124,6 +133,18 @@ class FalconCsaxs(Device): sim_mode=False, **kwargs, ): + """Initialize Falcon detector + Args: + #TODO add here the parameters for kind, read_attrs, configuration_attrs, parent + prefix (str): PV prefix ("X12SA-SITORO:) + name (str): 'falcon' + kind (str): + read_attrs (list): + configuration_attrs (list): + parent (object): + device_manager (object): BEC device manager + sim_mode (bool): simulation mode to start the detector without BEC, e.g. from ipython shell + """ super().__init__( prefix=prefix, name=name, @@ -137,7 +158,8 @@ class FalconCsaxs(Device): raise FalconError("Add DeviceManager to initialization or init with sim_mode=True") self._stopped = False self.name = name - self.wait_for_connection() # Make sure to be connected before talking to PVs + self.wait_for_connection() + # Spin up connections for simulation or BEC mode if not sim_mode: from bec_lib.core.bec_service import SERVICE_CONFIG @@ -145,15 +167,21 @@ class FalconCsaxs(Device): self._producer = self.device_manager.producer self.service_cfg = SERVICE_CONFIG.config["service_config"]["file_writer"] else: + base_path = f"/sls/X12SA/data/{self.scaninfo.username}/Data10/" self._producer = bec_utils.MockProducer() self.device_manager = bec_utils.MockDeviceManager() self.scaninfo = BecScaninfoMixin(device_manager, sim_mode) self.scaninfo.load_scan_metadata() - self.service_cfg = {"base_path": f"/sls/X12SA/data/{self.scaninfo.username}/Data10/"} + self.service_cfg = {"base_path": base_path} + self.scaninfo = BecScaninfoMixin(device_manager, sim_mode) self.scaninfo.load_scan_metadata() self.filewriter = FileWriterMixin(self.service_cfg) - + self._init_detector() + + def _init_detector(self) -> None: + """Set up detector parameters, init detector, init filewriter + """ self.readout = 0.003 # 3 ms self._value_pixel_per_buffer = 20 # 16 self._clean_up() @@ -162,6 +190,7 @@ class FalconCsaxs(Device): def _clean_up(self) -> None: """Clean up""" + #TODO clarify when to use put and when to use set! self.hdf5.capture.put(0) self.stop_all.put(1) self.erase_all.put(1) diff --git a/ophyd_devices/epics/devices/pilatus_csaxs.py b/ophyd_devices/epics/devices/pilatus_csaxs.py index b1c066a..61849f3 100644 --- a/ophyd_devices/epics/devices/pilatus_csaxs.py +++ b/ophyd_devices/epics/devices/pilatus_csaxs.py @@ -78,6 +78,11 @@ class PilatusCsaxs(DetectorBase): """ + # Specify which functions are revealed to the user in BEC client + USER_ACCESS = [ + "describe", + ] + cam = ADCpt(SlsDetectorCam, "cam1:") def __init__( @@ -93,6 +98,18 @@ class PilatusCsaxs(DetectorBase): sim_mode=False, **kwargs, ): + """Initialize the Pilatus detector + Args: + #TODO add here the parameters for kind, read_attrs, configuration_attrs, parent + prefix (str): PV prefix ("X12SA-ES-PILATUS300K:) + name (str): 'pilatus_2' + kind (str): + read_attrs (list): + configuration_attrs (list): + parent (object): + device_manager (object): BEC device manager + sim_mode (bool): simulation mode to start the detector without BEC, e.g. from ipython shell + """ super().__init__( prefix=prefix, name=name, @@ -106,7 +123,8 @@ class PilatusCsaxs(DetectorBase): raise PilatusError("Add DeviceManager to initialization or init with sim_mode=True") self.name = name - self.wait_for_connection() # Make sure to be connected before talking to PVs + self.wait_for_connection() + # Spin up connections for simulation or BEC mode if not sim_mode: from bec_lib.core.bec_service import SERVICE_CONFIG @@ -114,16 +132,17 @@ class PilatusCsaxs(DetectorBase): self._producer = self.device_manager.producer self.service_cfg = SERVICE_CONFIG.config["service_config"]["file_writer"] else: + base_path = f"/sls/X12SA/data/{self.scaninfo.username}/Data10/" self._producer = bec_utils.MockProducer() self.device_manager = bec_utils.MockDeviceManager() self.scaninfo = BecScaninfoMixin(device_manager, sim_mode) self.scaninfo.load_scan_metadata() - self.service_cfg = {"base_path": f"/sls/X12SA/data/{self.scaninfo.username}/Data10/"} + self.service_cfg = {"base_path": base_path} self.scaninfo = BecScaninfoMixin(device_manager, sim_mode) - self.filepath_h5 = "" - + self.scaninfo.load_scan_metadata() self.filewriter = FileWriterMixin(self.service_cfg) + self.readout = 1e-3 # 3 ms # TODO maybe needed