Ensure smart stack exits and saves on failure only if check background is false
This commit is contained in:
parent
d3bd921db2
commit
dabb195b08
2 changed files with 40 additions and 34 deletions
|
|
@ -421,37 +421,35 @@ class AutofocusThing(lt.Thing):
|
||||||
is close to focus, but not quite within ``dz/2``. It will attempt to autofocus
|
is close to focus, but not quite within ``dz/2``. It will attempt to autofocus
|
||||||
up to 10 times.
|
up to 10 times.
|
||||||
"""
|
"""
|
||||||
repeat = True
|
|
||||||
attempts = 0
|
attempts = 0
|
||||||
backlash = 200
|
backlash = 200
|
||||||
|
|
||||||
with sharpness_monitor.run():
|
with sharpness_monitor.run():
|
||||||
while repeat and attempts < 10:
|
while attempts < 10:
|
||||||
if start == "centre":
|
if start == "centre":
|
||||||
stage.move_relative(x=0, y=0, z=-(backlash + dz / 2))
|
stage.move_relative(x=0, y=0, z=-(backlash + dz / 2))
|
||||||
stage.move_relative(x=0, y=0, z=backlash)
|
stage.move_relative(x=0, y=0, z=backlash)
|
||||||
|
|
||||||
|
# Always start centrally for future runs
|
||||||
|
start = "centre"
|
||||||
|
|
||||||
focus_data_index, _ = sharpness_monitor.focus_rel(
|
focus_data_index, _ = sharpness_monitor.focus_rel(
|
||||||
dz, block_cancellation=True
|
dz, block_cancellation=True
|
||||||
)
|
)
|
||||||
_times, heights, sizes = sharpness_monitor.move_data(focus_data_index)
|
_times, heights, sizes = sharpness_monitor.move_data(focus_data_index)
|
||||||
|
|
||||||
peak_height = heights[np.argmax(sizes)]
|
peak_height = heights[np.argmax(sizes)]
|
||||||
height_min = np.min(heights)
|
target_min = np.min(heights) + dz / 5
|
||||||
height_max = np.max(heights)
|
target_max = np.max(heights) - dz / 5
|
||||||
|
|
||||||
|
# move to the peak
|
||||||
|
stage.move_absolute(z=peak_height - backlash)
|
||||||
|
stage.move_absolute(z=peak_height)
|
||||||
|
|
||||||
|
if target_min < peak_height < target_max:
|
||||||
|
# If it is within the target range then break.
|
||||||
|
break
|
||||||
|
|
||||||
if (
|
|
||||||
peak_height - height_min < dz / 5
|
|
||||||
or height_max - peak_height < dz / 5
|
|
||||||
):
|
|
||||||
attempts += 1
|
|
||||||
start = "centre"
|
|
||||||
stage.move_absolute(z=peak_height - backlash)
|
|
||||||
stage.move_absolute(z=peak_height)
|
|
||||||
else:
|
|
||||||
repeat = False
|
|
||||||
stage.move_relative(x=0, y=0, z=-(dz + backlash))
|
|
||||||
stage.move_absolute(z=peak_height)
|
|
||||||
return heights.tolist(), sizes.tolist()
|
return heights.tolist(), sizes.tolist()
|
||||||
|
|
||||||
stack_images_to_save = lt.ThingSetting(
|
stack_images_to_save = lt.ThingSetting(
|
||||||
|
|
@ -566,7 +564,8 @@ class AutofocusThing(lt.Thing):
|
||||||
stage: Stage,
|
stage: Stage,
|
||||||
sharpness_monitor: SharpnessMonitorDep,
|
sharpness_monitor: SharpnessMonitorDep,
|
||||||
stack_parameters: StackParams,
|
stack_parameters: StackParams,
|
||||||
) -> tuple[bool, int]:
|
save_on_failure: bool = False,
|
||||||
|
) -> tuple[bool, Optional[int]]:
|
||||||
"""Run a smart stack.
|
"""Run a smart stack.
|
||||||
|
|
||||||
A smart stack captures images offset in z, testing whether the sharpest image
|
A smart stack captures images offset in z, testing whether the sharpest image
|
||||||
|
|
@ -582,15 +581,16 @@ class AutofocusThing(lt.Thing):
|
||||||
supplied by LabThings dependency injection
|
supplied by LabThings dependency injection
|
||||||
:param stack_parameters: A StackParams object containing the required
|
:param stack_parameters: A StackParams object containing the required
|
||||||
parameters to run a stack.
|
parameters to run a stack.
|
||||||
|
:param save_on_failure: Whether to save an image even if the capture failed
|
||||||
|
|
||||||
: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
|
||||||
"""
|
"""
|
||||||
tries = 0
|
attempt = 0
|
||||||
# Loop until a stack is successful
|
while True:
|
||||||
while tries < stack_parameters.max_attempts:
|
attempt += 1
|
||||||
success, captures, sharpest_id = self.z_stack(
|
success, captures, sharpest_id = self.z_stack(
|
||||||
stack_parameters=stack_parameters,
|
stack_parameters=stack_parameters,
|
||||||
cam=cam,
|
cam=cam,
|
||||||
|
|
@ -600,6 +600,9 @@ class AutofocusThing(lt.Thing):
|
||||||
if success:
|
if success:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if attempt >= stack_parameters.max_attempts:
|
||||||
|
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["z"]
|
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
|
||||||
|
|
@ -613,15 +616,14 @@ class AutofocusThing(lt.Thing):
|
||||||
# Save stack_parameters.image_to_save images centred on the sharpest capture.
|
# Save stack_parameters.image_to_save images centred on the sharpest capture.
|
||||||
# If the smart_stack failed the exact number of images saved may not be
|
# If the smart_stack failed the exact number of images saved may not be
|
||||||
# stack_parameters.image_to_save
|
# stack_parameters.image_to_save
|
||||||
self.save_stack(
|
if success or save_on_failure:
|
||||||
sharpest_id=sharpest_id,
|
self.save_stack(
|
||||||
captures=captures,
|
sharpest_id=sharpest_id,
|
||||||
stack_parameters=stack_parameters,
|
captures=captures,
|
||||||
cam=cam,
|
stack_parameters=stack_parameters,
|
||||||
)
|
cam=cam,
|
||||||
|
)
|
||||||
|
|
||||||
# Return whether or not the smart stack was successful, and the z position of
|
|
||||||
# the sharpest image, for path planning and tracking
|
|
||||||
return success, _get_capture_by_id(captures, sharpest_id).position["z"]
|
return success, _get_capture_by_id(captures, sharpest_id).position["z"]
|
||||||
|
|
||||||
def reset_stack(
|
def reset_stack(
|
||||||
|
|
@ -683,7 +685,7 @@ class AutofocusThing(lt.Thing):
|
||||||
stack_parameters: StackParams,
|
stack_parameters: StackParams,
|
||||||
cam: CameraClient,
|
cam: CameraClient,
|
||||||
stage: Stage,
|
stage: Stage,
|
||||||
) -> tuple[bool, list[CaptureInfo], Optional[int]]:
|
) -> tuple[bool, list[CaptureInfo], int]:
|
||||||
"""Capture a series of images checking that sharpest image central.
|
"""Capture a series of images checking that sharpest image central.
|
||||||
|
|
||||||
The images are separated in z offset by stack_parameters.stack_dz, as they
|
The images are separated in z offset by stack_parameters.stack_dz, as they
|
||||||
|
|
@ -699,7 +701,7 @@ class AutofocusThing(lt.Thing):
|
||||||
|
|
||||||
* the stack result (True for successful stack, False for failed stack),
|
* the stack result (True for successful stack, False for failed stack),
|
||||||
* a list of CaptureInfo objects,
|
* a list of CaptureInfo objects,
|
||||||
* the buffer_id of the sharpest image (or None if the stack failed).
|
* the buffer_id of the sharpest image
|
||||||
"""
|
"""
|
||||||
# Move down by the height of the z stack, plus an overshoot
|
# Move down by the height of the z stack, plus an overshoot
|
||||||
# Better to start too low and take too many images than too high and need to refocus
|
# Better to start too low and take too many images than too high and need to refocus
|
||||||
|
|
@ -739,10 +741,10 @@ class AutofocusThing(lt.Thing):
|
||||||
return True, captures, capture_id
|
return True, captures, capture_id
|
||||||
|
|
||||||
if result == "restart":
|
if result == "restart":
|
||||||
return False, captures, None
|
return False, captures, capture_id
|
||||||
# If reached here the result was "continue"
|
# If reached here the result was "continue"
|
||||||
stage.move_relative(z=stack_parameters.stack_dz)
|
stage.move_relative(z=stack_parameters.stack_dz)
|
||||||
return False, captures, None
|
return False, captures, capture_id
|
||||||
|
|
||||||
def capture_stack_image(
|
def capture_stack_image(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
|
|
@ -467,13 +467,17 @@ class SmartScanThing(lt.Thing):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
focused, focused_height = self._autofocus.run_smart_stack(
|
focused, focused_height = self._autofocus.run_smart_stack(
|
||||||
stack_parameters=self._stack_params
|
stack_parameters=self._stack_params,
|
||||||
|
save_on_failure=not self._scan_data.skip_background,
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
|
# An image was captured if we are focussed or we are not skipping background.
|
||||||
|
imaged = focused or not self._scan_data.skip_background
|
||||||
|
|
||||||
route_planner.mark_location_visited(
|
route_planner.mark_location_visited(
|
||||||
current_pos_xyz, imaged=True, focused=focused
|
current_pos_xyz, imaged=imaged, focused=focused
|
||||||
)
|
)
|
||||||
|
|
||||||
# increment capture counter as thread has completed
|
# increment capture counter as thread has completed
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue