This commit is contained in:
2019-03-06 11:33:37 +01:00
parent 1f5fcb7ad8
commit 23fa8c8b99
16 changed files with 10 additions and 857 deletions

View File

@@ -1,4 +0,0 @@
print caget("X06DA-OP-BPM1:SUM")
print mono_beam.read()

View File

@@ -1,79 +0,0 @@
slits = ['Primaries horizontal','Primaries Vertical',
'ExpBox Tert. horizontal ','ExpBox Tert. vertical',
'ExpBox Quart. horizontal','ExpBox Quart. vertical']
ev = get_string('Please select slits', None, slits)
if ev is None:
raise Exception("Aborted")
elif ev == slits[0]: #Primaries-Horizontal after collimating mirror and before mono
mmot = phs # slit size
smot = phc # slit centre
r = 10.0 # scan half range
pclose = r/10. # slit size for scan
popen = 12.0 # slit size in open position
detector = mono_beam
#MESSAGE,'Not ready yet',/cont
elif ev == slits[0]: #Primaries-Vertical before collimating mirror
mmot = pvs
smot = pvc
r = 2.0
pclose = r/10.
popen = 2.0
detector = mono_beam
#MESSAGE,'Not ready yet',/cont
elif ev == slits[2]: #Exposure box Tertiary slits-Horizontal before IO
mmot = ths
smot = thc
r = 1.0
pclose = r/10.0
popen = 1.0
detector = Channel('X06DA-ES-BM:I0', 'd')
elif ev == slits[0]: #Exposure box Tertiary slits-Vertical
mmot = tvs
smot = tvc
r = 0.4
pclose = r/4.
popen = .4
detector = Channel('X06DA-ES-BM:I0', 'd')
elif ev == slits[0]: #Exposure box Quartenary slits-Horizontal after I0
mmot = qhs
smot = qhc
r = 0.4
pclose = r/8.
popen = .40
detector = marcover
#MESSAGE,'To make sure the diode is connected',/cont
elif ev == slits[5]: #Exposure box Quartenary slits-Vertical
mmot = qvs
smot = qvc
r = 0.3
pclose = r/6.
popen = .20
detector = mono_beam
#MESSAGE,'To make sure the diode is connected',/cont
mmot.write(pclose)
result = lscan(smot, detector, -r,r, 20, latency = 0.5, relative = True) #SCAN,smot,-r,r,20,data=d,gfit=a,time=.5,detec=detector
(ydata, xdata) = (result.getReadable(0), result.getPositions(0))
ydata = [x*1e6 for x in ydata]
maxy = max(ydata) #MAX(y,im)
cen =sum([ydata[i] * xdata[i] for i in range(len(ydata))]) / sum(ydata) #TOTAL(x*y) / TOTAL(y) #TODO: is right?
#OPLOT,x,GAUSSFIT(x,y,a,ESTIMATES = [maxy,cen,pclose,0,0,0],nterms=6)*1e-6, color=240,psym=6
(n, m, s) = fit(ydata, xdata)
#help,mmot
mmot.write(popen)
if abs(m) < 1 and abs(m-cen) < 0.5: #TODO: is a(1) the mean?
print 'moving centre of slits to: ', m
smot.mov(m)
else:
#PLOTS,cen,[0,maxy]*1e6,color=240,linestyle=1 : #TODO ?
msg='fit failed - do you want to drive to centre of mass position: '+ cen +' ?'
if get_option(msg, 'YesNo') == 'Yes':
smot.mov(cen)

View File

@@ -1,90 +0,0 @@
# check_rock.com: a shell script to call idl routine to rock first or second crystal at X06DA
# when the flux is low
# purpose: to prevent crystal falls off the rocking curve when the temp of first crystal change.
# 20080506 meitian
# 20100621 mt & vo -> new CVD BPM in mono. check flux and ROCK, and then check vertical beam position and FBM
print "======"
print "check&rock"
print "======"
# get energy first with simple calculation (i.e. not very accurate)
THETA1 = th1.read()
THETA2 = th2.read()
ENERGY = get_energy()
if int(ENERGY) < 6:
raise Exception("No rocking optimization for lower energy for 3rd harmonics rejection")
# if theta1 and theta2 differ too much (>0.01deg), rock won't work well, sete should be used in this case
# 20130614, change threshold from 0.015 to 0.02
if abs(THETA1 + THETA2) > 0.02:
raise Exception("Two mono crystals are not synchronized, please use 'sete()'")
#
# check the flux
print "check and rock"
BPM1C1 = caget("X06DA-OP-BPM1:CHAN1", 'd')
BPM1C2 = caget("X06DA-OP-BPM1:CHAN2", 'd')
BPM1C3 = caget("X06DA-OP-BPM1:CHAN3", 'd')
BPM1C4 = caget("X06DA-OP-BPM1:CHAN4", 'd')
BPM1 = (BPM1C1 + BPM1C2 + BPM1C3 + BPM1C4) / 4
print "OP-BPM1 average = ", BPM1
# if the BPM1 reading is too low, means no beam, do not rock, and quit
# without beam, BPM1 and 2 readings are about 1.2-1.2 nA
if BPM1 <= 2:
raise Exception("Flux is too low, either no beam or FE shutter is not open.")
print "Current energy is ", ENERGY, ", mono theta2 is ", THETA2, "."
# 20080507 number for BPM1
# keV 7 8 9 10 11 12 13 14 15 16 17
# BPM1 with room light: 150 140 120 110 100 90 80 80 70 50 40
# BPM1 w/o room light: 134 123 111 95 81 70 61 54 47 40 20
# new CVD BPM 20100621
# 6 7 8 9 10 11 12.4 13 14 15 16 17
# 51 65 63 57 53 48 40 37 33 27 18 6
# get correct threshold for different energy
BPM1_limit = ["41", "52", "50", "44," "42", "39", "32", "30", "26", "21", "14", "4"]
i = 0
for i in range(12):
n = i + 6
if n == int(ENERGY):
print int(ENERGY), n, i, BPM1_limit[i] #TODO: There was bug indexing here?
BPM1_lowLimit = BPM1_limit[i]
# if flux is low, rock
if BPM1 <= BPM1_lowLimit:
print "BPM1 reading is lower than ", BPM1_lowLimit
print "lets rock."
rock()
time.sleep(2)
else :
print "BPM1 reading is higher than ", BPM1_lowLimit
print "nothing to do, quit."
print " "
#TODO: Should abort?
#==========================================================
print "======"
print "check and fbm"
# check the X06DA-ES-BPM1:POSV
if ( eh_shutter.read() == "NOT_OPEN" ):
raise Exception("ExpHutchShutter closed - program will exit")
BPM1POSV = es_beam_posv.read()
print "Vertical beam postion at ES-BPM1: ", BPM1POSV
# to get an integer (microns), 0.005 * 1000 / 1 with bc will do it.
POSV = int(BPM1POSV * 1000)
# if the POSV reading is not within +/- 8 microns means beam position is drifted, do FBM
# if flux is low, rock
if POSV <= -6 or POSV >= 6 :
print "Beam is not aligned at E-BOX BPM1"
print "lets fix it."
fbm()
time.sleep(2)
else :
print "Beam is aligned at E-BOX BPM1,"
print "nothing to do, quit."
print " "

View File

@@ -1,6 +0,0 @@
"""
Diode scan
"""
asd
#Execute the scan: 200 steps, a1 from 0 to 40

View File

@@ -1,77 +0,0 @@
###################################################################################################
#
###################################################################################################
#tc1 = caget('X06DA-OP-MO:TC1') # theta1 thermo couple 1
energy = get_energy() # Mono energy
dtz = detector_z.read()
if current.read() < 200:
raise Exception ('Ring current too low')
if fe_absorber.read()!= 'OPEN':
raise Exception ('FrontEndAbsorber closed') # FrontEnd absorber shutter state
if fe_shutter.read() != 'OPEN':
raise Exception ('FrontendShutter closed')
if eh_shutter.read() != 'OPEN': # ExpHutch shutter state
raise Exception ('ExpHutchShutter closed ')
if mono_energy.read()> 17.5: #Mono energy
raise Exception ('Sorry, no feedback above 17.5 keV for now')
tc = 40 # 2015.09.20 quick fix by MT JW
cur = es_beam.read()
op1 = caget('X06DA-OP-XPM1:CHAN1', 'd')
if op1 < 1.0:
sete_failed = 1
raise Exception ('X06DA-OP-XPM1:CHAN1 < 10 - please check monochromator, frontend, primary slits, ring current and undulator - program exits')
# define max deviations
dmx = 14.0 # 2 x distance mirror HR-XBPM
ymax = 2e-3 # endwhile criterion for vertical correction
if cur < tc: #check if beam is on CVD-XBPM
sete_failed = 1
raise Exception ('evere problem - NO BEAM ON HR-DIFFRACTOMETER XBPM')
# initial mirror TRY3 position
y3i = try3.read()
print "initial y3i: " + str(y3i)
# how much beam is off?
by = es_beam_posv.read()
print "EBOX-POSV before rock: " + str(by)
# if beam is not off, do nothing
if abs(by) > ymax:
rock(th1)
# result of ROCK
time.sleep(2.0)
by = es_beam_posv.read()
print "EBOX-POSV after rock: " + str(by)
# feedback
while abs(by) >= ymax :
by = es_beam_posv.read()
print "current EBOX-POSV: " + str(by)
cur = es_beam.read()
if cur > tc:
if (eh_shutter.read() == 'OPEN') and (abs(by) > ymax):
if abs(by) > (50*ymax):
raise Exception ('TODO')
#limit mirror TRY3 movement
y3 = try3.read()
if abs(y3i - y3 - 1e-4 * round(by/1e-3)) > 0.008:
raise Exception ('Feedback trying to move mirror Y3 beyond safe limit')
try3.moveRel(-1e-4 * round(by/1e-3))
print "current X06DA-OP-MI1:TRY3: ", y3
time.sleep(0.25)
print "TRY3 net movement: " + str(y3i-try3.read()) #print how much TRY3 moved

View File

@@ -1,55 +0,0 @@
from mathutils import estimate_peak_indexes, fit_gaussians, create_fit_point_list, Gaussian
import java.awt.Color as Color
import mathutils
mathutils.MAX_ITERATIONS = 100000
def fit(ydata, xdata = None, draw_plot = True):
if xdata is None:
xdata = frange(0, len(ydata), 1)
max_y= max(ydata)
index_max = ydata.index(max_y)
max_x= xdata[index_max]
print "Max index:" + str(index_max),
print " x:" + str(max_x),
print " y:" + str(max_y)
if draw_plot:
plots = plot([ydata],["data"],[xdata], title="Fit" )
p = None if plots is None else plots[0]
gaussians = fit_gaussians(ydata, xdata, [index_max,])
if gaussians[0] is None:
if draw_plot and (p is not None):
p.addMarker(max_x, None, "Max="+str(round(max_x,4)), Color.GRAY)
print "Fitting error"
return (None, None, None)
(norm, mean, sigma) = gaussians[0]
if draw_plot:
fitted_gaussian_function = Gaussian(norm, mean, sigma)
scale_x = [float(min(xdata)), float(max(xdata)) ]
points = max((len(xdata)+1), 100)
resolution = (scale_x[1]-scale_x[0]) / points
fit_y = []
fit_x = frange(scale_x[0],scale_x[1],resolution, True)
for x in fit_x:
fit_y.append(fitted_gaussian_function.value(x))
#Server
if p is None:
plot([ydata,fit_y],["data","fit"],[xdata,fit_x], title="Fit")
draw_plot = False
else:
p.addSeries(LinePlotSeries("fit"))
p.getSeries(1).setData(fit_x, fit_y)
if abs(mean - xdata[index_max]) < abs((scale_x[0] + scale_x[1])/2):
if draw_plot:
p.addMarker(mean, None, "Mean="+str(round(mean,4)), Color.MAGENTA.darker())
print "Mean -> " + str(mean)
return (norm, mean, sigma)
else:
if draw_plot:
p.addMarker(max_x, None, "Max="+str(round(max_x,4)), Color.GRAY)
print "Invalid gaussian fit: " + str(mean)
return (None, None, None)

View File

@@ -1,86 +0,0 @@
# from Clemens' flux calc & Robin's paper [Owen et al, JSR 16, 2009, Silicon PIN diodes]
#--------- formula --------------------------------------------
# flux = I_ph * eps_Si /e/E/( 1-exp(A_Si*rsi*t_Si ) )
# with Al and air atten:
# flux= flux * exp(A_Al*ral*t_Al) * exp(A_air*rair*t_air)
#
# with A_ being the photoelectric cross sections of the materials
#--------- parameters -----------------------------------------
# density of Si
rsi = 2.33 # g/cm^3
# density of Al
ral = 2.699 # g/cm^3
# density of air
rair = 1.205e-3 # g/cm^3
eps_si = 3.62 # eV energy req. for charge separation in Si (generation of el/hole pairs)
e = 1.602e-19 # As , elementary charge
t_si = 0.0012 # thickness of diode in cm (== 12 micron) ; [* 10000]
t_al = 0.002 # thickness of diode in cm ; (== 20 micron)
#--------- input---------------------------------------------------
cur = float(get_string('Please enter the measured diode current [in mA]', 0.1))
ep = float(get_string('Please enter the photon energy [in keV]', 12.4 ))
t_si= float(get_string('Please enter the thickness of the Si layer [in micron]', t_si))
t_si = t_si/10000. # --> cm
t_al = float(get_string('Please enter the thickness of the Al layer [in micron, 0 if not available]', t_al))
t_al = t_al/10000
t_air = float(get_string('Please enter the pathway in air [in mm]', 165.+100.))
#--------- calc----------------------------------------------------
# energy deposit in Silicon
polys=[4.158,- 2.238, - 0.477, 0.0789]
hlp_si= poly(math.log10(ep), polys)
A_Si= 10.0 ** hlp_si
efact=math.exp(-A_Si*rsi*t_si)
sifact=1.0-efact
#help, cur, eps_si, ep
fl0=cur* eps_si/1.602/ep/sifact *1.e13
# Aluminium attenuation
# ratio of photoelectric cross section to density for Aluminium
polyal= [4.106, - 2.349, - 0.413, 0.0638 ]
hlp_al= poly(math.log10(ep), polyal)
A_Al= 10.0 ** hlp_al
# attenuation due to aluminium
alfact=math.exp(-A_Al*ral*t_al)
# Air attenuation
# ratio of photoelectric cross section to density for air
polyair= [3.153, - 1.026, - 2.348, 0.928]
hlp_air= poly(math.log10(ep), polyair)
A_air= 10.0 ** hlp_air
# attenuation due to air
airfact=math.exp(-A_air*rair*t_air/10.)
# total flux from photocurrent
fl=fl0/alfact/airfact
f = fl
msg = ' Energy: ' + '%7.4f' % e + ' keV\n'
msg = msg+ ' Diodecurrent: ' + str(cur).strip() +' mA\n'
msg = msg+ '\n'
msg = msg+ ' Thickness of active Si layer: ' + str(t_si*10000.).strip() + ' micron\n'
msg = msg+ ' Thickness of Al layer in front of diode: ' + str(t_al*10000.).strip() + ' micron\n'
msg = msg+ ' Length of path in air in front of diode: ' + str(t_air).strip() + ' mm\n'
msg = msg+ '\n'
msg = msg+ ' ===> flux: %8.2E photons / s' % f
print msg
show_message(msg, "flux_diode", False)

View File

@@ -1,3 +1,3 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.groovy
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.groovy
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,4 +1,4 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.js
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.js
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,184 +1,4 @@
###################################################################################################
# Deployment specific global definitions - executed after startup.py
###################################################################################################
###################################################################################################
# Deployment specific global definitions - executed after startup.py
###################################################################################################
dtor = math.pi /180.0
for d in [pvs, pvc, phs, phc, ths, thc, tvs, tvc, qhs, qhc, qvs, qvc]:
d.setBlockingWrite(True)
def a2e(t,h=1.0,k=1.0,l=1.0, deg =True, ln = False):
lncorr= 2.e-4 if ln else 0.0
d0=2 * 5.43102 * (1.0-lncorr) / math.sqrt(h**2+k**2+l**2)
tt= (t * dtor) if (deg or (t>1.0)) else t
return 12.39842 / (d0*math.sin(tt))
def angle(e,h=1.0,k=1.0,l=1.0, deg =True, ln = False,bent = False):
lncorr = 2.e-4 if ln else 0.0
d0 =2 * 5.43102 * (1.0-lncorr) / math.sqrt(h**2+k**2+l**2)
a = math.asin(12.39842/d0/e)
if bent:
rho = 2*19.65*8.35/28*math.sin(a)
dt = 0.2e-3/rho*0.279
d0 = 2*5.43102*(1+dt)/math.sqrt(h**2+k**2+l**2)
a = math.asin(12.39842/d0/e)
a = a/dtor if deg else a
return a
def get_energy(debug_msg = True):
t2 = th2.position
e = a2e(abs(t2))
if debug_msg:
print 'Energy [keV]:'+ str(e) + ' Wavelength [A]:' + str(12.39842/e)
return e
def set_energy(e, debug_msg = True):
e = float(e)
if e< 4.7 or e > 18.0:
raise Exception ("please select an energy between 4.7 an 18 keV")
t1e = th1_encoder.read()
t2e = th2_encoder.read()
t1v = th1.read()
t2v = th2.read()
t1s = angle(e,1,1,1,ln=True)
t2s = angle(e,1,1,1)
# calculate the corrections later, after
# calibration of encoders
dt1 = 0.
dt2 = 0.
# it is better to move both crystals by the same amount. however,
# if one motor got stuck and the other did not, we should not move
# them by the same amount but each according to its calculated deltha theta
t1p = -t1s
t2p = t2s
if debug_msg:
print 'set angles th1=' + str(t1p) + " th2=" + str(t2p)
th1.move(t1p) #TODO: simultaneous move?
th2.move(t2p)
th1.waitReady(-1)
th2.waitReady(-1)
if debug_msg:
print 'done set energy'
def shopen():
exp_shutter.write("OPEN")
def shclose():
exp_shutter.write("CLOSED")
def vfoc (dx=0.1):
#scan,'dfy',0,2*dx,25,/fit,det='des',dat=d
motor = cy #TODO: Is right? original was not relative; motor channel was X06DA-ES-DF1:TRY-VAL
sensor = mono_beam #TODO: sensor is not clear since set det to des(X06DA-ES-KBOX:SIG-RAW) but parameter is called 'detector' in scan: is default mono_beam used?
result = lscan(motor, sensor, -dx, dx, 25, latency = 0.3, relative = True) #TODO: range is 0, 2*dx?
(ydata, xdata) = (result.getReadable(0), result.getPositions(0))
from mathutils import deriv, fit_gaussians, Gaussian, get_values
d = [x*1e6 for x in deriv(ydata, xdata)]
gaussians = fit_gaussians(d, xdata , [d.index(max(d)) ,])
(n, m, s) = gaussians[0]
fitted_gaussian_function = Gaussian(n, m, s)
g = get_values(fitted_gaussian_function,xdata)
plot((ydata, d, g), ("Sensor", "Deriv", "Gauss Fit"), (xdata,xdata,xdata))
#PLOT,d(0,*),deriv(reform(d(1,*))*1e6)
#oplot,d(0,*),gaussfit(reform(d(0,*)),deriv(reform(d(1,*))*1e6),a,nterm=5),ps=-6
print 'CENTRE ',m
print 'FWHM microns',s*2354.
motor.move(m) #?motor.move(-dx+a(1))
#WM,'mb1' #WHAT for?
#WM,'mb2'
return (n, m, s)
def knife():
pvc0 = pvc.read()
pvs0 = pvs.read()
try:
step = 0.175
pvc.write(pvc0 - 3.*step)
pvs.write(0.1)
c = []
for i in range(5):
pvc.write(pvc0 + step * i)
a = vfoc()
c.apppend(a[1])
print 'mean',mean(c)
print 'stdev',stdev(c)
finally:
pvc.write(pvc0)
pvs.write(pvs0)
def knifescan(motor, ll, hl, n=25):
try:
shopen()
time.sleep(1.0)
result = lscan(motor, marcover, ll, hl, n, latency = 0.3, relative = True)
#scan, motor, ll, hl, n,det='marcover',dat=d
(ydata, xdata) = (result.getReadable(0), result.getPositions(0))
d = deriv(ydata, xdata)
#inversed #IF MOTOR EQ 'dfx' THEN sign = -1. ELSE sign = 1 #TODO
if motor in []:
d = [x*-1.0 for x in d]
gaussians = fit_gaussians(d, xdata , [d.index(max(d)) ,])
(n, m, s) = gaussians[0]
#PLOT,D(0,*), SIGN*DERIV(d(1,*)), THICK=2
#OPLOT, d(0,*), GAUSSFIT(d(0,*),SIGN*DERIV(d(1,*)),a),col=150
plot((ydata, d, g), ("Sensor", "Deriv", "Gauss Fit"), (xdata,xdata,xdata))
print 'Centre [scanunits]',m
print 'FWHM [scanunits]',s*2.3542 #sigma to FWHM factor is 2.3542
finally:
shclose()
run("fit")
run("rock")
#run("sete")
#run("seteq")
def fbm():
"""
"""
run("fbm")
def rocknroll():
"""
"""
run("rocknroll")
def censlits():
"""
"""
run("censlits")
def flux_diode():
"""
"""
run("flux_diode")
def sete(e, all=True, wavelength=False):
run("sete", {"e":e, "all":all, "wavelength":wavelength})
def seteq(e):
run("seteq", {"e":e})
def check_rock():
run("check_rock")
import ch.psi.pshell.device.ReadonlyRegisterBase as ReadonlyRegisterBase
class EnergyReader(ReadonlyRegisterBase):
def doRead(self):
return get_energy(False)
add_device(EnergyReader("energy",3), True)

View File

@@ -1,47 +0,0 @@
###################################################################################################
#
###################################################################################################
#from startup import * #Not needed: executed from local
def rock(axis = th1, tt = 0.2, seti0 = False, dx = None, noref = False):
"""
"""
#inject() #Not needed: executed from local
if axis is None:
axis = th1
if noref == False:
mono_beam_ref.write(-1.0)
e = get_energy()
if dx is None:
dx = 7.5e-2/e
# put 'Retry deadband' to 0.00004 and 'Retries Max' to 5
time.sleep(0.2)
caput(axis.channelName + '.RDBD',0.00004)
caput(axis.channelName + '.RTRY',5)
print time.strftime('%X %x')
axis_pos = axis.read()
result = lscan(axis, mono_beam, -dx, dx, 20, latency = 0.3, relative = True)
(ydata, xdata) = (result.getReadable(0), result.getPositions(0))
(norm, mean, sigma) = fit(ydata, xdata)
if (mean is not None) and (mean <= (axis_pos + dx)) and (mean >= (axis_pos - dx)):
axis.move(mean)
if seti0:
time.sleep(2)
run("setI0")
#add after_rock BPM1:SUM as reference for monitoring monochromator thermal drift
if (noref==False):
time.sleep(3) # wait a bit until mono theta finish moving
br = mono_beam.read()
mono_beam_ref.write(br)
print 'rock_success new mono beam at ' + str(br) + ' at ' + str(e) + ' keV'
return True
else:
max_x= xdata[ydata.index(max(ydata))]
print 'fit failed - centering on maximum: ' + str(max_x)
axis.move(max_x)
return False

View File

@@ -1,14 +0,0 @@
ei = get_energy()
if ei < 6.0:
print "No rocking optimization for lower energy for 3rd harmonics rejection'
rock(th1)
#check beam position at EBOX and fbm if needed
time.sleep(2.0)
by = es_beam_posv.read()
if (abs(by) > 0.005):
print by
print 'Beam is not aligned at E-BOX BPM: do fbm.'
run("fbm")

View File

@@ -1,83 +0,0 @@
def error(msg):
caput(beam_err, (msg[:40]) if len(msg) > 40 else msg)
raise Exception (msg)
#def sete(e, all=True, wavelengt=False):
beam_err = BEAMLINE_XNAME + '-ES-DAQ:BEAM-ERROR'
beam_set = BEAMLINE_XNAME + '-ES-DAQ:BEAM-SET'
ring_current_cutoff = 300.0
if wavelength:
e = 12.39842/e
if e < 4.7 or e > 17.5:
error('ERROR:Energy out of range: 4.7 to 17.5 keV')
print time.strftime('%X %x')
print '... Setting energy to '+ str(e) +' keV.'
msg = 'Working... (aiming @ '+ str(e) +' keV)'
caput(beam_err, (msg[:40]) if len(msg) > 40 else msg)
if caget('ALIRF-GUN:CUR-LOWLIM', 'd') < ring_current_cutoff:
error('ERROR:Current is too low: < ' + str(ring_current_cutoff) + 'mA')
if fe_absorber.read()!= 'OPEN':
raise Exception ('FrontEndAbsorber closed') # FrontEnd absorber shutter state
if fe_shutter.read() != "OPEN":
raise Exception ('FrontendShutter closed')
e0 = get_energy(False);
dE = abs(e-e0)
print '... started to move monochromator motors'
print '... alignment will take some minutes '
act = 0
# do a setenergy to move theta 1 and 2 to calculated position in case they are not synchronized.
theta1 = th1.read() #TODO: setpoint?
etheta1 = a2e(abs(theta1),1,1,1,deg=True,ln=True)
theta2 = th2.read()
etheta2 = a2e(abs(theta2),1,1,1,deg=True,ln=False)
if abs (etheta1-etheta2) > 0.01:
set_energy(e)
while abs(e-e0) > 3e-5/math.tan(angle(e, deg=False)): #TODO: deg==false? WHILE ABS(e-e0) GT 3e-5/TAN(ANGLE(e)) DO BEGIN
set_energy(e)
e0 = get_energy(False)
#----- correcting theta2 if intensity is low or if the encoder -----
#----- differs by more than rocking curve width from theory --------
# -------- for sete, /all, remove all filters
if all:
filter1.write("None")
filter2.write("None")
filter3.write("None")
filter4.write("None")
time.sleep(0.5)
#-------- rock FIRST crystal until its peak is reached -------------
while rock(th1)==False: #TODO: #ROCK,1,dt = (dE>1.)*4e-2/e,ffail=ff
pass
# finer final rock
time.sleep(1.0)
print 'FINER FINAL ROCK'
rock()
e0 = get_energy()
print e0
mono_energy.write(e0)
print mono_energy.read()
caput(beam_err, 'Finito')
caput(beam_set, 'DONE')
print 'sete_done'

View File

@@ -1,95 +0,0 @@
#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'

View File

@@ -1,19 +0,0 @@
s = []
v = []
t = []
for i in range(10):
s.append(caget('X06SA-OP-BPM3:SUM'))
v.append(caget ('X06SA-OP-BPM3:POSV'))
t.append(caget('X06SA-OP-MO:TC3'))
time.sleep(0.09)
"""
#TODO
!x06saopbpm3y = MEAN(v)
#dum = NEWCAPUT('X06SA-OP1-MI:BPM_IO',MEAN(S))
"""
print 'Setting I0 to '+ str(mean(s))+' +/- '+str(stdev(s))+' nA'
print 'Setting BPM3_Y to'+ str(mean(v))+' +/- '+str(stdev(v))+' mm'
print 'Setting TC3 to '+ str(mean(t))+' +/- '+str(stdev(t))+' mm'

View File

@@ -1,12 +0,0 @@
show_message("My message", title = "Title", blocking = True)
print get_option("Choose:" , type = "YesNoCancel")
print get_string("Enter string:", default = "default")
print get_string("Choose string:", default = "default", alternatives = ["default", "alt1", "alt2"])
print get_string("Enter password:", password = True)