Merge branch 'fix-camera-stage-mapping-matrix' into 'master'

Fix handling of missing CSM matrix

See merge request openflexure/openflexure-microscope-server!127
This commit is contained in:
Richard Bowman 2021-05-05 09:57:28 +00:00
commit 09d2cbfdef

View file

@ -83,6 +83,15 @@ class LoggingMoveWrapper:
self._history: List[Tuple[float, Optional[CoordinateType]]] = [] self._history: List[Tuple[float, Optional[CoordinateType]]] = []
class CSMUncalibratedError(RuntimeError):
"""A calibrated camera stage mapper is required, but this one is not calibrated.
The camera stage mapper requires calibration information to relate image pixels
to stage coordinates. If a method attempts to retrieve this calibration before
it exists, we raise this exception.
"""
class CSMExtension(BaseExtension): class CSMExtension(BaseExtension):
""" """
Use the camera as an encoder, so we can relate camera and stage coordinates Use the camera as an encoder, so we can relate camera and stage coordinates
@ -133,7 +142,12 @@ class CSMExtension(BaseExtension):
def get_settings(self) -> Dict[str, Any]: def get_settings(self) -> Dict[str, Any]:
"""Retrieve the settings for this extension""" """Retrieve the settings for this extension"""
keys: List[str] = ["extensions", self.name] keys: List[str] = ["extensions", self.name]
return get_by_path(self.microscope.read_settings(), keys) try:
return get_by_path(self.microscope.read_settings(), keys)
except KeyError as exc:
raise CSMUncalibratedError(
"Camera stage mapping calibration data is missing"
) from exc
def camera_stage_functions(self) -> Tuple[Callable, Callable, Callable, Callable]: def camera_stage_functions(self) -> Tuple[Callable, Callable, Callable, Callable]:
"""Return functions that allow us to interface with the microscope""" """Return functions that allow us to interface with the microscope"""
@ -194,10 +208,13 @@ class CSMExtension(BaseExtension):
@property @property
def image_to_stage_displacement_matrix(self) -> np.ndarray: # 2x2 integer array def image_to_stage_displacement_matrix(self) -> np.ndarray: # 2x2 integer array
"""A 2x2 matrix that converts displacement in image coordinates to stage coordinates.""" """A 2x2 matrix that converts displacement in image coordinates to stage coordinates."""
displacement_matrix = self.get_settings().get("image_to_stage_displacement") settings = self.get_settings()
if not displacement_matrix: try:
raise ValueError("The microscope has not yet been calibrated.") return np.array(settings["image_to_stage_displacement"])
return np.array(displacement_matrix) except KeyError as exc:
raise CSMUncalibratedError(
"The microscope has not yet been calibrated."
) from exc
def move_in_image_coordinates(self, displacement_in_pixels: XYCoordinateType): def move_in_image_coordinates(self, displacement_in_pixels: XYCoordinateType):
"""Move by a given number of pixels on the camera""" """Move by a given number of pixels on the camera"""