Files
sf-op/script/Alignment/BPM_quad_alignment.py
2020-02-07 11:43:37 +01:00

111 lines
3.9 KiB
Python

import ch.psi.pshell.epics.Positioner as Positioner
dry_run = False
do_elog = True
is_panel = get_exec_pars().source != CommandSource.ui # must be check before run
run("CPython/wrapper")
#Parameters
if is_panel:
MCR1 = args[0]
else:
U = "X"
MQUA = "SATMA01-MQUA050"
MCR1 = {"X": "SATCB01-MCRX430", "Y": "SATCB01-MCRY430" }
BPM1 = {"X": "SARCL01-DBPM150:X1", "Y": "SARCL01-DBPM150:Y1" }
BPM2 = {"X": "SARCL02-DBPM110:X1", "Y": "SARCL02-DBPM110:Y1" }
dC = 2.0
dK = 0.05
step = 10
nb = 5
lat = 0.0
plt = plot(None, title="Output")[0]
#Plot setup
plt.clear()
plt.removeMarker(None)
plt.setStyle(plt.Style.ErrorXY)
plt.addSeries(LinePlotErrorSeries("run0", Color.red))
plt.addSeries(LinePlotErrorSeries("run1", Color.yellow))
plt.addSeries(LinePlotErrorSeries("run2", Color.green))
plt.getAxis(plt.AxisId.X).setLabel("BPM1 (mm)")
plt.getAxis(plt.AxisId.Y).setLabel("BPM2 (mm)")
plt.setLegendVisible(True)
#Creating Phase positioner
if dry_run:
kick1 = Positioner("kick1", "SATCB01-MCRX430:I-SET", "SATCB01-MCRX430:I-READ")
quad = Positioner("quad", "SATMA01-MQUA050:K1L-SET", "SATMA01-MQUA050:K1L-READ")
else:
kick1 = Positioner("kick1", MCR1[U] + ":I-SET", MCR1[U] + ":I-READ")
quad = Positioner("quad", MQUA + ":K1L-SET", MQUA + ":K1L-READ")
quad.config.minValue = -2.0
quad.config.maxValue = 2.0
kick1.initialize()
quad.initialize()
kick1_ini = kick1.read()
quad_ini = quad.read()
start = kick1_ini - dC / 2
stop = kick1_ini + dC / 2
#Creating averagers
X1 = "ca://" + BPM1[U]
X2 = "ca://" + BPM2[U]
X1_averager = create_averager(X1, nb, -1) # -1 event based, waits for the next value
X2_averager = create_averager(X2, nb, -1) # ca:// it comes from epics channels
X2_averager.monitored = True # not blocking, will return last nb values
#Record callback: uptate of output plot
def after_sample(record, scan):
global plt,i
X1_mean, X1_stdev = record.values[0].mean, record.values[0].stdev
X2_mean, X2_stdev = record.values[1].mean, record.values[1].stdev
plt.getSeries(i).appendData(X1_mean, X2_mean, X1_stdev, X2_stdev)
#The scan loop
try:
data = []
i = 0
for K1L in (quad_ini, quad_ini - dK, quad_ini + dK):
kick1.write(start)
quad.write(K1L)
time.sleep(2.0)
r = lscan(kick1, [X1_averager, X2_averager], start, stop, step , latency=lat, after_read = after_sample)
data.append({"K1L":K1L,"scan":r})
i = i + 1
finally:
kick1.write(kick1_ini)
kick1.close()
quad.write(quad_ini)
quad.close()
#Fitting and plotting
P = []
for i in range(len(data)):
x = data[i]["scan"].getReadable(0)
y = data[i]["scan"].getReadable(1)
(p, x_fit, y_fit, R2) = linfit(x, y)
P.append(p)
plt.addSeries(LinePlotErrorSeries("Fit"+str(i), plt.getSeries(i).color))
plt.getSeries(i+3).setData(x_fit, y_fit)
plt.getSeries(i+3).setPointsVisible(False)
a, b = P[1][0], P[1][1] #second line +K
c, d = P[2][0], P[2][1] #third line -K
ui = (d - b)/(a - c) if a != c else None
#Elog entry
if do_elog:
if get_option("Generated data file:\n" + get_exec_pars().path +"\n\n" + "Save to ELOG?", "YesNo") == "Yes":
title = "BPM_Quad_scan"
log_msg = "Data file: " + get_exec_pars().path + "\n\n"
log_msg = log_msg + "MQUA: " + MQUA + "\n"
log_msg = log_msg + "BPM1: " + BPM1[U] + "\n"
log_msg = log_msg + "BPM2: " + BPM2[U] + "\n"
log_msg = log_msg + "MQUA center: " + str(ui) + "\n"
sleep(0.1) #Give some time to plot to be finished - it is not sync with acquisition
file_name = os.path.abspath(get_context().setup.getContextPath() + "/BPM_Quad_Plot.png")
plt.saveSnapshot(file_name , "png")
elog(title, log_msg, [file_name,])
set_return(ui)