SETTLING_TIME =0.5 MAX_CONTRAST = 10e14 MAX_SHIFT = 300 import java.awt.Rectangle as Rectangle class RoiContrast(ReadonlyRegisterBase): def doRead(self): if hasattr(self, "roi"): return image.getData().getGradientVariance(False, self.roi) return 0.0 def getName(self): return "roi_contrast" def set_roi(self, roi): self.roi=roi if get_device("image_contrast") is None: add_device(image.getContrast(), False) if get_device("roi_contrast") is None: add_device(RoiContrast(), False) def get_focus_scan_pos(): return objective.read(),obj_stig_a.read(),obj_stig_b.read() def apply_focus_scan_pos(pos): objective.write(pos[0]) obj_stig_a.write(pos[1]) obj_stig_b.write(pos[2]) focus_scan_roi=None focus_scan_renderer=None def show_focus_scan_roi(): global focus_scan_roi, focus_scan_renderer if focus_scan_renderer is None: pn=show_panel(image) ov=Overlays.Rect(Pen(Color.BLUE), Point(focus_scan_roi.x,focus_scan_roi.y),Dimension(focus_scan_roi.width,focus_scan_roi.height)) pn.clearOverlays() #ov.setMovable(True) pn.addOverlay(ov) else: pn = focus_scan_renderer if len(pn.overlays)==0: pn.addOverlay(Overlays.Rect(pn.getPenProfile())) pn.overlays[0].setMovable(True) ov=pn.overlays[0] ov.update(Point(focus_scan_roi.x,focus_scan_roi.y),Dimension(focus_scan_roi.width,focus_scan_roi.height)) pn.refresh() def set_focus_scan_roi(roi, renderer=None): global focus_scan_roi, focus_scan_renderer focus_scan_renderer = renderer focus_scan_roi = roi show_focus_scan_roi() def get_focus_scan_roi(): return focus_scan_roi def scan_contrast(positioner, pos_range, pos_step, roi = None, average = 1, update_position = True): if roi is None: sensor = image_contrast else: sensor = roi_contrast roi_contrast.set_roi(roi) if average > 1: sensor = create_averager(sensor, average, interval = eiger.exposure, name = image_contrast.name, monitored = False) def after_read(rec): if rec[sensor] > MAX_CONTRAST: print "Invalid contrast value" time.sleep(eiger.exposure) rec.invalidate() def before_pass(scan, num_pass): print "Waiting to reach scan init pos" time.sleep(1.0) cur = positioner.read() if (cur < positioner.minValue+pos_range) or (cur > positioner.maxValue-pos_range): raise Exception("Cannot perform contrast scan: " + positioner.name + " too close to limit") r = lscan( positioner, [sensor,], -pos_range, pos_range, pos_step, \ latency=eiger.exposure+SETTLING_TIME, relative=True, after_read=after_read, before_pass=before_pass) ydata, xdata = r[sensor], r[positioner] if average > 1: ydata = [v.doubleValue() for v in ydata] (norm, mn, std ) = fit (ydata, xdata, limit_to_range=True) range_scan = (min(r[positioner]), max(r[positioner])) if (mn is not None) and (range_scan[0] <= mn <= range_scan[1]): print "Valid fit for ", positioner.name, mn if update_position: time.sleep(0.5) # Wait restoring positions print "Updating position: ", positioner.name, mn positioner.write(mn) else: print "Invalid fit for ", positioner.name, mn, range_scan time.sleep(SETTLING_TIME) # Wait restoring positions return r def update_roi_pos(cur_data, former_data): try: roi=get_focus_scan_roi() calc_roi = Roi(roi.x,roi.y,roi.width, roi.height) xoff, yoff, error, diffphase, _ = calculate_shift(former_data,cur_data, calc_roi) print "Calculated shift: ", xoff, yoff, error, diffphase, if (abs(xoff) <= MAX_SHIFT) and (abs(yoff) <= MAX_SHIFT): x,y=int(roi.x - xoff), int(roi.y - yoff) print "Updating ROI location to ", x, y x,y=max(x,0), max(y,0) x,y=min(x,cur_data.width-roi.width), min(y,cur_data.height-roi.height) roi.setLocation(x,y) show_focus_scan_roi() else: print "Error - shift too big: xoff, yoff" except: print "Error calculating shift: " + str(sys.exc_info()[1]) former_data=None def scan_focus(positioner, pos_range, pos_step, average = 1, update_position = True, save_images=True): global former_data roi=get_focus_scan_roi() former_data = image.data initial_state = get_focus_scan_pos() initial_roi_location = roi.location if roi is not None else None if roi is None: sensor = image_contrast else: sensor = roi_contrast roi_contrast.set_roi(roi) if average > 1: sensor = create_averager(sensor, average, interval = eiger.exposure, name = image_contrast.name, monitored = False) def before_read(pos,scan): global former_data if str(eiger.grabMode)=="Single": eiger.start() else: time.sleep(eiger.exposure) image.waitNext(20000) cur_data = image.data try: print "----- Pos: ", pos update_roi_pos(cur_data, former_data) finally: former_data = cur_data print "New ROI pos: " , roi_contrast.roi.location def after_read(rec, scan): global former_data if rec[sensor] > MAX_CONTRAST: print "Invalid contrast value" time.sleep(eiger.exposure) rec.invalidate() else: if (save_images): filename = get_exec_pars().path + "/images/" + str(rec.index) + ".tif" meta={positioner.name:rec[positioner], "contrast": rec[sensor]} save_as_tiff(former_data, filename, check=True, parallel=True, metadata=meta) def before_pass(scan, num_pass): pass #print "Waiting to reach scan init pos" #time.sleep(1.0) r = lscan( positioner, [sensor,], -pos_range, pos_range, pos_step, \ latency=SETTLING_TIME, relative=True, initial_move=False, restore_position=False, \ before_read=before_read, after_read=after_read, before_pass=before_pass) ydata, xdata = r[sensor], r[positioner] if average > 1: ydata = [v.doubleValue() for v in ydata] (norm, mn, std ) = fit (ydata, xdata, limit_to_range=True) range_scan = (min(r[positioner]), max(r[positioner])) if (mn is not None) and (range_scan[0] <= mn <= range_scan[1]): print "Valid fit for ", positioner.name, mn if update_position: #time.sleep(1.0) # Wait restoring positions #print "Updating position: ", positioner.name, mn #show_message("Setting mx pos", blocking = True) #time.sleep(3.0) former_data = image.data positioner.write(mn) time.sleep(eiger.exposure+SETTLING_TIME) #show_message("Updating ROI", blocking = True) update_roi_pos(image.data, former_data) else: apply_focus_scan_pos(initial_state) if initial_roi_location: roi.location=initial_roi_location else: print "Invalid fit for ", positioner.name, mn, range_scan apply_focus_scan_pos(initial_state) if initial_roi_location: roi.location=initial_roi_location time.sleep(0.) # Wait restoring positions return r