from types import SimpleNamespace from time import sleep import numpy as np from slic.core.adjustable import Adjustable, PVAdjustable, PVEnumAdjustable from slic.core.device import Device from slic.utils.hastyepics import get_pv as PV from slic.devices.general.motor import Motor class BerninaMono(Device): def __init__(self, ID, name="Bernina DCM", **kwargs): super().__init__(ID, name=name, **kwargs) self.theta = Motor(ID + ":RX12") self.x = Motor(ID + ":TX12") self.gap = Motor(ID + ":T2") self.roll1 = Motor(ID + ":RZ1") self.roll2 = Motor(ID + ":RZ2") self.pitch2 = Motor(ID + ":RX2") self.energy = DoubleCrystalMonoEnergy(ID, name=name) class DoubleCrystalMonoEnergy(Adjustable): def __init__(self, ID, name=None): self.wait_time = 0.1 pvname_setvalue = "SAROP21-ARAMIS:ENERGY_SP" pvname_readback = "SAROP21-ARAMIS:ENERGY" pvname_moving = "SAROP21-ODCM098:MOVING" pvname_stop = "SAROP21-ODCM098:STOP.PROC" pv_setvalue = PV(pvname_setvalue) pv_readback = PV(pvname_readback) pv_moving = PV(pvname_moving) pv_stop = PV(pvname_stop) units = pv_readback.units super().__init__(ID, name=name, units=units) self.pvnames = SimpleNamespace( setvalue = pvname_setvalue, readback = pvname_readback, moving = pvname_moving, stop = pvname_stop ) self.pvs = SimpleNamespace( setvalue = pv_setvalue, readback = pv_readback, moving = pv_moving, stop = pv_stop ) def get_current_value(self): return self.pvs.readback.get() def set_current_value(self, value): self.pvs.setvalue.put(value) sleep(3) def set_target_value(self, value): self.set_current_value(value) # while abs(self.wait_for_valid_value() - value) > accuracy: while self.is_moving(): sleep(self.wait_time) def wait_for_valid_value(self): val = np.nan while not np.isfinite(val): val = self.get_current_value() return val def is_moving(self): moving = self.pvs.moving.get() return bool(moving) def stop(self): self.pvs.stop.put(1)