diff --git a/eco/bernina/bernina.py b/eco/bernina/bernina.py index 23983f2..eaacb8b 100644 --- a/eco/bernina/bernina.py +++ b/eco/bernina/bernina.py @@ -126,6 +126,12 @@ namespace.append_obj( name="slit_mono", module_name="eco.xoptics.slits", ) +namespace.append_obj( + "SolidTargetDetectorPBPS", + "SAROP21-PBPS103", + name="mon_mono", + module_name="eco.xdiagnostics.intensity_monitors", +) from eco.devices_general.motors import SmaractStreamdevice, SmaractRecord @@ -242,6 +248,13 @@ namespace.append_obj( module_name="eco.xdiagnostics.intensity_monitors", lazy=True, ) +namespace.append_obj( + "SolidTargetDetectorPBPS", + "SARFE10-PBPS053", + name="mon_und", + module_name="eco.xdiagnostics.intensity_monitors", +) + namespace.append_obj( "RefLaser_Aramis", "SAROP21-OLAS136", @@ -263,6 +276,10 @@ namespace.append_obj( lazy=True, ) +namespace.append_obj( + "DownstreamDiagnostic", name="dsd", module_name="eco.xdiagnostics.dsd" +) + namespace.append_obj( "Pprm_dsd", pvname="SARES20-DSDPPRM", @@ -443,6 +460,13 @@ namespace.append_obj( name="analog_inputs", module_name="eco.devices_general.wago", ) +namespace.append_obj( + "WagoAnalogOutputs", + "SARES20-CWAG-GPS01", + lazy=True, + name="analog_outputs", + module_name="eco.devices_general.wago", +) namespace.append_obj( "GudeStrip", "SARES20-CPPS-01", @@ -1345,6 +1369,17 @@ namespace.append_obj(JohannAnalyzer, name="analyzer") ############## experiment specific ############# + +namespace.append_obj( + "Bernina_XEYE", + zoomstage_pv=config_bernina.xeye.zoomstage_pv._value, + camera_pv=config_bernina.xeye.camera_pv._value, + bshost=config_bernina.xeye.bshost._value, + bsport=config_bernina.xeye.bsport._value, + name="xeye", + module_name="eco.xdiagnostics.profile_monitors", +) + # try to append pgroup folder to path !!!!! This caused eco to run in a timeout without error traceback !!!!! try: @@ -1365,6 +1400,17 @@ except: print("Did not succed to append an eco folder in current prgoup") +class Xspect_EH55(Assembly): + def __init__(self, name="xspect_bernina"): + super().__init__(name=name) + self._append(MotorRecord, "SARES20-MF1:MOT_15", name="x_crystal") + self._append(MotorRecord, "SARES20-MF1:MOT_16", name="y_crystal") + # self._append(SmaractRecord,'SARES20-MF1:MOT_16',name='theta_crystal') + + +namespace.append_obj(Xspect_EH55, name="xspect_bernina", lazy=True) + + #### pgroup specific appending, might be temporary at this location #### # namespace.append_obj("Xom", module_name="xom", name="xom", lazy=True) diff --git a/eco/bernina/config.py b/eco/bernina/config.py index 59cd577..7c16502 100755 --- a/eco/bernina/config.py +++ b/eco/bernina/config.py @@ -75,28 +75,28 @@ components = [ # "type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS", # "kwargs": {"VME_crate": "SAROP21-CVME-PBPS2", "link": 9}, # }, - { - "name": "mon_und", - "z_und": 53, - "desc": "Intensity/position monitor after Undulator", - "type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS_new", - "args": ["SARFE10-PBPS053"], - "kwargs": { - "VME_crate": "SAROP21-CVME-PBPS1", - "link": 9, - "channels": { - "up": "SLAAR21-LSCP1-FNS:CH6:VAL_GET", - "down": "SLAAR21-LSCP1-FNS:CH7:VAL_GET", - "left": "SLAAR21-LSCP1-FNS:CH4:VAL_GET", - "right": "SLAAR21-LSCP1-FNS:CH5:VAL_GET", - }, - "calc": { - "itot": "SLAAR21-LTIM01-EVR0:CALCI", - "xpos": "SLAAR21-LTIM01-EVR0:CALCX", - "ypos": "SLAAR21-LTIM01-EVR0:CALCY", - }, - }, - }, + # { + # "name": "mon_und", + # "z_und": 53, + # "desc": "Intensity/position monitor after Undulator", + # "type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS_new", + # "args": ["SARFE10-PBPS053"], + # "kwargs": { + # "VME_crate": "SAROP21-CVME-PBPS1", + # "link": 9, + # "channels": { + # "up": "SLAAR21-LSCP1-FNS:CH6:VAL_GET", + # "down": "SLAAR21-LSCP1-FNS:CH7:VAL_GET", + # "left": "SLAAR21-LSCP1-FNS:CH4:VAL_GET", + # "right": "SLAAR21-LSCP1-FNS:CH5:VAL_GET", + # }, + # "calc": { + # "itot": "SLAAR21-LTIM01-EVR0:CALCI", + # "xpos": "SLAAR21-LTIM01-EVR0:CALCX", + # "ypos": "SLAAR21-LTIM01-EVR0:CALCY", + # }, + # }, + # }, { "name": "pshut_und", "type": "eco.xoptics.shutters:PhotonShutter", diff --git a/eco/devices_general/motors.py b/eco/devices_general/motors.py index b1912b5..869529b 100755 --- a/eco/devices_general/motors.py +++ b/eco/devices_general/motors.py @@ -883,6 +883,35 @@ class SmaractRecord(Assembly): Alias(an, channel=".".join([pvname, af]), channeltype="CA") ) self._currentChange = None + + self._append( + AdjustablePvEnum, + self.pvname + "_POS_TYPE_RB", + pvname_set=self.pvname + "_POS_TYPE_SP", + name="sensor_type", + is_setting=True, + ) + self._append( + AdjustablePv, + self.pvname + "_MAX_FREQ", + name="max_frequency", + is_setting=True, + ) + self._append( + AdjustablePv, self.pvname + ".VELO", name="speed", is_setting=False + ) + self._append( + AdjustablePv, + self.pvname + ".ACCL", + name="acceleration_time", + is_setting=False, + ) + self._append( + AdjustablePv, self.pvname + ".LLM", name="limit_low", is_setting=False + ) + self._append( + AdjustablePv, self.pvname + ".HLM", name="limit_high", is_setting=False + ) self._append( AdjustablePvEnum, self.pvname + ".STAT", @@ -903,6 +932,7 @@ class SmaractRecord(Assembly): name="autoset_unit", is_setting=True, ) + self._append( AdjustablePv, self.pvname + ".HOMR", @@ -927,21 +957,7 @@ class SmaractRecord(Assembly): is_setting=False, is_display=True, ) - self._append( - AdjustablePv, self.pvname + ".VELO", name="speed", is_setting=False - ) - self._append( - AdjustablePv, - self.pvname + ".ACCL", - name="acceleration_time", - is_setting=False, - ) - self._append( - AdjustablePv, self.pvname + ".LLM", name="limit_low", is_setting=False - ) - self._append( - AdjustablePv, self.pvname + ".HLM", name="limit_high", is_setting=False - ) + self._append( AdjustablePvEnum, self.pvname + ".SPMG", name="mode", is_setting=False ) @@ -979,13 +995,6 @@ class SmaractRecord(Assembly): is_status=False, is_display=False, ) - self._append( - AdjustablePvEnum, - self.pvname + "_POS_TYPE_RB", - pvname_set=self.pvname + "_POS_TYPE_SP", - name="sensor_type", - is_setting=True, - ) if backlash_definition: self._append( AdjustablePv, diff --git a/eco/devices_general/wago.py b/eco/devices_general/wago.py index 87a0eda..d37a43b 100644 --- a/eco/devices_general/wago.py +++ b/eco/devices_general/wago.py @@ -42,3 +42,55 @@ class WagoAnalogInputs(Assembly): self.pvbase = pvbase for n in range(1, 9): self._append(AnalogInput, pvbase + f":ADC{n:02d}", name=f"ch{n:d}") + + +class AnalogOutput(Assembly): + def __init__(self, pvname, name=None): + super().__init__(name=name) + self.pvname = pvname + self._append( + AdjustablePv, + self.pvname, + self.pvname + "_RB", + name="value", + is_setting=True, + is_display=True, + ) + self._append( + AdjustablePvString, + self.pvname + ".DESC", + name="description", + is_setting=True, + is_display=True, + ) + self._append( + AdjustablePvString, + self.pvname + ".EGU", + name="unit", + is_setting=False, + is_display=False, + ) + self._append( + DetectorPvData, + self.pvname + ".RVAL", + name="raw", + is_setting=False, + is_display=False, + ) + + def get_current_value(self): + return self.value.get_current_value() + + def __call__(self, *args): + if args: + self.value(*args).wait() + else: + return self.value.get_current_value() + + +class WagoAnalogOutputs(Assembly): + def __init__(self, pvbase, name=None): + super().__init__(name=name) + self.pvbase = pvbase + for n in range(1, 9): + self._append(AnalogOutput, pvbase + f":DAC{n:02d}", name=f"ch{n:d}") diff --git a/eco/elements/adj_obj.py b/eco/elements/adj_obj.py index 5289e50..3d86ea5 100644 --- a/eco/elements/adj_obj.py +++ b/eco/elements/adj_obj.py @@ -23,6 +23,12 @@ class AdjustableObject(Assembly): raise Exception(f"{fieldname} is not in dictionary") return d[fieldname] + def update_base_dict(self, updatedict): + tmp = self._base_dict.get_current_value() + tmp.update(updatedict) + self._base_dict.set_target_value(tmp) + self.__init__(self._base_dict, name=self.name) + def init_object(self): # super().__init__(name=self.name) for k, v in self._base_dict.get_current_value().items(): diff --git a/eco/elements/memory.py b/eco/elements/memory.py index 50fb2b5..e5cb6fc 100644 --- a/eco/elements/memory.py +++ b/eco/elements/memory.py @@ -125,6 +125,7 @@ class Memory: show_changes_only=True, set_changes_only=True, check_limits=True, + change_serially=False, force=False, ): # if input_obj: @@ -160,6 +161,8 @@ class Memory: changes.append(to.set_target_value(val, check=check_limits)) else: changes.append(to.set_target_value(val)) + if change_serially: + changes[-1].wait() if wait: for change in changes: change.wait() diff --git a/eco/xdiagnostics/dsd.py b/eco/xdiagnostics/dsd.py index 8d25741..18ff37a 100644 --- a/eco/xdiagnostics/dsd.py +++ b/eco/xdiagnostics/dsd.py @@ -10,6 +10,7 @@ from ..elements.assembly import Assembly from .profile_monitors import Pprm_dsd from .intensity_monitors import SolidTargetDetectorPBPS_new_assembly import numpy as np +from epics import PV class DownstreamDiagnostic(Assembly): @@ -24,9 +25,14 @@ class DownstreamDiagnostic(Assembly): self._append( MotorRecord, "SARES20-DSD:MOTOR_DSDY", name="ybase", is_setting=True ) - def get_xyposition_for_kb_angles_in_rad(self, theta_kbver, theta_kbhor): y = np.tan(2 * theta_kbver) * 7075 x = np.tan(2 * theta_kbhor) / np.cos(2 * theta_kbver) * 6325 return x, y + + def home(self): + self._run_cmd("python /ioc/qt/ESB_DSD_home.py SARES20-DSD") + + def gui(self): + self._run_cmd("caqtdm -noMsg -macro P=SARES20-DSD /ioc/qt/ESB_DSD_motors.ui") diff --git a/eco/xdiagnostics/intensity_monitors.py b/eco/xdiagnostics/intensity_monitors.py index bd0eed0..de66e32 100755 --- a/eco/xdiagnostics/intensity_monitors.py +++ b/eco/xdiagnostics/intensity_monitors.py @@ -63,7 +63,7 @@ class SolidTargetDetectorPBPS(Assembly): # ch_left=15, # ch_right=14, # elog=None, - # name=None, + name=None, # calc=None, # calc_calib={}, ): @@ -95,6 +95,167 @@ class SolidTargetDetectorPBPS(Assembly): DetectorPvDataStream, pvname + ":YPOS", name="ypos", is_setting=False ) + # Calibration calculation record + + # Intensity + self._append( + AdjustablePv, + pvname + ":INTENSITY.INPA", + name="calc_intensity_input_A", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":INTENSITY.INPB", + name="calc_intensity_input_B", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":INTENSITY.INPC", + name="calc_intensity_input_C", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":INTENSITY.INPD", + name="calc_intensity_input_D", + is_setting=True, + is_display=False, + ) + + self._append( + AdjustablePv, + pvname + ":INTENSITY.E", + name="calc_intensity_const_E", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":INTENSITY.F", + name="calc_intensity_const_F", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":INTENSITY.G", + name="calc_intensity_const_G", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":INTENSITY.H", + name="calc_intensity_const_H", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":INTENSITY.CALC", + name="calc_intensity_function", + is_setting=True, + is_display=False, + ) + # X position + self._append( + AdjustablePv, + pvname + ":XPOS.INPA", + name="calc_xpos_input_A", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":XPOS.INPB", + name="calc_xpos_input_B", + is_setting=True, + is_display=False, + ) + self._append( + AdjustablePv, + pvname + ":XPOS.CALC", + name="calc_xpos_function", + is_setting=True, + is_display=False, + ) + + # self._append( + # AdjustablePv, pvname + ":XPOS.INPD", name="calc_input_D", is_setting=True, is_display=False + # ) + + # self._append( + # AdjustablePv, pvname + ":XPOS.IE", name="calc_input_E", is_setting=True, is_display=False + + # self._append( + # AdjustablePv, pvname + ":XPOS.IF", name="calc_input_F", is_setting=True, is_display=False + # ) + # self._append( + # AdjustablePv, pvname + ":XPOS.INPG", name="calc_input_G", is_setting=True, is_display=False + # ) + # self._append( + # AdjustablePv, pvname + ":XPOS.INPH", name="calc_input_H", is_setting=True, is_display=False + # ) + # self._append( + # AdjustablePv, pvname + ":XPOS.CALC", name="calc_function", is_setting=True, is_display=False + # ) + + # # Intensity + # # Set channels + # # Input data + # ep.PV(Devive_prefix+'INTENSITY.INPA').put(bytes(channels[0], "utf8")) + # ep.PV(Devive_prefix+'INTENSITY.INPB').put(bytes(channels[1], "utf8")) + # ep.PV(Devive_prefix+'INTENSITY.INPC').put(bytes(channels[2], "utf8")) + # ep.PV(Devive_prefix+'INTENSITY.INPD').put(bytes(channels[3], "utf8")) + # # Calibration values + # ep.PV(Devive_prefix+'INTENSITY.E').put(bytes(str(norm_diodes[0,0]), "utf8")) + # ep.PV(Devive_prefix+'INTENSITY.F').put(bytes(str(norm_diodes[0,1]), "utf8")) + # ep.PV(Devive_prefix+'INTENSITY.G').put(bytes(str(norm_diodes[0,2]), "utf8")) + # ep.PV(Devive_prefix+'INTENSITY.H').put(bytes(str(norm_diodes[0,3]), "utf8")) + # # Calculation + # ep.PV(Devive_prefix+'INTENSITY.CALC').put(bytes("A*E+B*F+C*G+D*H", "utf8")) + + # # XPOS + # # Set channels + # ep.PV(Devive_prefix+'XPOS.INPA').put(bytes(channels[2], "utf8")) + # ep.PV(Devive_prefix+'XPOS.INPB').put(bytes(channels[3], "utf8")) + # # Threshold value + # ep.PV(Devive_prefix+'XPOS.D').put(bytes(str(0.2), "utf8")) + # # Diode calibration value + # ep.PV(Devive_prefix+'XPOS.E').put(bytes(str(norm_diodes[0,2]), "utf8")) + # ep.PV(Devive_prefix+'XPOS.F').put(bytes(str(norm_diodes[0,3]), "utf8")) + # # Null value + # ep.PV(Devive_prefix+'XPOS.G').put(bytes(str(0), "utf8")) + # # Position calibration value + # ep.PV(Devive_prefix+'XPOS.I').put(bytes(str((Scan_x_range[1]-Scan_x_range[0])/ np.diff(scan_x_norm).mean()), "utf8")) + # # Intensity threshold value + # ep.PV(Devive_prefix+'XPOS.INPJ').put(bytes(Devive_prefix+'INTENSITY', "utf8")) + # # Calculation + # ep.PV(Devive_prefix+'XPOS.CALC').put(bytes("J