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 import subprocess #GRAB_MIN_TIME = 1000 CONTINOUS_MODE_MIN_TIME = 4000 ############################################################################### # ROI Integration ############################################################################### def start_eiger_ioc(): subprocess.call("/work/sls/bin/X_X11MA_EigerStart.sh") print "IOC started" def stop_eiger_ioc(): subprocess.call("/work/sls/bin/X_X11MA_EigerStop.sh") print "IOC stopped" """ 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) """ def integrate_roi(source, x,y, w, h): if source.data is None: source.update() rect = Rectangle(x,y, w, h) roi = source.data.getRoi(rect) """ outliers_mask = get_outliers_mask() if outliers_mask is not None: mask = outliers_mask.getRoi(rect) roi.mult(mask) outliers_threshold = get_outliers_threshold() if outliers_threshold>0: roi.threshold(outliers_threshold, False, 0.0) """ 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 ############################################################################### #chrono_grab= Chrono() def grab_frame(source, roi=None, wait_next=False, outliers_threshold=None, outliers_mask=None, retries=None, timeout=None): global eiger_averaging_number_of_samples #, chrono_grab #chrono_grab.waitTimeout(GRAB_MIN_TIME) """ if outliers_threshold is None: outliers_threshold = get_outliers_threshold() if outliers_mask is None: outliers_mask = get_outliers_mask() """ if wait_next: if retries is None: retries = 3 if timeout is None: timeout=10.0 exposures = 1 if (eiger_averaging_number_of_samples is None) else eiger_averaging_number_of_samples retries=max(retries,1) timeout = int(((eiger.exposure * exposures) + timeout) * 1000) for try_count in range(retries): if str(eiger.grabMode)=="Single": eiger.waitReady(5000) eiger.start() elif str(eiger.grabMode)=="Continuous": if not eiger.isStarted(): eiger.start() try: #eiger.getDataArray().waitCacheChange(timeout) source.waitNext(timeout) break except java.util.concurrent.TimeoutException: if try_count == (retries-1): raise msg = "Eiger timeout - retrying #" + str(try_count) print msg log(msg) #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) #chrono_grab = Chrono() return data def grab_frames(source, samples, roi=None, wait_next=False, sleep=0, outliers_threshold=None, outliers_mask=None, retries=None, timeout=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, retries, timeout) 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! calculated_shifts={} 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 _shift_and_save_as_tiff(data, filename, reference=None, roi=None, image_drift =None, check=False, show = False, metadata={}): global calculated_shifts try: if image_drift is None: xoff, yoff, error, diffphase, image_drift = calculate_shift(reference,data, roi) print xoff, yoff, error, diffphase, image_drift if (abs(xoff) > MAX_SHIFT) or (abs(yoff) > MAX_SHIFT): raise Exception("Shift too big:" + str(xoff, yoff)) print "-> Calculated shift: ", xoff, yoff, error, diffphase shifted_frame = apply_shift(data, image_drift) calculated_shifts[filename]=image_drift except: print "-> Error shifting image: " + str(sys.exc_info()[1]) return metadata["roi"] = str(roi) save_as_tiff(shifted_frame, filename, check, show, parallel=False, metadata=metadata) def shift_and_save_as_tiff(data, filename, reference=None, roi=None, shift=None, check=False, show = False, parallel=True, metadata={}): if parallel: return fork((_shift_and_save_as_tiff,(data, filename, reference, roi, shift, check, show, metadata)),) else: _shift_and_save_as_tiff(data, filename, reference, roi, shift, 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.waitReady(5000) else: eiger.grabMode=eiger.GrabMode.Single 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, exposure_time = 0.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(exposure_time, 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" eiger_averaging_number_of_samples=None def apply_averaging_detector(value): global eiger_averaging_number_of_samples if value: caput("X11MA-ES1-SD1:Proc1:EnableCallbacks", True) caput("X11MA-ES1-SD1:Proc1:EnableFilter", True) caput("X11MA-ES1-SD1:Proc1:AutoResetFilter", 1) caput("X11MA-ES1-SD1:Proc1:FilterCallbacks", 1) else: caput("X11MA-ES1-SD1:Proc1:EnableFilter", False) caput("X11MA-ES1-SD1:Proc1:NumFilter", 1) caput("X11MA-ES1-SD1:cam1:NumCycles", 1) eiger_averaging_number_of_samples = None def average_eiger_frames(samples, roi=None, wait_next=False, sleep=0, outliers_threshold=None, outliers_mask=None, retries=None, timeout=None): global eiger_averaging_number_of_samples #, chrono_eiger sample = int(samples) if is_averaging_detector(): if caget("X11MA-ES1-SD1:Proc1:EnableFilter")!="Enable": raise Excetion("Cannot average frames in Eiger: filter is disabled") #chrono_eiger.waitTimeout(1000) caput("X11MA-ES1-SD1:Proc1:NumFilter", samples) caput("X11MA-ES1-SD1:cam1:NumCycles", samples) if samples != eiger_averaging_number_of_samples: log ("Changed Eiger averaging number of samples: " + str(samples)) # TODO: if increasing number of samples next read returns quicly, as if using previous sample number eiger_averaging_number_of_samples = samples caput("X11MA-ES1-SD1:Proc1:ResetFilter", 1) chrono_eiger=Chrono() return grab_frame(image, roi, wait_next, outliers_threshold, outliers_mask, retries, timeout) else: ret = grab_frames(image, samples, roi, wait_next, sleep, outliers_threshold, outliers_mask, retries, timeout) 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 class ProcImage(Filter): def __init__(self): Filter.__init__(self, "image_filter") self.roi=None self.outliers_threshold=None self.outliers_mask =None def processData(self, data): if data is None: return None outliers_threshold = get_outliers_threshold() if (self.outliers_threshold is None) else self.outliers_threshold outliers_mask = get_outliers_mask() if (self.outliers_mask is None) else self.outliers_mask roi = self.roi data=data.copy() 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) #chrono_grab = Chrono() return data def process(self, image, data): return None #Does not generate BufferedImage here #image.removeAllListeners() proc_image_filter=ProcImage() raw.addListener(proc_image_filter) proc_image=ColormapAdapter("image", proc_image_filter) add_device(proc_image, True) raw.refresh() 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"