def focus(self, stage, *, start_offset=None, stop_offset=None, step=None, intensity=None, Nloops=None, wait=False, checkid=None, change_coordinates=True, speed=None, quick=None): """ start_offset: How far back from current position stop_offset: How far forth from surrent position step: Step size Nloops default 1: Each loop has a 10X smaller step size. wait default False: Should the thread wait for completion """ if not self.app_delegate.camera_delegate.isZoomed(): raise FocusError('Must select ROI to focus!') if self.thread.isRunning(): raise FocusError('Already Focusing') with MutexContainer(self._mutex): self._last_result = None if intensity is not None: self._settings["intensity"] = intensity if start_offset is not None: self._settings["From"] = start_offset if stop_offset is not None: self._settings["To"] = stop_offset if step is not None: self._settings["Step"] = step if Nloops is not None: self._settings["Nloops"] = Nloops if speed is not None: self._settings["speed"] = speed if quick is not None: self._settings["quick"] = quick self.update_settings.emit(self._settings) self.thread.set_args(self._settings, stage, checkid, change_coordinates) self.thread.start() if wait: self.wait_thread()
def run(self): if self._settings is None: self.callback(None, np.nan, FocusError("Settings not initialised!")) return if self._checkid is None: lockid = self._md.lock() if lockid is None: self.callback(None, np.nan, MotionError("Unable to lock the movement")) return else: lockid = self._checkid try: data, z_best, error = self._zcorrector.focus( self._settings, checkid=lockid, change_coordinates=self._change_coordinates) self._md.unlock() self.callback(data, z_best, error) except (FocusError, MotionError, CameraError) as e: logError() self.callback(None, np.nan, e) finally: self._md.unlock() self._settings = None
def piezo_plane(self, checkid=None, wait=False): stage = self._md.piezo XYs = ([-45, -45], [-45, 45], [45, 45], [45, -45]) self.plane_thread.settings(stage=stage, XYpos=XYs, arange=(5, -5, -0.5)) if checkid is not None: self.plane_thread.checkid = checkid self.plane_thread.start() if wait: success = self.plane_thread.wait(FOCUS_TIMEOUT_MS) if not success: raise FocusError("Timeout on focus") if self.plane_thread.error is not None: raise self.plane_thread.error
def run(self): try: start, stop, step = self._range positions = [] for i, corner in enumerate(self._pos): corner[2] = start self._stage.goto_position(corner, speed=1000, wait=True, checkid=self.checkid) self._fd.focus(start_offset=0, stop_offset=(stop - start), step=step, stage=self._stage, wait=True, checkid=self.checkid, change_coordinates=False, quick=False, speed=1000) data, z_best, error = self._fd.get_result() if error is None: positions.append(self._stage.get_position(raw=True)) if len(positions) < 3: raise FocusError('Need at least 3 successful focus.') corrections = self._stage.corrections offset, rotation_angles = solve_z( positions, offset=corrections["offset"], rotation_angles=corrections["rotation angles"]) corrections["offset"] = offset corrections["rotation angles"] = rotation_angles self._stage.corrections = corrections except (FocusError, MotionError) as e: logError() self.error = e self.error_signal.emit(f"Plane Error {e}")
def focus(self, settings, checkid=None, change_coordinates=True): """ Go to the best focal point for the laser """ start_offset = settings["From"] stop_offset = settings["To"] step = settings["Step"] N_loops = settings["Nloops"] intensity = settings["intensity"] self.speed = settings["speed"] self.quick = settings["quick"] self.lockid = checkid self.startlaser(intensity) Z = self.stage.get_position(raw=True)[2] z_start = Z + start_offset z_stop = Z + stop_offset current_step = float(step) list_zpos = [] list_int = [] for i in range(N_loops): data, success = self.focus_range(z_start, z_stop, current_step) zPos, intensities = data.T list_zpos.append(zPos) list_int.append(intensities) if not success: return np.asarray([list_zpos, list_int ]), np.nan, FocusError("Focus Failed") argbest = np.argmax(intensities) current_step /= 10 z_start = zPos[argbest - 1] z_stop = zPos[argbest + 1] self.endlaser() Y = intensities close = intensities > .8 * intensities.max() step = np.mean(np.diff(zPos)) if np.sum(close) < 4: close = np.abs(zPos - zPos[argbest]) < 1.5 * np.abs(step) fit = np.polyfit(zPos[close], Y[close], 2) zBest = -fit[1] / (2 * fit[0]) if np.abs(zBest - zPos[argbest]) > 2 * np.abs(step): zBest = zPos[argbest] self.stage.goto_position([np.nan, np.nan, zBest], speed=self.speed, wait=True, checkid=self.lockid, isRaw=True) if change_coordinates: self.stage.set_Z_zero() # save result and position return np.asarray([list_zpos, list_int]), zBest, None
def wait_thread(self): success = self.thread.wait(FOCUS_TIMEOUT) if not success: self.thread.terminate() raise FocusError("Timeout")
def get_result(self): self.wait_thread() if self._last_result is None: raise FocusError("No result to show, check focus is not running") return self._last_result