Files
x06da/script/seteq.py
2016-04-15 15:24:36 +02:00

96 lines
3.0 KiB
Python

#def seteq(e):
# this is sete not so quick version.
# mono two rotation stages are not as recise as needed.
# for quick energy change (needed for energy scan), move two thetas with same amount sometime go off the rocking curve.
# possible solutions:
# 1) check flux, if low , rock --> slow
# 2) maxth1 to adjust theta1
# 3) reduce 'Retry deadband' to 0.0001 (from 0.00004) and 'Retries Max' to 1 (from 5) --> use encoder too much will make things worse.
# what's the flux at beginning
Istart = mono_beam.read()
if e < 4.6 or e > 17.5:
raise Exception('ERROR:Energy out of range: 4.6 to 17.5 keV')
if fe_absorber.read()!= 'OPEN':
raise Exception ('FrontEndAbsorber closed') # FrontEnd absorber shutter state
if fe_shutter.read() != "OPEN":
raise Exception ('FrontendShutter closed')
if exp_shutter.read() == 'CLOSED':
raise Exception('Experiments hutch shutter closed - program needs beam for alignment')
e0 = get_energy(False)
#X06DA-ES-BPM1:POSV before energy change
eboxbpm0 = es_beam_posv.read()
print 'X06DA-ES-BPM1 vertial feedback to max flux'
print "X06DA-ES-BPM1:POSV BEFORE" + str(eboxbpm0)
#--------------- setting theta 1, 2 --------------------
# adjust 'Retry deadband' to 0.0001 (from 0.00004) and 'Retries Max' to 1 (from 5)
try:
caput(th1.channelName +'.RDBD',0.00001)
caput(th2.channelName +'.RDBD',0.00001)
caput(th1.channelName +'.RTRY',1)
caput(th2.channelName +'.RTRY',1)
#in order to do a small energy change without rock,
# 1) move theta2 to calculated angle
# 2) move theta1 to exact amount as theta2 moved
while (abs(e-e0) > (3e-5 / math.tan(angle(e, deg=False)))):
t1v = th1.read() #TODO: setpoint?
t2v = th2.read()
t2s = angle(float(e),1,1,1, deg=True)
dt2 = t2s-t2v
dt1 = -dt2
t1p = t1v+dt1
t2p = t2s # which is t2v+dt2
print 'set angles th1, th2, relative move dt1, dt2 ', t1p, t2p, dt1, dt2
th1.move(t1p)
th2.move(t2p)
e0=get_energy(False)
time.sleep(2.0)
Inow = mono_beam.read()
print e, Istart, Inow
# feedback at BPM5
eboxbpm = es_beam_posv.read()
while abs(eboxbpm-eboxbpm0) > 0.002:
if (eboxbpm-eboxbpm0) >0:
th1.moveRel(-0.00004)
else:
th1.moveRel(0.00004)
time.sleep(1.0)
eboxbpm = es_beam_posv.read()
# if BPM1:POSV is too off, stop it
if eboxbpm > 0.050:
raise Exception("BPM1:POSV is too off")
# put 'Retry deadband' to 0.00004 and 'Retries Max' to 5
# wait a bit until motor movement finished (of course, this won't work if move across large energy range. but who use seteq to do that.)
time.sleep(0.2)
finally:
caput(th1.channelName +'.RDBD',0.00004)
caput(th2.channelName +'.RDBD',0.00004)
caput(th1.channelName +'.RTRY',5)
caput(th2.channelName +'.RTRY',5)
e0 = get_energy()
print e0
mono_energy.write(e0)
print mono_energy.read()
# release the token!
#free_setetoken
print 'seteq_done'