From 67cee074cb71c4de9b2d4aad378460ab6a238d1b Mon Sep 17 00:00:00 2001 From: gac-x07mb Date: Mon, 2 Mar 2026 09:05:57 +0100 Subject: [PATCH] 02 2026 --- config/config.properties | 11 +- config/preferences.json | 15 +- config/settings.properties | 2 +- config/variables.properties | 8 +- ...MB-ES-MA1:TRZ1.VAL.properties => X4W7SB~B} | 0 script/Run_OTF_MA.py | 382 ++++++++++++++++++ .../Users/Thomas/EnergyScan_backup_220822.py | 214 ++++++++++ script/Users/Thomas/Run_OTF_MA.py | 6 +- .../Users/Thomas/{test:py.py => TEBAHO~G.PY} | 0 script/test/TestOTF.py | 6 + 10 files changed, 628 insertions(+), 16 deletions(-) rename devices/{X07MB-ES-MA1:TRZ1.VAL.properties => X4W7SB~B} (100%) create mode 100644 script/Run_OTF_MA.py create mode 100644 script/Users/Thomas/EnergyScan_backup_220822.py rename script/Users/Thomas/{test:py.py => TEBAHO~G.PY} (100%) create mode 100644 script/test/TestOTF.py diff --git a/config/config.properties b/config/config.properties index af43ed6..0b0d188 100644 --- a/config/config.properties +++ b/config/config.properties @@ -1,9 +1,12 @@ -#Mon Aug 08 10:04:55 CEST 2022 +#Tue Jun 06 14:23:25 CEST 2023 +xscanMoveTimeout=600 autoSaveScanData=true simulation=false commandExecutionEvents=false logDaysToLive=30 +xscanCrlogicChannel=null dataScanSaveOutput=false +xscanCrlogicSimulated=false userAuthenticator= logLevelConsole=Off filePermissionsConfig=Default @@ -16,6 +19,7 @@ fdaSerialization=true dataTransferPath=null scanStreamingPort=-1 saveConsoleSessionFiles=false +xscanAppendSuffix=true devicePoolFile={config}/devices.properties versionTrackingManual=true dataTransferMode=Off @@ -44,12 +48,17 @@ terminalEnabled=false notificationLevel=Off filePermissionsScripts=Default terminalPort=3579 +xscanCrlogicPrefix=null tasksFile={config}/tasks.properties dataTransferUser=null filePermissionsData=Default +xscanCrlogicAbortable=true +xscanContinuousUpdate=false createSessionFiles=false versionTrackingLogin={context}/svcusr-hlapp_robot noBytecodeFiles=false versionTrackingRemote=git@git.psi.ch\:pshell_config/x07mb.git dataProvider=fda +xscanCrlogicIoc=null +dataScanLazyTableCreation=false saveCommandStatistics=false diff --git a/config/preferences.json b/config/preferences.json index 8d9caf4..e3c3ba8 100644 --- a/config/preferences.json +++ b/config/preferences.json @@ -21,13 +21,13 @@ }, "fontPlotLabel" : { "name" : "SansSerif", - "style" : 0, - "size" : 15 + "style" : 1, + "size" : 19 }, "fontPlotTick" : { "name" : "SansSerif", - "style" : 0, - "size" : 15 + "style" : 1, + "size" : 22 }, "fontPlotTitle" : { "name" : "SansSerif", @@ -47,15 +47,16 @@ "hideEditorLineNumbers" : false, "hideEditorContextMenu" : false, "consoleLocation" : "Left", - "dataPanelLocation" : null, - "openDataFilesInDocTab" : false, + "dataPanelLocation" : "Left", + "openDataFilesInDocTab" : true, "noVariableEvaluationPropagation" : false, "processingScripts" : [ ], "asyncViewersUpdate" : false, + "asyncHistoryPlotsUpdate" : false, "scanPlotDisabled" : false, "scanTableDisabled" : false, "cachedDataPanel" : false, - "dataExtensions" : "", + "dataExtensions" : "xml log tif tiff txt", "dataSubFiles" : "", "hideFileName" : false, "showEmergencyStop" : false, diff --git a/config/settings.properties b/config/settings.properties index bfe979c..1d4788f 100644 --- a/config/settings.properties +++ b/config/settings.properties @@ -1,2 +1,2 @@ -#Mon Aug 08 10:01:14 CEST 2022 +#Mon Jan 30 11:36:32 CET 2023 FdaBrowser=true diff --git a/config/variables.properties b/config/variables.properties index b219414..5e9fd16 100644 --- a/config/variables.properties +++ b/config/variables.properties @@ -1,4 +1,4 @@ -#Mon Aug 08 10:05:00 CEST 2022 -LastRunDate=220409 -FileSequentialNumber=2614 -DaySequentialNumber=0 +#Mon Jun 26 23:00:59 CEST 2023 +LastRunDate=230626 +FileSequentialNumber=4133 +DaySequentialNumber=211 diff --git a/devices/X07MB-ES-MA1:TRZ1.VAL.properties b/devices/X4W7SB~B similarity index 100% rename from devices/X07MB-ES-MA1:TRZ1.VAL.properties rename to devices/X4W7SB~B diff --git a/script/Run_OTF_MA.py b/script/Run_OTF_MA.py new file mode 100644 index 0000000..fab766c --- /dev/null +++ b/script/Run_OTF_MA.py @@ -0,0 +1,382 @@ +import traceback +import imp +import os +#from CaChannel import * +#from epicsMotor import * +#from epicsPV import * +import time +import string +import sys +import json + + +# TO DO: Energy scan has onlz 1 positioner +# need to generalize definition of scans to several paraller positiner, +# to be able to use Create_Channels, alteratively need a dedicate channel creation for each scan type +# tricky, code should stay simple +# options. +# Define channel generation for each chanenl separatelz +# generalze scand to 1d and 2d with seveal posittioner in each dimension. +# this will get complicated ..... + +import X_X07MB_Pscan as PS +import X_X07MB_lib as PL +imp.reload(PS) # always reload module +imp.reload(PL) # always reload module + +E_start = 445 +E_end = 780 + +N_repeats = 1 # repetitions of each run without moving sample +time_of_scan = 8 +# time in minutes + + +delay = 0.2 +mode = None +offset = None +alpha = None +filename = None + +NoRead=0 + + +def before_pass(): + get_context().dataManager.provider.embeddedAtributes = False + # Called at begining pf scan + print('before_pass') + SC.PerformActions('Pre_Actions') + pars=get_exec_pars() + print('pars.output : ') + print(pars.output) + print('pars.scanPath: ') + print(pars.scanPath) + print('pars.name: (filename) ') + print(pars.name) + # missing + # NEED TO SET path for Moench here +#end before_pass + + +def before_read(): + # Cannot call routine in class in rscan call, need to go via local routine + #print('before_read') + # SC.DetectorActions() excecutes all standard action as defied in GUI + SC.PerformActions('Detector_Actions') + #print('.... done before_read ' ) + + # alternativly use caput here explicitly... + # if needed +#end before read + +def after_read(rec,scan): + print('ENTER after_read .................' ) + # Called after reading + # calculate default dead time corrections and writ to file + SC.after_read_dtc(rec,scan) + print('.... done after_read ' ) + return +#end after_read init + +def after_pass(): + # Called after scan + print('after_pass') + + SC.PerformActions('Post_Actions') + print('................ done after_pass') +#end after pass + + +def before_region(index,scan): + print (index) + +# make some reset +try: + del SC +except: + SC=0 +#endexept +# originbal tag for data saving +# '{data}/{year}/{month}/{day}/{year}_{month}{day}_{time}_{name}' +# ........... FIrst read the scan +# + + + +# ==================================================== +# +# SCRIPT STARTS HERE +# +# ==================================================== +if NoRead==0: + try: + SD = 0 + + + SD = PS.get_channels('SPECTRA') # READ SCAN DEFINITION FROM GUI USING OLD CODE + + print('returned from PS.get_channels()') + SC=0 + SC=PL.PscanLib(SD,Channel,caput,caputq,caget,cawait,get_exec_pars,create_table,append_table) # create instance of library + + print('... done SC.Create_All_Sensors()') + SD.update({'All_Sensors':[]}) + except: + traceback.print_tb(sys.exc_info()[2]) + raise + # endexcept +# endif +print('dddddddddddddddddddddddddd') +# example add new sensor, similarly add pre and postactions to existing code + +New_Sensors=[] +New_Sensors.append({'channel_name': 'X07MB-ES-MA1:ScanY.RBV' + , 'Subset_1': False + , 'Det_type': 'ScalarDetector' + , 'alias': 'MYSCANY_RBV' + , 'data_type': 'double'}) + +# examples add post action light on + +SD['Post_Actions'].append({'channel_name': 'X07MB-ES1-PP2:VO5' + , 'data_type': 'String' + , 'alias': 'Light_ON' + , 'operation': 'put' + , 'delay' : 0.1 + , 'value' : 5 }) + +# END OF USER INPUT + +# .... add new sensors to list +try: + try: + del AllSensors + except: + AllSensors=0 + #endecsept + All_Sensors = SC.Create_Sensor_List() # Create instance for all sensors + SC.Add_New_Sensors(New_Sensors) # Add user sensors +except: + traceback.print_tb(sys.exc_info()[2]) + raise +# endexcept + +# STRUCTUALR INCONSITENCY NEED TO CREATE List of sensors first +# without making Channel command.... ! +# +# TEST SAVE SCAN DEFINITION...Needs to be before definition +# SD is full GUI definiton of the scan try to save and reread this definiton + +SD.update({'New_Sensors' : New_Sensors}) +f=open('scandef.dat','w') +# Method to save abnd restore full scan definition... +with open('BaseScanDefinition.json', 'w') as fp: + json.dump(SD, fp,ensure_ascii=True) +#endwith +with open('BaseScanDefinition.json', 'r') as dd: + SD_reread=json.load(dd) +# .. this works, reread is unicode not string, but code seems still to work if all entries are in unicode + +# step I: CREATE ALL SENSORS AND STORE IN A LIST +print('++++++++++++++++++++++++++') +AllSensors=0 +try: + # Code for beamline save...... + SavePhoenix=PL.SavePhoenix(Channel,caput,caputq,caget,cawait) # Channel,caput,caputq,caget,cawait) + # SavePhoenix.write_beamline_data().. Works., move to before pass... + + SC.noprint=0 # chose printing from SD on / off + + # Now creat all epic s instances. print('... done SC.Create_All_Sensors()') + SD.update({'All_Sensors':All_Sensors}) + SC.Create_Channels('All_Sensors') + SC.Create_Channels('All_Positioner') + SC.Create_Channels('Detector_Actions') + SC.Create_Channels('Pre_Actions') + SC.Create_Channels('Post_Actions') + SC.Create_Channels('Energy_Scan') +except: + traceback.print_tb(sys.exc_info()[2]) + raise +# endexcept + +# ... create some abbreviations... +All_Sensors = SC.All_Sensors +All_Positioner = SD['All_Positioner'] +Pre_Actions = SD['Pre_Actions'] +Post_Actions = SD['Post_Actions'] +Detector_Actions = SD['Detector_Actions'] +Energy_Scan = SD['Energy_Scan'] + + +#............SOME OUTPUT +#print('----------- All_Positioner ---') +#print(' ') +#print(SD['All_Positioner']) +#print(' ------------ Pre_Action -------- ') +#print(' ') +#print(SD['Pre_Actions']) +#print(' ------------ Post_Action -------- ') +#print(' ') +#print(SD['Post_Actions']) +#print(' ') +#print(' ----------- Detector_Action--------- ') +#print(' ') +#print(SD['Detector_Actions']) +## ............. MISSING CREATE POSTACTIONS:::::: + +# STEP II read the energy position +print('') +print('..................................... positioner Energy ID? readback automatically saved? ') +print('initial energies e_i ',SD['e_i']) +print('final energies e_f ',SD['e_f']) +print('DELTA E e_delta ',SD['e_delta']) +print('DWELL TIME e_n_cycles',SD['e_n_cycles']) +print(SD['Energy_Scan']['Energy_Ranges']) + +#try: +# EnergyRanges,Cycles = SC.PositionerEnergyScan() +#except: +# traceback.print_tb(sys.exc_info()[2]) +# raise +# endexcept nowcall +#print(EnergyRanges,Cycles) + +# STEP II ... read the detector actions + +# Step IV perform the Preaction +#P=SC.DetectorActions() + +print(All_Sensors) +print('Energy_Ranges') +print(SD['Energy_Scan']['Energy_Ranges']) + +pars=get_exec_pars() +print('pars.output') +print(pars.output) +print('pars.scanPath') +print(pars.scanPath) +print(' ') +print('---------------') +print(' ') +print(' CALL SCAN NOW ') +print(' ') + +p=set_exec_pars(name=SD['filename']) + +get_context().dataManager.provider.embeddedAtributes = False + +time.sleep(.2) +print(' -') +print(' -') +print('-----------DATA READ START SCAN ----------------- ') +print(' -') +print(' -') + +TOP_UP=ChannelString('TOPUP_STAT','X07MB-ES-EVR:TOPUP-STAT') +TOP_UP.initialize() + +# make sure that X07MB trigger is on other wise there is no reading of the data + +#ContSample=Channel('X07MB-OP2:START-CSMPL') +#SingleSample=Channel('X07MB-OP2:SMPL') +#ContSample.put('1') +#time.sleep(.2) +#SingleSample.put(1) +#SingleSample.put(0) + +for i_n in range(SD['number_of_executions']): + for i in range(len(All_Positioner[0]['value'])): # loop in number of points + # set all positioner + time.sleep(.2) + print('--------- set next positioner -----------',i) + for j in range(len(All_Positioner)): # set positioner + time.sleep(.2) + print('--------- set positioner -----------',j) + + t0=time.time() + ThisPositioner = All_Positioner[j]['Channel'] + ThisPosition = All_Positioner[j]['value'][i] + print('next,i,j',i,j) + print('name',All_Positioner[j]['channel_name']) + print('value',All_Positioner[j]['value'][i]) + print(time.time()-t0) + # .............. SET NEW POSITIONER + #ThisPositioner.write(ThisPosition) + ThisPositioner.put(ThisPosition) + #ThisPositioner.putq(ThisPosition) # simultaneous walk no waiting.. + print(time.time()-t0) + print('wait .2 seconds') + time.sleep(.2) + + #endfor loop set positioner + # generate filename + + #.......... START TOPUP CHECK + + #while TOP_UP.read() == 'TOPUP-OFF': + # print('wait for next topup') + # time.sleep(0.05) + #end wait for toput + #while TOP_UP.read() == 'TOPUP-ON': + # print('wait to finish top up ') + # time.sleep(0.05) + #end topup + #time.sleep(2) + #end top up check + + for i_repeat in range(N_repeats): + time.sleep(1) + filename=SD['filename']+'_'+All_Positioner[0]['label'][i] + filename=set_exec_pars(name=SD['filename']+'_'+All_Positioner[0]['label'][i]) + pars=get_exec_pars() + + print('') + print('======================================') + print('CHOSEN FILENANME IS') + print(pars.name) + print('====================================') + print('') + # TO DO CHECKL FOR SPECIAL SIGN IN NAMES + time.sleep(1) + + #print('filename this run : ') + #print(pars.name) + + + print('--------------- NEXT CALL TO OTF ----------------') + try: + print('in try') + print('filenname',filename) + print('start') + # make sure that our trigger is set to 'on' + + print('---CALL OTF ----',i_n,i,'\n') + + print(E_start, E_end) + #for i_repeat in range(N_repeats): + time.sleep(1) + + + print('input into otf (before call)') + print(E_start, E_end, time_of_scan) + + + + print('Call OTF') + otf(E_start, E_end, time_of_scan, delay=0.3, mode = None, offset = None, alpha = None, name = filename) + ##endfor + + time.sleep(1) + print('---OTF DONE ----') + + except: + print('exception') + traceback.print_tb(sys.exc_info()[2]) + raise + # END EXecpt + #endfor + #endfor + #endfor +#endfor +print('... scan finished ') diff --git a/script/Users/Thomas/EnergyScan_backup_220822.py b/script/Users/Thomas/EnergyScan_backup_220822.py new file mode 100644 index 0000000..6cd454e --- /dev/null +++ b/script/Users/Thomas/EnergyScan_backup_220822.py @@ -0,0 +1,214 @@ +#Debugging +if get_exec_pars().innerArgs is None: + E1 = 500 + E2 = 600 + + TIME = 5 #min + DELAY = 0.0 #s + MODE = None #'LINEAR' #'CIRC +' + OFFSET = None + NAME = 'Circp' + ALPHA= None #0 + + + +print "\nStart energy scan..." +print E1,"eV ->",E2,"eV,",TIME,"min duration,",DELAY,"sec delay,",str(MODE),(str(ALPHA)+"deg") if (MODE=="LINEAR") else "" + +set_exec_pars(reset=True, name= NAME,open=False) + + + +#Pre-actions + +#wait_beam() # +#wait_id_ok() + +call_mscan=True +move_mono=True # if true, X-Tremeo runs, if false channel defiend under Ch runs + + +if move_mono == True: + set_pol(MODE, ALPHA, OFFSET) + set_energy_ma(float(E1)) + caput(ma_energy_rbv.channelName+".N", 10) # set energy readback averaging to 10 pts +else: + print(' do not move mono ') + + #Ch=Channel('X07MB-ES-MA1:TRZ1.VAL', name="Setpoint", monitored=True) + Ch=ChannelDouble('SETPOINT','X07MB-ES-MA1:TRZ1.VAL') + #Ch_rbv=Channel('X07MB-ES-MA1:TRZ1.RBV', name="Readback",monitored=True) + Ch_rbv=ChannelDouble('X07MB-ES-MA1:TRZ1.RBV','X07MB-ES-MA1:TRZ1.RBV') + Ch_rbv.monitored=True + Ch_rbv.initialize() + Ch.monitored=True + Ch.initialize() + + E0=Ch_rbv.read() + E1=E0 + E2=E0+.1 + print(E0,E1,E2) + #E1=970 + #E2=970 +# endexcept + + +# next +if move_mono == True: + print "Setup OTF" + caput('E1', E1) + caput('E2', E2) + caput('TIME', TIME) + caput('FOLDER', "OTF/" + get_context().setup.expandPath("OTF/{year}_{month}/{date}")) + caput('FILE', NAME) +#endif +time.sleep(max(DELAY, 0.1)) + +#Scan +print "Start OTF" +scan_completed = False + +try: + while True: + if move_mono == True: + caput('START', '1') + else: + print('mono off') + #Ch.putq(E2) # if defin es as channel + Ch.write(E2) # if defines as ChannelDouble + #endif + waiting = True + + + class Time(Readable): + def __init__(self): + self.start = time.time() + def read(self): + return time.time()-self.start + tm = Time() + + class norm_tey(Readable): + def read(self): + return float(ma_cadc1.take())/float(ma_cadc2.take()) + #enddef + #enf class norm_tey + + class norm_diode(Readable): + def read(self): + return float(ma_cadc3.take())/float(ma_cadc2.take()) + #enddef + #enf class + + #class norm_K2_I0(Readable): + # def read(self): + # return float(keith_2.take())/float(keith_3.take()) + # #enddef + ##enf class + + #class norm_keithley(Readable): + # def read(self): + # return float(keith_2.take())/float(keith_1.take()) + # #enddef + ##enf class + + # define channels for PGM paramters + + #ID_ENERY_TAKE=ID_ENERGY.take() + #,ma_mono_m1_rbv,ma_mono_m2_rbv + if move_mono == True: + position=ma_energy_rbv + else: + position=Ch_rbv + + snaps = (id_pol_mode, id_pol_angle,id_pol_offset,PH.ma_exitslit_rbv,ID_OFFSET,ES3_MF1_PRESSURE) #,ES1_userCalc1_T2) + diags = (current.cache) #Must use cache because mscan evensts are called from monitor callback tread (or else async=False). Sensors are automatically handled. + sensors = [position, ma_cadc1, ma_cadc2, ma_cadc3, ma_cadc4, ma_cadc5,norm_tey(), norm_diode()]#,ES1_userCalc1_T2]#, ID_ENERGY,ma_mono_m1_rbv,ma_mono_m2_rbv] + + + + + tm.setAlias("time") + ma_cadc1.setAlias("tey_raw") + ma_cadc2.setAlias("i0") + ma_cadc3.setAlias("diode_raw") + + def monitoring_task(): + global scan_completed + time.sleep(.1) + print('monitoring_task',move_mono) + + if move_mono == True: + print('call wait channel') + wait_channel('START', 'STOP', type = 's') + print('after wait channel') + else: + #wait_channel(Ch_rbv.get_channel_name(), E2, range=0.02) + # something is strang with the waiting and comparing... + # progam explicitly + #wait_channel(Ch_rbv.name, E2, comparator=.02) + while abs(Ch_rbv.read()-E2)>0.02: + print('still waiting',Ch_rbv.read()-E2) + time.sleep(.1) + #print('after while ') + #print('WAIT for ',E2) + #Ch_rbv.waitValueInRange(E2, timeout=None, comparator=0.02) #todo: in next version + #Ch_rbv.waitValueInRange(E2, 0.01, -1) + #endif + + scan_completed = True + print('Scan completed ') + get_exec_pars().currentScan.abort() + print('after abort in monitoring_task') + + + monitoring_future = fork(monitoring_task)[0] + + print("Scanning...\n") + try: + if call_mscan==True: + print('call mscan ') + mscan( position, sensors, -1, None, \ + range="auto",domain_axis=position.name, \ + enabled_plots=["norm_tey", "norm_diode",ma_cadc1, ma_cadc3, ma_cadc2], \ + snaps=snaps, diags=diags) + print('.....mscan done ') + else: + print('-------------------------------------') + print('DO NOT CALL mscan ') + print('-------------------------------------') + #endelse + finally: + if not scan_completed: + print('... cancel monitoring_future..') + monitoring_future.cancel(True) + print('monitoring is done',monitoring_future.isDone()) + print "Finished Energy scan." + if after_sample(): #Repeat if id error and not ABORT_ON_ID_ERROR: + break + +except: #n + if not scan_completed: + print sys.exc_info() + if move_mono == True: + print("Aborting...") + while caget('START') == 'START': + caput('START', '0') + time.sleep(0.1) + raise + #endif +#endexcept +print('-------DONE --------------') +# Finally, if mon is not use +# return to initial position + +if move_mono == False: + time.sleep(1) + print('------- MOVING BACK FINISHED --------------') + Ch.write(E0) + while abs(Ch_rbv.read()-E0)>0.02: + print('Driving motor back ',Ch_rbv.read()-E0) + time.sleep(.1) + + print('------- MOVING BACK FINISHED --------------') + time.sleep(2) +#endif diff --git a/script/Users/Thomas/Run_OTF_MA.py b/script/Users/Thomas/Run_OTF_MA.py index d418cc8..eb2406d 100644 --- a/script/Users/Thomas/Run_OTF_MA.py +++ b/script/Users/Thomas/Run_OTF_MA.py @@ -24,10 +24,10 @@ import X_X07MB_lib as PL imp.reload(PS) # always reload module imp.reload(PL) # always reload module -E_start = 970 -E_end = 975 +E_start = 835 +E_end = 890 -time_of_scan = 1 # time in minutes +time_of_scan = 3 # time in minutes delay = 0.2 mode = None diff --git a/script/Users/Thomas/test:py.py b/script/Users/Thomas/TEBAHO~G.PY similarity index 100% rename from script/Users/Thomas/test:py.py rename to script/Users/Thomas/TEBAHO~G.PY diff --git a/script/test/TestOTF.py b/script/test/TestOTF.py new file mode 100644 index 0000000..585fd94 --- /dev/null +++ b/script/test/TestOTF.py @@ -0,0 +1,6 @@ +START = 1500.0 +END =1550.0 +TIME = 2.0 +NAME = "test_otf" + +otf(START, END, TIME, delay=0.0, mode = None, offset = None, alpha = None, name = NAME) \ No newline at end of file