Test stack params at start of scan main loop
This commit is contained in:
parent
4345f8c336
commit
18e49ba50c
2 changed files with 54 additions and 24 deletions
|
|
@ -10,7 +10,7 @@ See repository root for licensing information.
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from typing import Annotated, Mapping, Optional, Sequence, Literal
|
from typing import Annotated, Mapping, Optional, Sequence, Literal, Type
|
||||||
import os
|
import os
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
@ -44,6 +44,7 @@ class StackParams:
|
||||||
autofocus_dz: int,
|
autofocus_dz: int,
|
||||||
images_dir: str,
|
images_dir: str,
|
||||||
save_resolution: tuple[int, int],
|
save_resolution: tuple[int, int],
|
||||||
|
logger: lt.deps.InvocationLogger,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialise the parameters. All arguments are keyword only.
|
"""Initialise the parameters. All arguments are keyword only.
|
||||||
|
|
||||||
|
|
@ -58,7 +59,18 @@ class StackParams:
|
||||||
:param autofocus_dz: The number of steps in a full autofocus (when required)
|
:param autofocus_dz: The number of steps in a full autofocus (when required)
|
||||||
:param images_dir: The directory to save images to disk
|
:param images_dir: The directory to save images to disk
|
||||||
:param save_resolution: The resolution to save the captures to disk with
|
:param save_resolution: The resolution to save the captures to disk with
|
||||||
|
:param logger: A logger passed from the calling Thing
|
||||||
"""
|
"""
|
||||||
|
if min_images_to_test < 3:
|
||||||
|
logger.warning(
|
||||||
|
"Can't test for focus with fewer than 3 images. Running scan with test images = 3"
|
||||||
|
)
|
||||||
|
min_images_to_test = 3
|
||||||
|
elif min_images_to_test > 9:
|
||||||
|
logger.warning(
|
||||||
|
"Testing with more than 9 images is likely to focus on the cover slip, or strike the sample. Running scan with test images = 9"
|
||||||
|
)
|
||||||
|
min_images_to_test = 9
|
||||||
if min_images_to_test < images_to_save:
|
if min_images_to_test < images_to_save:
|
||||||
raise ValueError("Can't save more images than the minimum number tested")
|
raise ValueError("Can't save more images than the minimum number tested")
|
||||||
if min_images_to_test % 2 == 0 or min_images_to_test <= 0:
|
if min_images_to_test % 2 == 0 or min_images_to_test <= 0:
|
||||||
|
|
@ -467,7 +479,7 @@ class AutofocusThing(lt.Thing):
|
||||||
enough more images may be captured. After new images are captured the number sets
|
enough more images may be captured. After new images are captured the number sets
|
||||||
the number of images used for checking if focus is central.
|
the number of images used for checking if focus is central.
|
||||||
|
|
||||||
Defaults to 9 which balances reliability and speed/
|
Defaults to 9 which balances reliability and speed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
stack_dz = lt.ThingSetting(initial_value=50, model=int)
|
stack_dz = lt.ThingSetting(initial_value=50, model=int)
|
||||||
|
|
@ -480,15 +492,40 @@ class AutofocusThing(lt.Thing):
|
||||||
* 200 for 20x
|
* 200 for 20x
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@lt.thing_action
|
||||||
|
def set_stack_params(
|
||||||
|
self,
|
||||||
|
images_dir: str,
|
||||||
|
autofocus_dz: int,
|
||||||
|
save_resolution: tuple[int, int],
|
||||||
|
logger: lt.deps.InvocationLogger,
|
||||||
|
) -> Type[StackParams]:
|
||||||
|
"""Set up the parameters used for all stacks in a scan.
|
||||||
|
|
||||||
|
:param images_dir: the folder to save all images
|
||||||
|
:param autofocus_dz: the range to autofocus over if a stack fails
|
||||||
|
:param save_resolution: The resolution to save the captures to disk with
|
||||||
|
:param logger: A logger passed from the calling Thing
|
||||||
|
|
||||||
|
:returns: A StackParams object with the required parameters.
|
||||||
|
"""
|
||||||
|
return StackParams(
|
||||||
|
stack_dz=self.stack_dz,
|
||||||
|
images_to_save=self.stack_images_to_save,
|
||||||
|
min_images_to_test=self.stack_min_images_to_test,
|
||||||
|
autofocus_dz=autofocus_dz,
|
||||||
|
images_dir=images_dir,
|
||||||
|
save_resolution=save_resolution,
|
||||||
|
logger=logger,
|
||||||
|
)
|
||||||
|
|
||||||
@lt.thing_action
|
@lt.thing_action
|
||||||
def run_smart_stack(
|
def run_smart_stack(
|
||||||
self,
|
self,
|
||||||
cam: CameraClient,
|
cam: CameraClient,
|
||||||
stage: Stage,
|
stage: Stage,
|
||||||
sharpness_monitor: SharpnessMonitorDep,
|
sharpness_monitor: SharpnessMonitorDep,
|
||||||
images_dir: str,
|
stack_parameters: Type[StackParams],
|
||||||
autofocus_dz: int,
|
|
||||||
save_resolution: tuple[int, int],
|
|
||||||
) -> tuple[bool, int]:
|
) -> tuple[bool, int]:
|
||||||
"""Run a smart stack.
|
"""Run a smart stack.
|
||||||
|
|
||||||
|
|
@ -503,27 +540,14 @@ class AutofocusThing(lt.Thing):
|
||||||
:param stage: Stage Dependency supplied by LabThings dependency injection
|
:param stage: Stage Dependency supplied by LabThings dependency injection
|
||||||
:param sharpness_monitor: Sharpness Monitor Dependency (for focus detection)
|
:param sharpness_monitor: Sharpness Monitor Dependency (for focus detection)
|
||||||
supplied by LabThings dependency injection
|
supplied by LabThings dependency injection
|
||||||
:param images_dir: the folder to save all images
|
:param stack_parameters: A StackParams object containing the required
|
||||||
:param autofocus_dz: the range to autofocus over if a stack fails
|
parameters to run a stack.
|
||||||
:param save_resolution: The resolution the images should be saved at, the
|
|
||||||
images will be resampled if this doesn't match the camera's capture
|
|
||||||
resolution
|
|
||||||
|
|
||||||
:returns: A tuple containing:
|
:returns: A tuple containing:
|
||||||
|
|
||||||
* A boolean, True if stack was successfully
|
* A boolean, True if stack was successfully
|
||||||
* The z position of the sharpest image
|
* The z position of the sharpest image
|
||||||
"""
|
"""
|
||||||
# Set the variables to prevent changes from the GUI or other windows
|
|
||||||
stack_parameters = StackParams(
|
|
||||||
stack_dz=self.stack_dz,
|
|
||||||
images_to_save=self.stack_images_to_save,
|
|
||||||
min_images_to_test=self.stack_min_images_to_test,
|
|
||||||
autofocus_dz=autofocus_dz,
|
|
||||||
images_dir=images_dir,
|
|
||||||
save_resolution=save_resolution,
|
|
||||||
)
|
|
||||||
|
|
||||||
tries = 0
|
tries = 0
|
||||||
# Loop until a stack is successful
|
# Loop until a stack is successful
|
||||||
while tries < stack_parameters.max_attempts:
|
while tries < stack_parameters.max_attempts:
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ from openflexure_microscope_server import scan_planners
|
||||||
from openflexure_microscope_server import stitching
|
from openflexure_microscope_server import stitching
|
||||||
|
|
||||||
# Things
|
# Things
|
||||||
from .autofocus import AutofocusThing
|
from .autofocus import AutofocusThing, StackParams
|
||||||
from .camera_stage_mapping import CameraStageMapper
|
from .camera_stage_mapping import CameraStageMapper
|
||||||
from .camera import CameraDependency as CameraClient
|
from .camera import CameraDependency as CameraClient
|
||||||
from .stage import StageDependency as StageDep
|
from .stage import StageDependency as StageDep
|
||||||
|
|
@ -121,6 +121,7 @@ class SmartScanThing(lt.Thing):
|
||||||
self._stage: Optional[StageDep] = None
|
self._stage: Optional[StageDep] = None
|
||||||
self._cam: Optional[CameraClient] = None
|
self._cam: Optional[CameraClient] = None
|
||||||
self._csm: Optional[CSMDep] = None
|
self._csm: Optional[CSMDep] = None
|
||||||
|
self._stack_params: Optional[StackParams] = None
|
||||||
|
|
||||||
self._ongoing_scan: Optional[scan_directories.ScanDirectory] = None
|
self._ongoing_scan: Optional[scan_directories.ScanDirectory] = None
|
||||||
self._scan_data: Optional[scan_directories.ScanData] = None
|
self._scan_data: Optional[scan_directories.ScanData] = None
|
||||||
|
|
@ -189,6 +190,7 @@ class SmartScanThing(lt.Thing):
|
||||||
self._scan_lock.release()
|
self._scan_lock.release()
|
||||||
# Ensure any PreviewStitcher created cannot be reused.
|
# Ensure any PreviewStitcher created cannot be reused.
|
||||||
self._preview_stitcher = None
|
self._preview_stitcher = None
|
||||||
|
self._stack_params = None
|
||||||
|
|
||||||
# Remove any scan folders containing zero images.
|
# Remove any scan folders containing zero images.
|
||||||
self.purge_empty_scans(logger=logger)
|
self.purge_empty_scans(logger=logger)
|
||||||
|
|
@ -363,6 +365,12 @@ class SmartScanThing(lt.Thing):
|
||||||
self._cam.start_streaming(main_resolution=(3280, 2464))
|
self._cam.start_streaming(main_resolution=(3280, 2464))
|
||||||
self._scan_data = self._collect_scan_data()
|
self._scan_data = self._collect_scan_data()
|
||||||
self._ongoing_scan.save_scan_data(self._scan_data)
|
self._ongoing_scan.save_scan_data(self._scan_data)
|
||||||
|
self._stack_params = self._autofocus.set_stack_params(
|
||||||
|
images_dir=self._ongoing_scan.images_dir,
|
||||||
|
autofocus_dz=self.autofocus_dz,
|
||||||
|
save_resolution=self._scan_data.save_resolution,
|
||||||
|
logger=self._scan_logger,
|
||||||
|
)
|
||||||
self._preview_stitcher = stitching.PreviewStitcher(
|
self._preview_stitcher = stitching.PreviewStitcher(
|
||||||
self._ongoing_scan.images_dir,
|
self._ongoing_scan.images_dir,
|
||||||
overlap=self._scan_data.overlap,
|
overlap=self._scan_data.overlap,
|
||||||
|
|
@ -451,9 +459,7 @@ class SmartScanThing(lt.Thing):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
focused, focused_height = self._autofocus.run_smart_stack(
|
focused, focused_height = self._autofocus.run_smart_stack(
|
||||||
images_dir=self._ongoing_scan.images_dir,
|
stack_parameters=self._stack_params
|
||||||
autofocus_dz=self._scan_data.autofocus_dz,
|
|
||||||
save_resolution=self._scan_data.save_resolution,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
current_pos_xyz = (new_pos_xyz[0], new_pos_xyz[1], focused_height)
|
current_pos_xyz = (new_pos_xyz[0], new_pos_xyz[1], focused_height)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue