Add curent_foil to reference foil changer
CI for debye_bec / test (pull_request) Successful in 1m49s
CI for debye_bec / test (push) Successful in 3m15s

This commit is contained in:
2026-09-24 08:08:21 +02:00
parent 93d5a4d03d
commit 64a8cc035f
2 changed files with 78 additions and 3 deletions
+67 -2
View File
@@ -5,8 +5,9 @@ from __future__ import annotations
import enum
from typing import TYPE_CHECKING
from bec_lib.logger import bec_logger
from ophyd import Component as Cpt
from ophyd import EpicsSignal, EpicsSignalRO, EpicsSignalWithRBV
from ophyd import EpicsSignal, EpicsSignalRO, EpicsSignalWithRBV, Signal
from ophyd.status import DeviceStatus
from ophyd_devices.interfaces.base_classes.psi_device_base import PSIDeviceBase
from ophyd_devices.utils.errors import DeviceStopError
@@ -14,6 +15,8 @@ from ophyd_devices.utils.errors import DeviceStopError
if TYPE_CHECKING:
from bec_lib.devicemanager import ScanInfo
logger = bec_logger.logger
class Status(int, enum.Enum):
"""Enum class for the status field"""
@@ -34,6 +37,63 @@ class OpMode(int, enum.Enum):
ERRORMODE = 3
N_FOILS = 38
class CurrentFoilSignal(Signal):
"""
Soft signal reflecting the description of the foil currently
inserted. Recomputed whenever 'ref_rb', 'status' or any of the
`foilNN` signals on the parent device change.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._subscribed = False
def _foil_signal(self):
if self.parent.status.get() != Status.INSERTED:
return None
idx = self.parent.ref_rb.get()
try:
idx = int(round(idx)) + 1
except (TypeError, ValueError):
return None
return getattr(self.parent, f"foil{idx:02d}", None)
def _compute(self):
sig = self._foil_signal()
if sig is None:
return ""
try:
return sig.get()
except Exception:
logger.exception("current_foil: failed to read %s", sig.name)
return ""
def get(self, **kwargs):
self._readback = self._compute()
return self._readback
def _on_upstream_change(self, value=None, timestamp=None, **kwargs):
old_value = self._readback
new_value = self._compute()
self._readback = new_value
self._run_subs(
sub_type=self.SUB_VALUE, old_value=old_value, value=new_value, timestamp=timestamp
)
def subscribe_to_parent_signals(self):
if self._subscribed:
return
self.parent.ref_rb.subscribe(self._on_upstream_change, run=False)
self.parent.status.subscribe(self._on_upstream_change, run=False)
for i in range(1, N_FOILS + 1):
getattr(self.parent, f"foil{i:02d}").subscribe(self._on_upstream_change, run=False)
self._subscribed = True
self._readback = self._compute()
class Reffoilchanger(PSIDeviceBase):
"""Class for the ES2 Reference Foil Changer"""
@@ -71,8 +131,12 @@ class Reffoilchanger(PSIDeviceBase):
)
ref_set = Cpt(EpicsSignal, suffix="ES2-REF:SELN-SET", kind="config", doc="Requested reference")
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 (angle)",
)
current_foil = Cpt(CurrentFoilSignal, value="", kind="normal", doc="Inserted reference")
foil01 = Cpt(EpicsSignalRO, suffix="ES-REFFOIL:FOIL01.DESC", kind="config", doc="Foil 01")
foil02 = Cpt(EpicsSignalRO, suffix="ES-REFFOIL:FOIL02.DESC", kind="config", doc="Foil 02")
@@ -115,6 +179,7 @@ class Reffoilchanger(PSIDeviceBase):
def __init__(self, *, name: str, prefix: str = "", scan_info: ScanInfo | None = None, **kwargs):
super().__init__(name=name, prefix=prefix, scan_info=scan_info, **kwargs)
self.current_foil.subscribe_to_parent_signals()
self.foils = [
self.foil01,
+11 -1
View File
@@ -236,7 +236,9 @@ class DebyeNexusStructure(DefaultFormat):
self.configuration.get("nidaq", {}).get("nidaq_add_chans", {}).get("value")
)
rle = self.configuration.get("nidaq", {}).get("nidaq_enable_compression", {}).get("value")
rle = (
self.configuration.get("nidaq", {}).get("nidaq_enable_compression", {}).get("value")
)
measurement_mode = entry.create_group(name="mode")
measurement_mode.attrs["NX_class"] = "NX_CHAR"
@@ -288,6 +290,14 @@ class DebyeNexusStructure(DefaultFormat):
)
ref_trans.attrs["NX_class"] = "NX_CHAR"
foil = (
self.device_manager.devices.reffoilchanger.read(cached=True)
.get("current_foil")
.get("value")
)
ref_foil = ai2ai4_active.create_dataset(name="Reference", data=foil)
ref_foil.attrs["NX_class"] = "NX_CHAR"
main_data = entry.create_group(name="data")
main_data.attrs["NX_class"] = "NXdata"