Spelling corrections and docstring improvements
Co-authored by Joe Knapper <jaknapper@hotmail.com>
This commit is contained in:
parent
bd411db5ea
commit
06632f195e
5 changed files with 33 additions and 29 deletions
|
|
@ -38,5 +38,5 @@ select = [
|
|||
|
||||
# Line length is set to 88 for ruff. This is what the formatter aims for
|
||||
# some lines are not formatted to 88 if the formatter can't easily break
|
||||
# them. Allow up to 99 beofre throwing a long line error
|
||||
# them. Allow up to 99 before throwing a long line error
|
||||
line-length = 99
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ XYZPosList: TypeAlias = list[XYZPos]
|
|||
|
||||
def enforce_xy_tuple(value: XYPos) -> XYPos:
|
||||
"""
|
||||
Used for enfocring that an input is a tuple and is the correct length
|
||||
Used for enforcing that an input is a tuple and is the correct length
|
||||
"""
|
||||
if not isinstance(value, (list, tuple)):
|
||||
raise ValueError("2 value tuple expected")
|
||||
|
|
@ -35,7 +35,7 @@ def enforce_xy_tuple(value: XYPos) -> XYPos:
|
|||
|
||||
def enforce_xyz_tuple(value: XYZPos) -> XYZPos:
|
||||
"""
|
||||
Used for enfocring that an input is a tuple and is the correct length
|
||||
Used for enforcing that an input is a tuple and is the correct length
|
||||
"""
|
||||
if not isinstance(value, (list, tuple)):
|
||||
raise ValueError("3 value tuple expected")
|
||||
|
|
@ -64,7 +64,7 @@ class ScanPlanner:
|
|||
locations are adjusted.
|
||||
|
||||
When subclassing be sure to use enforce_xy_tuple and enforce_xyz_tuple on any user
|
||||
data before
|
||||
data before running
|
||||
"""
|
||||
|
||||
def __init__(self, intial_position: XYPos, planner_settings: Optional[dict] = None):
|
||||
|
|
@ -199,15 +199,15 @@ class ScanPlanner:
|
|||
path_pos = np.array(self._focused_locations, dtype="float64")[:, :2]
|
||||
|
||||
# Use linalg.norm to calculate the direct distance bweween the points
|
||||
# Note linalg.norm always used float64
|
||||
# Note linalg.norm always uses float64
|
||||
dists = np.linalg.norm((path_pos - current_pos), axis=1)
|
||||
|
||||
# Get indicies of all mimuma.
|
||||
# Get indices of all minima.
|
||||
# Note np.where always returns a tuple of arrays, hence the trailing [0]
|
||||
indicies = np.where(dists == np.min(dists))[0]
|
||||
indices = np.where(dists == np.min(dists))[0]
|
||||
|
||||
# The last index is most recent
|
||||
return self._focused_locations[indicies[-1]]
|
||||
return self._focused_locations[indices[-1]]
|
||||
|
||||
def mark_location_visited(
|
||||
self, xyz_pos: XYZPos, imaged: bool, focused: bool
|
||||
|
|
@ -216,7 +216,7 @@ class ScanPlanner:
|
|||
Mark the location as visited
|
||||
|
||||
Args:
|
||||
xyz_pos: the x_y poistion
|
||||
xyz_pos: the x_y_z position
|
||||
imaged: true if an image was taken, false if not (due to background detect)
|
||||
focused: true if autofocus completed successfully
|
||||
"""
|
||||
|
|
@ -289,10 +289,10 @@ class SmartSpiral(ScanPlanner):
|
|||
self, xyz_pos: XYZPos, imaged: bool = True, focused: bool = True
|
||||
) -> None:
|
||||
"""
|
||||
Mark the location as visited. Adjust extra poisitons accordingly
|
||||
Mark the location as visited. Adjust extra positions accordingly
|
||||
|
||||
Args:
|
||||
xyz_pos: the x_y poistion
|
||||
xyz_pos: the x_y_z position
|
||||
imaged: true if an image was taken, false if not (due to background detect)
|
||||
focused: true if autofocus completed successfully
|
||||
"""
|
||||
|
|
@ -306,9 +306,9 @@ class SmartSpiral(ScanPlanner):
|
|||
|
||||
def _add_surrounding_positions(self, xy_pos: XYPos) -> None:
|
||||
"""
|
||||
This adds the surrounding (4 point connectivity) poistions
|
||||
This adds the surrounding (4 point connectivity) positions
|
||||
to the remaining locations if they are not too far away or
|
||||
or already planned or already visited
|
||||
already planned or already visited
|
||||
"""
|
||||
new_positions = [
|
||||
(xy_pos[0] - self._dx, xy_pos[1]),
|
||||
|
|
@ -318,7 +318,7 @@ class SmartSpiral(ScanPlanner):
|
|||
]
|
||||
|
||||
for new_pos in new_positions:
|
||||
# Skip position if already planned or fixited
|
||||
# Skip position if already planned or visited
|
||||
if self.position_planned(new_pos) or self.position_visited(new_pos):
|
||||
continue
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,11 @@ def unpack_autofocus(scan_data):
|
|||
|
||||
|
||||
def focus_change_acceptable(prev_pos, prev_z, new_pos, new_z, fractional_limit):
|
||||
# limit is the largest ratio of change in z to change in xy that's allowed
|
||||
"""Return true if the change in z-position is small enough.
|
||||
|
||||
A large change in z-position in an indication of focus failure.
|
||||
fractional_limit is the largest ratio of change in z to change in xy that's allowed
|
||||
"""
|
||||
|
||||
prev_xy = np.asarray(prev_pos, dtype="float64")
|
||||
new_xy = np.asarray(new_pos, dtype="float64")
|
||||
|
|
@ -100,7 +104,7 @@ def ensure_free_disk_space(path: str, min_space: int = 500000000) -> None:
|
|||
default = 500,000,000 (500MiB)
|
||||
|
||||
Raises:
|
||||
NotEnoughFreeSpaceError is the
|
||||
NotEnoughFreeSpaceError if the remaining storage is below min_space
|
||||
"""
|
||||
du = shutil.disk_usage(path)
|
||||
if du.free < min_space:
|
||||
|
|
@ -449,7 +453,7 @@ class SmartScanThing(Thing):
|
|||
)
|
||||
autofocus_dz = 0
|
||||
|
||||
# Fix scan parameters in case UI is updates during scan.
|
||||
# Fix scan parameters in case UI is updated during scan.
|
||||
self._scan_data = {
|
||||
"scan_name": self._ongoing_scan_name,
|
||||
"overlap": overlap,
|
||||
|
|
@ -464,7 +468,7 @@ class SmartScanThing(Thing):
|
|||
}
|
||||
|
||||
@_scan_running
|
||||
def _save_scan_inputs_jons(self):
|
||||
def _save_scan_inputs_json(self):
|
||||
# This should be a method of the scan_data dataclass
|
||||
|
||||
data = {
|
||||
|
|
@ -504,7 +508,7 @@ class SmartScanThing(Thing):
|
|||
|
||||
try:
|
||||
self._set_scan_data()
|
||||
self._save_scan_inputs_jons()
|
||||
self._save_scan_inputs_json()
|
||||
if self._scan_images_taken != 0:
|
||||
msg = "_scan_images_taken should be zero before starting scanning"
|
||||
raise RuntimeError(msg)
|
||||
|
|
@ -575,7 +579,7 @@ class SmartScanThing(Thing):
|
|||
new_pos_xyz = self._move_to_next_point(next_pos_xy, z_est)
|
||||
|
||||
capture_image = True
|
||||
# If skipping background, take and image to check if is background
|
||||
# If skipping background, take an image to check if it is background
|
||||
if self._scan_data["skip_background"]:
|
||||
capture_image = self._background_detect.image_is_sample()
|
||||
|
||||
|
|
@ -583,7 +587,7 @@ class SmartScanThing(Thing):
|
|||
route_planner.mark_location_visited(
|
||||
new_pos_xyz, imaged=False, focused=False
|
||||
)
|
||||
# Background franction is actually a percentage
|
||||
# Background fraction is actually a percentage
|
||||
back_perc = round(self._background_detect.background_fraction(), 0)
|
||||
msg = f"Skipping {new_pos_xyz} as it is {back_perc}% background."
|
||||
self._scan_logger.info(msg)
|
||||
|
|
@ -826,8 +830,8 @@ class SmartScanThing(Thing):
|
|||
).encode("utf-8")
|
||||
piexif.insert(piexif.dump(exif_dict), jpeg_path)
|
||||
except: # noqa: E722
|
||||
# We need to capture any exeption as there are many reasons metadata
|
||||
# might not be added. We wern rather than log the error.
|
||||
# We need to capture any exception as there are many reasons metadata
|
||||
# might not be added. We warn rather than log the error.
|
||||
self._scan_logger.warning(f"Failed to add metadata to {jpeg_path}")
|
||||
except Exception as e:
|
||||
raise IOError(f"An error occurred while saving {jpeg_path}") from e
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ def test_v_basic_smart_spiral():
|
|||
planner = scan_planners.SmartSpiral(
|
||||
intial_position=intial_position, planner_settings=planner_settings
|
||||
)
|
||||
# Create a planner it shouldn't start complete
|
||||
# Create a planner. It shouldn't be complete.
|
||||
assert not planner.scan_complete
|
||||
# When we start it should want to stay in the inital pos and have
|
||||
# no z_estimate
|
||||
|
|
@ -47,7 +47,7 @@ def test_v_basic_smart_spiral():
|
|||
assert xy_pos == intial_position
|
||||
assert z_pos is None
|
||||
|
||||
# Try to make imaged with only xy_position
|
||||
# Try to mark location as imaged with only xy_position
|
||||
with pytest.raises(ValueError):
|
||||
planner.mark_location_visited(xy_pos, imaged=False, focused=False)
|
||||
# scan still not complete
|
||||
|
|
@ -100,7 +100,7 @@ def test_smart_spiral_first_few_pos():
|
|||
This test is VERY long, not really a "unit". It checks step-by-step
|
||||
that data is added correctly for the first few postions in a scan.
|
||||
|
||||
This should catch basic caseses of if the algorithm is updated.
|
||||
This should catch basic cases of if the algorithm is updated.
|
||||
"""
|
||||
intial_position = (100, 50)
|
||||
planner_settings = {"dx": 50, "dy": 50, "max_dist": 10000}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class FakeSample:
|
|||
Return whether an image at a given location with a given image size
|
||||
is on the sample
|
||||
|
||||
This doesn't check the entire image feild as this is designed to be used
|
||||
This doesn't check the entire image field as this is designed to be used
|
||||
where the fake sample is much larger than the image and has smooth edges
|
||||
It just checks the 4 corners
|
||||
"""
|
||||
|
|
@ -48,7 +48,7 @@ class FakeSample:
|
|||
@property
|
||||
def patch(self) -> PathPatch:
|
||||
"""
|
||||
The sample as a matplotlib patch fro plotting
|
||||
The sample as a matplotlib patch for plotting
|
||||
"""
|
||||
patch = PathPatch(self._sample_perimeter)
|
||||
patch.set(color=(1.0, 0.8, 1.0, 1.0))
|
||||
|
|
@ -86,7 +86,7 @@ def visualise_scan(sample: FakeSample, planner: scan_planners.ScanPlanner) -> Fi
|
|||
def interp_closed_path(xy_points: list[tuple[int, int]], n_points: int) -> MatPath:
|
||||
"""
|
||||
Given a lists of xy_points interpolate an n_point closed curve. This can be used
|
||||
to creat an arbitrary sample shape plan a scan.
|
||||
to create an arbitrary sample shape plan a scan.
|
||||
|
||||
Modified from:
|
||||
https://stackoverflow.com/questions/33962717/interpolating-a-closed-curve-using-scipy
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue