Merge branch 'remove_autofocus_test' into 'v3'
Remove autofocus test See merge request openflexure/openflexure-microscope-server!255
This commit is contained in:
commit
97beb9147b
2 changed files with 10 additions and 78 deletions
|
|
@ -253,22 +253,6 @@ class AutofocusThing(Thing):
|
||||||
stage.move_absolute(z=peak_height)
|
stage.move_absolute(z=peak_height)
|
||||||
return heights.tolist(), sizes.tolist()
|
return heights.tolist(), sizes.tolist()
|
||||||
|
|
||||||
@thing_action
|
|
||||||
def verify_focus_sharpness(
|
|
||||||
self, sweep_sizes: list, camera: WrappedCamera, threshold: float = 0.95
|
|
||||||
):
|
|
||||||
"""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.max(sweep_sizes)
|
|
||||||
base = np.min(sweep_sizes)
|
|
||||||
cutoff = threshold * (peak - base)
|
|
||||||
|
|
||||||
return current_sharpness >= base + cutoff
|
|
||||||
|
|
||||||
@thing_property
|
@thing_property
|
||||||
def stack_images_to_capture(self) -> int:
|
def stack_images_to_capture(self) -> int:
|
||||||
"""The number of images to capture and save in a stack
|
"""The number of images to capture and save in a stack
|
||||||
|
|
|
||||||
|
|
@ -43,30 +43,6 @@ BackgroundDep = direct_thing_client_dependency(
|
||||||
IMAGE_REGEX = re.compile(r"-?[0-9]+_-?[0-9]+\.jpeg$")
|
IMAGE_REGEX = re.compile(r"-?[0-9]+_-?[0-9]+\.jpeg$")
|
||||||
|
|
||||||
|
|
||||||
def unpack_autofocus(scan_data):
|
|
||||||
"""Extract z, sharpness data from a move_and_measure call
|
|
||||||
|
|
||||||
Data will start at `start_index`, i.e. `start_index` points are dropped
|
|
||||||
from the beginning of the array.
|
|
||||||
"""
|
|
||||||
jpeg_times = scan_data["jpeg_times"]
|
|
||||||
jpeg_sizes = scan_data["jpeg_sizes"]
|
|
||||||
jpeg_sizes_mb = [x / 10**3 for x in jpeg_sizes]
|
|
||||||
stage_times = scan_data["stage_times"]
|
|
||||||
stage_positions = scan_data["stage_positions"]
|
|
||||||
stage_height = [pos[2] for pos in stage_positions]
|
|
||||||
|
|
||||||
jpeg_heights = np.interp(jpeg_times, stage_times, stage_height)
|
|
||||||
|
|
||||||
def turningpoints(lst):
|
|
||||||
dx = np.diff(lst)
|
|
||||||
return dx[1:] * dx[:-1] < 0
|
|
||||||
|
|
||||||
turning = np.where(turningpoints(jpeg_heights))[0] + 1
|
|
||||||
|
|
||||||
return jpeg_heights[turning[0] : turning[1]], jpeg_sizes_mb[turning[0] : turning[1]]
|
|
||||||
|
|
||||||
|
|
||||||
class NotEnoughFreeSpaceError(IOError):
|
class NotEnoughFreeSpaceError(IOError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -603,8 +579,16 @@ class SmartScanThing(Thing):
|
||||||
|
|
||||||
focused = False
|
focused = False
|
||||||
if self._scan_data["autofocus_on"]:
|
if self._scan_data["autofocus_on"]:
|
||||||
focused, focused_z = self._try_autofocus(new_pos_xyz)
|
self._autofocus.looping_autofocus(
|
||||||
current_pos_xyz = (new_pos_xyz[0], new_pos_xyz[1], focused_z)
|
dz=self._scan_data["autofocus_dz"], start="centre"
|
||||||
|
)
|
||||||
|
current_pos_xyz = (
|
||||||
|
new_pos_xyz[0],
|
||||||
|
new_pos_xyz[1],
|
||||||
|
self._stage.position["z"],
|
||||||
|
)
|
||||||
|
# Without a test for autofocus success, assume it worked
|
||||||
|
focused = True
|
||||||
|
|
||||||
route_planner.mark_location_visited(
|
route_planner.mark_location_visited(
|
||||||
current_pos_xyz, imaged=True, focused=focused
|
current_pos_xyz, imaged=True, focused=focused
|
||||||
|
|
@ -628,42 +612,6 @@ class SmartScanThing(Thing):
|
||||||
scan_name=self._ongoing_scan_name,
|
scan_name=self._ongoing_scan_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
@_scan_running
|
|
||||||
def _try_autofocus(
|
|
||||||
self,
|
|
||||||
this_xyz: tuple[int, int, int],
|
|
||||||
) -> bool:
|
|
||||||
"""
|
|
||||||
Try to perform autofocus and return boolean for if successful
|
|
||||||
|
|
||||||
Args:
|
|
||||||
this_xyz is the current x,y,z position.
|
|
||||||
|
|
||||||
Return True, focused_height on successful autofocus.
|
|
||||||
Return False, initial_height if failed after 3 tries - the position will be the initial estimate
|
|
||||||
"""
|
|
||||||
attempts = 0
|
|
||||||
max_attempts = 3
|
|
||||||
dz = self._scan_data["autofocus_dz"]
|
|
||||||
|
|
||||||
while attempts < max_attempts:
|
|
||||||
attempts += 1
|
|
||||||
|
|
||||||
_, jpeg_sizes = self._autofocus.looping_autofocus(dz=dz, start="centre")
|
|
||||||
time.sleep(0.2)
|
|
||||||
autofocus_sharp_enough = self._autofocus.verify_focus_sharpness(
|
|
||||||
sweep_sizes=jpeg_sizes, camera=CamDep, threshold=0.92
|
|
||||||
)
|
|
||||||
|
|
||||||
# If sharp enough, break and return success, otherwise go to start and try again
|
|
||||||
if autofocus_sharp_enough:
|
|
||||||
return True, self._stage.position["z"]
|
|
||||||
else:
|
|
||||||
self._stage.move_absolute(z=this_xyz[2])
|
|
||||||
|
|
||||||
self._scan_logger.warning("Could not autofocus after 3 attempts.")
|
|
||||||
return False, self._stage.position["z"]
|
|
||||||
|
|
||||||
@_scan_running
|
@_scan_running
|
||||||
def _return_to_starting_position(self):
|
def _return_to_starting_position(self):
|
||||||
self._scan_logger.info("Returning to starting position.")
|
self._scan_logger.info("Returning to starting position.")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue