diff --git a/src/openflexure_microscope_server/things/camera/__init__.py b/src/openflexure_microscope_server/things/camera/__init__.py index bca3c63f..fc11ca1f 100644 --- a/src/openflexure_microscope_server/things/camera/__init__.py +++ b/src/openflexure_microscope_server/things/camera/__init__.py @@ -198,6 +198,15 @@ class BaseCamera(lt.Thing): """Close hardware connection when the Thing context manager is closed.""" raise NotImplementedError("CameraThings must define their own __exit__ method") + @lt.thing_property + def calibration_required(self) -> bool: + """Whether the camera needs calibrating. + + This always returns False in BaseCamera. It should be reimplemented by child + classes if calibration is required. + """ + return False + @lt.thing_action def start_streaming( self, main_resolution: tuple[int, int], buffer_count: int diff --git a/src/openflexure_microscope_server/things/camera/picamera.py b/src/openflexure_microscope_server/things/camera/picamera.py index 2afc1d7b..68f5c281 100644 --- a/src/openflexure_microscope_server/things/camera/picamera.py +++ b/src/openflexure_microscope_server/things/camera/picamera.py @@ -213,6 +213,11 @@ class StreamingPiCamera2(BaseCamera): finally: self._setting_save_in_progress = False + @lt.thing_property + def calibration_required(self) -> bool: + """Whether the camera needs calibrating.""" + return not self.lens_shading_is_static + ## Persistent controls! These are settings _analogue_gain: float = 1.0 diff --git a/src/openflexure_microscope_server/things/camera_stage_mapping.py b/src/openflexure_microscope_server/things/camera_stage_mapping.py index a05a3385..57c9a596 100644 --- a/src/openflexure_microscope_server/things/camera_stage_mapping.py +++ b/src/openflexure_microscope_server/things/camera_stage_mapping.py @@ -242,6 +242,11 @@ class CameraStageMapper(lt.Thing): return None return self.last_calibration["image_resolution"] + @lt.thing_property + def calibration_required(self) -> bool: + """Whether the camera stage mapper needs calibrating.""" + return self.image_to_stage_displacement_matrix is None + def assert_calibrated(self) -> None: """Raise an exception if the image_to_stage_displacement matrix is not set.""" if self.image_to_stage_displacement_matrix is None: