From 53d1798c84fc6de4c36ac5b9193ba124de739ece Mon Sep 17 00:00:00 2001 From: gac-x12sa Date: Tue, 15 Jul 2025 16:56:01 +0200 Subject: [PATCH] feat: added xbpm device and added in config --- csaxs_bec/device_configs/frontend.yaml | 11 ++++ csaxs_bec/devices/epics/xbpms.py | 78 ++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 csaxs_bec/devices/epics/xbpms.py diff --git a/csaxs_bec/device_configs/frontend.yaml b/csaxs_bec/device_configs/frontend.yaml index ea25451..be8936f 100644 --- a/csaxs_bec/device_configs/frontend.yaml +++ b/csaxs_bec/device_configs/frontend.yaml @@ -135,4 +135,15 @@ xbpm1c4: enabled: true readoutPriority: monitored readOnly: true + softwareTrigger: false + +xbpm1: + description: 'XBPM1 (frontend)' + deviceClass: csaxs_bec.devices.epics.xbpms.BPMDevice + deviceConfig: + prefix: 'X12SA-FE-XBPM1' + onFailure: raise + enabled: true + readoutPriority: monitored + readOnly: true softwareTrigger: false \ No newline at end of file diff --git a/csaxs_bec/devices/epics/xbpms.py b/csaxs_bec/devices/epics/xbpms.py new file mode 100644 index 0000000..27e5927 --- /dev/null +++ b/csaxs_bec/devices/epics/xbpms.py @@ -0,0 +1,78 @@ +from ophyd import Signal, Device, EpicsSignalRO +from ophyd import Component as Cpt + +class SumSignal(Signal): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._metadata.update(write_access=False) + + def wait_for_connection(self, timeout=0): + super().wait_for_connection(timeout) + self._metadata.update(connected=True) + + def get(self, **kwargs): + val1 = self.parent.current1.get() + val2 = self.parent.current2.get() + val3 = self.parent.current3.get() + val4 = self.parent.current4.get() + return val1 + val2 + val3 + val4 + + def describe(self): + desc = { + "shape": [], + "dtype": "number", + "source": "PV: {} / {}".format(self.parent.current1.pvname, self.parent.current1.pvname), + "units": "", + "precision": self.parent.current1.precision, + } + return desc + +class DiffXYSignal(Signal): + def __init__(self, sum1, sum2, *args, **kwargs): + self.sum1 = sum1 + self.sum2 = sum2 + super().__init__(*args, **kwargs) + self._metadata.update(write_access=False) + + def wait_for_connection(self, timeout=0): + super().wait_for_connection(timeout) + self._metadata.update(connected=True) + + def get(self, **kwargs): + summed_1 = 0 + summed_2 = 0 + for signal in self.sum1: + summed_1 += getattr(self.parent, signal).get() + for signal in self.sum2: + summed_2 += getattr(self.parent, signal).get() + + return summed_1 - summed_2 + + def describe(self): + desc = { + "shape": [], + "dtype": "number", + "source": "PV: {} / {}".format(self.parent.current1.pvname, self.parent.current1.pvname), + "units": "", + "precision": self.parent.current1.precision, + } + return desc + +class BPMDevice(Device): + current1 = Cpt(EpicsSignalRO, ":Current1:MeanValue_RBV", kind="normal") + current2 = Cpt(EpicsSignalRO, ":Current2:MeanValue_RBV", kind="normal") + current3 = Cpt(EpicsSignalRO, ":Current3:MeanValue_RBV", kind="normal") + current4 = Cpt(EpicsSignalRO, ":Current4:MeanValue_RBV", kind="normal") + sum = Cpt(SumSignal, kind="hinted") + x = Cpt(DiffXYSignal, sum1=["current1", "current2"], sum2=["current3", "current4"]) + y = Cpt(DiffXYSignal, sum1=["current1", "current3"], sum2=["current2", "current4"]) + + def __init__(self, prefix="", *args, **kwargs): + super().__init__(*args, prefix=prefix, **kwargs) + + + +if __name__ == "__main__": + dev = BPMDevice(name="bpm", prefix='X12SA-FE-XBPM1') + dev.wait_for_connection() + print(dev.read()) \ No newline at end of file