Test the success of refocusing

This commit is contained in:
Joe Knapper 2024-02-13 15:24:42 +00:00
parent f2d85cb891
commit f1c315783c
2 changed files with 50 additions and 17 deletions

View file

@ -26,6 +26,7 @@ from pydantic import BaseModel
Stage = direct_thing_client_dependency(SangaboardThing, "/stage/")
Camera = raw_thing_dependency(StreamingPiCamera2)
WrappedCamera = direct_thing_client_dependency(StreamingPiCamera2, "/camera/")
### Autofocus utilities
@ -206,12 +207,14 @@ class AutofocusThing(Thing):
"""
repeat = True
attempts = 0
backlash = 200
with m.run():
while repeat and attempts < 10:
if start == 'centre':
stage.move_relative(x = 0, y = 0, z = -dz / 2)
stage.move_relative(x = 0, y = 0, z = -(backlash + dz / 2))
stage.move_relative(x = 0, y = 0, z = backlash)
i, z = m.focus_rel(dz, block_cancellation=True)
_, heights, sizes = m.move_data(i)
@ -226,8 +229,24 @@ class AutofocusThing(Thing):
):
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)
stage.move_absolute(z = peak_height)
stage.move_relative(x = 0, y = 0, z = -(dz+backlash))
stage.move_absolute(z = peak_height)
return heights.tolist(), sizes.tolist()
@thing_action
def verify_focus_sharpness(self, sweep_sizes: list, camera: WrappedCamera, leniency: int = 1):
'''Take the sharpness curve of the autofocus, and the size of the current frame
to see if the autofocus completed successfully. Returns True if current sharpness
is within "leniency" number of frames from the peak of the autofocus'''
current_sharpness = camera.grab_jpeg_size(stream_name='lores')
peak = np.argmax(sweep_sizes)
accepted_range = [peak - leniency, peak + leniency]
sharpness_range = [sweep_sizes[i] for i in accepted_range]
return current_sharpness >= min(sharpness_range)

View file

@ -640,24 +640,29 @@ class SmartScanThing(Thing):
attempts = 0
if self.autofocus_dz > 200:
while True:
autofocus.looping_autofocus(dz=self.autofocus_dz, start = 'base')
jpeg_zs, jpeg_sizes = autofocus.looping_autofocus(dz=self.autofocus_dz, start = 'base')
current_height = stage.position["z"]
autofocus_success = autofocus.verify_focus_sharpness(sweep_sizes = jpeg_sizes, camera = CamDep, leniency = 1)
logger.info(f"We just tested the focus! Result was {autofocus_success}")
# if there have been successful autofocuses in this scan, find the closest one in x-y
# test if the change in z between them exceeds a ratio (indicating a failed autofocus)
if len(focused_path) > 0:
nearest_focused_site = focused_path[closest(loc, focused_path)]
result = limit_focus_change(
nearest_focused_site[0:2],
nearest_focused_site[-1],
loc[0:2],
current_height,
0.3,
)
if autofocus_success:
# if there have been successful autofocuses in this scan, find the closest one in x-y
# test if the change in z between them exceeds a ratio (indicating a failed autofocus)
if len(focused_path) > 0:
nearest_focused_site = focused_path[closest(loc, focused_path)]
result = limit_focus_change(
nearest_focused_site[0:2],
nearest_focused_site[-1],
loc[0:2],
current_height,
0.3,
)
# if there haven't been any previous autofocuses, we have to assume this one worked
# if there haven't been any previous autofocuses, we have to assume this one worked
else:
result = "accept"
else:
result = "accept"
result = "reject"
# if the autofocus worked, add the current position to the list of successful locations
if result == "accept":
@ -762,6 +767,15 @@ class SmartScanThing(Thing):
def max_range(self, value: int) -> None:
self.thing_settings["max_range"] = value
@thing_property
def stitch_tiff(self) -> bool:
"""The maximum distance from the centre of the scan before we break"""
return self.thing_settings.get("stitch_tiff", False)
@stitch_tiff.setter
def stitch_tiff(self, value: bool) -> None:
self.thing_settings["stitch_tiff"] = value
@thing_property
def skip_background(self) -> bool:
"""Whether to detect and skip empty fields of view