This commit is contained in:
gac-x07mb
2026-03-02 09:05:57 +01:00
parent 20496ec4a8
commit 67cee074cb
10 changed files with 628 additions and 16 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -1,2 +1,2 @@
#Mon Aug 08 10:01:14 CEST 2022
#Mon Jan 30 11:36:32 CET 2023
FdaBrowser=true

View File

@@ -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

382
script/Run_OTF_MA.py Normal file
View File

@@ -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 ')

View File

@@ -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

View File

@@ -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

6
script/test/TestOTF.py Normal file
View File

@@ -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)