Initial slic setup at cristallina
This commit is contained in:
293
PSSS_motion.py
Normal file
293
PSSS_motion.py
Normal file
@@ -0,0 +1,293 @@
|
||||
#!/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()
|
||||
|
||||
Reference in New Issue
Block a user