From c0a8d1562899a835472222805afd370aee4e3893 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Wed, 22 Oct 2025 14:12:42 +0100 Subject: [PATCH] Add calibration_required property to Camera and CSM things. --- .../things/camera/__init__.py | 9 +++++++++ .../things/camera/picamera.py | 5 +++++ .../things/camera_stage_mapping.py | 5 +++++ 3 files changed, 19 insertions(+) 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: