Files
sf-op/script/Diagnostics/DLACScan.py
2017-08-08 18:14:38 +02:00

199 lines
6.8 KiB
Python

import traceback
is_panel = get_exec_pars().source != CommandSource.ui #Must be checked before callin "run"
DLAC_POSITIONS = ["RF_shield", "Mirror1", "Mirror2", "Shrom1", "Shrom2", "Shrom3", "Shrom4"]
#IN_POSITION = 0.01
dry_run = False
run("Devices/Elements")
run("Diagnostics/sig_process_wrapper")
BPM_SENSORS = [("x","X1"), ("y","Y1"), ("q","Q1")] #(logic name sufix, channel sufix)
TRAVEL_SPEED = 0.001
#Paramter parsing
prefix = args[0] if is_panel else "SINDI02-DLAC055"
scan_type = args[1] if is_panel else "Shrom3"
scan_range = args[2] if is_panel else [-0.12, 0.12]
cycles = args[3] if is_panel else 1
velocity = args[4] if is_panel else 0.00001
bpms = args[5] if is_panel else ["SINDI02-DBPM040", "SINDI02-DBPM080"]
blms = args[6] if is_panel else ["SINDI02-DBLM085", "S10DI01-DBLM045"]
bkgrd = args[7] if is_panel else 5 #Number of beam synchronous messages
plt = args[8] if is_panel else plot(None, title = "DLAC Scan")[0]
do_elog = True if is_panel else False
print "DLAC scan parameters: ", prefix, scan_type, scan_range, cycles, velocity, bpms, blms, bkgrd
center_pos = 199.484
scan_type_index = DLAC_POSITIONS.index(scan_type)
if scan_type_index<0:
raise Exception("Bad sample position name")
#Plot setup
plt.clear()
plt.removeMarker(None)
plt.getAxis(plt.AxisId.X).setLabel("Position");
plt.getAxis(plt.AxisId.Y).setLabel("");
plt.getAxis(plt.AxisId.Y2).setLabel("");
plt.setLegendVisible(True);
snapshots = []
#Motor
if dry_run:
motor = DummyMotor("SimMotor")
motor.config.defaultSpeed = 10.0
motor.config.maxSpeed = TRAVEL_SPEED
motor.config.maxValue = 1000.0
else:
motor = ch.psi.pshell.epics.Motor("DLAC motor", prefix + ":MOTOR_Y1")
motor.config.resolution = 0.001 #In-position band
motor.monitored = True
motor.setPrecision(7)
motor.initialize()
add_device(motor, True)
motor.setSpeed(TRAVEL_SPEED)
park_pos = caget (prefix + ":P0_U0_SP")
# center_pos = caget (prefix + ":P" + str(scan_type_index) + "_U0_SP")
#List of stream channels
channels = [] #[("m_pos", scanner.motor_bs_readback.get_name()), ]
for i in range (len(blms)):
channels.append (("blm" + str(i+1), blms[i] + ":B1_LOSS"))
series = LinePlotSeries(blms[i], None, min(i+1, 2))
plt.addSeries(series)
series.setLinesVisible(False)
series.setPointSize(2)
for i in range (len(bpms)):
for sensor in BPM_SENSORS:
channels.append (("bpm" + str(i+1) + "_" + sensor[0], bpms[i] + ":" + sensor[1]))
#Metadata
set_attribute("/", "DLAC Scanner", prefix)
set_attribute("/", "Sample", scan_type)
set_attribute("/", "Range", scan_range)
set_attribute("/", "Cycles", cycles)
set_attribute("/", "Velocity", velocity)
set_attribute("/", "Background Measures", bkgrd)
set_attribute("/", "BPMs", bpms)
set_attribute("/", "BLMs", blms)
filename = get_exec_pars().path
#Stream creation
print "Starting stream..."
st = Stream("pulse_id", dispatcher)
for c in channels:
st.addScalar(c[0], c[1], 10, 0)
st.initialize()
st.start()
st.waitCacheChange(10000) #Wait stream be running before starting scan
if st.take() is None:
raise Exception("Error initializing data stream")
start = st.take().timestamp
#Scan callback
scan_complete, cur_cycle = False, 0
destination = None
def check_end_scan(record, scan):
global scan_complete, start, destination
if motor.ready:
#if motor.isInPosition(destination):
print "Data aquisition completed"
scan_complete=True
scan.abort()
record.cancel() #So it won't be saved
else:
position = float( record[1].timestamp - start )
for i in range (len(blms)):
plt.getSeries(i).appendData(position, record[2 + i])
#Process background
def do_background():
#Store Background
if bkgrd>0:
motor.move(park_pos)
time.sleep(0.1)
set_exec_pars(group = "background")
r = mscan (st, st.getReadables()[4:], bkgrd)
for i in range(len(r.getReadables())):
d = r.getReadable(i)
path = get_exec_pars().group + "/"+ r.getReadables()[i].name
set_attribute(path, "Mean", mean(d))
set_attribute(path, "Sigma", stdev(d) )
motor.move(center_pos + scan_range[0] )
motor.setSpeed(velocity)
msg = ""
print "Starting scan..."
try:
do_background()
#plt.getAxis(plt.AxisId.X).setRange(scan_range[0], scan_range[1])
for s in plt.getAllSeries():
s.clear()
plt.removeMarker(None)
for i in range(cycles):
scan_complete=False
try:
cur_cycle = i+1
set_exec_pars(group="Cycle_" + str(cur_cycle), reset=True)
motor.setSpeed(TRAVEL_SPEED)
motor.move(center_pos + scan_range[0] )
#time.sleep(1.0)
motor.setSpeed(velocity)
destination = center_pos + scan_range[1]
motor.moveAsync(destination)
# time.sleep(1.0)
#if (i%2) == 0:
# motor.moveAsync(center_pos + scan_range[1])
#else:
# motor.moveAsync(center_pos + scan_range[0])
start = st.take().timestamp
mscan ( st, [motor.readback,] + st.getReadables(), -1, -1, take_initial = True, after_read = check_end_scan)
except:
print "Quit scan"
if not scan_complete:
raise
print "Scan complete"
"""
finally:
#Combining data of multiple series
calculate()
img_file = os.path.abspath(filename + "_" + get_exec_pars().group[0:1] + ".png")
time.sleep(0.1) #Give some time to plot finish (async)
plt.saveSnapshot(img_file, "png")
snapshots.append(img_file)
"""
finally:
print "Closing stream"
st.close()
motor.setSpeed(TRAVEL_SPEED)
print msg
# save the entry in the logbook
if do_elog:
if get_option("Generated data file:\n" + filename +"\n\n" + msg + "\n\n" + "Save to ELOG?", "YesNo") == "Yes":
log_msg = "Data file: " + filename
log_msg = log_msg + "\nDLAC: " + prefix
log_msg = log_msg + "\nSample: " + str(scan_type)
log_msg = log_msg + "\nRange: " + str(scan_range)
log_msg = log_msg + "\nCycles: " + str(cycles)
log_msg = log_msg + "\nVelocity: " + str(velocity)
log_msg = log_msg + "\nBackground Measures: " + str(bkgrd)
log_msg = log_msg + "\nBPMs: " + str(bpms)
log_msg = log_msg + "\nBLMs: " + str(blms)
log_msg = log_msg + "\n" + msg
elog("Wire Scan", log_msg, snapshots)