From 01a17cbe3aa684e3a14b36b2760e2c16414077c3 Mon Sep 17 00:00:00 2001 From: gac-x01da Date: Tue, 18 Mar 2025 17:52:23 +0100 Subject: [PATCH] feat: add support BEC core scans --- debye_bec/device_configs/x01da_database.yaml | 2 +- .../device_configs/x01da_test_config.yaml | 138 +++++++++--------- debye_bec/devices/mo1_bragg/mo1_bragg.py | 6 +- debye_bec/devices/nidaq/nidaq.py | 83 +++++++++-- debye_bec/scans/mono_bragg_scans.py | 9 +- 5 files changed, 152 insertions(+), 86 deletions(-) diff --git a/debye_bec/device_configs/x01da_database.yaml b/debye_bec/device_configs/x01da_database.yaml index e50414a..639fd3a 100644 --- a/debye_bec/device_configs/x01da_database.yaml +++ b/debye_bec/device_configs/x01da_database.yaml @@ -210,7 +210,7 @@ cm_xstripe: mo1_bragg: readoutPriority: baseline description: Positioner for the Monochromator - deviceClass: debye_bec.devices.mo1_bragg.Mo1Bragg + deviceClass: debye_bec.devices.mo1_bragg.mo1.bragg.Mo1Bragg deviceConfig: prefix: "X01DA-OP-MO1:BRAGG:" onFailure: retry diff --git a/debye_bec/device_configs/x01da_test_config.yaml b/debye_bec/device_configs/x01da_test_config.yaml index 7526ed0..5f0cfb1 100644 --- a/debye_bec/device_configs/x01da_test_config.yaml +++ b/debye_bec/device_configs/x01da_test_config.yaml @@ -20,85 +20,85 @@ dummy_pv: # NIDAQ nidaq: - readoutPriority: async + readoutPriority: monitored description: NIDAQ backend for data reading for debye scans - deviceClass: debye_bec.devices.nidaq.NIDAQ + deviceClass: debye_bec.devices.nidaq.nidaq.Nidaq deviceConfig: prefix: "X01DA-PC-SCANSERVER:" onFailure: retry enabled: true softwareTrigger: false -# ES0 Filter -# es0filter: -# readoutPriority: async -# description: ES0 filter station -# deviceClass: debye_bec.devices.es0filter.ES0Filter -# deviceConfig: -# prefix: "X01DA-ES0-FI:" -# onFailure: retry -# enabled: true -# softwareTrigger: false +# Ionization Chambers -# Current amplifiers -# amplifiers: -# readoutPriority: async -# description: ES current amplifiers -# deviceClass: debye_bec.devices.amplifiers.Amplifiers -# deviceConfig: -# prefix: "X01DA-ES:AMP5004" -# onFailure: retry -# enabled: true -# softwareTrigger: false - -# HV power supplies -hv_supplies: - readoutPriority: baseline - description: HV power supplies - deviceClass: debye_bec.devices.hv_supplies.HVSupplies - deviceConfig: - prefix: "X01DA-" - onFailure: retry - enabled: true - softwareTrigger: false - -beam_monitor_1: - readoutPriority: baseline - description: Beam monitor 1 - deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam - deviceConfig: - prefix: "X01DA-OP-GIGE01:" - onFailure: retry - enabled: true - softwareTrigger: false - -beam_monitor_2: - readoutPriority: baseline - description: Beam monitor 2 - deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam - deviceConfig: - prefix: "X01DA-OP-GIGE02:" - onFailure: retry - enabled: true - softwareTrigger: false - -xray_eye: - readoutPriority: baseline - description: X-ray eye - deviceClass: debye_bec.devices.cameras.basler_cam.BaslerCam - deviceConfig: - prefix: "X01DA-ES-XRAYEYE:" - onFailure: retry - enabled: true - softwareTrigger: false - -# Gas Mix Setup -# gas_mix_setup: +# ic0: # readoutPriority: baseline -# description: Gas Mix Setup for Ionization Chambers -# deviceClass: debye_bec.devices.gas_mix_setup.GasMixSetup +# description: Ionization chamber 0 +# deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber0 # deviceConfig: -# prefix: "X01DA-ES-GMES:" +# prefix: "X01DA-" +# onFailure: retry +# enabled: true +# softwareTrigger: false +# ic1: +# readoutPriority: baseline +# description: Ionization chamber 1 +# deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber1 +# deviceConfig: +# prefix: "X01DA-" +# onFailure: retry +# enabled: true +# softwareTrigger: false +# ic2: +# readoutPriority: baseline +# description: Ionization chamber 2 +# deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber2 +# deviceConfig: +# prefix: "X01DA-" +# onFailure: retry +# enabled: true +# softwareTrigger: false + +# ES0 Filter + +es0filter: + readoutPriority: baseline + description: ES0 filter station + deviceClass: debye_bec.devices.es0filter.ES0Filter + deviceConfig: + prefix: "X01DA-ES0-FI:" + onFailure: retry + enabled: true + softwareTrigger: false + +# Beam Monitors + +# beam_monitor_1: +# readoutPriority: async +# description: Beam monitor 1 +# deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam +# deviceConfig: +# prefix: "X01DA-OP-GIGE01:" +# onFailure: retry +# enabled: true +# softwareTrigger: false + +# beam_monitor_2: +# readoutPriority: async +# description: Beam monitor 2 +# deviceClass: debye_bec.devices.cameras.prosilica_cam.ProsilicaCam +# deviceConfig: +# prefix: "X01DA-OP-GIGE02:" +# onFailure: retry +# enabled: true +# softwareTrigger: false + +# xray_eye: +# readoutPriority: async +# description: X-ray eye +# deviceClass: debye_bec.devices.cameras.basler_cam.BaslerCam +# deviceConfig: +# prefix: "X01DA-ES-XRAYEYE:" # onFailure: retry # enabled: true # softwareTrigger: false diff --git a/debye_bec/devices/mo1_bragg/mo1_bragg.py b/debye_bec/devices/mo1_bragg/mo1_bragg.py index 1c743af..178a8ba 100644 --- a/debye_bec/devices/mo1_bragg/mo1_bragg.py +++ b/debye_bec/devices/mo1_bragg/mo1_bragg.py @@ -119,8 +119,6 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner): Information about the upcoming scan can be accessed from the scan_info (self.scan_info.msg) object. """ - if not self.scan_info.msg.scan_type == "fly": - return self._check_scan_msg(ScanControlLoadMessage.PENDING) scan_name = self.scan_info.msg.scan_name @@ -198,9 +196,7 @@ class Mo1Bragg(PSIDeviceBase, Mo1BraggPositioner): mode=ScanControlMode.ADVANCED, scan_duration=self.scan_parameter.scan_duration ) else: - raise Mo1BraggError( - f"Scan mode {scan_name} not implemented for scan_type={self.scan_info.msg.scan_type} on device {self.name}" - ) + return # Load the scan parameters to the controller self.scan_control.scan_load.put(1) # Wait for params to be checked from controller diff --git a/debye_bec/devices/nidaq/nidaq.py b/debye_bec/devices/nidaq/nidaq.py index f3a0b5b..f6b31e9 100644 --- a/debye_bec/devices/nidaq/nidaq.py +++ b/debye_bec/devices/nidaq/nidaq.py @@ -28,20 +28,85 @@ class NidaqError(Exception): class NidaqControl(Device): """Nidaq control class with all PVs""" + ### Readback PVs for EpicsEmitter ### + ai0 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI0", kind=Kind.normal, doc="EPICS analog input 0",auto_monitor=True) + ai1 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI1", kind=Kind.normal, doc="EPICS analog input 1",auto_monitor=True) + ai2 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI2", kind=Kind.normal, doc="EPICS analog input 2",auto_monitor=True) + ai3 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI3", kind=Kind.normal, doc="EPICS analog input 3",auto_monitor=True) + ai4 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI4", kind=Kind.normal, doc="EPICS analog input 4",auto_monitor=True) + ai5 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI5", kind=Kind.normal, doc="EPICS analog input 5",auto_monitor=True) + ai6 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI6", kind=Kind.normal, doc="EPICS analog input 6",auto_monitor=True) + ai7 = Cpt(EpicsSignalRO, suffix="NIDAQ-AI7", kind=Kind.normal, doc="EPICS analog input 7",auto_monitor=True) + + ci0 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI0", kind=Kind.normal, doc="EPICS counter input 0", auto_monitor=True) + ci1 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI1", kind=Kind.normal, doc="EPICS counter input 1", auto_monitor=True) + ci2 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI2", kind=Kind.normal, doc="EPICS counter input 2", auto_monitor=True) + ci3 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI3", kind=Kind.normal, doc="EPICS counter input 3", auto_monitor=True) + ci4 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI4", kind=Kind.normal, doc="EPICS counter input 4", auto_monitor=True) + ci5 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI5", kind=Kind.normal, doc="EPICS counter input 5", auto_monitor=True) + ci6 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI6", kind=Kind.normal, doc="EPICS counter input 6", auto_monitor=True) + ci7 = Cpt(EpicsSignalRO, suffix="NIDAQ-CI7", kind=Kind.normal, doc="EPICS counter input 7", auto_monitor=True) + + di0 = Cpt(EpicsSignalRO, suffix="NIDAQ-DI0", kind=Kind.normal, doc="EPICS digital input 0", auto_monitor=True) + di1 = Cpt(EpicsSignalRO, suffix="NIDAQ-DI1", kind=Kind.normal, doc="EPICS digital input 1", auto_monitor=True) + di2 = Cpt(EpicsSignalRO, suffix="NIDAQ-DI2", kind=Kind.normal, doc="EPICS digital input 2", auto_monitor=True) + di3 = Cpt(EpicsSignalRO, suffix="NIDAQ-DI3", kind=Kind.normal, doc="EPICS digital input 3", auto_monitor=True) + di4 = Cpt(EpicsSignalRO, suffix="NIDAQ-DI4", kind=Kind.normal, doc="EPICS digital input 4", auto_monitor=True) + + enc_epics = Cpt(EpicsSignalRO, suffix="NIDAQ-ENC", kind=Kind.normal, doc="EPICS Encoder reading", auto_monitor=True) + + ### Readback for BEC emitter ### + + ai0_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 0, MEAN") + ai1_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 1, MEAN") + ai2_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 2, MEAN") + ai3_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 3, MEAN") + ai4_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 4, MEAN") + ai5_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 5, MEAN") + ai6_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 6, MEAN") + ai7_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 7, MEAN") + + ai0_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 0, STD") + ai1_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 1, STD") + ai2_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 2, STD") + ai3_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 3, STD") + ai4_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 4, STD") + ai5_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 5, STD") + ai6_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 6, STD") + ai7_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream analog input 7, STD") + + ci0_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 0, MEAN") + ci1_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 1, MEAN") + ci2_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 2, MEAN") + ci3_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 3, MEAN") + ci4_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 4, MEAN") + ci5_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 5, MEAN") + ci6_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 6, MEAN") + ci7_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7, MEAN") + + ci0_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 0. STD") + ci1_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 1. STD") + ci2_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 2. STD") + ci3_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 3. STD") + ci4_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 4. STD") + ci5_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 5. STD") + ci6_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 6. STD") + ci7_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7. STD") + + di0_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 0, MAX") + di1_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 1, MAX") + di2_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 2, MAX") + di3_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 3, MAX") + di4_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 4, MAX") + enc = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_1 = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_2 = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_3 = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_4 = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_5 = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_6 = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_7 = Cpt(SetableSignal, value=0, kind=Kind.normal) - signal_8 = Cpt(SetableSignal, value=0, kind=Kind.normal) + + ### Control PVs ### enable_compression = Cpt(EpicsSignal, suffix="NIDAQ-EnableRLE", kind=Kind.config) kickoff_call = Cpt(EpicsSignal, suffix="NIDAQ-Kickoff", kind=Kind.config) stage_call = Cpt(EpicsSignal, suffix="NIDAQ-Stage", kind=Kind.config) - state = Cpt(EpicsSignal, suffix="NIDAQ-FSMState", kind=Kind.config) + state = Cpt(EpicsSignal, suffix="NIDAQ-FSMState", kind=Kind.config, auto_monitor=True) server_status = Cpt(EpicsSignalRO, suffix="NIDAQ-ServerStatus", kind=Kind.config) compression_ratio = Cpt(EpicsSignalRO, suffix="NIDAQ-CompressionRatio", kind=Kind.config) scan_type = Cpt(EpicsSignal, suffix="NIDAQ-ScanType", kind=Kind.config) diff --git a/debye_bec/scans/mono_bragg_scans.py b/debye_bec/scans/mono_bragg_scans.py index 7df6c47..d6de55d 100644 --- a/debye_bec/scans/mono_bragg_scans.py +++ b/debye_bec/scans/mono_bragg_scans.py @@ -1,7 +1,7 @@ """This module contains the scan classes for the mono bragg motor of the Debye beamline.""" import time - +from typing import Literal import numpy as np from bec_lib.device import DeviceBase from bec_lib.logger import bec_logger @@ -56,6 +56,11 @@ class XASSimpleScan(AsyncFlyScanBase): self.scan_duration = scan_duration self.primary_readout_cycle = 1 + def update_readout_priority(self): + """Ensure that NIDAQ is not monitored for any quick EXAFS.""" + super().update_readout_priority() + self.readout_priority['async'].append('nidaq') + def prepare_positions(self): """Prepare the positions for the scan. @@ -96,7 +101,7 @@ class XASSimpleScan(AsyncFlyScanBase): time.sleep(self.primary_readout_cycle) self.point_id += 1 - self.num_pos = self.point_id + 1 + self.num_pos = self.point_id class XASSimpleScanWithXRD(XASSimpleScan):