From 37e9e75dd27a10ee52f2e596e1c111a8452586c2 Mon Sep 17 00:00:00 2001 From: Roman Mankowsky Date: Tue, 17 Nov 2020 10:37:36 +0100 Subject: [PATCH] Added new implementation of smaract --- eco/devices_general/adjustable.py | 31 ++- eco/devices_general/motors.py | 313 ++++++++++++++++++++++++++++-- eco/loptics/bernina_experiment.py | 101 +++++----- eco/xoptics/dcm_new.py | 2 +- eco/xoptics/kb_bernina.py | 28 +-- 5 files changed, 390 insertions(+), 85 deletions(-) diff --git a/eco/devices_general/adjustable.py b/eco/devices_general/adjustable.py index c3cc43e..c045189 100644 --- a/eco/devices_general/adjustable.py +++ b/eco/devices_general/adjustable.py @@ -376,11 +376,21 @@ class PvRecord: # @default_representation @spec_convenience class PvEnum: - def __init__(self, pvname, name=None): + def __init__(self, pvname, pvname_set=None, name=None): self.Id = pvname self._pv = PV(pvname) self.name = name self.enum_strs = self._pv.enum_strs + + if pvname_set: + self._pv_set = PV(pvname_set) + tstrs = self._pv_set.enum_strs + if not (tstrs == self.enum_strs): + raise Exception("pv enum setter strings do not match the values!") + + else: + self._pv_set = None + if name: enumname = self.name else: @@ -402,8 +412,11 @@ class PvEnum: def set_target_value(self, value, hold=False): """ Adjustable convention""" value = self.validate(value) - - changer = lambda value: self._pv.put(value, wait=True) + if self._pv_set: + tpv = self._pv_set + else: + tpv = self._pv + changer = lambda value: tpv.put(value, wait=True) return Changer( target=value, parent=self, changer=changer, hold=hold, stopper=None ) @@ -425,6 +438,7 @@ class PvEnum: s += "{:>4} {} {}\n".format(val, sel, name) return s + class PvString: def __init__(self, pvname, name=None, elog=None): self.name = name @@ -441,7 +455,7 @@ class PvString: return Changer( target=value, parent=self, changer=changer, hold=hold, stopper=None ) - + def __repr__(self): return self.get_current_value() @@ -451,6 +465,7 @@ class PvString: else: return self.get_current_value() + @default_representation @spec_convenience class AdjustableVirtual: @@ -536,8 +551,10 @@ class AdjustableGetSet: self._set = foo_set self._get = foo_get - def set_target_value(self,value): - return Changer(target=value, parent=self, changer=self._set, hold=False, stopper=None) - + def set_target_value(self, value): + return Changer( + target=value, parent=self, changer=self._set, hold=False, stopper=None + ) + def get_current_value(self): return self._get() diff --git a/eco/devices_general/motors.py b/eco/devices_general/motors.py index 52bf6e7..037f375 100755 --- a/eco/devices_general/motors.py +++ b/eco/devices_general/motors.py @@ -12,7 +12,9 @@ from ..utilities.KeyPress import KeyPress import sys, colorama from .. import global_config from ..elements.assembly import Assembly +import time from .adjustable import PvRecord, PvEnum, PvString +import numpy as np if hasattr(global_config, "elog"): elog = global_config.elog @@ -54,13 +56,279 @@ def _keywordChecker(kw_key_list_tups): @spec_convenience @update_changes -class MotorRecord_new(Assembly): +class SmaractStreamdevice(Assembly): + def __init__( + self, + pvname, + accuracy=1e-3, + name=None, + elog=None, + alias_fields={ + "readback": "MOTRBV", + "user_set_pos": "SET_POS", + "user_direction": "DIR", + }, + ): + super().__init__(name=name) + self.settings.append(self) + + self.pvname = pvname + self._elog = elog + for an, af in alias_fields.items(): + self.alias.append( + Alias(an, channel=":".join([pvname, af]), channeltype="CA") + ) + self._currentChange = None + # self.description = EpicsString(pvname + ".DESC") + self._append(PvEnum, self.pvname + ":DIR", name="direction", is_setting=True) + self._append( + PvRecord, self.pvname + ":SET_POS", name="set_pos", is_setting=True + ) + self._append( + PvRecord, self.pvname + ":GET_HOMED", name="speed", is_setting=False + ) + self._append( + PvRecord, + self.pvname + ":FRM_BACK.PROC", + name="home_backward", + is_setting=False, + ) + self._append( + PvRecord, + self.pvname + ":FRM_FORW.PROC", + name="home_forward", + is_setting=False, + ) + self._append( + PvRecord, self.pvname + ":GET_HOMED", name="is_homed", is_setting=False + ) + self._append( + PvRecord, + self.pvname + ":CALIBRATE.PROC", + name="calibrate_sensor", + is_setting=False, + ) + self._append( + PvRecord, + self.pvname + ":CL_MAX_FREQ", + name="maximum_frequency", + is_setting=False, + ) + self._append( + PvRecord, + self.pvname + ":HOLD", + name="holding_time_ms", + is_setting=True, + ) + self._append( + PvRecord, + self.pvname + ":AMPLITUDE", + name="voltage_4KADU_per_100V", + is_setting=True, + ) + self._append( + PvRecord, + self.pvname + ":DRIVE", + name="_drive", + is_setting=False, + ) + self._append( + PvRecord, + self.pvname + ":MOTRBV", + name="_readback", + is_setting=False, + ) + self._append( + PvEnum, self.pvname + ":STAGE_TYPE", name="stage_type", is_setting=True + ) + self._append( + PvEnum, self.pvname + ":STATUS", name="status_channel", is_setting=False + ) + self._append( + PvEnum, + self.pvname + ":GET_SENSOR_TYPE", + pvname_set=self.pvname + ":SET_SENSOR_TYPE", + name="sensor_type", + is_setting=True, + ) + self._append(PvRecord, self.pvname + ":LLM", name="limit_low", is_setting=False) + self._append( + PvRecord, self.pvname + ":HLM", name="limit_high", is_setting=False + ) + self.accuracy = accuracy + self._stop_pv = PV(self.pvname + ":STOP.PROC") + self.stop = lambda: self._stop_pv.put(1) + + def set_target_value(self, value, hold=False, check=True): + def changer(value): + self._drive.set_target_value(value) + + # self._status_message = _status_messages[self._status] + # if self._status < 0: + # raise AdjustableError(self._status_message) + # elif self._status > 0: + # print("\n") + # print(self._status_message) + + changer = lambda value: self.move(value, check=check) + return Changer( + target=value, + parent=self, + changer=changer, + hold=hold, + stopper=self.stop, + ) + + def get_current_value(self): + return self._readback.get_current_value() + + def get_close_to(self, value, accuracy): + movedone = 1 + if np.abs(value - self.get_current_value()) > accuracy: + movedone = 0 + return movedone + + def move(self, value, check=True, update_value_time=0.05, timeout=120): + if check: + lim_low, lim_high = self.get_limits() + if not (lim_low < value) and (value < lim_high): + raise AdjustableError("Soft limits violated!") + t_start = time.time() + self._drive.set_target_value(value) + while not self.get_close_to(value, self.accuracy): + if (time.time() - t_start) > timeout: + raise AdjustableError( + f"motion timeout reached in smaract {self.name}:{self.pvname}" + ) + time.sleep(update_value_time) + + def add_value_callback(self, callback, index=None): + return self._readback._pv.add_callback(callback=callback, index=index) + + def clear_value_callback(self, index=None): + if index: + self._readback._pv.remove_callback(index) + else: + self._readback._pv.clear_callbacks() + + def get_limits(self): + return self.limit_low.get_current_value(), self.limit_high.get_current_value() + + def set_limits(self, low_limit, high_limit, relative_to_present=False): + if relative_to_present: + tval = self.get_current_value() + low_limit += tval + high_limit += tval + self.limit_low.set_target_value(low_limit) + self.limit_high.set_target_value(high_limit) + + # return string with motor value as variable representation + def __str__(self): + # """ return short info for the current motor""" + s = f"{self.name}" + s += f"\t@ {colorama.Style.BRIGHT}{self.get_current_value():1.6g}{colorama.Style.RESET_ALL}" + # # s += "\tuser limits (low,high) : {:1.6g},{:1.6g}\n".format(*self.get_limits()) + s += f"\n{colorama.Style.DIM}low limit {colorama.Style.RESET_ALL}" + s += ValueInRange(*self.get_limits()).get_str(self.get_current_value()) + s += f" {colorama.Style.DIM}high limit{colorama.Style.RESET_ALL}" + # # s += "\tuser limits (low,high) : {:1.6g},{1.6g}".format(self.get_limits()) + return s + + def __repr__(self): + print(str(self)) + return object.__repr__(self) + + def __call__(self, value): + self._currentChange = self.set_target_value(value) + + def _tweak_ioc(self, step_value=None): + pv = PV(self.pvname + ":TWV") + pvf = PV(self.pvname + ":TWF.PROC") + pvr = PV(self.pvname + ":TWR.PROC") + if not step_value: + step_value = pv.get() + print(f"Tweaking {self.name} at step size {step_value}", end="\r") + + help = "q = exit; up = step*2; down = step/2, left = neg dir, right = pos dir\n" + help = help + "g = go abs, s = set" + print(f"tweaking {self.name}") + print(help) + print(f"Starting at {self.get_current_value()}") + step_value = float(step_value) + oldstep = 0 + k = KeyPress() + cll = colorama.ansi.clear_line() + + class Printer: + def print(self, **kwargs): + print( + cll + f"stepsize: {self.stepsize}; current: {kwargs['value']}", + end="\r", + ) + + p = Printer() + print(" ") + p.stepsize = step_value + p.print(value=self.get_current_value()) + ind_callback = self.add_value_callback(p.print) + pv.put(step_value) + while k.isq() is False: + if oldstep != step_value: + p.stepsize = step_value + p.print(value=self.get_current_value()) + oldstep = step_value + k.waitkey() + if k.isu(): + step_value = step_value * 2.0 + pv.put(step_value) + elif k.isd(): + step_value = step_value / 2.0 + pv.put(step_value) + elif k.isr(): + pvf.put(1) + elif k.isl(): + pvr.put(1) + elif k.iskey("g"): + print("enter absolute position (char to abort go to)") + sys.stdout.flush() + v = sys.stdin.readline() + try: + v = float(v.strip()) + self.set_target_value(v) + except: + print("value cannot be converted to float, exit go to mode ...") + sys.stdout.flush() + elif k.iskey("s"): + print("enter new set value (char to abort setting)") + sys.stdout.flush() + v = sys.stdin.readline() + try: + v = float(v[0:-1]) + self.reset_current_value_to(v) + except: + print("value cannot be converted to float, exit go to mode ...") + sys.stdout.flush() + elif k.isq(): + break + else: + print(help) + self.clear_value_callback(index=ind_callback) + print(f"final position: {self.get_current_value()}") + print(f"final tweak step: {pv.get()}") + + def tweak(self, *args, **kwargs): + return self._tweak_ioc(*args, **kwargs) + + +@spec_convenience +@update_changes +class MotorRecord(Assembly): def __init__( self, pvname, name=None, elog=None, - alias_fields={"readback": "RBV", "user_offset": "OFF"}, + alias_fields={"readback": "RBV", "user_offset": "OFF", "user_direction": "DIR"}, ): super().__init__(name=name) self.settings.append(self) @@ -74,17 +342,24 @@ class MotorRecord_new(Assembly): ) self._currentChange = None # self.description = EpicsString(pvname + ".DESC") - self._append(PvEnum,self.pvname+'.DIR',name='direction',is_setting=True) - self._append(PvRecord,self.pvname+'.OFF',name='offset',is_setting=True) - self._append(PvRecord,self.pvname+'.VELO',name='speed',is_setting=False) - self._append(PvRecord,self.pvname+'.ACCL',name='acceleration_time',is_setting=False) - self._append(PvRecord,self.pvname+'.LLM',name='limit_low',is_setting=False) - self._append(PvRecord,self.pvname+'.HLM',name='limit_high',is_setting=False) - self._append(PvEnum,self.pvname+'.SPMG',name='motor_state',is_setting=False) - self._append(PvString,self.pvname+'.EGU',name='unit',is_setting=False) - self._append(PvString,self.pvname+'.DESC',name='description',is_setting=False) + self._append(PvEnum, self.pvname + ".DIR", name="direction", is_setting=True) + self._append(PvRecord, self.pvname + ".OFF", name="offset", is_setting=True) + self._append(PvRecord, self.pvname + ".VELO", name="speed", is_setting=False) + self._append( + PvRecord, self.pvname + ".ACCL", name="acceleration_time", is_setting=False + ) + self._append(PvRecord, self.pvname + ".LLM", name="limit_low", is_setting=False) + self._append( + PvRecord, self.pvname + ".HLM", name="limit_high", is_setting=False + ) + self._append( + PvEnum, self.pvname + ".SPMG", name="motor_state", is_setting=False + ) + self._append(PvString, self.pvname + ".EGU", name="unit", is_setting=False) + self._append( + PvString, self.pvname + ".DESC", name="description", is_setting=False + ) - # Conventional methods and properties for all Adjustable objects def set_target_value(self, value, hold=False, check=True): """ Adjustable convention""" @@ -144,9 +419,9 @@ class MotorRecord_new(Assembly): def set_limits( self, low_limit, high_limit, posType="user", relative_to_present=False ): - """ + """ set limits. usage: set_limits(low_limit, high_limit) - + """ _keywordChecker([("posType", posType, _posTypes)]) ll_name, hl_name = "LLM", "HLM" @@ -283,9 +558,13 @@ class MotorRecord_new(Assembly): def tweak(self, *args, **kwargs): return self._tweak_ioc(*args, **kwargs) + +MotorRecord_new = MotorRecord + + @spec_convenience @update_changes -class MotorRecord: +class MotorRecord_old: def __init__( self, pvname, @@ -387,9 +666,9 @@ class MotorRecord: def set_limits( self, low_limit, high_limit, posType="user", relative_to_present=False ): - """ + """ set limits. usage: set_limits(low_limit, high_limit) - + """ _keywordChecker([("posType", posType, _posTypes)]) ll_name, hl_name = "LLM", "HLM" diff --git a/eco/loptics/bernina_experiment.py b/eco/loptics/bernina_experiment.py index 9e3be25..76212a2 100755 --- a/eco/loptics/bernina_experiment.py +++ b/eco/loptics/bernina_experiment.py @@ -13,13 +13,9 @@ from pint import UnitRegistry ureg = UnitRegistry() -def addPvRecordToSelf(self, - pvsetname, - pvreadbackname=None, - accuracy=None, - sleeptime=0, - name=None - ): +def addPvRecordToSelf( + self, pvsetname, pvreadbackname=None, accuracy=None, sleeptime=0, name=None +): try: self.__dict__[name] = PvRecord( pvsetname, @@ -27,11 +23,12 @@ def addPvRecordToSelf(self, accuracy=accuracy, sleeptime=sleeptime, name=name, - ) + ) self.alias.append(self.__dict__[name].alias) except: print(f"Warning! Could not find PV {name} (Id:{pvsetname} RB:{pvreadbackname})") + def addMotorRecordToSelf(self, Id=None, name=None): self.__dict__[name] = MotorRecord(Id, name=name) self.alias.append(self.__dict__[name].alias) @@ -47,13 +44,9 @@ def addDelayStageToSelf(self, stage=None, name=None): self.alias.append(self.__dict__[name].alias) -def addPvRecordToSelf(self, - pvsetname, - pvreadbackname=None, - accuracy=None, - sleeptime=0, - name=None - ): +def addPvRecordToSelf( + self, pvsetname, pvreadbackname=None, accuracy=None, sleeptime=0, name=None +): try: self.__dict__[name] = PvRecord( pvsetname, @@ -61,14 +54,12 @@ def addPvRecordToSelf(self, accuracy=accuracy, sleeptime=sleeptime, name=name, - ) + ) self.alias.append(self.__dict__[name].alias) except: print(f"Warning! Could not find PV {name} (Id:{pvsetname} RB:{pvreadbackname})") - - class DelayTime(AdjustableVirtual): def __init__( self, stage, direction=1, passes=2, reset_current_value_to=True, name=None @@ -76,7 +67,7 @@ class DelayTime(AdjustableVirtual): self._direction = direction self._group_velo = 299798458 # m/s self._passes = passes - self.Id = stage.Id + "_delay" + # self.Id = stage.Id + "_delay" self._stage = stage AdjustableVirtual.__init__( self, @@ -86,8 +77,20 @@ class DelayTime(AdjustableVirtual): reset_current_value_to=reset_current_value_to, name=name, ) - addPvRecordToSelf(self, pvsetname="SIN-TIMAST-TMA:Evt-22-Freq-SP", pvreadbackname ="SIN-TIMAST-TMA:Evt-22-Freq-I", accuracy= 0.5, name='frequency_pp') - addPvRecordToSelf(self, pvsetname="SIN-TIMAST-TMA:Evt-27-Freq-SP", pvreadbackname ="SIN-TIMAST-TMA:Evt-27-Freq-I", accuracy= 0.5, name='frequency_dark') + addPvRecordToSelf( + self, + pvsetname="SIN-TIMAST-TMA:Evt-22-Freq-SP", + pvreadbackname="SIN-TIMAST-TMA:Evt-22-Freq-I", + accuracy=0.5, + name="frequency_pp", + ) + addPvRecordToSelf( + self, + pvsetname="SIN-TIMAST-TMA:Evt-27-Freq-SP", + pvreadbackname="SIN-TIMAST-TMA:Evt-27-Freq-I", + accuracy=0.5, + name="frequency_dark", + ) def _mm_to_s(self, mm): return mm * 1e-3 * self._passes / self._group_velo * self._direction @@ -117,7 +120,7 @@ class DelayTime(AdjustableVirtual): class DelayCompensation(AdjustableVirtual): - """Simple virtual adjustable for compensating delay adjustables. It assumes the first adjustable is the master for + """Simple virtual adjustable for compensating delay adjustables. It assumes the first adjustable is the master for getting the current value.""" def __init__(self, adjustables, directions, set_current_value=True, name=None): @@ -184,7 +187,9 @@ class Laser_Exp: self.alias.append(self.delay_bsen.alias) try: - addMotorRecordToSelf(self, Id=self.Id + "-M522:MOTOR_1", name="_delay_thz_stg" ) + addMotorRecordToSelf( + self, Id=self.Id + "-M522:MOTOR_1", name="_delay_thz_stg" + ) self.delay_thz = DelayTime(self._delay_thz_stg, name="delay_thz") self.alias.append(self.delay_thz.alias) except: @@ -199,12 +204,12 @@ class Laser_Exp: print("Problems initializing global delay stage") # Implementation of delay compensation, this assumes for now that delays_glob and delay_tt actually delay in positive directions. - #try: + # try: # self.delay_lxtt = DelayCompensation( # [self.delay_glob, self.delay_tt], [-1, 1], name="delay_lxtt" # ) # self.alias.append(self.delay_lxtt.alias) - #except: + # except: # print("Problems initializing virtual pump delay stage") # compressor addMotorRecordToSelf(self, Id=self.Id + "-M532:MOT", name="compressor") @@ -214,19 +219,19 @@ class Laser_Exp: # addDelayStageToSelf(self, self.__dict__["_lam_delay_smarstg"], name="lam_delay_smar") # self._lam_delayStg_Smar = SmarActRecord('SLAAR21-LMTS-LAM11') # self.lam_delay_Smar = DelayStage(self._lam_delayStg_Smar) - #try: + # try: # addMotorRecordToSelf(self, Id=self.Id + "-M548:MOT", name="_lam_delaystg") # addDelayStageToSelf( # self, self.__dict__["_lam_delaystg"], name="lam_delay" # ) # this try except does not work - #except: + # except: # print("Problems initializing LAM delay stage") # self._lam_delayStg = MotorRecord(self.Id+'-M548:MOT') # self.lam_delay = DelayStage(self._lam_delayStg) # PALM delay stages - #addMotorRecordToSelf(self, Id=self.Id + "-M552:MOT", name="_palm_delaystg") - #addDelayStageToSelf(self, self.__dict__["_palm_delaystg"], name="palm_delay") + # addMotorRecordToSelf(self, Id=self.Id + "-M552:MOT", name="_palm_delaystg") + # addDelayStageToSelf(self, self.__dict__["_palm_delaystg"], name="palm_delay") # self._palm_delayStg = MotorRecord(self.Id+'-M552:MOT') # self.palm_delay = DelayStage(self._palm_delayStg) @@ -245,33 +250,38 @@ class Laser_Exp: ### SmarAct stages used in the experiment ### try: for smar_name, smar_address in self.smar_config.items(): - addSmarActRecordToSelf(self, Id=(self.IdSA + smar_address), name=smar_name) + addSmarActRecordToSelf( + self, Id=(self.IdSA + smar_address), name=smar_name + ) except Exception as expt: print("Issue with initializing smaract stages from eco smar_config") print(expt) ## IR beam pointing mirrors - #try: + # try: # addPvRecordToSelf(self, pvsetname="SLAAR21-LMNP-ESBIR13:DRIVE", pvreadbackname ="SLAAR21-LMNP-ESBIR13:MOTRBV", accuracy= 10, name='IR_mirr1_ry') # addPvRecordToSelf(self, pvsetname="SLAAR21-LMNP-ESBIR14:DRIVE", pvreadbackname ="SLAAR21-LMNP-ESBIR14:MOTRBV", accuracy= 10, name='IR_mirr1_rx') - #except: + # except: # print("Issue intializing picomotor IR beam pointing mirrors") # pass try: - addSmarActRecordToSelf(self, Id='SARES23-ESB4', name='IR_mirr1_rx') - addSmarActRecordToSelf(self, Id='SARES23-LIC7', name='IR_mirr1_ry') + addSmarActRecordToSelf(self, Id="SARES23-ESB4", name="IR_mirr1_rx") + addSmarActRecordToSelf(self, Id="SARES23-LIC7", name="IR_mirr1_ry") - addSmarActRecordToSelf(self, Id='SARES23-ESB1', name='IR_mirr2_ry') - addSmarActRecordToSelf(self, Id='SARES23-ESB2', name='IR_mirr2_rz') - addSmarActRecordToSelf(self, Id='SARES23-ESB3', name='IR_mirr2_z') + addSmarActRecordToSelf(self, Id="SARES23-ESB1", name="IR_mirr2_ry") + addSmarActRecordToSelf(self, Id="SARES23-ESB2", name="IR_mirr2_rz") + addSmarActRecordToSelf(self, Id="SARES23-ESB3", name="IR_mirr2_z") except: print("Issue intializing SmarAct IR beam pointing mirrors") pass ## beam pointing offsets try: - def set_position_monitor_offsets(cam1_center=[None,None],cam2_center=[None,None]): - dims = ['x','y'] + + def set_position_monitor_offsets( + cam1_center=[None, None], cam2_center=[None, None] + ): + dims = ["x", "y"] channels_cam1_xy = [ "SLAAR21-LTIM01-EVR0:CALCS.INPB", "SARES20-CVME-01-EVR0:CALCI.INPB", @@ -282,30 +292,29 @@ class Laser_Exp: ] print("Old crosshair position cam1") for dim, tc, tv in zip(dims, channels_cam1_xy, cam1_center): - print(f'{dim}: {PV(tc).get()}') + print(f"{dim}: {PV(tc).get()}") # PV(tc).put(bytes(str(tv), "utf8")) print("Old crosshair position cam2") for dim, tc, tv in zip(dims, channels_cam2_xy, cam2_center): - print(f'{dim}: {PV(tc).get()}') + print(f"{dim}: {PV(tc).get()}") # PV(tc).put(bytes(str(tv), "utf8")) print("New crosshair position cam1") for dim, tc, tv in zip(dims, channels_cam1_xy, cam1_center): if not tv: break - print(f'{dim}: {tv}') + print(f"{dim}: {tv}") PV(tc).put(bytes(str(tv), "utf8")) print("New crosshair position cam2") for dim, tc, tv in zip(dims, channels_cam2_xy, cam2_center): if not tv: break - print(f'{dim}: {tv}') + print(f"{dim}: {tv}") PV(tc).put(bytes(str(tv), "utf8")) + self.set_position_monitor_offsets = set_position_monitor_offsets except: pass - - def get_adjustable_positions_str(self): ostr = "*****Laser motor positions******\n" @@ -323,5 +332,3 @@ class Laser_Exp: def __repr__(self): return self.get_adjustable_positions_str() - - diff --git a/eco/xoptics/dcm_new.py b/eco/xoptics/dcm_new.py index b496f02..5d9bd5a 100644 --- a/eco/xoptics/dcm_new.py +++ b/eco/xoptics/dcm_new.py @@ -20,7 +20,7 @@ class DoubleCrystalMono(Assembly): self, pvname, name=None, - energy_sp="SAROP21-ARAMIS:ENERGY_SP", + energy_sp="SGE-OP2E-ARAMIS:E_ENERGY_SP", energy_rb="SAROP21-ARAMIS:ENERGY", ): super().__init__(name=name) diff --git a/eco/xoptics/kb_bernina.py b/eco/xoptics/kb_bernina.py index d35aeb0..88cac60 100644 --- a/eco/xoptics/kb_bernina.py +++ b/eco/xoptics/kb_bernina.py @@ -138,20 +138,22 @@ class KBMirrorBernina_new(Assembly): self.d_win1 = d_win1 self.d_target = d_target - self._add(MotorRecord, pvname_hor + ":W_X", name="x_hor") - self._add(MotorRecord, pvname_hor + ":W_Y", name="y_hor") - self._add(MotorRecord, pvname_hor + ":W_RY", name="y_hor") - self._add(MotorRecord, pvname_hor + ":W_RY", name="pitch_hor") - self._add(MotorRecord, pvname_hor + ":W_RZ", name="roll_hor") - self._add(MotorRecord, pvname_hor + ":W_RX", name="yaw_hor") - self._add(MotorRecord, pvname_hor + ":BU", name="bend_upstream_hor") - self._add(MotorRecord, pvname_hor + ":BD", name="bend_downstream_hor") + self._append(MotorRecord, pvname_hor + ":W_X", name="x_hor") + self._append(MotorRecord, pvname_hor + ":W_Y", name="y_hor") + self._append(MotorRecord, pvname_hor + ":W_RY", name="y_hor") + self._append(MotorRecord, pvname_hor + ":W_RY", name="pitch_hor") + self._append(MotorRecord, pvname_hor + ":W_RZ", name="roll_hor") + self._append(MotorRecord, pvname_hor + ":W_RX", name="yaw_hor") + self._append(MotorRecord, pvname_hor + ":BU", name="bend_upstream_hor") + self._append(MotorRecord, pvname_hor + ":BD", name="bend_downstream_hor") - self._add(MotorRecord, pvname_hor + ":TY1", name="y1_phys_hor") - self._add(MotorRecord, pvname_hor + ":TY2", name="y2_phys_hor") - self._add(MotorRecord, pvname_hor + ":TY3", name="y3_phys_hor") - self._add(MotorRecord, pvname_hor + ":TX1", name="x1_phys_hor") - self._add(MotorRecord, pvname_hor + ":TX2", name="x2_phys_hor") + self._append(MotorRecord, pvname_hor + ":TY1", name="y1_phys_hor") + self._append(MotorRecord, pvname_hor + ":TY2", name="y2_phys_hor") + self._append(MotorRecord, pvname_hor + ":TY3", name="y3_phys_hor") + self._append(MotorRecord, pvname_hor + ":TX1", name="x1_phys_hor") + self._append(MotorRecord, pvname_hor + ":TX2", name="x2_phys_hor") + + self._append() self._add( PvRecord,