From 39e2e0baad44fa057863048fe21e09fdbc93c32e Mon Sep 17 00:00:00 2001 From: Joel Collins Date: Mon, 27 May 2019 13:35:53 +0100 Subject: [PATCH 1/3] Re-implemented scan methods --- openflexure_microscope/stage/sanga.py | 48 ++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/openflexure_microscope/stage/sanga.py b/openflexure_microscope/stage/sanga.py index aa1ccfa2..59d70d76 100644 --- a/openflexure_microscope/stage/sanga.py +++ b/openflexure_microscope/stage/sanga.py @@ -21,6 +21,7 @@ class SangaStage(BaseStage): self.board = Sangaboard(port, **kwargs) self._backlash = None + self.axis_names = ['x', 'y', 'z'] @property def state(self): @@ -61,7 +62,10 @@ class SangaStage(BaseStage): back by ``backlash[i]``. This is computed per-axis, so if some axes are moving in the same direction as ``backlash``, they won't do two moves. """ - return self._backlash if self._backlash else np.array([0]*self.n_axes) + if self._backlash is not None: + return self._backlash + else: + return np.array([0] * self.n_axes) @backlash.setter def backlash(self, blsh): @@ -98,7 +102,7 @@ class SangaStage(BaseStage): # For each axis where we're moving in the *opposite* # direction to self.backlash, we deliberately overshoot: initial_move -= np.where( - self.backlash*displacement < 0, + self.backlash * displacement < 0, self.backlash, np.zeros(self.n_axes, dtype=self.backlash.dtype) ) @@ -114,6 +118,42 @@ class SangaStage(BaseStage): with self.lock: self.board.move_abs(final, **kwargs) + def scan_linear(self, rel_positions, backlash=True, return_to_start=True): + """ + Scan through a list of (relative) positions (generator fn) + rel_positions should be an nx3-element array (or list of 3 element arrays). + Positions should be relative to the starting position - not a list of relative moves. + backlash argument is passed to move_rel + if return_to_start is True (default) we return to the starting position after a + successful scan. NB we always attempt to return to the starting position if an + exception occurs during the scan.. + """ + starting_position = self.position + rel_positions = np.array(rel_positions) + assert rel_positions.shape[1] == 3, ValueError("Positions should be 3 elements long.") + try: + self.move_rel(rel_positions[0], backlash=backlash) + yield 0 + + for i, step in enumerate(np.diff(rel_positions, axis=0)): + self.move_rel(step, backlash=backlash) + yield i + 1 + except Exception as e: + return_to_start = True # always return to start if it went wrong. + raise e + finally: + if return_to_start: + self.move_abs(starting_position, backlash=backlash) + + def scan_z(self, dz, **kwargs): + """Scan through a list of (relative) z positions (generator fn) + This function takes a 1D numpy array of Z positions, relative to + the position at the start of the scan, and converts it into an + array of 3D positions with x=y=0. This, along with all the + keyword arguments, is then passed to ``scan_linear``. + """ + return self.scan_linear([[0, 0, z] for z in dz], **kwargs) + def close(self): """Cleanly close communication with the stage""" self.board.close() @@ -141,8 +181,8 @@ class SangaStage(BaseStage): need to worry about that here. """ if type is not None: - print("An exception occurred inside a with block, resetting " + - "position to its value at the start of the with block") + print("An exception occurred inside a with block, resetting position \ + to its value at the start of the with block") try: time.sleep(0.5) self.move_abs(self._position_on_enter) From 5e34b998ddbd0376d24c89dcf9dc31a63ae4313e Mon Sep 17 00:00:00 2001 From: Joel Collins Date: Tue, 28 May 2019 09:27:47 +0100 Subject: [PATCH 2/3] Fixed plugin calling old focus_rel method --- openflexure_microscope/plugins/default/autofocus/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openflexure_microscope/plugins/default/autofocus/plugin.py b/openflexure_microscope/plugins/default/autofocus/plugin.py index 78a0ac10..e11b08f6 100644 --- a/openflexure_microscope/plugins/default/autofocus/plugin.py +++ b/openflexure_microscope/plugins/default/autofocus/plugin.py @@ -45,7 +45,7 @@ class AutofocusPlugin(MicroscopePlugin): sharpnesses.append(self.measure_sharpness(metric_fn)) newposition = positions[np.argmax(sharpnesses)] - stage.focus_rel(newposition - stage.position[2]) + stage.move_rel([0, 0, newposition - stage.position[2]]) return positions, sharpnesses From 60c49a8331430fdc3875c2b95cbfa44660d94922 Mon Sep 17 00:00:00 2001 From: Joel Collins Date: Tue, 28 May 2019 09:28:08 +0100 Subject: [PATCH 3/3] Fixed setting Iterable vs Int backlash --- openflexure_microscope/stage/sanga.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openflexure_microscope/stage/sanga.py b/openflexure_microscope/stage/sanga.py index 59d70d76..fbccb9f4 100644 --- a/openflexure_microscope/stage/sanga.py +++ b/openflexure_microscope/stage/sanga.py @@ -1,5 +1,7 @@ import numpy as np import time +import logging +from collections.abc import Iterable from .sangaboard import Sangaboard from openflexure_microscope.stage.base import BaseStage @@ -69,10 +71,14 @@ class SangaStage(BaseStage): @backlash.setter def backlash(self, blsh): + logging.debug("Setting backlash to {}".format(blsh)) if blsh is None: self._backlash = None - assert len(blsh) == self.n_axes - self._backlash = np.array([int(blsh)]*self.n_axes, dtype=np.int) + elif isinstance(blsh, Iterable): + assert len(blsh) == self.n_axes + self._backlash = np.array(blsh) + else: + self._backlash = np.array([int(blsh)]*self.n_axes, dtype=np.int) def move_rel(self, displacement, axis=None, backlash=True): """Make a relative move, optionally correcting for backlash.