Files
x11ma/script/devices/eiger.py
2020-12-18 11:39:10 +01:00

388 lines
13 KiB
Python

from ijutils import *
from ch.psi.pshell.imaging.Overlays import *
from ch.psi.pshell.imaging.Utils import *
import ch.psi.pshell.imaging.Pen as Pen
import java.awt.Rectangle as Rectangle
import ch.psi.pshell.imaging.Data as Data
import ch.psi.pshell.device.Camera.DataType as DataType
import ch.psi.utils.Chrono as Chrono
CONTINOUS_MODE_MIN_TIME = 4000
###############################################################################
# ROI Integration
###############################################################################
def start_eiger_ioc():
cmd= "cd /sls/X11MA/data/X11MA/SW/Eiger/;launch"
return run("sshutils", {"USR": "gac-x11ma", "PWD": "", "HOST": "x11ma-softioc","PORT": 22, "CMD": cmd})
def stop_eiger_ioc():
try:
caputq("X11MA-ES1-SD1:SYSRESET", 1);
print "IOC stopped"
except:
print "IOC not running"
cmd= "proc=$(ps aux | grep 'Eiger Receiver' | awk -F ' ' '{print $2}' | xargs); kill $proc"
return run("sshutils", {"USR": "gac-x11ma", "PWD": "", "HOST": "x11ma-softioc","PORT": 22, "CMD": cmd})
def integrate_roi(source, x,y, w, h):
if source.data is None:
source.update()
roi = source.data.getRoi(Rectangle(x,y, w, h))
return roi.integrate(False)
class RoiIntensitySourceListener (ImageListener):
def __init__(self, parent):
self.parent = parent
def onImage(self, origin, image, data):
self.parent.update()
def onError(self, origin, ex):
pass
class RoiIntensity(ReadonlyRegisterBase):
def __init__(self, name, source, x,y, w, h):
ReadonlyRegisterBase.__init__(self, name)
self.source=source
self.roi = x,y, w, h
self.source_listener = RoiIntensitySourceListener(self)
def doRead(self):
x,y, w, h = self.roi
return integrate_roi(self.source, x,y, w, h)
def doSetMonitored(self, value):
if value:
self.source.addListener(self.source_listener)
else:
self.source.removeListener(self.source_listener)
def doClose(self):
self.source.removeListener(self.source_listener)
def create_roi_devices(roi_list, add = True):
rois = []
for r in roi_list:
roi = RoiIntensity(r, image, roi_list[r][0], roi_list[r][1], roi_list[r][2], roi_list[r][3])
if add:
add_device(roi, True)
rois.append(roi)
return rois
###############################################################################
# Frame integration
###############################################################################
"""
def get_image(source, roi=None, wait_next=False):
if wait_next:
source.waitNext(-1)
elif wait_next:
if str(source.camera)=="Single":
eiger.start()
eiger.waitCacheChange(20000)
ret = load_image(Utils.grayscale(source.output, Rectangle(roi[0], roi[1], roi[2], roi[3]) if (roi is not None) else None))
return ret
def grab_frames(source, samples, roi=None, wait_next=False, sleep=0):
frames = []
for i in range(samples):
if sleep>0:
time.sleep(sleep)
aux = get_image(source, roi, wait_next)
frames.append(aux)
return frames
def average_frames(source, samples=1, roi=None, wait_next=False, sleep=0, as_float=True):
return average_ips(grab_frames(source, samples, roi, wait_next, sleep), as_float)
def integrate_frames(source, samples=1, roi=None, wait_next=False, sleep=0, as_float=True):
return integrate_ips(grab_frames(source, samples, roi, wait_next, sleep), as_float)
"""
def grab_frame(source, roi=None, wait_next=False, outliers_threshold=None, outliers_mask=None):
if outliers_threshold is None:
outliers_threshold = get_outliers_threshold()
if outliers_mask is None:
outliers_mask = get_outliers_mask()
if wait_next:
if str(eiger.grabMode)=="Single":
eiger.waitReady(5000)
eiger.start()
#eiger.getDataArray().waitCacheChange(2000)
source.waitNext(20000 + int(eiger.exposure * 1000))
#ret = load_image(Utils.grayscale(source.output, Rectangle(roi[0], roi[1], roi[2], roi[3]) if (roi is not None) else None))
time.sleep(0.01)
data=source.data
if roi is not None:
data = data.getRoi(Rectangle(roi[0], roi[1], roi[2], roi[3]))
#ret = load_image(img)
if outliers_mask is not None:
data.mult(outliers_mask)
if outliers_threshold>0:
data.threshold(outliers_threshold, False, None)
return data
def grab_frames(source, samples, roi=None, wait_next=False, sleep=0, outliers_threshold=None, outliers_mask=None):
frames = []
for i in range(samples):
if (i>0) and (sleep>0):
time.sleep(sleep)
aux = grab_frame(source, roi, wait_next, outliers_threshold, outliers_mask)
frames.append(aux)
return frames
def integrate_frames(frames):
if frames is None or (len(frames)==0):
return None
ret = frames[0].copy()
for data in frames[1:]:
ret.sum(data)
return ret
def average_frames(frames):
ret = integrate_frames(frames)
if ret is not None:
ret.div(len(frames))
return ret
def _timestamp(prec=0):
t = time.time()
s = time.strftime("%y/%m/%d %H:%M:%S", time.localtime(t))
if prec > 0:
s += ("%.9f" % (t % 1,))[1:2+prec]
return s
def _save_as_tiff(data, filename, check=False, show = False, metadata={}):
if type(data) == Data:
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)
#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", metadata)
#finfo = open(filename + ".info", "w")
#for k, v in metadata.items():
# finfo.write(str(k) + ': '+ str(v) + '\n')
#info.close()
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))
#TODO: Original checkcode was deleted!
def save_as_tiff(data, filename, check=False, show = False, parallel=True, metadata={}):
if parallel:
return fork((_save_as_tiff,(data, filename, check, show, metadata)),)
else:
_save_as_tiff(data, filename, check, show, metadata)
def trigger_eiger(wait=True):
eiger.waitReady(5000)
eiger.start()
if wait:
image.waitNext(20000 + int(eiger.exposure * 1000))
#eiger.waitNewImage(20000 + int(eiger.exposure * 1000))
def get_eiger_exposure_readback():
return caget("X11MA-ES1-SD1:cam1:AcquireTime_RBV",'f')
def set_exposure_time(value, check = True, retries=5):
if value == eiger.getExposure():
return
started = eiger.isStarted()
if started:
stop_eiger()
for i in range(retries):
try:
eiger.setExposure(value)
if check:
readback=get_eiger_exposure_readback()
if abs(value - readback) > 0.01:
raise Exception("Error changing Eiger exposure time to %f: readback=%f" % (value, readback))
except:
if i==(retries-1):
raise
else:
print "Error changing Eiger exposure time: retrying"
time.sleep(0.3)
if started:
if eiger.grabMode==eiger.GrabMode.Continuous:
eiger.start()
def get_eiger_number_of_frames():
return caget("X11MA-ES1-SD1:cam1:NumFrames_RBV",'i')
def set_eiger_number_of_frames(value, check = True):
if value == get_eiger_number_of_frames():
return
started = eiger.isStarted()
if started:
stop_eiger()
caput("X11MA-ES1-SD1:cam1:NumFrames",value)
if check:
readback = get_eiger_number_of_frames()
if value != readback:
raise Exception("Error changing Eiger number of frames to %d: readback=%d" % (value, readback))
if started:
if eiger.grabMode==eiger.GrabMode.Continuous:
eiger.start()
#Wait for channel to chenge
def stop_eiger():
global chrono_eiger
chrono_eiger.waitTimeout(CONTINOUS_MODE_MIN_TIME)
started = eiger.isStarted()
if started:
eiger.stop()
eiger.grabMode=eiger.GrabMode.Single
eiger.stop()
eiger.waitReady(5000)
time.sleep(0.1)
#if eiger.acquire.read() >0:
# raise Exception("Error stopping Eiger")
chrono_eiger = Chrono()
def init_eiger(exposure=None, check=True, retries=2):
"""
Set Eiger scan mode
"""
global chrono_eiger
chrono_eiger.waitTimeout(CONTINOUS_MODE_MIN_TIME)
for i in range(retries):
try:
stop_eiger() #Set mode single
eiger.setNumImages(1)# Is it relevant?
set_eiger_number_of_frames(1)
if exposure:
set_exposure_time(exposure, check)
apply_averaging_detector(is_averaging_detector())
break
except:
if i==(retries-1):
raise
else:
print "Error initializing Eiger, retrying: " + str(sys.exc_info()[1])
def restore_eiger(check=True, retries=2):
"""
Set Eiger default mode
"""
global chrono_eiger
for i in range(retries):
try:
stop_eiger()
eiger.setNumImages(1)# Is it relevant?
set_eiger_number_of_frames(1, check)
set_exposure_time(0.2, check)
apply_averaging_detector(False)
eiger.grabMode=eiger.GrabMode.Continuous
eiger.start()
chrono_eiger = Chrono()
break
except:
if i==(retries-1):
raise
else:
print "Error restoring Eiger, retrying " + str(sys.exc_info()[1])
def is_averaging_detector():
return str(get_setting("AVERAGING_DETECTOR")).lower()=="true"
def apply_averaging_detector(value):
if value:
caput("X11MA-ES1-SD1:Proc1:EnableCallbacks", True)
caput("X11MA-ES1-SD1:Proc1:EnableFilter", True)
else:
caput("X11MA-ES1-SD1:Proc1:EnableFilter", False)
caput("X11MA-ES1-SD1:Proc1:NumFilter", 1)
caput("X11MA-ES1-SD1:cam1:NumCycles", 1)
def average_eiger_frames(samples, roi=None, wait_next=False, sleep=0, outliers_threshold=None, outliers_mask=None):
if is_averaging_detector():
caput("X11MA-ES1-SD1:Proc1:NumFilter", samples)
caput("X11MA-ES1-SD1:cam1:NumCycles", samples)
return grab_frame(image, roi, wait_next, outliers_threshold, outliers_mask)
else:
ret = grab_frames(image, samples, roi, wait_next, sleep, outliers_threshold, outliers_mask)
return average_frames(ret) if samples > 1 else ret[0]
_outliers_mask_timestamp = 0
_outliers_mask = None
def get_outliers_mask(data_type='f'):
global _outliers_mask_timestamp, _outliers_mask
if get_exec_pars().start == _outliers_mask_timestamp:
return _outliers_mask
_outliers_mask_timestamp = get_exec_pars().start
try:
_outliers_mask = None
filename = get_outliers_mask_file()
if filename:
ip=open_image(filename)
#TRANSPOSE - ImageJ stores the data transposed
ip.getProcessor().rotate(-90)
ip.getProcessor().flipVertical()
array = get_ip_array(ip)
array = Convert.toPrimitiveArray(array, ScriptUtils.getType(data_type))
_outliers_mask = Data(array)
print "Generated outliers mask"
except:
pass
return _outliers_mask
eiger.setDataType(DataType.Float32)
eiger.getDataArray().monitored=True
if False:
integrate_roi(image, 10, 5, 20, 10)
add_device(RoiIntensity("Region1", image, 10, 5, 20, 10), True)
add_device(RoiIntensity("Region2", image, 10, 5, 40, 20), True)
import ch.psi.pshell.data.ProviderCSV as ProviderCSV
ProviderCSV.setDefaultItemSeparator(" ")
tscan((Region1, Region2), 10, 0.1, layout="table", provider = "csv")
ret = grab_frames(image, 10, sleep=0.1)
av = integrate_frames(ret)
save_as_tiff(av,"{images}/data.tif", True)
print "Success"