Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
632d554245 | ||
|
|
efd8842540 | ||
|
|
fd1626fbcd | ||
|
|
062df3171b | ||
|
|
37a268fe7b | ||
|
|
e9e7d84e60 | ||
|
|
1c0c9ad53e | ||
|
|
faeb991b75 | ||
|
|
7377613213 | ||
|
|
d8383d3b73 | ||
|
|
c3bfab2056 | ||
|
|
0261c601ff | ||
|
|
d3dc130f11 | ||
|
|
ed1e5a027f | ||
|
|
df2961ce8e | ||
|
|
e179fc1a07 |
@@ -386,4 +386,64 @@ es_light_toggle:
|
|||||||
read_pv: "X01DA-EH-LIGHT:TOGGLE"
|
read_pv: "X01DA-EH-LIGHT:TOGGLE"
|
||||||
onFailure: retry
|
onFailure: retry
|
||||||
enabled: true
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
es_gas_sensor_o2:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: ES Gas Sensor O2
|
||||||
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
|
deviceConfig:
|
||||||
|
read_pv: "X01DA-KIMESSA2:EH-O2"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
es_gas_sensor_h2s:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: ES Gas Sensor H2S
|
||||||
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
|
deviceConfig:
|
||||||
|
read_pv: "X01DA-KIMESSA2:EH-H2S"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
es_gas_sensor_no2:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: ES Gas Sensor NO2
|
||||||
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
|
deviceConfig:
|
||||||
|
read_pv: "X01DA-KIMESSA2:EH-NO2"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
es_gas_sensor_co:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: ES Gas Sensor CO
|
||||||
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
|
deviceConfig:
|
||||||
|
read_pv: "X01DA-KIMESSA2:EH-CO"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
es_gas_sensor_h2:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: ES Gas Sensor H2
|
||||||
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
|
deviceConfig:
|
||||||
|
read_pv: "X01DA-KIMESSA2:EH-H2"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
es_gas_sensor_nh3:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: ES Gas Sensor NH3
|
||||||
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
|
deviceConfig:
|
||||||
|
read_pv: "X01DA-KIMESSA2:EH-NH3"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
34
debye_bec/device_configs/x01da_hutch_cameras.yaml
Normal file
34
debye_bec/device_configs/x01da_hutch_cameras.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
###################################
|
||||||
|
## Hutch Cameras ##
|
||||||
|
###################################
|
||||||
|
|
||||||
|
hutch_cam_1:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: Hutch Camera 1
|
||||||
|
deviceClass: debye_bec.devices.cameras.hutch_cam.HutchCam
|
||||||
|
deviceConfig:
|
||||||
|
prefix: "pcp085420"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
hutch_cam_2:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: Hutch Camera 2
|
||||||
|
deviceClass: debye_bec.devices.cameras.hutch_cam.HutchCam
|
||||||
|
deviceConfig:
|
||||||
|
prefix: "pcp085436"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
|
hutch_cam_3:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: Hutch Camera 3
|
||||||
|
deviceClass: debye_bec.devices.cameras.hutch_cam.HutchCam
|
||||||
|
deviceConfig:
|
||||||
|
prefix: "pcp085435"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
@@ -51,7 +51,7 @@ optics_config:
|
|||||||
## Experimental Hutch ##
|
## Experimental Hutch ##
|
||||||
###################################
|
###################################
|
||||||
|
|
||||||
## NIDAQ
|
# ## NIDAQ
|
||||||
nidaq:
|
nidaq:
|
||||||
readoutPriority: monitored
|
readoutPriority: monitored
|
||||||
description: NIDAQ backend for data reading for debye scans
|
description: NIDAQ backend for data reading for debye scans
|
||||||
@@ -67,8 +67,13 @@ xas_config:
|
|||||||
- !include ./x01da_xas.yaml
|
- !include ./x01da_xas.yaml
|
||||||
|
|
||||||
## XRD (Pilatus, pinhole, beamstop)
|
## XRD (Pilatus, pinhole, beamstop)
|
||||||
xrd_config:
|
#xrd_config:
|
||||||
- !include ./x01da_xrd.yaml
|
# - !include ./x01da_xrd.yaml
|
||||||
|
|
||||||
|
# Commented out because too slow
|
||||||
|
## Hutch cameras
|
||||||
|
# hutch_cams:
|
||||||
|
# - !include ./x01da_hutch_cameras.yaml
|
||||||
|
|
||||||
## Remaining experimental hutch
|
## Remaining experimental hutch
|
||||||
es_config:
|
es_config:
|
||||||
|
|||||||
@@ -3,35 +3,45 @@
|
|||||||
## Ionization Chambers ##
|
## Ionization Chambers ##
|
||||||
###################################
|
###################################
|
||||||
|
|
||||||
# ic0:
|
ic0:
|
||||||
# readoutPriority: baseline
|
readoutPriority: baseline
|
||||||
# description: Ionization chamber 0
|
description: Ionization chamber 0
|
||||||
# deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber0
|
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber0
|
||||||
# deviceConfig:
|
deviceConfig:
|
||||||
# prefix: "X01DA-"
|
prefix: "X01DA-"
|
||||||
# onFailure: retry
|
onFailure: retry
|
||||||
# enabled: true
|
enabled: true
|
||||||
# softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
# ic1:
|
ic1:
|
||||||
# readoutPriority: baseline
|
readoutPriority: baseline
|
||||||
# description: Ionization chamber 1
|
description: Ionization chamber 1
|
||||||
# deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber1
|
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber1
|
||||||
# deviceConfig:
|
deviceConfig:
|
||||||
# prefix: "X01DA-"
|
prefix: "X01DA-"
|
||||||
# onFailure: retry
|
onFailure: retry
|
||||||
# enabled: true
|
enabled: true
|
||||||
# softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
# ic2:
|
ic2:
|
||||||
# readoutPriority: baseline
|
readoutPriority: baseline
|
||||||
# description: Ionization chamber 2
|
description: Ionization chamber 2
|
||||||
# deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber2
|
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.IonizationChamber2
|
||||||
# deviceConfig:
|
deviceConfig:
|
||||||
# prefix: "X01DA-"
|
prefix: "X01DA-"
|
||||||
# onFailure: retry
|
onFailure: retry
|
||||||
# enabled: true
|
enabled: true
|
||||||
# softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
|
pips:
|
||||||
|
readoutPriority: baseline
|
||||||
|
description: Pips diode
|
||||||
|
deviceClass: debye_bec.devices.ionization_chambers.ionization_chamber.Pips
|
||||||
|
deviceConfig:
|
||||||
|
prefix: "X01DA-"
|
||||||
|
onFailure: retry
|
||||||
|
enabled: true
|
||||||
|
softwareTrigger: false
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
## Reference Foil Changer ##
|
## Reference Foil Changer ##
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ pilatus_curtain:
|
|||||||
softwareTrigger: false
|
softwareTrigger: false
|
||||||
|
|
||||||
pilatus:
|
pilatus:
|
||||||
readoutPriority: async
|
readoutPriority: baseline
|
||||||
description: Pilatus
|
description: Pilatus
|
||||||
deviceClass: debye_bec.devices.pilatus.pilatus.Pilatus
|
deviceClass: debye_bec.devices.pilatus.pilatus.Pilatus
|
||||||
deviceTags:
|
deviceTags:
|
||||||
@@ -97,12 +97,12 @@ pilatus:
|
|||||||
enabled: true
|
enabled: true
|
||||||
softwareTrigger: true
|
softwareTrigger: true
|
||||||
|
|
||||||
# sampl_pil:
|
pilatus_smpl:
|
||||||
# readoutPriority: baseline
|
readoutPriority: baseline
|
||||||
# description: Sample to pilatus distance
|
description: Sample to pilatus distance
|
||||||
# deviceClass: ophyd.EpicsSignalRO
|
deviceClass: ophyd.EpicsSignalRO
|
||||||
# deviceConfig:
|
deviceConfig:
|
||||||
# read_pv: "X01DA-SAMPL-PIL"
|
read_pv: "X01DA-ES2-DET:SMPLDIST"
|
||||||
# onFailure: retry
|
onFailure: retry
|
||||||
# enabled: true
|
enabled: true
|
||||||
# softwareTrigger: false
|
softwareTrigger: false
|
||||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from ophyd import ADBase
|
from ophyd import ADBase, EpicsSignalRO
|
||||||
from ophyd import ADComponent as ADCpt
|
from ophyd import ADComponent as ADCpt
|
||||||
from ophyd import Component as Cpt
|
from ophyd import Component as Cpt
|
||||||
from ophyd_devices import PreviewSignal
|
from ophyd_devices import PreviewSignal
|
||||||
@@ -20,6 +20,16 @@ if TYPE_CHECKING: # pragma: no cover
|
|||||||
class BaslerCamBase(ADBase):
|
class BaslerCamBase(ADBase):
|
||||||
"""BaslerCam Base class."""
|
"""BaslerCam Base class."""
|
||||||
|
|
||||||
|
cam_detector_state_string = Cpt(EpicsSignalRO, suffix="cam1:DetectorState_RBV", string=True)
|
||||||
|
|
||||||
|
_default_configuration_attrs = [
|
||||||
|
'cam1.acquire_time',
|
||||||
|
'cam1.detector_state',
|
||||||
|
'cam_detector_state_string',
|
||||||
|
'cam1.gain',
|
||||||
|
'cam1.model',
|
||||||
|
]
|
||||||
|
|
||||||
cam1 = ADCpt(AravisDetectorCam, "cam1:")
|
cam1 = ADCpt(AravisDetectorCam, "cam1:")
|
||||||
image1 = ADCpt(ImagePlugin_V35, "image1:")
|
image1 = ADCpt(ImagePlugin_V35, "image1:")
|
||||||
|
|
||||||
|
|||||||
79
debye_bec/devices/cameras/hutch_cam.py
Normal file
79
debye_bec/devices/cameras/hutch_cam.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
"""EH Hutch Cameras"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import threading
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from bec_lib.logger import bec_logger
|
||||||
|
from bec_lib.file_utils import get_full_path
|
||||||
|
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
|
||||||
|
from ophyd_devices import DeviceStatus
|
||||||
|
|
||||||
|
if TYPE_CHECKING: # pragma: no cover
|
||||||
|
from bec_lib.devicemanager import ScanInfo
|
||||||
|
from bec_lib.messages import ScanStatusMessage
|
||||||
|
|
||||||
|
logger = bec_logger.logger
|
||||||
|
|
||||||
|
CAM_USERNAME = "camera_user"
|
||||||
|
CAM_PASSWORD = "camera_user1"
|
||||||
|
CAM_PORT = 554
|
||||||
|
|
||||||
|
class HutchCam(PSIDeviceBase):
|
||||||
|
"""Class for the Hutch Cameras"""
|
||||||
|
|
||||||
|
# image = Cpt(Signal, name='image', kind='config')
|
||||||
|
|
||||||
|
def __init__(self, *, name: str, prefix: str = "", scan_info: ScanInfo | None = None, **kwargs):
|
||||||
|
super().__init__(name=name, scan_info=scan_info, **kwargs)
|
||||||
|
|
||||||
|
self.hostname = prefix
|
||||||
|
self.status = None
|
||||||
|
|
||||||
|
# pylint: disable=E1101
|
||||||
|
def on_connected(self) -> None:
|
||||||
|
"""
|
||||||
|
Called after the device is connected and its signals are connected.
|
||||||
|
Default values for signals should be set here.
|
||||||
|
"""
|
||||||
|
rtsp_url = f"rtsp://{CAM_USERNAME}:{CAM_PASSWORD}@{self.hostname}.psi.ch:{CAM_PORT}/rtpstream/config1"
|
||||||
|
cap = cv2.VideoCapture(f"{rtsp_url}?tcp")
|
||||||
|
if not cap.isOpened():
|
||||||
|
logger.error(self, "Connection Failed", "Could not connect to the camera stream.")
|
||||||
|
return
|
||||||
|
cap.release()
|
||||||
|
|
||||||
|
def on_stage(self) -> DeviceStatus:
|
||||||
|
"""Called while staging the device."""
|
||||||
|
|
||||||
|
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||||
|
file_path = get_full_path(scan_msg, name='hutch_cam_' + self.hostname).removesuffix('h5')
|
||||||
|
|
||||||
|
self.status = DeviceStatus(self)
|
||||||
|
|
||||||
|
thread = threading.Thread(target=self._save_picture, args=(file_path, self.status), daemon=True)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
return self.status
|
||||||
|
|
||||||
|
def _save_picture(self, file_path, status):
|
||||||
|
try:
|
||||||
|
logger.info(f'Capture from camera {self.hostname}')
|
||||||
|
rtsp_url = f"rtsp://{CAM_USERNAME}:{CAM_PASSWORD}@{self.hostname}.psi.ch:{CAM_PORT}/rtpstream/config1"
|
||||||
|
cap = cv2.VideoCapture(f"{rtsp_url}?tcp")
|
||||||
|
if not cap.isOpened():
|
||||||
|
logger.error("Connection Failed", "Could not connect to the camera stream.")
|
||||||
|
return
|
||||||
|
logger.info(f'Connection to camera {self.hostname} established')
|
||||||
|
ret, frame = cap.readAsync()
|
||||||
|
cap.release()
|
||||||
|
if not ret:
|
||||||
|
logger.error("Capture Failed", "Failed to capture image from camera.")
|
||||||
|
return
|
||||||
|
cv2.imwrite(file_path + 'png', frame)
|
||||||
|
status.set_finished()
|
||||||
|
logger.info(f'Capture from camera {self.hostname} done')
|
||||||
|
except Exception as e:
|
||||||
|
status.set_exception(e)
|
||||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from ophyd import ADBase
|
from ophyd import ADBase, EpicsSignalRO
|
||||||
from ophyd import ADComponent as ADCpt
|
from ophyd import ADComponent as ADCpt
|
||||||
from ophyd import Component as Cpt
|
from ophyd import Component as Cpt
|
||||||
from ophyd_devices import PreviewSignal
|
from ophyd_devices import PreviewSignal
|
||||||
@@ -20,6 +20,16 @@ if TYPE_CHECKING: # pragma: no cover
|
|||||||
class ProsilicaCamBase(ADBase):
|
class ProsilicaCamBase(ADBase):
|
||||||
"""Base class for Prosilica cameras."""
|
"""Base class for Prosilica cameras."""
|
||||||
|
|
||||||
|
cam_detector_state_string = Cpt(EpicsSignalRO, suffix="cam1:DetectorState_RBV", string=True)
|
||||||
|
|
||||||
|
_default_configuration_attrs = [
|
||||||
|
'cam1.acquire_time',
|
||||||
|
'cam1.detector_state',
|
||||||
|
'cam_detector_state_string',
|
||||||
|
'cam1.gain',
|
||||||
|
'cam1.model',
|
||||||
|
]
|
||||||
|
|
||||||
cam1 = ADCpt(ProsilicaDetectorCam, "cam1:")
|
cam1 = ADCpt(ProsilicaDetectorCam, "cam1:")
|
||||||
image1 = ADCpt(ImagePlugin_V35, "image1:")
|
image1 = ADCpt(ImagePlugin_V35, "image1:")
|
||||||
|
|
||||||
|
|||||||
@@ -33,22 +33,24 @@ class EpicsSignalSplit(EpicsSignal):
|
|||||||
class GasMixSetupControl(Device):
|
class GasMixSetupControl(Device):
|
||||||
"""GasMixSetup Control for Inonization Chamber 0"""
|
"""GasMixSetup Control for Inonization Chamber 0"""
|
||||||
|
|
||||||
gas1_req = Cpt(EpicsSignalWithRBV, suffix="Gas1Req", kind="config", doc="Gas 1 requirement")
|
gas1_req = Cpt(EpicsSignalWithRBV, suffix="Gas1Req", kind="omitted", doc="Gas 1 requirement")
|
||||||
conc1_req = Cpt(
|
conc1_req = Cpt(
|
||||||
EpicsSignalWithRBV, suffix="Conc1Req", kind="config", doc="Concentration 1 requirement"
|
EpicsSignalWithRBV, suffix="Conc1Req", kind="omitted", doc="Concentration 1 requirement"
|
||||||
)
|
)
|
||||||
gas2_req = Cpt(EpicsSignalWithRBV, suffix="Gas2Req", kind="config", doc="Gas 2 requirement")
|
gas2_req = Cpt(EpicsSignalWithRBV, suffix="Gas2Req", kind="omitted", doc="Gas 2 requirement")
|
||||||
conc2_req = Cpt(
|
conc2_req = Cpt(
|
||||||
EpicsSignalWithRBV, suffix="Conc2Req", kind="config", doc="Concentration 2 requirement"
|
EpicsSignalWithRBV, suffix="Conc2Req", kind="omitted", doc="Concentration 2 requirement"
|
||||||
)
|
)
|
||||||
press_req = Cpt(
|
press_req = Cpt(
|
||||||
EpicsSignalWithRBV, suffix="PressReq", kind="config", doc="Pressure requirement"
|
EpicsSignalWithRBV, suffix="PressReq", kind="omitted", doc="Pressure requirement"
|
||||||
)
|
)
|
||||||
fill = Cpt(EpicsSignal, suffix="Fill", kind="config", doc="Fill the chamber")
|
fill = Cpt(EpicsSignal, suffix="Fill", kind="config", doc="Fill the chamber")
|
||||||
status = Cpt(EpicsSignalRO, suffix="Status", kind="config", doc="Status")
|
status = Cpt(EpicsSignalRO, suffix="Status", kind="config", doc="Status")
|
||||||
gas1 = Cpt(EpicsSignalRO, suffix="Gas1", kind="config", doc="Gas 1")
|
gas1 = Cpt(EpicsSignalRO, suffix="Gas1", kind="config", doc="Gas 1")
|
||||||
|
gas1_string = Cpt(EpicsSignalRO, suffix="Gas1", kind="config", doc="Gas 1", string=True)
|
||||||
conc1 = Cpt(EpicsSignalRO, suffix="Conc1", kind="config", doc="Concentration 1")
|
conc1 = Cpt(EpicsSignalRO, suffix="Conc1", kind="config", doc="Concentration 1")
|
||||||
gas2 = Cpt(EpicsSignalRO, suffix="Gas2", kind="config", doc="Gas 2")
|
gas2 = Cpt(EpicsSignalRO, suffix="Gas2", kind="config", doc="Gas 2")
|
||||||
|
gas2_string = Cpt(EpicsSignalRO, suffix="Gas2", kind="config", doc="Gas 2", string=True)
|
||||||
conc2 = Cpt(EpicsSignalRO, suffix="Conc2", kind="config", doc="Concentration 2")
|
conc2 = Cpt(EpicsSignalRO, suffix="Conc2", kind="config", doc="Concentration 2")
|
||||||
press = Cpt(EpicsSignalRO, suffix="PressTransm", kind="config", doc="Current Pressure")
|
press = Cpt(EpicsSignalRO, suffix="PressTransm", kind="config", doc="Current Pressure")
|
||||||
|
|
||||||
@@ -84,10 +86,25 @@ class IonizationChamber0(PSIDeviceBase):
|
|||||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||||
),
|
),
|
||||||
|
"cOnOff_string": (
|
||||||
|
EpicsSignal,
|
||||||
|
(f"ES:AMP5004.cOnOff{num}"),
|
||||||
|
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cGain_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cFilter_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
}
|
}
|
||||||
amp = Dcpt(amp_signals)
|
amp = Dcpt(amp_signals)
|
||||||
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
||||||
gmes_status = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
gmes_status_msg = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||||
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES1-IC{num-1}:")
|
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES1-IC{num-1}:")
|
||||||
hv_en_signals = {
|
hv_en_signals = {
|
||||||
"ext_ena": (
|
"ext_ena": (
|
||||||
@@ -275,10 +292,25 @@ class IonizationChamber1(IonizationChamber0):
|
|||||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||||
),
|
),
|
||||||
|
"cOnOff_string": (
|
||||||
|
EpicsSignal,
|
||||||
|
(f"ES:AMP5004.cOnOff{num}"),
|
||||||
|
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cGain_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cFilter_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
}
|
}
|
||||||
amp = Dcpt(amp_signals)
|
amp = Dcpt(amp_signals)
|
||||||
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
||||||
gmes_status = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
gmes_status_msg = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||||
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES2-IC{num-1}:")
|
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES2-IC{num-1}:")
|
||||||
hv_en_signals = {
|
hv_en_signals = {
|
||||||
"ext_ena": (
|
"ext_ena": (
|
||||||
@@ -311,10 +343,25 @@ class IonizationChamber2(IonizationChamber0):
|
|||||||
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||||
),
|
),
|
||||||
|
"cOnOff_string": (
|
||||||
|
EpicsSignal,
|
||||||
|
(f"ES:AMP5004.cOnOff{num}"),
|
||||||
|
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cGain_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cFilter_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
}
|
}
|
||||||
amp = Dcpt(amp_signals)
|
amp = Dcpt(amp_signals)
|
||||||
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
gmes = Cpt(GasMixSetupControl, suffix=f"ES-GMES:IC{num-1}")
|
||||||
gmes_status = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
gmes_status_msg = Cpt(EpicsSignalRO, suffix="ES-GMES:StatusMsg0", kind="config", doc="Status")
|
||||||
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES2-IC{num-1}:")
|
hv = Cpt(HighVoltageSuppliesControl, suffix=f"ES2-IC{num-1}:")
|
||||||
hv_en_signals = {
|
hv_en_signals = {
|
||||||
"ext_ena": (
|
"ext_ena": (
|
||||||
@@ -325,3 +372,63 @@ class IonizationChamber2(IonizationChamber0):
|
|||||||
"ena": (EpicsSignal, "ES2-IC12:HV-Ena", {"kind": "config", "doc": "Enable signal of HV"}),
|
"ena": (EpicsSignal, "ES2-IC12:HV-Ena", {"kind": "config", "doc": "Enable signal of HV"}),
|
||||||
}
|
}
|
||||||
hv_en = Dcpt(hv_en_signals)
|
hv_en = Dcpt(hv_en_signals)
|
||||||
|
|
||||||
|
class Pips(IonizationChamber0):
|
||||||
|
"""Pips, prefix should be 'X01DA-'."""
|
||||||
|
|
||||||
|
USER_ACCESS = ["set_gain", "set_filter"]
|
||||||
|
|
||||||
|
num = 4
|
||||||
|
amp_signals = {
|
||||||
|
"cOnOff": (
|
||||||
|
EpicsSignal,
|
||||||
|
(f"ES:AMP5004.cOnOff{num}"),
|
||||||
|
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}"},
|
||||||
|
),
|
||||||
|
"cGain_ENUM": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}"},
|
||||||
|
),
|
||||||
|
"cFilter_ENUM": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}"},
|
||||||
|
),
|
||||||
|
"cOnOff_string": (
|
||||||
|
EpicsSignal,
|
||||||
|
(f"ES:AMP5004.cOnOff{num}"),
|
||||||
|
{"kind": "config", "doc": f"Enable ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cGain_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cGain{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Gain of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
"cFilter_ENUM_string": (
|
||||||
|
EpicsSignalWithRBV,
|
||||||
|
(f"ES:AMP5004:cFilter{num}_ENUM"),
|
||||||
|
{"kind": "config", "doc": f"Filter of ch{num} -> IC{num-1}", "string": True},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
amp = Dcpt(amp_signals)
|
||||||
|
gmes = None
|
||||||
|
gmes_status_msg = None
|
||||||
|
hv = None
|
||||||
|
hv_en_signals = None
|
||||||
|
hv_en = None
|
||||||
|
|
||||||
|
@typechecked
|
||||||
|
def set_hv(self, *_) -> None:
|
||||||
|
"""Not available for the PIPS"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
@typechecked
|
||||||
|
def set_grid(self, *_) -> None:
|
||||||
|
"""Not available for the PIPS"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
@typechecked
|
||||||
|
def fill(self, *_) -> None:
|
||||||
|
"""Not available for the PIPS"""
|
||||||
|
return None
|
||||||
|
|||||||
@@ -146,6 +146,76 @@ class NidaqControl(Device):
|
|||||||
doc="EPICS counter input 7",
|
doc="EPICS counter input 7",
|
||||||
auto_monitor=True,
|
auto_monitor=True,
|
||||||
)
|
)
|
||||||
|
ci8 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI8",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 8",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci9 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI9",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 9",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci10 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI10",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 0",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci11 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI11",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 1",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci12 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI12",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 2",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci13 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI13",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 3",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci14 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI14",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 4",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci15 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI15",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 5",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci16 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI16",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 6",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
ci17 = Cpt(
|
||||||
|
EpicsSignalRO,
|
||||||
|
suffix="NIDAQ-CI17",
|
||||||
|
kind=Kind.normal,
|
||||||
|
doc="EPICS counter input 7",
|
||||||
|
auto_monitor=True,
|
||||||
|
)
|
||||||
|
|
||||||
di0 = Cpt(
|
di0 = Cpt(
|
||||||
EpicsSignalRO,
|
EpicsSignalRO,
|
||||||
@@ -275,6 +345,36 @@ class NidaqControl(Device):
|
|||||||
ci7_mean = Cpt(
|
ci7_mean = Cpt(
|
||||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7, MEAN"
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7, MEAN"
|
||||||
)
|
)
|
||||||
|
ci8_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 8, MEAN"
|
||||||
|
)
|
||||||
|
ci9_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 9, MEAN"
|
||||||
|
)
|
||||||
|
ci10_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 10, MEAN"
|
||||||
|
)
|
||||||
|
ci11_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 11, MEAN"
|
||||||
|
)
|
||||||
|
ci12_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 12, MEAN"
|
||||||
|
)
|
||||||
|
ci13_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 13, MEAN"
|
||||||
|
)
|
||||||
|
ci14_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 14, MEAN"
|
||||||
|
)
|
||||||
|
ci15_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 15, MEAN"
|
||||||
|
)
|
||||||
|
ci16_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 16, MEAN"
|
||||||
|
)
|
||||||
|
ci17_mean = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 17, MEAN"
|
||||||
|
)
|
||||||
|
|
||||||
ci0_std_dev = Cpt(
|
ci0_std_dev = Cpt(
|
||||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 0. STD"
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 0. STD"
|
||||||
@@ -300,12 +400,54 @@ class NidaqControl(Device):
|
|||||||
ci7_std_dev = Cpt(
|
ci7_std_dev = Cpt(
|
||||||
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7. STD"
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 7. STD"
|
||||||
)
|
)
|
||||||
|
ci8_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 8. STD"
|
||||||
|
)
|
||||||
|
ci9_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 9. STD"
|
||||||
|
)
|
||||||
|
ci10_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 10. STD"
|
||||||
|
)
|
||||||
|
ci11_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 11. STD"
|
||||||
|
)
|
||||||
|
ci12_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 12. STD"
|
||||||
|
)
|
||||||
|
ci13_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 13. STD"
|
||||||
|
)
|
||||||
|
ci14_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 14. STD"
|
||||||
|
)
|
||||||
|
ci15_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 15. STD"
|
||||||
|
)
|
||||||
|
ci16_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 16. STD"
|
||||||
|
)
|
||||||
|
ci17_std_dev = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter input 17. STD"
|
||||||
|
)
|
||||||
|
|
||||||
|
cisum = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream counter sum"
|
||||||
|
)
|
||||||
|
smpl_abs = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream sample absorption"
|
||||||
|
)
|
||||||
|
ref_abs = Cpt(
|
||||||
|
SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream reference absorption"
|
||||||
|
)
|
||||||
|
|
||||||
xas_timestamp = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XAS timestamp")
|
xas_timestamp = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XAS timestamp")
|
||||||
|
|
||||||
xrd_timestamp = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD timestamp")
|
xrd_timestamp = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD timestamp")
|
||||||
|
xrd_angle = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD angle")
|
||||||
xrd_energy = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD energy")
|
xrd_energy = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD energy")
|
||||||
|
xrd_ai0_mean = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD ai0 mean")
|
||||||
|
xrd_ai0_std_dev = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream XRD ai0 std dev")
|
||||||
|
|
||||||
di0_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 0, MAX")
|
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")
|
di1_max = Cpt(SetableSignal, value=0, kind=Kind.normal, doc="NIDAQ stream digital input 1, MAX")
|
||||||
@@ -320,16 +462,21 @@ class NidaqControl(Device):
|
|||||||
### Control PVs ###
|
### Control PVs ###
|
||||||
|
|
||||||
enable_compression = Cpt(EpicsSignal, suffix="NIDAQ-EnableRLE", kind=Kind.config)
|
enable_compression = Cpt(EpicsSignal, suffix="NIDAQ-EnableRLE", kind=Kind.config)
|
||||||
|
enable_dead_time_correction = Cpt(EpicsSignal, suffix="NIDAQ-EnableDTC", kind=Kind.config)
|
||||||
kickoff_call = Cpt(EpicsSignal, suffix="NIDAQ-Kickoff", kind=Kind.config)
|
kickoff_call = Cpt(EpicsSignal, suffix="NIDAQ-Kickoff", kind=Kind.config)
|
||||||
stage_call = Cpt(EpicsSignal, suffix="NIDAQ-Stage", kind=Kind.config)
|
stage_call = Cpt(EpicsSignal, suffix="NIDAQ-Stage", kind=Kind.config)
|
||||||
state = Cpt(EpicsSignal, suffix="NIDAQ-FSMState", kind=Kind.config, auto_monitor=True)
|
state = Cpt(EpicsSignal, suffix="NIDAQ-FSMState", kind=Kind.config, auto_monitor=True)
|
||||||
server_status = Cpt(EpicsSignalRO, suffix="NIDAQ-ServerStatus", kind=Kind.config)
|
server_status = Cpt(EpicsSignalRO, suffix="NIDAQ-ServerStatus", kind=Kind.config)
|
||||||
compression_ratio = Cpt(EpicsSignalRO, suffix="NIDAQ-CompressionRatio", kind=Kind.config)
|
compression_ratio = Cpt(EpicsSignalRO, suffix="NIDAQ-CompressionRatio", kind=Kind.config)
|
||||||
scan_type = Cpt(EpicsSignal, suffix="NIDAQ-ScanType", kind=Kind.config)
|
scan_type = Cpt(EpicsSignal, suffix="NIDAQ-ScanType", kind=Kind.config)
|
||||||
|
scan_type_string = Cpt(EpicsSignal, suffix="NIDAQ-ScanType", kind=Kind.config, string=True)
|
||||||
sampling_rate = Cpt(EpicsSignal, suffix="NIDAQ-SamplingRateRequested", kind=Kind.config)
|
sampling_rate = Cpt(EpicsSignal, suffix="NIDAQ-SamplingRateRequested", kind=Kind.config)
|
||||||
|
sampling_rate_string = Cpt(EpicsSignal, suffix="NIDAQ-SamplingRateRequested", kind=Kind.config, string=True)
|
||||||
scan_duration = Cpt(EpicsSignal, suffix="NIDAQ-SamplingDuration", kind=Kind.config)
|
scan_duration = Cpt(EpicsSignal, suffix="NIDAQ-SamplingDuration", kind=Kind.config)
|
||||||
readout_range = Cpt(EpicsSignal, suffix="NIDAQ-ReadoutRange", kind=Kind.config)
|
readout_range = Cpt(EpicsSignal, suffix="NIDAQ-ReadoutRange", kind=Kind.config)
|
||||||
|
readout_range_string = Cpt(EpicsSignal, suffix="NIDAQ-ReadoutRange", kind=Kind.config, string=True)
|
||||||
encoder_factor = Cpt(EpicsSignal, suffix="NIDAQ-EncoderFactor", kind=Kind.config)
|
encoder_factor = Cpt(EpicsSignal, suffix="NIDAQ-EncoderFactor", kind=Kind.config)
|
||||||
|
encoder_factor_string = Cpt(EpicsSignal, suffix="NIDAQ-EncoderFactor", kind=Kind.config, string=True)
|
||||||
stop_call = Cpt(EpicsSignal, suffix="NIDAQ-Stop", kind=Kind.config)
|
stop_call = Cpt(EpicsSignal, suffix="NIDAQ-Stop", kind=Kind.config)
|
||||||
power = Cpt(EpicsSignal, suffix="NIDAQ-Power", kind=Kind.config)
|
power = Cpt(EpicsSignal, suffix="NIDAQ-Power", kind=Kind.config)
|
||||||
heartbeat = Cpt(EpicsSignal, suffix="NIDAQ-Heartbeat", kind=Kind.config, auto_monitor=True)
|
heartbeat = Cpt(EpicsSignal, suffix="NIDAQ-Heartbeat", kind=Kind.config, auto_monitor=True)
|
||||||
@@ -357,7 +504,7 @@ class Nidaq(PSIDeviceBase, NidaqControl):
|
|||||||
super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs)
|
super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs)
|
||||||
self.scan_info: ScanInfo
|
self.scan_info: ScanInfo
|
||||||
self.timeout_wait_for_signal = 5 # put 5s firsts
|
self.timeout_wait_for_signal = 5 # put 5s firsts
|
||||||
self._timeout_wait_for_pv = 3 # 3s timeout for pv calls
|
self._timeout_wait_for_pv = 5 # 5s timeout for pv calls. editted due to timeout issues persisting
|
||||||
self.valid_scan_names = [
|
self.valid_scan_names = [
|
||||||
"xas_simple_scan",
|
"xas_simple_scan",
|
||||||
"xas_simple_scan_with_xrd",
|
"xas_simple_scan_with_xrd",
|
||||||
@@ -556,7 +703,11 @@ class Nidaq(PSIDeviceBase, NidaqControl):
|
|||||||
# Stage call to IOC
|
# Stage call to IOC
|
||||||
status = CompareStatus(self.state, NidaqState.STAGE)
|
status = CompareStatus(self.state, NidaqState.STAGE)
|
||||||
self.cancel_on_stop(status)
|
self.cancel_on_stop(status)
|
||||||
self.stage_call.set(1).wait(timeout=self._timeout_wait_for_pv)
|
# TODO 11.11.25/HS64
|
||||||
|
# Switched from set to put in the hope to get rid of the rare event where nidaq is stopped at the start of a scan
|
||||||
|
# Problems consistently persisting, testing changing back to set, unconvinced this is the actual cause 14.11.25/AHC
|
||||||
|
# self.stage_call.set(1).wait(timeout=self._timeout_wait_for_pv)
|
||||||
|
self.stage_call.put(1)
|
||||||
status.wait(timeout=self.timeout_wait_for_signal)
|
status.wait(timeout=self.timeout_wait_for_signal)
|
||||||
if self.scan_info.msg.scan_name != "nidaq_continuous_scan":
|
if self.scan_info.msg.scan_name != "nidaq_continuous_scan":
|
||||||
status = self.on_kickoff()
|
status = self.on_kickoff()
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import enum
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Tuple
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from bec_lib.file_utils import get_full_path
|
from bec_lib.file_utils import get_full_path
|
||||||
from bec_lib.logger import bec_logger
|
from bec_lib.logger import bec_logger
|
||||||
from ophyd import Component as Cpt
|
from ophyd import Component as Cpt
|
||||||
from ophyd import EpicsSignal, Kind
|
from ophyd import EpicsSignal, EpicsSignalRO, Kind
|
||||||
from ophyd.areadetector.cam import ADBase, PilatusDetectorCam
|
from ophyd.areadetector.cam import ADBase, PilatusDetectorCam
|
||||||
from ophyd.areadetector.plugins import HDF5Plugin_V22 as HDF5Plugin
|
from ophyd.areadetector.plugins import HDF5Plugin_V22 as HDF5Plugin
|
||||||
from ophyd.areadetector.plugins import ImagePlugin_V22 as ImagePlugin
|
from ophyd.areadetector.plugins import ImagePlugin_V22 as ImagePlugin
|
||||||
@@ -145,6 +145,19 @@ class Pilatus(PSIDeviceBase, ADBase):
|
|||||||
|
|
||||||
# USER_ACCESS = ["start_live_mode", "stop_live_mode"]
|
# USER_ACCESS = ["start_live_mode", "stop_live_mode"]
|
||||||
|
|
||||||
|
cam_gain_menu_string = Cpt(EpicsSignalRO, suffix='cam1:GainMenu', string=True)
|
||||||
|
|
||||||
|
_default_configuration_attrs = [
|
||||||
|
'cam.threshold_energy',
|
||||||
|
'cam.threshold_auto_apply',
|
||||||
|
'cam.gain_menu',
|
||||||
|
'cam_gain_menu_string',
|
||||||
|
'cam.pixel_cut_off',
|
||||||
|
'cam.acquire_time',
|
||||||
|
'cam.num_exposures',
|
||||||
|
'cam.model',
|
||||||
|
]
|
||||||
|
|
||||||
cam = Cpt(PilatusDetectorCam, "cam1:")
|
cam = Cpt(PilatusDetectorCam, "cam1:")
|
||||||
hdf = Cpt(HDF5Plugin, "HDF1:")
|
hdf = Cpt(HDF5Plugin, "HDF1:")
|
||||||
image1 = Cpt(ImagePlugin, "image1:")
|
image1 = Cpt(ImagePlugin, "image1:")
|
||||||
@@ -203,22 +216,11 @@ class Pilatus(PSIDeviceBase, ADBase):
|
|||||||
PreviewSignal,
|
PreviewSignal,
|
||||||
name="preview",
|
name="preview",
|
||||||
ndim=2,
|
ndim=2,
|
||||||
num_rotation_90=0, # Check this
|
num_rotation_90=3,
|
||||||
doc="Preview signal for the Pilatus Detector",
|
doc="Preview signal for the Pilatus Detector",
|
||||||
)
|
)
|
||||||
file_event = Cpt(FileEventSignal, name="file_event")
|
file_event = Cpt(FileEventSignal, name="file_event")
|
||||||
|
|
||||||
@property
|
|
||||||
def baseline_signals(self):
|
|
||||||
"""Define baseline signals"""
|
|
||||||
return [
|
|
||||||
self.cam.acquire_time,
|
|
||||||
self.cam.num_exposures,
|
|
||||||
self.cam.threshold_energy,
|
|
||||||
self.cam.gain_menu,
|
|
||||||
self.cam.pixel_cut_off,
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@@ -366,68 +368,51 @@ class Pilatus(PSIDeviceBase, ADBase):
|
|||||||
status = status_acquire & status_writing & status_cam_server
|
status = status_acquire & status_writing & status_cam_server
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def _calculate_trigger(self, scan_msg: ScanStatusMessage):
|
def _calculate_trigger(self, scan_msg: ScanStatusMessage) -> Tuple[float, float]:
|
||||||
self._update_scan_parameter()
|
self._update_scan_parameter()
|
||||||
total_osc = 0
|
total_osc = 0
|
||||||
|
calc_duration = 0
|
||||||
total_trig_lo = 0
|
total_trig_lo = 0
|
||||||
total_trig_hi = 0
|
total_trig_hi = 0
|
||||||
calc_duration = 0
|
# Switching high/low is intended as angle is inverse to energy and settings in BEC are always in energy
|
||||||
n_trig_lo = 1
|
loc_break_enable_low = self.scan_parameter.break_enable_high
|
||||||
n_trig_hi = 1
|
loc_break_time_low = self.scan_parameter.break_time_high
|
||||||
init_lo = 1
|
loc_cycle_low = self.scan_parameter.cycle_high
|
||||||
init_hi = 1
|
loc_break_enable_high = self.scan_parameter.break_enable_low
|
||||||
lo_done = 0
|
loc_break_time_high = self.scan_parameter.break_time_low
|
||||||
hi_done = 0
|
loc_cycle_high = self.scan_parameter.cycle_low
|
||||||
if not self.scan_parameter.break_enable_low:
|
|
||||||
lo_done = 1
|
if not loc_break_enable_low:
|
||||||
if not self.scan_parameter.break_enable_high:
|
loc_break_time_low = 0
|
||||||
hi_done = 1
|
loc_cycle_low = 1
|
||||||
start_time = time.time()
|
if not loc_break_enable_high:
|
||||||
while True:
|
loc_break_time_high = 0
|
||||||
# TODO, we should not use infinite loops, for now let's add the escape Timeout of 20s, but should eventually be reviewed.
|
loc_cycle_high = 1
|
||||||
if time.time() - start_time > 20:
|
|
||||||
raise RuntimeError(
|
total_osc = self.scan_parameter.scan_duration / (
|
||||||
f"Calculating the number of triggers for scan {scan_msg.scan_name} took more than 20 seconds, aborting."
|
self.scan_parameter.scan_time +
|
||||||
)
|
loc_break_time_low / (2 * loc_cycle_low) +
|
||||||
|
loc_break_time_high / (2 * loc_cycle_high)
|
||||||
|
)
|
||||||
|
total_osc = np.ceil(total_osc)
|
||||||
|
total_osc = total_osc + total_osc % 2 # round up to the next even number
|
||||||
|
|
||||||
|
if loc_break_enable_low:
|
||||||
|
total_trig_lo = np.floor(total_osc / (2 * loc_cycle_low))
|
||||||
|
if loc_break_enable_high:
|
||||||
|
total_trig_hi = np.floor(total_osc / (2 * loc_cycle_high))
|
||||||
|
calc_duration = total_osc * self.scan_parameter.scan_time + total_trig_lo * loc_break_time_low + total_trig_hi * loc_break_time_high
|
||||||
|
|
||||||
|
if calc_duration < self.scan_parameter.scan_duration:
|
||||||
|
# Due to inaccuracy in formula, this can happen, we then need to manually add two oscillations and recalculate the triggers
|
||||||
total_osc = total_osc + 2
|
total_osc = total_osc + 2
|
||||||
calc_duration = calc_duration + 2 * self.scan_parameter.scan_time
|
if loc_break_enable_low:
|
||||||
|
total_trig_lo = np.floor(total_osc / (2 * loc_cycle_low))
|
||||||
|
if loc_break_enable_high:
|
||||||
|
total_trig_hi = np.floor(total_osc / (2 * loc_cycle_high))
|
||||||
|
calc_duration = total_osc * self.scan_parameter.scan_time + total_trig_lo * loc_break_time_low + total_trig_hi * loc_break_time_high
|
||||||
|
|
||||||
if self.scan_parameter.break_enable_low and n_trig_lo >= self.scan_parameter.cycle_low:
|
return total_trig_lo, total_trig_hi
|
||||||
n_trig_lo = 1
|
|
||||||
calc_duration = calc_duration + self.scan_parameter.break_time_low
|
|
||||||
if init_lo:
|
|
||||||
lo_done = 1
|
|
||||||
init_lo = 0
|
|
||||||
else:
|
|
||||||
n_trig_lo += 1
|
|
||||||
|
|
||||||
if (
|
|
||||||
self.scan_parameter.break_enable_high
|
|
||||||
and n_trig_hi >= self.scan_parameter.cycle_high
|
|
||||||
):
|
|
||||||
n_trig_hi = 1
|
|
||||||
calc_duration = calc_duration + self.scan_parameter.break_time_high
|
|
||||||
if init_hi:
|
|
||||||
hi_done = 1
|
|
||||||
init_hi = 0
|
|
||||||
else:
|
|
||||||
n_trig_hi += 1
|
|
||||||
|
|
||||||
if lo_done and hi_done:
|
|
||||||
n = np.floor(self.scan_parameter.scan_duration / calc_duration)
|
|
||||||
total_osc = total_osc * n
|
|
||||||
if self.scan_parameter.break_enable_low:
|
|
||||||
total_trig_lo = n + 1
|
|
||||||
if self.scan_parameter.break_enable_high:
|
|
||||||
total_trig_hi = n + 1
|
|
||||||
calc_duration = calc_duration * n
|
|
||||||
lo_done = 0
|
|
||||||
hi_done = 0
|
|
||||||
|
|
||||||
if calc_duration >= self.scan_parameter.scan_duration:
|
|
||||||
break
|
|
||||||
|
|
||||||
return total_trig_lo + total_trig_hi
|
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Beamline Specific Implementations #
|
# Beamline Specific Implementations #
|
||||||
@@ -480,6 +465,14 @@ class Pilatus(PSIDeviceBase, ADBase):
|
|||||||
"""
|
"""
|
||||||
# self.stop_live_mode() # Make sure that live mode is stopped if scan runs
|
# self.stop_live_mode() # Make sure that live mode is stopped if scan runs
|
||||||
|
|
||||||
|
# If user has activated alignment mode on qt panel, switch back to multitrigger and stop acquisition
|
||||||
|
if self.cam.trigger_mode.get() != TRIGGERMODE.MULT_TRIGGER.value:
|
||||||
|
self.cam.trigger_mode.set(TRIGGERMODE.MULT_TRIGGER.value).wait(5)
|
||||||
|
if self.cam.acquire.get() == ACQUIREMODE.ACQUIRING.value:
|
||||||
|
self.cam.acquire.put(0)
|
||||||
|
status_cam = CompareStatus(self.cam.acquire, ACQUIREMODE.DONE.value)
|
||||||
|
status_cam.wait(timeout=5)
|
||||||
|
|
||||||
scan_msg: ScanStatusMessage = self.scan_info.msg
|
scan_msg: ScanStatusMessage = self.scan_info.msg
|
||||||
if scan_msg.scan_name in self.xas_xrd_scan_names:
|
if scan_msg.scan_name in self.xas_xrd_scan_names:
|
||||||
self._update_scan_parameter()
|
self._update_scan_parameter()
|
||||||
|
|||||||
@@ -69,11 +69,11 @@ class PilatusCurtain(PSIDeviceBase):
|
|||||||
|
|
||||||
def on_unstage(self) -> DeviceStatus | None:
|
def on_unstage(self) -> DeviceStatus | None:
|
||||||
"""Called while unstaging the device."""
|
"""Called while unstaging the device."""
|
||||||
return self.close()
|
# return self.close()
|
||||||
|
|
||||||
def on_stop(self) -> DeviceStatus | None:
|
def on_stop(self) -> DeviceStatus | None:
|
||||||
"""Called when the device is stopped."""
|
"""Called when the device is stopped."""
|
||||||
return self.close()
|
# return self.close()
|
||||||
|
|
||||||
def open(self) -> DeviceStatus | None:
|
def open(self) -> DeviceStatus | None:
|
||||||
"""Open the cover"""
|
"""Open the cover"""
|
||||||
|
|||||||
@@ -52,9 +52,15 @@ class Reffoilchanger(PSIDeviceBase):
|
|||||||
status = Cpt(
|
status = Cpt(
|
||||||
EpicsSignal, suffix="ES2-REF:SELN-FilterState-ENUM_RBV", kind="config", doc="Status"
|
EpicsSignal, suffix="ES2-REF:SELN-FilterState-ENUM_RBV", kind="config", doc="Status"
|
||||||
)
|
)
|
||||||
|
status_string = Cpt(
|
||||||
|
EpicsSignal, suffix="ES2-REF:SELN-FilterState-ENUM_RBV", kind="config", doc="Status", string=True
|
||||||
|
)
|
||||||
op_mode = Cpt(
|
op_mode = Cpt(
|
||||||
EpicsSignalWithRBV, suffix="ES2-REF:SELN-OpMode-ENUM", kind="config", doc="Status"
|
EpicsSignalWithRBV, suffix="ES2-REF:SELN-OpMode-ENUM", kind="config", doc="Status"
|
||||||
)
|
)
|
||||||
|
op_mode_string = Cpt(
|
||||||
|
EpicsSignalWithRBV, suffix="ES2-REF:SELN-OpMode-ENUM", kind="config", doc="Status", string=True
|
||||||
|
)
|
||||||
ref_set = Cpt(EpicsSignal, suffix="ES2-REF:SELN-SET", kind="config", doc="Requested reference")
|
ref_set = Cpt(EpicsSignal, suffix="ES2-REF:SELN-SET", kind="config", doc="Requested reference")
|
||||||
ref_rb = Cpt(
|
ref_rb = Cpt(
|
||||||
EpicsSignalRO, suffix="ES2-REF:SELN-RB", kind="config", doc="Currently set reference"
|
EpicsSignalRO, suffix="ES2-REF:SELN-RB", kind="config", doc="Currently set reference"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Topic :: Scientific/Engineering",
|
"Topic :: Scientific/Engineering",
|
||||||
]
|
]
|
||||||
dependencies = ["numpy", "scipy", "bec_lib", "h5py", "ophyd_devices"]
|
dependencies = ["numpy", "scipy", "bec_lib", "h5py", "ophyd_devices", "opencv-python==4.11.0.86"]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
|
|||||||
Reference in New Issue
Block a user