diff --git a/eco/acquisition/bs_data.py b/eco/acquisition/bs_data.py index fc6a1ab..eafbda6 100755 --- a/eco/acquisition/bs_data.py +++ b/eco/acquisition/bs_data.py @@ -172,6 +172,7 @@ class BStools: f"Path {data_dir.absolute().as_posix()} does not exist, will try to create it..." ) data_dir.mkdir(parents=True) + print(f"Tried to create {data_dir.absolute().as_posix()}") data_dir.chmod(0o775) print(f"Tried to change permissions to 775") diff --git a/eco/acquisition/daq_client.py b/eco/acquisition/daq_client.py index 4ac3513..fd1efa6 100644 --- a/eco/acquisition/daq_client.py +++ b/eco/acquisition/daq_client.py @@ -1,3 +1,4 @@ +import shutil import time import requests from pathlib import Path @@ -63,15 +64,18 @@ class Daq(Assembly): self._detectors_event_code = detectors_event_code self.name = name self._default_file_path = None - if not rate_multiplicator=='auto': - print('warning: rate multiplicator automatically determined from event_master!') - - + if not rate_multiplicator == "auto": + print( + "warning: rate multiplicator automatically determined from event_master!" + ) + @property def rate_multiplicator(self): - freq = self._event_master.__dict__[f'code{self._detectors_event_code:03d}'].frequency.get_current_value() - return int(100/freq) - + freq = self._event_master.__dict__[ + f"code{self._detectors_event_code:03d}" + ].frequency.get_current_value() + return int(100 / freq) + @property def pgroup(self): if isinstance(self._pgroup, Adjustable): @@ -121,8 +125,8 @@ class Daq(Assembly): def start(self, label=None, **kwargs): starttime_local = time.time() - while self.pulse_id._pv.get_timevars()['timestamp'] < starttime_local: - time.sleep(.02) + while self.pulse_id._pv.get_timevars()["timestamp"] < starttime_local: + time.sleep(0.02) start_id = self.pulse_id.get_current_value(use_monitor=False) acq_pars = { "label": label, @@ -266,7 +270,9 @@ class Daq(Assembly): f"{self.broker_address}/power_on_detector", json=par ).json() - def take_pedestal(self, JF_list=None, pgroup=None): + def take_pedestal( + self, JF_list=None, pedestalmode=False, pgroup=None, verbose=False + ): if pgroup is None: pgroup = self.pgroup if not JF_list: @@ -275,16 +281,25 @@ class Daq(Assembly): "pgroup": pgroup, "rate_multiplicator": 1, "detectors": {tJF: {} for tJF in JF_list}, + "pedestalmode": pedestalmode, } + if verbose: + print(self.broker_address) + print(parameters) + return requests.post( f"{self.broker_address}/take_pedestal", json=parameters ).json() - def append_aux(self, *file_names, run_number=None, pgroup=None): + def append_aux(self, *file_names, run_number=None, pgroup=None, check_group=True): if pgroup is None: pgroup = self.pgroup if run_number is None: run_number = self.get_last_run_number() + if check_group: + for file_name in file_names: + if not Path(file_name).group() == pgroup: + shutil.chown(file_name, group=pgroup) return requests.post( self.broker_address_aux + "/copy_user_files", diff --git a/eco/acquisition/epics_data.py b/eco/acquisition/epics_data.py index 23dd6ca..7b1bb69 100644 --- a/eco/acquisition/epics_data.py +++ b/eco/acquisition/epics_data.py @@ -11,6 +11,7 @@ from .utilities import Acquisition import time from ..elements.adjustable import AdjustableFS + class EpicsDaq: def __init__( self, @@ -19,19 +20,25 @@ class EpicsDaq: channel_list=None, ): self.name = name - self.default_file_path = AdjustableFS(f'/sf/bernina/config/eco/reference_values/{name}_default_file_path.json', default_value="~/data/", name="default_file_path") + self.default_file_path = AdjustableFS( + f"/sf/bernina/config/eco/reference_values/{name}_default_file_path.json", + default_value="~/data/", + name="default_file_path", + ) self._elog = elog self.channels = {} self.pulse_id = PV("SLAAR11-LTIM01-EVR0:RX-PULSEID") self.channel_list = channel_list self.update_channels() + @property def _default_file_path(self): return self.default_file_path() + @_default_file_path.setter def _default_file_path(self, val): self.default_file_path(val) - + def update_channels(self): channels = self.channel_list.get_current_value() for channel in channels: @@ -63,8 +70,8 @@ class EpicsDaq: else: shape = (N_pulses,) dtype = type(channelval) - data[k]=np.ndarray(shape, dtype=dtype) - counters[k]=0 + data[k] = np.ndarray(shape, dtype=dtype) + counters[k] = 0 def cb_getdata(ch=None, k="", *args, **kwargs): data[k][counters[k]] = kwargs["value"] @@ -175,7 +182,7 @@ class Epicstools: if counters[m] == N_pulses: ch.clear_callbacks() - for (m, channel) in enumerate(channels): + for m, channel in enumerate(channels): channel.add_callback(callback=cb_getdata, ch=channel, m=m) while True: sleep(0.005) @@ -183,7 +190,7 @@ class Epicstools: break f = h5py.File(name=fina, mode="w") - for (n, channel) in enumerate(channel_list): + for n, channel in enumerate(channel_list): dat = f.create_group(name=channel) dat.create_dataset(name="data", data=data[n]) dat.create_dataset( diff --git a/eco/bernina/bernina.py b/eco/bernina/bernina.py index f95d170..0445b4b 100644 --- a/eco/bernina/bernina.py +++ b/eco/bernina/bernina.py @@ -25,7 +25,7 @@ from ..aliases import NamespaceCollection import pyttsx3 from ..utilities.path_alias import PathAlias -import sys, os +import sys, os, shutil import numpy as np from IPython import get_ipython @@ -50,9 +50,13 @@ namespace.append_obj(AdjustableObject, _config_bernina_dict, name="config_bernin namespace.append_obj( "RunData", config_bernina.pgroup, - name='runs', - load_kwargs = {'checknstore_parsing_result': '/sf/bernina/data/{pgroup}/res', 'load_dap_data':True, 'lazyEscArrays':True}, - module_name='eco.acquisition.scan_data', + name="runs", + load_kwargs={ + "checknstore_parsing_result": "/sf/bernina/data/{pgroup}/res", + "load_dap_data": True, + "lazyEscArrays": True, + }, + module_name="eco.acquisition.scan_data", ) namespace.append_obj( @@ -111,7 +115,7 @@ namespace.append_obj( add_to_cnf=True, lazy=True, ) -eco.defaults.ARCHIVER=archiver +eco.defaults.ARCHIVER = archiver namespace.append_obj( "get_strip_chart_function", @@ -726,7 +730,7 @@ namespace.append_obj( "TimetoolBerninaUSD", module_name="eco.timing.timing_diag", pvname_mirror="SARES23-LIC:MOT_11", - andor_spectrometer='SLAAR11-LSPC-ALCOR1', + andor_spectrometer="SLAAR11-LSPC-ALCOR1", name="tt_kb", lazy=True, ) @@ -982,7 +986,7 @@ namespace.append_obj( module_name="eco.endstations.bernina_robots", name="rob", pshell_url="http://PC14742:8080/", - robot_config = config_bernina.robot_config, + robot_config=config_bernina.robot_config, pgroup_adj=config_bernina.pgroup, jf_config=config_JFs, lazy=True, @@ -1066,15 +1070,15 @@ namespace.append_obj( ) -# namespace.append_obj( -# "Jungfrau", -# "JF03T01V02", -# name="det_i0", -# pgroup_adj=config_bernina.pgroup, -# module_name="eco.detector.jungfrau", -# config_adj=config_JFs, -# lazy=True, -# ) +namespace.append_obj( + "Jungfrau", + "JF01T03V01", + name="_det_diff", + pgroup_adj=config_bernina.pgroup, + module_name="eco.detector.jungfrau", + config_adj=config_JFs, + lazy=True, +) namespace.append_obj( "Jungfrau", @@ -1162,11 +1166,11 @@ namespace.append_obj( ### draft new epics daq ### namespace.append_obj( - "EpicsDaq", - channel_list=channels_CA_epicsdaq, - name="daq_epics_local", - module_name="eco.acquisition.epics_data", - lazy=True, + "EpicsDaq", + channel_list=channels_CA_epicsdaq, + name="daq_epics_local", + module_name="eco.acquisition.epics_data", + lazy=True, ) ### old epics daq ### # namespace.append_obj( @@ -1185,16 +1189,16 @@ namespace.append_obj( # ) namespace.append_obj( - "Scans", - name="scans_epics", - module_name="eco.acquisition.scan", - data_base_dir=f"{config_bernina.pgroup()}/scan_data", - scan_info_dir=f"{daq_epics_local.default_file_path()}/{config_bernina.pgroup()}/scan_info", - default_counters=[daq_epics_local], - checker=None, - scan_directories=True, - run_table=None, - lazy=True, + "Scans", + name="scans_epics", + module_name="eco.acquisition.scan", + data_base_dir=f"{config_bernina.pgroup()}/scan_data", + scan_info_dir=f"{daq_epics_local.default_file_path()}/{config_bernina.pgroup()}/scan_info", + default_counters=[daq_epics_local], + checker=None, + scan_directories=True, + run_table=None, + lazy=True, ) # # @@ -1211,7 +1215,7 @@ namespace.append_obj( pulse_id_adj="SLAAR21-LTIM01-EVR0:RX-PULSEID", event_master=event_master, detectors_event_code=50, - rate_multiplicator='auto', + rate_multiplicator="auto", name="daq", module_name="eco.acquisition.daq_client", lazy=True, @@ -1275,12 +1279,20 @@ def _write_namespace_status_to_scan( scan.status["status_run_end"] = namespace_status if (not end_scan) and not (len(scan.values_done) == 1): return - runno = daq.get_last_run_number() + if hasattr(scan,'daq_run_number'): + runno = scan.daq_run_number + else: + runno = daq.get_last_run_number() pgroup = daq.pgroup tmpdir = Path(f"/sf/bernina/data/{pgroup}/res/tmp/stat_run{runno:04d}") tmpdir.mkdir(exist_ok=True, parents=True) + try: + tmpdir.chmod(0o775) + except: + pass + statusfile = tmpdir / Path("status.json") - if not Path(statusfile).exists(): + if not statusfile.exists(): with open(statusfile, "w") as f: json.dump(scan.status, f, sort_keys=True, cls=NumpyEncoder, indent=4) else: @@ -1288,6 +1300,8 @@ def _write_namespace_status_to_scan( f.seek(0) json.dump(scan.status, f, sort_keys=True, cls=NumpyEncoder, indent=4) f.truncate() + if not statusfile.group() == statusfile.parent.group(): + shutil.chown(statusfile, group=statusfile.parent.group()) response = daq.append_aux( statusfile.resolve().as_posix(), pgroup=pgroup, @@ -1302,10 +1316,17 @@ def _write_namespace_status_to_scan( def _write_namespace_aliases_to_scan(scan, daq=daq, force=False, **kwargs): if force or (len(scan.values_done) == 1): namespace_aliases = namespace.alias.get_all() - runno = daq.get_last_run_number() + if hasattr(scan,'daq_run_number'): + runno = scan.daq_run_number + else: + runno = daq.get_last_run_number() pgroup = daq.pgroup tmpdir = Path(f"/sf/bernina/data/{pgroup}/res/tmp/aliases_run{runno:04d}") tmpdir.mkdir(exist_ok=True, parents=True) + try: + tmpdir.chmod(0o775) + except: + pass aliasfile = tmpdir / Path("aliases.json") if not Path(aliasfile).exists(): with open(aliasfile, "w") as f: @@ -1319,6 +1340,8 @@ def _write_namespace_aliases_to_scan(scan, daq=daq, force=False, **kwargs): namespace_aliases, f, sort_keys=True, cls=NumpyEncoder, indent=4 ) f.truncate() + if not aliasfile.group() == aliasfile.parent.group(): + shutil.chown(aliasfile, group=aliasfile.parent.group()) scan.remaining_tasks.append( Thread( @@ -1395,10 +1418,17 @@ def _copy_scan_info_to_raw(scan, daq=daq, **kwargs): si["scan_files"] = newfiles # save temprary file and send then to raw - runno = daq.get_last_run_number() + if hasattr(scan,'daq_run_number'): + runno = scan.daq_run_number + else: + runno = daq.get_last_run_number() pgroup = daq.pgroup tmpdir = Path(f"/sf/bernina/data/{pgroup}/res/tmp/info_run{runno:04d}") tmpdir.mkdir(exist_ok=True, parents=True) + try: + tmpdir.chmod(0o775) + except: + pass scaninfofile = tmpdir / Path("scan_info_rel.json") if not Path(scaninfofile).exists(): with open(scaninfofile, "w") as f: @@ -1408,7 +1438,8 @@ def _copy_scan_info_to_raw(scan, daq=daq, **kwargs): f.seek(0) json.dump(si, f, sort_keys=True, cls=NumpyEncoder, indent=4) f.truncate() - + if not scaninfofile.group() == scaninfofile.parent.group(): + shutil.chown(scaninfofile, group=scaninfofile.parent.group()) # print(f"Copying info file to run {runno} to the raw directory of {pgroup}.") scan.remaining_tasks.append( @@ -1432,8 +1463,12 @@ from eco.detector import Jungfrau def _copy_selected_JF_pedestals_to_raw( scan, daq=daq, copy_selected_JF_pedestals_to_raw=True, **kwargs ): - def copy_to_aux(daq): - runno = daq.get_last_run_number() + def copy_to_aux(daq,scan): + if hasattr(scan,'daq_run_number'): + runno = scan.daq_run_number + else: + runno = daq.get_last_run_number() + pgroup = daq.pgroup for jf_id in daq.channels["channels_JF"](): @@ -1463,7 +1498,7 @@ def _copy_selected_JF_pedestals_to_raw( ) if copy_selected_JF_pedestals_to_raw: - scan.remaining_tasks.append(Thread(target=copy_to_aux, args=[daq])) + scan.remaining_tasks.append(Thread(target=copy_to_aux, args=[daq,scan])) scan.remaining_tasks[-1].start() @@ -1485,6 +1520,8 @@ def _increment_daq_run_number(scan, daq=daq, **kwargs): for i in range(n): rn = daq.get_next_run_number() print(rn) + scan.daq_run_number = daq_run_number + except Exception as e: print(e) @@ -1568,10 +1605,17 @@ def end_scan_monitors(scan, daq=daq, **kwargs): from os.path import relpath # save temprary file and send then to raw - runno = daq.get_last_run_number() + if hasattr(scan,'daq_run_number'): + runno = scan.daq_run_number + else: + runno = daq.get_last_run_number() pgroup = daq.pgroup tmpdir = Path(f"/sf/bernina/data/{pgroup}/res/tmp/info_run{runno:04d}") tmpdir.mkdir(exist_ok=True, parents=True) + try: + tmpdir.chmod(0o775) + except: + pass scanmonitorfile = tmpdir / Path("scan_monitor.pkl") if not Path(scanmonitorfile).exists(): with open(scanmonitorfile, "wb") as f: @@ -1797,11 +1841,11 @@ namespace.append_obj( # this is the large inline camera namespace.append_obj( - "BerninaInlineMicroscope", - pvname_camera="SARES20-CAMS142-M3", - lazy=True, - name="samplecam_inline", - module_name="eco.microscopes", + "BerninaInlineMicroscope", + pvname_camera="SARES20-CAMS142-M3", + lazy=True, + name="samplecam_inline", + module_name="eco.microscopes", ) # namespace.append_obj( @@ -1841,22 +1885,22 @@ namespace.append_obj( # lazy=True, # ) -#namespace.append_obj( +# namespace.append_obj( # "MicroscopeFeturaPlus", # "SARES20-PROF142-M1", # lazy=True, # name="samplecam_highres", # module_name="eco.microscopes", -#) +# ) -#namespace.append_obj( +# namespace.append_obj( # "MicroscopeMotorRecord", # "SARES20-CAMS142-C1", # lazy=True, # pvname_zoom="SARES20-MF1:MOT_7", # name="samplecam_topview", # module_name="eco.microscopes", -#) +# ) namespace.append_obj( "CameraBasler", @@ -2643,7 +2687,11 @@ try: f"/sf/bernina/data/{config_bernina.pgroup()}/res/eco" ) pgroup_eco_path.mkdir(mode=0o775, exist_ok=True) - pgroup_eco_path.chmod(mode=0o775) + try: + pgroup_eco_path.chmod(mode=0o775) + except: + pass + sys.path.append(pgroup_eco_path.as_posix()) else: print( @@ -2679,26 +2727,26 @@ namespace.append_obj(Xspect_EH55, name="xspect_bernina", lazy=True) ############## BIG JJ SLIT ##################### namespace.append_obj( - "SlitBladesGeneral", - name="slit_cleanup_air", - def_blade_up={ - "args": [MotorRecord, "SARES20-MF1:MOT_10"], - "kwargs": {"is_psi_mforce": True}, - }, - def_blade_down={ - "args": [MotorRecord, "SARES20-MF1:MOT_9"], - "kwargs": {"is_psi_mforce": True}, - }, - def_blade_left={ - "args": [MotorRecord, "SARES20-MF1:MOT_12"], - "kwargs": {"is_psi_mforce": True}, - }, - def_blade_right={ - "args": [MotorRecord, "SARES20-MF1:MOT_11"], - "kwargs": {"is_psi_mforce": True}, - }, - module_name="eco.xoptics.slits", - lazy=True, + "SlitBladesGeneral", + name="slit_cleanup_air", + def_blade_up={ + "args": [MotorRecord, "SARES20-MF1:MOT_10"], + "kwargs": {"is_psi_mforce": True}, + }, + def_blade_down={ + "args": [MotorRecord, "SARES20-MF1:MOT_9"], + "kwargs": {"is_psi_mforce": True}, + }, + def_blade_left={ + "args": [MotorRecord, "SARES20-MF1:MOT_12"], + "kwargs": {"is_psi_mforce": True}, + }, + def_blade_right={ + "args": [MotorRecord, "SARES20-MF1:MOT_11"], + "kwargs": {"is_psi_mforce": True}, + }, + module_name="eco.xoptics.slits", + lazy=True, ) ############## SMALL JJ SLIT ##################### @@ -2760,10 +2808,10 @@ class IlluminatorsLasers(Assembly): def __init__(self, name="sample_illumination"): super().__init__(name=name) self._append( - MpodChannel, - pvbase="SARES21-CPCL-PS7071", - channel_number=5, - name="illumination_inline", + MpodChannel, + pvbase="SARES21-CPCL-PS7071", + channel_number=5, + name="illumination_inline", ) self._append( MpodChannel, @@ -2771,18 +2819,18 @@ class IlluminatorsLasers(Assembly): channel_number=2, name="illumination_side", ) - #self._append( + # self._append( # MpodChannel, # pvbase="SARES21-CPCL-PS7071", # channel_number=6, # name="illumination_top", - #) - #self._append( + # ) + # self._append( # MpodChannel, # pvbase="SARES21-CPCL-PS7071", # channel_number=4, # name="flattening_laser", - #) + # ) namespace.append_obj(IlluminatorsLasers, name="sample_illumination", lazy=True) @@ -2861,9 +2909,8 @@ class Tapedrive(Assembly): self._append(SmaractRecord, "SARES23-USR:MOT_12", name="freespace_ver") self._append(SmaractRecord, "SARES23-USR:MOT_13", name="freespace_hor") - self._append(MotorRecord, "SARES20-MF1:MOT_13",name='x_target_totem') - self._append(MotorRecord, "SARES20-MF1:MOT_14",name='y_target_totem') - + self._append(MotorRecord, "SARES20-MF1:MOT_13", name="x_target_totem") + self._append(MotorRecord, "SARES20-MF1:MOT_14", name="y_target_totem") self._append(AnalogOutput, "SARES20-CWAG-GPS01:DAC01", name="shutter1") self._append(AnalogOutput, "SARES20-CWAG-GPS01:DAC02", name="shutter2") @@ -2925,21 +2972,22 @@ class Tapedrive(Assembly): DigitizerIoxosBoxcarChannel, "SARES20-LSCP9-FNS:CH2", name="diode_2" ) - self._append( AdjustableFS, "/photonics/home/gac-bernina/eco/configuration/p20231_mono_und_offset", name="mono_und_calib", - default_value=[[6500,0],[7100,0]], + default_value=[[6500, 0], [7100, 0]], is_setting=True, ) def en_set(en): ofs = np.array(self.mono_und_calib()).T - fel_ofs = ofs[1][np.argmin(abs(ofs[0]-en))] - return en , en/1000 - fel_ofs + fel_ofs = ofs[1][np.argmin(abs(ofs[0] - en))] + return en, en / 1000 - fel_ofs + def en_get(monoen, felen): return monoen + self._append( AdjustableVirtual, [mono, fel.aramis_photon_energy_undulators], @@ -2947,10 +2995,15 @@ class Tapedrive(Assembly): en_set, name="mono_und_energy", ) + def add_mono_und_calibration(self): mono_energy = mono.get_current_value() - fel_offset = mono.get_current_value() /1000 - fel.aramis_photon_energy_undulators.get_current_value() - self.mono_und_calib.mvr([[mono_energy,fel_offset]]) + fel_offset = ( + mono.get_current_value() / 1000 + - fel.aramis_photon_energy_undulators.get_current_value() + ) + self.mono_und_calib.mvr([[mono_energy, fel_offset]]) + # namespace.append_obj(Tapedrive, name="tapedrive", lazy=True) @@ -3068,17 +3121,18 @@ def name2pgroups(name, beamline="bernina"): return eq + ni - - def timetool_data_monitor(warning_threshold=1000, loopsleep=5): dir(bs_worker) tt_kb.spectrum_signal.stream.accumulate(do_accumulate=True) - print('Monitoring timetool data ...') + print("Monitoring timetool data ...") while True: - eid_diff= int(event_system.pulse_id.get_current_value() - tt_kb.spectrum_signal.stream.eventIds[-1][-1]) - if eid_diff> warning_threshold: + eid_diff = int( + event_system.pulse_id.get_current_value() + - tt_kb.spectrum_signal.stream.eventIds[-1][-1] + ) + if eid_diff > warning_threshold: message = f"Last timetool data {eid_diff} pulses ago!" print(message) try: @@ -3089,4 +3143,3 @@ def timetool_data_monitor(warning_threshold=1000, loopsleep=5): except: pass time.sleep(loopsleep) - diff --git a/eco/detector/jungfrau.py b/eco/detector/jungfrau.py index 3752fd7..3868089 100644 --- a/eco/detector/jungfrau.py +++ b/eco/detector/jungfrau.py @@ -1,4 +1,5 @@ import shutil +import time from tkinter import W from eco.base.adjustable import Adjustable @@ -110,6 +111,7 @@ class Jungfrau(Assembly): name="gain_file_in_run", is_display=True, ) + self._last_dap_req_time = 0 self._append( AdjustableGetSet, self.get_dap_settings, @@ -162,14 +164,19 @@ class Jungfrau(Assembly): dest = Path( f"/sf/bernina/data/{self.pgroup()}/res/tmp/gainmaps_{self.jf_id}.h5" ) - + try: if not dest.exists(): dest.parent.mkdir(parents=True, exist_ok=True, mode=0o775) + try: + dest.parent.chmod(0o775) + except: + pass shutil.copyfile(f, dest) + except PermissionError: return "No permissions to res directory!" - + if intempdir: return dest.as_posix() else: @@ -189,24 +196,29 @@ class Jungfrau(Assembly): try: if not dest.exists(): dest.parent.mkdir(parents=True, exist_ok=True, mode=0o775) - dest.parent.chmod(0o775) + try: + dest.parent.chmod(0o775) + except: + pass shutil.copyfile(f, dest) except PermissionError: return "No poermissions to res directory!" - if intempdir: return dest.as_posix() else: return f"aux/{dest.name}" def get_dap_settings(self): - m = requests.get( - f"{self.broker_address_aux}/get_dap_settings", - json={"detector_name": self.jf_id}, - ).json() - if m["status"] == "ok": - return m["parameters"] + if 5 < (time.time()-self._last_dap_req_time): + self._last_dap_message = requests.get( + f"{self.broker_address_aux}/get_dap_settings", + json={"detector_name": self.jf_id}, + ).json() + self._last_dap_req_time = time.time() + + if self._last_dap_message["status"] == "ok": + return self._last_dap_message["parameters"] def set_dap_settings(self, dap_setting_dict): # print("Setting not implmented yet!") diff --git a/eco/devices_general/env_sensors.py b/eco/devices_general/env_sensors.py index 3f6ae94..caa6c0d 100644 --- a/eco/devices_general/env_sensors.py +++ b/eco/devices_general/env_sensors.py @@ -49,6 +49,7 @@ class BerninaEnvironment(Assembly): for pvbase,channelnumbers,tnames in zip(pvbases,channels,channelnames): for n,tname in zip(channelnumbers,tnames): self._append(I2cChannel,pvbase,channelnumber=n,name=tname) + self._append(DetectorPvData,"IKA-GAMA:Luft_SF", unit='%', name='he_recovery_air_content') class WagoSensor(Assembly): diff --git a/eco/elements/adjustable.py b/eco/elements/adjustable.py index 99196a6..5771f51 100644 --- a/eco/elements/adjustable.py +++ b/eco/elements/adjustable.py @@ -466,6 +466,10 @@ class AdjustableFS: if not self.file_path.exists(): if not self.file_path.parent.exists(): self.file_path.parent.mkdir(parents=True) + try: + self.file_path.parent.chmod(0o775) + except: + pass self._write_value(default_value) self.alias = Alias(name) self.name = name @@ -630,15 +634,15 @@ class AdjustableGetSet: self, foo_get, foo_set, - set_returns_changer = False, + set_returns_changer=False, precision=0, check_interval=None, cache_get_seconds=None, - unit = None, + unit=None, name=None, ): """assumes a waiting setterin function, in case no check_interval parameter is supplied. - if returns_changer, does not create an additional thread""" + if returns_changer, does not create an additional thread""" self.alias = Alias(name) self.name = name @@ -884,4 +888,4 @@ class NumpyEncoder(json.JSONEncoder): return float(obj) elif isinstance(obj, np.ndarray): return obj.tolist() - return json.JSONEncoder.default(self, obj) \ No newline at end of file + return json.JSONEncoder.default(self, obj) diff --git a/eco/elements/assembly.py b/eco/elements/assembly.py index cf1e966..47c4dcd 100644 --- a/eco/elements/assembly.py +++ b/eco/elements/assembly.py @@ -160,8 +160,7 @@ class Assembly: self.view_toplevel_only.append(self.__dict__[name]) def get_status( - self, base="self", verbose=True, print_times=False, channeltypes=None - ): + self, base="self", verbose=True, print_times=False, channeltypes=None,print_name=False): if base == "self": base = self settings = {} @@ -177,6 +176,9 @@ class Assembly: transient=True, description="Reading settings ...", ): + + if print_name: + print(ts.name) # if (not (ts is self)) and hasattr(ts, "get_status"): # tstat = ts.get_status(base=base) # settings.update(tstat["settings"]) diff --git a/eco/elements/memory.py b/eco/elements/memory.py index 5c0900a..4bee02e 100644 --- a/eco/elements/memory.py +++ b/eco/elements/memory.py @@ -42,6 +42,10 @@ class Memory: self.dir = Path(self.base_dir) / Path("/".join(reversed(name))) try: self.dir.mkdir(exist_ok=True) + try: + self.dir.chmod(0o775) + except: + pass except: print("Could not create memory directory") self._memories = AdjustableFS( @@ -245,8 +249,7 @@ class Memory: else: return changes - def recall_from_runtable(self): - ... + def recall_from_runtable(self): ... def get_memory_difference_str( self, diff --git a/eco/endstations/bernina_robots.py b/eco/endstations/bernina_robots.py index feffe7d..7388c9a 100644 --- a/eco/endstations/bernina_robots.py +++ b/eco/endstations/bernina_robots.py @@ -99,30 +99,38 @@ class StaeubliTx200(Assembly): print("Loading bernina URDF robot model failed") ### adding JF ### if robot_config is not None: - if robot_config.jf_id() is not None: - self._append( - Jungfrau, - robot_config.jf_id(), - pgroup_adj=pgroup_adj, - config_adj=jf_config, - name=robot_config.jf_name(), - ) - if "JF01" in robot_config.jf_id(): - self.config.tool("t_JF01T03") - elif "JF07" in robot_config.jf_id(): - self.config.tool("t_JF07T32") + try: + if robot_config.jf_id() is not None: + self._append( + Jungfrau, + robot_config.jf_id(), + pgroup_adj=pgroup_adj, + config_adj=jf_config, + name=robot_config.jf_name(), + ) + if "JF01" in robot_config.jf_id(): + self.config.tool("t_JF01T03") + elif "JF07" in robot_config.jf_id(): + self.config.tool("t_JF07T32") + except Exception as e: + print("Adding of JF detector failed with:") + print(e) if robot_config is not None: - if robot_config.diffcalc(): - from ..utilities.recspace import Crystals - self.configuration=["robot", robot_config.goniometer()] - self._append( - Crystals, - diffractometer_you=self, - name="diffcalc", - is_setting=False, - is_display=False, - ) + try: + if robot_config.diffcalc(): + from ..utilities.recspace import Crystals + self.configuration=["robot", robot_config.goniometer()] + self._append( + Crystals, + diffractometer_you=self, + name="diffcalc", + is_setting=False, + is_display=False, + ) + except Exception as e: + print("Adding diffractometer for diffcalc calculation failed with:") + print(e) def _get_info(self): d= {k: v for k, v in self._cache.items() if k in self._info_fields} @@ -205,6 +213,9 @@ class StaeubliTx200(Assembly): self._set_eval_cmd(f"robot.general_motion(**{kwargs})", stopper=self.abort_record, timeout = 1200, background=False, stopper_msg="Motion aborted by user, resetting all motions.") ######## Utility functions ########## + def restart_server(self): + self.pc.eval(":restart") + def cart2sph(self, x=None, y=None, z=None, return_dict=True): vals = {k: v for k, v in zip(["x", "y", "z"], [x,y,z]) if not v is None} return self.get_eval_result(cmd=f"robot.cart2sph(**{vals})") diff --git a/eco/endstations/bernina_sample_environments.py b/eco/endstations/bernina_sample_environments.py index 2c29203..d26b368 100644 --- a/eco/endstations/bernina_sample_environments.py +++ b/eco/endstations/bernina_sample_environments.py @@ -35,6 +35,50 @@ def addSmarActRecordToSelf(self, Id=None, name=None, **kwargs): self.__dict__[name] = SmaractRecord(Id, name=name, **kwargs) self.alias.append(self.__dict__[name].alias) +class THzVirtualStages(Assembly): + def __init__(self, name=None, mz=None, pz=None): + super().__init__(name=name) + self._mz = mz + self._pz = pz + self._append( + AdjustableFS, + "/photonics/home/gac-bernina/eco/configuration/p21145_mirr_z0", + name="offset_mirr_z", + default_value=0, + is_setting=True, + ) + self._append( + AdjustableFS, + "/photonics/home/gac-bernina/eco/configuration/p21145_par_z0", + name="offset_par_z", + default_value=0, + is_setting=True, + ) + + + def get_focus_z(mz, pz): + return pz - self.offset_par_z() + + def set_focus_z(z): + mz = self.offset_mirr_z() + z + pz = self.offset_par_z() + z + return mz, pz + + self._append( + AdjustableVirtual, + [mz, pz], + get_focus_z, + set_focus_z, + name="focus_virtual", + ) + + def set_offsets_to_current_value(self): + self.offset_mirr_z.mv(self._mz()) + self.offset_par_z.mv(self._pz()) + + + + class High_field_thz_chamber(Assembly): def __init__(self, name=None, alias_namespace=None, configuration=[], illumination_mpod = None, helium_control_valve=None): super().__init__(name=name) @@ -199,6 +243,13 @@ class High_field_thz_chamber(Assembly): self.home_smaract_stages_cube = home_smaract_stages_cube self.set_stage_config_cube = set_stage_config_cube + ### Virtual stages ### + self._append( + THzVirtualStages, + name="virtual_stages", + mz=self.inc_z, + pz = self.z, + is_setting=False) if "ocb" in configuration: pass @@ -483,12 +534,15 @@ class Organic_crystal_breadboard(Assembly): "pvname": "SLAAR21-LMOT-ELL1", }, "waveplate_ir": { + "pvname": "SLAAR21-LMOT-ELL5", + }, + "eos_block": { "pvname": "SLAAR21-LMOT-ELL2", }, "crystal": { "pvname": "SLAAR21-LMOT-ELL3", }, - "waveplate_thz": { + "thz_filter": { "pvname": "SLAAR21-LMOT-ELL4", }, } diff --git a/eco/fel/swissfel.py b/eco/fel/swissfel.py index 5ed6727..f77f8f0 100644 --- a/eco/fel/swissfel.py +++ b/eco/fel/swissfel.py @@ -235,6 +235,13 @@ class MessageBoard(Assembly): is_setting=True, ) self._append(Message, "SF-OP:ESB-MSG", name="bernina_message", is_setting=True) + self._append( + AdjustablePvEnum, + "SF-OP:ESC-MSG:STATUS", + name="cristallina_status", + is_setting=True, + ) + self._append(Message, "SF-OP:ESC-MSG", name="cristallina_message", is_setting=True) self._append( AdjustablePvEnum, "SF-OP:ESE-MSG:STATUS", diff --git a/eco/loptics/bernina_laser.py b/eco/loptics/bernina_laser.py index 6daf08b..76b95f9 100644 --- a/eco/loptics/bernina_laser.py +++ b/eco/loptics/bernina_laser.py @@ -1,7 +1,7 @@ from eco.loptics.position_monitors import CameraPositionMonitor from ..elements.assembly import Assembly from functools import partial -from ..devices_general.motors import SmaractStreamdevice, MotorRecord, SmaractRecord +from ..devices_general.motors import SmaractStreamdevice, MotorRecord, SmaractRecord, ThorlabsPiezoRecord from ..elements.adjustable import AdjustableMemory, AdjustableVirtual, AdjustableFS from ..epics.adjustable import AdjustablePv, AdjustablePvEnum from ..epics.detector import DetectorPvData @@ -297,6 +297,28 @@ class LaserBernina(Assembly): self._append( MotorRecord, self.pvname + "-M534:MOT", name="wp_att", is_setting=True ) + try: + self.motor_configuration_thorlabs = { + + "waveplate_lambda_half": { + "pvname": "SLAAR21-LMOT-ELL3", + }, + "waveplate_lambda_fourth": { + "pvname": "SLAAR21-LMOT-ELL4", + }, + } + + + ### thorlabs piezo motors ### + for name, config in self.motor_configuration_thorlabs.items(): + self._append( + ThorlabsPiezoRecord, + pvname=config["pvname"], + name=name, + is_setting=True, + ) + except Exception as e: + print(e) ######## Implementation segmented ND filter wheel in rotation stage ######### diff --git a/eco/timing/timing_diag.py b/eco/timing/timing_diag.py index f91de67..ba3a08f 100644 --- a/eco/timing/timing_diag.py +++ b/eco/timing/timing_diag.py @@ -1,4 +1,5 @@ from eco.detector.detectors_psi import DetectorBsStream +from eco.epics.detector import DetectorPvDataStream from eco.devices_general.pipelines_swissfel import Pipeline from eco.devices_general.spectrometers import SpectrometerAndor from eco.microscopes.microscopes import FeturaPlusZoom @@ -13,9 +14,10 @@ import datetime from pint import UnitRegistry from time import sleep from ..xdiagnostics.profile_monitors import Target_xyz - +from eco.xdiagnostics.intensity_monitors import CalibrationRecord from .timetool_online_helper import TtProcessor - +import numpy as np +import pylab as plt # from time import sleep ureg = UnitRegistry() @@ -162,7 +164,27 @@ class TimetoolBerninaUSD(Assembly): accuracy=10, is_setting=True, ) - + self._append( + DetectorPvDataStream, + "SLAAR21-GEN:SPECTT", + name="edge_position_px", + is_setting=False, + is_display=True, + ) + self._append( + DetectorPvDataStream, + "SLAAR21-LTIM01-EVR0:CALCI", + name="edge_position_fs", + is_setting=False, + is_display=True, + ) + self._append( + CalibrationRecord, + pvbase="SLAAR21-LTIM01-EVR0:CALCI", + name="calibration", + is_setting=True, + is_display=False, + ) self._append( DetectorBsStream, "SARES20-CAMS142-M5.roi_signal_x_profile", @@ -202,6 +224,57 @@ class TimetoolBerninaUSD(Assembly): print(f"Andor spectrometer initialization failed with: \n{e}") + def get_calibration_values(self, seconds=5, scan_range=1.5e-12, plot=False): + t0 = self.delay() + x = np.linspace(t0-scan_range / 2, t0+scan_range / 2, 25) + y = [] + if plot: + plt.ion() + plt.close("tt_calib") + fig = plt.figure("tt_calib") + line = plt.plot(0,0)[0] + plt.show() + try: + for pos in x: + print(f"Moving to {pos*1e15} fs") + self.delay.set_target_value(pos).wait() + y.append(np.mean(self.edge_position_px.acquire(seconds=seconds).wait())) + if plot: + line.set_data(x[:len(y)],y) + fig.canvas.draw() + except Exception as e: + print(e) + print(f"Moving back to inital value of {t0}") + self.delay.set_target_value(t0) + + p = np.polynomial.Polynomial.fit(y,x,2).coef + if plot: + fit = plt.plot(np.polyval(p,y),y, label=p) + plt.legend() + print(f"Fit results c0 + c1*px + c2*px^2:\n{p}") + print(f"Moving back to inital value of {t0}") + self.delay.set_target_value(t0) + return p + + def set_calibration_values(self, c): + self.calibration.const_E.set_target_value(c[0]) + self.calibration.const_F.set_target_value(c[1]) + self.calibration.const_G.set_target_value(c[2]) + + def calibrate(self, seconds=5, scan_range=1.5e-12, plot=True): + t0 = self.delay() + if abs(t0) > 50e-15: + ans = "" + while not any([a in ans for a in ["y", "n"]]): + try: + ans = input(f"Timetool delay stage is at {t0*1e15} fs. Continue the calibration (y/n)?") + except: + continue + if ans == "n": + return + p = self.get_calibration_values(seconds=seconds, scan_range=scan_range, plot=plot) + self.set_calibration_values(p*1e15) + def get_online_data(self): self.online_monitor = TtProcessor() @@ -451,4 +524,4 @@ class TimetoolSpatial(Assembly): # fig = plt.figure("bsen spectrometer pattern") # fig.clf() # ax = fig.add_subplot(111) - # ax.imshow(im) \ No newline at end of file + # ax.imshow(im) diff --git a/eco/utilities/elog_scilog.py b/eco/utilities/elog_scilog.py index 136ece4..42549cf 100755 --- a/eco/utilities/elog_scilog.py +++ b/eco/utilities/elog_scilog.py @@ -34,8 +34,14 @@ def getDefaultElogInstance( if pgroup: lbs = log.get_logbooks(ownerGroup=pgroup) if len(lbs) > 1: - raise Exception(f"Found more than one elog for user group {pgroup}") - log.select_logbook(lbs[0]) + print(f"Found more than one elog for user group {pgroup}") + for lb in lbs: + creater = lb.createdBy + if creater == 'scilog-admin@psi.ch': + log.select_logbook(lb) + print(f"Choosing default logbook created by 'scilog-admin@psi.ch'") + else: + log.select_logbook(lbs[0]) return log, user diff --git a/eco/utilities/rt_bak.py b/eco/utilities/rt_bak.py index 801b26a..168bc0f 100644 --- a/eco/utilities/rt_bak.py +++ b/eco/utilities/rt_bak.py @@ -219,6 +219,10 @@ class Run_Table: f"Path {data_dir.absolute().as_posix()} does not exist, will try to create it..." ) data_dir.mkdir(parents=True) + try: + data_dir.chmod(0o775) + except: + pass print(f"Tried to create {data_dir.absolute().as_posix()}") data_dir.chmod(0o775) print(f"Tried to change permissions to 775") diff --git a/eco/utilities/runtable.py b/eco/utilities/runtable.py index 1278ef4..c1144cb 100644 --- a/eco/utilities/runtable.py +++ b/eco/utilities/runtable.py @@ -6,6 +6,7 @@ from ..elements.adjustable import AdjustableFS from ..elements.memory import Memory from subprocess import call from eco.utilities.config import Proxy + warnings.simplefilter(action="ignore", category=pd.errors.PerformanceWarning) warnings.simplefilter(action="ignore", category=UserWarning) import timeit @@ -76,7 +77,7 @@ class Gsheet_API: def _append_to_gspread_key_df(self, gspread_key_df): if os.path.exists(self._keydf_fname): self._key_df = pd.read_pickle(self._keydf_fname) - #deprecated: self._key_df = self._key_df.append(gspread_key_df) + # deprecated: self._key_df = self._key_df.append(gspread_key_df) self._key_df = pd.concat([self._key_df, gspread_key_df]) self._key_df.to_pickle(self._keydf_fname) else: @@ -191,7 +192,8 @@ class Container: def _create_lazy_container(self, n): def cr(): - return Container(df = self._df, name=self._top_level_name + n + ".") + return Container(df=self._df, name=self._top_level_name + n + ".") + return cr def _create_first_level_container(self, names, lazy=True): @@ -199,7 +201,9 @@ class Container: if lazy: self.__dict__[n] = Proxy(self._create_lazy_container(n)) else: - self.__dict__[n] = Container(self._df, name=self._top_level_name + n + ".") + self.__dict__[n] = Container( + self._df, name=self._top_level_name + n + "." + ) def to_dataframe(self, full_name=True, next_level=False): df = self._slice_df() @@ -244,7 +248,6 @@ class Container: src = src.append(sr) return src - def __dir__(self): next_level_names = self._get_next_level_names() to_create = np.array( @@ -330,6 +333,7 @@ class Run_Table2: def to_dataframe(self): return DataFrame(self._data) + ###### diagnostic and convencience functions ###### def run_table_from_other_pgroup(self, pgroup): @@ -339,10 +343,14 @@ class Run_Table2: usage: run_table_pxxx = run_table.run_table_from_other_pgroup('pxxx') """ - return Run_Table2(data=f'/sf/bernina/data/{pgroup}/res/run_table/{pgroup}_runtable.pkl') + return Run_Table2( + data=f"/sf/bernina/data/{pgroup}/res/run_table/{pgroup}_runtable.pkl" + ) def check_timeouts(self, include_bad_adjustables=True, plot=True, repeats=1): - return self._data.check_timeouts(include_bad_adjustables=include_bad_adjustables, plot=plot, repeats=repeats) + return self._data.check_timeouts( + include_bad_adjustables=include_bad_adjustables, plot=plot, repeats=repeats + ) def _reduce_df( self, @@ -374,10 +382,11 @@ class Run_Table2: def _create_lazy_container(self, dev): def cr(): return Container(df=self._data, name=dev + ".") + return cr def __dir__(self): - lazy=True + lazy = True devs = np.unique(np.array([n.split(".")[0] for n in self._data.columns])) for dev in devs: if dev not in self.__dict__.keys(): @@ -404,7 +413,9 @@ class Run_Table2: return self.__str__() def check_timeouts(self, include_bad_adjustables=True, plot=True, repeats=1): - return self._data.check_timeouts(include_bad_adjustables=include_bad_adjustables, plot=plot, repeats=repeats) + return self._data.check_timeouts( + include_bad_adjustables=include_bad_adjustables, plot=plot, repeats=repeats + ) class Run_Table_DataFrame(DataFrame): @@ -484,17 +495,17 @@ class Run_Table_DataFrame(DataFrame): if os.path.exists(self.fname): self.df = pd.read_pickle(self.fname) - def _append_run( - self, - runno, - wait=True, - *args, - **kwargs - ): + def _append_run(self, runno, wait=True, *args, **kwargs): if wait: self._append_run(runno, *args, **kwargs) else: - ar = threading.Thread(target=self.append_run, args=[runno,], kwargs=kwargs) + ar = threading.Thread( + target=self.append_run, + args=[ + runno, + ], + kwargs=kwargs, + ) ar.start() def append_run( @@ -520,13 +531,15 @@ class Run_Table_DataFrame(DataFrame): multiindex = pd.MultiIndex.from_tuples( [(dev, adj) for dev in dat.keys() for adj in dat[dev].keys()], names=names ) - values = np.array([val for adjs in dat.values() for val in adjs.values()], dtype=object) + values = np.array( + [val for adjs in dat.values() for val in adjs.values()], dtype=object + ) index = np.array( [f"{dev}.{adj}" for dev, adjs in dat.items() for adj in adjs.keys()] ) # run_df = DataFrame([values], columns=multiindex, index=[runno]) run_df = DataFrame([values], columns=index, index=[runno]) - #deprecated: self.df = self.append(run_df) + # deprecated: self.df = self.append(run_df) self.df = pd.concat([self.df, run_df]) self._remove_duplicates() @@ -549,15 +562,17 @@ class Run_Table_DataFrame(DataFrame): multiindex = pd.MultiIndex.from_tuples( [(dev, adj) for dev in dat.keys() for adj in dat[dev].keys()], names=names ) - values = np.array([val for adjs in dat.values() for val in adjs.values()], dtype=object) + values = np.array( + [val for adjs in dat.values() for val in adjs.values()], dtype=object + ) index = np.array( [f"{dev}.{adj}" for dev, adjs in dat.items() for adj in adjs.keys()] ) # pos_df = DataFrame([values], columns=multiindex, index=[f"p{posno}"]) pos_df = DataFrame([values], columns=index, index=[f"p{posno}"]) - #deprecated: self.df = self.append(pos_df) - self.df = pd.concat([self.df,pos_df]) + # deprecated: self.df = self.append(pos_df) + self.df = pd.concat([self.df, pos_df]) self._remove_duplicates() # self.order_df() self.save() @@ -572,9 +587,9 @@ class Run_Table_DataFrame(DataFrame): dat[devname] = {} bad_adjs = [] for adjname, adj in dev.items(): - if f'{devname}.{adjname}' in d.keys(): - dat[devname][adjname] = d[f'{devname}.{adjname}'] - print(f'{devname}.{adjname}') + if f"{devname}.{adjname}" in d.keys(): + dat[devname][adjname] = d[f"{devname}.{adjname}"] + print(f"{devname}.{adjname}") continue try: dat[devname][adjname] = adj.get_current_value() @@ -592,7 +607,12 @@ class Run_Table_DataFrame(DataFrame): else: dat = { devname: { - adjname: d[f'{devname}.{adjname}'] if f'{devname}.{adjname}' in d.keys() else adj.get_current_value() for adjname, adj in dev.items() + adjname: ( + d[f"{devname}.{adjname}"] + if f"{devname}.{adjname}" in d.keys() + else adj.get_current_value() + ) + for adjname, adj in dev.items() } for devname, dev in self.good_adjustables.items() } @@ -649,8 +669,8 @@ class Run_Table_DataFrame(DataFrame): if parent_name == device.name: self.adjustables[parent_name][key] = value else: - #print("GET ADJ", parent_name, name, key) - + # print("GET ADJ", parent_name, name, key) + self.adjustables[parent_name][".".join([name, key])] = value if parent_name == device.name: @@ -662,14 +682,15 @@ class Run_Table_DataFrame(DataFrame): ): if parent_name is None: parent_name = own_name - self._get_all_adjustables_fewerparents(parent_class, adj_prefix, parent_name, verbose=verbose) + self._get_all_adjustables_fewerparents( + parent_class, adj_prefix, parent_name, verbose=verbose + ) if parent_name is not parent_class.name: if adj_prefix is not None: adj_prefix = ".".join([adj_prefix, parent_class.name]) else: adj_prefix = parent_class.name - sub_classes = [] sub_classnames = [] for key in parent_class.__dict__.keys(): @@ -688,10 +709,14 @@ class Run_Table_DataFrame(DataFrame): for s in self._parse_exclude_class_types ] ), - ] ): - if adj_prefix is None or ~np.any([key == s for s in ".".join([parent_name,adj_prefix]).split(".")]): + if adj_prefix is None or ~np.any( + [ + key == s + for s in ".".join([parent_name, adj_prefix]).split(".") + ] + ): if s_class.name == None: s_class.name = key sub_classes.append(s_class) @@ -850,49 +875,68 @@ class Run_Table_DataFrame(DataFrame): devs = [item[0] for item in list(self.columns)] self.df = self[self._orderlist(list(self.columns), key_order, orderlist=devs)] - #### diagnostic and convenience functions #### - def check_timeouts(self, include_bad_adjustables=True, repeats=1, plot=True, verbose=True): + def check_timeouts( + self, include_bad_adjustables=True, repeats=1, plot=True, verbose=True + ): if len(self.adjustables) == 0: self._parse_parent_fewerparents(verbose=verbose) ts = [] - devs=[] + devs = [] + def get_dev_adjs(dev): for k, adj in dev.items(): val = adj.get_current_value() + for k, dev in self.good_adjustables.items(): + def func(dev=dev): return get_dev_adjs(dev) + t = timeit.timeit(func, number=repeats) ts.append(float(t)) devs.append(k) print(k, t) idx = np.argsort(ts) self.times = [np.array(devs)[idx], np.array(ts)[idx]] - print('recorded adjustable results stored in run_table._data.times') + print("recorded adjustable results stored in run_table._data.times") if include_bad_adjustables: for k, dev in self.bad_adjustables.items(): + def func(dev=dev): return get_dev_adjs(dev) + t = timeit.timeit(func, number=repeats) ts.append(float(t)) devs.append(k) print(k, t) idx = np.argsort(ts) - print('rejected timed out adjustable results stored in run_table._data.times_rejected') + print( + "rejected timed out adjustable results stored in run_table._data.times_rejected" + ) self.times_rejected = [np.array(devs)[idx], np.array(ts)[idx]] if plot: import pylab as plt + fig, ax = plt.subplots(1) if include_bad_adjustables: - plt.barh(self.times_rejected[0], self.times_rejected[1], color='red', label='rejected adjustables') - plt.barh(self.times[0], self.times[1], label='recorded adjustables', color='seagreen') - plt.xlabel('time (s)') + plt.barh( + self.times_rejected[0], + self.times_rejected[1], + color="red", + label="rejected adjustables", + ) + plt.barh( + self.times[0], + self.times[1], + label="recorded adjustables", + color="seagreen", + ) + plt.xlabel("time (s)") plt.legend() - def name2obj(obj_parent, name, delimiter="."): if type(name) is str: name = name.split(delimiter) diff --git a/eco/xoptics/att_usd.py b/eco/xoptics/att_usd.py index 660da9b..21132e2 100644 --- a/eco/xoptics/att_usd.py +++ b/eco/xoptics/att_usd.py @@ -235,13 +235,14 @@ class Att_usd(Assembly): sleep(0.5) mot.calibrate_sensor(1) - def home_smaract_stages(self, stages=None): - if stages == None: - stages = self.motor_configuration.keys() + def home_smaract_stages(self, motor_configuration=None): + if motor_configuration == None: + motor_configuration= self.motor_configuration + stages = motor_configuration.keys() print("#### Positions before homing ####") print(self.__repr__()) for name in stages: - config = self.motor_configuration[name] + config = motor_configuration[name] mot = self.__dict__[name] print( "#### Homing {} in {} direction ####".format( @@ -250,25 +251,27 @@ class Att_usd(Assembly): ) sleep(1) if config["home_direction"] == "back": - mot.home_backward(1) - while mot.status_channel().value == 7: + mot.home_reverse(1) + sleep(.5) + while not mot.flags.motion_complete(): sleep(1) - if mot.is_homed() == 0: + if not mot.flags.is_homed(): print( "Homing failed, try homing {} in forward direction".format(name) ) mot.home_forward(1) elif config["home_direction"] == "forward": mot.home_forward(1) - while mot.status_channel().value == 7: + sleep(.5) + while not mot.flags.motion_complete(): sleep(1) - if mot.is_homed() == 0: + if not mot.flags.is_homed(): print( "Homing failed, try homing {} in backward direction".format( name ) ) - mot.home_backward(1) + mot.home_reverse(1) def get_adjustable_positions_str(self): ostr = "*****att_usd target position******\n" diff --git a/image.jpg b/image.jpg deleted file mode 100644 index c98a906..0000000 Binary files a/image.jpg and /dev/null differ diff --git a/image.jpg.1 b/image.jpg.1 deleted file mode 100644 index 515a834..0000000 Binary files a/image.jpg.1 and /dev/null differ diff --git a/image.jpg.2 b/image.jpg.2 deleted file mode 100644 index 20127bb..0000000 Binary files a/image.jpg.2 and /dev/null differ diff --git a/image.jpg.3 b/image.jpg.3 deleted file mode 100644 index a8d916d..0000000 Binary files a/image.jpg.3 and /dev/null differ