Fixing a number of issues from the merge and refactor.

This commit is contained in:
Julian Stirling 2025-06-26 18:29:12 +01:00
parent 61dd5e4958
commit 6a87805b47
3 changed files with 13 additions and 38 deletions

View file

@ -20,9 +20,7 @@ from pydantic import BaseModel, computed_field
from labthings_fastapi.thing import Thing
from labthings_fastapi.dependencies.blocking_portal import BlockingPortal
from labthings_fastapi.decorators import thing_action, thing_property
from labthings_fastapi.dependencies.metadata import GetThingStates
from labthings_fastapi.types.numpy import NDArray
from labthings_fastapi.dependencies.invocation import InvocationLogger
from .camera import RawCameraDependency as Camera
from .camera import CameraDependency as WrappedCamera
@ -108,7 +106,7 @@ class StackParams(BaseModel):
This is 15 images more then the minimum number that are captured.
"""
return self.min_images_to_test
return self.min_images_to_test + 15
def slice_to_save(self, sharpest_index):
"""Return the slice of images to save given the index of the sharpest image"""
@ -131,7 +129,7 @@ class CaptureInfo:
@property
def filename(self) -> str:
"""The filename for this image generated from the poistion"""
return f"{self.position[0]}_{self.position[1]}_{self.position[2]}.jpeg"
return f"{self.position['x']}_{self.position['y']}_{self.position['z']}.jpeg"
def _get_capture_by_id(captures: list[CaptureInfo], buffer_id: int) -> CaptureInfo:
@ -408,8 +406,6 @@ class AutofocusThing(Thing):
self,
cam: WrappedCamera,
stage: Stage,
logger: InvocationLogger,
metadata_getter: GetThingStates,
sharpness_monitor: SharpnessMonitorDep,
images_dir: str,
autofocus_dz: int,
@ -450,15 +446,13 @@ class AutofocusThing(Thing):
stack_parameters=stack_parameters,
stage=stage,
cam=cam,
logger=logger,
metadata_getter=metadata_getter,
)
if success:
break
# The z position of the first images in the previous attempt.
initial_z_pos = captures[0].position[2]
initial_z_pos = captures[0].position["z"]
# If a stack is not successful, move to the start and autofocus
self.reset_stack(
initial_z_pos,
@ -473,11 +467,10 @@ class AutofocusThing(Thing):
captures=captures,
stack_parameters=stack_parameters,
cam=cam,
logger=logger,
)
# Return the z position of the sharpest image, for path planning and tracking
return _get_capture_by_id(captures, sharpest_id).position[2]
return _get_capture_by_id(captures, sharpest_id).position["z"]
def reset_stack(
self,
@ -508,7 +501,6 @@ class AutofocusThing(Thing):
captures: list[list],
stack_parameters: StackParams,
cam: WrappedCamera,
logger: InvocationLogger,
) -> int:
"""Save the required captures to disk. Will save the sharpest image,
and any images either side of focus.
@ -521,14 +513,13 @@ class AutofocusThing(Thing):
calling action
"""
sharpest_index = _get_capture_index_by_id(sharpest_id)
sharpest_index = _get_capture_index_by_id(captures, sharpest_id)
slice_to_save = stack_parameters.slice_to_save(sharpest_index)
# Loop through the range, saving each capture to disk
for capture in captures[slice_to_save]:
cam.save_from_memory(
jpeg_path=os.path.join(stack_parameters.images_dir, capture.filename),
logger=logger,
save_resolution=stack_parameters.capture_resolution,
buffer_id=capture.buffer_id,
)
@ -540,8 +531,6 @@ class AutofocusThing(Thing):
stack_parameters: StackParams,
stage: Stage,
cam: WrappedCamera,
logger: InvocationLogger,
metadata_getter: GetThingStates,
) -> tuple[bool, list[CaptureInfo], Optional[int]]:
"""Capture a series of images offset by stack_parameters.stack_dz, and test whether
the sharpest image is towards the centre of the stack.
@ -582,8 +571,6 @@ class AutofocusThing(Thing):
self.capture_stack_image(
cam,
stage,
logger,
metadata_getter,
buffer_max=stack_parameters.min_images_to_test,
)
)
@ -605,8 +592,6 @@ class AutofocusThing(Thing):
self,
cam: WrappedCamera,
stage: Stage,
logger: InvocationLogger,
metadata_getter: GetThingStates,
buffer_max: int,
) -> list:
"""Capture another image and return the capture information.
@ -614,9 +599,7 @@ class AutofocusThing(Thing):
The capture is stored by the camera Thing, and can be saved by ID.
"""
stage_location = stage.position
buffer_id = cam.capture_to_memory(
logger, metadata_getter, buffer_max=buffer_max
)
buffer_id = cam.capture_to_memory(buffer_max=buffer_max)
return CaptureInfo(
buffer_id=buffer_id,
position=stage_location,

View file

@ -221,8 +221,8 @@ class BaseCamera(Thing):
"""Capture an image and save it to disk
save_resolution can be set to resize the image before saving. By default this is None
meaning that the image is saved at original resoltion.
save_resolution can be set to resize the image before saving. By default this
is None meaning that the image is saved at original resoltion.
"""
image, metadata = self._robust_image_capture(
metadata_getter,
@ -239,7 +239,7 @@ class BaseCamera(Thing):
@thing_action
def capture_to_memory(
self, logger: InvocationLogger, metadata_getter: GetThingStates, buffer_max
self, logger: InvocationLogger, metadata_getter: GetThingStates, buffer_max: int
) -> None:
"""
Capture an image to memory. This can be saved later with `save_from_memory`
@ -272,6 +272,9 @@ class BaseCamera(Thing):
logger=logger,
save_resolution=save_resolution,
)
@thing_action
def clear_buffers(self) -> None:
self._memory_buffer.clear()
def _robust_image_capture(

View file

@ -656,6 +656,7 @@ class SmartScanThing(Thing):
focused_height = self._autofocus.run_smart_stack(
images_dir=self._ongoing_scan_images_dir,
autofocus_dz=self._scan_data["autofocus_dz"],
capture_resolution=self._scan_data["capture_resolution"],
)
current_pos_xyz = (
@ -668,18 +669,6 @@ class SmartScanThing(Thing):
current_pos_xyz, imaged=True, focused=True
)
site_folder = os.path.join(
self._ongoing_scan_images_dir,
"stacks",
f"{new_pos_xyz[0]}_{new_pos_xyz[1]}",
)
os.makedirs(site_folder, exist_ok=True)
self._autofocus.run_z_stack(
images_dir=self._ongoing_scan_images_dir,
stack_dir=site_folder,
capture_resolution=self._scan_data["capture_resolution"],
)
# increment capure counter as thread has completed
self._scan_images_taken += 1
# Add it to the incremental zip