diff --git a/openflexure_microscope/api/v1/blueprints/base.py b/openflexure_microscope/api/v1/blueprints/base.py index 2195a025..a4fe6c36 100644 --- a/openflexure_microscope/api/v1/blueprints/base.py +++ b/openflexure_microscope/api/v1/blueprints/base.py @@ -172,7 +172,7 @@ class ConfigAPI(MicroscopeView): logging.debug("Updating settings from POST request.") - self.microscope.write_config(payload.json) + self.microscope.apply_config(payload.json) self.microscope.save_config() return jsonify(self.microscope.read_config(json_safe=True)) diff --git a/openflexure_microscope/camera/base.py b/openflexure_microscope/camera/base.py index 8dbf339f..7f0a5e6c 100644 --- a/openflexure_microscope/camera/base.py +++ b/openflexure_microscope/camera/base.py @@ -144,7 +144,7 @@ class BaseCamera(metaclass=ABCMeta): pass @abstractmethod - def read_config(self): + def read_config(self) -> dict: """Return the current settings as a dictionary""" pass diff --git a/openflexure_microscope/camera/pi.py b/openflexure_microscope/camera/pi.py index 6a2bbd99..9b4c7332 100644 --- a/openflexure_microscope/camera/pi.py +++ b/openflexure_microscope/camera/pi.py @@ -95,7 +95,7 @@ class StreamingCamera(BaseCamera): self.camera.close() # HANDLE SETTINGS - def read_config(self): + def read_config(self) -> dict: """ Return config dictionary of the StreamingCamera. """ @@ -119,7 +119,7 @@ class StreamingCamera(BaseCamera): return conf_dict - def apply_config(self, config: dict) -> None: + def apply_config(self, config: dict): """ Write a config dictionary to the StreamingCamera config. diff --git a/openflexure_microscope/microscope.py b/openflexure_microscope/microscope.py index 81a447ea..d608e39b 100644 --- a/openflexure_microscope/microscope.py +++ b/openflexure_microscope/microscope.py @@ -164,15 +164,11 @@ class Microscope: # If attached to a camera if ('camera_settings' in config) and self.camera: - # Update camera config self.camera.apply_config(config['camera_settings']) # If attached to a stage if ('stage_settings' in config) and self.stage: - if 'backlash' in config: - # Construct backlash array - backlash = axes_to_array(config['backlash'], ['x', 'y', 'z'], [0, 0, 0]) - self.stage.backlash = backlash + self.stage.apply_config(config['stage_settings']) # Todo: tidy up with some loopy goodness if 'id' in config: @@ -208,21 +204,8 @@ class Microscope: settings_current['camera_settings'] = settings_current_camera # If attached to a stage - # TODO: Offload to stage object if self.stage: - if hasattr(self.stage.backlash, 'tolist'): - backlash = self.stage.backlash.tolist() - else: - backlash = self.stage.backlash - - settings_current_stage = { - 'backlash': { - 'x': backlash[0], - 'y': backlash[1], - 'z': backlash[2], - } - } - + settings_current_stage = self.stage.read_config() settings_current['stage_settings'] = settings_current_stage settings_full = self.settings_file.merge(settings_current) diff --git a/openflexure_microscope/stage/base.py b/openflexure_microscope/stage/base.py index 297f0f45..13d23be9 100644 --- a/openflexure_microscope/stage/base.py +++ b/openflexure_microscope/stage/base.py @@ -11,6 +11,16 @@ class BaseStage(metaclass=ABCMeta): def __init__(self): self.lock = StrictLock(timeout=5) + @abstractmethod + def apply_config(self, config: dict): + """Update settings from a config dictionary""" + pass + + @abstractmethod + def read_config(self): + """Return the current settings as a dictionary""" + pass + @property @abstractmethod def state(self): diff --git a/openflexure_microscope/stage/sanga.py b/openflexure_microscope/stage/sanga.py index fbccb9f4..2959b0e9 100644 --- a/openflexure_microscope/stage/sanga.py +++ b/openflexure_microscope/stage/sanga.py @@ -4,6 +4,7 @@ import logging from collections.abc import Iterable from .sangaboard import Sangaboard from openflexure_microscope.stage.base import BaseStage +from openflexure_microscope.utilities import axes_to_array class SangaStage(BaseStage): @@ -22,8 +23,9 @@ class SangaStage(BaseStage): BaseStage.__init__(self) self.board = Sangaboard(port, **kwargs) - self._backlash = None - self.axis_names = ['x', 'y', 'z'] + + self._backlash = None # Initialise backlash storage, used by property setter/getter + self.axis_names = ['x', 'y', 'z'] # Assume all sangaboards are 3 axis @property def state(self): @@ -80,6 +82,28 @@ class SangaStage(BaseStage): else: self._backlash = np.array([int(blsh)]*self.n_axes, dtype=np.int) + def apply_config(self, config: dict): + """Update settings from a config dictionary""" + + # Set backlash. Expects a dictionary with axis labels + if 'backlash' in config: + # Construct backlash array + backlash = axes_to_array(config['backlash'], ['x', 'y', 'z'], [0, 0, 0]) + self.backlash = backlash + + def read_config(self) -> dict: + """Return the current settings as a dictionary""" + blsh = self.backlash.tolist() + config = { + 'backlash': { + 'x': blsh[0], + 'y': blsh[1], + 'z': blsh[2], + } + } + + return config + def move_rel(self, displacement, axis=None, backlash=True): """Make a relative move, optionally correcting for backlash. displacement: integer or array/list of 3 integers