Loading openflexure_microscope/camera/base.py +0 −4 Original line number Diff line number Diff line Loading @@ -146,10 +146,6 @@ class BaseCamera(metaclass=ABCMeta): """Return the current settings as a dictionary""" return {"paths": self.paths} def save_settings(self): """(Optional) Save any settings to disk that need to be stored""" return def __enter__(self): """Create camera on context enter.""" return self Loading openflexure_microscope/camera/pi.py +26 −55 Original line number Diff line number Diff line Loading @@ -47,7 +47,11 @@ from .base import BaseCamera, CaptureObject from .set_picamera_gain import set_analog_gain, set_digital_gain from openflexure_microscope.paths import settings_file_path from openflexure_microscope.utilities import serialise_array_b64 from openflexure_microscope.utilities import ( serialise_array_b64, ndarray_to_json, json_to_ndarray, ) # MAIN CLASS Loading Loading @@ -154,9 +158,6 @@ class PiCameraStreamer(BaseCamera): "image_resolution": self.image_resolution, "numpy_resolution": self.numpy_resolution, "jpeg_quality": self.jpeg_quality, "picamera_lst_path": self.picamera_lst_path if (self.picamera_lst_path and os.path.isfile(self.picamera_lst_path)) else None, "picamera": {}, } ) Loading @@ -170,12 +171,16 @@ class PiCameraStreamer(BaseCamera): except AttributeError: logging.debug("Unable to read PiCamera attribute {}".format(key)) return conf_dict # Include a serialised lens shading table if ( hasattr(self.camera, "lens_shading_table") and getattr(self.camera, "lens_shading_table") is not None ): conf_dict["picamera"]["lens_shading_table"] = ndarray_to_json( getattr(self.camera, "lens_shading_table") ) def save_settings(self): """Save lens-shading table to disk""" logging.info("Saving picamera_lst to {}".format(self.picamera_lst_path)) self.save_lens_shading_table() return conf_dict def update_settings(self, config: dict): """ Loading Loading @@ -209,22 +214,23 @@ class PiCameraStreamer(BaseCamera): config["picamera"], pause_for_effect=True ) # Handle lens shading if camera supports it if ( hasattr(self.camera, "lens_shading_table") and "lens_shading_table" in config["picamera"] ): try: self.camera.lens_shading_table = json_to_ndarray( config["picamera"].get("lens_shading_table") ) except KeyError as e: logging.error(e) # PiCameraStreamer parameters for key, value in config.items(): # For each provided setting if (key != "picamera") and hasattr(self, key): setattr(self, key, value) # Handle lens shading if camera supports it if ("picamera_lst_path" in config) and hasattr( self.camera, "lens_shading_table" ): logging.debug( "Applying lens_shading_table from file: {}".format( config["picamera_lst_path"] ) ) self.apply_lens_shading_table(config["picamera_lst_path"]) # If stream was paused to update config, unpause if paused_stream: logging.info("Resuming stream.") Loading Loading @@ -293,41 +299,6 @@ class PiCameraStreamer(BaseCamera): if pause_for_effect: time.sleep(0.2) def read_lens_shading_table(self): """ Read the current lens shading table as a numpy array, if it exists. Return None otherwise. """ if hasattr(self.camera, "lens_shading_table"): return self.camera.lens_shading_table else: return None def save_lens_shading_table(self): """ Save the current lens shading table to an .npy file, if it exists. """ logging.debug(self.read_lens_shading_table()) if self.read_lens_shading_table() is not None: np.save(self.picamera_lst_path, self.read_lens_shading_table()) else: logging.warning("Unable to save a nonexistant lens shading table") def apply_lens_shading_table(self, lst_array_or_path): """ Apply a lens shading table from an .npy file, or numpy array. Args: lst_array_or_path: Numpy array, or path to .npy file, describing the lens-shading table """ if isinstance(lst_array_or_path, np.ndarray): self.camera.lens_shading_table = lst_array_or_path elif (type(lst_array_or_path) == str) and os.path.isfile(lst_array_or_path): self.camera.lens_shading_table = np.load(lst_array_or_path) else: logging.error( "Unsupported or missing data for camera lens_shading_table. Must be numpy ndarray, or .npy file path string. Skipping." ) def set_zoom(self, zoom_value: float = 1.0) -> None: """ Change the camera zoom, handling re-centering and scaling. Loading openflexure_microscope/microscope.py +0 −4 Original line number Diff line number Diff line Loading @@ -205,10 +205,6 @@ class Microscope: # Read curent config current_config = self.read_settings() # Save config to file if self.camera: self.camera.save_settings() if self.stage: self.stage.save_settings() self.settings_file.save(current_config, backup=True) @property Loading openflexure_microscope/stage/base.py +0 −4 Original line number Diff line number Diff line Loading @@ -23,10 +23,6 @@ class BaseStage(metaclass=ABCMeta): """Return the current settings as a dictionary""" pass def save_settings(self): """(Optional) Save any settings to disk that need to be stored""" return @property @abstractmethod def state(self): Loading openflexure_microscope/utilities.py +22 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import operator import base64 from uuid import UUID import numpy as np import logging from collections import abc from functools import reduce from contextlib import contextmanager Loading @@ -21,6 +22,27 @@ def serialise_array_b64(npy_arr): return b64_string, dtype, shape def ndarray_to_json(arr: np.ndarray): b64_string, dtype, shape = serialise_array_b64(arr) return { "@type": "ndarray", "dtype": dtype, "shape": shape, "base64": b64_string } def json_to_ndarray(json_dict: dict): if not json_dict.get("@type") != "ndarray": logging.warning("No valid @type attribute found. Conversion may fail.") for required_param in ("dtype", "shape", "base64"): if not json_dict.get(required_param): raise KeyError(f"Missing required key {required_param}") return deserialise_array_b64(json_dict.get("base64"), json_dict.get("dtype"), json_dict.get("shape")) @contextmanager def set_properties(obj, **kwargs): """A context manager to set, then reset, certain properties of an object. Loading Loading
openflexure_microscope/camera/base.py +0 −4 Original line number Diff line number Diff line Loading @@ -146,10 +146,6 @@ class BaseCamera(metaclass=ABCMeta): """Return the current settings as a dictionary""" return {"paths": self.paths} def save_settings(self): """(Optional) Save any settings to disk that need to be stored""" return def __enter__(self): """Create camera on context enter.""" return self Loading
openflexure_microscope/camera/pi.py +26 −55 Original line number Diff line number Diff line Loading @@ -47,7 +47,11 @@ from .base import BaseCamera, CaptureObject from .set_picamera_gain import set_analog_gain, set_digital_gain from openflexure_microscope.paths import settings_file_path from openflexure_microscope.utilities import serialise_array_b64 from openflexure_microscope.utilities import ( serialise_array_b64, ndarray_to_json, json_to_ndarray, ) # MAIN CLASS Loading Loading @@ -154,9 +158,6 @@ class PiCameraStreamer(BaseCamera): "image_resolution": self.image_resolution, "numpy_resolution": self.numpy_resolution, "jpeg_quality": self.jpeg_quality, "picamera_lst_path": self.picamera_lst_path if (self.picamera_lst_path and os.path.isfile(self.picamera_lst_path)) else None, "picamera": {}, } ) Loading @@ -170,12 +171,16 @@ class PiCameraStreamer(BaseCamera): except AttributeError: logging.debug("Unable to read PiCamera attribute {}".format(key)) return conf_dict # Include a serialised lens shading table if ( hasattr(self.camera, "lens_shading_table") and getattr(self.camera, "lens_shading_table") is not None ): conf_dict["picamera"]["lens_shading_table"] = ndarray_to_json( getattr(self.camera, "lens_shading_table") ) def save_settings(self): """Save lens-shading table to disk""" logging.info("Saving picamera_lst to {}".format(self.picamera_lst_path)) self.save_lens_shading_table() return conf_dict def update_settings(self, config: dict): """ Loading Loading @@ -209,22 +214,23 @@ class PiCameraStreamer(BaseCamera): config["picamera"], pause_for_effect=True ) # Handle lens shading if camera supports it if ( hasattr(self.camera, "lens_shading_table") and "lens_shading_table" in config["picamera"] ): try: self.camera.lens_shading_table = json_to_ndarray( config["picamera"].get("lens_shading_table") ) except KeyError as e: logging.error(e) # PiCameraStreamer parameters for key, value in config.items(): # For each provided setting if (key != "picamera") and hasattr(self, key): setattr(self, key, value) # Handle lens shading if camera supports it if ("picamera_lst_path" in config) and hasattr( self.camera, "lens_shading_table" ): logging.debug( "Applying lens_shading_table from file: {}".format( config["picamera_lst_path"] ) ) self.apply_lens_shading_table(config["picamera_lst_path"]) # If stream was paused to update config, unpause if paused_stream: logging.info("Resuming stream.") Loading Loading @@ -293,41 +299,6 @@ class PiCameraStreamer(BaseCamera): if pause_for_effect: time.sleep(0.2) def read_lens_shading_table(self): """ Read the current lens shading table as a numpy array, if it exists. Return None otherwise. """ if hasattr(self.camera, "lens_shading_table"): return self.camera.lens_shading_table else: return None def save_lens_shading_table(self): """ Save the current lens shading table to an .npy file, if it exists. """ logging.debug(self.read_lens_shading_table()) if self.read_lens_shading_table() is not None: np.save(self.picamera_lst_path, self.read_lens_shading_table()) else: logging.warning("Unable to save a nonexistant lens shading table") def apply_lens_shading_table(self, lst_array_or_path): """ Apply a lens shading table from an .npy file, or numpy array. Args: lst_array_or_path: Numpy array, or path to .npy file, describing the lens-shading table """ if isinstance(lst_array_or_path, np.ndarray): self.camera.lens_shading_table = lst_array_or_path elif (type(lst_array_or_path) == str) and os.path.isfile(lst_array_or_path): self.camera.lens_shading_table = np.load(lst_array_or_path) else: logging.error( "Unsupported or missing data for camera lens_shading_table. Must be numpy ndarray, or .npy file path string. Skipping." ) def set_zoom(self, zoom_value: float = 1.0) -> None: """ Change the camera zoom, handling re-centering and scaling. Loading
openflexure_microscope/microscope.py +0 −4 Original line number Diff line number Diff line Loading @@ -205,10 +205,6 @@ class Microscope: # Read curent config current_config = self.read_settings() # Save config to file if self.camera: self.camera.save_settings() if self.stage: self.stage.save_settings() self.settings_file.save(current_config, backup=True) @property Loading
openflexure_microscope/stage/base.py +0 −4 Original line number Diff line number Diff line Loading @@ -23,10 +23,6 @@ class BaseStage(metaclass=ABCMeta): """Return the current settings as a dictionary""" pass def save_settings(self): """(Optional) Save any settings to disk that need to be stored""" return @property @abstractmethod def state(self): Loading
openflexure_microscope/utilities.py +22 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import operator import base64 from uuid import UUID import numpy as np import logging from collections import abc from functools import reduce from contextlib import contextmanager Loading @@ -21,6 +22,27 @@ def serialise_array_b64(npy_arr): return b64_string, dtype, shape def ndarray_to_json(arr: np.ndarray): b64_string, dtype, shape = serialise_array_b64(arr) return { "@type": "ndarray", "dtype": dtype, "shape": shape, "base64": b64_string } def json_to_ndarray(json_dict: dict): if not json_dict.get("@type") != "ndarray": logging.warning("No valid @type attribute found. Conversion may fail.") for required_param in ("dtype", "shape", "base64"): if not json_dict.get(required_param): raise KeyError(f"Missing required key {required_param}") return deserialise_array_b64(json_dict.get("base64"), json_dict.get("dtype"), json_dict.get("shape")) @contextmanager def set_properties(obj, **kwargs): """A context manager to set, then reset, certain properties of an object. Loading