diff --git a/eco/bernina/config.py b/eco/bernina/config.py index 1d3de9a..519d05b 100755 --- a/eco/bernina/config.py +++ b/eco/bernina/config.py @@ -562,7 +562,7 @@ components = [ "z_und": 141, "desc": "Upstream diagnostics table", "type": "eco.endstations.hexapod:HexapodSymmetrie", - "kwargs": {}, + "kwargs": {'offset':[1.308,0.881,0.,0.027,0.231,0.]}, "lazy": True, }, { @@ -616,6 +616,26 @@ components = [ "kwargs": {"Id": "SARES23"}, "lazy": True, }, + + { + "args": [], + "name": "tht", + "z_und": 142, + "desc": "High field THz Table", + "type": "eco.endstations.bernina_sample_environments:High_field_thz_table", + "kwargs": {"Id": "SARES23"}, + "lazy": True, + }, + + { + "args": [], + "name": "eos", + "z_und": 142, + "desc": "electro optic sampling stages", + "type": "eco.endstations.bernina_sample_environments:electro_optic_sampling", + "kwargs": {"Id": "SARES23"}, + "lazy": True, + }, ] try: diff --git a/eco/endstations/bernina_sample_environments.py b/eco/endstations/bernina_sample_environments.py index a31af18..ac7b46f 100644 --- a/eco/endstations/bernina_sample_environments.py +++ b/eco/endstations/bernina_sample_environments.py @@ -31,16 +31,16 @@ class High_field_thz_chamber: self.motor_configuration = { "rx": { - "id": "-ESB4", - "pv_descr": "Motor4:1 THz Chamber Rx", + "id": "-ESB13", + "pv_descr": "Motor7:1 THz Chamber Rx", "type": 2, "sensor": 1, "speed": 250, "home_direction": "back", }, "x": { - "id": "-ESB5", - "pv_descr": "Motor5:2 THz Chamber x ", + "id": "-ESB14", + "pv_descr": "Motor7:2 THz Chamber x ", "type": 1, "sensor": 0, "speed": 250, @@ -132,3 +132,240 @@ class High_field_thz_chamber: def __repr__(self): return self.get_adjustable_positions_str() + + + + + +class High_field_thz_table: + def __init__(self, name=None, Id=None, alias_namespace=None): + self.Id = Id + self.name = name + self.alias = Alias(name) + + self.motor_configuration = { + "mirr2_x": { + "id": "-ESB1", + "pv_descr": "Motor3:1 THz mirror x ", + "type": 2, + "sensor": 1, + "speed": 250, + "home_direction": "back", + }, + "mirr2_rz": { + "id": "-ESB2", + "pv_descr": "Motor3:2 THz mirror rz ", + "type": 1, + "sensor": 0, + "speed": 250, + "home_direction": "back", + }, + "mirr2_ry": { + "id": "-ESB3", + "pv_descr": "Motor3:3 THz mirror ry ", + "type": 1, + "sensor": 0, + "speed": 250, + "home_direction": "back", + }, + "mirr2_z": { + "id": "-ESB4", + "pv_descr": "Motor4:1 THz mirror z", + "type": 2, + "sensor": 1, + "speed": 250, + "home_direction": "back", + }, + "par2_x": { + "id": "-ESB5", + "pv_descr": "Motor4:2 THz parabola2 x", + "type": 2, + "sensor": 1, + "speed": 250, + "home_direction": "back", + }, + + "mirr1_x": { + "id": "-ESB7", + "pv_descr": "Motor5:1 near IR mirror x", + "type": 2, + "sensor": 1, + "speed": 250, + "home_direction": "back", + }, + "mirr1_ry": { + "id": "-ESB8", + "pv_descr": "Motor5:2 near IR mirror ry", + "type": 2, + "sensor": 1, + "speed": 250, + "home_direction": "back", + }, + "mirr1_rx": { + "id": "-ESB9", + "pv_descr": "Motor5:3 near IR mirror rx", + "type": 2, + "sensor": 1, + "speed": 250, + "home_direction": "back", + }, + } + + ### in vacuum smaract motors ### + for name, config in self.motor_configuration.items(): + addSmarActRecordToSelf(self, Id=Id + config["id"], name=name) + + def set_stage_config(self): + for name, config in self.motor_configuration.items(): + mot = self.__dict__[name]._device + mot.put("NAME", config["pv_descr"]) + mot.put("STAGE_TYPE", config["type"]) + mot.put("SET_SENSOR_TYPE", config["sensor"]) + mot.put("CL_MAX_FREQ", config["speed"]) + sleep(0.5) + mot.put("CALIBRATE.PROC", 1) + + def home_smaract_stages(self, stages=None): + if stages == None: + stages = self.motor_configuration.keys() + print("#### Positions before homing ####") + print(self.__repr__()) + for name in stages: + config = self.motor_configuration[name] + mot = self.__dict__[name]._device + print( + "#### Homing {} in {} direction ####".format( + name, config["home_direction"] + ) + ) + sleep(1) + if config["home_direction"] == "back": + mot.put("FRM_BACK.PROC", 1) + while mot.get("STATUS") == 7: + sleep(1) + if mot.get("GET_HOMED") == 0: + print( + "Homing failed, try homing {} in forward direction".format(name) + ) + mot.put("FRM_FORW.PROC", 1) + elif config["home_direction"] == "forward": + mot.put("FRM_FORW.PROC", 1) + while mot.get("STATUS") == 7: + sleep(1) + if mot.get("GET_HOMED") == 0: + print( + "Homing failed, try homing {} in backward direction".format( + name + ) + ) + mot.put("FRM_BACK.PROC", 1) + + def get_adjustable_positions_str(self): + ostr = "*****THz table motor positions******\n" + + for tkey, item in self.__dict__.items(): + if hasattr(item, "get_current_value"): + pos = item.get_current_value() + ostr += " " + tkey.ljust(17) + " : % 14g\n" % pos + return ostr + + def __repr__(self): + return self.get_adjustable_positions_str() + + + + + +class electro_optic_sampling: + def __init__(self, name=None, Id=None, alias_namespace=None): + self.Id = Id + self.name = name + self.alias = Alias(name) + + self.motor_configuration = { + "ry": { + "id": "-ESB16", + "pv_descr": "Motor8:1 EOS prism ry ", + "type": 2, + "sensor": 1, + "speed": 250, + "home_direction": "back", + }, + "rx": { + "id": "-ESB17", + "pv_descr": "Motor8:2 EOS prism rx ", + "type": 1, + "sensor": 0, + "speed": 250, + "home_direction": "back", + }, + "x": { + "id": "-ESB18", + "pv_descr": "Motor8:3 EOS prism x ", + "type": 1, + "sensor": 0, + "speed": 250, + "home_direction": "back", + }, + } + + ### in vacuum smaract motors ### + for name, config in self.motor_configuration.items(): + addSmarActRecordToSelf(self, Id=Id + config["id"], name=name) + + def set_stage_config(self): + for name, config in self.motor_configuration.items(): + mot = self.__dict__[name]._device + mot.put("NAME", config["pv_descr"]) + mot.put("STAGE_TYPE", config["type"]) + mot.put("SET_SENSOR_TYPE", config["sensor"]) + mot.put("CL_MAX_FREQ", config["speed"]) + sleep(0.5) + mot.put("CALIBRATE.PROC", 1) + + def home_smaract_stages(self, stages=None): + if stages == None: + stages = self.motor_configuration.keys() + print("#### Positions before homing ####") + print(self.__repr__()) + for name in stages: + config = self.motor_configuration[name] + mot = self.__dict__[name]._device + print( + "#### Homing {} in {} direction ####".format( + name, config["home_direction"] + ) + ) + sleep(1) + if config["home_direction"] == "back": + mot.put("FRM_BACK.PROC", 1) + while mot.get("STATUS") == 7: + sleep(1) + if mot.get("GET_HOMED") == 0: + print( + "Homing failed, try homing {} in forward direction".format(name) + ) + mot.put("FRM_FORW.PROC", 1) + elif config["home_direction"] == "forward": + mot.put("FRM_FORW.PROC", 1) + while mot.get("STATUS") == 7: + sleep(1) + if mot.get("GET_HOMED") == 0: + print( + "Homing failed, try homing {} in backward direction".format( + name + ) + ) + mot.put("FRM_BACK.PROC", 1) + + def get_adjustable_positions_str(self): + ostr = "*****EOS motor positions******\n" + + for tkey, item in self.__dict__.items(): + if hasattr(item, "get_current_value"): + pos = item.get_current_value() + ostr += " " + tkey.ljust(17) + " : % 14g\n" % pos + return ostr + + def __repr__(self): + return self.get_adjustable_positions_str() diff --git a/eco/endstations/hexapod.py b/eco/endstations/hexapod.py index 3e6234a..8828d1e 100644 --- a/eco/endstations/hexapod.py +++ b/eco/endstations/hexapod.py @@ -20,8 +20,9 @@ class Hexapod_PI: class HexapodSymmetrie: - def __init__(self,pv_master='SARES20-HEXSYM',name='hex_usd'): + def __init__(self,pv_master='SARES20-HEXSYM',name='hex_usd',offset=[0,0,0,0,0,0]): self.name = name + self.offset = offset self.pvname = pv_master self.coordinate_switch = PvEnum(f'{self.pvname}:MOVE#PARAM:CM',name='hex_usd_coordinate_switch') self.pvs_setpos = { @@ -43,12 +44,12 @@ class HexapodSymmetrie: self._ctrl_pv = PV(f'{self.pvname}:STATE#PANEL:SET.VAL') def set_coordinates(self,x,y,z,rx,ry,rz): - self.pvs_setpos['x'].set(x) - self.pvs_setpos['y'].set(y) - self.pvs_setpos['z'].set(z) - self.pvs_setpos['rx'].set(rx) - self.pvs_setpos['ry'].set(ry) - self.pvs_setpos['rz'].set(rz) + self.pvs_setpos['x'].put(x) + self.pvs_setpos['y'].put(y) + self.pvs_setpos['z'].put(z) + self.pvs_setpos['rx'].put(rx) + self.pvs_setpos['ry'].put(ry) + self.pvs_setpos['rz'].put(rz) def get_coordinates(self): x = self.pvs_getpos['x'].get() @@ -60,10 +61,10 @@ class HexapodSymmetrie: return x,y,z,rx,ry,rz def set_control_on(self): - self._ctrl_pv.set(3) + self._ctrl_pv.put(3) def set_control_off(self): - self._ctrl_pv.set(4) + self._ctrl_pv.put(4) def get_control_state(self): stat = self._ctrl_pv.get() @@ -76,9 +77,24 @@ class HexapodSymmetrie: elif stat==11: return 'moving' - def start_move(self,target=None,precision=[.001,.001,.001,.001,.001,.001]): + def move_to_coordinates(self,x,y,z,rx,ry,rz,precision=[.001,.001,.001,.001,.001,.001],coordinate_type='absolute',relative_to_eco_offset=True): + self.coordinate_switch.set_target_value(coordinate_type).wait() + if relative_to_eco_offset: + x = x+self.offset[0] + y = y+self.offset[1] + z = z+self.offset[2] + rx = rx+self.offset[3] + ry = ry+self.offset[4] + rz = rz+self.offset[5] + self.set_coordinates(x,y,z,rx,ry,rz) + sleep(.1) + self.start_move(target=(x,y,z,rx,ry,rz),precision=precision,coordinate_type=coordinate_type) + + def start_move(self,target=None,precision=[.001,.001,.001,.001,.001,.001],coordinate_type='absolute'): print('Starting to move... stop with Ctrl-C') - self._ctrl_pv.set(11) + self.set_control_on() + sleep(0.2) + self._ctrl_pv.put(11) #this starts moving! while 1: try: if target: @@ -91,7 +107,10 @@ class HexapodSymmetrie: except KeyboardInterrupt: self.stop_move() print('Motion stopped') + break + self.set_control_off() + sleep(0.05) def stop_move(self): - self._ctrl_pv.set(2) + self._ctrl_pv.put(2) diff --git a/eco/xoptics/kb_bernina.py b/eco/xoptics/kb_bernina.py index 4cf3be6..5fd36b0 100644 --- a/eco/xoptics/kb_bernina.py +++ b/eco/xoptics/kb_bernina.py @@ -52,6 +52,23 @@ class KBMirrorBernina: # res['fwhm_kbhor'] = (fwhm_z(self.d_kbhor+z_fochor,w0_hor),fwhm_z(self.d_kbhor+z_focver,w0_ver)) return res + def move_hex_for_kb_angles(self,the_kbver,the_kbhor): + pos = self.calc_positions(the_kbver,the_kbhor) + x = pos['x_hex'] + y = pos['y_hex'] + rx = pos['rx_hex']*180/np.pi + ry = pos['ry_hex']*180/np.pi + z=rz=0. + print(f"moving to (x/mm,y/mm,z/mm,rx/°,ry/°,rz/°) = ({x:g},{y:g},{z:g},{rx:g},{ry:g},{rz:g})") + if not input("start moving upstream large hexapod? (y/n)")=="y": + print("did nothing") + return + else: + self.usd_table.move_to_coordinates(x,y,z,rx,ry,rz) + + + +