Files
x06da/script/local.py
2016-03-17 10:54:59 +01:00

177 lines
5.4 KiB
Python

###################################################################################################
# Deployment specific global definitions - executed after startup.py
###################################################################################################
BEAMLINE_XNAME = "X06DA"
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, wavelengt=False):
run("sete", {"e":e, "all":all, "wavelengt":wavelengt})
def seteq(e):
runq("seteq", {"e":e})
import ch.psi.pshell.device.ReadonlyRegisterBase as ReadonlyRegisterBase
class EnergyReader(ReadonlyRegisterBase):
def doRead(self):
return get_energy(False)
add_device(EnergyReader("energy"), True)