Fixing a number of issues from the merge and refactor.
This commit is contained in:
parent
61dd5e4958
commit
6a87805b47
3 changed files with 13 additions and 38 deletions
|
|
@ -20,9 +20,7 @@ from pydantic import BaseModel, computed_field
|
||||||
from labthings_fastapi.thing import Thing
|
from labthings_fastapi.thing import Thing
|
||||||
from labthings_fastapi.dependencies.blocking_portal import BlockingPortal
|
from labthings_fastapi.dependencies.blocking_portal import BlockingPortal
|
||||||
from labthings_fastapi.decorators import thing_action, thing_property
|
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.types.numpy import NDArray
|
||||||
from labthings_fastapi.dependencies.invocation import InvocationLogger
|
|
||||||
|
|
||||||
from .camera import RawCameraDependency as Camera
|
from .camera import RawCameraDependency as Camera
|
||||||
from .camera import CameraDependency as WrappedCamera
|
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.
|
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):
|
def slice_to_save(self, sharpest_index):
|
||||||
"""Return the slice of images to save given the index of the sharpest image"""
|
"""Return the slice of images to save given the index of the sharpest image"""
|
||||||
|
|
@ -131,7 +129,7 @@ class CaptureInfo:
|
||||||
@property
|
@property
|
||||||
def filename(self) -> str:
|
def filename(self) -> str:
|
||||||
"""The filename for this image generated from the poistion"""
|
"""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:
|
def _get_capture_by_id(captures: list[CaptureInfo], buffer_id: int) -> CaptureInfo:
|
||||||
|
|
@ -408,8 +406,6 @@ class AutofocusThing(Thing):
|
||||||
self,
|
self,
|
||||||
cam: WrappedCamera,
|
cam: WrappedCamera,
|
||||||
stage: Stage,
|
stage: Stage,
|
||||||
logger: InvocationLogger,
|
|
||||||
metadata_getter: GetThingStates,
|
|
||||||
sharpness_monitor: SharpnessMonitorDep,
|
sharpness_monitor: SharpnessMonitorDep,
|
||||||
images_dir: str,
|
images_dir: str,
|
||||||
autofocus_dz: int,
|
autofocus_dz: int,
|
||||||
|
|
@ -450,15 +446,13 @@ class AutofocusThing(Thing):
|
||||||
stack_parameters=stack_parameters,
|
stack_parameters=stack_parameters,
|
||||||
stage=stage,
|
stage=stage,
|
||||||
cam=cam,
|
cam=cam,
|
||||||
logger=logger,
|
|
||||||
metadata_getter=metadata_getter,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
break
|
break
|
||||||
|
|
||||||
# The z position of the first images in the previous attempt.
|
# 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
|
# If a stack is not successful, move to the start and autofocus
|
||||||
self.reset_stack(
|
self.reset_stack(
|
||||||
initial_z_pos,
|
initial_z_pos,
|
||||||
|
|
@ -473,11 +467,10 @@ class AutofocusThing(Thing):
|
||||||
captures=captures,
|
captures=captures,
|
||||||
stack_parameters=stack_parameters,
|
stack_parameters=stack_parameters,
|
||||||
cam=cam,
|
cam=cam,
|
||||||
logger=logger,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Return the z position of the sharpest image, for path planning and tracking
|
# 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(
|
def reset_stack(
|
||||||
self,
|
self,
|
||||||
|
|
@ -508,7 +501,6 @@ class AutofocusThing(Thing):
|
||||||
captures: list[list],
|
captures: list[list],
|
||||||
stack_parameters: StackParams,
|
stack_parameters: StackParams,
|
||||||
cam: WrappedCamera,
|
cam: WrappedCamera,
|
||||||
logger: InvocationLogger,
|
|
||||||
) -> int:
|
) -> int:
|
||||||
"""Save the required captures to disk. Will save the sharpest image,
|
"""Save the required captures to disk. Will save the sharpest image,
|
||||||
and any images either side of focus.
|
and any images either side of focus.
|
||||||
|
|
@ -521,14 +513,13 @@ class AutofocusThing(Thing):
|
||||||
calling action
|
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)
|
slice_to_save = stack_parameters.slice_to_save(sharpest_index)
|
||||||
|
|
||||||
# Loop through the range, saving each capture to disk
|
# Loop through the range, saving each capture to disk
|
||||||
for capture in captures[slice_to_save]:
|
for capture in captures[slice_to_save]:
|
||||||
cam.save_from_memory(
|
cam.save_from_memory(
|
||||||
jpeg_path=os.path.join(stack_parameters.images_dir, capture.filename),
|
jpeg_path=os.path.join(stack_parameters.images_dir, capture.filename),
|
||||||
logger=logger,
|
|
||||||
save_resolution=stack_parameters.capture_resolution,
|
save_resolution=stack_parameters.capture_resolution,
|
||||||
buffer_id=capture.buffer_id,
|
buffer_id=capture.buffer_id,
|
||||||
)
|
)
|
||||||
|
|
@ -540,8 +531,6 @@ class AutofocusThing(Thing):
|
||||||
stack_parameters: StackParams,
|
stack_parameters: StackParams,
|
||||||
stage: Stage,
|
stage: Stage,
|
||||||
cam: WrappedCamera,
|
cam: WrappedCamera,
|
||||||
logger: InvocationLogger,
|
|
||||||
metadata_getter: GetThingStates,
|
|
||||||
) -> tuple[bool, list[CaptureInfo], Optional[int]]:
|
) -> tuple[bool, list[CaptureInfo], Optional[int]]:
|
||||||
"""Capture a series of images offset by stack_parameters.stack_dz, and test whether
|
"""Capture a series of images offset by stack_parameters.stack_dz, and test whether
|
||||||
the sharpest image is towards the centre of the stack.
|
the sharpest image is towards the centre of the stack.
|
||||||
|
|
@ -582,8 +571,6 @@ class AutofocusThing(Thing):
|
||||||
self.capture_stack_image(
|
self.capture_stack_image(
|
||||||
cam,
|
cam,
|
||||||
stage,
|
stage,
|
||||||
logger,
|
|
||||||
metadata_getter,
|
|
||||||
buffer_max=stack_parameters.min_images_to_test,
|
buffer_max=stack_parameters.min_images_to_test,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -605,8 +592,6 @@ class AutofocusThing(Thing):
|
||||||
self,
|
self,
|
||||||
cam: WrappedCamera,
|
cam: WrappedCamera,
|
||||||
stage: Stage,
|
stage: Stage,
|
||||||
logger: InvocationLogger,
|
|
||||||
metadata_getter: GetThingStates,
|
|
||||||
buffer_max: int,
|
buffer_max: int,
|
||||||
) -> list:
|
) -> list:
|
||||||
"""Capture another image and return the capture information.
|
"""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.
|
The capture is stored by the camera Thing, and can be saved by ID.
|
||||||
"""
|
"""
|
||||||
stage_location = stage.position
|
stage_location = stage.position
|
||||||
buffer_id = cam.capture_to_memory(
|
buffer_id = cam.capture_to_memory(buffer_max=buffer_max)
|
||||||
logger, metadata_getter, buffer_max=buffer_max
|
|
||||||
)
|
|
||||||
return CaptureInfo(
|
return CaptureInfo(
|
||||||
buffer_id=buffer_id,
|
buffer_id=buffer_id,
|
||||||
position=stage_location,
|
position=stage_location,
|
||||||
|
|
|
||||||
|
|
@ -221,8 +221,8 @@ class BaseCamera(Thing):
|
||||||
"""Capture an image and save it to disk
|
"""Capture an image and save it to disk
|
||||||
|
|
||||||
|
|
||||||
save_resolution can be set to resize the image before saving. By default this is None
|
save_resolution can be set to resize the image before saving. By default this
|
||||||
meaning that the image is saved at original resoltion.
|
is None meaning that the image is saved at original resoltion.
|
||||||
"""
|
"""
|
||||||
image, metadata = self._robust_image_capture(
|
image, metadata = self._robust_image_capture(
|
||||||
metadata_getter,
|
metadata_getter,
|
||||||
|
|
@ -239,7 +239,7 @@ class BaseCamera(Thing):
|
||||||
|
|
||||||
@thing_action
|
@thing_action
|
||||||
def capture_to_memory(
|
def capture_to_memory(
|
||||||
self, logger: InvocationLogger, metadata_getter: GetThingStates, buffer_max
|
self, logger: InvocationLogger, metadata_getter: GetThingStates, buffer_max: int
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Capture an image to memory. This can be saved later with `save_from_memory`
|
Capture an image to memory. This can be saved later with `save_from_memory`
|
||||||
|
|
@ -272,6 +272,9 @@ class BaseCamera(Thing):
|
||||||
logger=logger,
|
logger=logger,
|
||||||
save_resolution=save_resolution,
|
save_resolution=save_resolution,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@thing_action
|
||||||
|
def clear_buffers(self) -> None:
|
||||||
self._memory_buffer.clear()
|
self._memory_buffer.clear()
|
||||||
|
|
||||||
def _robust_image_capture(
|
def _robust_image_capture(
|
||||||
|
|
|
||||||
|
|
@ -656,6 +656,7 @@ class SmartScanThing(Thing):
|
||||||
focused_height = self._autofocus.run_smart_stack(
|
focused_height = self._autofocus.run_smart_stack(
|
||||||
images_dir=self._ongoing_scan_images_dir,
|
images_dir=self._ongoing_scan_images_dir,
|
||||||
autofocus_dz=self._scan_data["autofocus_dz"],
|
autofocus_dz=self._scan_data["autofocus_dz"],
|
||||||
|
capture_resolution=self._scan_data["capture_resolution"],
|
||||||
)
|
)
|
||||||
|
|
||||||
current_pos_xyz = (
|
current_pos_xyz = (
|
||||||
|
|
@ -668,18 +669,6 @@ class SmartScanThing(Thing):
|
||||||
current_pos_xyz, imaged=True, focused=True
|
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
|
# increment capure counter as thread has completed
|
||||||
self._scan_images_taken += 1
|
self._scan_images_taken += 1
|
||||||
# Add it to the incremental zip
|
# Add it to the incremental zip
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue