From eee88565655eaab62ec66f018dcbe02d09594716 Mon Sep 17 00:00:00 2001 From: Klaus Wakonig Date: Wed, 28 Jun 2023 11:11:43 +0200 Subject: [PATCH] fix: adjustments for new bec_lib --- .gitlab-ci.yml | 2 +- ophyd_devices/eiger1p5m_csaxs/eiger1p5m.py | 2 +- ophyd_devices/epics/devices/X07MADevices.py | 2 +- ophyd_devices/galil/galil_ophyd.py | 5 +- ophyd_devices/rt_lamni/rt_lamni_ophyd.py | 3 +- ophyd_devices/sim/sim.py | 121 +++++++++++++++++++- ophyd_devices/smaract/smaract_ophyd.py | 3 +- ophyd_devices/utils/socket.py | 2 +- 8 files changed, 130 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4ec6ea0..0ca69e0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,5 +20,5 @@ pytest: stage: Test script: - git clone https://oauth2:$CI_BEC_KEY@gitlab.psi.ch/bec/bec.git - - pip install -e ./bec/bec_client_lib + - pip install -e ./bec/bec_lib - pytest -v ./tests diff --git a/ophyd_devices/eiger1p5m_csaxs/eiger1p5m.py b/ophyd_devices/eiger1p5m_csaxs/eiger1p5m.py index b46d62b..2d6c572 100644 --- a/ophyd_devices/eiger1p5m_csaxs/eiger1p5m.py +++ b/ophyd_devices/eiger1p5m_csaxs/eiger1p5m.py @@ -2,7 +2,7 @@ import os import time from typing import List -from bec_client_lib.core import BECMessage, MessageEndpoints, bec_logger +from bec_lib.core import BECMessage, MessageEndpoints, bec_logger from ophyd import Component as Cpt from ophyd import Device, DeviceStatus, EpicsSignal, EpicsSignalRO, Signal diff --git a/ophyd_devices/epics/devices/X07MADevices.py b/ophyd_devices/epics/devices/X07MADevices.py index 65a2a5e..f082cb5 100644 --- a/ophyd_devices/epics/devices/X07MADevices.py +++ b/ophyd_devices/epics/devices/X07MADevices.py @@ -6,7 +6,7 @@ import traceback from collections import OrderedDict from typing import Any -from bec_client_lib.core import bec_logger +from bec_lib.core import bec_logger from ophyd import Component as Cpt from ophyd import Device, EpicsMotor, EpicsSignal, EpicsSignalRO from ophyd import FormattedComponent as FCpt diff --git a/ophyd_devices/galil/galil_ophyd.py b/ophyd_devices/galil/galil_ophyd.py index 2074203..6b5755a 100644 --- a/ophyd_devices/galil/galil_ophyd.py +++ b/ophyd_devices/galil/galil_ophyd.py @@ -4,14 +4,15 @@ import time from typing import List import numpy as np -from bec_client_lib.core import bec_logger +from bec_lib.core import bec_logger from ophyd import Component as Cpt from ophyd import Device, PositionerBase, Signal from ophyd.status import wait as status_wait from ophyd.utils import LimitError, ReadOnlyError +from prettytable import PrettyTable + from ophyd_devices.utils.controller import Controller, threadlocked from ophyd_devices.utils.socket import SocketIO, SocketSignal, raise_if_disconnected -from prettytable import PrettyTable logger = bec_logger.logger diff --git a/ophyd_devices/rt_lamni/rt_lamni_ophyd.py b/ophyd_devices/rt_lamni/rt_lamni_ophyd.py index 91bd265..f8671ab 100644 --- a/ophyd_devices/rt_lamni/rt_lamni_ophyd.py +++ b/ophyd_devices/rt_lamni/rt_lamni_ophyd.py @@ -4,11 +4,12 @@ import time from typing import List import numpy as np -from bec_client_lib.core import BECMessage, MessageEndpoints, bec_logger +from bec_lib.core import BECMessage, MessageEndpoints, bec_logger from ophyd import Component as Cpt from ophyd import Device, PositionerBase, Signal from ophyd.status import wait as status_wait from ophyd.utils import LimitError, ReadOnlyError + from ophyd_devices.utils.controller import Controller, threadlocked from ophyd_devices.utils.socket import SocketIO, SocketSignal, raise_if_disconnected diff --git a/ophyd_devices/sim/sim.py b/ophyd_devices/sim/sim.py index da750d5..c26a679 100644 --- a/ophyd_devices/sim/sim.py +++ b/ophyd_devices/sim/sim.py @@ -5,10 +5,10 @@ import warnings from typing import List import numpy as np -from bec_client_lib.core import BECMessage, MessageEndpoints, bec_logger +from bec_lib.core import BECMessage, MessageEndpoints, bec_logger from ophyd import Component as Cpt from ophyd import Device, DeviceStatus, OphydObject, PositionerBase, Signal -from ophyd.sim import _ReadbackSignal, _SetpointSignal +from ophyd.sim import EnumSignal, SynSignal, _ReadbackSignal, _SetpointSignal from ophyd.utils import LimitError, ReadOnlyError logger = bec_logger.logger @@ -66,6 +66,39 @@ class _ReadbackSignal(Signal): raise ReadOnlyError("The signal {} is readonly.".format(self.name)) +class _ReadbackSignalCompute(Signal): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._metadata.update( + connected=True, + write_access=False, + ) + + def get(self): + readback = self.parent._compute() + self._readback = self.parent.sim_state["readback"] = readback + return readback + + def describe(self): + res = super().describe() + # There should be only one key here, but for the sake of + # generality.... + for k in res: + res[k]["precision"] = self.parent.precision + return res + + @property + def timestamp(self): + """Timestamp of the readback value""" + return self.parent.sim_state["readback_ts"] + + def put(self, value, *, timestamp=None, force=False): + raise ReadOnlyError("The signal {} is readonly.".format(self.name)) + + def set(self, value, *, timestamp=None, force=False): + raise ReadOnlyError("The signal {} is readonly.".format(self.name)) + + class _ReadbackSignalRand(Signal): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -747,6 +780,90 @@ class SynAxisOPAAS(Device, PositionerBase): return "mm" +class SynGaussBEC(Device): + """ + Evaluate a point on a Gaussian based on the value of a motor. + + Parameters + ---------- + name : string + motor : Device + motor_field : string + center : number + center of peak + Imax : number + max intensity of peak + sigma : number, optional + Default is 1. + noise : {'poisson', 'uniform', None}, optional + Add noise to the gaussian peak. + noise_multiplier : float, optional + Only relevant for 'uniform' noise. Multiply the random amount of + noise by 'noise_multiplier' + random_state : numpy random state object, optional + np.random.RandomState(0), to generate random number with given seed + + Example + ------- + motor = SynAxis(name='motor') + det = SynGauss('det', motor, 'motor', center=0, Imax=1, sigma=1) + """ + + val = Cpt(_ReadbackSignalCompute, value=0, kind="hinted") + Imax = Cpt(Signal, value=10, kind="config") + center = Cpt(Signal, value=0, kind="config") + sigma = Cpt(Signal, value=1, kind="config") + motor = Cpt(Signal, value="samx", kind="config") + noise = Cpt( + EnumSignal, + value="none", + kind="config", + enum_strings=("none", "poisson", "uniform"), + ) + noise_multiplier = Cpt(Signal, value=1, kind="config") + + def __init__(self, name, *, device_manager=None, random_state=None, **kwargs): + self.device_manager = device_manager + set_later = {} + for k in ("sigma", "noise", "noise_multiplier"): + v = kwargs.pop(k, None) + if v is not None: + set_later[k] = v + super().__init__(name=name, **kwargs) + + self.random_state = random_state or np.random + self.val.name = self.name + self.precision = 3 + self.sim_state = {"readback": 0, "readback_ts": ttime.time()} + for k, v in set_later.items(): + getattr(self, k).put(v) + + def _compute(self): + try: + m = self.device_manager.devices[self.motor.get()].obj.read()[self.motor.get()]["value"] + # we need to do this one at a time because + # - self.read() may be screwed with by the user + # - self.get() would cause infinite recursion + Imax = self.Imax.get() + center = self.center.get() + sigma = self.sigma.get() + noise = self.noise.get() + noise_multiplier = self.noise_multiplier.get() + v = Imax * np.exp(-((m - center) ** 2) / (2 * sigma**2)) + if noise == "poisson": + v = int(self.random_state.poisson(np.round(v), 1)) + elif noise == "uniform": + v += self.random_state.uniform(-1, 1) * noise_multiplier + return v + except Exception: + return 0 + + def get(self, *args, **kwargs): + self.sim_state["readback"] = self._compute() + self.sim_state["readback_ts"] = ttime.time() + return self.val.get() + + class SynDeviceSubOPAAS(Device): zsub = Cpt(SynAxisOPAAS, name="zsub") diff --git a/ophyd_devices/smaract/smaract_ophyd.py b/ophyd_devices/smaract/smaract_ophyd.py index 72d6b8e..638cced 100644 --- a/ophyd_devices/smaract/smaract_ophyd.py +++ b/ophyd_devices/smaract/smaract_ophyd.py @@ -4,11 +4,12 @@ import time from typing import List import numpy as np -from bec_client_lib.core import bec_logger +from bec_lib.core import bec_logger from ophyd import Component as Cpt from ophyd import Device, PositionerBase, Signal from ophyd.status import wait as status_wait from ophyd.utils import LimitError, ReadOnlyError + from ophyd_devices.smaract.smaract_controller import SmaractController from ophyd_devices.smaract.smaract_errors import SmaractCommunicationError, SmaractError from ophyd_devices.utils.controller import threadlocked diff --git a/ophyd_devices/utils/socket.py b/ophyd_devices/utils/socket.py index 07a6ce2..3bcd61b 100644 --- a/ophyd_devices/utils/socket.py +++ b/ophyd_devices/utils/socket.py @@ -6,7 +6,7 @@ import time import typing import numpy as np -from bec_client_lib.core import bec_logger +from bec_lib.core import bec_logger from ophyd import Signal from ophyd.utils.errors import DisconnectedError