diff --git a/ruff-increased-checking.toml b/ruff-increased-checking.toml index 9c4ffb8e..118cfbff 100644 --- a/ruff-increased-checking.toml +++ b/ruff-increased-checking.toml @@ -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 diff --git a/src/openflexure_microscope_server/scan_planners.py b/src/openflexure_microscope_server/scan_planners.py index d6d94e6a..75ffd0fb 100644 --- a/src/openflexure_microscope_server/scan_planners.py +++ b/src/openflexure_microscope_server/scan_planners.py @@ -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 diff --git a/src/openflexure_microscope_server/things/smart_scan.py b/src/openflexure_microscope_server/things/smart_scan.py index 0c327b0d..5d853b69 100644 --- a/src/openflexure_microscope_server/things/smart_scan.py +++ b/src/openflexure_microscope_server/things/smart_scan.py @@ -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 diff --git a/tests/test_scan_planners.py b/tests/test_scan_planners.py index e4699d91..da5ff961 100644 --- a/tests/test_scan_planners.py +++ b/tests/test_scan_planners.py @@ -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} diff --git a/tests/utilities/scan_test_helpers.py b/tests/utilities/scan_test_helpers.py index 82fc84bd..6901361a 100644 --- a/tests/utilities/scan_test_helpers.py +++ b/tests/utilities/scan_test_helpers.py @@ -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