Image Measurements

This commit is contained in:
gac-x11ma
2020-09-29 10:37:10 +02:00
parent 076b810bf1
commit 1507333ad4
14 changed files with 912 additions and 337 deletions
+86
View File
@@ -0,0 +1,86 @@
from collections import OrderedDict
diag_channels = { \
#"photon energy": "X11MA-PGM:rbkenergy", \
#"grating number": "X11MA-PGM:grating", \
#"cff value": "X11MA-PGM:rbkcff", \
"diffraction order": "X11MA-PGM:difforder0", \
#"exit slit size":"X11MA-OP2-SL:TRY.VAL", \
"front end size":"X11MA-FE-DSAPER", \
"status fast shutter":"X11MA-VME-ES1:FAST-SHTR", \
"girder x": "X11MA-HG:X1", \
"girder y": "X11MA-HG:Y1", \
"girder z": "X11MA-HG:Z1", \
"girder pitch": "X11MA-HG:PITCH1", \
"girder yaw": "X11MA-HG:YAW1", \
"girder roll set": "X11MA-HG:ROLL_SET", \
"CMU ox": "X11MA-OP-CM:ox", \
"CMU oy": "X11MA-OP-CM:oy", \
"CMU oz": "X11MA-OP-CM:oz", \
"CMU oRx": "X11MA-OP-CM:oRx", \
"CMU oRy": "X11MA-OP-CM:oRy", \
"CMU oRz": "X11MA-OP-CM:oRz", \
"CMU TRB": "X11MA-OP2-CM:TRB.RBV", \
#"mode": "X11PHS-E:OPT", \
#"id1 mode": "X11MA-ID1:MODE", \
#"id1 offset": "X11MA-ID1:ENERGY-OFFS", \
#"id1 alpha": "X11MA-ID1:ALPHA", \
#"id1 harmonic": "X11MA-ID1:HARMONIC", \
"id1 gap": "X11MA-ID1-GAP:READ", \
"id1 shift": "X11MA-ID1-SHIFT:READ", \
#"id2 mode": "X11MA-ID2:MODE", \
#"id2 offset": "X11MA-ID2:ENERGY-OFFS", \
#"id2 alpha": "X11MA-ID2:ALPHA", \
#"id2 harmonic": "X11MA-ID2:HARMONIC", \
"id2 gap": "X11MA-ID2-GAP:READ", \
"id2 shift": "X11MA-ID2-SHIFT:READ", \
"keithley 10 IO": "X11Keithley1-read", \
#"ring current": "ARIDI-PCT:CURRENT", \
"PEEM high voltage": "X11MA-ES1-PEEM:UMON", \
"PEEM leakage current": "X11MA-ES1-PEEM:IMON", \
"Pressure in PEEM": "X11MA-ES1-MAIN:PRESSURE", \
"Pressure in Column": "X11MA-ES1-COLU:PRESSURE", \
"Sample temperature": "X11MA-ES1-SW:Pt100-T", \
"Pt100 resistance": "X11MA-ES1-SW:Pt100-R", \
"high voltage": "X11MA-ES1-SD1:cam1:HighVoltage_RBV", \
}
diag_devices = {
"photon energy": energy_rbk, \
"grating number": Grating, \
"cff value": cff, \
"exit slit size": ES, \
"mode": energy_opt, \
"id1 mode": id1_mode, \
"id1 offset": id1_offset, \
"id1 alpha": id1_alpha, \
"id1 harmonic": id1_harmonic, \
"id2 mode": id2_mode, \
"id2 offset": id2_offset, \
"id2 alpha": id2_alpha, \
"id2 harmonic": id2_harmonic, \
"ring current": machine_cur, \
}
def get_diags():
ret = {}
for k,v in diag_devices.items():
try:
ret[k]=str(v.read())
except:
ret[k]="Error: " + sys.exc_info()[1]
for k,v in diag_channels.items():
try:
ret[k]=caget(v,'s')
except:
ret[k]="Error: " + sys.exc_info()[1]
ret["exposure time"] = str(eiger.getExposure())
return OrderedDict(sorted(ret.items(), key=lambda i: i[0].lower()))
def print_diags():
diags = get_diags()
for k in diags.keys():
print k + ": " + diags[k]
+17 -10
View File
@@ -145,22 +145,29 @@ def _save_as_tiff(data, filename, check=False, show = False, metadata={}):
ip = load_array(data.matrix)
else:
ip = data
info = "Timestamp: " + _timestamp(3)
for key,val in metadata.items():
info = info + "\n" + str(key) + ": " + str(val)
ip.setProperty("Info", info)
data = get_ip_array(ip)
#info = "Timestamp: " + _timestamp(3)
#for key,val in metadata.items():
# info = info + "\n" + str(key) + ": " + str(val)
#print "Info:" ,info
#ip.setProperty("Info", info)
metadata["Timestamp"] = time.strftime("%y/%m/%d %H:%M:%S",time.localtime())
if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
save_image(ip, filename,"tiff")
save_image(ip, filename,"tiff", metadata)
#finfo = open(filename + ".info", "w")
#for k, v in metadata.items():
# finfo.write(str(k) + ': '+ str(v) + '\n')
#info.close()
if check:
if check:
data = get_ip_array(ip)
import java.util.Arrays as Arrays
ip=open_image(filename)
read = get_ip_array(ip)
print (" ------> Error reading array: " + str(filename))
#print (" ------> Error reading array: " + str(filename))
#TODO: Original checkcode was deleted!
def save_as_tiff(data, filename, check=False, show = False, parallel=True, metadata={}):
if parallel:
+62 -18
View File
@@ -32,8 +32,8 @@ def get_id_pol(id, as_string=False):
# 5: LIn
if id<1 or id>2: raise Exception("Invalid id")
#ret = caget ("X11MA-ID1:MODE" if id==1 else "X11MA-ID2:MODE", 's' if as_string else 'i')
ret = caget ("X11MA-ID1:MODE" if id==1 else "X11MA-ID2:MODE", 'i')
if ret==0:
mode = id1_mode.read() if (id==1) else id2_mode.read()
if mode=="LINEAR":
#linear mode
alpha = get_alpha_id(id)
if alpha==0 :
@@ -42,6 +42,12 @@ def get_id_pol(id, as_string=False):
ret = 4
else:
ret = 5
elif mode == "CIRC +":
ret = 1
elif mode == "CIRC -":
ret = 2
else:
ret = -1
if as_string:
for (k,v) in POL_IDS.items():
if v==ret:
@@ -51,18 +57,21 @@ def get_id_pol(id, as_string=False):
def get_alpha_id(id):
if id<1 or id>2: raise Exception("Invalid id")
return caget ("X11MA-ID1:ALPHA" if id==1 else "X11MA-ID2:ALPHA")
return id1_alpha.read() if (id==1) else id2_alpha.read()
def put_id_offset(id, v):
if id<1 or id>2:
if id == 1:
id1_offset.write(v)
elif id == 2:
id2_offset.write(v)
else:
raise Exception("Invalid id")
caput("X11MA-ID1:ENERGY-OFFS" if (id==1) else "X11MA-ID2:ENERGY-OFFS",v)
def get_id_offset(id):
if id<1 or id>2:
raise Exception("Invalid id")
return caget("X11MA-ID1:ENERGY-OFFS" if (id==1) else "X11MA-ID2:ENERGY-OFFS")
return id1_offset.read() if (id==1) else id2_offset.read()
def put_id_pol(id, pol, alpha=None):
@@ -71,31 +80,35 @@ def put_id_pol(id, pol, alpha=None):
#pol = 3 : Mode =0, alpha = 0 lin hor
#pol = 4 : Mode =0, alpha = 90 lin vert
#pol = 5 : Mode =0, alpha = ? lin rot
print "Set id" + str(id) + " Pol=" + str(pol) + " Alpha=" + str(alpha)
if id<1 or id>2:
raise Exception("Invalid id")
pv1="X11MA-ID1:MODE" if (id==1) else "X11MA-ID2:MODE"
pv2="X11MA-ID1:ALPHA" if (id==1) else "X11MA-ID2:ALPHA"
mode_dev = id1_mode if (id==1) else id2_mode
alpha_dev = id1_alpha if (id==1) else id2_alpha
if is_string(pol):
pol=POL_IDS[pol]
if pol == 1:
caput(pv1,1)
mode_dev.write("CIRC +")
elif pol == 2:
caput(pv1,2)
mode_dev.write("CIRC -")
elif pol == 3:
caput(pv1,0)
caput(pv2,0)
mode_dev.write("LINEAR")
time.sleep(0.5)
alpha_dev.write(0)
elif pol == 4:
caput(pv1,0)
caput(pv2,90)
mode_dev.write("LINEAR")
time.sleep(0.5)
alpha_dev.write(90)
elif pol == 5:
caput(pv1,0)
mode_dev.write("LINEAR")
if alpha is not None:
time.sleep(1.0)
caput(pv2,alpha)
time.sleep(0.5)
alpha_dev.write(alpha)
def tune_detune(active_id):
offset_1 = float(get_setting("OFFSET_ID_1"))
@@ -109,3 +122,34 @@ def tune_detune(active_id):
print "Tune ID2"
put_id_offset(1, offset_1-40) #detuneID1
put_id_offset(2, offset_2) #tuneID2
class IdPol(ReadonlyRegisterBase):
def __init__(self, id):
self.id = id
def doRead(self):
return get_id_pol(self.id, True)
def getName(self):
return "id" + str(self.id) + "_pol"
add_device(IdPol(1), True)
add_device(IdPol(2), True)
id1_pol.update()
id2_pol.update()
id1_pol.setPolling(2000)
id2_pol.setPolling(2000)
class EnOptDesc(ReadonlyRegisterBase):
def doRead(self):
opt = energy_opt.read()
if opt == "PGM": return "PGM"
if opt == "PGM+ID1": return "ID1"
if opt == "PGM+ID2": return "ID2"
if opt == "PGM+ID1+ID2": return "ID1_ID2"
return ""
def getName(self):
return "energy_opt_desc"
add_device(EnOptDesc(), True)
energy_opt_desc.setPolling(2000)
+60 -1
View File
@@ -235,7 +235,7 @@ def otf(start, end, time, delay = 0.0, mode = None, offset = None, alpha = None,
#Devices
###################################################################################################
for dev in ["eiger", "id", "chopper"]:
for dev in ["eiger", "id", "chopper", "diag"]:
try:
run("devices/" + dev)
except:
@@ -428,6 +428,65 @@ def put_energy(v):
wait_channel(ALL_DONE, 1, type = 'i')
###################################################################################################
#Image measurements
###################################################################################################
from ijutils import get_measurement, load_array
import ch.psi.pshell.imaging.Filter as Filter
from ch.psi.pshell.imaging.Overlays import Text
import ch.psi.pshell.imaging.Pen as Pen
class MeasurementsFilter(Filter):
def __init__(self, measurements):
self.overlay = Text(Pen(java.awt.Color.GREEN.darker()), "", \
java.awt.Font("Verdana", java.awt.Font.PLAIN, 12), java.awt.Point(20,20))
self.measurements = measurements
self.source = None
self.renderer = None
def process(self, image, data):
try:
ip = load_array(data.array, data.width, data.height)
msg = ""
if self.measurements is not None:
for measurement in self.measurements:
val = get_measurement(ip,measurement)
msg = msg + "%s = %1.4f\n" % (measurement,val)
self.overlay.update(msg)
except:
self.overlay.update(str(sys.exc_info()[1]))
return image
def start(self, source, renderer=None):
self.stop()
self.source = source
self.renderer = renderer if (renderer is not None) else show_panel(source)
self.source.setFilter(self)
self.renderer.addOverlay(self.overlay)
def stop(self):
if self.renderer is not None:
self.renderer.removeOverlay(self.overlay)
if self.source is not None:
self.source.setFilter(None)
self.source = None
self.renderer = None
filter_measurements = None
def start_measurements(measurements=["StdDev"], source = image, renderer=None):
global filter_measurements
stop_measurements()
filter_measurements = MeasurementsFilter(measurements)
filter_measurements.start(string_to_obj(source), string_to_obj(renderer))
def stop_measurements():
global filter_measurements
if filter_measurements is not None:
filter_measurements.stop()
filter_measurements = None
###################################################################################################
#Settings
###################################################################################################
+25 -16
View File
@@ -8,22 +8,23 @@ if get_exec_pars().source == CommandSource.ui:
EXPOSURE_1 = 1.0
AVERAGE_1 = 2.0
ENERGY_1 = 850.0
POLARIZATION_1 = "Circ_Plus"
#POLARIZATION_1 = "Circ_Plus"
EXPOSURE_2 = 1.0
AVERAGE_2 = 2.0
ENERGY_2= 900.0
POLARIZATION_2 = "Circ_Minus"
#POLARIZATION_2 = "Circ_Minus"
DRY_RUN = get_dry_run()
SHOW_IMAGES = True
SAVE_DIAGS = True
ID = get_setting("ID")
EXPOSURE = [EXPOSURE_1, EXPOSURE_2]
AVERAGE = [int(AVERAGE_1), int(AVERAGE_2)]
ENERGY = [ENERGY_1, ENERGY_2]
ENERGY = [ENERGY_1, ENERGY_2]
#POLARIZATION = [POLARIZATION_1, POLARIZATION_2]
if METHOD == "Two_Energies":
@@ -92,19 +93,18 @@ pol_id2=POL_IDS[get_setting("POL_ID_2")]
#rbkEnergy=energy_rbk.read()
if METHOD == "Two_Pol":
if ID == "ID1":
if METHOD == "Two_Pol":
if ID == "ID1":
current_pol = pol_id1
elif ID == "ID2":
elif ID == "ID2":
current_pol = pol_id2
elif ID == "ID1_ID2":
put_id_pol(1,pol_id1)
put_id_pol(2,pol_id2)
elif ID == "ID1_ID2":
current_pol=pol_id1
if SWITCHING == "Tune_Detune":
tune_detune(1) #Tune ID1, Detune ID2
tune_detune(1) #Tune ID1, Detune ID2
else:
if ID == "ID1_ID2":
put_id_pol(2, current_pol) #Force both IDs to same polarization
wait_channel("X11PHS:alldone", 1)
def imageinfo(info):
@@ -161,7 +161,7 @@ def save_image_file(frame, cycle=-1, frame_index=0):
if SHOW_IMAGES:
plot(frame.matrix if (type(frame) == Data) else get_ip_array(frame), name = get_image_file_name(cycle, frame_index, True))
if AUTO_SAVE and (frame is not None):
filename = get_image_file_name(cycle, frame_index)
filename = get_image_file_name(cycle, frame_index)
threads.append(save_as_tiff(frame, filename, check=False, parallel=True, metadata=(get_diags() if SAVE_DIAGS else {})))
log(filename)
@@ -180,10 +180,7 @@ try:
log("")
log("nround = " + str(cycle) + " / " + str(MEASUREMENTS))
if METHOD == "Two_Energies":
change_energy(ENERGY_1)
###??? SETAR POLARIZATION?
if METHOD == "Two_Energies":
change_energy(ENERGY_1)
for i in range(2):
@@ -228,6 +225,7 @@ try:
join(t)
if (MEASUREMENTS > 1) and (AUTO_SAVE == 1):
print "--- Averaging..."
for i in range(len(frames)):
"""
measures = []
for cycle in range(1, MEASUREMENTS + 1):
@@ -235,7 +233,18 @@ try:
ip = open_image(filename)
#measures.append(Data(get_ip_array(ip)))
measures.append(ip)
#av = average_frames(measures) #Result is transposed???
#av = average_frames(measures) #Result is transposed???
av=average_ips (measures, roi=None, as_float=True)
"""
integration = None
for cycle in range(1, MEASUREMENTS + 1):
filename = get_image_file_name(cycle, i)
print "Open " , filename
ip = open_image(filename)
if integration is None:
integration = ip
else:
integration =integrate_ips ([integration, ip], as_float=True)
av=op_const(integration, "divide", float(MEASUREMENTS), in_place=True)
save_image_file(av, -1, i)
finally:
+4 -2
View File
@@ -11,6 +11,8 @@ if get_exec_pars().source == CommandSource.ui:
RANGES = [[500.0, 1000.0, 100.0]]
DRY_RUN = get_dry_run()
SAVE_DIAGS = True
log("ROIs: " + str(ROI))
if len(RANGES) == 0:
@@ -63,8 +65,8 @@ def grab_image(position, scan):
#filename = get_exec_pars().path + "/" + ("%02d" % Scan_Nr) + "/s" + "{seq}%03d" + "_" + ("%03d.tif" % scan.recordIndex)
filename = get_exec_pars().path + "/" + str(scan.currentPass) + "/s" + "{seq}%03d" + "_" + ("%03d.tif" % scan.recordIndex)
filename = get_context().setup.expandPath(filename)
print filename
save_as_tiff(av, filename)
print filename
save_as_tiff(av, filename, metadata=(get_diags() if SAVE_DIAGS else {}))
class Average(ReadableMatrix):
def read(self):
+8 -8
View File
@@ -38,26 +38,26 @@ elif ID =='ID1_ID2':
if ID == "ID1":
#current_pol=POL_IDS[POL_ID_1] #get_id_pol(1)
put_id_pol(1,POL_ID_1)
put_id_pol(1,POL_ID_1, ALPHA_ID_1 if (POL_ID_1=="Lin") else None )
caput('X11MA-ID2-GAP:SET',100) #open Gap ID2
caput('X11MA-ID1:HARMONIC', int(HARMONIC_ID_1))
id1_harmonic.write(int(HARMONIC_ID_1))
put_id_offset(1, float(OFFSET_ID_1)) #offset on ID1
elif ID == "ID2":
#current_pol=POL_IDS[POL_ID_2]#get_id_pol(2)
put_id_pol(2,POL_ID_2)
put_id_pol(2,POL_ID_2, ALPHA_ID_2 if (POL_ID_2=="Lin") else None )
caput('X11MA-ID1-GAP:SET',100) #open Gap ID1
caput('X11MA-ID2:HARMONIC', int(HARMONIC_ID_2))
id2_harmonic.write(int(HARMONIC_ID_2))
put_id_offset(2, float(OFFSET_ID_2)) #offset on ID2
elif ID == "ID1_ID2":
#polID1=POL_IDS[POL_ID_1]
#polID2=POL_IDS[POL_ID_2]
put_id_pol(1,POL_ID_1)
put_id_pol(2,POL_ID_2)
put_id_pol(1,POL_ID_1, ALPHA_ID_1 if (POL_ID_1=="Lin") else None )
put_id_pol(2,POL_ID_2, ALPHA_ID_2 if (POL_ID_2=="Lin") else None )
#current_pol=polID1
caput('X11MA-ID1:HARMONIC', int(HARMONIC_ID_1))
caput('X11MA-ID2:HARMONIC', int(HARMONIC_ID_2))
id1_harmonic.write(int(HARMONIC_ID_1))
id2_harmonic.write(int(HARMONIC_ID_2))
put_id_offset(1, float(OFFSET_ID_1)) #offset on ID1
put_id_offset(2, float(OFFSET_ID_2)) #offset on ID2
+89
View File
@@ -0,0 +1,89 @@
from collections import OrderedDict
diag_channels = { \
#"photon energy": "X11MA-PGM:rbkenergy", \
#"grating number": "X11MA-PGM:grating", \
#"cff value": "X11MA-PGM:rbkcff", \
"diffraction order": "X11MA-PGM:difforder0", \
#"exit slit size":"X11MA-OP2-SL:TRY.VAL", \
"front end size":"X11MA-FE-DSAPER", \
"status fast shutter":"X11MA-VME-ES1:FAST-SHTR", \
"girder x": "X11MA-HG:X1", \
"girder y": "X11MA-HG:Y1", \
"girder z": "X11MA-HG:Z1", \
"girder pitch": "X11MA-HG:PITCH1", \
"girder yaw": "X11MA-HG:YAW1", \
"girder roll set": "X11MA-HG:ROLL_SET", \
"CMU ox": "X11MA-OP-CM:ox", \
"CMU oy": "X11MA-OP-CM:oy", \
"CMU oz": "X11MA-OP-CM:oz", \
"CMU oRx": "X11MA-OP-CM:oRx", \
"CMU oRy": "X11MA-OP-CM:oRy", \
"CMU oRz": "X11MA-OP-CM:oRz", \
"CMU TRB": "X11MA-OP2-CM:TRB.RBV", \
#"mode": "X11PHS-E:OPT", \
#"id1 mode": "X11MA-ID1:MODE", \
#"id1 offset": "X11MA-ID1:ENERGY-OFFS", \
#"id1 alpha": "X11MA-ID1:ALPHA", \
#"id1 harmonic": "X11MA-ID1:HARMONIC", \
"id1 gap": "X11MA-ID1-GAP:READ", \
"id1 shift": "X11MA-ID1-SHIFT:READ", \
#"id2 mode": "X11MA-ID2:MODE", \
#"id2 offset": "X11MA-ID2:ENERGY-OFFS", \
#"id2 alpha": "X11MA-ID2:ALPHA", \
#"id2 harmonic": "X11MA-ID2:HARMONIC", \
"id2 gap": "X11MA-ID2-GAP:READ", \
"id2 shift": "X11MA-ID2-SHIFT:READ", \
"keithley 10 IO": "X11Keithley1-read", \
#"ring current": "ARIDI-PCT:CURRENT", \
"PEEM high voltage": "X11MA-ES1-PEEM:UMON", \
"PEEM leakage current": "X11MA-ES1-PEEM:IMON", \
"Pressure in PEEM": "X11MA-ES1-MAIN:PRESSURE", \
"Pressure in Column": "X11MA-ES1-COLU:PRESSURE", \
"Sample temperature": "X11MA-ES1-SW:Pt100-T", \
"Pt100 resistance": "X11MA-ES1-SW:Pt100-R", \
"high voltage": "X11MA-ES1-SD1:cam1:HighVoltage_RBV", \
}
diag_devices = {
"photon energy": energy_rbk, \
"grating number": Grating, \
"cff value": cff, \
"exit slit size": ES, \
"mode": energy_opt, \
"id1 mode": id1_mode, \
"id1 offset": id1_offset, \
"id1 alpha": id1_alpha, \
"id1 harmonic": id1_harmonic, \
"id2 mode": id2_mode, \
"id2 offset": id2_offset, \
"id2 alpha": id2_alpha, \
"id2 harmonic": id2_harmonic, \
"ring current": machine_cur, \
}
def get_diags():
ret = {}
for k,v in diag_devices.items():
try:
ret[k]=str(v.read())
except:
ret[k]="Error: " + sys.exc_info()[1]
for k,v in diag_channels.items():
try:
ret[k]=caget(v,'s')
except:
ret[k]="Error: " + sys.exc_info()[1]
ret["exposure time"] = str(eiger.getExposure())
return OrderedDict(sorted(ret.items(), key=lambda i: i[0].lower()))
def print_diags():
diags = get_diags()
for k in diags.keys():
print k + ": " + diags[k]
#- exposure time
#- mode: normal or tune/detune