large cleanup, part 1

This commit is contained in:
2023-09-13 17:29:36 +02:00
parent 89a76ee62a
commit ef7007582f
47 changed files with 5106 additions and 1323 deletions

View File

@ -1,293 +0,0 @@
#!/usr/bin/env python
#*-----------------------------------------------------------------------*
#| |
#| Copyright (c) 2014 by Paul Scherrer Institute (http://www.psi.ch) |
#| |
#| Author Thierry Zamofing (thierry.zamofing@psi.ch) |
#*-----------------------------------------------------------------------*
'''
motion procedures for PSSS:
mode:
0: homing
1: calc energy and SPECTRUM_X out of camera arm angle
move CamPosX out of CristBendRot
'''
from __future__ import print_function
from errno import ENETRESET
import logging, sys, os, json
import CaChannel,time
import numpy as np
class PSSS:
def __init__(self, args):
# import pdb; pdb.set_trace()
# sys.exit()
# {'mode': 0, 'stdout': True, 'var': []}
# {'mode': 5, 'stdout': True, 'var': ['SARFE10-PSSS059']}
self.args=args
prefix=self.args.var[0]
prefix=prefix[0:prefix.find('-')+1]
self.prefix=prefix
#print('Prefix='+prefix)
self.pv=dict()
def getPv(self,name):
try:
pv=self.pv[name]
except KeyError:
prefix=self.prefix
pv = CaChannel.CaChannel(prefix+name) ;pv.searchw()
self.pv[name]=pv
return pv
def moveLimit(self,m,val):
self.moveAbs(m,val)
def waitMotionDone(self,m):
s=m+'.DMOV'
pv=self.getPv(s)
sys.stdout.write('wait motion '+s+' ');sys.stdout.flush();
while pv.getw()==0:
sys.stdout.write('.');sys.stdout.flush();
time.sleep(.1)
print('done');
def setPos(self,m,ofs):
pvSET=self.getPv(m+'.SET')
pvVAL=self.getPv(m+'.VAL')
pvSET.putw(1)#Set
print('set ofset to %f'%ofs)
pvVAL.putw(ofs) #set value (without move)
time.sleep(.1) # wait for safety
pvSET.putw(0)#Use
time.sleep(.1) # wait for safety
def moveAbs(self,m,val):
pvVAL=self.getPv(m+'.VAL')
pvVAL.putw(val) #set position and move
def homing(self):
pvNameLst=('PSSS055:MOTOR_ROT_X1',
'PSSS055:MOTOR_X1',
'PSSS055:MOTOR_Y1',
'PSSS055:MOTOR_PROBE',
'PSSS059:MOTOR_X5',
'PSSS059:MOTOR_Y5',
'PSSS059:MOTOR_Z5',
'PSSS059:MOTOR_X3',
'PSSS059:MOTOR_Y3')
pvHOME = self.getPv('PSSS059:HOMING.VAL')
if pvHOME.getw(1) == 1:
print('homing still in progress. abort new procedure')
#return
pvHOME.putw(1)#homing in progress
try:
pvHomr=self.getPv(pvNameLst[0]+'.HOMR')
pvHomr.putw(1)#homing MOTOR_ROT_X1
self.waitMotionDone(pvNameLst[0])
homing=(
(1,200,10,0), # PSSS055:MOTOR_X1 Home on +limit switch to +10mm
(2,10,4.475,2.22), # PSSS055:MOTOR_Y1 Home on +limit switch to +4.475mm
(3,50,0,-9), # PSSS055:MOTOR_PROBE Home on +limit switch to +0mm
(4,80,35,0), # PSSS059:MOTOR_X5 Home on +limit switch to +35mm
(5,30,10,0), # PSSS059:MOTOR_Y5 Home on +limit switch to +10mm
# (6,20,8.9,0), # PSSS059:MOTOR_Z5 Home on +limit switch to +8.9mm Set HLM to 10, LLM to -2mm
(7,30,1,0), # PSSS059:MOTOR_X3 Home on +limit switch to +10mm
(8,30,1,-1.4), # PSSS059:MOTOR_Y3 Home on +limit switch to +10mm
)
for idx,mvLim,setPos,mvPos in homing:
pvName=pvNameLst[idx]
print('homing %s %f %f %f'%(pvName,mvLim,setPos,mvPos))
self.moveLimit(pvName,mvLim)
for idx,mvLim,setPos,mvPos in homing:
pvName=pvNameLst[idx]
self.waitMotionDone(pvName)
self.setPos(pvName,setPos)
time.sleep(2);print ("sleep 2 sec.")
for idx,mvLim,setPos,mvPos in homing:
pvName=pvNameLst[idx]
self.moveAbs(pvName,mvPos)
for idx,mvLim,setPos,mvPos in homing:
pvName=pvNameLst[idx]
self.waitMotionDone(pvName)
except AssertionError as e: #BaseException as e:
print(e)
pvHOME.putw(3)#homing failed
else:
pvHOME.putw(2)#homing done
def set_energy_motor(self,energy2motor,scan=False, rotWait=False):
crystalType=self.getPv('PSSS059:CRYSTAL_SP').getw()
#crystalType=2
#print(crystalType)
#print(type(crystalType))
if crystalType==0: return
# 0 None
# 1 Si(111)R155
# 2 Si(220)R75
# 3 Si(220)R145
# 4 Si(220)R200
# 5 Si(333)R155
#load lut
fnXtlLst=(None,"Si111R155","Si220R75","Si220R145","Si220R200","Si333R155")
#print(__file__)
base=os.path.dirname(__file__)
fn=os.path.join(base,'lut'+fnXtlLst[crystalType]+'.txt')
lut= np.genfromtxt(fn, delimiter='\t',names=True)
#lut
#lut.dtype
#lut[1]['Energy']
#lut['Energy']
#lut=np.genfromtxt(fn, delimiter='\t',skip_header=1)
if energy2motor:
energy =self.getPv('PSSS059:ENERGY').getw()
#energy =6000
gratingType=self.getPv('PSSS055:GRATING_SP').getw()
#gratingType=3
camPosX='CamPosX'
if gratingType in(1,2):camPosX+='_100nm'
elif gratingType==3:camPosX+='_150nm'
elif gratingType==4:camPosX+='_200nm'
camArmRot =np.interp(energy,lut['Energy'],lut['CamArmRot'])
cristBendRot=np.interp(energy,lut['Energy'],lut['CristBendRot'])
camPosX =np.interp(energy,lut['Energy'],lut[camPosX])
evPerPix =np.interp(energy,lut['Energy'],lut['EvPerPix'])
else:
camArmRot=self.getPv('PSSS059:MOTOR_ROT_X4').getw()
idx=~np.isnan(lut['CamArmRot'])
lutCamArmRot=lut['CamArmRot'][idx]
energy =np.interp(camArmRot,lutCamArmRot[::-1],lut['Energy'][idx][::-1])
evPerPix =np.interp(camArmRot,lutCamArmRot[::-1],lut['EvPerPix'][idx][::-1])
#camera: 2560 x 2160
n=2560
i=np.arange(n)-n/2
spctr_x=energy+i*evPerPix
pv=self.getPv('PSSS059:SPECTRUM_X')
pv.putw(spctr_x)
pv=self.getPv('PSSS059:SPECTRUM_Y')
mu=2560./2
sigma=100.
x=np.arange(2560.)
spctr_y= 1000.*np.exp(-( (x-mu)**2 / ( 2.0 * sigma**2 ) ) )
pv.putw(spctr_y)
if energy2motor:
print('energy2motor: camArmRot: %g cristBendRot: %g camPosX:%g evPerPix:%g'%(camArmRot,cristBendRot,camPosX,evPerPix))
pv=self.getPv('PSSS059:MOTOR_ROT_X4')
pv.putw(camArmRot)
pv=self.getPv('PSSS059:MOTOR_ROT_X3')
pv.putw(cristBendRot)
if rotWait == True:
self.waitMotionDone('PSSS059:MOTOR_ROT_X3')
if scan == False: # if True the camera X position will not be changed
pv=self.getPv('PSSS059:MOTOR_X5')
pv.putw(camPosX)
else:
print('motor2energy: energy: %g evPerPix:%g'%(energy,evPerPix))
pv=self.getPv('PSSS059:ENERGY')
pv.putw(energy)
def grating2motor(self):
energy =self.getPv('PSSS059:ENERGY').getw()
gratingType=self.getPv('PSSS055:GRATING_SP').getw()
if gratingType==0:
print('no grating')
girderX=0.
else:
base=os.path.dirname(__file__)
fn=fn=os.path.join(base,'lutGirderXTrans.txt')
lut= np.genfromtxt(fn, delimiter='\t',names=True)
d={1:'100nm',2:'100nm',3:'150nm',4:'200nm'}
print(gratingType)
grtStr=d[gratingType]
girderX =np.interp(energy,lut['Energy'],lut[grtStr])
print("girderX:%g"%(girderX))
pv=self.getPv('PSSS059:MOTOR_X2')
pv.putw(girderX)
if __name__=='__main__':
from optparse import OptionParser, IndentedHelpFormatter
class MyFormatter(IndentedHelpFormatter):
'helper class for formating the OptionParser'
def __init__(self):
IndentedHelpFormatter.__init__(self)
def format_epilog(self, epilog):
if epilog:
return epilog
else:
return ""
def parse_args():
'main command line interpreter function'
(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>3 else sys.argv[0])+' '
exampleCmd=('MYPREFIX',
)
epilog=__doc__+'''
Examples:'''+''.join(map(lambda s:cmd+s, exampleCmd))+'\n '
fmt=MyFormatter()
parser=OptionParser(epilog=epilog, formatter=fmt)
parser.add_option('-m', '--mode', type="int", help='move instead of homing', default=0)
parser.add_option('-s', '--stdout', action="store_true", help='log to stdout instead of file')
(args, other)=parser.parse_args()
#print(args,other)
args.var=other
#args.var=('SARFE10-',)
fn='/afs/psi.ch/intranet/Controls/scratch/'+os.path.basename(__file__)+'_'+os.environ.get('USER')+'.log'
if not args.stdout:
print('output redirected to file:\n'+fn)
stdoutBak=sys.stdout
sys.stdout = open(fn, 'a+')
print('*'*30+'\n'+time.ctime()+': run on host:'+os.environ.get('HOSTNAME'))
print('Args:'+str(args)+' '+str(args.var))
sys.stdout.flush()
psss=PSSS(args)
if args.mode==0:
psss.homing()
elif args.mode==1:
psss.set_energy_motor(energy2motor=True)
elif args.mode==2:
psss.set_energy_motor(energy2motor=False)
elif args.mode==3:
psss.grating2motor()
elif args.mode==4:
psss.set_energy_motor(energy2motor=True, scan=True)
elif args.mode==5:
psss.set_energy_motor(energy2motor=True, scan=True,rotWait=True)
print('PSSS_motion done.')
return
#os.environ['EPICS_CA_ADDR_LIST']='localhost'
#os.environ['EPICS_CA_ADDR_LIST']='172.26.0.255 172.26.2.255 172.26.8.255 172.26.16.255 172.26.24.255 172.26.32.255 172.26.40.255 172.26.110.255 172.26.111.255 172.26.120.255 129.129.242.255 129.129.243.255'
parse_args()

Binary file not shown.

Binary file not shown.

Binary file not shown.

268
acquisition/base.py Normal file
View File

@ -0,0 +1,268 @@
import time
# setup logging
from loguru import logger
def simple_scan():
"""
adjustable: Adjustable names to scan.
n_pulses (int): Number of pulses per step.
filename (str): Name of output file.
"""
scan.scan1D(adjustable, start_pos, end_pos, step_size, n_pulses, filename)
# TODO: make stand work with stand as well, what's the easiest way here?
def simple_acquisition(daq, filename, n_pulses=10, sample="LiTbF4 sample (left)", comment="", parameters="", stand_client=None):
logger.info("Simple acquisition started.")
task = daq.acquire(filename, n_pulses=n_pulses, n_repeat=1, is_scan_step=False, wait=True)
run_number = daq.client.run_number
# fname = task.filenames[0]
# pattern = r"run([0-9]{4})"
# match = re.search(pattern, fname)
# run_number = int(match.groups()[0])
# stand_client.add_row(run_number=run_number)
all_things = {}
all_things["run_number"] = run_number
all_things["time"] = time.asctime()
all_things["topic"] = "Li magnetism"
all_things["sample"] = sample
all_things["comment"] = comment
all_things["parameters"] = parameters
# TODO
# combine with other parameters (spreadsheet overview)
# overviews = {thing.name: thing.get() for thing in overview}
# combined = all_things | overviews
combined = all_things
if stand_client is not None:
stand_client.add_row(**combined)
logger.debug(f"Simple acquisition complete: {combined}")
return run_number
def scan_positions(positions_x, positions_y):
for x in positions_x:
for y in positions_y:
smaract_mini_XYZ.x.mv(x)
smaract_mini_XYZ.y.mv(y)
time.sleep(1)
# while smaract_mini_XYZ.x.is_moving():
# time.sleep(1)
simple_acquisition(
"Speckle scan grid 5",
n_pulses=100,
comment=f"Grid scan 5",
parameters=f"at x={x:.5f}mm, y={y:.5f}mm, OWIS:{OWIS.get():.3f}mm",
)
def minimized_acquisition(daq, run_number=839, n_pulses=100):
if n_pulses > 6000:
logger.warning("DAQ cannot provide data of so many pulses in one request. Aborting.")
return
import cta_lib
repetitions = n_pulses
# this is such an ugly interface...
# anyway: we set the number of repetitions for the CTA
cta.cta_client.set_repetition_config(config={"mode": cta_lib.CtaLib.RepetitionMode.NTIMES, "n": repetitions})
# logger.info(f"CTA start sequence, total runtime approximately {repetitions/10:.1f}s.")
cta.cta_client.start()
time.sleep(1)
start = time.time()
while cta.cta_client.is_running():
print(f"Wait for CTA sequence to finish, {time.time() - start:.0f}s elapsed.")
time.sleep(5)
# Without the wait time the DAQ is returning fewer images than we asked it for
print("Waiting 60s for DAQ pipeline")
time.sleep(60)
CTA_sequence_start_PID = int(PV("SAR-CCTA-ESC:seq0Ctrl-StartedAt-O").get())
logger.info(f"Retrieve images starting from pid {CTA_sequence_start_PID}.")
# n_pulses*10 because of current rate_multiplicator
res = daq.retrieve(
"CTA_pulses",
np.arange(CTA_sequence_start_PID, CTA_sequence_start_PID + n_pulses * 10),
run_number=run_number,
)
logger.debug(res)
def acquire_measured(daq, filename, sample="", comment="", parameters="", repetitions=1, no_CTA=False):
""" Combined acquisition: necessary to create a new run and then start the CTA sequence to
collect data for repetitions x 10 minutes at 10 Hz.
This is all rather brittle and rough but runs OK at the moment.
"""
run_number = daq.client.run_number # get current run number
all_things = {}
all_things["run_number"] = run_number + 1 # but store next one
all_things["time"] = time.asctime()
all_things["topic"] = "Li magnetism"
all_things["sample"] = sample
all_things["comment"] = comment
all_things["parameters"] = parameters
overviews = {thing.name: thing.get() for thing in overview}
combined = all_things | overviews
stand_client.add_row(**combined)
logger.debug(f"Simple acquisition complete: {combined}")
run_number = None # should automatically increase in broker client
logger.info(f"Retrieve images starting from pid {CTA_sequence_start_PID}.")
# n_pulses*10 because of current rate_multiplicator
res = daq.retrieve(
"CTA_pulses",
np.arange(CTA_sequence_start_PID, CTA_sequence_start_PID + n_pulses * 10),
run_number=run_number,
)
logger.debug(res)
def acquire_long(daq, filename, sample="", comment="", parameters="", repetitions=1, no_CTA=False):
""" Combined acquisition: necessary to create a new run and then start the CTA sequence to
collect data for repetitions x 10 minutes at 10 Hz.
This is all rather brittle and rough but runs OK at the moment.
"""
n_pulses = 6000 # 10 minutes, longer is not possible because the DAQ complains. So we split this up.
if no_CTA:
run_number = simple_acquisition(filename, n_pulses=n_pulses, sample=sample, comment=comment, parameters=parameters, daq=daq)
return
# only 10 pulses as a baseline
run_number = simple_acquisition(filename, n_pulses=10, sample=sample, comment=comment, parameters=parameters, daq=daq)
for _ in range(repetitions):
minimized_acquisition(run_number=run_number, n_pulses=n_pulses, daq=daq)
def acquire_long_energy(daq, filename, sample="LiHoF4 sample", comment="", parameters="", repetitions=1):
""" Use acquire long to make an enery scan, every energy is a new run.
"""
energies = np.linspace(8044, 8092, 13)
#energies = np.linspace(8044, 8092, 7)
for i, energy in enumerate(energies):
undulators.set_target_value(energy)
time.sleep(10)
parameters = f'Energy: {energy}eV, multiplicator:{daq.client.config.rate_multiplicator}, steps: {i} of {len(energies)-1}'
acquire_long(filename=f'LiTbF4,energy_scan_energy_{energy}_multiplicator_{daq.client.config.rate_multiplicator}',sample=sample, comment=comment,
parameters=parameters, daq=daq, repetitions=repetitions, no_CTA=True)
# def acquire_long_energy(filename, sample="", comment="", parameters="", daq=slow_daq, repetitions=1):
# """ a brittle energy scan combined with the CTA
# """
# target_values = np.arange(7490, 7540, 2)
# for target in target_values:
# undulators.set_target_value(target)
# time.sleep(10)
# run_number = simple_acquisition(filename, n_pulses=10, sample=sample, comment=comment, parameters=parameters, daq=slow_daq)
# n_pulses = 60 # 1 minute.
# minimized_acquisition(run_number=run_number, n_pulses=n_pulses, daq=slow_daq)
def acquisition_pms(daq, run_number=200):
import cta_lib
cta.cta_client.set_repetition_config(config={"mode": cta_lib.CtaLib.RepetitionMode.NTIMES, "n": 1})
cta.cta_client.start()
time.sleep(1)
start = time.time()
while cta.cta_client.is_running():
print(f"Wait for CTA sequence to finish, {time.time() - start:.0f}s elapsed.")
time.sleep(5)
CTA_sequence_start_PID = int(PV("SAR-CCTA-ESC:seq0Ctrl-StartedAt-O").get())
CTA_sequence_length = int(PV("SAR-CCTA-ESC:seq0Ctrl-Length-I").get())
CTA_sequence_end_PID = CTA_sequence_start_PID + CTA_sequence_length - 1
print("Start PID = ", CTA_sequence_start_PID)
print("End PID = ", CTA_sequence_end_PID)
# Without the wait time the DAQ is returning fewer images than we asked it for
print("Waiting 30s for DAQ pipeline")
time.sleep(30)
logger.info(f"Retrieve images starting from pid {CTA_sequence_start_PID}.")
print(np.arange(CTA_sequence_start_PID, CTA_sequence_end_PID+1))
res = daq.retrieve(
"PuMa_run",
np.arange(CTA_sequence_start_PID, CTA_sequence_end_PID),
run_number=run_number,
)
logger.debug(res)
def acquire_and_pulse(tag="test"):
# empty images because pulse picker is closed here, only for the generation of a new run
task = daq.acquire(tag, n_pulses=1, n_repeat=1, is_scan_step=False, wait=True)
run_number = int(task.filenames[0].split("/")[6][3:])
print(f"new run {run_number} generated.")
acquisition_pms(run_number=run_number)
def acquire_and_pulse_long(tag="test"):
pp_normal(opening='on')
time.sleep(0.1)
# empty images because pulse picker is closed here, only for the generation of a new run
task = daq.acquire(tag, n_pulses=1000, n_repeat=1, is_scan_step=False, wait=True)
run_number = int(task.filenames[0].split("/")[6][3:])
print(f"new run {run_number} generated.")
pp_cta()
time.sleep(0.1)
acquisition_pms(run_number=run_number)

313
beamline/PSSS_motion.py Normal file
View File

@ -0,0 +1,313 @@
#!/usr/bin/env python
# *-----------------------------------------------------------------------*
# | |
# | Copyright (c) 2014 by Paul Scherrer Institute (http://www.psi.ch) |
# | |
# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
# *-----------------------------------------------------------------------*
"""
motion procedures for PSSS:
mode:
0: homing
1: calc energy and SPECTRUM_X out of camera arm angle
move CamPosX out of CristBendRot
"""
from __future__ import print_function
from errno import ENETRESET
import logging, sys, os, json
import CaChannel, time
import numpy as np
class PSSS:
def __init__(self, args):
# import pdb; pdb.set_trace()
# sys.exit()
# {'mode': 0, 'stdout': True, 'var': []}
# {'mode': 5, 'stdout': True, 'var': ['SARFE10-PSSS059']}
self.args = args
prefix = self.args.var[0]
prefix = prefix[0 : prefix.find("-") + 1]
self.prefix = prefix
# print('Prefix='+prefix)
self.pv = dict()
def getPv(self, name):
try:
pv = self.pv[name]
except KeyError:
prefix = self.prefix
pv = CaChannel.CaChannel(prefix + name)
pv.searchw()
self.pv[name] = pv
return pv
def moveLimit(self, m, val):
self.moveAbs(m, val)
def waitMotionDone(self, m):
s = m + ".DMOV"
pv = self.getPv(s)
sys.stdout.write("wait motion " + s + " ")
sys.stdout.flush()
while pv.getw() == 0:
sys.stdout.write(".")
sys.stdout.flush()
time.sleep(0.1)
print("done")
def setPos(self, m, ofs):
pvSET = self.getPv(m + ".SET")
pvVAL = self.getPv(m + ".VAL")
pvSET.putw(1) # Set
print("set ofset to %f" % ofs)
pvVAL.putw(ofs) # set value (without move)
time.sleep(0.1) # wait for safety
pvSET.putw(0) # Use
time.sleep(0.1) # wait for safety
def moveAbs(self, m, val):
pvVAL = self.getPv(m + ".VAL")
pvVAL.putw(val) # set position and move
def homing(self):
pvNameLst = (
"PSSS055:MOTOR_ROT_X1",
"PSSS055:MOTOR_X1",
"PSSS055:MOTOR_Y1",
"PSSS055:MOTOR_PROBE",
"PSSS059:MOTOR_X5",
"PSSS059:MOTOR_Y5",
"PSSS059:MOTOR_Z5",
"PSSS059:MOTOR_X3",
"PSSS059:MOTOR_Y3",
)
pvHOME = self.getPv("PSSS059:HOMING.VAL")
if pvHOME.getw(1) == 1:
print("homing still in progress. abort new procedure")
# return
pvHOME.putw(1) # homing in progress
try:
pvHomr = self.getPv(pvNameLst[0] + ".HOMR")
pvHomr.putw(1) # homing MOTOR_ROT_X1
self.waitMotionDone(pvNameLst[0])
homing = (
(1, 200, 10, 0), # PSSS055:MOTOR_X1 Home on +limit switch to +10mm
(2, 10, 4.475, 2.22), # PSSS055:MOTOR_Y1 Home on +limit switch to +4.475mm
(3, 50, 0, -9), # PSSS055:MOTOR_PROBE Home on +limit switch to +0mm
(4, 80, 35, 0), # PSSS059:MOTOR_X5 Home on +limit switch to +35mm
(5, 30, 10, 0), # PSSS059:MOTOR_Y5 Home on +limit switch to +10mm
# (6,20,8.9,0), # PSSS059:MOTOR_Z5 Home on +limit switch to +8.9mm Set HLM to 10, LLM to -2mm
(7, 30, 1, 0), # PSSS059:MOTOR_X3 Home on +limit switch to +10mm
(8, 30, 1, -1.4), # PSSS059:MOTOR_Y3 Home on +limit switch to +10mm
)
for idx, mvLim, setPos, mvPos in homing:
pvName = pvNameLst[idx]
print("homing %s %f %f %f" % (pvName, mvLim, setPos, mvPos))
self.moveLimit(pvName, mvLim)
for idx, mvLim, setPos, mvPos in homing:
pvName = pvNameLst[idx]
self.waitMotionDone(pvName)
self.setPos(pvName, setPos)
time.sleep(2)
print("sleep 2 sec.")
for idx, mvLim, setPos, mvPos in homing:
pvName = pvNameLst[idx]
self.moveAbs(pvName, mvPos)
for idx, mvLim, setPos, mvPos in homing:
pvName = pvNameLst[idx]
self.waitMotionDone(pvName)
except AssertionError as e: # BaseException as e:
print(e)
pvHOME.putw(3) # homing failed
else:
pvHOME.putw(2) # homing done
def set_energy_motor(self, energy2motor, scan=False, rotWait=False):
crystalType = self.getPv("PSSS059:CRYSTAL_SP").getw()
# crystalType=2
# print(crystalType)
# print(type(crystalType))
if crystalType == 0:
return
# 0 None
# 1 Si(111)R155
# 2 Si(220)R75
# 3 Si(220)R145
# 4 Si(220)R200
# 5 Si(333)R155
# load lut
fnXtlLst = (None, "Si111R155", "Si220R75", "Si220R145", "Si220R200", "Si333R155")
# print(__file__)
base = os.path.dirname(__file__)
fn = os.path.join(base, "lut" + fnXtlLst[crystalType] + ".txt")
lut = np.genfromtxt(fn, delimiter="\t", names=True)
# lut
# lut.dtype
# lut[1]['Energy']
# lut['Energy']
# lut=np.genfromtxt(fn, delimiter='\t',skip_header=1)
if energy2motor:
energy = self.getPv("PSSS059:ENERGY").getw()
# energy =6000
gratingType = self.getPv("PSSS055:GRATING_SP").getw()
# gratingType=3
camPosX = "CamPosX"
if gratingType in (1, 2):
camPosX += "_100nm"
elif gratingType == 3:
camPosX += "_150nm"
elif gratingType == 4:
camPosX += "_200nm"
camArmRot = np.interp(energy, lut["Energy"], lut["CamArmRot"])
cristBendRot = np.interp(energy, lut["Energy"], lut["CristBendRot"])
camPosX = np.interp(energy, lut["Energy"], lut[camPosX])
evPerPix = np.interp(energy, lut["Energy"], lut["EvPerPix"])
else:
camArmRot = self.getPv("PSSS059:MOTOR_ROT_X4").getw()
idx = ~np.isnan(lut["CamArmRot"])
lutCamArmRot = lut["CamArmRot"][idx]
energy = np.interp(camArmRot, lutCamArmRot[::-1], lut["Energy"][idx][::-1])
evPerPix = np.interp(camArmRot, lutCamArmRot[::-1], lut["EvPerPix"][idx][::-1])
# camera: 2560 x 2160
n = 2560
i = np.arange(n) - n / 2
spctr_x = energy + i * evPerPix
pv = self.getPv("PSSS059:SPECTRUM_X")
pv.putw(spctr_x)
pv = self.getPv("PSSS059:SPECTRUM_Y")
mu = 2560.0 / 2
sigma = 100.0
x = np.arange(2560.0)
spctr_y = 1000.0 * np.exp(-((x - mu) ** 2 / (2.0 * sigma**2)))
pv.putw(spctr_y)
if energy2motor:
print(
"energy2motor: camArmRot: %g cristBendRot: %g camPosX:%g evPerPix:%g"
% (camArmRot, cristBendRot, camPosX, evPerPix)
)
pv = self.getPv("PSSS059:MOTOR_ROT_X4")
pv.putw(camArmRot)
pv = self.getPv("PSSS059:MOTOR_ROT_X3")
pv.putw(cristBendRot)
if rotWait == True:
self.waitMotionDone("PSSS059:MOTOR_ROT_X3")
if scan == False: # if True the camera X position will not be changed
pv = self.getPv("PSSS059:MOTOR_X5")
pv.putw(camPosX)
else:
print("motor2energy: energy: %g evPerPix:%g" % (energy, evPerPix))
pv = self.getPv("PSSS059:ENERGY")
pv.putw(energy)
def grating2motor(self):
energy = self.getPv("PSSS059:ENERGY").getw()
gratingType = self.getPv("PSSS055:GRATING_SP").getw()
if gratingType == 0:
print("no grating")
girderX = 0.0
else:
base = os.path.dirname(__file__)
fn = fn = os.path.join(base, "lutGirderXTrans.txt")
lut = np.genfromtxt(fn, delimiter="\t", names=True)
d = {1: "100nm", 2: "100nm", 3: "150nm", 4: "200nm"}
print(gratingType)
grtStr = d[gratingType]
girderX = np.interp(energy, lut["Energy"], lut[grtStr])
print("girderX:%g" % (girderX))
pv = self.getPv("PSSS059:MOTOR_X2")
pv.putw(girderX)
if __name__ == "__main__":
from optparse import OptionParser, IndentedHelpFormatter
class MyFormatter(IndentedHelpFormatter):
"helper class for formating the OptionParser"
def __init__(self):
IndentedHelpFormatter.__init__(self)
def format_epilog(self, epilog):
if epilog:
return epilog
else:
return ""
def parse_args():
"main command line interpreter function"
(h, t) = os.path.split(sys.argv[0])
cmd = "\n " + (t if len(h) > 3 else sys.argv[0]) + " "
exampleCmd = ("MYPREFIX",)
epilog = (
__doc__
+ """
Examples:"""
+ "".join(map(lambda s: cmd + s, exampleCmd))
+ "\n "
)
fmt = MyFormatter()
parser = OptionParser(epilog=epilog, formatter=fmt)
parser.add_option("-m", "--mode", type="int", help="move instead of homing", default=0)
parser.add_option("-s", "--stdout", action="store_true", help="log to stdout instead of file")
(args, other) = parser.parse_args()
# print(args,other)
args.var = other
# args.var=('SARFE10-',)
fn = (
"/afs/psi.ch/intranet/Controls/scratch/"
+ os.path.basename(__file__)
+ "_"
+ os.environ.get("USER")
+ ".log"
)
if not args.stdout:
print("output redirected to file:\n" + fn)
stdoutBak = sys.stdout
sys.stdout = open(fn, "a+")
print("*" * 30 + "\n" + time.ctime() + ": run on host:" + os.environ.get("HOSTNAME"))
print("Args:" + str(args) + " " + str(args.var))
sys.stdout.flush()
psss = PSSS(args)
if args.mode == 0:
psss.homing()
elif args.mode == 1:
psss.set_energy_motor(energy2motor=True)
elif args.mode == 2:
psss.set_energy_motor(energy2motor=False)
elif args.mode == 3:
psss.grating2motor()
elif args.mode == 4:
psss.set_energy_motor(energy2motor=True, scan=True)
elif args.mode == 5:
psss.set_energy_motor(energy2motor=True, scan=True, rotWait=True)
print("PSSS_motion done.")
return
# os.environ['EPICS_CA_ADDR_LIST']='localhost'
# os.environ['EPICS_CA_ADDR_LIST']='172.26.0.255 172.26.2.255 172.26.8.255 172.26.16.255 172.26.24.255 172.26.32.255 172.26.40.255 172.26.110.255 172.26.111.255 172.26.120.255 129.129.242.255 129.129.243.255'
parse_args()

85
beamline/bernina_mono.py Normal file
View File

@ -0,0 +1,85 @@
from types import SimpleNamespace
from time import sleep
import numpy as np
from slic.core.adjustable import Adjustable, PVAdjustable, PVEnumAdjustable
from slic.core.device import Device
from slic.utils.hastyepics import get_pv as PV
from slic.devices.general.motor import Motor
class BerninaMono(Device):
def __init__(self, ID, name="Bernina DCM", **kwargs):
super().__init__(ID, name=name, **kwargs)
self.theta = Motor(ID + ":RX12")
self.x = Motor(ID + ":TX12")
self.gap = Motor(ID + ":T2")
self.roll1 = Motor(ID + ":RZ1")
self.roll2 = Motor(ID + ":RZ2")
self.pitch2 = Motor(ID + ":RX2")
self.energy = DoubleCrystalMonoEnergy(ID, name=name)
class DoubleCrystalMonoEnergy(Adjustable):
def __init__(self, ID, name=None):
self.wait_time = 0.1
pvname_setvalue = "SAROP21-ARAMIS:ENERGY_SP"
pvname_readback = "SAROP21-ARAMIS:ENERGY"
pvname_moving = "SAROP21-ODCM098:MOVING"
pvname_stop = "SAROP21-ODCM098:STOP.PROC"
pv_setvalue = PV(pvname_setvalue)
pv_readback = PV(pvname_readback)
pv_moving = PV(pvname_moving)
pv_stop = PV(pvname_stop)
units = pv_readback.units
super().__init__(ID, name=name, units=units)
self.pvnames = SimpleNamespace(
setvalue = pvname_setvalue,
readback = pvname_readback,
moving = pvname_moving,
stop = pvname_stop
)
self.pvs = SimpleNamespace(
setvalue = pv_setvalue,
readback = pv_readback,
moving = pv_moving,
stop = pv_stop
)
def get_current_value(self):
return self.pvs.readback.get()
def set_current_value(self, value):
self.pvs.setvalue.put(value)
sleep(3)
def set_target_value(self, value):
self.set_current_value(value)
# while abs(self.wait_for_valid_value() - value) > accuracy:
while self.is_moving():
sleep(self.wait_time)
def wait_for_valid_value(self):
val = np.nan
while not np.isfinite(val):
val = self.get_current_value()
return val
def is_moving(self):
moving = self.pvs.moving.get()
return bool(moving)
def stop(self):
self.pvs.stop.put(1)

View File

@ -5,80 +5,87 @@ from epics import PV
from logzero import logger as log
from slic.core.adjustable import Adjustable, PVAdjustable, PVEnumAdjustable
from slic.core.scanner.scanbackend import wait_for_all #, stop_all
from slic.core.scanner.scanbackend import wait_for_all # , stop_all
import subprocess
UND_NAME_FMT = "SARUN{:02}-UIND030"
N_UND_CHIC = None
N_UNDS = list(range(3, 15+1))
#N_UNDS.remove(N_UND_CHIC) # does not exist
N_UNDS = list(range(3, 15 + 1))
# N_UNDS.remove(N_UND_CHIC) # does not exist
# from Alvra mono calibration
# energy_offset = 20.37839
# energy_offset = 20.37839
# Cristallina without calibration
energy_offset = 26
energy_offset = 0
# move the PSSS motor according to the energy
# TODO: improve this hack
PSSS_MOVE = False
PSSS_MOVE = True
def set_PSSS_energy(energy : float):
""" When scanning the energy with the undulator we
adjust the spectrometer to follow.
def set_PSSS_energy(energy: float):
"""When scanning the energy with the undulator we
adjust the spectrometer to follow.
"""
energy = energy - energy_offset
print(f"Adjusting PSSS to {energy}")
PSSS_energy_PV_name = 'SARFE10-PSSS059:ENERGY'
PSSS_energy_PV_name = "SARFE10-PSSS059:ENERGY"
PSSS_energy_PV = PV(PSSS_energy_PV_name)
PSSS_energy_PV.put(energy, wait=True)
ret = subprocess.run(["python", "/sf/photo/src/PSSS_motor/qt/PSSS_motion.py", "-s", "-m5", "SARFE10-PSSS059"])
sleep(2)
if ret.returncode != 0:
log.warning("WARNING: PSSS adjustment failed.")
else:
print("Finished adjusting PSSS.")
class Undulators(Adjustable):
"""
for n_und_ref=None (default), the reference undulator currently used by the machine will be used
"""
def __init__(self, n_unds=N_UNDS, n_und_ref=None, scaled=True, ID="ARAMIS_UNDULATORS", name="Aramis Undulators", units="eV"):
# # don't allow setting these since there's no chic :)
# chic_fudge_offset = 0
# adjust_chic = False
def __init__(
self, n_unds=N_UNDS, n_und_ref=None, scaled=True, ID="ARAMIS_UNDULATORS", name="Aramis Undulators", units="eV"
):
# # don't allow setting these since there's no chic :)
# chic_fudge_offset = 0
# adjust_chic = False
super().__init__(ID, name=name, units=units)
machine_n_und_ref = get_machine_n_und_ref()
if n_und_ref is None:
if machine_n_und_ref is None:
raise ValueError(f"could not read reference undulator currently used by the machine, please specify n_und_ref")
raise ValueError(
f"could not read reference undulator currently used by the machine, please specify n_und_ref"
)
n_und_ref = machine_n_und_ref
if n_und_ref != machine_n_und_ref:
log.warning(f"the chosen reference undulator ({n_und_ref}) is not the reference undulator currently used by the machine ({machine_n_und_ref})")
log.warning(
f"the chosen reference undulator ({n_und_ref}) is not the reference undulator currently used by the machine ({machine_n_und_ref})"
)
n_unds = list(n_unds)
if N_UND_CHIC in n_unds:
log.warning(f"the CHIC ({N_UND_CHIC}) is in the list of active undulators: {n_unds}, and will be ignored/removed")
log.warning(
f"the CHIC ({N_UND_CHIC}) is in the list of active undulators: {n_unds}, and will be ignored/removed"
)
n_unds.remove(N_UND_CHIC)
if n_und_ref not in n_unds:
raise ValueError(f"the reference undulator ({n_und_ref}) is not in the list of active undulators: {n_unds}")
self.n_unds = n_unds
self.n_und_ref = n_und_ref
@ -86,11 +93,10 @@ class Undulators(Adjustable):
self.und_name_cal = und_name_cal = UND_NAME_FMT.format(n_und_ref)
self.adjs = {name: Undulator(name) for name in und_names}
# self.chic = CHIC(chic_fudge_offset, name, units)
# self.phases = Phases(n_unds)
# self.chic = CHIC(chic_fudge_offset, name, units)
# self.phases = Phases(n_unds)
# self.adjust_chic = adjust_chic
# self.adjust_chic = adjust_chic
self.scaled = scaled
self.convert = ConverterEK()
@ -98,8 +104,6 @@ class Undulators(Adjustable):
a = self.adjs[und_name_cal]
self.scale = ScalerEK(a)
def set_target_value(self, value, hold=False):
value = value + energy_offset
k = self.convert.K(value)
@ -133,32 +137,32 @@ class Undulators(Adjustable):
tasks.append(t)
wait_for_all(tasks)
# # make sure new K values have been written TODO: needed?
# sleep(2) # check if this can be shortened back to 0.5
# # make sure new K values have been written TODO: needed?
# sleep(2) # check if this can be shortened back to 0.5
# # switching on radial motors ...
# wait_for_all([
# a.adj_radial_on.set_target_value(1, hold=False) for a in self.adjs.values()
# ])
# # switching on radial motors ...
# wait_for_all([
# a.adj_radial_on.set_target_value(1, hold=False) for a in self.adjs.values()
# ])
# # press a few times
# for _ in range(3):
# # ... and pushing go to ensure proper movements
# wait_for_all([
# a.adj_radial_go.set_target_value(1, hold=False) for a in self.adjs.values()
# ])
# sleep(0.2)
# # press a few times
# for _ in range(3):
# # ... and pushing go to ensure proper movements
# wait_for_all([
# a.adj_radial_go.set_target_value(1, hold=False) for a in self.adjs.values()
# ])
# sleep(0.2)
# # make sure the undulators finished moving TODO: needed?
# sleep(5)
# # make sure the undulators finished moving TODO: needed?
# sleep(5)
# if self.adjust_chic:
# print("CHIC adjustment follows")
## self.chic.set_target_value(value, hold=False).wait() #TODO: test whether an additional sleep is needed
# self.phases.set(value)
# print("CHIC adjustment done")
# else:
# print("CHIC adjustment skipped")
# if self.adjust_chic:
# print("CHIC adjustment follows")
## self.chic.set_target_value(value, hold=False).wait() #TODO: test whether an additional sleep is needed
# self.phases.set(value)
# print("CHIC adjustment done")
# else:
# print("CHIC adjustment skipped")
# make sure the undulators and phases finished moving TODO: needed?
sleep(5)
@ -170,60 +174,61 @@ class Undulators(Adjustable):
return self._as_task(change, hold=hold)
def get_current_value(self):
n = self.und_name_cal
a = self.adjs[n]
k = a.get_current_value()
energy = self.convert.E(k) - energy_offset
# all_ks = [a.get_current_value() for a in self.adjs.values()]
# checks = np.isclose(all_ks, k, rtol=0, atol=0.001)
# if not all(checks):
# print(f"Warning: Ks are not all close to {k}:")
# for name, k, chk in zip(self.adjs.keys(), all_ks, checks):
# if not chk:
# print(name, k)
return energy # if we need to fudge the number to match the mono, do it here!
# all_ks = [a.get_current_value() for a in self.adjs.values()]
# checks = np.isclose(all_ks, k, rtol=0, atol=0.001)
# if not all(checks):
# print(f"Warning: Ks are not all close to {k}:")
# for name, k, chk in zip(self.adjs.keys(), all_ks, checks):
# if not chk:
# print(name, k)
return energy # if we need to fudge the number to match the mono, do it here!
def is_moving(self):
return any(a.is_moving() for a in self.adjs)
class Undulator(PVAdjustable):
def __init__(self, name, accuracy=0.0005):
pvname_setvalue = name + ":K_SET"
pvname_readback = pvname_setvalue # name + ":K_READ" #TODO: there are no readback values?
super().__init__(pvname_setvalue, pvname_readback=pvname_readback, accuracy=accuracy, active_move=True, name=name, internal=True)
pvname_readback = pvname_setvalue # name + ":K_READ" #TODO: there are no readback values?
super().__init__(
pvname_setvalue,
pvname_readback=pvname_readback,
accuracy=accuracy,
active_move=True,
name=name,
internal=True,
)
self.adj_energy = PVAdjustable(name + ":FELPHOTENE", internal=True)
# self.adj_radial_on = PVAdjustable(name + ":RADIAL-ON", internal=True) #TODO: do not exist
# self.adj_radial_go = PVAdjustable(name + ":RADIAL-GO", internal=True) #TODO: do not exist
# self.adj_radial_on_proc = PVAdjustable(name + ":RADIAL-ON.PROC", internal=True)
# self.adj_radial_go_proc = PVAdjustable(name + ":RADIAL-GO.PROC", internal=True)
# self.adj_radial_on = PVAdjustable(name + ":RADIAL-ON", internal=True) #TODO: do not exist
# self.adj_radial_go = PVAdjustable(name + ":RADIAL-GO", internal=True) #TODO: do not exist
# self.adj_radial_on_proc = PVAdjustable(name + ":RADIAL-ON.PROC", internal=True)
# self.adj_radial_go_proc = PVAdjustable(name + ":RADIAL-GO.PROC", internal=True)
@property
def energy(self):
return self.adj_energy.get_current_value() * 1000
class ConverterEK:
h = 4.135667696e-15 # eV * s
c = 299792458 # m / s
lambda_u = 15e-3 # m
const = 2 * h * c / lambda_u # eV
h = 4.135667696e-15 # eV * s
c = 299792458 # m / s
lambda_u = 15e-3 # m
const = 2 * h * c / lambda_u # eV
electron_rest_energy = 0.51099895 # MeV
electron_rest_energy = 0.51099895 # MeV
# was: pvname_electron_energy="SATCL01-MBND100:P-READ"
# was: pvname_electron_energy="SATCB01:ENE-FILT-OP"
def __init__(self, pvname_electron_energy="SARCL02-MBND100:P-READ"): #S30CB13:ENE-FILT-OP
def __init__(self, pvname_electron_energy="SARCL02-MBND100:P-READ"): # S30CB13:ENE-FILT-OP
self.pv_electron_energy = PV(pvname_electron_energy)
def K(self, energy):
@ -245,9 +250,7 @@ class ConverterEK:
return gamma**2
class ScalerEK:
def __init__(self, und_reference):
self.und = und_reference
@ -261,8 +264,7 @@ class ScalerEK:
return np.sqrt(K_target_squared)
#class CHIC(PVAdjustable):
# class CHIC(PVAdjustable):
#
# def __init__(self, fudge_offset, name, units):
# self.fudge_offset = fudge_offset
@ -294,10 +296,7 @@ class ScalerEK:
# return super().get_current_value() * 1000
#class TwoColorChicane(PVAdjustable):
# class TwoColorChicane(PVAdjustable):
#
# def __init__(self, name):#, t0=0):
## self.t0 = t0
@ -311,10 +310,7 @@ class ScalerEK:
## return super().get_current_value()
#class Phases:
# class Phases:
#
# def __init__(self, n_unds=N_UNDS):
# # 22 does not have a chicane
@ -357,10 +353,7 @@ class ScalerEK:
## pv_fixed_energy.put(current_state) # reset to original state
#class Phases:
# class Phases:
# def __init__(self, n_unds=N_UNDS):
# # 22 does not have a chicane
@ -394,9 +387,6 @@ class ScalerEK:
# ])
def get_machine_n_und_ref():
res = PVEnumAdjustable("SARUN:REF-UND").get()
if not res.startswith("SARUN"):
@ -408,8 +398,3 @@ def get_machine_n_und_ref():
except ValueError:
return None
return res

View File

@ -7,17 +7,17 @@
# TODO: JF settings regarding raw conversion, compression, etc.
detectors = [
# "JF16T03V01",
"JF16T03V01",
]
camera_channels = [
# "SARES30-CAMS156-PCO1:FPICTURE", # PCO edge camera for the wavefront analysis (from Alvra)
# "SARES30-CAMS156-SMX-OAV:FPICTURE", # SwissMX OAV camera picture
"SARES30-CAMS156-XE:FPICTURE", # X-ray eye
# "SARES30-CAMS156-XE:FPICTURE", # X-ray eye
]
####################
# Machine gas intensity monitor
# Machine gas intensity monitor
channels_gas_monitor = [
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG",
# "SARFE10-PBPG050:SLOW-X",
@ -25,7 +25,7 @@ channels_gas_monitor = [
"SARFE10-PBIG050-EVR0:CALCI", # good for correlations with total beam intensity
"SARFE10-PBPG050:HAMP-INTENSITY-CAL",
]
# RF phases and amplitudes
# RF phases and amplitudes
channels_RF = [
"SINSB01-RLLE-DSP:PHASE-VS",
"SINSB02-RLLE-DSP:PHASE-VS",
@ -96,7 +96,7 @@ channels_RF = [
"S30CB14-RLLE-DSP:AMPLT-VS",
]
channels_Xeye = ['SARES30-CAMS156-XE:intensity']
channels_Xeye = ["SARES30-CAMS156-XE:intensity"]
######################
# PBPS053
@ -108,7 +108,7 @@ channels_PBPS053 = [
####################
# PSSS059
channels_PSSS059=[
channels_PSSS059 = [
"SARFE10-PSSS059:FIT-COM",
"SARFE10-PSSS059:FIT-FWHM",
"SARFE10-PSSS059:FIT-RES",
@ -119,19 +119,21 @@ channels_PSSS059=[
"SARFE10-PSSS059:SPECTRUM_Y_SUM",
"SARFE10-PSSS059:SPECTRUM_X",
"SARFE10-PSSS059:SPECTRUM_Y",
#"SARFE10-PSSS059:FPICTURE",
"SARFE10-PSSS059:FIT_ERR",
# "SARFE10-PSSS059:FPICTURE",
"SARFE10-PSSS059:processing_parameters",
"SARFE10-PSSS059:SPECTRUM_AVG_CENTER",
"SARFE10-PSSS059:SPECTRUM_AVG_FWHM",
"SARFE10-PSSS059:SPECTRUM_AVG_Y",
]
###################################
## Bernina channels
# Beam position monitor PBPS113
channels_Bernina=[
#"SAROP21-PBPS103:INTENSITY",
channels_Bernina = [
"SAROP21-PBPS103:INTENSITY",
"SAROP21-PBPS103:XPOS",
"SAROP21-PBPS103:YPOS",
"SAROP21-PPRM113:FPICTURE",
"SAROP21-PPRM113:intensity",
"SAROP21-PPRM113:x_fit_mean",
"SAROP21-PPRM113:y_fit_mean",
]
###################################
# Beam position monitor PBPS113
@ -142,7 +144,6 @@ channels_PBPS113 = [
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD4",
"SAROP31-PBPS113:XPOS",
"SAROP31-PBPS113:YPOS",
]
@ -190,6 +191,11 @@ channels_PPRM113 = [
###########################
# Beam position monitor PBPS149
# "SARES30-CAMS156-PCO1:FPICTURE", # PCO edge camera for the wavefront analysis (from Alvra)
# "SARES30-CAMS156-SMX-OAV:FPIC
###########################
# Beam position monitor
channels_PBPS149 = [
"SAROP31-PBPS149:INTENSITY",
"SAROP31-PBPS149:INTENSITY_UJ",
@ -197,28 +203,9 @@ channels_PBPS149 = [
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD4",
"SAROP31-PBPS149:XPOS",
"SAROP31-PBPS149:YPOS",
]
channels_PBPS149_waveforms = [
"SAROP31-PBPS149:Lnk9Ch0-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch1-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch2-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch3-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch4-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch5-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch6-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch7-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch8-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch9-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch10-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch11-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch12-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch13-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch14-WF-DATA",
"SAROP31-PBPS149:Lnk9Ch15-WF-DATA",
]
#######################
# Profile monitor PPRM150 (from _proc process)
@ -246,43 +233,56 @@ channels_PPRM150 = [
#######################
# Cristallina event reciever
channels_EVR = [
'SAR-CVME-TIFALL6:EvtSet',
"SAR-CVME-TIFALL6:EvtSet",
]
#######################
# Digitizer
channels_digitizer =[
channels_digitizer = [
"SARES30-LTIM01-EVR0:DUMMY_PV1_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV2_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV3_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV4_NBS",
"SARES30-LSCP1-FNS:CH0:VAL_GET", # Signal-Background
"SARES30-LSCP1-CRISTA1:CH0:1", # Waveform signal
"SARES30-LSCP1-CRISTA1:CH2:1", # Waveform trigger
"SARES30-LTIM01-EVR0:CALCI", # Calculated intensity
"SARES30-LSCP1-FNS:CH0:VAL_GET", # Signal-Background
"SARES30-LSCP1-CRISTA1:CH0:1", # Waveform signal
"SARES30-LSCP1-CRISTA1:CH2:1", # Waveform trigger
"SARES30-LTIM01-EVR0:CALCI", # Calculated intensity
]
#######################
# Other BS channels that we sometimes use
channels_other = [
]
channels_other = []
bs_channels = (
camera_channels
+ channels_gas_monitor
+ channels_RF
+ channels_Xeye
# + channels_RF
# + channels_Xeye
+ channels_PBPS053
+ channels_PSSS059
#+ channels_Bernina
+ channels_PBPS113
# + channels_PBPS113_waveforms
+ channels_PPRM113
# + channels_PPRM113
+ channels_PBPS149
# + channels_PBPS149_waveforms
+ channels_PPRM150
# + channels_PPRM150
+ channels_EVR
# + channels_digitizer
# + channels_other
)
bs_channels_OAPU107_scan = (
channels_gas_monitor
+ channels_PBPS053
+ channels_PSSS059
+ channels_PBPS113
+ channels_PPRM113
)
bs_channels_pbps_snapshot = (
channels_gas_monitor
+ channels_PBPS053
+ channels_PSSS059
+ channels_PBPS113
+ channels_PBPS149
)

259
channels/channels_copy.py Normal file
View File

@ -0,0 +1,259 @@
# Channels at Cristallina endstation
##########################################################################################################
# BS channels
# TODO: JF settings regarding raw conversion, compression, etc.
detectors = [
# "JF16T03V01",
]
####################
channels_gas_monitor = [
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG",
"SARFE10-PBPG050:SLOW-X",
"SARFE10-PBPG050:SLOW-Y",
"SARFE10-PBIG050-EVR0:CALCI", # good for correlations with total beam intensity
"SARFE10-PBPG050:HAMP-INTENSITY-CAL",
]
######################
### PCO edge camera for the wavefront analysis
channels_PCO = [
"SARES30-CAMS156-PCO1:FPICTURE",
]
######################
### SwissMX OAV camera picture
channels_OAV = [] # "SARES30-CAMS156-SMX-OAV:FPICTURE",
######################
### PBPS053
channels_PBPS053 = [
"SARFE10-PBPS053:INTENSITY",
"SARFE10-PBPS053:XPOS",
"SARFE10-PBPS053:YPOS",
]
###################################
### Beam position monitor PBPS113
channels_PBPS113 = [
"SAROP31-PBPS113:INTENSITY",
"SAROP31-PBPS113:INTENSITY_UJ",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD0",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD4",
"SAROP31-PBPS113:XPOS",
"SAROP31-PBPS113:YPOS",
]
####################
## PSS059
channels_pss059 = [
# "SARFE10-PSSS059:FPICTURE", # full pictures only when really needed
"SARFE10-PSSS059:SPECTRUM_X",
"SARFE10-PSSS059:SPECTRUM_Y",
"SARFE10-PSSS059:SPECTRUM_CENTER",
"SARFE10-PSSS059:SPECTRUM_COM",
"SARFE10-PSSS059:SPECTRUM_FWHM",
"SARFE10-PSSS059:SPECTRUM_STD",
"SARFE10-PSSS059:FIT_ERR",
"SARFE10-PSSS059:processing_parameters",
# SARFE10-PSSS059:SPECTRUM_AVG_CENTER
# SARFE10-PSSS059:SPECTRUM_AVG_FWHM
# SARFE10-PSSS059:SPECTRUM_AVG_Y
]
#######################
# from _proc process
channels_PPRM113 = [
"SAROP31-PPRM113:intensity",
"SAROP31-PPRM113:x_center_of_mass",
"SAROP31-PPRM113:x_fit_amplitude",
"SAROP31-PPRM113:x_fit_mean",
"SAROP31-PPRM113:x_fit_offset",
"SAROP31-PPRM113:x_fit_standard_deviation",
"SAROP31-PPRM113:x_fwhm",
"SAROP31-PPRM113:x_profile",
"SAROP31-PPRM113:x_rms",
"SAROP31-PPRM113:y_center_of_mass",
"SAROP31-PPRM113:y_fit_amplitude",
"SAROP31-PPRM113:y_fit_mean",
"SAROP31-PPRM113:y_fit_offset",
"SAROP31-PPRM113:y_fit_standard_deviation",
"SAROP31-PPRM113:y_fwhm",
"SAROP31-PPRM113:y_profile",
"SAROP31-PPRM113:y_rms",
# "SAROP31-PPRM113:FPICTURE", # full pictures for debugging purposes at the moment, from _ib process
]
#######################
# from _proc process
channels_PPRM150 = [
"SAROP31-PPRM150:intensity",
"SAROP31-PPRM150:x_center_of_mass",
"SAROP31-PPRM150:x_fit_amplitude",
"SAROP31-PPRM150:x_fit_mean",
"SAROP31-PPRM150:x_fit_offset",
"SAROP31-PPRM150:x_fit_standard_deviation",
"SAROP31-PPRM150:x_fwhm",
"SAROP31-PPRM150:x_profile",
"SAROP31-PPRM150:x_rms",
"SAROP31-PPRM150:y_center_of_mass",
"SAROP31-PPRM150:y_fit_amplitude",
"SAROP31-PPRM150:y_fit_mean",
"SAROP31-PPRM150:y_fit_offset",
"SAROP31-PPRM150:y_fit_standard_deviation",
"SAROP31-PPRM150:y_fwhm",
"SAROP31-PPRM150:y_profile",
"SAROP31-PPRM150:y_rms",
# "SAROP31-PPRM150:FPICTURE", # full pictures for debugging purposes at the moment, from _ib process
]
###########################
# Beam position monitor
channel_PBPS149 = [
"SAROP31-PBPS149:INTENSITY",
"SAROP31-PBPS149:INTENSITY_UJ",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD0",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD4",
"SAROP31-PBPS149:XPOS",
"SAROP31-PBPS149:YPOS",
]
further_channels = [
####################
## Digitizer
# Integration limits
"SARES30-LTIM01-EVR0:DUMMY_PV1_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV2_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV3_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV4_NBS",
# Signal-Background
"SARES30-LSCP1-FNS:CH0:VAL_GET",
# Waveform signal
"SARES30-LSCP1-CRISTA1:CH0:1",
# Waveform trigger
"SARES30-LSCP1-CRISTA1:CH2:1",
# Calculated intensity
"SARES30-LTIM01-EVR0:CALCI",
]
channels = (
channels_gas_monitor
+ channels_PCO
+ channels_OAV
+ channels_PBPS053
+ channels_pss059
+ channels_PPRM113
+ channels_PPRM150
+ channel_PBPS149
+ channel_PBPS149
+ further_channels
)
##########################################################################################################
pv_channels = [
####################
## OAPU044
"SARFE10-OAPU044:MOTOR_X",
"SARFE10-OAPU044:MOTOR_Y",
"SARFE10-OAPU044:MOTOR_W",
"SARFE10-OAPU044:MOTOR_H",
####################
## OATT053
"SARFE10-OATT053:MOTOR_1",
"SARFE10-OATT053:MOTOR_1.RBV",
"SARFE10-OATT053:MOTOR_2",
"SARFE10-OATT053:MOTOR_2.RBV",
"SARFE10-OATT053:MOTOR_3",
"SARFE10-OATT053:MOTOR_3.RBV",
"SARFE10-OATT053:MOTOR_4",
"SARFE10-OATT053:MOTOR_4.RBV",
"SARFE10-OATT053:MOTOR_5",
"SARFE10-OATT053:MOTOR_5.RBV",
"SARFE10-OATT053:MOTOR_6",
"SARFE10-OATT053:MOTOR_6.RBV",
"SARFE10-OATT053:ENERGY",
"SARFE10-OATT053:TRANS_SP",
"SARFE10-OATT053:TRANS_RB",
####################
## OATA150
"SAROP31-OATA150:MOTOR_1",
"SAROP31-OATA150:MOTOR_2",
"SAROP31-OATA150:MOTOR_3",
"SAROP31-OATA150:MOTOR_4",
"SAROP31-OATA150:MOTOR_5",
"SAROP31-OATA150:MOTOR_6",
####################
## PSSS
"SARFE10-PSSS059:MOTOR_Y3.VAL",
"SARFE10-PSSS059:MOTOR_ROT_X3.VAL",
"SARFE10-PSSS059:MOTOR_X5.VAL",
"SARFE10-PSSS059:MOTOR_X3.VAL",
###########################
# KB mirrors
"SAROP31-OKBV153:W_X.RBV",
"SAROP31-OKBV153:W_Y.RBV",
"SAROP31-OKBV153:W_RX.RBV",
"SAROP31-OKBV153:W_RY.RBV",
"SAROP31-OKBV153:W_RZ.RBV",
"SAROP31-OKBV153:BU.RBV",
"SAROP31-OKBV153:BD.RBV",
"SAROP31-OKBV153:TY1.RBV",
"SAROP31-OKBV153:TY2.RBV",
"SAROP31-OKBV153:TY3.RBV",
"SAROP31-OKBV153:TX1.RBV",
"SAROP31-OKBV153:TX2.RBV",
"SAROP31-OKBH154:W_X.RBV",
"SAROP31-OKBH154:W_Y.RBV",
"SAROP31-OKBH154:W_RX.RBV",
"SAROP31-OKBH154:W_RY.RBV",
"SAROP31-OKBH154:W_RZ.RBV",
"SAROP31-OKBH154:BU.RBV",
"SAROP31-OKBH154:BD.RBV",
"SAROP31-OKBH154:TY1.RBV",
"SAROP31-OKBH154:TY2.RBV",
"SAROP31-OKBH154:TY3.RBV",
"SAROP31-OKBH154:TX2.RBV",
####################
## FEL Photon Energy
"SARUN:FELPHOTENE",
###################
## FEL Photon Pulse Energy
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG",
]
pvs_slits = [
# TODO: PVS slits can't be read by the DAQ module currently. Therefore disabled it.
# "SARFE10-OAPU044:MOTOR_X.VAL",
# "SARFE10-OAPU044:MOTOR_X.RBV"
]
pvs_apertures = [
"SAROP31-OAPU149:MOTOR_X.VAL", # the x pos of the aperture
"SAROP31-OAPU149:MOTOR_X.RBV", # the x pos of the aperture
]
###############################
smaract_channels = [
"SARES30-XSMA156:X:MOTRBV",
"SARES30-XSMA156:Y:MOTRBV",
"SARES30-XSMA156:Z:MOTRBV",
"SARES30-XSMA156:Ry:MOTRBV",
"SARES30-XSMA156:Rx:MOTRBV",
"SARES30-XSMA156:Rz:MOTRBV",
]
pvs = pvs_slits + pv_channels + smaract_channels

View File

@ -6,11 +6,10 @@
# TODO: JF settings regarding raw conversion, compression, etc.
detectors_min = [
# "JF16T03V01",
# "JF16T03V01",
]
channels_min = ["SARFE10-PSSS059:SPECTRUM_Y"]
pvs_min = ['SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG']#pvs_slits + pv_channels + smaract_channels
pvs_min = ["SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG"] # pvs_slits + pv_channels + smaract_channels

View File

@ -7,9 +7,9 @@
#######################
# Machine
pvs_machine = [
"SARCL02-MBND100:P-READ", # Predicted bunch energy
"SARUN:FELPHOTENE.VAL", # Predicted photon energy from machine settings
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG.VAL" # Average pulse energy from the gas detector
"SARCL02-MBND100:P-READ", # Predicted bunch energy
"SARUN:FELPHOTENE.VAL", # Predicted photon energy from machine settings
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG.VAL", # Average pulse energy from the gas detector
]
pvs_RF = [
"SINSB01-RSYS:GET-VSUM-PHASE-OFFSET",
@ -83,7 +83,7 @@ pvs_RF = [
#######################
# Undulator gap
pvs_undulator =[
pvs_undulator = [
"SARUN03-UIND030:K_SET.VAL",
"SARUN04-UIND030:K_SET.VAL",
"SARUN05-UIND030:K_SET.VAL",
@ -100,7 +100,7 @@ pvs_undulator =[
]
####################
# Machine gas intensity monitor
# Machine gas intensity monitor
pvs_gas_monitor = [
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-US",
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-DS",
@ -108,7 +108,7 @@ pvs_gas_monitor = [
#####################
# Slits OAPU044
pvs_OAPU044=[
pvs_OAPU044 = [
"SARFE10-OAPU044:MOTOR_X",
"SARFE10-OAPU044:MOTOR_Y",
"SARFE10-OAPU044:MOTOR_W",
@ -121,11 +121,30 @@ pvs_PBPS053 = [
"SARFE10-PBPS053:MOTOR_X1",
"SARFE10-PBPS053:MOTOR_X2",
"SARFE10-PBPS053:MOTOR_PROBE",
]
]
###################
# Spectrometer PSSS059
pvs_PSSS059 = [
"SARFE10-PSSS055:MOTOR_X1.RBV",
"SARFE10-PSSS055:MOTOR_Y1.RBV",
"SARFE10-PSSS055:MOTOR_ROT_X1.RBV",
"SARFE10-PSSS055:MOTOR_PROBE.RBV",
"SARFE10-PSSS059:MOTOR_X3.RBV",
"SARFE10-PSSS059:MOTOR_Y3.RBV",
"SARFE10-PSSS059:MOTOR_ROT_X3.RBV",
"SARFE10-PSSS059:MOTOR_Y4.RBV",
"SARFE10-PSSS059:MOTOR_ROT_X4.RBV",
"SARFE10-PSSS059:MOTOR_X5.RBV",
"SARFE10-PSSS059:MOTOR_Y5.RBV",
"SARFE10-PSSS059:MOTOR_Z5.RBV",
"SARFE10-PSSS055:GRATING_SP",
"SARFE10-PSSS059:CRYSTAL_SP",
]
####################
# Upstream attenuator OATT053
pvs_OATT053=[
pvs_OATT053 = [
"SARFE10-OATT053:MOTOR_1",
"SARFE10-OATT053:MOTOR_1.RBV",
"SARFE10-OATT053:MOTOR_2",
@ -149,23 +168,20 @@ pvs_PPRM053 = [
"SARFE10-PPRM053:MOTOR_PROBE.RBV",
]
####################
# Single shot spectrometer PSS059
pvs_PSSS059 = [
# "SARFE10-PSSS059:FPICTURE", # full pictures only when really needed
"SARFE10-PSSS059:SPECTRUM_X",
"SARFE10-PSSS059:SPECTRUM_Y",
"SARFE10-PSSS059:SPECTRUM_CENTER",
"SARFE10-PSSS059:SPECTRUM_COM",
"SARFE10-PSSS059:SPECTRUM_FWHM",
"SARFE10-PSSS059:SPECTRUM_STD",
"SARFE10-PSSS059:FIT_ERR",
"SARFE10-PSSS059:processing_parameters",
"SARFE10-PSSS059:SPECTRUM_AVG_CENTER,"
"SARFE10-PSSS059:SPECTRUM_AVG_FWHM",
"SARFE10-PSSS059:SPECTRUM_AVG_Y",
###################
# Bernina mono
pvs_Bernina = [
"SAROP21-ARAMIS:ENERGY_SP",
"SAROP21-ARAMIS:ENERGY",
"SAROP21-PBPS103:MOTOR_X1.DRBV",
"SAROP21-PBPS103:MOTOR_Y1.DRBV",
"SAROP21-PBPS103:MOTOR_X1.RBV",
"SAROP21-PBPS103:MOTOR_Y1.RBV",
"SAROP21-PBPS103:MOTOR_PROBE.RBV",
"SAROP21-PPRM113:MOTOR_PROBE.RBV"
]
####################
# First Cristallina horizontal offset mirror OOMH067
pvs_OOMH067 = [
@ -215,15 +231,17 @@ pvs_PPRM085 = [
###################
# Slits OAPU107
pvs_OAPU107 = [
"SAROP31-OAPU107:MOTOR_X.VAL",
"SAROP31-OAPU107:MOTOR_X.RBV",
"SAROP31-OAPU107:MOTOR_X.VAL",
"SAROP31-OAPU107:MOTOR_X.RBV",
"SAROP31-OAPU107:MOTOR_Y.VAL",
"SAROP31-OAPU107:MOTOR_Y.RBV",
"SAROP31-OAPU107:MOTOR_Y.RBV",
]
###################
## Beam position and intensity monitor PBPS113
pvs_PBPS113 = [
"SAROP31-PBPS113:MOTOR_X1.DRBV",
"SAROP31-PBPS113:MOTOR_Y1.DRBV",
"SAROP31-PBPS113:MOTOR_X1.RBV",
"SAROP31-PBPS113:MOTOR_Y1.RBV",
"SAROP31-PBPS113:MOTOR_PROBE.RBV",
@ -244,15 +262,17 @@ pvs_OLAS147 = [
###################
# Slits OAPU149
pvs_OAPU149 = [
"SAROP31-OAPU149:MOTOR_X.VAL",
"SAROP31-OAPU149:MOTOR_X.RBV",
"SAROP31-OAPU149:MOTOR_X.VAL",
"SAROP31-OAPU149:MOTOR_X.RBV",
"SAROP31-OAPU149:MOTOR_Y.VAL",
"SAROP31-OAPU149:MOTOR_Y.RBV",
"SAROP31-OAPU149:MOTOR_Y.RBV",
]
###################
# Beam position and intensity monitor PBPS149
pvs_PBPS149 = [
"SAROP31-PBPS149:MOTOR_X1.DRBV",
"SAROP31-PBPS149:MOTOR_Y1.DRBV",
"SAROP31-PBPS149:MOTOR_X1.RBV",
"SAROP31-PBPS149:MOTOR_Y1.RBV",
"SAROP31-PBPS149:MOTOR_PROBE.RBV",
@ -325,7 +345,7 @@ pvs_PPRM150 = [
###########################
# Vertical KB mirror OKBV153
pvs_OKBV153 = [
pvs_OKBV153 = [
"SAROP31-OKBV153:W_X.RBV",
"SAROP31-OKBV153:W_Y.RBV",
"SAROP31-OKBV153:W_RX.RBV",
@ -349,7 +369,7 @@ pvs_PSCD153 = [
###########################
# Horizontal KB mirror OKBH154
pvs_OKBH154 = [
pvs_OKBH154 = [
"SAROP31-OKBH154:W_X.RBV",
"SAROP31-OKBH154:W_Y.RBV",
"SAROP31-OKBH154:W_RX.RBV",
@ -384,7 +404,7 @@ pvs_smaract_xyz = [
####################
# Attocube motors
pvs_attocube=[
pvs_attocube = [
"SARES30-ATTOCUBE:A0-POS",
"SARES30-ATTOCUBE:A1-POS",
]
@ -400,16 +420,16 @@ pvs_smaract_juraj = [
"SARES30-XSMA156:Rz:MOTRBV",
]
pvs = (
pvs_machine
+ pvs_RF
+ pvs_undulator
pvs = (
pvs_machine
# + pvs_RF
# + pvs_undulator
+ pvs_gas_monitor
+ pvs_OAPU044
+ pvs_PBPS053
+ pvs_PSSS059
+ pvs_OATT053
+ pvs_PPRM053
+ pvs_PSSS059
+ pvs_OOMH067
+ pvs_PSCR068
+ pvs_OOMH084
@ -424,14 +444,14 @@ pvs = (
+ pvs_OATA150
+ pvs_OPPI151
+ pvs_ODMV152
+ pvs_PPRM150
+ pvs_OKBV153
+ pvs_PSCD153
+ pvs_OKBH154
+ pvs_standa
+ pvs_smaract_xyz
# + pvs_standa
# + pvs_smaract_xyz
# + pvs_Bernina
)
# + pvs_attocube
# + pvs_smaract_juraj
# + pvs_attocube
# + pvs_smaract_juraj

View File

@ -1,260 +0,0 @@
# Channels at Cristallina endstation
##########################################################################################################
# BS channels
# TODO: JF settings regarding raw conversion, compression, etc.
detectors = [
# "JF16T03V01",
]
####################
channels_gas_monitor = [
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG",
"SARFE10-PBPG050:SLOW-X",
"SARFE10-PBPG050:SLOW-Y",
"SARFE10-PBIG050-EVR0:CALCI", # good for correlations with total beam intensity
"SARFE10-PBPG050:HAMP-INTENSITY-CAL",
]
######################
### PCO edge camera for the wavefront analysis
channels_PCO=["SARES30-CAMS156-PCO1:FPICTURE",
]
######################
### SwissMX OAV camera picture
channels_OAV=[#"SARES30-CAMS156-SMX-OAV:FPICTURE",
]
######################
### PBPS053
channels_PBPS053 = [
"SARFE10-PBPS053:INTENSITY",
"SARFE10-PBPS053:XPOS",
"SARFE10-PBPS053:YPOS",
]
###################################
### Beam position monitor PBPS113
channels_PBPS113 = [
"SAROP31-PBPS113:INTENSITY",
"SAROP31-PBPS113:INTENSITY_UJ",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD0",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD4",
"SAROP31-PBPS113:XPOS",
"SAROP31-PBPS113:YPOS",
]
####################
## PSS059
channels_pss059 = [
#"SARFE10-PSSS059:FPICTURE", # full pictures only when really needed
"SARFE10-PSSS059:SPECTRUM_X",
"SARFE10-PSSS059:SPECTRUM_Y",
"SARFE10-PSSS059:SPECTRUM_CENTER",
"SARFE10-PSSS059:SPECTRUM_COM",
"SARFE10-PSSS059:SPECTRUM_FWHM",
"SARFE10-PSSS059:SPECTRUM_STD",
"SARFE10-PSSS059:FIT_ERR",
"SARFE10-PSSS059:processing_parameters",
#SARFE10-PSSS059:SPECTRUM_AVG_CENTER
#SARFE10-PSSS059:SPECTRUM_AVG_FWHM
#SARFE10-PSSS059:SPECTRUM_AVG_Y
]
#######################
# from _proc process
channels_PPRM113 = [
"SAROP31-PPRM113:intensity",
"SAROP31-PPRM113:x_center_of_mass",
"SAROP31-PPRM113:x_fit_amplitude",
"SAROP31-PPRM113:x_fit_mean",
"SAROP31-PPRM113:x_fit_offset",
"SAROP31-PPRM113:x_fit_standard_deviation",
"SAROP31-PPRM113:x_fwhm",
"SAROP31-PPRM113:x_profile",
"SAROP31-PPRM113:x_rms",
"SAROP31-PPRM113:y_center_of_mass",
"SAROP31-PPRM113:y_fit_amplitude",
"SAROP31-PPRM113:y_fit_mean",
"SAROP31-PPRM113:y_fit_offset",
"SAROP31-PPRM113:y_fit_standard_deviation",
"SAROP31-PPRM113:y_fwhm",
"SAROP31-PPRM113:y_profile",
"SAROP31-PPRM113:y_rms",
#"SAROP31-PPRM113:FPICTURE", # full pictures for debugging purposes at the moment, from _ib process
]
#######################
# from _proc process
channels_PPRM150 = [
"SAROP31-PPRM150:intensity",
"SAROP31-PPRM150:x_center_of_mass",
"SAROP31-PPRM150:x_fit_amplitude",
"SAROP31-PPRM150:x_fit_mean",
"SAROP31-PPRM150:x_fit_offset",
"SAROP31-PPRM150:x_fit_standard_deviation",
"SAROP31-PPRM150:x_fwhm",
"SAROP31-PPRM150:x_profile",
"SAROP31-PPRM150:x_rms",
"SAROP31-PPRM150:y_center_of_mass",
"SAROP31-PPRM150:y_fit_amplitude",
"SAROP31-PPRM150:y_fit_mean",
"SAROP31-PPRM150:y_fit_offset",
"SAROP31-PPRM150:y_fit_standard_deviation",
"SAROP31-PPRM150:y_fwhm",
"SAROP31-PPRM150:y_profile",
"SAROP31-PPRM150:y_rms",
#"SAROP31-PPRM150:FPICTURE", # full pictures for debugging purposes at the moment, from _ib process
]
###########################
# Beam position monitor
channel_PBPS149 =[
"SAROP31-PBPS149:INTENSITY",
"SAROP31-PBPS149:INTENSITY_UJ",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD0",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD4",
"SAROP31-PBPS149:XPOS",
"SAROP31-PBPS149:YPOS",
]
further_channels = [
####################
## Digitizer
#Integration limits
"SARES30-LTIM01-EVR0:DUMMY_PV1_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV2_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV3_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV4_NBS",
# Signal-Background
"SARES30-LSCP1-FNS:CH0:VAL_GET",
#Waveform signal
"SARES30-LSCP1-CRISTA1:CH0:1",
#Waveform trigger
"SARES30-LSCP1-CRISTA1:CH2:1",
#Calculated intensity
"SARES30-LTIM01-EVR0:CALCI",
]
channels = channels_gas_monitor + channels_PCO + channels_OAV + channels_PBPS053 + channels_pss059 + channels_PPRM113 + channels_PPRM150 + channel_PBPS149 + channel_PBPS149 + further_channels
##########################################################################################################
pv_channels = [
####################
## OAPU044
"SARFE10-OAPU044:MOTOR_X",
"SARFE10-OAPU044:MOTOR_Y",
"SARFE10-OAPU044:MOTOR_W",
"SARFE10-OAPU044:MOTOR_H",
####################
## OATT053
"SARFE10-OATT053:MOTOR_1",
"SARFE10-OATT053:MOTOR_1.RBV",
"SARFE10-OATT053:MOTOR_2",
"SARFE10-OATT053:MOTOR_2.RBV",
"SARFE10-OATT053:MOTOR_3",
"SARFE10-OATT053:MOTOR_3.RBV",
"SARFE10-OATT053:MOTOR_4",
"SARFE10-OATT053:MOTOR_4.RBV",
"SARFE10-OATT053:MOTOR_5",
"SARFE10-OATT053:MOTOR_5.RBV",
"SARFE10-OATT053:MOTOR_6",
"SARFE10-OATT053:MOTOR_6.RBV",
"SARFE10-OATT053:ENERGY",
"SARFE10-OATT053:TRANS_SP",
"SARFE10-OATT053:TRANS_RB",
####################
## OATA150
"SAROP31-OATA150:MOTOR_1",
"SAROP31-OATA150:MOTOR_2",
"SAROP31-OATA150:MOTOR_3",
"SAROP31-OATA150:MOTOR_4",
"SAROP31-OATA150:MOTOR_5",
"SAROP31-OATA150:MOTOR_6",
####################
## PSSS
'SARFE10-PSSS059:MOTOR_Y3.VAL',
'SARFE10-PSSS059:MOTOR_ROT_X3.VAL',
'SARFE10-PSSS059:MOTOR_X5.VAL',
'SARFE10-PSSS059:MOTOR_X3.VAL',
###########################
# KB mirrors
"SAROP31-OKBV153:W_X.RBV",
"SAROP31-OKBV153:W_Y.RBV",
"SAROP31-OKBV153:W_RX.RBV",
"SAROP31-OKBV153:W_RY.RBV",
"SAROP31-OKBV153:W_RZ.RBV",
"SAROP31-OKBV153:BU.RBV",
"SAROP31-OKBV153:BD.RBV",
"SAROP31-OKBV153:TY1.RBV",
"SAROP31-OKBV153:TY2.RBV",
"SAROP31-OKBV153:TY3.RBV",
"SAROP31-OKBV153:TX1.RBV",
"SAROP31-OKBV153:TX2.RBV",
"SAROP31-OKBH154:W_X.RBV",
"SAROP31-OKBH154:W_Y.RBV",
"SAROP31-OKBH154:W_RX.RBV",
"SAROP31-OKBH154:W_RY.RBV",
"SAROP31-OKBH154:W_RZ.RBV",
"SAROP31-OKBH154:BU.RBV",
"SAROP31-OKBH154:BD.RBV",
"SAROP31-OKBH154:TY1.RBV",
"SAROP31-OKBH154:TY2.RBV",
"SAROP31-OKBH154:TY3.RBV",
"SAROP31-OKBH154:TX2.RBV",
####################
## FEL Photon Energy
'SARUN:FELPHOTENE',
###################
## FEL Photon Pulse Energy
'SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG',
]
pvs_slits = [
# TODO: PVS slits can't be read by the DAQ module currently. Therefore disabled it.
# "SARFE10-OAPU044:MOTOR_X.VAL",
# "SARFE10-OAPU044:MOTOR_X.RBV"
]
pvs_apertures = [
"SAROP31-OAPU149:MOTOR_X.VAL", # the x pos of the aperture
"SAROP31-OAPU149:MOTOR_X.RBV", # the x pos of the aperture
]
###############################
smaract_channels = [
"SARES30-XSMA156:X:MOTRBV",
"SARES30-XSMA156:Y:MOTRBV",
"SARES30-XSMA156:Z:MOTRBV",
"SARES30-XSMA156:Ry:MOTRBV",
"SARES30-XSMA156:Rx:MOTRBV",
"SARES30-XSMA156:Rz:MOTRBV",
]
pvs = pvs_slits + pv_channels + smaract_channels

View File

@ -1,42 +0,0 @@
import requests
import json
class Client:
def __init__(self, host="saresc-vcons-02", port=9090):
self.host = host
self.port = port
self.session = requests.Session()
def add_row(self, **kwargs):
addr = self._make_addr()
resp = self.session.patch(addr, json=kwargs)
return ResponseWrapper(resp)
def get(self):
addr = self._make_addr()
resp = self.session.get(addr)
return ResponseWrapper(resp)
def clear(self):
addr = self._make_addr()
resp = self.session.delete(addr)
return ResponseWrapper(resp)
def _make_addr(self):
return f"http://{self.host}:{self.port}/"
class ResponseWrapper:
def __init__(self, resp):
resp.raise_for_status()
self.resp = resp
def __repr__(self):
return self.resp.text

View File

@ -1,36 +1,42 @@
#!/usr/bin/env python
import sys
import os
os.chdir('/sf/cristallina/applications/slic/cristallina')
import re
# setup logging
import logging
logger = logging.getLogger("slic")
logger.setLevel(logging.INFO)
import time
from time import sleep
from tracemalloc import start
import numpy as np
os.chdir("/sf/cristallina/applications/slic/cristallina_cleanup")
# setup logging
from loguru import logger
logger.remove()
logger.add(
sys.stderr,
format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}",
level="INFO",
)
logger.info("Loading started.")
# create file handler which logs
try:
fh = logging.FileHandler('/sf/cristallina/applications/slic/cristallina/log/cristallina.log')
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
# TODO: better directory for log files? should not be pgroup specific so that this always works
try:
logger.add(
"/sf/cristallina/applications/slic/cristallina/log/cristallina.log",
format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}",
level="DEBUG",
)
except PermissionError as e:
logger.warning("Cannot write log file.")
logger.warning(e)
from time import sleep
from tracemalloc import start
from epics import PV
from stand_client import Client
stand_client = Client(host='saresc-vcons-02.psi.ch', port=9090)
from alignment_laser import AlignmentLaser
from devices.alignment_laser import AlignmentLaser
from slic.gui import GUI
from slic.core.adjustable import Adjustable, PVAdjustable, DummyAdjustable
from slic.core.acquisition import SFAcquisition, PVAcquisition
@ -43,26 +49,55 @@ from slic.devices.xoptics.pulsepicker import PulsePicker
from slic.utils import devices, Marker, as_shortcut
from slic.utils import Channels, Config, Elog, Screenshot, PV
from slic.core.acquisition.fakeacquisition import FakeAcquisition
from slic.devices.timing.events import CTASequencer
from bs_channels import detectors, bs_channels, camera_channels
from pv_channels import pvs
from slic.devices.timing.events import CTASequencer
from channels.bs_channels import detectors, bs_channels, camera_channels
from channels.pv_channels import pvs
from spreadsheet import overview
from channels_minimal import detectors_min, channels_min, pvs_min
from pp_shutter import PP_Shutter
# from channels_minimal import detectors_min, channels_min, pvs_min
from devices.pp_shutter import PP_Shutter
# DEVICES
# TODO: requires the stand client, need small howto how to start and configure or let it run all the time
# from slic.core.acquisition.spreadsheet import Spreadsheet
try:
from stand_client import Client
stand_host = "saresc-vcons-02.psi.ch"
stand_client = Client(host=stand_host, port=9090)
response = stand_client.get()
logger.info("Connected to stand server")
except Exception as error:
# catching with a broad net because different connection errors can occur.
logger.warning(f"Cannot connect to stand server on {stand_host}. Caught {error}.")
# spreadsheet = Spreadsheet(adjs, placeholders=PLACEHOLDERS, host="127.0.0.1", port=8080))
################# DEVICES #################
dummy = DummyAdjustable(units="au")
# Attenuators
from slic.devices.xoptics.aramis_attenuator import Attenuator
from knife_edge import KnifeEdge
from standa import standa
from devices.knife_edge import KnifeEdge
from devices.standa import standa
standa = standa
Newport_large = Motor("SARES30-MOBI1:MOT_5")
OWIS = Motor("SARES30-MOBI1:MOT_6") # small OWIS linear stage
attenuator = Attenuator("SAROP31-OATA150", description="Cristallina attenuator OATA150")
def test_attenuator():
tfundamental = attenuator.get_transmission()
try:
assert tfundamental > 0
except TypeError:
logger.warning("No transmission value reported from {attenuator.ID}")
test_attenuator()
front_end_attenuator = Attenuator("SARFE10-OATT053", description="Front end attenuator OATT053")
cta = CTASequencer("SAR-CCTA-ESC")
@ -77,26 +112,26 @@ pbps149 = IntensityMonitorPBPS(
"SAROP31-PBPS149",
# vme_crate="SAROP31-CVME-PBPS2", # please check this!
# link=9,
description="Intensity/position monitor in the experimental hutch"
description="Intensity/position monitor in the experimental hutch",
)
def test_attenuator():
tfundamental = attenuator.get_transmission()
try:
assert tfundamental > 0
except TypeError:
logger.warning("No transmission value reported from {attenuator.ID}")
test_attenuator()
# Undulators
import undulator
from beamline import undulator
undulators = undulator.Undulators()
logger.info(f"Using undulator (Aramis) offset to PSSS energy of {undulator.energy_offset} eV.")
# Shutter
shutter = PP_Shutter("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP", name="Cristallina pulse picker shutter") # Shutter buttton when using the pulse picker
pulsepicker = PulsePicker("SAROP31-OPPI151","SARES30-LTIM01-EVR0:Pul3", name="Cristallina X-ray pulse picker OPPI151")
shutter = PP_Shutter(
"SARES30-LTIM01-EVR0:RearUniv0-Ena-SP", name="Cristallina pulse picker shutter"
) # Shutter buttton when using the pulse picker
pulsepicker = PulsePicker(
"SAROP31-OPPI151",
"SARES30-LTIM01-EVR0:Pul3",
name="Cristallina X-ray pulse picker OPPI151",
)
# Alignment laser
alaser = AlignmentLaser("SAROP31-OLAS147:MOTOR_1", name="Cristallina alignment laser OLAS147")
@ -105,23 +140,22 @@ alaser = AlignmentLaser("SAROP31-OLAS147:MOTOR_1", name="Cristallina alignment l
from slic.devices.xoptics import slits
## Smaract & attocube stages
from smaract_device_def import smaract_Juraj, smaract_mini_XYZ
from attocube_device_def import attocube
from jj_device_def import jjslits
from devices.smaract_device_def import smaract_Juraj, smaract_mini_XYZ
from devices.attocube_device_def import attocube
from devices.jj_device_def import jjslits
# KBs
from slic.devices.xoptics.kb import KBHor,KBVer
kbHor = KBHor(
"SAROP31-OKBH154",
description="Cristallina horizontal KB mirror"
)
kbVer = KBVer(
"SAROP31-OKBV153",
description="Cristallina vertical KB mirror"
)
from slic.devices.xoptics.kb import KBHor, KBVer
kbHor = KBHor("SAROP31-OKBH154", description="Cristallina horizontal KB mirror")
kbVer = KBVer("SAROP31-OKBV153", description="Cristallina vertical KB mirror")
# Bernina monochromator
from beamline.bernina_mono import BerninaMono
BerninaDCM = BerninaMono("SAROP21-ODCM098")
###########################################
################# DAQ Setup #################
instrument = "cristallina"
# pgroup = "p19739" # commissioning March 2022 -- July 2022
@ -131,46 +165,67 @@ instrument = "cristallina"
# pgroup = "p20557" # CrQ PMS commisioning 1
# pgroup = "p20509" # CrQ commissoing DilSc1
# pgroup = "p20519" # beamline commissioning 2
# pgroup = "p20840" # Cr beamline commisioning (Jan-Feb 2023)
# pgroup = "p20841" # CrQ PMS commisioning 2 (Jan 2023)
# pgroup = "p20993" # CrQ commissoing DilSc2 (March 2023)
pgroup = "p21147" # SAXS
# pgroup = "p21147" # SAXS
# pgroup = "p21238" # Cristallina photon diagnostics p-group with Chris
# pgroup = "p21224" # SwissMX commissioning 7
# pgroup = "p19150" # Scratch
pgroup = "p19150" # Scratch
# pgroup = "p19152" # Scratch
# pgroup = "p20840" # Cr beamline commisioning (Jan-Feb 2023)
# pgroup = "p21261" # CrQ PMS-3 July 2023
# pgroup = "p21528" # Cr-MX Colletier 2023-09-05
daq = SFAcquisition(
instrument,
pgroup,
default_channels=bs_channels ,
default_channels=bs_channels,
default_pvs=pvs,
default_detectors=detectors,
rate_multiplicator=1,
)
# There is a new EPICS buffer, so the archiver is no longer used. This makes sure we are taking PVs from the right place.
daq.update_config_pvs()
# daq = FakeAcquisition(instrument, pgroup)
# daqPV = PVAcquisition(instrument, pgroup, default_channels=channels_ks) # workaround for KS not going to DB
# scan = Scanner(scan_info_dir=f"/sf/{instrument}/data/{pgroup}/res/scan_info", default_acquisitions=[daq], condition=None)
# Run the scan only when gas monitor value larger than 10uJ (and smaller than 2000uJ):
# required fraction defines ammount of data recorded to save the step and move on to the next one
check_intensity_gas_monitor = PVCondition("SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-US", vmin=10, vmax=2000, wait_time=0.5, required_fraction=0.8)
check_intensity_gas_monitor = PVCondition(
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-US",
vmin=-100,
vmax=2000,
wait_time=0.5,
required_fraction=0.8,
)
scan = Scanner(default_acquisitions=[daq], condition = check_intensity_gas_monitor)
scan = Scanner(default_acquisitions=[daq], condition=check_intensity_gas_monitor)
gui = GUI(scan, show_goto=True, show_spec=True)
logger.info(f"Running at {instrument} with pgroup {pgroup}.")
logger.info("Loading finished.")
def simple_acquisition(filename):
task = daq.acquire(filename)
#fname = task.filenames[0]
#pattern = r"run([0-9]{4})"
#match = re.search(pattern, fname)
#run_number = int(match.groups()[0])
#stand_client.add_row(run_number=run_number)
stand_client.add_row(run_number=-4,step=0, smaract_x=smaract_mini_XYZ.x.get_current_value(),smaract_y=smaract_mini_XYZ.y.get_current_value(),smaract_z=smaract_mini_XYZ.z.get_current_value()
slow_daq_test = SFAcquisition(
instrument,
"p19150",
default_channels=bs_channels,
default_pvs=pvs,
default_detectors=detectors,
rate_multiplicator=100,
)
slow_daq = SFAcquisition(
instrument,
pgroup,
default_channels=bs_channels,
default_pvs=pvs,
default_detectors=detectors,
rate_multiplicator=100,
)

View File

@ -4,10 +4,11 @@ from slic.utils import typename
class AlignmentLaser:
"""Class for the alignment laser"""
def __init__(self, ID,name="Cristallina alignment laser"):
def __init__(self, ID, name="Cristallina alignment laser"):
self.ID = ID
self.name = name or ID
pvname_setvalue = ID
pvname_setvalue = ID
pvname_readback = ID
self._adj = PVAdjustable(pvname_setvalue, pvname_readback, accuracy=0, internal=True)
@ -24,16 +25,15 @@ class AlignmentLaser:
return "not connected"
elif state < -18:
return "In"
elif state >-6:
elif state > -6:
return "Out"
else:
return "in an undefined position"
#TODO: Save the status downstream of the beamline when laser is out before bringing it back in
# TODO: Save the status downstream of the beamline when laser is out before bringing it back in
def get_downstream_status(self):
return
def __repr__(self):
tn = typename(self)
return f"{tn} \"{self.name}\" is {self.status}"
return f'{tn} "{self.name}" is {self.status}'

View File

@ -15,12 +15,12 @@ from slic.core.adjustable import Adjustable, AdjustableError
from slic.utils import typename
from slic.utils.printing import printable_dict
from slic.utils.hastyepics import get_pv as PV
# from ..basedevice import BaseDevice
from slic.core.device.basedevice import BaseDevice
class AttocubeStage(BaseDevice):
def __init__(self, name=None, **axis_ids):
self.name = name
self.axis_ids = axis_ids
@ -32,15 +32,15 @@ class AttocubeStage(BaseDevice):
setattr(self, ax_name, ax)
self.axes[ax_name] = ax
def __repr__(self):
tname = typename(self)
name = self.name
head = f"{tname} \"{name}\""
head = f'{tname} "{name}"'
to_print = {ax_name: ax.get_current_value() for ax_name, ax in self.axes.items()}
return printable_dict(to_print, head)
# Commments after talking to Sven:
# 1. give values in init and then fill self.config
# 2. set_target_value() is the method for the scanner. Therefore, update it so that it has move() inside it.
@ -56,9 +56,24 @@ class AttocubeStage(BaseDevice):
# where .acqure() has a the event_map - basically for every pulse id it shows whether the event was on or off. this way we can search for pulse ids for every drilling shot if we wanted to.
# event map channel is probably somewhere on the list when typing: " ioc records .*Evt.* "
class AttocubeAxis(Adjustable):
def __init__(self, ID, name=None, units=None, internal=False, tolerance=0.3, timeout=300.0, pos_check_delay=0.15, target_gnd=None, move_attempts = 5, move_attempt_sleep=4, verbose_move = False, ignore_limits=True, confirm_move= True):
class AttocubeAxis(Adjustable):
def __init__(
self,
ID,
name=None,
units=None,
internal=False,
tolerance=0.3,
timeout=300.0,
pos_check_delay=0.15,
target_gnd=None,
move_attempts=5,
move_attempt_sleep=4,
verbose_move=False,
ignore_limits=True,
confirm_move=True,
):
super().__init__(ID, name=name, units=units, internal=internal)
self.wait_time = 0.1
@ -66,37 +81,37 @@ class AttocubeAxis(Adjustable):
self.timeout = timeout
self.config = SimpleNamespace(
tolerance = tolerance,
timeout = timeout,
pos_check_delay = pos_check_delay,
target_gnd = target_gnd,
move_attempts = move_attempts,
move_attempt_sleep = move_attempt_sleep,
verbose_move = verbose_move,
ignore_limits = ignore_limits,
confirm_move = confirm_move,
tolerance=tolerance,
timeout=timeout,
pos_check_delay=pos_check_delay,
target_gnd=target_gnd,
move_attempts=move_attempts,
move_attempt_sleep=move_attempt_sleep,
verbose_move=verbose_move,
ignore_limits=ignore_limits,
confirm_move=confirm_move,
)
self.pvs = SimpleNamespace(
drive = PV(ID + "-SET_TARGET"),
readback = PV(ID + "-POS"),
amplitude = PV(ID + "-AMPL_SET"),
amplitude_rb = PV(ID + "-AMPL_RB"),
frequency = PV(ID + "-FREQ_SET"),
frequency_rb = PV(ID + "-FREQ_RB"),
moving_status = PV(ID + "-MOVING"),
hlm = PV(ID + ":HLM"), # not implemented yet, but hopefully will be added later
llm = PV(ID + ":LLM"), # not implemented yet, but hopefully will be added later
stop = PV(ID + "-STOP_AUTO_CMD"),
move = PV(ID + "-MV_ABS_SET"),
stop_auto_cmd = PV(ID + "-STOP_AUTO_CMD"),
target_tol_rb = PV(ID + "-TARGET_RANGE"),
target_tol_set = PV(ID + "-SET_TARGET_RANGE"),
target_reached = PV(ID + "-TARGET_REACHED_RB"),
target_ground = PV(ID + "-TARGET_GND_SET"),
output_enabled = PV(ID + "-ENABLE_SET"),
units = PV(ID + "-UNIT"),
output_RB = PV(ID + "-ENABLE_RB"),
drive=PV(ID + "-SET_TARGET"),
readback=PV(ID + "-POS"),
amplitude=PV(ID + "-AMPL_SET"),
amplitude_rb=PV(ID + "-AMPL_RB"),
frequency=PV(ID + "-FREQ_SET"),
frequency_rb=PV(ID + "-FREQ_RB"),
moving_status=PV(ID + "-MOVING"),
hlm=PV(ID + ":HLM"), # not implemented yet, but hopefully will be added later
llm=PV(ID + ":LLM"), # not implemented yet, but hopefully will be added later
stop=PV(ID + "-STOP_AUTO_CMD"),
move=PV(ID + "-MV_ABS_SET"),
stop_auto_cmd=PV(ID + "-STOP_AUTO_CMD"),
target_tol_rb=PV(ID + "-TARGET_RANGE"),
target_tol_set=PV(ID + "-SET_TARGET_RANGE"),
target_reached=PV(ID + "-TARGET_REACHED_RB"),
target_ground=PV(ID + "-TARGET_GND_SET"),
output_enabled=PV(ID + "-ENABLE_SET"),
units=PV(ID + "-UNIT"),
output_RB=PV(ID + "-ENABLE_RB"),
)
@property
@ -110,7 +125,7 @@ class AttocubeAxis(Adjustable):
def units(self, value):
self._units = value
def disable_output(self,verbose=True):
def disable_output(self, verbose=True):
old_value = self.pvs.output_RB.value
self.pvs.output_enabled.put(0)
if verbose:
@ -118,8 +133,8 @@ class AttocubeAxis(Adjustable):
print("Output has been disabled")
else:
print("Output has been off and stays that way")
def enable_output(self,verbose=True):
def enable_output(self, verbose=True):
old_value = self.pvs.output_RB.value
self.pvs.output_enabled.put(1)
if verbose:
@ -131,37 +146,37 @@ class AttocubeAxis(Adjustable):
def get_ground_on_targert(self):
return self.pvs.target_ground.value
def get_amplitude(self,verbose=False):
def get_amplitude(self, verbose=False):
amplitude = self.pvs.amplitude_rb.value
if verbose:
print(f'Drive amplitude is {amplitude/1000} V')
return amplitude/1000
print(f"Drive amplitude is {amplitude/1000} V")
return amplitude / 1000
def set_amplitude(self,value,verbose=False,check=False):
def set_amplitude(self, value, verbose=False, check=False):
"""Set drive amplitude for the axis in Volts. Add check=True for checking if it happened (takes 2s)."""
self.pvs.amplitude.put(value*1000)
self.pvs.amplitude.put(value * 1000)
if check:
time.sleep(2)
assert self.pvs.amplitude_rb.value == value*1000, 'drive amplitude readback does not match set value'
assert self.pvs.amplitude_rb.value == value * 1000, "drive amplitude readback does not match set value"
if verbose:
print(f'Drive amplitude is set to {value} V')
print(f"Drive amplitude is set to {value} V")
def get_frequency(self,verbose=False):
def get_frequency(self, verbose=False):
frequency = self.pvs.frequency_rb.value
if verbose:
print(f'Drive frequency is {frequency} V')
print(f"Drive frequency is {frequency} V")
return frequency
def set_frequency(self,value,verbose=False,check=False):
def set_frequency(self, value, verbose=False, check=False):
"""Set drive frequency for the axis in Hz. Add check=True for checking if it happened (takes 2s)."""
self.pvs.frequency.put(value)
if check:
time.sleep(2)
assert self.pvs.frequency_rb.value == value, 'drive frequency readback does not match set value'
assert self.pvs.frequency_rb.value == value, "drive frequency readback does not match set value"
if verbose:
print(f'Drive frequency is set to {value} Hz')
def set_ground_on_target(self,value,verbose=True):
print(f"Drive frequency is set to {value} Hz")
def set_ground_on_target(self, value, verbose=True):
if value == True or value == 1:
self.pvs.target_ground.put(1)
if verbose:
@ -176,7 +191,7 @@ class AttocubeAxis(Adjustable):
def get_target_tolerance(self):
return self.pvs.target_tol_rb.value
def set_target_tolerance(self,value):
def set_target_tolerance(self, value):
self.pvs.target_tol_set.put(value)
print(f"target tolerance set to {value} {self.pvs.units.char_value}")
@ -196,26 +211,26 @@ class AttocubeAxis(Adjustable):
def is_moving(self):
return self.is_at_target()
def is_at_target(self,from_pv=False, tolerance = None):
"""Check whether target was reached.
def is_at_target(self, from_pv=False, tolerance=None):
"""Check whether target was reached.
If from_pv is True TARGET_REACHED_RB is used, else it's calculated as diffrence between the readback and set value within tolerance.
Default is False, because otherwise tolerance can only be set and read out as an integer."""
if tolerance == None:
tolerance = self.config.tolerance
tolerance = self.config.tolerance
if from_pv == True:
return self.pvs.target_reached.value == 1
else:
return abs( self.pvs.readback.get() - self.pvs.drive.get() ) < tolerance
return abs(self.pvs.readback.get() - self.pvs.drive.get()) < tolerance
def allow_move(self):
self.pvs.move.put(1, wait=True)
def forbid_move(self):
self.pvs.move.put(0, wait=True)
def set_move_allowed(self,value):
def set_move_allowed(self, value):
if value == True or value == 1:
self.pvs.move.put(1)
self.pvs.move.put(1)
elif value == False or value == 0:
self.pvs.move.put(0)
else:
@ -226,23 +241,23 @@ class AttocubeAxis(Adjustable):
return low <= val <= high
def get_epics_limits(self):
low = self.pvs.llm.get()
low = self.pvs.llm.get()
high = self.pvs.hlm.get()
return low, high
def set_epics_limits(self, low, high, relative_to_current=False):
low = -np.inf if low is None else low
low = -np.inf if low is None else low
high = +np.inf if high is None else high
if relative_to_current:
val = self.get_current_value()
low += val
low += val
high += val
self.pvs.llm.put(low)
self.pvs.hlm.put(high)
###
# Things to be desired from the epics module:
# 1. Set SET_TARGET_RANGE as a float or somehow alow decimals to be entered
# 1. Set SET_TARGET_RANGE as a float or somehow alow decimals to be entered
# 2. Soft epics limits
def set_target_value(self, val, relative=False, wait=True):
@ -254,7 +269,7 @@ class AttocubeAxis(Adjustable):
val value to move to (float) [Must be provided]
relative move relative to current position (T/F) [F]
wait whether to wait for move to complete (T/F) [F]
return values:
==============
-13 : invalid value (cannot convert to float). Move not attempted.
@ -270,19 +285,19 @@ class AttocubeAxis(Adjustable):
1 : move-without-wait executed, move confirmed.
# 3 : move-without-wait finished, hard limit violation seen.
# 4 : move-without-wait finished, soft limit violation seen.
"""
INVALID_VALUE = -13
OUTSIDE_LIMITS = -12
NOT_CONNECTED = -11
TIMEOUT = -8
UNKNOWN_ERROR = -5
SUCCESS = 0
EXECUTED = 0
CONFIRMED = 1
PUT_SUCCESS = 1
PUT_TIMEOUT = -1
"""
INVALID_VALUE = -13
OUTSIDE_LIMITS = -12
NOT_CONNECTED = -11
TIMEOUT = -8
UNKNOWN_ERROR = -5
SUCCESS = 0
EXECUTED = 0
CONFIRMED = 1
PUT_SUCCESS = 1
PUT_TIMEOUT = -1
try:
val = float(val)
@ -302,11 +317,11 @@ class AttocubeAxis(Adjustable):
self.enable_output(verbose=False)
if self.config.target_gnd == True or self.config.target_gnd == 1:
self.set_ground_on_target(True,verbose=False)
self.set_ground_on_target(True, verbose=False)
elif self.config.target_gnd == False or self.config.target_gnd == 0:
self.set_ground_on_target(False,verbose=False)
self.set_ground_on_target(False, verbose=False)
self.allow_move()
self.allow_move()
if put_stat is None:
return NOT_CONNECTED
@ -319,7 +334,7 @@ class AttocubeAxis(Adjustable):
t0 = time.time()
tstart = t0 + min(self.config.timeout, 10)
tout = t0 + self.config.timeout
tout = t0 + self.config.timeout
if not wait and not self.config.confirm_move:
return EXECUTED
@ -331,41 +346,38 @@ class AttocubeAxis(Adjustable):
return TIMEOUT
# Wait before checking if target value reached. It's necessary as sometimes this PV takes a while to set for the new target value.
time.sleep(self.config.pos_check_delay)
time.sleep(self.config.pos_check_delay)
while self.is_at_target() == False and time.time() <= tout:
# If the value is near the last 2um. Move the cube to setpoint a few more times to get to the right position.
if self.is_at_target( tolerance = 2):
for attempt in range(self.config.move_attempts):
if self.is_at_target(tolerance=2):
for attempt in range(self.config.move_attempts):
if self.config.verbose_move:
print(f'move attempt: {attempt+1}')
print(f"move attempt: {attempt+1}")
self.pvs.move.put(1, wait=True)
time.sleep(self.config.move_attempt_sleep)
if self.is_at_target():
if self.config.verbose_move:
print(f'Move finished. Had to poke the cube {attempt+1}x to get there though.')
print(f"Move finished. Had to poke the cube {attempt+1}x to get there though.")
return SUCCESS
print('Position reached within 2um, but not better.')
print("Position reached within 2um, but not better.")
return TIMEOUT
if self.is_at_target():
return SUCCESS
return UNKNOWN_ERROR
def move(self, val, relative=False, wait=True):
''''Same as set target value, just for convenience'''
"""'Same as set target value, just for convenience"""
return self.set_target_value(val, relative=relative, wait=wait)
def gui(self):
device, motor = self.ID.split(":")
cmd = f'caqtdm -macro "DEVICE={device}" S_ANC350.ui'
return subprocess.Popen(cmd, shell=True)
class AttocubeError(AdjustableError):
pass

View File

@ -1,9 +1,10 @@
from attocube import AttocubeStage
from devices.attocube import AttocubeStage
attocube = AttocubeStage("SARES30-ATTOCUBE",
Y='SARES30-ATTOCUBE:A2',
X='SARES30-ATTOCUBE:A1',
)
attocube = AttocubeStage(
"SARES30-ATTOCUBE",
Y="SARES30-ATTOCUBE:A2",
X="SARES30-ATTOCUBE:A1",
)
# def make_AttocubeStage(name):
# return AttocubeStage(name,
@ -19,7 +20,6 @@ attocube = AttocubeStage("SARES30-ATTOCUBE",
# )
# def set_target_value(self, value):
# t1 = self.stage1.set_target_value(value)
# t2 = self.stage2.set_target_value(-value)
@ -30,13 +30,8 @@ attocube = AttocubeStage("SARES30-ATTOCUBE",
# return any(self.stage1.is_moving(), self.stage2.is_moving())
# t = daq.aquire(...)
# for pos in []:
# mot.set_target_value(pos).wait()
# sleep()
# t.stop()
# t.stop()

View File

@ -2,7 +2,6 @@ from slic.core.adjustable import Adjustable
class MyNewCoolThing(Adjustable):
pos = 0
def get_current_value(self):

18
devices/jj_device_def.py Normal file
View File

@ -0,0 +1,18 @@
from slic.core.device import Device, SimpleDevice
from slic.devices.general.motor import Motor
class SlitUnitCenterWidthJJ(Device):
def __init__(self, ID, motor_naming="MOTOR", **kwargs):
super().__init__(ID, **kwargs)
self.x = SimpleDevice(
ID + "-X", center=Motor(ID + ":" + motor_naming + "_X"), width=Motor(ID + ":" + motor_naming + "_W")
)
self.y = SimpleDevice(
ID + "-Y", center=Motor(ID + ":" + motor_naming + "_Y"), width=Motor(ID + ":" + motor_naming + "_H")
)
jjslits = SlitUnitCenterWidthJJ("SARES30-MOBI2", motor_naming="MOT")

View File

@ -4,10 +4,11 @@ from slic.utils import typename
class PP_Shutter:
"""Class for when pulse picker is used as a shutter. Opening and closing is done with turning on and off the event reciever universal output ON and OFF."""
def __init__(self, ID,name="X-ray Pulse Picker Shutter"):
def __init__(self, ID, name="X-ray Pulse Picker Shutter"):
self.ID = ID
self.name = name or ID
pvname_setvalue = ID
pvname_setvalue = ID
pvname_readback = ID
self._adj = PVAdjustable(pvname_setvalue, pvname_readback, accuracy=0, internal=True)
@ -26,4 +27,4 @@ class PP_Shutter:
def __repr__(self):
tn = typename(self)
return f"{tn} \"{self.name}\" is {self.status}"
return f'{tn} "{self.name}" is {self.status}'

35
devices/pulse_picker.py Normal file
View File

@ -0,0 +1,35 @@
from epics import PV
def pp_normal(opening = True):
""" Set pulse picker to fixed open or closed mode.
"""
PV("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP").put("Disabled")
PV("SARES30-LTIM01-EVR0:RearUniv0_SOURCE").put("HIGH")
PV("SARES30-LTIM01-EVR0:RearUniv0_SOURCE2").put("HIGH")
if opening:
PV("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP").put("Enabled")
else:
PV("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP").put("Disabled")
def pp_cta():
""" Set pulse picker to use the CTA as control input.
(check connections and parameters!)
"""
PV("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP").put("Disabled")
PV("SARES30-LTIM01-EVR0:RearUniv0_SOURCE").put("PULSER")
PV("SARES30-LTIM01-EVR0:RearUniv0_SOURCE2").put("PULSER")
PV("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD").put("3")
PV("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD2").put("3")
PV("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP").put("Enabled")

View File

@ -9,25 +9,24 @@ from slic.core.adjustable import Adjustable, AdjustableError
from slic.utils import typename
from slic.utils.printing import printable_dict
from slic.utils.hastyepics import get_pv as PV
# from ..basedevice import BaseDevice
from slic.core.device.basedevice import BaseDevice
class Status(IntEnum):
STOPPED = 0
STEPPING = 1
SCANNING = 2
HOLDING = 3
TARGETING = 4
MOVE_DELAY = 5
STOPPED = 0
STEPPING = 1
SCANNING = 2
HOLDING = 3
TARGETING = 4
MOVE_DELAY = 5
CALIBRATING = 6
FINDING_REF = 7
LOCKED = 8
LOCKED = 8
class SmarActStage(BaseDevice):
def __init__(self, name=None, **axis_ids):
self.name = name
self.axis_ids = axis_ids
@ -39,20 +38,17 @@ class SmarActStage(BaseDevice):
setattr(self, ax_name, ax)
self.axes[ax_name] = ax
def __repr__(self):
tname = typename(self)
name = self.name
head = f"{tname} \"{name}\""
head = f'{tname} "{name}"'
to_print = {ax_name: ax.get_current_value() for ax_name, ax in self.axes.items()}
return printable_dict(to_print, head)
class SmarActAxis(Adjustable):
def __init__(self, ID, name=None, units=None, internal=False,tolerance=0.5):
def __init__(self, ID, name=None, units=None, internal=False, tolerance=0.5):
super().__init__(ID, name=name, units=units, internal=internal)
self.wait_time = 0.1
@ -60,20 +56,20 @@ class SmarActAxis(Adjustable):
self._move_requested = False
self.config = SimpleNamespace(
tolerance = tolerance,
tolerance=tolerance,
)
self.pvs = SimpleNamespace(
drive = PV(ID + ":DRIVE"),
readback = PV(ID + ":MOTRBV"),
hlm = PV(ID + ":HLM"),
llm = PV(ID + ":LLM"),
status = PV(ID + ":STATUS"),
set_pos = PV(ID + ":SET_POS"),
stop = PV(ID + ":STOP.PROC"),
hold = PV(ID + ":HOLD"),
twv = PV(ID + ":TWV"),
units = PV(ID + ":DRIVE.EGU")
drive=PV(ID + ":DRIVE"),
readback=PV(ID + ":MOTRBV"),
hlm=PV(ID + ":HLM"),
llm=PV(ID + ":LLM"),
status=PV(ID + ":STATUS"),
set_pos=PV(ID + ":SET_POS"),
stop=PV(ID + ":STOP.PROC"),
hold=PV(ID + ":HOLD"),
twv=PV(ID + ":TWV"),
units=PV(ID + ":DRIVE.EGU"),
)
@property
@ -87,7 +83,6 @@ class SmarActAxis(Adjustable):
def units(self, value):
self._units = value
def get_current_value(self, readback=True):
if readback:
return self.pvs.readback.get()
@ -111,33 +106,32 @@ class SmarActAxis(Adjustable):
if time.time() >= timeout:
tname = typename(self)
self.stop()
raise SmarActError(f"starting to move {tname} \"{self.name}\" to {value} {self.units} timed out")
raise SmarActError(f'starting to move {tname} "{self.name}" to {value} {self.units} timed out')
# wait for move done
while self._move_requested and self.is_moving():
if self.is_holding(): # holding == arrived at target!
if self.is_holding(): # holding == arrived at target!
break
time.sleep(wait_time)
self._move_requested = False
print("move done")
def is_at_target(self,from_pv=False, tolerance = None):
"""Check whether target was reached.
def is_at_target(self, from_pv=False, tolerance=None):
"""Check whether target was reached.
If from_pv is True TARGET_REACHED_RB is used, else it's calculated as diffrence between the readback and set value within tolerance.
Default is False, because otherwise tolerance can only be set and read out as an integer."""
if tolerance == None:
tolerance = self.config.tolerance
tolerance = self.config.tolerance
if from_pv == True:
return self.pvs.target_reached.value == 1
else:
return abs( self.pvs.readback.get() - self.pvs.drive.get() ) < tolerance
return abs(self.pvs.readback.get() - self.pvs.drive.get()) < tolerance
def stop(self):
self._move_requested = False
self.pvs.stop.put(1, wait=True)
def is_moving(self):
return self.status != Status.STOPPED
@ -148,27 +142,25 @@ class SmarActAxis(Adjustable):
def status(self):
return self.pvs.status.get()
def within_epics_limits(self, val):
low, high = self.get_epics_limits()
return low <= val <= high
def get_epics_limits(self):
low = self.pvs.llm.get()
low = self.pvs.llm.get()
high = self.pvs.hlm.get()
return low, high
def set_epics_limits(self, low, high, relative_to_current=False):
low = -np.inf if low is None else low
low = -np.inf if low is None else low
high = +np.inf if high is None else high
if relative_to_current:
val = self.get_current_value()
low += val
low += val
high += val
self.pvs.llm.put(low)
self.pvs.hlm.put(high)
def move(self, val, relative=False, wait=True, ignore_limits=False, confirm_move=True, timeout=300.0):
"""
moves SmarAct drive to position (emulating pyepics Motor class)
@ -199,17 +191,17 @@ class SmarActAxis(Adjustable):
# 4 : move-without-wait finished, soft limit violation seen.
"""
INVALID_VALUE = -13
INVALID_VALUE = -13
OUTSIDE_LIMITS = -12
NOT_CONNECTED = -11
TIMEOUT = -8
UNKNOWN_ERROR = -5
SUCCESS = 0
EXECUTED = 0
CONFIRMED = 1
NOT_CONNECTED = -11
TIMEOUT = -8
UNKNOWN_ERROR = -5
SUCCESS = 0
EXECUTED = 0
CONFIRMED = 1
PUT_SUCCESS = 1
PUT_TIMEOUT = -1
PUT_SUCCESS = 1
PUT_TIMEOUT = -1
try:
val = float(val)
@ -237,9 +229,9 @@ class SmarActAxis(Adjustable):
stat = self.status
t0 = time.time()
thold = t0 + self.pvs.hold.get() * 0.001
thold = t0 + self.pvs.hold.get() * 0.001
tstart = t0 + min(timeout, 10)
tout = t0 + timeout
tout = t0 + timeout
if not wait and not confirm_move:
return EXECUTED
@ -273,7 +265,7 @@ class SmarActAxis(Adjustable):
twv = self.pvs.twv.get()
twv = abs(twv)
ca.poll(evt=1.0e-1)
while stat == Status.HOLDING and time.time() <= tout:
ca.poll(evt=1.0e-2)
@ -286,16 +278,11 @@ class SmarActAxis(Adjustable):
return UNKNOWN_ERROR
def gui(self):
device, motor = self.ID.split(":")
cmd = f'caqtdm -macro "P={device}:,M={motor}" SARES30-CPCL-SMARACTX1_6axis_old.ui'
return subprocess.Popen(cmd, shell=True)
class SmarActError(AdjustableError):
pass

View File

@ -1,5 +1,5 @@
# from slic.devices.general.smaract import SmarActStage
from smaract import SmarActStage
from devices.smaract import SmarActStage
from slic.core.device.simpledevice import SimpleDevice
from slic.devices.general.motor import Motor
@ -15,18 +15,18 @@ smaract_y = Motor("SARES30-MCS2750:MOT_3")
smaract_mini_XYZ = SimpleDevice("XYZ smaract stage (mini)", x=smaract_x, y=smaract_y, z=smaract_z)
smaract_Juraj = SmarActStage("SARES30-XSMA156",
X='SARES30-XSMA156:X',
Y='SARES30-XSMA156:Y',
Z='SARES30-XSMA156:Z',
Ry='SARES30-XSMA156:Ry',
Rx='SARES30-XSMA156:Rx',
Rz='SARES30-XSMA156:Rz',
)
smaract_Juraj = SmarActStage(
"SARES30-XSMA156",
X="SARES30-XSMA156:X",
Y="SARES30-XSMA156:Y",
Z="SARES30-XSMA156:Z",
Ry="SARES30-XSMA156:Ry",
Rx="SARES30-XSMA156:Rx",
Rz="SARES30-XSMA156:Rz",
)
# smaract_mini_XYZ = SmarActStage("SARES30-MCS2750",
# X='SARES30-MCS2750:MOT_1',
# Y='SARES30-MCS2750:MOT_2',
# Z='SARES30-MCS2750:MOT_3',
# )
# Y='SARES30-MCS2750:MOT_2',
# Z='SARES30-MCS2750:MOT_3',
# )

5
exp_temp/apertures.py Normal file
View File

@ -0,0 +1,5 @@
from slic.devices.xoptics import slits
slits149 = slits.SlitUnitCenterWidth('SAROP31-OAPU149')
slits107 = slits.SlitUnitCenterWidth('SAROP31-OAPU107')

View File

@ -0,0 +1,73 @@
from time import sleep
from epics import PV
#from slic.devices.xoptics.aramis_attenuator import Attenuator
pulse_picker_opening_pv = "SARES30-LTIM01-EVR0:RearUniv0-Ena-SP"
def attenuator_scan(transmissions,att,daq,sleep_time=8,label='test',n_pulses=100,detectors=None,pvs=None,channels=None):
PV(pulse_picker_opening_pv).put("Disabled")
sleep(1)
for idx,transmission in enumerate(transmissions):
print("Setting transmission = ",transmission)
att.trans1st(transmission)
sleep(sleep_time)
PV(pulse_picker_opening_pv).put("Enabled")
sleep(1)
print("Acquiring scan point ",idx,", Transmission = ",transmission)
if idx == 0:
#print("First point")
daq.acquire(label,is_scan_step=False,n_pulses=n_pulses,detectors=detectors,channels=channels,pvs=pvs)
else:
#print("Not first point")
daq.acquire(label,is_scan_step=True,n_pulses=n_pulses,detectors=detectors,channels=channels,pvs=pvs)
PV(pulse_picker_opening_pv).put("Disabled")
sleep(1)
print("Returning to first transmission = ",transmissions[0])
att.trans1st(transmissions[0])
sleep(sleep_time)
def attenuator_scan_cont(transmissions,att,daq,sleep_time=8,label='test',n_pulses=100,detectors=None,pvs=None,channels=None):
PV(pulse_picker_opening_pv).put("Disabled")
sleep(1)
for idx,transmission in enumerate(transmissions):
print("Setting transmission = ",transmission)
att.trans1st(transmission)
sleep(sleep_time)
PV(pulse_picker_opening_pv).put("Enabled")
sleep(1)
print("Acquiring scan point ",idx,", Transmission = ",transmission)
if idx < 0:
#print("First point")
daq.acquire(label,is_scan_step=False,n_pulses=n_pulses,detectors=detectors,channels=channels,pvs=pvs)
else:
#print("Not first point")
daq.acquire(label,is_scan_step=True,n_pulses=n_pulses,detectors=detectors,channels=channels,pvs=pvs)
PV(pulse_picker_opening_pv).put("Disabled")
sleep(1)
print("Returning to first transmission = ",transmissions[0])
att.trans1st(transmissions[0])
sleep(sleep_time)

804
exp_temp/channels.py Normal file
View File

@ -0,0 +1,804 @@
# Channels to save at Cristallina endstation
##########################################################################################################
##########################################################################################################
##########################################################################################################
# BS channels
# TODO: JF settings regarding raw conversion, compression, etc.
detectors = [
"JF16T03V01",
]
camera_channels = [
# "SARES30-CAMS156-PCO1:FPICTURE", # PCO edge camera for the wavefront analysis (from Alvra)
# "SARES30-CAMS156-SMX-OAV:FPICTURE", # SwissMX OAV camera picture
# "SARES30-CAMS156-XE:FPICTURE", # X-ray eye
]
####################
# Machine gas intensity monitor
channels_gas_monitor = [
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG",
# "SARFE10-PBPG050:SLOW-X",
# "SARFE10-PBPG050:SLOW-Y",
"SARFE10-PBIG050-EVR0:CALCI", # good for correlations with total beam intensity
"SARFE10-PBPG050:HAMP-INTENSITY-CAL",
]
# RF phases and amplitudes
channels_RF = [
"SINSB01-RLLE-DSP:PHASE-VS",
"SINSB02-RLLE-DSP:PHASE-VS",
"SINSB03-RLLE-DSP:PHASE-VS",
"SINSB04-RLLE-DSP:PHASE-VS",
"SINXB01-RLLE-DSP:PHASE-VS",
"SINDI01-RLLE-DSP:PHASE-VS",
"S10CB01-RLLE-DSP:PHASE-VS",
"S10CB02-RLLE-DSP:PHASE-VS",
"S10CB03-RLLE-DSP:PHASE-VS",
"S10CB04-RLLE-DSP:PHASE-VS",
"S10CB05-RLLE-DSP:PHASE-VS",
"S10CB06-RLLE-DSP:PHASE-VS",
"S10CB07-RLLE-DSP:PHASE-VS",
"S10CB08-RLLE-DSP:PHASE-VS",
"S10CB09-RLLE-DSP:PHASE-VS",
"S20CB01-RLLE-DSP:PHASE-VS",
"S20CB02-RLLE-DSP:PHASE-VS",
"S20CB03-RLLE-DSP:PHASE-VS",
"S20CB04-RLLE-DSP:PHASE-VS",
"S30CB01-RLLE-DSP:PHASE-VS",
"S30CB02-RLLE-DSP:PHASE-VS",
"S30CB03-RLLE-DSP:PHASE-VS",
"S30CB04-RLLE-DSP:PHASE-VS",
"S30CB05-RLLE-DSP:PHASE-VS",
"S30CB06-RLLE-DSP:PHASE-VS",
"S30CB07-RLLE-DSP:PHASE-VS",
"S30CB08-RLLE-DSP:PHASE-VS",
"S30CB09-RLLE-DSP:PHASE-VS",
"S30CB10-RLLE-DSP:PHASE-VS",
"S30CB11-RLLE-DSP:PHASE-VS",
"S30CB12-RLLE-DSP:PHASE-VS",
"S30CB13-RLLE-DSP:PHASE-VS",
"S30CB14-RLLE-DSP:PHASE-VS",
"SINEG01-RLLE-DSP:AMPLT-VS",
"SINSB01-RLLE-DSP:AMPLT-VS",
"SINSB02-RLLE-DSP:AMPLT-VS",
"SINSB03-RLLE-DSP:AMPLT-VS",
"SINSB04-RLLE-DSP:AMPLT-VS",
"SINXB01-RLLE-DSP:AMPLT-VS",
"SINDI01-RLLE-DSP:AMPLT-VS",
"S10CB01-RLLE-DSP:AMPLT-VS",
"S10CB02-RLLE-DSP:AMPLT-VS",
"S10CB03-RLLE-DSP:AMPLT-VS",
"S10CB04-RLLE-DSP:AMPLT-VS",
"S10CB05-RLLE-DSP:AMPLT-VS",
"S10CB06-RLLE-DSP:AMPLT-VS",
"S10CB07-RLLE-DSP:AMPLT-VS",
"S10CB08-RLLE-DSP:AMPLT-VS",
"S10CB09-RLLE-DSP:AMPLT-VS",
"S20CB01-RLLE-DSP:AMPLT-VS",
"S20CB02-RLLE-DSP:AMPLT-VS",
"S20CB03-RLLE-DSP:AMPLT-VS",
"S20CB04-RLLE-DSP:AMPLT-VS",
"S30CB01-RLLE-DSP:AMPLT-VS",
"S30CB02-RLLE-DSP:AMPLT-VS",
"S30CB03-RLLE-DSP:AMPLT-VS",
"S30CB04-RLLE-DSP:AMPLT-VS",
"S30CB05-RLLE-DSP:AMPLT-VS",
"S30CB06-RLLE-DSP:AMPLT-VS",
"S30CB07-RLLE-DSP:AMPLT-VS",
"S30CB08-RLLE-DSP:AMPLT-VS",
"S30CB09-RLLE-DSP:AMPLT-VS",
"S30CB10-RLLE-DSP:AMPLT-VS",
"S30CB11-RLLE-DSP:AMPLT-VS",
"S30CB12-RLLE-DSP:AMPLT-VS",
"S30CB13-RLLE-DSP:AMPLT-VS",
"S30CB14-RLLE-DSP:AMPLT-VS",
]
channels_Xeye = ["SARES30-CAMS156-XE:intensity"]
######################
# PBPS053
channels_PBPS053 = [
"SARFE10-PBPS053:INTENSITY",
"SARFE10-PBPS053:XPOS",
"SARFE10-PBPS053:YPOS",
]
####################
# PSSS059
channels_PSSS059 = [
"SARFE10-PSSS059:FIT-COM",
"SARFE10-PSSS059:FIT-FWHM",
"SARFE10-PSSS059:FIT-RES",
"SARFE10-PSSS059:FIT-RMS",
"SARFE10-PSSS059:SPECT-COM",
"SARFE10-PSSS059:SPECT-RES",
"SARFE10-PSSS059:SPECT-RMS",
"SARFE10-PSSS059:SPECTRUM_Y_SUM",
"SARFE10-PSSS059:SPECTRUM_X",
"SARFE10-PSSS059:SPECTRUM_Y",
# "SARFE10-PSSS059:FPICTURE",
# "SARFE10-PSSS059:FIT_ERR",
"SARFE10-PSSS059:processing_parameters",
# "SARFE10-PSSS059:SPECTRUM_AVG_CENTER",
# "SARFE10-PSSS059:SPECTRUM_AVG_FWHM",
# "SARFE10-PSSS059:SPECTRUM_AVG_Y",
]
###################################
## Bernina channels
# Beam position monitor PBPS113
channels_Bernina = [
"SAROP21-PBPS103:INTENSITY",
"SAROP21-PBPS103:XPOS",
"SAROP21-PBPS103:YPOS",
"SAROP21-PPRM113:FPICTURE",
"SAROP21-PPRM113:intensity",
"SAROP21-PPRM113:x_fit_mean",
"SAROP21-PPRM113:y_fit_mean",
]
###################################
# Beam position monitor PBPS113
channels_PBPS113 = [
"SAROP31-PBPS113:INTENSITY",
"SAROP31-PBPS113:INTENSITY_UJ",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD0",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS113:XPOS",
"SAROP31-PBPS113:YPOS",
]
channels_PBPS113_waveforms = [
"SAROP31-PBPS113:Lnk9Ch0-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch1-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch2-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch3-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch4-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch5-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch6-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch7-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch8-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch9-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch10-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch11-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch12-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch13-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch14-WF-DATA",
"SAROP31-PBPS113:Lnk9Ch15-WF-DATA",
]
####################
# Profile monitor PPRM113 (from _proc process)
channels_PPRM113 = [
"SAROP31-PPRM113:intensity",
"SAROP31-PPRM113:x_center_of_mass",
"SAROP31-PPRM113:x_fit_amplitude",
"SAROP31-PPRM113:x_fit_mean",
"SAROP31-PPRM113:x_fit_offset",
"SAROP31-PPRM113:x_fit_standard_deviation",
"SAROP31-PPRM113:x_fwhm",
"SAROP31-PPRM113:x_profile",
"SAROP31-PPRM113:x_rms",
"SAROP31-PPRM113:y_center_of_mass",
"SAROP31-PPRM113:y_fit_amplitude",
"SAROP31-PPRM113:y_fit_mean",
"SAROP31-PPRM113:y_fit_offset",
"SAROP31-PPRM113:y_fit_standard_deviation",
"SAROP31-PPRM113:y_fwhm",
"SAROP31-PPRM113:y_profile",
"SAROP31-PPRM113:y_rms",
# "SAROP31-PPRM113:FPICTURE", # full pictures for debugging purposes at the moment, from _ib process
]
###########################
# Beam position monitor PBPS149
# "SARES30-CAMS156-PCO1:FPICTURE", # PCO edge camera for the wavefront analysis (from Alvra)
# "SARES30-CAMS156-SMX-OAV:FPIC
###########################
# Beam position monitor
channels_PBPS149 = [
"SAROP31-PBPS149:INTENSITY",
"SAROP31-PBPS149:INTENSITY_UJ",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD0",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD1",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD2",
"SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD3",
"SAROP31-PBPS149:XPOS",
"SAROP31-PBPS149:YPOS",
]
#######################
# Profile monitor PPRM150 (from _proc process)
channels_PPRM150 = [
"SAROP31-PPRM150:intensity",
"SAROP31-PPRM150:x_center_of_mass",
"SAROP31-PPRM150:x_fit_amplitude",
"SAROP31-PPRM150:x_fit_mean",
"SAROP31-PPRM150:x_fit_offset",
"SAROP31-PPRM150:x_fit_standard_deviation",
"SAROP31-PPRM150:x_fwhm",
"SAROP31-PPRM150:x_profile",
"SAROP31-PPRM150:x_rms",
"SAROP31-PPRM150:y_center_of_mass",
"SAROP31-PPRM150:y_fit_amplitude",
"SAROP31-PPRM150:y_fit_mean",
"SAROP31-PPRM150:y_fit_offset",
"SAROP31-PPRM150:y_fit_standard_deviation",
"SAROP31-PPRM150:y_fwhm",
"SAROP31-PPRM150:y_profile",
"SAROP31-PPRM150:y_rms",
# "SAROP31-PPRM150:FPICTURE", # full pictures for debugging purposes at the moment, from _ib process
]
#######################
# Cristallina event reciever
channels_EVR = [
"SAR-CVME-TIFALL6:EvtSet",
]
#######################
# Digitizer
channels_digitizer = [
"SARES30-LTIM01-EVR0:DUMMY_PV1_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV2_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV3_NBS",
"SARES30-LTIM01-EVR0:DUMMY_PV4_NBS",
"SARES30-LSCP1-FNS:CH0:VAL_GET", # Signal-Background
"SARES30-LSCP1-CRISTA1:CH0:1", # Waveform signal
"SARES30-LSCP1-CRISTA1:CH2:1", # Waveform trigger
"SARES30-LTIM01-EVR0:CALCI", # Calculated intensity
]
##########################################################################################################
##########################################################################################################
##########################################################################################################
# Epics PVS
# Compression, charge settings
#######################
# Machine
pvs_machine = [
"SARCL02-MBND100:P-READ", # Predicted bunch energy
"SARUN:FELPHOTENE.VAL", # Predicted photon energy from machine settings
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG.VAL", # Average pulse energy from the gas detector
]
pvs_RF = [
"SINSB01-RSYS:GET-VSUM-PHASE-OFFSET",
"SINSB02-RSYS:GET-VSUM-PHASE-OFFSET",
"SINSB03-RSYS:GET-VSUM-PHASE-OFFSET",
"SINSB04-RSYS:GET-VSUM-PHASE-OFFSET",
"SINXB01-RSYS:GET-VSUM-PHASE-OFFSET",
"SINDI01-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB01-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB02-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB03-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB04-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB06-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB05-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB07-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB08-RSYS:GET-VSUM-PHASE-OFFSET",
"S10CB09-RSYS:GET-VSUM-PHASE-OFFSET",
"S20CB01-RSYS:GET-VSUM-PHASE-OFFSET",
"S20CB02-RSYS:GET-VSUM-PHASE-OFFSET",
"S20CB03-RSYS:GET-VSUM-PHASE-OFFSET",
"S20CB04-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB01-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB02-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB03-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB04-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB05-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB06-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB07-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB08-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB09-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB10-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB11-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB12-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB13-RSYS:GET-VSUM-PHASE-OFFSET",
"S30CB14-RSYS:GET-VSUM-PHASE-OFFSET",
"SINEG01-RSYS:GET-VSUM-AMPLT-SCALE",
"SINSB01-RSYS:GET-VSUM-AMPLT-SCALE",
"SINSB02-RSYS:GET-VSUM-AMPLT-SCALE",
"SINSB03-RSYS:GET-VSUM-AMPLT-SCALE",
"SINSB04-RSYS:GET-VSUM-AMPLT-SCALE",
"SINXB01-RSYS:GET-VSUM-AMPLT-SCALE",
"SINDI01-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB01-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB02-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB03-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB04-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB05-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB06-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB07-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB08-RSYS:GET-VSUM-AMPLT-SCALE",
"S10CB09-RSYS:GET-VSUM-AMPLT-SCALE",
"S20CB01-RSYS:GET-VSUM-AMPLT-SCALE",
"S20CB02-RSYS:GET-VSUM-AMPLT-SCALE",
"S20CB03-RSYS:GET-VSUM-AMPLT-SCALE",
"S20CB04-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB01-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB02-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB03-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB04-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB05-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB06-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB07-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB08-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB09-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB10-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB11-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB12-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB13-RSYS:GET-VSUM-AMPLT-SCALE",
"S30CB14-RSYS:GET-VSUM-AMPLT-SCALE",
]
#######################
# Undulator gap
pvs_undulator = [
"SARUN03-UIND030:K_SET.VAL",
"SARUN04-UIND030:K_SET.VAL",
"SARUN05-UIND030:K_SET.VAL",
"SARUN06-UIND030:K_SET.VAL",
"SARUN07-UIND030:K_SET.VAL",
"SARUN08-UIND030:K_SET.VAL",
"SARUN09-UIND030:K_SET.VAL",
"SARUN10-UIND030:K_SET.VAL",
"SARUN11-UIND030:K_SET.VAL",
"SARUN12-UIND030:K_SET.VAL",
"SARUN13-UIND030:K_SET.VAL",
"SARUN14-UIND030:K_SET.VAL",
"SARUN15-UIND030:K_SET.VAL",
]
####################
# Machine gas intensity monitor
pvs_gas_monitor = [
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-US",
"SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-DS",
]
#####################
# Slits OAPU044
pvs_OAPU044 = [
"SARFE10-OAPU044:MOTOR_X",
"SARFE10-OAPU044:MOTOR_Y",
"SARFE10-OAPU044:MOTOR_W",
"SARFE10-OAPU044:MOTOR_H",
]
###################
# Beam position monitor PBPS053
pvs_PBPS053 = [
"SARFE10-PBPS053:MOTOR_X1",
"SARFE10-PBPS053:MOTOR_X2",
"SARFE10-PBPS053:MOTOR_PROBE",
]
####################
# Upstream attenuator OATT053
pvs_OATT053 = [
"SARFE10-OATT053:MOTOR_1",
"SARFE10-OATT053:MOTOR_1.RBV",
"SARFE10-OATT053:MOTOR_2",
"SARFE10-OATT053:MOTOR_2.RBV",
"SARFE10-OATT053:MOTOR_3",
"SARFE10-OATT053:MOTOR_3.RBV",
"SARFE10-OATT053:MOTOR_4",
"SARFE10-OATT053:MOTOR_4.RBV",
"SARFE10-OATT053:MOTOR_5",
"SARFE10-OATT053:MOTOR_5.RBV",
"SARFE10-OATT053:MOTOR_6",
"SARFE10-OATT053:MOTOR_6.RBV",
"SARFE10-OATT053:ENERGY",
"SARFE10-OATT053:TRANS_SP",
"SARFE10-OATT053:TRANS_RB",
]
###################
# Beam profile monitor PPRM053
pvs_PPRM053 = [
"SARFE10-PPRM053:MOTOR_PROBE.RBV",
]
###################
# Bernina mono
pvs_Bernina = [
"SAROP21-ARAMIS:ENERGY_SP",
"SAROP21-ARAMIS:ENERGY",
"SAROP21-PBPS103:MOTOR_X1.DRBV",
"SAROP21-PBPS103:MOTOR_Y1.DRBV",
"SAROP21-PBPS103:MOTOR_X1.RBV",
"SAROP21-PBPS103:MOTOR_Y1.RBV",
"SAROP21-PBPS103:MOTOR_PROBE.RBV",
"SAROP21-PPRM113:MOTOR_PROBE.RBV"
]
####################
# Single shot spectrometer PSS059
pvs_PSSS059 = [
"SARFE10-PSSS055:MOTOR_X1.RBV",
"SARFE10-PSSS055:MOTOR_Y1.RBV",
"SARFE10-PSSS055:MOTOR_ROT_X1.RBV",
"SARFE10-PSSS055:MOTOR_PROBE.RBV",
"SARFE10-PSSS059:MOTOR_X3.RBV",
"SARFE10-PSSS059:MOTOR_Y3.RBV",
"SARFE10-PSSS059:MOTOR_ROT_X3.RBV",
"SARFE10-PSSS059:MOTOR_Y4.RBV",
"SARFE10-PSSS059:MOTOR_ROT_X4.RBV",
"SARFE10-PSSS059:MOTOR_X5.RBV",
"SARFE10-PSSS059:MOTOR_Y5.RBV",
"SARFE10-PSSS059:MOTOR_Z5.RBV",
"SARFE10-PSSS055:GRATING_SP",
"SARFE10-PSSS059:CRYSTAL_SP",
"SARFE10-PSSS059:SPC_ROI_YMIN",
"SARFE10-PSSS059:SPC_ROI_YMAX",
]
####################
# First Cristallina horizontal offset mirror OOMH067
pvs_OOMH067 = [
"SAROP31-OOMH067:W_X.RBV",
"SAROP31-OOMH067:W_Y.RBV",
"SAROP31-OOMH067:W_RX.RBV",
"SAROP31-OOMH067:W_RY.RBV",
"SAROP31-OOMH067:W_RZ.RBV",
"SAROP31-OOMH067:BU.RBV",
"SAROP31-OOMH067:BD.RBV",
"SAROP31-OOMH067:VS1.RBV",
"SAROP31-OOMH067:VS2.RBV",
"SAROP31-OOMH067:VS3.RBV",
"SAROP31-OOMH067:TX.RBV",
"SAROP31-OOMH067:RY.RBV",
]
####################
# Beam screen between the first two horizontal mirrors PSCR068
pvs_PSCR068 = [
"SAROP31-PSCR068:MOTOR_PROBE.RBV",
]
####################
# Second Cristallina horizontal offset mirror OOMH084
pvs_OOMH084 = [
"SAROP31-OOMH084:W_X.RBV",
"SAROP31-OOMH084:W_Y.RBV",
"SAROP31-OOMH084:W_RX.RBV",
"SAROP31-OOMH084:W_RY.RBV",
"SAROP31-OOMH084:W_RZ.RBV",
"SAROP31-OOMH084:BU.RBV",
"SAROP31-OOMH084:BD.RBV",
"SAROP31-OOMH084:VS1.RBV",
"SAROP31-OOMH084:VS2.RBV",
"SAROP31-OOMH084:VS3.RBV",
"SAROP31-OOMH084:TX.RBV",
"SAROP31-OOMH084:RY.RBV",
]
###################
# Beam profile monitor PPRM085
pvs_PPRM085 = [
"SAROP31-PPRM085:MOTOR_PROBE.RBV",
]
###################
# Slits OAPU107
pvs_OAPU107 = [
"SAROP31-OAPU107:MOTOR_X.VAL",
"SAROP31-OAPU107:MOTOR_X.RBV",
"SAROP31-OAPU107:MOTOR_Y.VAL",
"SAROP31-OAPU107:MOTOR_Y.RBV",
]
###################
## Beam position and intensity monitor PBPS113
pvs_PBPS113 = [
"SAROP31-PBPS113:MOTOR_X1.DRBV",
"SAROP31-PBPS113:MOTOR_Y1.DRBV",
"SAROP31-PBPS113:MOTOR_X1.RBV",
"SAROP31-PBPS113:MOTOR_Y1.RBV",
"SAROP31-PBPS113:MOTOR_PROBE.RBV",
]
###################
# Beam profile monitor PPRM113
pvs_PPRM113 = [
"SAROP31-PPRM113:MOTOR_PROBE.RBV",
]
####################
# Alignment laser mirror OLAS147
pvs_OLAS147 = [
"SAROP31-OLAS147:MOTOR_1.RBV",
]
###################
# Slits OAPU149
pvs_OAPU149 = [
"SAROP31-OAPU149:MOTOR_X.VAL",
"SAROP31-OAPU149:MOTOR_X.RBV",
"SAROP31-OAPU149:MOTOR_Y.VAL",
"SAROP31-OAPU149:MOTOR_Y.RBV",
]
###################
# Beam position and intensity monitor PBPS149
pvs_PBPS149 = [
"SAROP31-PBPS149:MOTOR_X1.DRBV",
"SAROP31-PBPS149:MOTOR_Y1.DRBV",
"SAROP31-PBPS149:MOTOR_X1.RBV",
"SAROP31-PBPS149:MOTOR_Y1.RBV",
"SAROP31-PBPS149:MOTOR_PROBE.RBV",
]
###################
# Beam profile monitor PPRM150
pvs_PPRM150 = [
"SAROP31-PPRM150:MOTOR_PROBE.RBV",
]
####################
# Attenuators OATA150
pvs_OATA150 = [
"SAROP31-OATA150:MOTOR_1.RBV",
"SAROP31-OATA150:MOTOR_2.RBV",
"SAROP31-OATA150:MOTOR_3.RBV",
"SAROP31-OATA150:MOTOR_4.RBV",
"SAROP31-OATA150:MOTOR_5.RBV",
"SAROP31-OATA150:MOTOR_6.RBV",
"SAROP31-OATA150:ENERGY",
"SAROP31-OATA150:TRANS_SP",
"SAROP31-OATA150:TRANS_RB",
"SAROP31-OATA150:TRANS3EDHARM_RB",
"SAROP31-OATA150:MOT2TRANS.VALD"
]
####################
# Pulse picker OPPI151
pvs_OPPI151 = [
"SAROP31-OPPI151:MOTOR_X.RBV",
"SAROP31-OPPI151:MOTOR_Y.RBV",
]
####################
## Horizontal offset mirror ODMV152
pvs_ODMV152 = [
"SAROP31-ODMV152:W_X.RBV",
"SAROP31-ODMV152:W_Y.RBV",
"SAROP31-ODMV152:W_RX.RBV",
"SAROP31-ODMV152:W_RZ.RBV",
"SAROP31-ODMV152:BU.RBV",
"SAROP31-ODMV152:BD.RBV",
"SAROP31-ODMV152:VS1.RBV",
"SAROP31-ODMV152:VS2.RBV",
"SAROP31-ODMV152:VS3.RBV",
"SAROP31-ODMV152:TX.RBV",
]
#######################
# from _proc process
pvs_PPRM150 = [
"SAROP31-PPRM150:MOTOR_PROBE.RBV",
]
###########################
# Vertical KB mirror OKBV153
pvs_OKBV153 = [
"SAROP31-OKBV153:W_X.RBV",
"SAROP31-OKBV153:W_Y.RBV",
"SAROP31-OKBV153:W_RX.RBV",
"SAROP31-OKBV153:W_RY.RBV",
"SAROP31-OKBV153:W_RZ.RBV",
"SAROP31-OKBV153:BU.RBV",
"SAROP31-OKBV153:BD.RBV",
"SAROP31-OKBV153:TY1.RBV",
"SAROP31-OKBV153:TY2.RBV",
"SAROP31-OKBV153:TY3.RBV",
"SAROP31-OKBV153:TX1.RBV",
"SAROP31-OKBV153:TX2.RBV",
]
####################
# Screen between the KB's PSCD153
# Not implemented yet
pvs_PSCD153 = [
"SAROP31-PSCD153:MOTOR_PROBE.RBV"
]
###########################
# Horizontal KB mirror OKBH154
pvs_OKBH154 = [
"SAROP31-OKBH154:W_X.RBV",
"SAROP31-OKBH154:W_Y.RBV",
"SAROP31-OKBH154:W_RX.RBV",
"SAROP31-OKBH154:W_RY.RBV",
"SAROP31-OKBH154:W_RZ.RBV",
"SAROP31-OKBH154:BU.RBV",
"SAROP31-OKBH154:BD.RBV",
"SAROP31-OKBH154:TY1.RBV",
"SAROP31-OKBH154:TY2.RBV",
"SAROP31-OKBH154:TY3.RBV",
"SAROP31-OKBH154:TX2.RBV",
]
####################
# Standa motors (mainly used with the X-ray eye)
pvs_standa = [
"SARES30-MOBI1:MOT_1.RBV",
"SARES30-MOBI1:MOT_2.RBV",
"SARES30-MOBI1:MOT_3.RBV",
]
###############################
# Smaract stages mini XYZ from SwissMX
pvs_smaract_xyz = [
"SARES30-MCS2750:MOT_1.RBV",
"SARES30-MCS2750:MOT_1.VAL",
"SARES30-MCS2750:MOT_2.RBV",
"SARES30-MCS2750:MOT_2.VAL",
"SARES30-MCS2750:MOT_3.RBV",
"SARES30-MCS2750:MOT_3.VAL",
]
####################
# Attocube motors
pvs_attocube = [
"SARES30-ATTOCUBE:A0-POS",
"SARES30-ATTOCUBE:A1-POS",
]
###############################
# Smaract stages from Juraj
pvs_smaract_juraj = [
"SARES30-XSMA156:X:MOTRBV",
"SARES30-XSMA156:Y:MOTRBV",
"SARES30-XSMA156:Z:MOTRBV",
"SARES30-XSMA156:Ry:MOTRBV",
"SARES30-XSMA156:Rx:MOTRBV",
"SARES30-XSMA156:Rz:MOTRBV",
]
pvs = (
pvs_machine
# + pvs_RF
# + pvs_undulator
+ pvs_gas_monitor
+ pvs_OAPU044
+ pvs_PBPS053
+ pvs_OATT053
+ pvs_PPRM053
+ pvs_PSSS059
+ pvs_OOMH067
+ pvs_PSCR068
+ pvs_OOMH084
+ pvs_PPRM085
+ pvs_OAPU107
+ pvs_PBPS113
+ pvs_PPRM113
+ pvs_OLAS147
+ pvs_OAPU149
+ pvs_PBPS149
+ pvs_PPRM150
+ pvs_OATA150
+ pvs_OPPI151
+ pvs_ODMV152
+ pvs_OKBV153
+ pvs_PSCD153
+ pvs_OKBH154
# + pvs_standa
# + pvs_smaract_xyz
# + pvs_Bernina
)
# + pvs_attocube
# + pvs_smaract_juraj
##########################
#########################
####################
detectors_jf_direct_beam_012 = [
"JF16T03V01",
]
####################
bs_channels_OAPU107_scan = (
channels_gas_monitor
+ channels_PBPS053
+ channels_PSSS059
+ channels_PBPS113
+ channels_PBPS113
+ channels_PPRM150
)
bs_channels_OAPU149_scan = (
channels_gas_monitor
+ channels_PBPS053
+ channels_PSSS059
+ channels_PBPS113
+ channels_PBPS113
+ channels_PPRM150
)
bs_channels_pbps_snapshot = (
channels_gas_monitor
+ channels_PBPS053
+ channels_PSSS059
+ channels_PBPS113
+ channels_PBPS149
)
bs_channels_PPRM150 = (
channels_gas_monitor
+ channels_PBPS053
+ channels_PSSS059
+ channels_PPRM150
+ ["SAROP31-PPRM150:FPICTURE"]
)
bs_channels_jf_direct_beam = (
channels_gas_monitor
+ channels_PBPS053
+ channels_PSSS059
+ channels_PBPS113
+ channels_PBPS149
+ channels_EVR
)
####################
pvs_channels_PPRM150 = (
pvs_gas_monitor
+ pvs_OAPU044
+ pvs_PBPS053
+ pvs_OATT053
+ pvs_PPRM053
+ pvs_PSSS059
+ pvs_OOMH067
+ pvs_PSCR068
+ pvs_OOMH084
+ pvs_PPRM085
+ pvs_OAPU107
+ pvs_PBPS113
+ pvs_PPRM113
+ pvs_OLAS147
+ pvs_OAPU149
+ pvs_PBPS149
+ pvs_PPRM150
)
pvs_channels_jf_direct_beam = (
pvs_gas_monitor
+ pvs_OAPU044
+ pvs_PBPS053
+ pvs_OATT053
+ pvs_PPRM053
+ pvs_PSSS059
+ pvs_OOMH067
+ pvs_OOMH084
+ pvs_PPRM085
+ pvs_OAPU107
+ pvs_PBPS113
+ pvs_PPRM113
+ pvs_OAPU149
+ pvs_PBPS149
+ pvs_OATA150
+ pvs_OPPI151
+ pvs_ODMV152
+ pvs_OKBV153
+ pvs_PSCD153
+ pvs_OKBH154
)

View File

@ -5,12 +5,14 @@ from slic.utils import typename
CTA_sequence_start_PID = PV("SAR-CCTA-ESC:seq0Ctrl-StartedAt-O")
class PP_Shutter:
"""Pulsed magnet instrument classs"""
def __init__(self, ID,name="Pulsed Magnet Instrument"):
def __init__(self, ID, name="Pulsed Magnet Instrument"):
self.ID = ID
self.name = name or ID
pvname_setvalue = ID
pvname_setvalue = ID
pvname_readback = ID
self._adj = PVAdjustable(pvname_setvalue, pvname_readback, accuracy=0, internal=True)
@ -29,7 +31,4 @@ class PP_Shutter:
def __repr__(self):
tn = typename(self)
return f"{tn} \"{self.name}\" is {self.status}"
return f'{tn} "{self.name}" is {self.status}'

View File

@ -1,20 +0,0 @@
from slic.core.device import Device, SimpleDevice
from slic.devices.general.motor import Motor
class SlitUnitCenterWidthJJ(Device):
def __init__(self, ID, motor_naming="MOTOR",**kwargs):
super().__init__(ID, **kwargs)
self.x = SimpleDevice(ID + "-X",
center = Motor(ID + ":"+motor_naming+"_X"),
width = Motor(ID + ":"+motor_naming+"_W")
)
self.y = SimpleDevice(ID + "-Y",
center = Motor(ID + ":"+motor_naming+"_Y"),
width = Motor(ID + ":"+motor_naming+"_H")
)
jjslits = SlitUnitCenterWidthJJ("SARES30-MOBI2", motor_naming="MOT")

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,12 @@
from time import sleep, time
from cristallina import cta, daq
def make_pulse_train():
recording = daq.acquire('pulsing_sequence',n_pulses=100*101,wait=False)
recording = daq.acquire("pulsing_sequence", n_pulses=100 * 101, wait=False)
cta.start()
recording.wait()
print('done')
print("done")
#daq.acquire(filename, data_base_dir=None, detectors=None, channels=None, pvs=None, scan_info=None, n_pulses=100, continuous=False, is_scan_step=False, wait=True):
# daq.acquire(filename, data_base_dir=None, detectors=None, channels=None, pvs=None, scan_info=None, n_pulses=100, continuous=False, is_scan_step=False, wait=True):

View File

@ -3,9 +3,10 @@ from time import sleep, time
from tracemalloc import start
import numpy as np
from collections import defaultdict
#from epics import PV
#from slic.utils import nice_arange
#from slic.devices.general.motor import Motor
# from epics import PV
# from slic.utils import nice_arange
# from slic.devices.general.motor import Motor
import matplotlib.pyplot as plt
import epics
from cristallina import Newport_large, attocube, attenuator
@ -15,80 +16,81 @@ from tqdm import tqdm
from standa import standa
from slic.devices.timing.events import CTASequencer
cta = CTASequencer("SAR-CCTA-ESC")
# setup logging
# setup logging
import logging
logger = logging.getLogger("slic.hole_drilling")
logger.setLevel(logging.INFO)
#formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-8s %(message)s',
# formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-8s %(message)s',
# datefmt='%Y-%m-%d %H:%M:%S')
# create file handler which logs
try:
fh = logging.FileHandler('/sf/cristallina/applications/slic/cristallina/log/hole_drilling.log')
try:
fh = logging.FileHandler("/sf/cristallina/applications/slic/cristallina/log/hole_drilling.log")
fh.setLevel(logging.DEBUG)
#fh.setFormatter(formatter)
# fh.setFormatter(formatter)
logger.addHandler(fh)
except PermissionError as e:
logger.warning("Cannot write log file.")
logger.warning(e)
attenuator = Attenuator("SAROP31-OATA150", description="Cristallina attenuator OATA150")
from slic.devices.xoptics.kb import KBHor,KBVer
kbHor = KBHor(
"SAROP31-OKBH154",
description="Cristallina horizontal KB mirror"
)
from slic.devices.xoptics.kb import KBHor, KBVer
kbVer = KBVer(
"SAROP31-OKBV153",
description="Cristallina vertical KB mirror"
)
kbHor = KBHor("SAROP31-OKBH154", description="Cristallina horizontal KB mirror")
kbVer = KBVer("SAROP31-OKBV153", description="Cristallina vertical KB mirror")
do_not_move_benders = True
testing_flag = False
pos = np.array([0,0])
pos = np.array([0, 0])
# parameters
n_same_holes = 3
attenuations = np.linspace(0.15,0.35,9)#np.linspace(0.1,0.35,11)#np.linspace(0.1,0.35,6)#np.logspace(-3,0,num=7)
KBv_home = [1.3 , 1.6]
KBh_home = [1.4 , 1.7]
attenuations = np.linspace(0.15, 0.35, 9) # np.linspace(0.1,0.35,11)#np.linspace(0.1,0.35,6)#np.logspace(-3,0,num=7)
KBv_home = [1.3, 1.6]
KBh_home = [1.4, 1.7]
# Spacings
between_same_shots = 150
between_attenuations = 150
between_KB_settings = 500#500
between_KB_settings = 500 # 500
### 23.02
def kb_settings_list(best,step,no_steps):
def kb_settings_list(best, step, no_steps):
for i in range(no_steps):
if i == 0:
l=[]
l.append([best[0]+i*step,best[1]])
l = []
l.append([best[0] + i * step, best[1]])
for i in range(no_steps):
if i == 0:
pass
l.append([best[0],best[1]+i*step])
return l
l.append([best[0], best[1] + i * step])
return l
KBvs = kb_settings_list([1.595, 1.874], 0.05, 3)
KBhs = kb_settings_list([1.799000, 2.100000], 0.05, 3)
KBvs = kb_settings_list([1.595,1.874],0.05,3)
KBhs = kb_settings_list([1.799000,2.100000],0.05,3)
### 24.02
def kb_settings_list_new(best,step,no_steps_one_way):
l=[]
first = np.array(best) - np.array([step*no_steps_one_way,step*no_steps_one_way])
for i in range(no_steps_one_way*2+1):
l.append([first[0]+i*step,first[1]+i*step])
return l
KBvs = kb_settings_list_new([1.595,1.874],0.0075,3)
KBhs = kb_settings_list_new([1.799000,2.100000],0.0075,3)
def kb_settings_list_new(best, step, no_steps_one_way):
l = []
first = np.array(best) - np.array([step * no_steps_one_way, step * no_steps_one_way])
for i in range(no_steps_one_way * 2 + 1):
l.append([first[0] + i * step, first[1] + i * step])
return l
KBvs = kb_settings_list_new([1.595, 1.874], 0.0075, 3)
KBhs = kb_settings_list_new([1.799000, 2.100000], 0.0075, 3)
# Time estimates for total time calculation (time in seconds)
@ -100,9 +102,10 @@ t_atten_change = 10
smaract_stage = True
# Change to mm from um if smaract stage selected
if smaract_stage:
between_same_shots = between_same_shots/1000
between_attenuations = between_attenuations/1000
between_KB_settings = between_KB_settings/1000
between_same_shots = between_same_shots / 1000
between_attenuations = between_attenuations / 1000
between_KB_settings = between_KB_settings / 1000
def shoot(n_shots=1):
epics.caput("SAR-CCTA-ESC:seq0Ctrl-Cycles-I", n_shots)
@ -113,6 +116,7 @@ def shoot(n_shots=1):
def move_x_rel(distance):
standa.x.mvr(distance)
def move_y_rel(distance):
standa.z.mvr(distance)
@ -121,64 +125,70 @@ def move_absolute(x, y):
standa.x.mv(x).wait()
standa.z.mv(y).wait()
def make_holes(quantity,spacing=0.25,wait=1):
def make_holes(quantity, spacing=0.25, wait=1):
start_x = standa.x.get()
start_y = standa.z.get()
print(f'Starting postion:\n {standa}')
print(f"Starting postion:\n {standa}")
for i in range(quantity):
print(f'Shot {i}')
print(f"Shot {i}")
shoot()
sleep(wait)
move_x_rel(spacing)
print('Done')
print('Returning to the start')
print("Done")
print("Returning to the start")
standa.x.mv(start_x)
standa.z.mv(start_y)
def drill_holes_grid(x_start, x_stop, n_cols, y_start, y_stop, n_rows, wait_time=0.5):
# make grid
x_pos = np.linspace(x_start, x_stop, n_cols)
x_spacing = (x_stop-x_start)/(n_cols-1)
x_spacing = (x_stop - x_start) / (n_cols - 1)
y_pos = np.linspace(y_start, y_stop, n_rows)
y_spacing = (y_stop-y_start)/(n_rows-1)
y_spacing = (y_stop - y_start) / (n_rows - 1)
# TODO: add settings we want to change per row
row_settings = defaultdict(lambda: {'n_pulses' : 100})
row_settings[0] = {'n_pulses' : 500}
row_settings[1] = {'n_pulses' : 100}
row_settings[2] = {'n_pulses' : 10}
row_settings[3] = {'n_pulses' : 1}
row_settings = defaultdict(lambda: {"n_pulses": 100})
row_settings[0] = {"n_pulses": 500}
row_settings[1] = {"n_pulses": 100}
row_settings[2] = {"n_pulses": 10}
row_settings[3] = {"n_pulses": 1}
x_start = standa.x.get()
y_start = standa.z.get()
logger.info(f"Begin hole pattern at x:{x_start:.5f}, y:{y_start:.5f}, with transmission: {attenuator.get_transmission():.5f}.")
logger.info(
f"Begin hole pattern at x:{x_start:.5f}, y:{y_start:.5f}, with transmission: {attenuator.get_transmission():.5f}."
)
for row, y in enumerate(y_pos):
settings = row_settings[row]
n_pulses = settings['n_pulses']
n_pulses = settings["n_pulses"]
for x in x_pos:
move_absolute(x, y)
sleep(wait_time)
shoot(n_pulses)
sleep(0.2)
while cta.cta_client.is_running():
# wait until sequence is done
print('waiting for CTA ...')
print("waiting for CTA ...")
sleep(0.1)
logger.info(f"At {time():.5f}s, drilled {n_pulses} hole(s) at x:{x:.5f}, y:{y:.5f}, with transmission: {attenuator.get_transmission():.5f}.")
logger.info(
f"At {time():.5f}s, drilled {n_pulses} hole(s) at x:{x:.5f}, y:{y:.5f}, with transmission: {attenuator.get_transmission():.5f}."
)
move_absolute(x_start, y_start)
def drill_here():
def drill_here():
x_start = standa.x.get()
x_stop = x_start + 2
n_cols = 11

View File

@ -2,9 +2,10 @@ from datetime import datetime
from time import sleep, time
from tracemalloc import start
import numpy as np
#from epics import PV
#from slic.utils import nice_arange
#from slic.devices.general.motor import Motor
# from epics import PV
# from slic.utils import nice_arange
# from slic.devices.general.motor import Motor
import matplotlib.pyplot as plt
import epics
from cristallina import Newport_large, attocube, attenuator
@ -14,56 +15,56 @@ from tqdm import tqdm
attenuator = Attenuator("SAROP31-OATA150", description="Cristallina attenuator OATA150")
from slic.devices.xoptics.kb import KBHor,KBVer
kbHor = KBHor(
"SAROP31-OKBH154",
description="Cristallina horizontal KB mirror"
)
from slic.devices.xoptics.kb import KBHor, KBVer
kbVer = KBVer(
"SAROP31-OKBV153",
description="Cristallina vertical KB mirror"
)
kbHor = KBHor("SAROP31-OKBH154", description="Cristallina horizontal KB mirror")
kbVer = KBVer("SAROP31-OKBV153", description="Cristallina vertical KB mirror")
do_not_move_benders = True
testing_flag = False
pos = np.array([0,0])
pos = np.array([0, 0])
# parameters
n_same_holes = 3
attenuations = np.linspace(0.15,0.35,9)#np.linspace(0.1,0.35,11)#np.linspace(0.1,0.35,6)#np.logspace(-3,0,num=7)
KBv_home = [1.3 , 1.6]
KBh_home = [1.4 , 1.7]
attenuations = np.linspace(0.15, 0.35, 9) # np.linspace(0.1,0.35,11)#np.linspace(0.1,0.35,6)#np.logspace(-3,0,num=7)
KBv_home = [1.3, 1.6]
KBh_home = [1.4, 1.7]
# Spacings
between_same_shots = 150
between_attenuations = 150
between_KB_settings = 500#500
between_KB_settings = 500 # 500
### 23.02
def kb_settings_list(best,step,no_steps):
def kb_settings_list(best, step, no_steps):
for i in range(no_steps):
if i == 0:
l=[]
l.append([best[0]+i*step,best[1]])
l = []
l.append([best[0] + i * step, best[1]])
for i in range(no_steps):
if i == 0:
pass
l.append([best[0],best[1]+i*step])
return l
l.append([best[0], best[1] + i * step])
return l
KBvs = kb_settings_list([1.595, 1.874], 0.05, 3)
KBhs = kb_settings_list([1.799000, 2.100000], 0.05, 3)
KBvs = kb_settings_list([1.595,1.874],0.05,3)
KBhs = kb_settings_list([1.799000,2.100000],0.05,3)
### 24.02
def kb_settings_list_new(best,step,no_steps_one_way):
l=[]
first = np.array(best) - np.array([step*no_steps_one_way,step*no_steps_one_way])
for i in range(no_steps_one_way*2+1):
l.append([first[0]+i*step,first[1]+i*step])
return l
KBvs = kb_settings_list_new([1.595,1.874],0.0075,3)
KBhs = kb_settings_list_new([1.799000,2.100000],0.0075,3)
def kb_settings_list_new(best, step, no_steps_one_way):
l = []
first = np.array(best) - np.array([step * no_steps_one_way, step * no_steps_one_way])
for i in range(no_steps_one_way * 2 + 1):
l.append([first[0] + i * step, first[1] + i * step])
return l
KBvs = kb_settings_list_new([1.595, 1.874], 0.0075, 3)
KBhs = kb_settings_list_new([1.799000, 2.100000], 0.0075, 3)
# Time estimates for total time calculation (time in seconds)
@ -75,29 +76,31 @@ t_atten_change = 10
smaract_stage = True
# Change to mm from um if smaract stage selected
if smaract_stage:
between_same_shots = between_same_shots/1000
between_attenuations = between_attenuations/1000
between_KB_settings = between_KB_settings/1000
between_same_shots = between_same_shots / 1000
between_attenuations = between_attenuations / 1000
between_KB_settings = between_KB_settings / 1000
def shoot(pos=pos,testing=testing_flag):
def shoot(pos=pos, testing=testing_flag):
if testing:
print(f'Shot at: {pos}')
print(f"Shot at: {pos}")
return pos
else:
print(f'Shot at: {pos}')
print(f"Shot at: {pos}")
sleep(2)
epics.caput("SAR-CCTA-ESC:seq0Ctrl-Start-I",1)
epics.caput("SAR-CCTA-ESC:seq0Ctrl-Start-I", 1)
pass
def change_benders(bender_1,bender_2,KB = None,do_not_move_benders = do_not_move_benders):
def change_benders(bender_1, bender_2, KB=None, do_not_move_benders=do_not_move_benders):
check_KB_value(KB)
current_values = get_bender_values(KB)
if current_values[0] > bender_1 or current_values[1] > bender_2:
print('Unbending first because of backlash')
print("Unbending first because of backlash")
if do_not_move_benders != True:
# Move home first
if KB == 'h' or KB == 'H':
if KB == "h" or KB == "H":
kbHor.bend1.set_target_value(KBh_home[0]).wait()
sleep(1)
kbHor.bend2.set_target_value(KBh_home[1]).wait()
@ -109,13 +112,13 @@ def change_benders(bender_1,bender_2,KB = None,do_not_move_benders = do_not_move
sleep(1)
if do_not_move_benders:
print(f'Bender 1 to: {bender_1}')
print(f'Bender 2 to: {bender_2}')
return
print(f"Bender 1 to: {bender_1}")
print(f"Bender 2 to: {bender_2}")
return
# Move to the new position
print(f'Changing {KB} bender to: [{bender_1} , {bender_2}]')
if KB == 'h' or KB == 'H':
print(f"Changing {KB} bender to: [{bender_1} , {bender_2}]")
if KB == "h" or KB == "H":
kbHor.bend1.set_target_value(bender_1).wait()
sleep(1)
kbHor.bend2.set_target_value(bender_2).wait()
@ -125,67 +128,72 @@ def change_benders(bender_1,bender_2,KB = None,do_not_move_benders = do_not_move
sleep(1)
kbVer.bend2.set_target_value(bender_2).wait()
sleep(1)
def check_KB_value(KB):
if KB not in ['H','h','V','v']:
raise KeyError(f"KB can only be horizontal (H) or vertical (V), not {KB}")
if KB not in ["H", "h", "V", "v"]:
raise KeyError(f"KB can only be horizontal (H) or vertical (V), not {KB}")
def get_bender_values(KB=None):
check_KB_value(KB)
if KB == 'h' or KB == 'H':
return [kbHor.bend1.get(),kbHor.bend2.get()]
if KB == "h" or KB == "H":
return [kbHor.bend1.get(), kbHor.bend2.get()]
else:
return [kbVer.bend1.get(),kbVer.bend2.get()]
return [kbVer.bend1.get(), kbVer.bend2.get()]
def move_x_rel(distance,testing=testing_flag,pos=pos):
def move_x_rel(distance, testing=testing_flag, pos=pos):
if testing == True:
pos = pos + np.array([distance,0])
pos = pos + np.array([distance, 0])
return pos
else:
if smaract_stage:
smaract_mini_XYZ.x.mvr(distance).wait()
else:
attocube.X.set_target_value(distance, relative=True).wait()
pos = pos + np.array([distance,0])
pos = pos + np.array([distance, 0])
return pos
def move_y_rel(distance,testing=testing_flag,pos=pos):
def move_y_rel(distance, testing=testing_flag, pos=pos):
if testing == True:
pos = pos + np.array([0,distance])
pos = pos + np.array([0, distance])
return pos
else:
if smaract_stage:
smaract_mini_XYZ.y.mvr(distance).wait()
else:
attocube.Y.set_target_value(distance, relative=True).wait()
pos = pos + np.array([0,distance])
pos = pos + np.array([0, distance])
return pos
def move_x(value,testing=testing_flag,pos=pos):
def move_x(value, testing=testing_flag, pos=pos):
if testing == True:
pos[0]=value
pos[0] = value
return pos
else:
if smaract_stage:
smaract_mini_XYZ.x.mv(value).wait()
else:
attocube.X.set_target_value(value, relative=False).wait()
return [value,pos[1]]
return [value, pos[1]]
def move_y(value,testing=testing_flag,pos=pos):
def move_y(value, testing=testing_flag, pos=pos):
if testing == True:
pos[1]=value
pos[1] = value
return pos
else:
if smaract_stage:
smaract_mini_XYZ.y.mv(value).wait()
else:
else:
attocube.Y.set_target_value(value, relative=False).wait()
return [pos[0],value]
return [pos[0], value]
def move(target_pos,testing=True,pos=pos):
def move(target_pos, testing=True, pos=pos):
if testing == True:
pass
else:
@ -198,16 +206,18 @@ def move(target_pos,testing=True,pos=pos):
pos = target_pos
return pos
def get_original_position(testing=testing_flag):
if testing == True:
original_position = pos
else:
if smaract_stage:
original_position = [smaract_mini_XYZ.x.get_current_value(),smaract_mini_XYZ.y.get_current_value()]
original_position = [smaract_mini_XYZ.x.get_current_value(), smaract_mini_XYZ.y.get_current_value()]
else:
original_position = [attocube.X.get_current_value(),attocube.Y.get_current_value()]
original_position = [attocube.X.get_current_value(), attocube.Y.get_current_value()]
return original_position
def set_attenuation(value):
attenuator.set_transmission(value)
sleep(1)
@ -215,20 +225,21 @@ def set_attenuation(value):
sleep(1)
return value
def make_attenuations(attenuations,testing=testing_flag,pos=pos):
def make_attenuations(attenuations, testing=testing_flag, pos=pos):
original_position = get_original_position(testing=testing)
# Make all attenuations
for attenuation in attenuations:
print(f'Setting attenuation to: {attenuation}')
print(f"Setting attenuation to: {attenuation}")
if testing:
print('Testing: no attenuator change')
print("Testing: no attenuator change")
else:
set_attenuation(attenuation)
print('Making same shots')
make_same_shots(n_same_holes,pos=pos,testing=testing)
pos = move_y_rel(between_attenuations,pos=pos,testing=testing)
print("Making same shots")
make_same_shots(n_same_holes, pos=pos, testing=testing)
pos = move_y_rel(between_attenuations, pos=pos, testing=testing)
# Return back to where you started
if testing == True:
pos = original_position
@ -236,24 +247,34 @@ def make_attenuations(attenuations,testing=testing_flag,pos=pos):
pos = move(original_position, testing=testing)
return pos
def make_same_shots(n_same_holes,testing=testing_flag,pos=pos):
def make_same_shots(n_same_holes, testing=testing_flag, pos=pos):
original_position = get_original_position(testing=testing)
# Make holes
for shot in range(n_same_holes):
sleep(1)
shoot(pos=pos,testing=testing)
pos = move_x_rel(between_same_shots,pos=pos,testing=testing)
# Return back to where you started
move(original_position,testing=testing)
shoot(pos=pos, testing=testing)
pos = move_x_rel(between_same_shots, pos=pos, testing=testing)
def estimate_total_time(KBhs=KBhs,KBvs=KBvs,attenuations=attenuations,n_same_holes=n_same_holes,t_kb_change=t_kb_change,t_atten_change=t_atten_change,t_shot=t_shot):
total_time = len(KBhs)*len(KBvs)*( t_kb_change+len(attenuations)*(t_atten_change+n_same_holes*t_shot) )
print(f'Total time estimate: {(total_time/60):.1f} minutes or {(total_time/60/60):.1f} hours')
# Return back to where you started
move(original_position, testing=testing)
def estimate_total_time(
KBhs=KBhs,
KBvs=KBvs,
attenuations=attenuations,
n_same_holes=n_same_holes,
t_kb_change=t_kb_change,
t_atten_change=t_atten_change,
t_shot=t_shot,
):
total_time = len(KBhs) * len(KBvs) * (t_kb_change + len(attenuations) * (t_atten_change + n_same_holes * t_shot))
print(f"Total time estimate: {(total_time/60):.1f} minutes or {(total_time/60/60):.1f} hours")
return total_time
# Get the starting x-position
if testing_flag == True:
starting_x_pos = pos[0]
@ -264,53 +285,54 @@ else:
starting_x_pos = attocube.X.get_current_value()
def make_everything(KBvs,KBhs,attenuations,n_same_holes,testing=testing_flag,pos=pos,do_not_move_benders=True):
def make_everything(KBvs, KBhs, attenuations, n_same_holes, testing=testing_flag, pos=pos, do_not_move_benders=True):
# The loop to make inprints
for i,KBv in enumerate(tqdm(KBvs)):
change_benders(KBv[0],KBv[1],KB = 'v',do_not_move_benders=do_not_move_benders)
for i, KBv in enumerate(tqdm(KBvs)):
change_benders(KBv[0], KBv[1], KB="v", do_not_move_benders=do_not_move_benders)
for ind,KBh in enumerate(KBhs):
change_benders(KBh[0],KBh[1],KB = 'h')
print(f'Progress so far: KBv loop: {i+1}/{len(KBvs)}. KBh loop:{ind+1}/{len(KBhs)}')
make_attenuations(attenuations,pos=pos,testing=testing)
for ind, KBh in enumerate(KBhs):
change_benders(KBh[0], KBh[1], KB="h")
print(f'Moving to a new KBh setting')
# Move to the last shot of the same shot + the spacing between KB settings
pos = move_x_rel(between_KB_settings+between_same_shots*(n_same_holes-1),pos=pos,testing=testing)
print(f"Progress so far: KBv loop: {i+1}/{len(KBvs)}. KBh loop:{ind+1}/{len(KBhs)}")
make_attenuations(attenuations, pos=pos, testing=testing)
print('KBh set done, returning to starting_x_pos')
# Move to the last shot of the same shot + the spacing between KB settings
print(f"Moving to a new KBh setting")
# Move to the last shot of the same shot + the spacing between KB settings
pos = move_x_rel(between_KB_settings + between_same_shots * (n_same_holes - 1), pos=pos, testing=testing)
pos = move_x(starting_x_pos,pos=pos,testing=testing)
print("KBh set done, returning to starting_x_pos")
# Move to the last shot of the same shot + the spacing between KB settings
print('#################################################################################')
print('Moving to a new KBv setting')
# Move to the last shot of the same shot + the spacing between KB settings
pos = move_x(starting_x_pos, pos=pos, testing=testing)
pos = move_y_rel(between_KB_settings+between_attenuations*(len(attenuations)-1),pos=pos,testing=testing)
print("#################################################################################")
print("Moving to a new KBv setting")
# Move to the last shot of the same shot + the spacing between KB settings
pos = move_y_rel(between_KB_settings + between_attenuations * (len(attenuations) - 1), pos=pos, testing=testing)
print('Inprints are done')
print("Inprints are done")
set_attenuation(1e-6)
status_pv = PV('SF-OP:ESC-MSG:STATUS')
status_pv = PV("SF-OP:ESC-MSG:STATUS")
status_pv.put(0)
# print(f'Total time estimate: {(total_time/60):.1f} minutes or {(total_time/60/60):.1f} hours')
# print(f'Total time estimate: {(total_time/60):.1f} minutes or {(total_time/60/60):.1f} hours')
# To do:
# Fix movement of the attocubes in real time
# Load lut files into the controller and check that x is x and y is y
def make_z_scan(z_list,n_same_holes,attenuations,vertical_spacing=0.150):
def make_z_scan(z_list, n_same_holes, attenuations, vertical_spacing=0.150):
original_position = get_original_position(testing=False)
for attenuation in attenuations:
set_attenuation(attenuation)
for z in z_list:
Newport_large.mv(z).wait()
sleep(1)
make_same_shots(n_same_holes,testing=False)
move_y_rel(vertical_spacing,testing=False)
move(original_position,testing=False)
make_same_shots(n_same_holes, testing=False)
move_y_rel(vertical_spacing, testing=False)
move(original_position, testing=False)
sleep(1)
move_x_rel(1,testing=False)
move_x_rel(1, testing=False)

464
retrieve.ipynb Normal file
View File

@ -0,0 +1,464 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "8960fc34-a3b8-4f3a-85a4-22ea697ee38a",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "1a5fa748-9641-4c93-b0bf-9a2a3ac58745",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2023-05-22 at 08:16:27 | INFO | Loading started.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b]0;⊚slic\u0007could not set up DBusNotify: org.freedesktop.DBus.Error.NoReply: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2023-05-22 at 08:16:32 | INFO | Connected to stand server\n",
"2023-05-22 at 08:16:33 | INFO | Using undulator (Aramis) offset to PSSS energy of 13 eV.\n",
"2023-05-22 at 08:16:33 | INFO | Running at cristallina with pgroup p21147.\n",
"2023-05-22 at 08:16:33 | INFO | Loading finished.\n"
]
}
],
"source": [
"%run cristallina.py"
]
},
{
"cell_type": "markdown",
"id": "69ae9d05-4a12-40b0-b0a7-d5436eaf23ea",
"metadata": {},
"source": [
"We recorded at 1 Hz with the CTA and 6000 repetions."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "09065809-9077-46b1-8fea-a13c0a92e2a2",
"metadata": {},
"outputs": [],
"source": [
"shots = 6000 # repetitions from CTA"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1713739a-6399-43fa-ad60-1ef2a0903d1a",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">array</span><span style=\"font-weight: bold\">([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">120000</span>., <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">180000</span>., <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">240000</span>., <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">300000</span>., <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">360000</span>., <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">420000</span>., <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">480000</span>.,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">540000</span>.<span style=\"font-weight: bold\">])</span>\n",
"</pre>\n"
],
"text/plain": [
"\n",
"\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m\u001b[1;36m120000\u001b[0m., \u001b[1;36m180000\u001b[0m., \u001b[1;36m240000\u001b[0m., \u001b[1;36m300000\u001b[0m., \u001b[1;36m360000\u001b[0m., \u001b[1;36m420000\u001b[0m., \u001b[1;36m480000\u001b[0m.,\n",
" \u001b[1;36m540000\u001b[0m.\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"pids = shots*100\n",
"\n",
"missing = np.arange(2,10)*pids/10\n",
"missing\n"
]
},
{
"cell_type": "markdown",
"id": "a15fc525-b909-43a1-a105-bf13272a3257",
"metadata": {},
"source": [
"Missing are the images from pids 12000 to 18000, 18000 to 24000 and so on. Already recorded are the first 60000.\n"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "0b0d72f1-9528-4077-89f1-1476b4b74411",
"metadata": {},
"outputs": [],
"source": [
"# with scratch pgroup:\n",
"\n",
"daq_test = SFAcquisition(\n",
" instrument,\n",
" \"p19150\",\n",
" default_channels=bs_channels,\n",
" default_pvs=pvs,\n",
" default_detectors=detectors,\n",
" rate_multiplicator=100,\n",
")\n",
"\n",
"slow_daq_test = SFAcquisition(\n",
" instrument,\n",
" \"p19150\",\n",
" default_channels=bs_channels,\n",
" default_pvs=pvs,\n",
" default_detectors=detectors,\n",
" rate_multiplicator=100,\n",
")\n",
"\n",
"slow_daq = SFAcquisition(\n",
" instrument,\n",
" pgroup,\n",
" default_channels=bs_channels,\n",
" default_pvs=pvs,\n",
" default_detectors=detectors,\n",
" rate_multiplicator=100,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d1db9525-bb0e-4c32-8aa5-752091928bbd",
"metadata": {},
"outputs": [],
"source": [
"pgroup = \"p21147\" # SAXS\n",
"\n",
"if False:\n",
" res = daq.retrieve(\n",
" \"CTA_pulses\",\n",
" np.arange(CTA_sequence_start_PID, CTA_sequence_start_PID + n_pulses * 10),\n",
" run_number=run_number,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "77d93f9d-2a11-4059-966f-4640f1ea86b0",
"metadata": {},
"outputs": [
{
"ename": "BrokerError",
"evalue": "An error happened on the server:\nUnknown error",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mBrokerError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[11], line 5\u001b[0m\n\u001b[1;32m 1\u001b[0m CTA_sequence_start_PID \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m18111678900\u001b[39m\n\u001b[1;32m 3\u001b[0m length \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m200\u001b[39m\n\u001b[0;32m----> 5\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mslow_daq_test\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mretrieve\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 6\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mCTA_pulses\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marange\u001b[49m\u001b[43m(\u001b[49m\u001b[43mCTA_sequence_start_PID\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mCTA_sequence_start_PID\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mlength\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_number\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 9\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/sfacquisition.py:125\u001b[0m, in \u001b[0;36mSFAcquisition.retrieve\u001b[0;34m(self, filename, pulseids, run_number)\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m is_continuous(pulseids):\n\u001b[1;32m 123\u001b[0m params[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mselected_pulse_ids\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m pulseids\n\u001b[0;32m--> 125\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mretrieve\u001b[49m\u001b[43m(\u001b[49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43maddress\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 127\u001b[0m res_run_number \u001b[38;5;241m=\u001b[39m res[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 128\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m res_run_number \u001b[38;5;241m==\u001b[39m run_number, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mreceived \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mres_run_number\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m and expected \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrun_number\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m run numbers not identical\u001b[39m\u001b[38;5;124m\"\u001b[39m\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/broker_client.py:251\u001b[0m, in \u001b[0;36mretrieve\u001b[0;34m(address, *args, **kwargs)\u001b[0m\n\u001b[1;32m 249\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mretrieve\u001b[39m(address, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 250\u001b[0m requrl \u001b[38;5;241m=\u001b[39m address\u001b[38;5;241m.\u001b[39mrstrip(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/retrieve_from_buffers\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m--> 251\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mpost_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequrl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 252\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mdict\u001b[39m(\n\u001b[1;32m 253\u001b[0m run_number \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]),\n\u001b[1;32m 254\u001b[0m acq_number \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124macquisition_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]),\n\u001b[1;32m 255\u001b[0m total_acq_number \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124munique_acquisition_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]),\n\u001b[1;32m 256\u001b[0m filenames \u001b[38;5;241m=\u001b[39m response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfiles\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 257\u001b[0m )\n\u001b[1;32m 258\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m res\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/broker_client.py:275\u001b[0m, in \u001b[0;36mpost_request\u001b[0;34m(requrl, params, timeout)\u001b[0m\n\u001b[1;32m 273\u001b[0m params \u001b[38;5;241m=\u001b[39m json_validate(params)\n\u001b[1;32m 274\u001b[0m response \u001b[38;5;241m=\u001b[39m requests\u001b[38;5;241m.\u001b[39mpost(requrl, json\u001b[38;5;241m=\u001b[39mparams, timeout\u001b[38;5;241m=\u001b[39mtimeout)\u001b[38;5;241m.\u001b[39mjson()\n\u001b[0;32m--> 275\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mvalidate_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresponse\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/broker_client.py:289\u001b[0m, in \u001b[0;36mvalidate_response\u001b[0;34m(resp)\u001b[0m\n\u001b[1;32m 287\u001b[0m message \u001b[38;5;241m=\u001b[39m resp\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessage\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUnknown error\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 288\u001b[0m msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAn error happened on the server:\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(message)\n\u001b[0;32m--> 289\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m BrokerError(msg)\n",
"\u001b[0;31mBrokerError\u001b[0m: An error happened on the server:\nUnknown error"
]
}
],
"source": [
"CTA_sequence_start_PID = 18111678900\n",
"\n",
"length = 200\n",
"\n",
"res = slow_daq_test.retrieve(\n",
" \"CTA_pulses\",\n",
" np.arange(CTA_sequence_start_PID, CTA_sequence_start_PID + length),\n",
" run_number=None,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "0733b5e8-b7f0-4693-b772-670ee62d6e35",
"metadata": {},
"outputs": [
{
"ename": "BrokerError",
"evalue": "An error happened on the server:\nUnknown error",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mBrokerError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[11], line 6\u001b[0m\n\u001b[1;32m 2\u001b[0m CTA_sequence_start_PID \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m18111618800\u001b[39m\n\u001b[1;32m 4\u001b[0m length \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1000\u001b[39m\n\u001b[0;32m----> 6\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mslow_daq\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mretrieve\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mCTA_pulses\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marange\u001b[49m\u001b[43m(\u001b[49m\u001b[43mCTA_sequence_start_PID\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mCTA_sequence_start_PID\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mlength\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 9\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_number\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m1120\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 10\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/sfacquisition.py:125\u001b[0m, in \u001b[0;36mSFAcquisition.retrieve\u001b[0;34m(self, filename, pulseids, run_number)\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m is_continuous(pulseids):\n\u001b[1;32m 123\u001b[0m params[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mselected_pulse_ids\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m pulseids\n\u001b[0;32m--> 125\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mretrieve\u001b[49m\u001b[43m(\u001b[49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43maddress\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 127\u001b[0m res_run_number \u001b[38;5;241m=\u001b[39m res[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 128\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m res_run_number \u001b[38;5;241m==\u001b[39m run_number, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mreceived \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mres_run_number\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m and expected \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrun_number\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m run numbers not identical\u001b[39m\u001b[38;5;124m\"\u001b[39m\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/broker_client.py:251\u001b[0m, in \u001b[0;36mretrieve\u001b[0;34m(address, *args, **kwargs)\u001b[0m\n\u001b[1;32m 249\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mretrieve\u001b[39m(address, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 250\u001b[0m requrl \u001b[38;5;241m=\u001b[39m address\u001b[38;5;241m.\u001b[39mrstrip(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/retrieve_from_buffers\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m--> 251\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mpost_request\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequrl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 252\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mdict\u001b[39m(\n\u001b[1;32m 253\u001b[0m run_number \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]),\n\u001b[1;32m 254\u001b[0m acq_number \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124macquisition_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]),\n\u001b[1;32m 255\u001b[0m total_acq_number \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124munique_acquisition_number\u001b[39m\u001b[38;5;124m\"\u001b[39m]),\n\u001b[1;32m 256\u001b[0m filenames \u001b[38;5;241m=\u001b[39m response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfiles\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 257\u001b[0m )\n\u001b[1;32m 258\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m res\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/broker_client.py:275\u001b[0m, in \u001b[0;36mpost_request\u001b[0;34m(requrl, params, timeout)\u001b[0m\n\u001b[1;32m 273\u001b[0m params \u001b[38;5;241m=\u001b[39m json_validate(params)\n\u001b[1;32m 274\u001b[0m response \u001b[38;5;241m=\u001b[39m requests\u001b[38;5;241m.\u001b[39mpost(requrl, json\u001b[38;5;241m=\u001b[39mparams, timeout\u001b[38;5;241m=\u001b[39mtimeout)\u001b[38;5;241m.\u001b[39mjson()\n\u001b[0;32m--> 275\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mvalidate_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresponse\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[0;32m/gfa/.mounts/sf_cristallina/applications/slic/slic-package/slic/core/acquisition/broker_client.py:289\u001b[0m, in \u001b[0;36mvalidate_response\u001b[0;34m(resp)\u001b[0m\n\u001b[1;32m 287\u001b[0m message \u001b[38;5;241m=\u001b[39m resp\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessage\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUnknown error\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 288\u001b[0m msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAn error happened on the server:\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(message)\n\u001b[0;32m--> 289\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m BrokerError(msg)\n",
"\u001b[0;31mBrokerError\u001b[0m: An error happened on the server:\nUnknown error"
]
}
],
"source": [
"CTA_sequence_start_PID = 18111678900\n",
"CTA_sequence_start_PID = 18111618800\n",
"\n",
"length = 1000\n",
"\n",
"res = slow_daq.retrieve(\n",
" \"CTA_pulses\",\n",
" np.arange(CTA_sequence_start_PID, CTA_sequence_start_PID + length),\n",
" run_number=1120,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "a0b1dece-021b-4bf5-9031-3db06c56b8fb",
"metadata": {},
"outputs": [],
"source": [
"#CTA_sequence_start_PID = 18111678900\n",
"CTA_sequence_start_PID = 18111618800\n",
"CTA_sequence_start_PID = 18116377800\n",
"\n",
"CTA_sequence_start_PID = 18114660400 # works\n",
"CTA_sequence_start_PID = 18113444000 # fails \n",
"CTA_sequence_start_PID = 18114052200 # fails\n",
"\n",
"\n",
"CTA_sequence_start_PID = 18114660400 # works\n",
"\n",
"length = 60000\n",
"\n",
"\n",
"for start_pid in [18114720400, 18114780500, 18114840600, 18114900700, 18114960800,\n",
" 18115020900, 18115081000, 18115141100, 18115201200, 18115261300]:\n",
"\n",
" res = slow_daq.retrieve(\n",
" \"CTA_pulses\",\n",
" np.arange(start_pid, start_pid + length),\n",
" run_number=1129,\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "684e664b-fe6d-404d-86b9-7a223fa990c3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Advanced run number to 1129.\n",
"No detectors specified, using default detector list.\n",
"No PVs specified, using default PV list.\n",
"No channels specified, using default channel list.\n",
"\u001b[31m\u001b[1mOffline Channels:\n",
"-----------------\n",
"- SAR-CVME-TIFALL6:EvtSet\n",
"- SARFE10-PSSS059:FIT_ERR\n",
"- SARFE10-PSSS059:SPECTRUM_AVG_CENTER\n",
"- SARFE10-PSSS059:SPECTRUM_AVG_FWHM\n",
"- SARFE10-PSSS059:SPECTRUM_AVG_Y\n",
"\u001b[39m\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 1%|██ | 2/200 [00:03<05:02, 1.5s/@]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"run number: 1129\n",
"acq number: 1\n",
"total acq number: 1970\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n"
]
},
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"DAQTask: done\n",
"\n",
"Output files:\n",
"-------------\n",
"- <span style=\"color: #800080; text-decoration-color: #800080\">/sf/cristallina/data/p21147/raw/run1129/data/</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff\">acq0001.PVDATA.h5</span>\n",
"- <span style=\"color: #800080; text-decoration-color: #800080\">/sf/cristallina/data/p21147/raw/run1129/data/</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff\">acq0001.BSDATA.h5</span>\n",
"- <span style=\"color: #800080; text-decoration-color: #800080\">/sf/cristallina/data/p21147/raw/run1129/data/</span><span style=\"color: #ff00ff; text-decoration-color: #ff00ff\">acq0001.JF16T03V01.h5</span>\n",
"</pre>\n"
],
"text/plain": [
"\n",
"DAQTask: done\n",
"\n",
"Output files:\n",
"-------------\n",
"- \u001b[35m/sf/cristallina/data/p21147/raw/run1129/data/\u001b[0m\u001b[95macq0001.PVDATA.h5\u001b[0m\n",
"- \u001b[35m/sf/cristallina/data/p21147/raw/run1129/data/\u001b[0m\u001b[95macq0001.BSDATA.h5\u001b[0m\n",
"- \u001b[35m/sf/cristallina/data/p21147/raw/run1129/data/\u001b[0m\u001b[95macq0001.JF16T03V01.h5\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"slow_daq.acquire('something', n_pulses=2)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "3852ea6f-b014-402b-ba9c-fb5778a76e00",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">array</span><span style=\"font-weight: bold\">([</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114720400</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114780500</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114840600</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114900700</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114960800</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115020900</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115081000</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115141100</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115201200</span>, <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115261300</span><span style=\"font-weight: bold\">])</span>\n",
"</pre>\n"
],
"text/plain": [
"\n",
"\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m\u001b[1;36m18114720400\u001b[0m, \u001b[1;36m18114780500\u001b[0m, \u001b[1;36m18114840600\u001b[0m, \u001b[1;36m18114900700\u001b[0m, \u001b[1;36m18114960800\u001b[0m,\n",
" \u001b[1;36m18115020900\u001b[0m, \u001b[1;36m18115081000\u001b[0m, \u001b[1;36m18115141100\u001b[0m, \u001b[1;36m18115201200\u001b[0m, \u001b[1;36m18115261300\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"np.array([[18114720400],\n",
" [18114780500],\n",
" [18114840600],\n",
" [18114900700],\n",
" [18114960800],\n",
" [18115020900],\n",
" [18115081000],\n",
" [18115141100],\n",
" [18115201200],\n",
" [18115261300]]).flatten()\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "c4de9b27-2721-449b-a3e6-6658d3e611c8",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
"<span style=\"font-weight: bold\">[</span>\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114720400</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114780500</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114840600</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114900700</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18114960800</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115020900</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115081000</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115141100</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115201200</span>,\n",
" <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">18115261300</span>\n",
"<span style=\"font-weight: bold\">]</span>\n",
"</pre>\n"
],
"text/plain": [
"\n",
"\u001b[1m[\u001b[0m\n",
" \u001b[1;36m18114720400\u001b[0m,\n",
" \u001b[1;36m18114780500\u001b[0m,\n",
" \u001b[1;36m18114840600\u001b[0m,\n",
" \u001b[1;36m18114900700\u001b[0m,\n",
" \u001b[1;36m18114960800\u001b[0m,\n",
" \u001b[1;36m18115020900\u001b[0m,\n",
" \u001b[1;36m18115081000\u001b[0m,\n",
" \u001b[1;36m18115141100\u001b[0m,\n",
" \u001b[1;36m18115201200\u001b[0m,\n",
" \u001b[1;36m18115261300\u001b[0m\n",
"\u001b[1m]\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"[18114720400, 18114780500, 18114840600, 18114900700, 18114960800,\n",
" 18115020900, 18115081000, 18115141100, 18115201200, 18115261300]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a8be60a2-d85b-4cbc-8e8b-ffd749b09d15",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.16"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -1,3 +0,0 @@
#!/bin/bash
echo /sf/cristallina/$1/res

View File

@ -8,94 +8,85 @@ class PVStringAdjustable(PVAdjustable):
return self.pvs.readback.get(as_string=True).strip()
n_unds = [
6, 7, 8, 9, 10, 11, 12, 13, # 14 is the CHIC
15, 16, 17, 18, 19, 20, 21, 22
]
n_unds = [6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22] # 14 is the CHIC
#UND_NAME_FMT = "SARUN{:02}-UIND030"
#N_UND_CHIC = None
# UND_NAME_FMT = "SARUN{:02}-UIND030"
# N_UND_CHIC = None
#N_UNDS = list(range(3, 15+1))
# N_UNDS = list(range(3, 15+1))
#undulator_info = {}
#for i in n_unds:
# undulator_info = {}
# for i in n_unds:
# undulator_info[f"energy{i}"] = PVAdjustable(f"SARUN{i:02}-UIND030:FELPHOTENE", internal=True)
# undulator_info[f"polarisation{i}"] = PVEnumAdjustable(f"SARUN{i:02}-UIND030:POL-SET", internal=True)
overview = SimpleDevice("Cristallina Overview",
OKHB154_X_trans = PVAdjustable("SAROP31-OKBH154:W_X.RBV", internal=True),
OKHB154_Y_trans = PVAdjustable("SAROP31-OKBH154:W_Y.RBV", internal=True),
OKHB154_X_rot = PVAdjustable("SAROP31-OKBH154:W_RX.RBV", internal=True),
OKHB154_Y_rot = PVAdjustable("SAROP31-OKBH154:W_RY.RBV", internal=True),
OKHB154_Z_rot = PVAdjustable("SAROP31-OKBH154:W_RZ.RBV", internal=True),
OKBV153_X_trans = PVAdjustable("SAROP31-OKBV153:W_X.RBV", internal=True),
OKBV153_Y_trans = PVAdjustable("SAROP31-OKBV153:W_Y.RBV", internal=True),
OKBV153_X_rot = PVAdjustable("SAROP31-OKBV153:W_RX.RBV", internal=True),
OKBV153_Y_rot = PVAdjustable("SAROP31-OKBV153:W_RY.RBV", internal=True),
OKBV153_Z_rot = PVAdjustable("SAROP31-OKBV153:W_RZ.RBV", internal=True),
ODMV152_X_trans = PVAdjustable("SAROP31-OKBV153:W_X.RBV", internal=True),
ODMV152_Y_trans = PVAdjustable("SAROP31-OKBV153:W_Y.RBV", internal=True),
ODMV152_X_rot = PVAdjustable("SAROP31-OKBV153:W_RX.RBV", internal=True),
ODMV152_Y_rot = PVAdjustable("SAROP31-OKBV153:W_RY.RBV", internal=True),
ODMV152_COATING = PVAdjustable("SAROP31-ODMV152:COATING_SP", internal=True),
OATA150_transmission = PVAdjustable("SAROP31-OATA150:TRANS_SP", internal=True),
PBPS149_motor_probe = PVAdjustable("SAROP31-PBPS149:MOTOR_PROBE.RBV", internal=True),
PBPS149_motor_X1 = PVAdjustable("SAROP31-PBPS149:MOTOR_X1.RBV", internal=True),
PBPS149_motor_Y1 = PVAdjustable("SAROP31-PBPS149:MOTOR_Y1.RBV", internal=True),
PBPS149_wafer = PVAdjustable("SAROP31-PBPS149:PROBE_SP", internal=True),
OAPU149_hor_pos = PVAdjustable("SAROP31-OAPU149:MOTOR_X.VAL", internal=True),
OAPU149_hor_width = PVAdjustable("SAROP31-OAPU149:MOTOR_W.VAL", internal=True),
OAPU149_vert_pos = PVAdjustable("SAROP31-OAPU149:MOTOR_Y.VAL", internal=True),
OAPU149_vert_width = PVAdjustable("SAROP31-OAPU149:MOTOR_H.VAL", internal=True),
OAPU107_hor_pos = PVAdjustable("SAROP31-OAPU107:MOTOR_X.VAL", internal=True),
OAPU107_hor_width = PVAdjustable("SAROP31-OAPU107:MOTOR_W.VAL", internal=True),
OAPU107_vert_pos = PVAdjustable("SAROP31-OAPU107:MOTOR_Y.VAL", internal=True),
OAPU107_vert_width = PVAdjustable("SAROP31-OAPU107:MOTOR_H.VAL", internal=True),
OOMH084_X_trans = PVAdjustable("SAROP31-OOMH084:W_X.RBV", internal=True),
OOMH084_Y_trans = PVAdjustable("SAROP31-OOMH084:W_Y.RBV", internal=True),
OOMH084_X_rot = PVAdjustable("SAROP31-OOMH084:W_RX.RBV", internal=True),
OOMH084_Y_rot = PVAdjustable("SAROP31-OOMH084:W_RY.RBV", internal=True),
OOMH084_Z_rot = PVAdjustable("SAROP31-OOMH084:W_RZ.RBV", internal=True),
OOMH084_COATING = PVAdjustable("SAROP31-OOMH084:COATING_SP", internal=True),
OOMH067_X_trans = PVAdjustable("SAROP31-OOMH067:W_X.RBV", internal=True),
OOMH067_Y_trans = PVAdjustable("SAROP31-OOMH067:W_Y.RBV", internal=True),
OOMH067_X_rot = PVAdjustable("SAROP31-OOMH067:W_RX.RBV", internal=True),
OOMH067_Y_rot = PVAdjustable("SAROP31-OOMH067:W_RY.RBV", internal=True),
OOMH067_Z_rot = PVAdjustable("SAROP31-OOMH067:W_RZ.RBV", internal=True),
OOMH067_COATING = PVAdjustable("SAROP31-OOMH067:COATING_SP", internal=True),
overview = SimpleDevice(
"Cristallina Overview",
# OKHB154_X_trans = PVAdjustable("SAROP31-OKBH154:W_X.RBV", internal=True),
# OKHB154_Y_trans = PVAdjustable("SAROP31-OKBH154:W_Y.RBV", internal=True),
# OKHB154_X_rot = PVAdjustable("SAROP31-OKBH154:W_RX.RBV", internal=True),
# OKHB154_Y_rot = PVAdjustable("SAROP31-OKBH154:W_RY.RBV", internal=True),
# OKHB154_Z_rot = PVAdjustable("SAROP31-OKBH154:W_RZ.RBV", internal=True),
# OKBV153_X_trans = PVAdjustable("SAROP31-OKBV153:W_X.RBV", internal=True),
# OKBV153_Y_trans = PVAdjustable("SAROP31-OKBV153:W_Y.RBV", internal=True),
# OKBV153_X_rot = PVAdjustable("SAROP31-OKBV153:W_RX.RBV", internal=True),
# OKBV153_Y_rot = PVAdjustable("SAROP31-OKBV153:W_RY.RBV", internal=True),
# OKBV153_Z_rot = PVAdjustable("SAROP31-OKBV153:W_RZ.RBV", internal=True),
# ODMV152_X_trans = PVAdjustable("SAROP31-OKBV153:W_X.RBV", internal=True),
# ODMV152_Y_trans = PVAdjustable("SAROP31-OKBV153:W_Y.RBV", internal=True),
# ODMV152_X_rot = PVAdjustable("SAROP31-OKBV153:W_RX.RBV", internal=True),
# ODMV152_Y_rot = PVAdjustable("SAROP31-OKBV153:W_RY.RBV", internal=True),
# ODMV152_COATING = PVAdjustable("SAROP31-ODMV152:COATING_SP", internal=True),
OATA150_transmission=PVAdjustable("SAROP31-OATA150:TRANS_SP", internal=True),
# PBPS149_motor_probe = PVAdjustable("SAROP31-PBPS149:MOTOR_PROBE.RBV", internal=True),
# PBPS149_motor_X1 = PVAdjustable("SAROP31-PBPS149:MOTOR_X1.RBV", internal=True),
# PBPS149_motor_Y1 = PVAdjustable("SAROP31-PBPS149:MOTOR_Y1.RBV", internal=True),
# PBPS149_wafer = PVAdjustable("SAROP31-PBPS149:PROBE_SP", internal=True),
# OAPU149_hor_pos = PVAdjustable("SAROP31-OAPU149:MOTOR_X.VAL", internal=True),
# OAPU149_hor_width = PVAdjustable("SAROP31-OAPU149:MOTOR_W.VAL", internal=True),
# OAPU149_vert_pos = PVAdjustable("SAROP31-OAPU149:MOTOR_Y.VAL", internal=True),
# OAPU149_vert_width = PVAdjustable("SAROP31-OAPU149:MOTOR_H.VAL", internal=True),
# OAPU107_hor_pos = PVAdjustable("SAROP31-OAPU107:MOTOR_X.VAL", internal=True),
# OAPU107_hor_width = PVAdjustable("SAROP31-OAPU107:MOTOR_W.VAL", internal=True),
# OAPU107_vert_pos = PVAdjustable("SAROP31-OAPU107:MOTOR_Y.VAL", internal=True),
# OAPU107_vert_width = PVAdjustable("SAROP31-OAPU107:MOTOR_H.VAL", internal=True),
# OOMH084_X_trans = PVAdjustable("SAROP31-OOMH084:W_X.RBV", internal=True),
# OOMH084_Y_trans = PVAdjustable("SAROP31-OOMH084:W_Y.RBV", internal=True),
# OOMH084_X_rot = PVAdjustable("SAROP31-OOMH084:W_RX.RBV", internal=True),
# OOMH084_Y_rot = PVAdjustable("SAROP31-OOMH084:W_RY.RBV", internal=True),
# OOMH084_Z_rot = PVAdjustable("SAROP31-OOMH084:W_RZ.RBV", internal=True),
# OOMH084_COATING = PVAdjustable("SAROP31-OOMH084:COATING_SP", internal=True),
# OOMH067_X_trans = PVAdjustable("SAROP31-OOMH067:W_X.RBV", internal=True),
# OOMH067_Y_trans = PVAdjustable("SAROP31-OOMH067:W_Y.RBV", internal=True),
# OOMH067_X_rot = PVAdjustable("SAROP31-OOMH067:W_RX.RBV", internal=True),
# OOMH067_Y_rot = PVAdjustable("SAROP31-OOMH067:W_RY.RBV", internal=True),
# OOMH067_Z_rot = PVAdjustable("SAROP31-OOMH067:W_RZ.RBV", internal=True),
# OOMH067_COATING = PVAdjustable("SAROP31-OOMH067:COATING_SP", internal=True),
SMARACT_MINI_X=PVAdjustable("SARES30-MCS2750:MOT_2.RBV", internal=True),
SMARACT_MINI_Y=PVAdjustable("SARES30-MCS2750:MOT_3.RBV", internal=True),
SMARACT_MINI_Z=PVAdjustable("SARES30-MCS2750:MOT_1.RBV", internal=True),
)
spreadsheet_line = []
spreadsheet_line = [
]
@as_shortcut
def print_overview():
print(overview)
@as_shortcut
def print_line_for_spreadsheet():
ov = overview.__dict__
def get(i):
if i in ov:
return str(ov[i].get())
return ""
res = [get(i) for i in spreadsheet_line]
res = ",".join(res)
print(res)