diff --git a/eco/bernina/bernina.py b/eco/bernina/bernina.py index 2348fd2..8dc28dd 100644 --- a/eco/bernina/bernina.py +++ b/eco/bernina/bernina.py @@ -226,7 +226,7 @@ namespace.append_obj( n_output_rear=16, name="evr", module_name="eco.timing.event_timing_new_new", - lazy=True, + lazy=False, ) namespace.append_obj( "EventReceiver", @@ -237,7 +237,7 @@ namespace.append_obj( n_output_rear=16, name="evr_laser", module_name="eco.timing.event_timing_new_new", - lazy=True, + lazy=False, ) namespace.append_obj( "EventReceiver", @@ -248,7 +248,7 @@ namespace.append_obj( n_output_rear=16, name="evr_hutch_laser", module_name="eco.timing.event_timing_new_new", - lazy=True, + lazy=False, ) namespace.append_obj( "EventReceiver", @@ -259,7 +259,7 @@ namespace.append_obj( n_output_rear=0, name="evr_camserver72", module_name="eco.timing.event_timing_new_new", - lazy=True, + lazy=False, ) namespace.append_obj( "EventReceiver", @@ -270,7 +270,7 @@ namespace.append_obj( n_output_rear=0, name="evr_camserver83", module_name="eco.timing.event_timing_new_new", - lazy=True, + lazy=False, ) namespace.append_obj( "EventReceiver", @@ -281,7 +281,7 @@ namespace.append_obj( n_output_rear=0, name="evr_camserver84", module_name="eco.timing.event_timing_new_new", - lazy=True, + lazy=False, ) namespace.append_obj( "EventReceiver", @@ -292,7 +292,8 @@ namespace.append_obj( n_output_rear=0, name="evr_camserver85", module_name="eco.timing.event_timing_new_new", - lazy=True, + # lazy=True, + lazy=False, ) namespace.append_obj( @@ -327,7 +328,21 @@ namespace.append_obj( "GudeStrip", "SARES20-CPPS-01", lazy=True, - name="powerstrip_mobile", + name="powerstrip_gps", + module_name="eco.devices_general.powersockets", +) +namespace.append_obj( + "GudeStrip", + "SARES20-CPPS-04", + lazy=True, + name="powerstrip_xrd", + module_name="eco.devices_general.powersockets", +) +namespace.append_obj( + "GudeStrip", + "SARES20-CPPS-02", + lazy=True, + name="powerstrip_patch2", module_name="eco.devices_general.powersockets", ) namespace.append_obj( @@ -339,15 +354,15 @@ namespace.append_obj( fina_hex_angle_offset="~/eco/reference_values/hex_pi_angle_offset.json", lazy=True, ) -#namespace.append_obj( -# "XRDYou", -# module_name="eco.endstations.bernina_diffractometers", -# Id="SARES21-XRD", -# configuration=config_berninamesp["xrd_config"], -# diff_detector={"jf_id": "JF01T03V01"}, -# name="xrd", -# lazy=True, -#) +namespace.append_obj( + "XRDYou", + module_name="eco.endstations.bernina_diffractometers", + Id="SARES21-XRD", + configuration=config_berninamesp["xrd_config"], + diff_detector={"jf_id": "JF01T03V01"}, + name="xrd", + lazy=True, +) namespace.append_obj( "KBMirrorBernina_new", "SAROP21-OKBV139", @@ -355,7 +370,7 @@ namespace.append_obj( module_name="eco.xoptics.kb_bernina", usd_table=usd_table, name="kb", - diffractometer=gps, + diffractometer=xrd, ) ### channelsfor daq ### @@ -482,6 +497,7 @@ def _append_namesace_status_to_scan(scan): base=None ) + def _append_namespace_aliases_to_scan(scan): scan.scan_info["scan_parameters"]["namespace_aliases"] = namespace.alias.get_all() @@ -492,24 +508,28 @@ def _message_end_scan(scan): e.runAndWait() e.stop() + def _increment_daq_run_number(scan, daq=daq): try: daq_last_run_number = daq.get_last_run_number() - if int(scan.run_number) is int(daq_last_run_number)+1: + if int(scan.run_number) is int(daq_last_run_number) + 1: daq_run_number = daq.get_next_run_number() - else: + else: daq_run_number = daq_last_run_number if int(scan.run_number) is not int(daq_run_number): - print(f'Difference in run number between eco {int(scan.run_number)} and daq {int(daq_run_number)}: using run number {int(scan.run_number)}') + print( + f"Difference in run number between eco {int(scan.run_number)} and daq {int(daq_run_number)}: using run number {int(scan.run_number)}" + ) if int(scan.run_number) > int(daq_run_number): n = int(scan.run_number) - int(daq_run_number) - print('Increasing daq run_number') + print("Increasing daq run_number") for i in range(n): rn = daq.get_next_run_number() print(rn) except Exception as e: print(e) + callbacks_start_scan = [] callbacks_start_scan = [lambda scan: namespace.init_all()] callbacks_start_scan.append(_append_namespace_aliases_to_scan) @@ -547,24 +567,24 @@ namespace.append_obj( #### Beam pointing cameras for THz setups #### -namespace.append_obj( - "CameraBasler", - pvname="SLAAR21-LCAM-C531", - lazy=True, - name="cam_NIR_position", - camserver_group=["Laser", "Bernina"], - module_name="eco.devices_general.cameras_swissfel", -) - - -namespace.append_obj( - "CameraBasler", - pvname="SLAAR21-LCAM-C511", - lazy=True, - name="cam_NIR_angle", - camserver_group=["Laser", "Bernina"], - module_name="eco.devices_general.cameras_swissfel", -) +# namespace.append_obj( +# "CameraBasler", +# pvname="SLAAR21-LCAM-C531", +# lazy=True, +# name="cam_NIR_position", +# camserver_group=["Laser", "Bernina"], +# module_name="eco.devices_general.cameras_swissfel", +# ) +# +# +# namespace.append_obj( +# "CameraBasler", +# pvname="SLAAR21-LCAM-C511", +# lazy=True, +# name="cam_NIR_angle", +# camserver_group=["Laser", "Bernina"], +# module_name="eco.devices_general.cameras_swissfel", +# ) namespace.append_obj( "AxisPTZ", @@ -591,9 +611,18 @@ namespace.append_obj( # pvname_zoom="SARES20-MF1:MOT_16", # ) +namespace.append_obj( + "MicroscopeMotorRecord", + "SARES20-CAMS142-C1", + lazy=True, + pvname_zoom="SARES20-MF1:MOT_16", + name="samplecam_microscope", + module_name="eco.microscopes", +) + namespace.append_obj( "CameraBasler", - "SARES20-CAMS142-M1", + "SARES20-CAMS142-C2", lazy=True, name="samplecam_sideview", module_name="eco.devices_general.cameras_swissfel", @@ -634,43 +663,98 @@ namespace.append_obj( name="las", module_name="eco.loptics.bernina_laser", ) -namespace.append_obj( - "IncouplingCleanBernina", - lazy=False, - name="las_inc", - module_name="eco.loptics.bernina_laser", -) +# namespace.append_obj( +# "IncouplingCleanBernina", +# lazy=False, +# name="las_inc", +# module_name="eco.loptics.bernina_laser", +# ) from ..elements.assembly import Assembly from ..devices_general.motors import SmaractStreamdevice +# namespace.append_obj( +# "Organic_crystal_breadboard", +# lazy=True, +# name="ocb", +# module_name="eco.endstations.bernina_sample_environments", +# Id="SARES23", +# ) + +from ..epics.adjustable import AdjustablePv + +# ad hoc N2 jet readout +class N2jet(Assembly): + def __init__(self, name=None): + super().__init__(name=name) + + ### lakeshore temperatures #### + self._append( + AdjustablePv, + pvsetname="SARES20-CRYO:TEMP-C_RBV", + pvreadbackname="SARES20-CRYO:TEMP-C_RBV", + accuracy=0.1, + name="sample_temp", + is_setting=False, + ) + ### oxford jet readouts #### + self._append( + AdjustablePv, + pvsetname="SARES20-OXCS:GasSetPoint", + pvreadbackname="SARES20-OXCS:GasSetPoint", + accuracy=0.1, + name="gas_temp_setpoint", + is_setting=False, + ) + self._append( + AdjustablePv, + pvsetname="SARES20-OXCS:GasTemp", + pvreadbackname="SARES20-OXCS:GasTemp", + accuracy=0.1, + name="gas_temp", + is_setting=False, + ) + self._append( + AdjustablePv, + pvsetname="SARES20-OXCS:GasFlow", + pvreadbackname="SARES20-OXCS:GasFlow", + accuracy=0.1, + name="gas_flow", + is_setting=False, + ) + self._append( + AdjustablePv, + pvsetname="SARES20-OXCS:Remaining", + pvreadbackname="SARES20-OXCS:Remaining", + accuracy=0.1, + name="gas_remaining", + is_setting=False, + ) + + namespace.append_obj( - "Organic_crystal_breadboard", + N2jet, lazy=True, - name="ocb", - module_name="eco.endstations.bernina_sample_environments", - Id="SARES23", + name="jet", ) + # ad hoc incoupling device class Incoupling(Assembly): def __init__(self, name=None): super().__init__(name=name) + self._append(SmaractStreamdevice, "SARES23-ESB16", name="tilt", is_setting=True) self._append( - SmaractStreamdevice, "SARES23-ESB17", name="rx_pump", is_setting=True - ) - self._append( - SmaractStreamdevice, "SARES23-ESB18", name="ry_pump", is_setting=True + SmaractStreamdevice, "SARES23-ESB17", name="rotation", is_setting=True ) -# namespace.append_obj( -# Incoupling, -# lazy=True, -# name="incoupling", -# ) - +namespace.append_obj( + Incoupling, + lazy=True, + name="las_inc", +) from ..devices_general.motors import MotorRecord from ..loptics.bernina_laser import DelayTime from ..microscopes import MicroscopeMotorRecord @@ -726,7 +810,7 @@ from ..microscopes import MicroscopeMotorRecord # from eco.xoptics import dcm_pathlength_compensation as dpc -#namespace.append_obj( +# namespace.append_obj( # "MonoTimecompensation", # # laser2pulse.pump_delay_exp, # las.delay_glob, @@ -736,7 +820,7 @@ from ..microscopes import MicroscopeMotorRecord # lazy=True, # name="mono_time_corrected", # module_name="eco.xoptics.dcm_pathlength_compensation", -#) +# ) # ad hoc interferometric timetool diff --git a/eco/bernina/config.py b/eco/bernina/config.py index 0882fae..202465e 100755 --- a/eco/bernina/config.py +++ b/eco/bernina/config.py @@ -149,6 +149,14 @@ components = [ "z_und": 115, "desc": "Bernina safety shutter", }, + { + "name": "sshut_fe", + "type": "eco.xoptics.shutters:SafetyShutter", + "args": ["SGE01-EPKT820:BST1_oeffnen"], + "kwargs": {}, + "z_und": 115, + "desc": "Bernina safety shutter", + }, { "name": "att_fe", "type": "eco.xoptics.attenuator_aramis:AttenuatorAramis", @@ -663,38 +671,38 @@ components = [ # "kwargs": {}, # "lazy": False, # }, - { - "args": [], - "name": "thc", - "z_und": 142, - "desc": "High field THz Chamber", - "type": "eco.endstations.bernina_sample_environments:High_field_thz_chamber", - "kwargs": {"Id": "SARES23", "configuration": ["ottifant"]}, - }, - { - "args": [], - "name": "ocb", - "z_und": 142, - "desc": "Organic Crystal Breadboard", - "type": "eco.endstations.bernina_sample_environments:Organic_crystal_breadboard", - "kwargs": {"Id": "SARES23"}, - }, - { - "args": [], - "name": "eos", - "z_und": 142, - "desc": "electro optic sampling stages", - "type": "eco.endstations.bernina_sample_environments:Electro_optic_sampling", - "kwargs": { - "Id": "SARES23", - "pgroup": config["pgroup"], - "diode_channels": { - "d1": "SARES20-LSCP9-FNS:CH1:VAL_GET", - "d2": "SARES20-LSCP9-FNS:CH2:VAL_GET", - "diff": "SARES20-LSCP9-FNS:CH3:VAL_GET", - }, - }, - }, + #{ + # "args": [], + # "name": "thc", + # "z_und": 142, + # "desc": "High field THz Chamber", + # "type": "eco.endstations.bernina_sample_environments:High_field_thz_chamber", + # "kwargs": {"Id": "SARES23", "configuration": ["ottifant"]}, + #}, +# { +# "args": [], +# "name": "ocb", +# "z_und": 142, +# "desc": "Organic Crystal Breadboard", +# "type": "eco.endstations.bernina_sample_environments:Organic_crystal_breadboard", +# "kwargs": {"Id": "SARES23"}, +# }, +# { +# "args": [], +# "name": "eos", +# "z_und": 142, +# "desc": "electro optic sampling stages", +# "type": "eco.endstations.bernina_sample_environments:Electro_optic_sampling", +# "kwargs": { +# "Id": "SARES23", +# "pgroup": config["pgroup"], +# "diode_channels": { +# "d1": "SARES20-LSCP9-FNS:CH1:VAL_GET", +# "d2": "SARES20-LSCP9-FNS:CH2:VAL_GET", +# "diff": "SARES20-LSCP9-FNS:CH3:VAL_GET", +# }, +# }, +# }, { "args": [], "name": "dsd", diff --git a/eco/detector/jungfrau.py b/eco/detector/jungfrau.py index e0a35d0..995c8e9 100644 --- a/eco/detector/jungfrau.py +++ b/eco/detector/jungfrau.py @@ -1,8 +1,11 @@ -from ..elements.adjustable import AdjustableVirtual +from tkinter import W +from ..elements.adjustable import AdjustableVirtual, AdjustableGetSet from ..epics.adjustable import AdjustablePv from ..elements.assembly import Assembly from ..aliases import Alias +from pathlib import Path from ..elements import memory +from datetime import datetime class Jungfrau(Assembly): @@ -36,9 +39,41 @@ class Jungfrau(Assembly): append_aliases=False, is_setting=True, ) + self._append( + AdjustableGetSet, + self.get_present_pedestal_filename, + lambda value: NotImplementedError( + "Can not set the pedestal file manually yet." + ), + name="pedestal_file", + is_status=True, + ) + self._append( + AdjustableGetSet, + self.get_present_gain_filename, + lambda value: NotImplementedError( + "Can not set the pedestal file manually yet." + ), + name="gain_file", + is_status=True, + ) def _set_trigger_enable(self, value): if value: self.trigger.set_target_value(self._trigger_on).wait() else: - self.trigger.set_target_value(self._triggeroff).wait() + self.trigger.set_target_value(self._trigger_off).wait() + + def get_present_gain_filename(self): + filepath = Path(f"/sf/jungfrau/config/gainMaps/{self.jf_id}/gains.h5") + + if filepath.exists(): + return filepath.resolve().as_posix() + else: + raise Exception(f"File {filepath.resolve().as_posix()} seems not to exist!") + + def get_present_pedestal_filename(self): + searchpath = Path(f"/sf/jungfrau/data/pedestal/{self.jf_id}") + filelist = list(searchpath.glob("*.h5")) + times = [datetime.strptime(f.stem, "%Y%m%d_%H%M%S") for f in filelist] + return filelist[times.index(max(times))].resolve().as_posix() diff --git a/eco/devices_general/motors.py b/eco/devices_general/motors.py index a318aef..9b20513 100755 --- a/eco/devices_general/motors.py +++ b/eco/devices_general/motors.py @@ -84,7 +84,7 @@ class SmaractStreamdevice(Assembly): offset_file=None, ): super().__init__(name=name) - self.settings.append(self) + # self.settings.append(self) self.settings_collection.append(self, force=True) self.pvname = pvname @@ -431,7 +431,7 @@ class MotorRecord(Assembly): expect_bad_limits=True, ): super().__init__(name=name) - self.settings.append(self) + # self.settings.append(self) self.settings_collection.append(self, force=True) self.pvname = pvname @@ -537,7 +537,7 @@ class MotorRecord(Assembly): is_status=False, ) - def check_bad_limits(self, abs_set_value=2 ** 53): + def check_bad_limits(self, abs_set_value=2**53): ll, hl = self.get_limits() if ll == 0 and hl == 0: self.set_limits(-abs_set_value, abs_set_value) diff --git a/eco/elements/assembly.py b/eco/elements/assembly.py index c6430f2..e09c0c2 100644 --- a/eco/elements/assembly.py +++ b/eco/elements/assembly.py @@ -57,8 +57,8 @@ class Assembly: def __init__(self, name=None, parent=None, is_alias=True): self.name = name self.alias = Alias(name, parent=parent) - self.settings = [] - self.status_indicators = [] + # self.settings = [] + # self.status_indicators = [] self.settings_collection = Collection(name="settings_collection") self.status_indicators_collection = Collection( name="status_indicators_collection" @@ -88,7 +88,7 @@ class Assembly: # print(f'object {name} / {foo_obj_init} not initialized with name/parent') # self.__dict__[name] = foo_obj_init(*args, **kwargs) if is_setting: - self.settings.append(self.__dict__[name]) + # self.settings.append(self.__dict__[name]) self.settings_collection.append(self.__dict__[name], recursive=True) if is_status: @@ -101,8 +101,8 @@ class Assembly: self.__dict__[name], recursive=False ) - if (not is_setting) and is_status: - self.status_indicators.append(self.__dict__[name]) + # if (not is_setting) and is_status: + # self.status_indicators.append(self.__dict__[name]) if view_toplevel_only: self.view_toplevel_only.append(self.__dict__[name]) diff --git a/eco/elements/memory.py b/eco/elements/memory.py index baa983b..841da9b 100644 --- a/eco/elements/memory.py +++ b/eco/elements/memory.py @@ -114,7 +114,7 @@ class Memory: return mem_filt else: - return mem_all + return mem_full def recall( self, diff --git a/eco/endstations/bernina_diffractometers.py b/eco/endstations/bernina_diffractometers.py index 1a4a970..b805e8e 100644 --- a/eco/endstations/bernina_diffractometers.py +++ b/eco/endstations/bernina_diffractometers.py @@ -108,24 +108,31 @@ class GPS(Assembly): MotorRecord, pvname + ":MOT_NY_RY2TH", name="nu", is_setting=True ) self._append( - MotorRecord, pvname + ":MOT_NY_RY2TH", name="gamma", is_setting=False, is_status=False, - ) + MotorRecord, + pvname + ":MOT_NY_RY2TH", + name="gamma", + is_setting=False, + is_status=False, + ) self._append( MotorRecord, pvname + ":MOT_MY_RYTH", name="mu", is_setting=True ) self._append( - MotorRecord, pvname + ":MOT_MY_RYTH", name="alpha", is_setting=False, is_status=False, - ) + MotorRecord, + pvname + ":MOT_MY_RYTH", + name="alpha", + is_setting=False, + is_status=False, + ) self.set_base_off = DeltaTauCurrOff("SARES22-GPS:asyn2.AOUT") - if "phi_table" in self.configuration: ### motors phi table ### self._append( - MotorRecord, pvname + ":MOT_HEX_RX", name="phi", is_setting=True + MotorRecord, pvname + ":MOT_HEX_RX", name="eta", is_setting=True ) self._append( - MotorRecord, pvname + ":MOT_HEX_TX", name="tphi", is_setting=True + MotorRecord, pvname + ":MOT_HEX_TX", name="transl_eta", is_setting=True ) if "phi_hex" in self.configuration: @@ -282,7 +289,14 @@ class GPS(Assembly): # bash -c 'caqtdm -noMsg -stylefile sfop.qss -macro P=SARES22-GPS /ioc/modules/qt/ESB_GPS_exp.ui' def calc_you2kappa( - self, eta, chi, phi, kappa_angle=60, degrees=True, bernina_kappa=True, invert_elbow=False, + self, + eta, + chi, + phi, + kappa_angle=60, + degrees=True, + bernina_kappa=True, + invert_elbow=False, ): """tool to convert from you definition angles to kappa angles, in particular the bernina kappa where the""" @@ -308,11 +322,13 @@ class GPS(Assembly): phi_k = phi_k if True: + def flip_ang(ang): if 1 < abs(ang // np.pi): return ang - np.sign(ang) * np.pi * 2 else: return ang + phi_k = flip_ang(phi_k) eta_k = flip_ang(eta_k) kappa = flip_ang(kappa) @@ -322,7 +338,14 @@ class GPS(Assembly): return eta_k, kappa, phi_k def calc_kappa2you( - self, eta_k, kappa, phi_k, kappa_angle=60, degrees=True, bernina_kappa=True, invert_elbow=False, + self, + eta_k, + kappa, + phi_k, + kappa_angle=60, + degrees=True, + bernina_kappa=True, + invert_elbow=False, ): if degrees: eta_k, kappa, phi_k, kappa_angle = np.deg2rad( @@ -372,7 +395,14 @@ class DeltaTauCurrOff: class XRDYou(Assembly): - def __init__(self, name=None, Id=None, configuration=["base"], diff_detector=None, invert_kappa_ellbow=True): + def __init__( + self, + name=None, + Id=None, + configuration=["base"], + diff_detector=None, + invert_kappa_ellbow=True, + ): """X-ray diffractometer platform in AiwssFEL Bernina.\ : list of elements mounted on the plaform, options are kappa, nutable, hlgonio, polana""" @@ -678,16 +708,21 @@ class XRDYou(Assembly): def set_youvar_value_to_current_kappa(value, varind): vars = list(get_current_kappa2you()) vars[varind] = value - return self.calc_you2kappa(*vars, - bernina_kappa=True, - invert_elbow=self.invert_kappa_ellbow, - ) + return self.calc_you2kappa( + *vars, + bernina_kappa=True, + invert_elbow=self.invert_kappa_ellbow, + ) self._append( AdjustableVirtual, [self.eta_kap, self.kappa, self.phi_kap], lambda eta_kap, kappa, phi_kap: self.calc_kappa2you( - eta_kap, kappa, phi_kap, invert_elbow=self.invert_kappa_ellbow,bernina_kappa=True, + eta_kap, + kappa, + phi_kap, + invert_elbow=self.invert_kappa_ellbow, + bernina_kappa=True, )[0], lambda value_eta: set_youvar_value_to_current_kappa(value_eta, 0), name="eta", @@ -697,7 +732,11 @@ class XRDYou(Assembly): AdjustableVirtual, [self.eta_kap, self.kappa, self.phi_kap], lambda eta_kap, kappa, phi_kap: self.calc_kappa2you( - eta_kap, kappa, phi_kap, invert_elbow=self.invert_kappa_ellbow,bernina_kappa=True, + eta_kap, + kappa, + phi_kap, + invert_elbow=self.invert_kappa_ellbow, + bernina_kappa=True, )[1], lambda value_chi: set_youvar_value_to_current_kappa(value_chi, 1), name="chi", @@ -707,7 +746,11 @@ class XRDYou(Assembly): AdjustableVirtual, [self.eta_kap, self.kappa, self.phi_kap], lambda eta_kap, kappa, phi_kap: self.calc_kappa2you( - eta_kap, kappa, phi_kap, invert_elbow=self.invert_kappa_ellbow,bernina_kappa=True, + eta_kap, + kappa, + phi_kap, + invert_elbow=self.invert_kappa_ellbow, + bernina_kappa=True, )[2], lambda value_phi: set_youvar_value_to_current_kappa(value_phi, 2), name="phi", @@ -751,10 +794,17 @@ class XRDYou(Assembly): # def calc_you2kappa(self, eta, chi, phi): # return you2kappa(eta, chi, phi) -################# + ################# def calc_you2kappa( - self, eta, chi, phi, kappa_angle=60, degrees=True, bernina_kappa=True, invert_elbow=False, + self, + eta, + chi, + phi, + kappa_angle=60, + degrees=True, + bernina_kappa=True, + invert_elbow=False, ): """tool to convert from you definition angles to kappa angles, in particular the bernina kappa where the""" @@ -779,11 +829,13 @@ class XRDYou(Assembly): eta_k = eta_k - np.pi / 2 kappa = -kappa if True: + def flip_ang(ang): if 1 < abs(ang // np.pi): return ang - np.sign(ang) * np.pi * 2 else: return ang + phi_k = flip_ang(phi_k) eta_k = flip_ang(eta_k) kappa = flip_ang(kappa) @@ -792,7 +844,14 @@ class XRDYou(Assembly): return eta_k, kappa, phi_k def calc_kappa2you( - self, eta_k, kappa, phi_k, kappa_angle=60, degrees=True, bernina_kappa=True, invert_elbow=False, + self, + eta_k, + kappa, + phi_k, + kappa_angle=60, + degrees=True, + bernina_kappa=True, + invert_elbow=False, ): if degrees: eta_k, kappa, phi_k, kappa_angle = np.deg2rad( @@ -801,7 +860,7 @@ class XRDYou(Assembly): if bernina_kappa: eta_k = eta_k + np.pi / 2 kappa = -kappa - #phi_k = -phi_k + # phi_k = -phi_k if invert_elbow: kappa = -kappa delta_angle = np.pi - np.arctan(np.tan(kappa / 2) * np.cos(kappa_angle)) @@ -817,52 +876,53 @@ class XRDYou(Assembly): phi = -phi return eta, chi, phi + ################# - # def calc_you2kappa( - # self, eta, chi, phi, kappa_angle=60, degrees=True, bernina_kappa=True - # ): - # """tool to convert from you definition angles to kappa angles, in - # particular the bernina kappa where the""" - # if bernina_kappa: - # eta = -eta - # if degrees: - # eta, chi, phi, kappa_angle = np.deg2rad([eta, chi, phi, kappa_angle]) - # delta_angle = np.arcsin(-np.tan(chi / 2) / np.tan(kappa_angle)) - # eta_k = eta - delta_angle - # kappa = 2 * np.arcsin(np.sin(chi / 2) / np.sin(kappa_angle)) - # phi_k = phi - delta_angle - # - # if bernina_kappa: - # eta_k = eta_k - np.pi / 2 - # kappa = -kappa - # phi_k = phi_k - # if degrees: - # eta_k, kappa, phi_k = np.rad2deg([eta_k, kappa, phi_k]) - # return eta_k, kappa, phi_k - # - # def calc_kappa2you( - # self, eta_k, kappa, phi_k, kappa_angle=60, degrees=True, bernina_kappa=True - # ): - # if degrees: - # eta_k, kappa, phi_k, kappa_angle = np.deg2rad( - # [eta_k, kappa, phi_k, kappa_angle] - # ) - # if bernina_kappa: - # eta_k = eta_k + np.pi / 2 - # kappa = -kappa - # phi_k = phi_k - # delta_angle = np.arctan(np.tan(kappa / 2) * np.cos(kappa_angle)) - # eta = eta_k - delta_angle - # chi = 2 * np.arcsin(np.sin(kappa / 2) * np.sin(kappa_angle)) - # phi = phi_k - delta_angle - # if degrees: - # eta, chi, phi = np.rad2deg([eta, chi, phi]) - # if bernina_kappa: - # eta = -eta - # return eta, chi, phi - # - # # def __repr__(self): - # # return self.get_adjustable_positions_str() +# def calc_you2kappa( +# self, eta, chi, phi, kappa_angle=60, degrees=True, bernina_kappa=True +# ): +# """tool to convert from you definition angles to kappa angles, in +# particular the bernina kappa where the""" +# if bernina_kappa: +# eta = -eta +# if degrees: +# eta, chi, phi, kappa_angle = np.deg2rad([eta, chi, phi, kappa_angle]) +# delta_angle = np.arcsin(-np.tan(chi / 2) / np.tan(kappa_angle)) +# eta_k = eta - delta_angle +# kappa = 2 * np.arcsin(np.sin(chi / 2) / np.sin(kappa_angle)) +# phi_k = phi - delta_angle +# +# if bernina_kappa: +# eta_k = eta_k - np.pi / 2 +# kappa = -kappa +# phi_k = phi_k +# if degrees: +# eta_k, kappa, phi_k = np.rad2deg([eta_k, kappa, phi_k]) +# return eta_k, kappa, phi_k +# +# def calc_kappa2you( +# self, eta_k, kappa, phi_k, kappa_angle=60, degrees=True, bernina_kappa=True +# ): +# if degrees: +# eta_k, kappa, phi_k, kappa_angle = np.deg2rad( +# [eta_k, kappa, phi_k, kappa_angle] +# ) +# if bernina_kappa: +# eta_k = eta_k + np.pi / 2 +# kappa = -kappa +# phi_k = phi_k +# delta_angle = np.arctan(np.tan(kappa / 2) * np.cos(kappa_angle)) +# eta = eta_k - delta_angle +# chi = 2 * np.arcsin(np.sin(kappa / 2) * np.sin(kappa_angle)) +# phi = phi_k - delta_angle +# if degrees: +# eta, chi, phi = np.rad2deg([eta, chi, phi]) +# if bernina_kappa: +# eta = -eta +# return eta, chi, phi +# +# # def __repr__(self): +# # return self.get_adjustable_positions_str() class XRD(Assembly): diff --git a/eco/loptics/bernina_laser.py b/eco/loptics/bernina_laser.py index a77d0d7..bcccdac 100644 --- a/eco/loptics/bernina_laser.py +++ b/eco/loptics/bernina_laser.py @@ -14,12 +14,13 @@ ureg = UnitRegistry() class IncouplingCleanBernina(Assembly): def __init__(self, name=None): super().__init__(name=name) - self._append(SmaractStreamdevice,"SARES23-LIC13",name='tilt') - self._append(SmaractStreamdevice,"SARES23-LIC14",name='rotation') + self._append(SmaractStreamdevice,"SARES23-ESB13",name='tilt') + self._append(SmaractStreamdevice,"SARES23-ESB14",name='rotation') self._append(SmaractStreamdevice,"SARES23-LIC15",name='transl_vertical') self._append(MotorRecord,"SARES20-MF2:MOT_5",name='transl_horizontal') + class LaserBernina(Assembly): def __init__(self, pvname, name=None): super().__init__(name=name) @@ -47,7 +48,10 @@ class LaserBernina(Assembly): self._append(AdjustableFS,'/photonics/home/gac-bernina/eco/configuration/wp_att_calibration',name='wp_att_calibration') def uJ2wp(uJ): - return np.interp(uJ,*np.asarray(self.wp_att_calibration())[::-1].T[::-1]) + direction = 1 + if np.mean(np.diff(np.asarray(self.wp_att_calibration()).T[1]))<0: + direction = -1 + return np.interp(uJ,*np.asarray(self.wp_att_calibration())[::direction].T[::-1]) def wp2uJ(wp): return np.interp(wp,*np.asarray(self.wp_att_calibration()).T) diff --git a/eco/microscopes/microscopes.py b/eco/microscopes/microscopes.py index 29e1bf0..2efe9f9 100644 --- a/eco/microscopes/microscopes.py +++ b/eco/microscopes/microscopes.py @@ -23,7 +23,7 @@ class MicroscopeMotorRecord(Assembly): CameraBasler, pvname_camera, camserver_alias=camserver_alias, - name="camera", + name=name, is_setting=True, is_status="recursive", ) @@ -62,7 +62,7 @@ class BerninaInlineMicroscope(Assembly): self._append( CameraBasler, pvname_camera, - camserver_alias = self.alias.get_full_name() + f" ({pvname_camera})", + camserver_alias=self.alias.get_full_name() + f" ({pvname_camera})", name="camera", is_setting=True, is_status="recursive", @@ -83,7 +83,7 @@ class OptoSigmaZoom(Assembly): name=None, ): super().__init__(name=name) - self.settings.append(self) + self.settings_collection.append(self) self._append( AdjustablePv, pv_set_position, diff --git a/eco/utilities/runtable.py b/eco/utilities/runtable.py index 09d59c6..dcd7651 100644 --- a/eco/utilities/runtable.py +++ b/eco/utilities/runtable.py @@ -719,7 +719,7 @@ class Gsheet_API: ) self.gc = gspread.authorize(self._credentials) self._keydf_fname = keydf_fname - self.keys = "metadata midir xrd energy transmission delay lxt pulse_id att_self att_fe_self" + self.keys = "metadata gps jet energy las_inc delay lxt pulse_id att_self att_fe_self" self._key_df=DataFrame() self.gsheet_keys = AdjustableFS(gsheet_key_path, name="gsheet_keys", default_value='metadata thc gps xrd att att_usd kb') self.init_runtable(exp_id) @@ -1023,7 +1023,7 @@ class Run_Table_DataFrame(DataFrame): self._parse_exclude_keys = "status_indicators settings_collection status_indicators_collection presets memory _elog _currentChange _flags __ alias namespace daq scan MasterEventSystem _motor Alias".split(" ") self._parse_exclude_class_types = ("__ alias namespace daq scan MasterEventSystem _motor Alias AdjustablePv".split(" ")) self._adj_exclude_class_types = ("__ alias namespace daq scan MasterEventSystem _motor Alias".split(" ")) - self.key_order = "metadata xrd midir env_thc temperature1_rbk temperature2_rbk time name gps gps_hex thc ocb eos las lxt phase_shifter mono att att_fe slit_und slit_switch slit_att slit_kb slit_cleanup pulse_id mono_energy_rbk att_transmission att_fe_transmission" + self.key_order = "metadata gps xrd midir env_thc temperature1_rbk temperature2_rbk time name gps gps_hex thc ocb eos las lxt phase_shifter mono att att_fe slit_und slit_switch slit_att slit_kb slit_cleanup pulse_id mono_energy_rbk att_transmission att_fe_transmission" pd.options.display.max_rows = 100 pd.options.display.max_columns = 50 pd.set_option("display.float_format", lambda x: "%.5g" % x) diff --git a/eco/xdiagnostics/intensity_monitors.py b/eco/xdiagnostics/intensity_monitors.py index 4412928..a3f464a 100755 --- a/eco/xdiagnostics/intensity_monitors.py +++ b/eco/xdiagnostics/intensity_monitors.py @@ -636,3 +636,202 @@ class SolidTargetDetectorPBPS_new_assembly(Assembly): return gains except: print("No diodes configured, can not change any gain!") + + +class SolidTargetDetectorPBPS_assembly(Assembly): + def __init__( + self, + pvname, + VME_crate=None, + pipeline=None, + link=None, + channels={}, + ch_up=12, + ch_down=13, + ch_left=15, + ch_right=14, + elog=None, + name=None, + calc=None, + calc_calib={}, + ): + super().__init__(name=name) + self.pvname = pvname + self._append( + MotorRecord, pvname + ":MOTOR_X1", name="x_diodes", is_setting=True + ) + self._append( + MotorRecord, pvname + ":MOTOR_Y1", name="y_diodes", is_setting=True + ) + self._append( + MotorRecord, pvname + ":MOTOR_PROBE", name="target_y", is_setting=True + ) + self._append( + AdjustablePvEnum, pvname + ":PROBE_SP", name="target", is_setting=True + ) + self + if VME_crate: + self.diode_up = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_up)) + self.diode_down = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_down)) + self.diode_left = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_left)) + self.diode_right = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_right)) + + if channels: + self._append( + DetectorPvDataStream, channels["up"], name="signal_up", is_setting=False + ) + self._append( + DetectorPvDataStream, + channels["down"], + name="signal_down", + is_setting=False, + ) + self._append( + DetectorPvDataStream, + channels["left"], + name="signal_left", + is_setting=False, + ) + self._append( + DetectorPvDataStream, + channels["right"], + name="signal_right", + is_setting=False, + ) + + if calc: + self._append( + DetectorPvDataStream, calc["itot"], name="intensity", is_setting=False + ) + self._append( + DetectorPvDataStream, calc["xpos"], name="xpos", is_setting=False + ) + self._append( + DetectorPvDataStream, calc["ypos"], name="ypos", is_setting=False + ) + + def get_calibration_values(self, seconds=5): + self.x_diodes.set_target_value(0).wait() + self.y_diodes.set_target_value(0).wait() + ds = [self.signal_up, self.signal_down, self.signal_left, self.signal_right] + aqs = [d.acquire(seconds=seconds) for d in ds] + data = [aq.wait() for aq in aqs] + mean = [np.mean(td) for td in data] + std = [np.std(td) for td in data] + norm_diodes = [1 / tm / 4 for tm in mean] + return norm_diodes + + def set_calibration_values(self, norm_diodes): + # this is now only for bernina when using the ioxos from sla + channels = [ + "SLAAR21-LTIM01-EVR0:CALCI.INPG", + "SLAAR21-LTIM01-EVR0:CALCI.INPH", + "SLAAR21-LTIM01-EVR0:CALCI.INPE", + "SLAAR21-LTIM01-EVR0:CALCI.INPF", + ] + for tc, tv in zip(channels, norm_diodes): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCX.INPE", "SLAAR21-LTIM01-EVR0:CALCX.INPF"] + for tc, tv in zip(channels, norm_diodes[2:4]): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCY.INPE", "SLAAR21-LTIM01-EVR0:CALCY.INPF"] + for tc, tv in zip(channels, norm_diodes[0:2]): + PV(tc).put(bytes(str(tv), "utf8")) + + def get_calibration_values_position( + self, calib_intensities, seconds=5, motion_range=0.2 + ): + self.x_diodes.set_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.y_diodes.set_limits(-motion_range / 2 - 0.1, +motion_range / 2 + 0.1) + self.x_diodes.set_target_value(0).wait() + self.y_diodes.set_target_value(0).wait() + raw = [] + for pos in [motion_range / 2, -motion_range / 2]: + print(pos) + self.x_diodes.set_target_value(pos).wait() + aqs = [ + ts.acquire(seconds=seconds) + for ts in [self.signal_left, self.signal_right] + ] + vals = [ + np.mean(aq.wait()) * calib + for aq, calib in zip(aqs, calib_intensities[0:2]) + ] + raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) + grad = motion_range / np.diff(raw)[0] + # xcalib = [np.diff(calib_intensities[0:2])[0]/np.sum(calib_intensities[0:2]), grad] + xcalib = [0, grad] + self.x_diodes.set_target_value(0).wait() + raw = [] + for pos in [motion_range / 2, -motion_range / 2]: + self.y_diodes.set_target_value(pos).wait() + aqs = [ + ts.acquire(seconds=seconds) for ts in [self.signal_up, self.signal_down] + ] + vals = [ + np.mean(aq.wait()) * calib + for aq, calib in zip(aqs, calib_intensities[2:4]) + ] + raw.append((vals[0] - vals[1]) / (vals[0] + vals[1])) + grad = motion_range / np.diff(raw)[0] + # ycalib = [np.diff(calib_intensities[2:4])[0]/np.sum(calib_intensities[2:4]), grad] + ycalib = [0, grad] + self.y_diodes.set_target_value(0).wait() + return xcalib, ycalib + + def set_calibration_values_position(self, xcalib, ycalib): + channels = ["SLAAR21-LTIM01-EVR0:CALCX.INPJ", "SLAAR21-LTIM01-EVR0:CALCX.INPI"] + # txcalib = [-1*xcalib[0],-1*xcalib[1]] + for tc, tv in zip(channels, xcalib): + PV(tc).put(bytes(str(tv), "utf8")) + channels = ["SLAAR21-LTIM01-EVR0:CALCY.INPJ", "SLAAR21-LTIM01-EVR0:CALCY.INPI"] + for tc, tv in zip(channels, ycalib): + PV(tc).put(bytes(str(tv), "utf8")) + + def calibrate(self, seconds=5): + c = self.get_calibration_values(seconds=seconds) + self.set_calibration_values(c) + xc, yc = self.get_calibration_values_position(c, seconds=seconds) + self.set_calibration_values_position(xc, yc) + + def set_gains(self, value): + try: + self.diode_up.gain.set(value) + self.diode_down.gain.set(value) + self.diode_left.gain.set(value) + self.diode_right.gain.set(value) + except: + print("No diodes configured, can not change any gain!") + + def get_available_gains(self): + try: + nu = self.diode_up.gain.names + nd = self.diode_down.gain.names + nl = self.diode_left.gain.names + nr = self.diode_right.gain.names + assert ( + nu == nd == nl == nr + ), "NB: the gain options of the four diodes are not equal!!!" + return nu + except: + print("No diodes configured, can not change any gain!") + + def get_gains(self): + try: + gains = dict() + gains["up"] = (self.diode_up.gain.get_name(), self.diode_up.gain.get()) + gains["down"] = ( + self.diode_down.gain.get_name(), + self.diode_down.gain.get(), + ) + gains["left"] = ( + self.diode_left.gain.get_name(), + self.diode_left.gain.get(), + ) + gains["right"] = ( + self.diode_right.gain.get_name(), + self.diode_right.gain.get(), + ) + return gains + except: + print("No diodes configured, can not change any gain!")