From fc347ea9475748f4804f04eaefec71a49531423e Mon Sep 17 00:00:00 2001 From: jmcchesn <jmcchesn@aps.anl.gov> Date: Mon, 10 Oct 2022 12:39:06 -0500 Subject: [PATCH] sotw and debugging --- iexcode/instruments/ARPES.py | 50 ++- iexcode/instruments/IEX_BL_config.py | 112 ++++-- iexcode/instruments/Kappa.py | 48 +-- iexcode/instruments/Logfile.py | 9 + iexcode/instruments/Octupole.py | 41 +-- iexcode/instruments/bakeout.py | 2 +- iexcode/instruments/scanRecord.py | 85 ++++- iexcode/instruments/utilities.py | 19 + iexcode/macros/commissioning.py | 309 ++++++++++++---- iexcode/macros/start_of_the_week.py | 529 +++++++++------------------ iexcode/staff_cheatsheet.md | 109 +++--- 11 files changed, 734 insertions(+), 579 deletions(-) diff --git a/iexcode/instruments/ARPES.py b/iexcode/instruments/ARPES.py index 5cbb65a..e211556 100644 --- a/iexcode/instruments/ARPES.py +++ b/iexcode/instruments/ARPES.py @@ -6,12 +6,12 @@ import numpy as np from epics import caget,caput import iexcode.instruments.cfg as iex -from iexcode.instruments.IEX_BL_config import Beamline_Config +from iexcode.instruments.IEX_BL_config import * from iexcode.instruments.IEX_cameras import _enable_endstation_cameras from iexcode.instruments.scanRecord import * from iexcode.instruments.files_and_folders import check_run,make_user_folders,folder_mda,path_dserv -from iexcode.instruments.Logfile import Logfile, log_name_set +from iexcode.instruments.Logfile import Logfile, log_init, log_name_set from iexcode.instruments.staff import staff_detector_dictionary from iexcode.instruments.xrays import xrays_detector_dictionary, _xrays_reset, xrays_get_all, xrays_log_dictionary @@ -64,12 +64,12 @@ def ARPES_init(*userName,**kwargs): #endstation iex.BL = Beamline_Config('ARPES',kwargs['scan_ioc'],kwargs['xrays'],kwargs['mode'],ARPES_Motors) - iex.BL.safe_state = ARPES_safe_state - iex.BL.endstation_get = ARPES_get_all + BLconfig_safe_state_set(ARPES_safe_state) + BLconfig_get_set(ARPES_get_all) #setting folders if kwargs['set_folders']: - if iex.BL.mode == 'staff': + if BLconfig_mode() == 'staff': user_name = 'Staff' else: if len(userName)==0: @@ -83,7 +83,7 @@ def ARPES_init(*userName,**kwargs): user_name = mda_user_name() #logging - iex.BL.mda.log=Logfile('ARPES',user_name,_ARPES_log_dictionary,set_file=False) + log_init('ARPES',user_name,_ARPES_log_dictionary,set_file=False) if kwargs['set_folders']: log_name_set() @@ -152,7 +152,7 @@ def _ARPES_detector_dictionary(): det_dict.update({17:EA._statsPlugin+"Total_RBV"}) #add detectors related to beamline - if iex.BL.xrays: + if BLconfig_xrays(): det_dict.update(xrays_detector_dictionary()) return det_dict @@ -217,19 +217,19 @@ def folders_ARPES(user_name,**kwargs): run = kwargs['run'] if kwargs['debug']: - print("run,folder,user_name,ioc,ftp: ",run,iex.BL.folder,user_name,kwargs['scan_ioc'],kwargs['ftp']) + print("run,folder,user_name,ioc,ftp: ",run,BLconfig_folder(),user_name,kwargs['scan_ioc'],kwargs['ftp']) # Create User Folder: - make_user_folders(run,iex.BL.folder,user_name,iex.BL.endstation_name,ftp=kwargs['ftp']) + make_user_folders(run,BLconfig_folder(),user_name,BLconfig_endstation_name(),ftp=kwargs['ftp']) sleep(5) if kwargs["set_folders"]: # Set up MDA folder: - folder_mda(run,iex.BL.folder,user_name,mda_prefix(),mda_ioc()) + folder_mda(run,BLconfig_folder(),user_name,mda_prefix(),mda_ioc()) #Set up Scienta folders: if EA.connected: - userPath = path_dserv(iex.BL.folder,run,user_name) + userPath = path_dserv(BLconfig_folder(),run,user_name) try: folders_EA(userPath,filePrefix="EA") except: @@ -242,16 +242,14 @@ def ARPES_default_scan_settings(): default setting for scan record Note: only get set if ARPES_reset is run """ - #writing default parameters to iex.BL.mda - - iex.BL.mda.detector_dictionary = _ARPES_detector_dictionary() - if iex.BL.mode=='staff': - iex.BL.mda.detector_dictionary.update(staff_detector_dictionary()) - - iex.BL.mda.trigger_dictionary = _ARPES_trigger_dictionary() - iex.BL.mda.before_scan_pv = _ARPES_scan_before_sequence() - iex.BL.mda.after_scan_pv = _ARPES_scan_after_sequence() - iex.BL.mda.snake_set = ARPES_snake_set #sending the function, no parenthesis + #writing default parameters to iex.BL.mda + mda_default_detector_dictionary(_ARPES_detector_dictionary()) + if BLconfig_mode() == 'staff': + mda_default_detector_dictionary(staff_detector_dictionary(),overwrite=False) + mda_default_trigger_dictionary(_ARPES_trigger_dictionary()) + mda_before_scan_pv(_ARPES_scan_before_sequence()) + mda_after_scan_pv(_ARPES_scan_after_sequence()) + mda_snake_set(ARPES_snake_set) #sending the function, no parenthesis def ARPES_reset(): @@ -264,13 +262,13 @@ def ARPES_reset(): #resetting the current amplifiers print("resetting the current amplifiers") - if iex.BL.xrays: + if BLconfig_xrays(): ca_reset_all() else: tey.reset() #resetting mono and other beamline stuff - if iex.BL.xrays: + if BLconfig_xrays(): _xrays_reset() #reseting the ARPES Lakeshore @@ -305,14 +303,14 @@ def ARPES_get_all(verbose=True): extra_pvs = ARPES_extra_pvs() for key in extra_pvs.keys(): vals.update(key,caget(extra_pvs[key])) - if iex.BL.xrays: + if BLconfig_xrays(): vals.update('exit_slit',slit3C_get()) if verbose: for key in vals: print(key+" = "+vals[key]) #beamline info - if iex.BL.xray: + if BLconfig_xrays(): beamline_info = xrays_get_all() vals.update(beamline_info) if verbose: @@ -351,7 +349,7 @@ def _ARPES_log_dictionary(): "tey2":(caget(ARPES_extra_pvs()['tey2']),"1.2e") } - if iex.BL.xrays == True: + if BLconfig_xrays() == True: d.update(xrays_log_dictionary()) return d diff --git a/iexcode/instruments/IEX_BL_config.py b/iexcode/instruments/IEX_BL_config.py index 8747f27..7a6b8b9 100644 --- a/iexcode/instruments/IEX_BL_config.py +++ b/iexcode/instruments/IEX_BL_config.py @@ -12,8 +12,91 @@ this will prompt for the endstation and will set the default parameters, look at init kwargs to see which defaults you can change. """ +def BLconfig_endstation_name(endstation_name=None): + """ + returns iex.BL.endstation_name ('ARPES','kappa','Octupole') if endstation_name = None, otherwise sets to new value + """ + if endstation_name == None: + endstation_name = iex.BL.endstation_name + else: + iex.BL.endstation_name = endstation_name + return endstation_name + +def BLconfig_folder(folder=None): + """ + returns iex.BL.folder ('b','c','d','e') if folder = None, otherwise sets to new value + """ + if folder == None: + folder = iex.BL.folder + else: + iex.BL.folder = folder + return folder + +def BLconfig_branch(branch=None): + """ + returns iex.BL.branch if branch is None, otherwise set to the new values + """ + if branch == None: + branch = iex.BL.branch + else: + iex.BL.branch = branch + return branch + +def BLconfig_xrays(xrays=None): + """ + returns iex.BL.xrays (True/False) if xrays = None, otherwise sets to new value + """ + if xrays == None: + xrays = iex.BL.xrays + else: + iex.BL.xrays = xrays + return xrays + +def BLconfig_mode(BL_mode=None): + """ + returns iex.BL.mode ('user'/'staff') if BL_mode = None, otherwise sets to new value + """ + if BL_mode == None: + BL_mode = iex.BL.mode + else: + iex.BL.mode = BL_mode + + return BL_mode + +def BLconfig_get_set(endstation_get): + """ + sets the BL config endstation_get + """ + iex.BL.endstation_get = endstation_get + +def BLconfig_safe_state_set(endstation_safe_state): + """ + sets the BL config safe state + """ + iex.BL.safe_state = endstation_safe_state + + +############################################################################################################## +def get_all(verbose=True): + """ + returns the current beamline and endstation setting + + """ + vals={} + vals.update(iex.BL.endstation_get(verbose)) + + return vals + + +############################################################################################################## +############################################################################################################## + #For new endstation modify here: -endstations_list = ['ARPES','kappa','Octupole'] +endstations_list = ['ARPES','kappa','Octupole'] + +############################################################################################################## +############################################################################################################## + class Beamline_Config: def __init__(self,endstation_name,scan_ioc,xrays,mode='user',Motors=None,**kwargs): """ @@ -94,30 +177,3 @@ class Beamline_Config: if 'endstation_get' in kwargs: self.endstation_get = kwargs['endstation_get'] - - -############################################################################################################## -############################## BL commands ############################## -############################################################################################################## -def BL_branch(): - """ - returns the branch from the Endstation instance - """ - return iex.BL.branch - -def BL_mode(): - """ - returns the beamline mode, User / Staff / No_Xray - """ - return iex.BL.mode - -############################################################################################################## -def get_all(verbose=True): - """ - returns the current beamline and endstation setting - - """ - vals={} - vals.update(iex.BL.endstation_get(verbose)) - - return vals diff --git a/iexcode/instruments/Kappa.py b/iexcode/instruments/Kappa.py index 3c2490b..667b5ec 100644 --- a/iexcode/instruments/Kappa.py +++ b/iexcode/instruments/Kappa.py @@ -6,12 +6,12 @@ from math import floor from epics import caget, caput,PV import iexcode.instruments.cfg as iex -from iexcode.instruments.IEX_BL_config import Beamline_Config +from iexcode.instruments.IEX_BL_config import * from iexcode.instruments.IEX_cameras import _enable_endstation_cameras from iexcode.instruments.scanRecord import * from iexcode.instruments.files_and_folders import check_run,make_user_folders,folder_mda,path_dserv -from iexcode.instruments.Logfile import Logfile,log_name_set +from iexcode.instruments.Logfile import log_init,log_name_set from iexcode.instruments.staff import staff_detector_dictionary from iexcode.instruments.xrays import xrays_detector_dictionary, _xrays_reset, xrays_get_all @@ -71,12 +71,12 @@ def kappa_init(*userName,**kwargs): #endstation iex.BL = Beamline_Config('kappa',kwargs['scan_ioc'],kwargs['xrays'],kwargs['mode'],kappa_Motors) - iex.BL.safe_state = kappa_safe_state - iex.BL.endstation_get = kappa_get_all + BLconfig_safe_state_set(kappa_safe_state) + BLconfig_get_set(kappa_get_all) #setting folders if kwargs['set_folders']: - if iex.BL.mode == 'staff': + if BLconfig_mode() == 'staff': user_name = 'Staff' else: if len(userName)==0: @@ -91,12 +91,13 @@ def kappa_init(*userName,**kwargs): print('user_name:',user_name) #logging - iex.BL.mda.log=Logfile('kappa',user_name,_kappa_log_dictionary,set_file=False) + log_init('kappa',user_name,_kappa_log_dictionary,set_file=False) if kwargs['set_folders']: log_name_set() #MPA iex.mpa = MPA() + global mpa = iex.mpa global tth_pv,tthdet tthdet = Kappa_Detector(kappa_Motors) tth_pv = _kappa_motor_dictionary('tth')[3] @@ -210,7 +211,7 @@ def _kappa_detector_dictionary(**kwargs): det_dict.update(vortex) #add detectors related to beamline - if iex.BL.xrays: + if BLconfig_xrays(): det_dict.update(xrays_detector_dictionary()) return det_dict @@ -293,21 +294,21 @@ def folders_kappa(user_name,**kwargs): run = kwargs['run'] if kwargs['debug']: - print("run,folder,user_name,ioc,ftp: ",run,iex.BL.folder,user_name,mda_ioc(),kwargs['ftp']) + print("run,folder,user_name,ioc,ftp: ",run,BLconfig_folder(),user_name,mda_ioc(),kwargs['ftp']) # Create User Folder: - make_user_folders(run,iex.BL.folder,user_name,iex.BL.endstation,ftp=kwargs['ftp']) + make_user_folders(run,BLconfig_folder(),user_name,BLconfig_endstation_name(),ftp=kwargs['ftp']) sleep(5) if kwargs["set_folders"]: # Set up MDA folder: - folder_mda(run,iex.BL.folder,user_name,mda_prefix(),mda_ioc()) + folder_mda(run,BLconfig_folder(),user_name,mda_prefix(),mda_ioc()) # Set up SPEC folder: - folders_spec(run,iex.BL.folder,user_name) + folders_spec(run,BLconfig_folder(),user_name) # Set up MPA folder: - #Folder_MPA(run,iex.BL.folder,user_name) + #Folder_MPA(run,BLconfig_folder(),user_name) #resetting if 'reset': @@ -319,14 +320,13 @@ def kappa_default_scan_settings(**kwargs): Note: only get set if ARPES_reset is run """ #writing default parameters to iex.BL.mda - iex.BL.mda.detector_dictionary = _kappa_detector_dictionary(**kwargs) - if iex.BL.mode=='staff': - iex.BL.mda.detector_dictionary.update(staff_detector_dictionary()) - - iex.BL.mda.trigger_dictionary = _kappa_trigger_dictionary() - iex.BL.mda.scan_before_sequence = _kappa_scan_before_sequence() - iex.BL.mda.scan_after_sequence = _kappa_scan_after_sequence() - iex.BL.mda.snake_set = kappa_snake_set #sending the function, no parenthesis + mda_default_detector_dictionary(_kappa_detector_dictionary(**kwargs)) + if BLconfig_mode()=='staff': + mda_default_detector_dictionary(staff_detector_dictionary(),overwrite=False) + mda_default_trigger_dictionary(_kappa_trigger_dictionary()) + mda_before_scan_pv(_kappa_scan_before_sequence()) + mda_after_scan_pv(_kappa_scan_after_sequence() ) + mda_snake_set(kappa_snake_set) #sending the function, no parenthesis def kappa_reset(**kwargs): @@ -347,7 +347,7 @@ def kappa_reset(**kwargs): MPA.mpa_ROI_reset() #resetting mono and other beamline stuff - if iex.BL.xrays: + if BLconfig_xrays(): ca_reset_all() _xrays_reset() @@ -377,13 +377,13 @@ def kappa_get_all(verbose=True): extra_pvs = kappa_extra_pvs() for key in extra_pvs.keys(): vals.update(key,caget(extra_pvs[key])) - if iex.BL.xrays: + if BLconfig_xrays(): vals.update('exit_slit',slit3D_get()) mesh.get() vals.update({'mesh':mesh.current_Amp}) #beamline info - if iex.BL.xray: + if BLconfig_xrays(): beamline_info = xrays_get_all() vals.update(beamline_info) @@ -957,7 +957,7 @@ def kappa_safe_state(**kwargs): if kwargs["mpa_off"]: try: - iex.mpa.HV_off() + mpa.HV_off() except: print('MPA is not running') diff --git a/iexcode/instruments/Logfile.py b/iexcode/instruments/Logfile.py index 509afc2..b180cba 100644 --- a/iexcode/instruments/Logfile.py +++ b/iexcode/instruments/Logfile.py @@ -33,12 +33,21 @@ def log_update(d=None,**kwargs): print('No logfile written') def log_name_set(file_name): + """ + change the name of the log file + """ try: iex.BL.mda.log.name_set(filename=file_name) iex.BL.mda.filename = file_name except: print('No logfile name change') +def log_init(endstation_name,user_name,log_dictionary,set_file=False): + """ + initialize the logfile + """ + iex.BL.mda.log=Logfile(endstation_name,user_name,log_dictionary,set_file=False) + ############################################################################################################## ############################## general logfile functions ############################## ############################################################################################################## diff --git a/iexcode/instruments/Octupole.py b/iexcode/instruments/Octupole.py index 11f4748..54912d1 100644 --- a/iexcode/instruments/Octupole.py +++ b/iexcode/instruments/Octupole.py @@ -5,12 +5,12 @@ from math import floor from epics import caget, caput,PV import iexcode.instruments.cfg as iex -from iexcode.instruments.IEX_BL_config import Beamline_Config +from iexcode.instruments.IEX_BL_config import * from iexcode.instruments.IEX_cameras import _enable_endstation_cameras from iexcode.instruments.scanRecord import * from iexcode.instruments.files_and_folders import check_run,make_user_folders,folder_mda,path_dserv -from iexcode.instruments.Logfile import Logfile,log_name_set +from iexcode.instruments.Logfile import Logfile, log_init,log_name_set from iexcode.instruments.staff import staff_detector_dictionary from iexcode.instruments.xrays import xrays_detector_dictionary, _xrays_reset, xrays_get_all @@ -66,12 +66,12 @@ def Octupole_init(*userName,**kwargs): #endstation iex.BL = Beamline_Config('Octupole',kwargs['scan_ioc'],kwargs['xrays'],kwargs['mode'],Octupole_Motors) - iex.BL.safe_state = Octupole_safe_state - iex.BL.endstation_get = Octupole_get_all + BLconfig_safe_state_set(Octupole_safe_state) + BLconfig_get_set(Octupole_get_all) #setting folders if kwargs['set_folders']: - if iex.BL.mode == 'staff': + if BLconfig_mode() == 'staff': user_name = 'Staff' else: if len(userName)==0: @@ -86,7 +86,7 @@ def Octupole_init(*userName,**kwargs): print('user_name:',user_name) #logging - iex.BL.mda.log=Logfile('Octupole',user_name,_Octupole_log_dictionary) + log_init('Octupole',user_name,_Octupole_log_dictionary) if kwargs['set_folders']: log_name_set() @@ -199,7 +199,7 @@ def _Octupole_detector_dictionary(**kwargs): det_dict.update(vortex) #add detectors related to beamline - if iex.BL.xrays: + if BLconfig_xrays(): det_dict.update(xrays_detector_dictionary()) return det_dict @@ -263,15 +263,15 @@ def folders_Octupole(user_name,**kwargs): run = kwargs['run'] if kwargs['debug']: - print("run,folder,user_name,ioc,ftp: ",run,iex.BL.folder,user_name,mda_ioc(),kwargs['ftp']) + print("run,folder,user_name,ioc,ftp: ",run,BLconfig_folder(),user_name,mda_ioc(),kwargs['ftp']) # Create User Folder: - make_user_folders(run,iex.BL.folder,user_name,iex.BL.endstation_name,ftp=kwargs['ftp']) + make_user_folders(run,BLconfig_folder(),user_name,BLconfig_endstation_name(),ftp=kwargs['ftp']) sleep(5) if kwargs["set_folders"]: # Set up MDA folder: - folder_mda(run,iex.BL.folder,user_name,mda_prefix(),mda_ioc()) + folder_mda(run,BLconfig_folder(),user_name,mda_prefix(),mda_ioc()) #resetting if 'reset': @@ -283,14 +283,13 @@ def Octupole_default_scan_settings(**kwargs): Note: only get set if ARPES_reset is run """ #writing default parameters to iex.BL.mda - iex.BL.mda.detector_dictionary = _Octupole_detector_dictionary(**kwargs) - if iex.BL.mode=='staff': - iex.BL.mda.detector_dictionary.update(staff_detector_dictionary()) - - iex.BL.mda.trigger_dictionary = _Octupole_trigger_dictionary() - iex.BL.mda.scan_before_sequence = _Octupole_scan_before_sequence() - iex.BL.mda.scan_after_sequence = _Octupole_scan_after_sequence() - iex.BL.mda.snake_set = Octupole_snake_set #sending the function, no parenthesis + mda_default_detector_dictionary(_Octupole_detector_dictionary(**kwargs)) + if BLconfig_mode()=='staff': + mda_default_detector_dictionary(staff_detector_dictionary(),overwrite=False) + mda_default_trigger_dictionary(_Octupole_trigger_dictionary()) + mda_before_scan_pv(_Octupole_scan_before_sequence()) + mda_after_scan_pv(_Octupole_scan_after_sequence()) + mda_snake_set(Octupole_snake_set) #sending the function, no parenthesis def Octupole_reset(**kwargs): @@ -302,7 +301,7 @@ def Octupole_reset(**kwargs): mda_reset() #resetting mono and anyother beamline stuff - if iex.BL.xrays: + if BLconfig_xrays(): ca_reset_all() _xrays_reset() @@ -327,13 +326,13 @@ def Octupole_get_all(verbose=True): extra_pvs = Octupole_extra_pvs() for key in extra_pvs.keys(): vals.update(key,caget(extra_pvs[key])) - if iex.BL.xrays: + if BLconfig_xrays(): vals.update('exit_slit',slit3D_get()) mesh.get() vals.update({'mesh':mesh.current}) #beamline info - if iex.BL.xray: + if BLconfig_xrays(): beamline_info = xrays_get_all() vals.update(beamline_info) diff --git a/iexcode/instruments/bakeout.py b/iexcode/instruments/bakeout.py index f232c19..44864ef 100644 --- a/iexcode/instruments/bakeout.py +++ b/iexcode/instruments/bakeout.py @@ -63,7 +63,7 @@ def bakout_scan(scan_ioc_name,chamber): mda_scan = ScanRecord(scan_ioc,detector_dictionary,trigger_dictionary,before_scan_pv,after_scan_pv) - mda_scan.time_scan(99999,60) + mda_scan.scan_time(99999,60) diff --git a/iexcode/instruments/scanRecord.py b/iexcode/instruments/scanRecord.py index 1a7cf1e..2853853 100644 --- a/iexcode/instruments/scanRecord.py +++ b/iexcode/instruments/scanRecord.py @@ -56,6 +56,28 @@ def scan_triggers_clear(**kwargs): def scan_detectors_set(**kwargs): iex.BL.mda.detectors_set(**kwargs) +def scan_empty(npts=1,**kwargs): + """ + starts a scan with out a drive + npts = number of points + + **kwargs: + execute = True/False (default=True) + see scanRecord.fillin for more options + """ + iex.BL.mda.scan_empty(npts=1,**kwargs) + +def scan_time(duration_min,step_min=1,**kwargs): + """ + starts a scan with the readback as time in seconds + duration: total time for the scan in minutes + step_min: steps per minute (sets the detector setting time for this) + + **kwargs + execute True/False (default = True) + trigger_dictionary = {1:'29idb:ca5:read'} + """ + iex.BL.mda.scan_time(duration_min,step_min=step_min,**kwargs) def scan_go(**kwargs): """ @@ -124,6 +146,62 @@ def mda_reset(): """ iex.BL.mda.reset_all() +def mda_default_detector_dictionary(detector_dictionary=None,overwrite=False): + """ + returns iex.BL.detector_dictionary if None, otherwise sets to new value + """ + if detector_dictionary == None: + detector_dictionary = iex.BL.detector_dictionary + else: + if overwrite == False: + iex.BL.mda.detector_dictionary = detector_dictionary + else: + iex.BL.mda.detector_dictionary.update(detector_dictionary) + return detector_dictionary + +def mda_default_trigger_dictionary(trigger_dictionary=None,overwrite=False): + """ + returns iex.BL.trigger_dictionary if None, otherwise sets to new value + """ + if trigger_dictionary == None: + trigger_dictionary = iex.BL.trigger_dictionary + else: + if overwrite == False: + iex.BL.mda.trigger_dictionary = trigger_dictionary + else: + iex.BL.mda.trigger_dictionary.update(trigger_dictionary) + return trigger_dictionary + +def mda_before_scan_pv(before_scan_pv=None): + """ + returns iex.BL.before_scan_pv if None, otherwise sets to new value + """ + if before_scan_pv == None: + before_scan_pv = iex.BL.before_scan_pv + else: + iex.BL.mda.before_scan_pv = before_scan_pv + return before_scan_pv + +def mda_after_scan_pv(after_scan_pv=None): + """ + returns iex.BL.after_scan_pv if None, otherwise sets to new value + """ + if after_scan_pv == None: + after_scan_pv = iex.BL.after_scan_pv + else: + iex.BL.mda.after_scan_pv = after_scan_pv + return after_scan_pv + +def mda_snake_set(snake_set=None): + """ + returns iex.BL.snake_set if None, otherwise sets to new value + """ + if snake_set == None: + snake_set = iex.BL.snake_set + else: + iex.BL.mda.snake_set = snake_set + return snake_set + def saveData_get_all(ioc_pv): """ @@ -929,9 +1007,7 @@ class ScanRecord: ############################################################################################################## ############################# empty and time scans ############################## ############################################################################################################## - - - def empty_scan(self,npts=1,**kwargs): + def scan_empty(self,npts=1,**kwargs): """ starts a scan with out a drive npts = number of points @@ -950,7 +1026,7 @@ class ScanRecord: if kwargs['execute']: self.go(**kwargs) - def time_scan(self,duration_min,step_min=1,**kwargs): + def scan_time(self,duration_min,step_min=1,**kwargs): """ starts a scan with the readback as time in seconds duration: total time for the scan in minutes @@ -958,7 +1034,6 @@ class ScanRecord: **kwargs execute True/False (default = True) - trigger_dictionary = {1:'29idb:ca5:read'} diff --git a/iexcode/instruments/utilities.py b/iexcode/instruments/utilities.py index da20726..b8fc153 100644 --- a/iexcode/instruments/utilities.py +++ b/iexcode/instruments/utilities.py @@ -125,6 +125,25 @@ def read_dict(filename,**kwargs): mydict=ast.literal_eval(lastline) return mydict +def write_dict(filename,d,**kwargs): + """ + filename = name with extension of dictionary to read + **kwargs: + path = path to folder containing dictionary file (default: .IEX_dictionaries) + """ + if 'path' in kwargs: + path = kwargs['path'] + else: + path = os.path.join(os.path.dirname(os.path.dirname(__file__)),'IEX_dictionaries') + fpath = os.path.join(path,filename) + + with open(fpath,'a+') as f: + for line in d.keys(): + f.write(str(d[line])) + if verbose: + print('Updated: '+fpath) + + def make_table(start_stop_step_lists): """ diff --git a/iexcode/macros/commissioning.py b/iexcode/macros/commissioning.py index 44695bb..b4086a0 100644 --- a/iexcode/macros/commissioning.py +++ b/iexcode/macros/commissioning.py @@ -412,7 +412,7 @@ def procedure_align_m1(): # 2017_3 - HEG after opitmization: mba_b_0241-0244 # 2018_1 - HEG before opitmization: mba_b_0005-0008 -def iex_steering(h_position,v_position): +def ID_steering_message(h_position,v_position): """ prints the required steering to compensate for the current """ @@ -450,37 +450,6 @@ def beamsteering_1A(h_position,v_position,FE_center_h=0,FE_center_v=0): v_steering=str(vrad)+v_direction return h_steering,v_steering -def M0M1_steering(H2,V2): - """ - M1 steering: (monoVslit-2V and 2H) - Roll: Rz more positive => 2V more positive (0.25 => .25 mm) - Pitch: Ry more positive => 2H more positive (0.03 => .5 mm - """ - print('\nBeam position:') - print(f" - vertical: V2 = {round(V2,3)}") - print(f" - horizontal: H2 = {round(H2,3)}") - v_steering=beamsteering_2B(V2) - m1_roll=beamsteering_2B(V2)[1] - print('\nCurrent position:') - current_roll=FMB_mirror_get(1)[5] - new_roll=current_roll+m1_roll - print('\nREMEMBER: 2V slit should always be centered at zero by steering M1 roll!') - print(" - vertical: "+str(current_roll)+str(v_steering[1])+" => Move_M1('RZ',"+str(new_roll)+")") - print(' - horizontal: reset slit 2BH center to ',str(H2)) - - print("\n\nM1 roll vs energy calibration/flux:") - print(" - 1.0 mm @ slit2V ~ 1.0 mrad on M1 roll") - print(" - 1.0 mm @ slit2V = 0.4 eV shift in energy") - print(" - 0.8 mm @ slit2V = 25% loss in intensity on Au 4f\n") - - -def beamsteering_2B(v_position): - vroll=round(v_position*0.05/0.04,3) - if v_position<0: v_direction=' +' - else: v_direction=' -' - v_steering=v_direction+str(abs(vroll))+' urad' - return v_steering,float(v_steering.split(" ")[1]) - def ID_steering_scans(**kwargs): """ @@ -489,18 +458,19 @@ def ID_steering_scans(**kwargs): beam should be center at slit center, steer ID until the coincide **kwargs: - verbose: default => True sound: playsound, default => True + ID_eV: ID setpoint, default => 2000 extended_range True/False - False: default range = -3,3,0.1 - True: -5,5,0.1 - + True: -5,5 + False: -3,3 (default) + W_mesh_in: put W_mesh in (default => True) + W_mesh_out: removes W_mesh (default => False) Note: """ kwargs.setdefault('sound',True) - kwargs.setdefault('set_ID',2000) + kwargs.setdefault('ID_eV',2000) kwargs.setdefault('W_mesh_in',True) - kwargs.setdefault('W_mesh_out',True) + kwargs.setdefault('W_mesh_out',False) kwargs.setdefault('verbose',False) if 'extended_range' in kwargs: @@ -509,24 +479,23 @@ def ID_steering_scans(**kwargs): start,stop = (-3,3) slit_name = 'slit1A' - size,center = slits_get(slit_name, verbose=False) H,V = _slits_wide_open_dictionary()[slit_name] if kwargs['W_mesh_in']: - Diagnostic('mesh_W','in') + diagnostic('mesh_W','in') print("\n================== Slit 1A scans: checking ID steering ================== ") - ID_set_eV(kwargs['set_ID']) + ID_set_eV(kwargs['ID_eV']) slits_scan_center('slit1A','H',start,stop,0.1,size=(0.25,V),comment='Slit center - 1H') slits_scan_center('slit1A','V',start,stop,0.1,size=(H,0.25),comment='Slit center - 1V') - slits_set(slit_name,size,center,verbose=False) + slits_set(slit_name,(H,V),(0,0),verbose=False) if kwargs['sound']: playsound() if kwargs['W_mesh_out']: - Diagnostic('mesh_W','out') + diagnostic('mesh_W','out') if kwargs['verbose']: print('\nsteering out => move beam more positive (10 urad ~ 0.25 mm)') @@ -546,9 +515,17 @@ def wire_scans(**kwargs): """ Checks for large misaligment or clipping by M0/M1 + **kwargs + sound: True/False (default => True) + ID_eV: if not None sets the ID (default => None) + Note: Does not set the ID, mvID = 2.0 gives a nice gaussian """ kwargs.setdefault('sound',True) + kwargs.setdefault('ID_eV',None) + + if kwargs['ID_eV'] != None: + mvID(kwargs['ID_eV']) slits_set_size('slit1A',(4.5,4.5)) scan_wire('H',comment='Wire scan - H',all_diag=False) # by default puts all meshes in + DiodeC @@ -557,8 +534,75 @@ def wire_scans(**kwargs): if kwargs['sound']: playsound() -def wire_plots(scanNum,det_num): - print('copy code here') + +def beamsteering_2V(v_position): + """ + calculates M1 roll based on measured position + """ + delta = round(v_position*0.25/0.20,3) + + if v_position < 0: + direction=' +' + else: + direction=' -' + + steering = direction + str(abs(delta))+' urad' + return steering, -delta + +def beamsteering_2H(h_position): + """ + calculates M1 pitch based on measured position + """ + delta =round(h_position*0.03/0.5,3) + + if h_position < 0: + direction=' +' + else: + direction=' -' + + steering = direction + str(abs(delta))+' urad' + return steering, -delta + +def M0M1_steering_message(): + """ + """ + message = '\nM1 steering: (monoVslit-2V and 2H)' + message += ' Roll: Rz more positive => 2V more positive (0.25 => .20 mm)' + message += ' Pitch: Ry more positive => 2H more positive (0.03 => .5 mm)' + + message = "\nM1 roll vs energy calibration/flux:" + message += " - 1.0 mm @ slit2V ~ 1.0 mrad on M1 roll (0.4 eV energy shift)" + message += " - 0.8 mm @ slit2V = 25% loss in intensity on Au 4f\n" + + message += '\nM1 pitch is less critical (typically with 1 mm, M1 pitch is used to adjust)' + + print(message) + +def M0M1_steering(h_position,v_position,verbose=False): + """ + calculates the required steering + """ + v_steering, roll_delta = beamsteering_2V(v_position) + h_steering, pitch_delta = beamsteering_2H(h_position) + + current_roll = FMB_mirror_get(1)[5] + new_roll = current_roll+roll_delta + current_pitch = FMB_mirror_get(1)[4] + new_pitch = current_pitch+pitch_delta + + message = '\nSlit-2 slit: should always be centered vertically, adjust M1 roll, horizontally adjust pitch if too far off' + + message +=" - vertical: "+str(current_roll)+str(v_steering)+" => FMB_mirror_move(1,'RZ',"+str(new_roll)+")" + if abs(h_position) > 1: + message += " - horizontal: error to large, need to steer M1 pitch => FMB_mirror_move(1,'RY',"+str(new_pitch)+")" + else: + message +=' - horizontal: reset slit 2H center to '+str(h_position) + + if verbose: + M0M1_steering_message() + return new_roll,new_pitch + + def monoVslit_quick_scan(slit_name, **kwargs): """ @@ -567,15 +611,23 @@ def monoVslit_quick_scan(slit_name, **kwargs): slit_name: slit1A,slit2B + **kwargs + sound + mono_energy: 505 red-shifted, gausian (default); + 470 blue-shifted, two lobes + + Note: does not put diagnostic in the beam """ kwargs.setdefault('sound',True) + kwargs.setdefault('mono_energy',505) energy(500) - mvmono(505) + mvmono(kwargs['mono_energy']) H,V = _slits_wide_open_dictionary()[slit_name] c = mono_grating_density_get()/1200.0 + slit_size = 300 if mono_grating_get()=='HEG' else 200 slits_scan_center(slit_name,'V',-V/2,V/2,0.25,size=(H,0.25*c)) sleep(1) @@ -586,50 +638,72 @@ def monoVslit_quick_scan(slit_name, **kwargs): if kwargs['sound']: playsound() - -def monoVslit_quick_plot(scanNum,detDiode,c,xrange=None): - position = fit_mda(scanNum,detDiode,c,'gauss',xrange) - plt.show() - return position - -def monoVslit_full_profile_scan(slit_list=["2H","2V","1H","1V"], **kwargs): +def monoVslit_full_profile_scan(slit, **kwargs): """ Makes a nice 2D image of the energy distribution of the beam across the grating at ID=500 at 500 eV - kwargs: - grating: if specified then will change the grating - + **kwargs: + grating: if specified then will change the grating + hv_list: [475,515,2] (default) + extended_range: True/False Previously BeamProfile """ + kwargs.setdefault(hv_list,[475,515,2]) if 'grating' in kwargs: grating(kwargs['grating']) c = mono_grating_density_get()/1200 + n = 2 if 'extended_range' in kwargs else 1 + hv_list = kwargs['hv_list'] mvID(500) apertures_set() - eVstart = 460 - eVstop = 540 - eVstep = 4 - for slit in slit_list: - if slit=="1H": - #Hsize,Vsize,Hstart,Hstop,Hstep = 0.50,2,-2,2,0.25*c_slit # => 35 min - scan_mono_vs_slit('1H',[0.5,-2,2,0.25*c],[eVstart,eVstop,eVstep],comment='Mono/Slit - 1H') - elif slit == "1V": - #Hsize,Vsize,Vstart,Vstop,Vstep = 2,0.50,-2,2,0.25*c_slit - scan_mono_vs_slit('1V',[0.5,-2,2,0.25*c],[eVstart,eVstop,eVstep],comment='Mono/Slit - 1V') - elif slit =="2H": - #Hsize,Vsize,Hstart,Hstop,Hstep = 0.50,8,-3,3,0.5*c_slit - scan_mono_vs_slit('2H',[0.5,-3,3,0.5*c],[eVstart,eVstop,eVstep],comment='Mono/Slit - 2H') - elif slit =="2V": - #Hsize,Vsize,Vstart,Vstop,Vstep = 6,0.25*c,-4*c,4*c,0.5*c_slit - scan_mono_vs_slit('2V',[0.5,-4,4,0.5*c],[eVstart,eVstop,eVstep],comment='Mono/Slit - 2V') + if slit=="1H" :#10 min + slit_name = 'slit1A' + slit_direction = 'H' + slit_list = [0.5,-.75*n,.75,0.25] + elif slit == "1V": #10 + slit_name = 'slit1A' + slit_direction = 'H' + slit_list = [0.5,-.75*n,.75*n,0.25*c] + + if slit=="2H" :#10 min + slit_name = 'slit2B' + slit_direction = 'H' + slit_list =[0.25,-2*n,2*n,0.5] + elif slit == "2V": #10/20 MEG/HEG + slit_name = 'slit2B' + slit_direction = 'V' + slit_list = [0.25*c,-2*c*n,2*c*n,0.5] + kwargs.update({'comment':'Mono/Slit - '+slit}) + scan_mono_vs_slit(slit_name,slit_direction,slit_list,hv_list,**kwargs) + kwargs.pop('comment') + +def scan_mono_vs_slit(slit_name,slit_direction,slit_list,hv_list,**kwargs): + """ + 2D beam profile + """ + execute = kwargs['execute'] + + hv_start,hv_stop,hv_step = tuple(hv_list) + kwargs.update({'execute':False}) + kwargs.update({'scan_dim':1}) + mono_scan(hv_start,hv_stop,hv_step,**kwargs) + + slit_size,slit_start,slit_stop,slit_step = tuple(slit_list) + kwargs.update({'scan_dim':2}) + kwargs.update({'size':slit_size}) + kwargs.update({'execute':execute}) + slits_scan_center(slit_name,slit_direction,slit_start,slit_stop,slit_stop,**kwargs) + kwargs.pop('size') + + mono_scan_after() ##################################################################################### @@ -804,6 +878,97 @@ def scan_cam_mono_pitch(motor,angle,delta,cam_num,iterations=1,**kwargs): i+=1 cam_live() + +def update_slit_dict(**kwargs): + """ + Interactive function to update the slit position dictionary (Dict_Slit.txt) + + **kwargs + readOnly == False, if true just pring the current slit dictionary + """ + filename ='Dict_Slit.txt' + + kwargs.setdefault("readOnly",False) + + try: + slit_position=read_dict(filename) + print('\nCurrent dictionary:\n') + print(slit_position) + + except KeyError: + print("Unable to read previous dictionary") + return + + if kwargs['readOnly']== True: + return slit_position + + else: + grt=input('\nWhich grating do you want to update (HEG or MEG) >') + s2v=input('New Slit 2B-V center >') + s2h=input('New Slit 2B-H center >') + s1v=input('New Slit 1A-V center >') + s1h=input('New Slit 1A-H center >') + if grt == '' or s1h == '' or s1v == '' or s2h == '' or s2v == '': + print('\nMissing input. No changes made in file.') + return + + if grt[0] == '"' or grt[0]=="'": grt = grt[1:4] + + # new_slit_position={grt.upper():{'S1H':float(s1h),'S1V':float(s1v),'S2H':float(s2h),'S2V':float(s2v)}} # change order to match scan/fit order + new_slit_position={grt.upper():{'S2V':float(s2v),'S2H':float(s2h),'S1V':float(s1v),'S1H':float(s1h)}} + slit_position.update(new_slit_position) + + d={ + 0:'\n======= '+today()+': \n', + 1:slit_position, + 2:'\n' + } + write_dict(filename,d) + + apertures_set() + return slit_position + + + + + +def update_mirror_dict(n,**kwargs): + """ + Update mirror position dictionary (Dict_Mn.txt) + **kwargs + TBD + """ + filename ='Dict_M'+str(n)+'.txt' + + kwargs.setdefault("readOnly",False) + + try: + mir_position=read_dict(filename) + print('\nCurrent dictionary:\n') + print(mir_position) + except KeyError: + print("Unable to read dictionary") + return + if kwargs['readOnly']== True: + return mir_position + + else: + if n in [0,1,3]: + TX,TY,TZ,RX,RY,RZ=FMB_mirror_get(n) + new_mir_position={'TX':float(TX),'TY':float(TY),'TZ':float(TZ),'RX':float(RX),'RY':float(RY),'RZ':float(TZ)} + mir_position.update(new_mir_position) + else: + print('\nInvalid mirror number. No changes made in file.') + return + + d={ + 0:'\n======= '+today()+': \n', + 1:mir_position, + 2:'\n' + } + write_dict(filename,d) + + return mir_position diff --git a/iexcode/macros/start_of_the_week.py b/iexcode/macros/start_of_the_week.py index 3add87d..d16f4a2 100644 --- a/iexcode/macros/start_of_the_week.py +++ b/iexcode/macros/start_of_the_week.py @@ -17,6 +17,11 @@ from iexcode.instruments.utilities import * from iexcode.macros.commissioning import * from iexcode.macros.quick_plot import * +global m3r_camNum +m3r_camNum = 6 + +def sotw(grt,branch,wait=False,**kwarg): + StartOfTheWeek(grt,branch,wait=wait,**kwarg) def default_detectors(branch): """ @@ -42,7 +47,7 @@ def interactive_fct(): while flag == '0': cmt=input('\nType comment >') print('\n================================') - logprint(cmt) + log_print(cmt) print('================================\n') flag=input('\nType ('+options+'), or press ENTER to abort script >') if flag == '1': print('\nresuming script...\n'); flag=1 @@ -62,18 +67,6 @@ def input2float(ask,default_x=0): print(X) return X - -def adjust_fit(m,xV,xH): - print('\nxrange for V (mda #'+str(m-1)+')? >') - x1V_new=input2float('x1 > ',xV[0]) - x2V_new=input2float('x2 > ',xV[1]) - print('\nxrange for H (mda #'+str(m)+')? >') - x1H_new=input2float('x1 > ',xH[0]) - x2H_new=input2float('x2 > ',xH[1]) - xV_new=[x1V_new,x2V_new] - xH_new=[x1H_new,x2H_new] - return xV_new,xH_new - def fit_center(m,d,FHWMv,FHWMh,xV=None,xH=None): v_position,h_position=0,0 try: @@ -90,7 +83,21 @@ def fit_center(m,d,FHWMv,FHWMh,xV=None,xH=None): print('\t H center: '+str(h_position)) return v_position,h_position -def interactive_fit(v_position,h_position,m,d,FHWMv,FHWMh,xV,xH): +def input_range(x1,x2): + x1 = input2float('x1 => ',x1) + x2 = input2float('x2 => ',x2) + return x1,x2 + +def interactive_fit_mda(val_name,scannum,det,FWHM_or_PolyOrder,fct,**kwargs): + """ + **kwargs + xrange + val_name, name for printing + """ + kwargs.setdefault('xrange',None) + kwargs.setdefault('val_name','') + fit_mda(scannum,det,FWHM_or_PolyOrder,fct,**kwargs) + foo=input('\nare you happy with those values (y or n)? >') if foo.lower() == 'y' or foo.lower() == 'yes': print('\nresuming script...\n') @@ -110,23 +117,13 @@ def interactive_fit(v_position,h_position,m,d,FHWMv,FHWMh,xV,xH): print('\nresuming script...\n') flagfit=0 if flagfit == '1': - v_position=input2float('V center >') - h_position=input2float('H center >') + val=input2float(val_name+' =>') flagfit=1 if flagfit == '2': - xV_new,xH_new=adjust_fit(m,xV,xH) - v_position,h_position=fit_center(m,d,FHWMv,FHWMh,xV_new,xH_new) + x1,x2 = input_range(x1,x2) + fit_mda(scannum,det,FWHM_or_PolyOrder,fct,xrange=(x1,x2)) flagfit=2 - return flagfit,v_position,h_position - -def after_scan(d,FHWMv,FHWMh,xV=None,xH=None): - m=MDA_GetLastFileNum() - v_position,h_position=fit_center(m,d,FHWMv,FHWMh,xV,xH) - flagfit,v_position,h_position=interactive_fit(v_position,h_position,m,d,FHWMv,FHWMh,xV,xH) - while flagfit > 0: - flagfit,v_position,h_position=interactive_fit(v_position,h_position,m,d,FHWMv,FHWMh,xV,xH) - print(flagfit,v_position,h_position) - return flagfit,v_position,h_position + return flagfit,val def StartOfTheWeek(grt,branch,wait=False,**kwargs): """ @@ -158,141 +155,126 @@ def StartOfTheWeek(grt,branch,wait=False,**kwargs): kwargs.setdefault('slit1A_extended',False) kwargs.setdefault('monoVslit_quick',True) - + ########################################################################### + ### checks and switch branch + ########################################################################### + + # defining detectors detCA4,detH,detV,detDiode = default_detectors(branch) - if kwargs['detDiode'] != None + if kwargs['detDiode'] != None: detDiode = kwargs['detDiode'] + #check that all scan types are valid + for scan in kwargs['scanType']: + if scan not in ['slit1','wire','flux','monoVslit']: + print_warning_message(scan+" is not a valid scan scanType=['slit1','wire','flux','monoVslit']") + return + + # checkin branch is defined and initializing BLconfig branch=branch.lower() - if iex.BL == None: - if branch == 'c': - BL_init=ARPES_init - else: - BL_init=kappa_init + if branch == 'c': + BL_init=ARPES_init + elif branch == 'd': + BL_init=kappa_init + cam_exposure_time(m3r_camNum,0.001) + else: + print_warning_message('Not a valid branch') + return - if kwargs['repeat']==False: #reset folders/detectors/... - BL_init('staff') + if kwargs['repeat']: + #check to see if init is defined + if BLconfig_branch() != branch: + BL_init('staff',reset=True,set_folders=True,xrays=True) else: - BL_init('staff',reset=False,set_folders=False) + BL_init('staff',reset=True,set_folders=True,xrays=True) switch_branch(branch) log_name_set('StartOfTheWeek_log.txt') log_print("\n\n================== Start Of The Week @ "+today('slash')+':\n') - - for scan in kwargs['scanType']: - if scan not in ['slit1','wire','flux','monoVslit']: - print(scan+" is not a valid scan scanType=['slit1','wire','flux','monoVslit']") - return - ### checking diode settings: - if branch == 'c': - ca = Keithley('b',detDiode) - ca.autoscale('Off') - - if not kwargs['detDiode']: - foo=input('What is the detector number (make sure it is IN!)? >') - detDiode=int(foo) - else: - foo=input('Is detector D'+str(kwargs['detDiode'])+' in direct beam (y or n)? >') - - print('Diagnostic used for direct beam measurements: D'+str(detDiode)) - - - print("\n\n================== Sets Beamline & Scans:") + #switching grating if needed grating(grt) ########################################################################### ### stuff that requires beam ########################################################################### + ### Wait for next 8AM: + if wait: + t = datetime.today() + if 0 <= t.hour <= 8: + wait_for_it(0,8,5) + else: + wait_for_it(1,8,5) ### checking branch shutter: - shutter_open = branch_shutter_status() - if shutter_open == False: - foo=input_d('Shutter '+branch.upper()+' is closed, do you want to open it (y or n)? >') - if foo.lower() == 'y' or foo.lower() == 'yes': - branch_shutter_open() - else: - print('Aborting...') - return + branch_shutter_open() + main_shutter_open() + + if main_shutter_status() == False: + print_warning_message('Aborting... main shutter did not open') + return + + if branch_shutter_status() == False: + print_warning_message('Aborting... '+branch+'-branch shutter did not open') + return ### checking QP ratio: - QP=caget('ID29:QuasiRatio.RVAL') + QP=ID_QP_ratio_get()[0] if QP != 100: foo=input('QP on!!! Continue (y or n)? >') if foo.lower() == 'y' or foo.lower() == 'yes': - print('Resuming...') + status = 'Continueing' else: - print('Aborting...') + status = 'Aborting...' + print(status) return - ### Wait for next 8AM: - if wait: - t = datetime.today() - if 0 <= t.hour <= 8: - wait_for_it(0,8,5) - else: - wait_for_it(1,8,5) - ### checking ID: polarization(kwargs['mode']) ### Ready to start: scanNum = mda_fileNum() - ########################################################################### + ### scanning + ########################################################################### + + #ID steering/Slit1A if 'slit1' in kwargs['scanType']: print("\n\n================== Slit 1A scans:") - mvID(2000) flag=2 - while flag==2: + while flag>1: #scanning - slit1A_kwargs = { - 'sound':kwargs['sound'], - 'extended_range':kwargs['slit1A_extended'] - } - ID_steering_scans(**slit1A_kwargs) - + ID_steering_scans(**kwargs) #plotting - try: - scanNum_h = last_mda()-1 - scanNum_v = last_mda() - h_position = ID_steering_plots(scanNum_h,detCA4,xrange=[-1,1]) - v_position = ID_steering_plots(scanNum_v,detCA4,xrange=[-1,1]) - iex_steering(h_position,v_position) + scanNum_h = last_mda()-1 + scanNum_v = last_mda() + + flagfit, h = interactive_fit_mda('H_center',scanNum_h,detCA4,1,'gauss',xrange=[-1,1]) + if flagfit == '': + return + + flagfit, v = interactive_fit_mda('V_center',scanNum_v,detCA4,1,'gauss',xrange=[-1,1],val_name='V_center') + if flagfit == '': + return + try: + ID_steering_message(h,v) + flag = interactive_fct() except: - print('\nUnable to fit position; try to adjust xrange.\n') + print('\nUnable to calculate ID steering') + print('steering out => move beam more positive (10 urad ~ 0.25 mm)') + print('steering up => move beam more positive (10 urad ~ 0.25 mm)') + flag = interactive_fct() + + if flag == '': + return - flag=interactive_fct() + diagnostic('mesh_W','out') - #want to refit - while flag == 3: - try: - fitH=input('do you want to fit mda #'+str(scanNum_h)+' ie horizontal (y or n)? >') - if fitH.lower() == 'y' or fitH.lower() == 'yes': - x1=input('x1 >') - x2=input('x2 >') - h_position = ID_steering_plots(scanNum_h,detCA4,xrange=[float(x1),float(x2)]) - - fitV=input('do you want to fit mda #'+str(scanNum_v)+' ie vertical (y or n)? >') - if fitV.lower() == 'y' or fitV.lower() == 'yes': - x1=input('x1 >') - x2=input('x2 >') - v_position = ID_steering_plots(scanNum_v,detCA4,xrange=[float(x1),float(x2)]) - - iex_steering(h_position,v_position) - foo=input('\nare you happy with the fit (y or n)? >') - if foo.lower() == 'y' or foo.lower() == 'yes': - flag=interactive_fct() - - except: - print('\nUnable to fit position; try to tweak xrange again\n') - flag=interactive_fct() - if flag == '': - return ###### Wire scans: if 'wire' in kwargs['scanType']: + print("\n\n================== Slit 1A scans:") + #scanning - mvID(2000) wire_scans(**kwargs) #plotting @@ -307,113 +289,99 @@ def StartOfTheWeek(grt,branch,wait=False,**kwargs): ###### Mono/slit scans: if 'monoVslit' in kwargs['scanType']: - list_position=[grt,'S1H','S1V','S2H','S2v'] - if mono_grating_get('HEG'): - slit(300) - c=2 + + #checking that detDiode is in + if not kwargs['detDiode']: + foo=input('What is the detector number for mono scans (make sure it is IN!)? >') + detDiode=int(foo) else: - slit(200) - c=1 - - diagnostics_all_out(diode_stay_in=True) + foo=input('Is detector D'+str(kwargs['detDiode'])+' in direct beam (y or n)? >') + print("\n\n================== Mono/slit scans:") - if kwargs['monoVslit_quick']: - for i,slit_name in enumerate(['slit2B','slit1A']): - print('\n---------- Scanning '+slit_name+':\n') - flag=2 - while flag==2: - #scanning - monoVslit_quick_scan(slit_name,**kwargs) - #plotting - try: - scanNum_v = last_mda()-1 - scanNum_h = last_mda() - V2 = monoVslit_quick_plot(scanNum_v,detDiode,c) - H2 = monoVslit_quick_plot(scanNum_h,detDiode,1) - - except: - print('Unable to fit position; try to adjust xrange.') - - flag=interactive_fct(mirror=True) - #want to refit - while flag == 3: - fitV2=input('do you want to FIT mda #'+str(scanNum_v)+' ie slit2-V (y or n)? >') - if fitV2.lower() == 'y' or fitV2.lower() == 'yes': - x1=input('x1 >') - x2=input('x2 >') - xrange=[float(x1),float(x2)] - V2 = monoVslit_quick_plot(scanNum_v,detDiode,c,xrange=xrange) - foo=input('do you want to replace '+slit_name+'-V value in list_position (y or n)? >') - if foo.lower() == 'y' or foo.lower() == 'yes': - list_position[1]=V2 - - fitH2=input('do you want to FIT mda #'+str(scanNum_h)+' ie slit2-H (y or n)? >') - if fitH2.lower() == 'y' or fitH2.lower() == 'yes': - x1=input('x1 >') - x2=input('x2 >') - xrange=[float(x1),float(x2)] - H2 = monoVslit_quick_plot(scanNum_h,detDiode,1,xrange=xrange) - foo=input('do you want to REPLACE '+slit_name+'-H value in list_position (y or n)? >') - if foo.lower() == 'y' or foo.lower() == 'yes': - list_position[1]=H2 - - if slit_name == 'slit2B': - M0M1_steering(H2,V2) - list_position[4] = V2 - list_position[3] = H2 - mirror = True - elif slit_name == 'slit1A': - list_position[2] = V2 - list_position[1] = H2 - mirror = False - - foo=input('\nare you happy with the fit (y or n)? >') - if foo.lower() == 'y' or foo.lower() == 'yes': - flag=interactive_fct(mirror=mirror) - - #happy with fitting but want to adjust roll - if flag == 4: - x=input('New M1 roll value >') - x=float(x) + for slit_name in ['slit2B','slit1A']: + # slit2B => M1 alignment + print('\n---------- Scanning '+slit_name+':\n') + flag=2 + + list_position = [grt,0,0,0,0] + while flag>1: + #scanning + if kwargs['monoVslit_quick']: + monoVslit_quick_scan(slit_name,**kwargs) + else: + monoVslit_full_profile_scan(slit_name,**kwargs) + #plotting + c = mono_grating_density_get()/1200 + + scanNum_v = last_mda()-1 + scanNum_h = last_mda() + + if kwargs['monoVslit_quick']: + flagfit, h = interactive_fit_mda('H_center',scanNum_h,detDiode,1,'gauss',xrange=[-1,1]) + if flagfit == '': + return + flagfit, v = interactive_fit_mda('V_center',scanNum_v,detDiode,c,'gauss',xrange=[-1,1]) + if flagfit == '': + return + flag = interactive_fct() + + print('\nBeam position - '+slit_name[-2:]+':') + print(f" - vertical: V = {round(v,3)}") + print(f" - horizontal: H = {round(h,3)}") + + if slit_name == 'slit2B': + #beam steering calculations + new_roll = M0M1_steering(h,v) + list_position[4] = v + list_position[3] = h + + foo = input('\nDo you want to steer M1 (y or n)?') + if foo[0].lower() == 'y': + new_roll = input2float('New M1 roll value => ',new_roll) try: - FMB_mirror_move(1,'RZ',x) - sleep(2); + FMB_mirror_move(1,'RZ',new_roll) + sleep(2) FMB_mirror_get(1) - print('\nrepeating scan...\n') - flag=2 + print('\nrepeating scans...') + flag == 2 except: - print('\ninvalid input; unable to move M1...\n') - flag=interactive_fct(mirror=True) + print('\invalid input; unable to move M1') + flag = interactive_fct() + + elif slit_name == 'slit1A': + list_position[2] = v + list_position[1] = h - print('\nBeam center fit @ '+str(list_position)) - foo=input('do you want to update the slit dictionary (y or n)? >') - if foo.lower() == 'y' or foo.lower() == 'yes': + if flag == '': + return + flag = 2 + + #update slit dictionary + print('\nBeam center fit @ ['+grt+',2V,2H,1V,1H]:'+str(list_position)) + + foo=input('Do you want to update the slit dictionary (y or n)? >') + if foo[0].lower() == 'y': slit_list=input('do you want to use '+str(list_position)+' (y or n)? >') - if foo.lower() == 'y' or foo.lower() == 'yes': + if foo[0].lower() == 'y': update_slit_dict(list_position) else: update_slit_dict() - - else: # 2D map - mvID(500) - flag=2 - while flag==2: - beam_profile(grt,["2V","2H","1V","1H"]) - - #interactive - flag=interactive_fct() + + #update M1 dictionary + foo=input('Do you want to update the M1 (y or n)? >') + if foo[0].lower() == 'y': + update_mirror_dict(1) if flag == '': return + ###### Check flux: if 'flux' in kwargs['scanType']: - diode_c('In') print("\n\n================== Check Flux:") flag=2 while flag==2: check_flux_scan(stay=True) - scanNum = last_mda() try: plot_mda(scanNum,detDiode,Flux=3);plt.show() @@ -428,153 +396,6 @@ def StartOfTheWeek(grt,branch,wait=False,**kwargs): print("\n\n================== All done:") print("\nDon't forget to put back the user folder !!!!") - - - ###### The end: - if list_position: - print('\nBeam center fit @ ['+grt+',2V,2H,1V,1H]:',list_position) - if kwargs['sound']: - playsound() - - return list_position - - - - -def update_slit_dict(mylist=None,**kwargs): - """ - Interactive function to update the slit position dictionary (Dict_Slit.txt) - mylist=['GRT',2V,2H,1V,1H] - **kwargs - readOnly == False, if true just pring the current slit dictionary - """ - filepath = "/home/beams22/29IDUSER/Documents/User_Macros/Macros_29id/IEX_Dictionaries/" - filename ='Dict_Slit.txt' - - kwargs.setdefault("readOnly",False) - - # print('\n\nWARNING: 2V slit should always be centered at zero ie steer M1 center beam on the grating') - # print('Increasing the roll moves the beam more positive: +0.05 pitch => ~ +0.04 slit position; Use:\n') - # print("Get_Mirror(1);Move_M1('RZ',x)") - # print("energy(500);mono(505);slit(200)") - # print("Scan_NarrowSlit_Go(which='2V',slit_parameters=[0.25, -2, 2, 0.25]) #for MEG; slit_parameters=[0.5, -2, 2, 0.25] for HEG") - # print("Scan_NarrowSlit_Go(which='2V',slit_parameters=[0.50, -2, 2, 0.25]) #for HEG") - # print('Once steering is completed, check 2H position:') - # print("Scan_NarrowSlit_Go(which='2H',slit_parameters=[0.25, -6, 6, 0.25]) ") - - - try: - slit_position=read_dict(filename) - print('\nCurrent dictionary:\n') - print(slit_position) - except KeyError: - print("Unable to read dictionary") - return - - if kwargs['readOnly']== True: - return slit_position - - else: - if mylist: - if len(mylist) == 5: - grt,s2v,s2h,s1v,s1h=mylist - else: - print('\nInvalid list. No changes made in file.') - return - - else: - grt=input('\nWhich grating do you want to update (HEG or MEG) >') - s2v=input('New Slit 2B-V center >') - s2h=input('New Slit 2B-H center >') - s1v=input('New Slit 1A-V center >') - s1h=input('New Slit 1A-H center >') - - if grt == '' or s1h == '' or s1v == '' or s2h == '' or s2v == '': - print('\nMissing input. No changes made in file.') - return - - if grt[0] == '"' or grt[0]=="'": grt = grt[1:4] - - # new_slit_position={grt.upper():{'S1H':float(s1h),'S1V':float(s1v),'S2H':float(s2h),'S2V':float(s2v)}} # change order to match scan/fit order - if grt.upper() == 'MEG' or grt.upper() == 'HEG': - new_slit_position={grt.upper():{'S2V':float(s2v),'S2H':float(s2h),'S1V':float(s1v),'S1H':float(s1h)}} - else: - print('\nInvalid grating name. No changes made in file.') - return - - - slit_position.update(new_slit_position) - - - with open(join(filepath, filename), "a+") as f: - f.write('\n======= '+today()+': \n') - f.write(str(slit_position)) - f.write('\n') - print('\nWriting dictionary to:',join(filepath, filename)) - sleep(2) - apertures_set() - return slit_position - - - -def update_slit_dict(**kwargs): - """ - Interactive function to update the slit position dictionary (Dict_Slit.txt) - **kwargs - readOnly == False, if true just pring the current slit dictionary - """ - filepath = "/home/beams22/29IDUSER/Documents/User_Macros/Macros_29id/IEX_Dictionaries/" - filename ='Dict_Slit.txt' - kwargs.setdefault("readOnly",False) - - print('\n\nWARNING: 2V slit should always be centered at zero ie steer M1 center beam on the grating') - print('Increasing the roll moves the beam more positive: +0.05 pitch => ~ +0.04 slit position; Use:\n') - print("Get_Mirror(1);Move_M1('RZ',x)") - print("energy(500);mono(505);slit(200)") - print("Scan_NarrowSlit_Go(which='2V',slit_parameters=[0.25, -2, 2, 0.25]) #for MEG; slit_parameters=[0.5, -2, 2, 0.25] for HEG") - print("Scan_NarrowSlit_Go(which='2V',slit_parameters=[0.50, -2, 2, 0.25]) #for HEG") - print('Once steering is completed, check 2H position:') - print("Scan_NarrowSlit_Go(which='2H',slit_parameters=[0.25, -6, 6, 0.25]) ") - - try: - slit_position=read_dict(filename) - print('\nCurrent dictionary:\n') - print(slit_position) - - except KeyError: - print("Unable to read previous dictionary") - return - - if kwargs['readOnly']== True: - return slit_position - - else: - grt=input('\nWhich grating do you want to update (HEG or MEG) >') - s2v=input('New Slit 2B-V center >') - s2h=input('New Slit 2B-H center >') - s1v=input('New Slit 1A-V center >') - s1h=input('New Slit 1A-H center >') - - if grt == '' or s1h == '' or s1v == '' or s2h == '' or s2v == '': - print('\nMissing input. No changes made in file.') - return - - if grt[0] == '"' or grt[0]=="'": grt = grt[1:4] - - # new_slit_position={grt.upper():{'S1H':float(s1h),'S1V':float(s1v),'S2H':float(s2h),'S2V':float(s2v)}} # change order to match scan/fit order - new_slit_position={grt.upper():{'S2V':float(s2v),'S2H':float(s2h),'S1V':float(s1v),'S1H':float(s1h)}} - slit_position.update(new_slit_position) - - - with open(join(filepath, filename), "a+") as f: - f.write('\n======= '+today()+': \n') - f.write(str(slit_position)) - f.write('\n') - print('\nWriting dictionary to:',join(filepath, filename)) - - apertures_set() - return slit_position - diff --git a/iexcode/staff_cheatsheet.md b/iexcode/staff_cheatsheet.md index 81e8426..910a8ee 100644 --- a/iexcode/staff_cheatsheet.md +++ b/iexcode/staff_cheatsheet.md @@ -12,7 +12,7 @@ ARPES sepcific functions tey,ca15 = ARPES_init('user_name') -## **AD_untilites** +## **AD_utilites** functions for common area detector operations ## **bakeout** @@ -43,27 +43,27 @@ config file which holds global variable BL and MPA beamline diagnostics, positions and current amplifiers To Do: add functions to enable scanning - diagnostic_name_list() #prints the name of all the diagnostics_all_in/out() #move all diagnostics to in/out position - diagnostic_InOut(name,In_Out) #moves the specified diagnostic in/out - diagnostic_read(name) #reads the current amplifier for a given diagnostic + diagnostic_name_list() #prints the name of all the diagnostics_all_in/out() #move all diagnostics to in/out position + diagnostic(name,in_out) #moves the specified + diagnostic_read(name) #reads the current amplifier for a given diagnostic ------------------------------------------------------------- - mesh_W(In_Out) #moves W-mesh in the A-hutch in/out - diode_c(In_Out) #moves diode in c-branch in/out - diode_c_read() #reads the current amplifier for the c-branch diode - diode_d(In_Out) #moves diode in c-branch in/out; located just before the kappa endstation - mesh_d(In_Out) #moves mesh in d-branch in/out; used for normalization - mesh_d_read() #reads the current amplifier for the d-branch mesh + mesh_W(In_Out) #moves W-mesh in the A-hutch in/out + diode_c(In_Out) #moves diode in c-branch in/out + diode_c_read() #reads the current amplifier for the c-branch diode + diode_d(In_Out) #moves diode in c-branch in/out; located just before the kappa endstation + mesh_d(In_Out) #moves mesh in d-branch in/out; used for normalization + mesh_d_read() #reads the current amplifier for the d-branch mesh ------------------------------------------------------------- - diagnostics_preset_list() #returns the dictionary with all preset positions + diagnostics_preset_list() #returns the dictionary with all preset positions diagnostics_presets_go(diag_name,preset_name) #goes to preset value _diagnostics_sp_write(diag_name,preset_name,val) ## **electron_analyzer** Scienta functions - folders_EA(userPath #sets the folder for spectra saving (called by folders_ARPES) - - EA_ioc_init() #initializes the ioc after a reboot (eventually goes in AutoSave) + folders_EA(userPath #sets the folder for spectra saving (called by folders_ARPES) + ------------------------------------------------------------- + EA_ioc_init() #initializes the ioc after a reboot (eventually goes in AutoSave) ------------------------------------------------------------- EA.get() #get current EA setting EA.put(KE,PE) #change EA setting @@ -86,19 +86,19 @@ Scienta functions ## **encoder** all beamline absolute encoders - encoder_name_list() #lists names in encoder dictionary - encoder_sync(name) #syncs all the encoders associated with name - encoders_reset_zero(name) #resets the center for the current position + encoder_name_list() #lists names in encoder dictionary + encoder_sync(name) #syncs all the encoders associated with name + encoders_reset_zero(name) #resets the center for the current position ## **files_and_folder** general functions for dealing with files and directories - path_dserv(folder,run,user_name) #path to user data directory on the dserve - check_run() #returns the current run based on todays date - folder_ftp(folder,run,user_name) #creates the folders on the ftp server, kip - make_user_folders(run,folder,user_name,endstation_name) #creates all the appropriate user folders - folder_mdarun,folder,user_name,file_prefix,ioc) #creates/set the user folder for the scanRecord - folder_SPEC(run,folder,user_name) #creat3s spec folder in 29iduser account + path_dserv(folder,run,user_name) #path to user data directory on the dserve + check_run() #returns the current run based on todays date + folder_ftp(folder,run,user_name) #creates the folders on the ftp server, kip + make_user_folders(run,folder,user_name,endstation_name) #creates all the appropriate user folders + folder_mdarun,folder,user_name,file_prefix,ioc) #creates/set the user folder for the scanRecord + folder_SPEC(run,folder,user_name) #creat3s spec folder in 29iduser account ## **FMB_mirrors** functions for M0,M1,M3R @@ -109,8 +109,8 @@ To Do: M0M1 table moves to dictionary with csv file FMB_mirror_move_all(mirror_num,position_list) #moves all the axes to the positions specified in position_list FMB_mirror_tweak(mirror_num,axis) #relative moves FMB_mirror_scan(mirror_num,start,stop,step) #scan a mirror axis - M0M1_Table #reads the dictionary file to get the previous mirror positions - M0M1_SP #writes the values form M0M1_Table to the set points (still need to push move) + M0M1_Table #reads the dictionary file to get the previous mirror positions + M0M1_SP #writes the values form M0M1_Table to the set points (still need to push move) ## **hxp_mirrors** Newport hexapods M3A/M4A and M4R @@ -128,17 +128,22 @@ Cameras to enable/disable when switching between branches ## **IEX_BL_config** used to access current beamline configuration, based on instance initialization not pv - Beamline_Config #class to carry all configuration info gets stored in - iexcode\instruments\cfg BL - BL_branch() #returns the branch (shutter not mirror position) - BL_mode() #returns the current mode (user/staff) - get_all() #gets relavent pv values + Beamline_Config #class to carry all configuration info gets stored in BL + BLconfig_endstation_name() #gets or sets iex.BL.endstation_name + BLconfig_folder() #gets or sets iex.BL.folder + BLconfig_branch() #gets or sets iex.BL.branch + BLconfig_xrays() #gets or sets iex.BL.xrays (True/False) + BLconfig_mode() #gets or sets iex.BL.mode ('user'/'staff') + BLconfig_get_set(endstation_get) #sets iex.BL.endstation_get + BLconfig_safe_state_set(endstation_safe_state) #sets iex.BL.safe_state + ------------------------------------------------------------- + get_all() #gets relavent pv values ## **IEX_VPU: undulator functions** insertion device functions ID_wait_for_permission() #waits for security access - + ------------------------------------------------------------- ID_get_all() #gets ID_mode, ID_QP_ratio, ID_sp, ID_rbv ID_energy_range() #return max/min for a given mode ID_ready() #looks at the two busy records @@ -158,8 +163,8 @@ insertion device functions ## **kappa_angle_calcs** - fourc2kappa(theta,chi,phi) # converts between four-circle angles and kappa angles - kappa2fourc(kth,kappa,kphi) # converts between kappa dn four-circle angles + fourc2kappa(theta,chi,phi) # converts between four-circle angles and kappa angles + kappa2fourc(kth,kappa,kphi) # converts between kappa dn four-circle angles ## **kappa_det** defines kappa tth detector class and other functions @@ -194,6 +199,7 @@ functions for writing logfile.txt, gets set by IEX_BL_config log_print(comment) #print a comment in the logfile log_update() #updates the logfile with the current info (used if script is aborted) log_name_set(new_name) #change name of logfile + log_init(endstation_name,user_name,log_dictionary) #sets up logging ## **m3r** functions for dealing with m3r @@ -244,18 +250,25 @@ functions and class for handling the scanRecord scan_fillin(VAL,RBV,start,stop,steps) #fills in scanRecord linear mode scan_fillin_table(VAL,RBV,my_table) #fills in scanRecord table mode scan_go() #starts a scan - + ------------------------------------------------------------- scan_after_table_reset() #sets back to linear and clears positioners - + ------------------------------------------------------------- scan_positioners_clear() #clears the positioners scan_positioner_after_set() #procs the after scan sequence scan_positioner_settling_time_set() #sets the settling time scan_triggers_set() #sets the scan triggers scan_triggers_clear() #clears the triggers scan_detectors_set() #adds a detector + ------------------------------------------------------------- + scan_empty() #scan with no positioners + scan_time(duration_min) #scan with positioner readback as time and detector settling as minutes + ------------------------------------------------------------- + mda_detector_dictionary() #reads,sets or updates default detector dictionary + mda_trigger_dictionaryy() #reads,sets or updates default trigger_dictionary + mda_before_scan_pv() #reads,sets before_scan_pv + mda_after_scan_pv() #reads,sets after_scan_pv + mda_snake_set() #reads,set snake_set function - .empty_scan #scan with no positioners - .time_scan #scan with positioner readback as time and detector settling as minutes ## **Scienta** base functions for taking spectra, called by electron_analyzer @@ -284,7 +297,7 @@ beamline slits and aperatures slits_set_center(slit_name,(Hcenter,Vcenter)) slits_scan_size(slit_name,direction,start,stop,step) slits_scan_center(slits_scan_center(slit_name,direction,start,stop,step) - slit1A_scribe_marks() #moves the slits so that the scribe marks should align + slit1A_scribe_marks() #moves the slits so that the scribe marks should align slit1A_get() slit1A_set(H_size,V_size) slit2B_get() @@ -321,16 +334,16 @@ functions for filling in user calcs and string Sequences ## **utilities** general functions - dateandtime() #prints current date and time - today() #returns a string with the date - print_warning_message(message) #prints a warning message_string - wait_for_it(D,H,M) #waits for future time - input_timeout(question,t) #used to break for an input - playsound() #plays audio file - range_up/down(start,end,step) #loop for noninteger counting (inclusive of last point) - take_closest_value(my_list,my_number) #takes the closest value from a list - read_dict(filename) #reads text files in iexcode.IEX_dictionaries - make_table(start_stop_step_lists) #makes a table array from a list of lists + dateandtime() #prints current date and time + today() #returns a string with the date + print_warning_message(message) #prints a warning message_string + wait_for_it(D,H,M) #waits for future time + input_timeout(question,t) #used to break for an input + playsound() #plays audio file + range_up/down(start,end,step) #loop for noninteger counting (inclusive of last point) + take_closest_value(my_list,my_number) #takes the closest value from a list + read_dict(filename) #reads text files in iexcode.IEX_dictionaries + make_table(start_stop_step_lists) #makes a table array from a list of lists ## **valves** control valves via epics -- GitLab