diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 00000000..84f6269c --- /dev/null +++ b/.codespellrc @@ -0,0 +1,18 @@ +[codespell] + +skip = node_modules, + *-lock.json, + *.git, + *.pyc, + __pycache__, + ./build, + ./dist, + ./apidocs, + ./openflexure, + ./htmlcov, + ./src/openflexure_microscope_server/static, + .venv, + *.egg-info, + report.xml + +regex = [a-zA-Z0-9\-'’]+ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2b57ff19..0a2f663e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -72,6 +72,13 @@ version-check: - tags - web +# A job to protect reviewers from Julian's terrible spelling. +spelling: + stage: analysis + extends: .python + script: + - codespell . + # Python static analysis with ruff ruff-lint: stage: analysis diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bfbc0cd..6147a9bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,7 +83,7 @@ The following merge requests have been merged into v3: * !286 Use same version number for server and webapp, add CI check * !285 Swapped the order of CSM so y axis is completed first * !283 Add scan directory to json config -* !287 Update depedencies and changelog prior to v3.0.0-alpha1 release +* !287 Update depedencies and changelog prior to v3.0.0-alpha1 release # [v2.11.0](https://gitlab.com/openflexure/openflexure-microscope-server/compare/v2.10.1...v2.11.0) (2022-08-08) ## New features diff --git a/README.md b/README.md index f88df89c..45469838 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > ## This is the v3 development branch > We are no longer actively developing v2, but v3 is not yet released. -> v3 is not yet stable enough for wider public release. Deveopment snapshots are released from time to time. +> v3 is not yet stable enough for wider public release. Development snapshots are released from time to time. > If you want to use a development snapshot before we do a wider alpha release the best thing to do is get in contact on the [forum](https://openflexure.discourse.group/). If you want to look at the code for v2 you should look at the [master branch](https://gitlab.com/openflexure/openflexure-microscope-server/-/tree/master). diff --git a/pyproject.toml b/pyproject.toml index 5be129f3..e45c6eaf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,8 @@ dev = [ "pytest-mock==3.14", "matplotlib~=3.10", "hypothesis", - "pydoctor" + "pydoctor~=25.4", + "codespell~=2.4", ] pi = [ "picamera2~=0.3.27", @@ -107,10 +108,10 @@ select = [ # "B", # Flake8 bugbear "A", # Flake8 builtins checker "C", # Flake8 comprehensions -# "FIX", #TODO/FIXME's in code. These should be added during develoment for ongoing tasks. +# "FIX", #TODO/FIXME's in code. These should be added during development for ongoing tasks. # If they are not fixed before merge they should be converted to GitLab issues # "LOG", # Flake8 logging issues (pedantic logger formatting issues can be added with "G") -# "T20", # Warns for print statments, production code should log +# "T20", # Warns for print statements, production code should log # "PT", # pytest linting "RET", # Consistent clear return statements "RSE", # Raise parentheses diff --git a/ruff-increased-checking.toml b/ruff-increased-checking.toml index 5973655d..fd63f8fe 100644 --- a/ruff-increased-checking.toml +++ b/ruff-increased-checking.toml @@ -19,10 +19,10 @@ select = [ "B", # Flake8 bugbear "A", # Flake8 builtins checker "C", # Flake8 comprehensions - "FIX", #TODO/FIXME's in code. These should be added during develoment for ongoing tasks. + "FIX", #TODO/FIXME's in code. These should be added during development for ongoing tasks. # If they are not fixed before merge they should be converted to GitLab issues "LOG", # Flake8 logging issues (pedantic logger formatting issues can be added with "G") - "T20", # Warns for print statments, production code should log + "T20", # Warns for print statements, production code should log "PT", # pytest linting "RET", # Consistent clear return statements "RSE", # Raise parentheses diff --git a/scripts/zenodo/README.md b/scripts/zenodo/README.md index 6fbc93fd..7f708e99 100644 --- a/scripts/zenodo/README.md +++ b/scripts/zenodo/README.md @@ -1,5 +1,5 @@ # Zenodo archiving -This folder contains some scripts put together by Kaspar Bumke, and re-used by Richard, to upload the contents of the repository, together with any CI build artefacts, to Zenodo. The result is a link, taking you to a pre-populated upload on Zenodo that you can manually correct and upload. In order to customise it for a new project, there are a few steps you need, outlined below. +This folder contains some scripts put together by Kaspar Bumke, and reused by Richard, to upload the contents of the repository, together with any CI build artefacts, to Zenodo. The result is a link, taking you to a pre-populated upload on Zenodo that you can manually correct and upload. In order to customise it for a new project, there are a few steps you need, outlined below. ## Setting up archival * Copy this folder to `scripts/zenodo` in your repository. diff --git a/scripts/zenodo/upload_to_zenodo.py b/scripts/zenodo/upload_to_zenodo.py index 81507716..309efec1 100644 --- a/scripts/zenodo/upload_to_zenodo.py +++ b/scripts/zenodo/upload_to_zenodo.py @@ -5,7 +5,7 @@ from argparse import ArgumentParser, Namespace from zenodo import Zenodo import yaml -# you have to explicitely set ZENODO_USE_SANDBOX=false to not use the +# You have to explicitly set ZENODO_USE_SANDBOX=false to not use the # sandbox, any other value or unset variable means this script will use # the sandbox zenodo site if "ZENODO_USE_SANDBOX" in os.environ: diff --git a/src/openflexure_microscope_server/logging.py b/src/openflexure_microscope_server/logging.py index 1c1d31d3..eb49f11f 100644 --- a/src/openflexure_microscope_server/logging.py +++ b/src/openflexure_microscope_server/logging.py @@ -31,7 +31,7 @@ def configure_logging(log_folder): """ root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) - # Explictly make OFM_LOG_FILE a global so it can be updated based on log settings + # Explicitly make OFM_LOG_FILE a global so it can be updated based on log settings global OFM_LOG_FILE OFM_LOG_FILE = os.path.join(log_folder, "openflexure_microscope.log") @@ -64,11 +64,11 @@ def retrieve_log() -> PlainTextResponse: This log is the one shown in the UI and on the logging page. - It does not include any of the ``uvicorn.access`` logs as these are emmitted + It does not include any of the ``uvicorn.access`` logs as these are emitted every time any API route is called. All logs, including ``uvicorn.access`` are logged to the OFM_LOG_FILE (see above) - ths is the best place to get logs about crashes. + this is the best place to get logs about crashes. """ return PlainTextResponse(OFM_HANDLER.log_history) @@ -92,7 +92,7 @@ class OFMHandler(logging.Handler): """A logging.Handler that stores the most recent logs for access by the server.""" def __init__(self, level=logging.INFO, max_logs=250): - """Inialise the handler with a set logging level and message buffer size. + """Initialise the handler with a set logging level and message buffer size. :param level: The level of logs captured. As standard logs of INFO and above are captured. diff --git a/src/openflexure_microscope_server/scan_planners.py b/src/openflexure_microscope_server/scan_planners.py index 59ba1469..b30cacc7 100644 --- a/src/openflexure_microscope_server/scan_planners.py +++ b/src/openflexure_microscope_server/scan_planners.py @@ -67,9 +67,9 @@ class ScanPlanner: * ``_parse()`` - to parse the planner_settings dictionary, saving values to class variables - * ``_intial_location_list()`` - Sets the list of locations for the scan to follow + * ``_initial_location_list()`` - Sets the list of locations for the scan to follow - For a simple scan pattern this should be sufficent. For more complex ones that + For a simple scan pattern this should be sufficient. For more complex ones that dynamically adjust the path it is suggested to override ``mark_location_visited()`` calling ``super().mark_location_visited()`` at the start of the method so that all locations are adjusted. @@ -78,17 +78,19 @@ class ScanPlanner: any user data before running. """ - def __init__(self, intial_position: XYPos, planner_settings: Optional[dict] = None): + def __init__( + self, initial_position: XYPos, planner_settings: Optional[dict] = None + ): """Set up lists for the path planning, and scan history.""" - self._initial_position = enforce_xy_tuple(intial_position) + self._initial_position = enforce_xy_tuple(initial_position) self._parse(planner_settings) # The remaining (x,y) locations to scan # (This was `path` before refactoring from the long `sample_scan` code) - self._remaining_locations: XYPosList = self._intial_location_list() + self._remaining_locations: XYPosList = self._initial_location_list() # This holds a list of all (x,y,z) locations where images were taken - # this may not be equivalent to the x,y poistions ins self._path_history + # this may not be equivalent to the x,y positions ins self._path_history # if background detect is used # (This was not used in the `sample_scan` code) self._imaged_locations: XYZPosList = [] @@ -132,10 +134,10 @@ class ScanPlanner: """Parse any settings sent to this planner and store them if needed.""" raise NotImplementedError("Did you call the ScanPlanner base class?") - def _intial_location_list(self) -> XYPosList: + def _initial_location_list(self) -> XYPosList: """Set the initial list of locations for this scan planner. - This is called on initalisation. + This is called on initialisation. For a simple grid scan/snake scan this would be all locations to move to. @@ -270,7 +272,7 @@ class SmartSpiral(ScanPlanner): self._dy = int(planner_settings["dy"]) self._max_dist = int(planner_settings["max_dist"]) - def _intial_location_list(self) -> XYPosList: + def _initial_location_list(self) -> XYPosList: """Set the initial list of locations for this scan planner. This is salled on initialisation. @@ -327,7 +329,7 @@ class SmartSpiral(ScanPlanner): self._remaining_locations.append(new_pos) def _re_sort_remaining_locations(self, current_pos: XYPos) -> None: - """Sort the remaining positions besed on the current location.""" + """Sort the remaining positions based on the current location.""" # Defined rather than use a lambda for readability def sort_key(pos): diff --git a/src/openflexure_microscope_server/things/autofocus.py b/src/openflexure_microscope_server/things/autofocus.py index 7c1b39c7..1353df65 100644 --- a/src/openflexure_microscope_server/things/autofocus.py +++ b/src/openflexure_microscope_server/things/autofocus.py @@ -38,7 +38,7 @@ class StackParams: images_dir: str, save_resolution: tuple[int, int], ) -> None: - """Initalise the parameters. All arguments are keyword only. + """Initialise the parameters. All arguments are keyword only. :param stack_dz: The number of motor steps between images :param images_to_save: The number of images to save to disk @@ -205,7 +205,7 @@ class JPEGSharpnessMonitor: """ def __init__(self, stage: Stage, camera: Camera, portal: lt.deps.BlockingPortal): - """Initalise a new JPEGSharpnessMonitor. The args are injected automatically. + """Initialise a new JPEGSharpnessMonitor. The args are injected automatically. :param stage: A direct_thing_client dependency for the the microscope stage. :param camera: A raw_thing_client depeendency for the camera. This is a raw @@ -245,7 +245,7 @@ class JPEGSharpnessMonitor: """Move the stage by dz, monitoring the position over time. This performs exactly one move. Multiple calls of this method - will append to the internal postition storage for more complex + will append to the internal position storage for more complex autofocus procedures. This should be run from within the JPEGSharpnessMonitor.run @@ -505,9 +505,9 @@ class AutofocusThing(lt.Thing): save_resolution=save_resolution, ) - trys = 0 + tries = 0 # Loop until a stack is successful - while trys < stack_parameters.max_attempts: + while tries < stack_parameters.max_attempts: success, captures, sharpest_id = self.z_stack( stack_parameters=stack_parameters, cam=cam, diff --git a/src/openflexure_microscope_server/things/background_detect.py b/src/openflexure_microscope_server/things/background_detect.py index 31057ceb..1c147093 100644 --- a/src/openflexure_microscope_server/things/background_detect.py +++ b/src/openflexure_microscope_server/things/background_detect.py @@ -77,7 +77,7 @@ class BackgroundDetectThing(lt.Thing): def background_mask(self, image: np.ndarray) -> np.ndarray: """Calculate a binary image, showing whether each pixel is background. - The image should be in LUV format, the ouput will be binary with the + The image should be in LUV format, the output will be binary with the same shape in the first two dimensions. """ d = self.background_distributions diff --git a/src/openflexure_microscope_server/things/camera/__init__.py b/src/openflexure_microscope_server/things/camera/__init__.py index 8bcf25eb..12301213 100644 --- a/src/openflexure_microscope_server/things/camera/__init__.py +++ b/src/openflexure_microscope_server/things/camera/__init__.py @@ -1,7 +1,7 @@ """OpenFlexure Microscope Camera. This module defines the interface for cameras. Any compatible lt.Thing -should enabe the server to work. +should enable the server to work. See repository root for licensing information. """ diff --git a/src/openflexure_microscope_server/things/camera/opencv.py b/src/openflexure_microscope_server/things/camera/opencv.py index 4c39191b..a5604432 100644 --- a/src/openflexure_microscope_server/things/camera/opencv.py +++ b/src/openflexure_microscope_server/things/camera/opencv.py @@ -86,7 +86,7 @@ class OpenCVCamera(BaseCamera): It's likely to be highly inefficient - raw and/or uncompressed captures using binary image formats will be added in due course. """ - logging.warning(f"OpenCV camera doen't respect {resolution} setting") + logging.warning(f"OpenCV camera doesn't respect {resolution} setting") ret, frame = self.cap.read() if not ret: raise RuntimeError( @@ -104,7 +104,7 @@ class OpenCVCamera(BaseCamera): This function will produce a JPEG image. """ - logging.warning(f"OpenCV camera doen't respect {resolution} setting") + logging.warning(f"OpenCV camera doesn't respect {resolution} setting") frame = self.capture_array() jpeg = cv2.imencode(".jpg", frame)[1].tobytes() exif_dict = { diff --git a/src/openflexure_microscope_server/things/camera/picamera.py b/src/openflexure_microscope_server/things/camera/picamera.py index d1990f8d..0e3dd04f 100644 --- a/src/openflexure_microscope_server/things/camera/picamera.py +++ b/src/openflexure_microscope_server/things/camera/picamera.py @@ -79,7 +79,7 @@ class SensorMode(BaseModel): class SensorModeSelector(BaseModel): """A Pydantic model holding the two values needed to select a PiCamera Sensor mode. - Theses values are the output size and the bit depth. + These values are the output size and the bit depth. This is a Pydantic model so that it can be saved to disk. """ @@ -95,7 +95,7 @@ class LensShading(BaseModel): (12, 16) in size. The arrays are luminance, red-difference chroma (Cr), and blue-difference chroma (Cb). - This is a Pydantic modell so that it can be saved to the disk. + This is a Pydantic model so that it can be saved to the disk. """ luminance: list[list[float]] @@ -162,7 +162,7 @@ class StreamingPiCamera2(BaseCamera): This method is run by any Thing when a ThingSetting is saved. However, the method reads the thing_setting. As reading the thing setting talks to the camera and calls save_settings if the value is not as expected, this could - cause recursion. Aslo this means that saving one setting causes all others + cause recursion. Also this means that saving one setting causes all others to be read each time. """ try: @@ -197,7 +197,7 @@ class StreamingPiCamera2(BaseCamera): @lt.thing_setting def colour_gains(self) -> tuple[float, float]: - """The red and blue colour gains, must be betwen 0.0 and 32.0.""" + """The red and blue colour gains, must be between 0.0 and 32.0.""" if not self._setting_save_in_progress and self.streaming: with self._streaming_picamera() as cam: cam_value = cam.capture_metadata()["ColourGains"] @@ -759,7 +759,7 @@ class StreamingPiCamera2(BaseCamera): same as the default behaviour, which is to use an adaptive lens shading table. - This flat table is used to take an image wth no lens shading so that the + This flat table is used to take an image with no lens shading so that the correct lens shading table can be calibrated. """ with self._streaming_picamera(pause_stream=True): diff --git a/src/openflexure_microscope_server/things/camera/picamera_recalibrate_utils.py b/src/openflexure_microscope_server/things/camera/picamera_recalibrate_utils.py index ef9b9b82..fbf827df 100644 --- a/src/openflexure_microscope_server/things/camera/picamera_recalibrate_utils.py +++ b/src/openflexure_microscope_server/things/camera/picamera_recalibrate_utils.py @@ -84,7 +84,7 @@ def set_minimum_exposure(camera: Picamera2) -> None: Note ISO is left at auto, because this is needed for the gains to be set correctly. """ - # Disable Automatic exposure and gain algoritm (AeEnable), and set analogue + # Disable Automatic exposure and gain algorithm (AeEnable), and set analogue # gain and exposure time. # Setting the shutter speed to 1us will result in it being set # to the minimum possible, which is ~8us for PiCamera v2 @@ -427,7 +427,7 @@ def set_static_lst( cr: np.ndarray, cb: np.ndarray, ) -> None: - """Update the ``rpi.alsc`` section of a camera tuning dict to use a static correcton. + """Update the ``rpi.alsc`` section of a camera tuning dict to use a static correction. ``tuning`` will be updated in-place to set its shading to static, and disable any adaptive tweaking by the algorithm. @@ -452,7 +452,7 @@ def set_static_ccm( float, float, float, float, float, float, float, float, float ], ) -> None: - """Update the ``rpi.alsc`` section of a camera tuning dict to use a static correcton. + """Update the ``rpi.alsc`` section of a camera tuning dict to use a static correction. ``tuning`` will be updated in-place to set its shading to static, and disable any adaptive tweaking by the algorithm. @@ -480,7 +480,7 @@ def set_static_geq( """Update the ``rpi.geq`` section of a camera tuning dict. :param tuning: the raspberry pi tuning file. This will be updated in-place to - set the geq offest to the given value. + set the geq offset to the given value. :param offset: The desired green equalisation offset. Default 65535. The default is the maximum allowed value. This means the brightness will always be below the threshold where averaging is used. This is default as we always need the green diff --git a/src/openflexure_microscope_server/things/camera/simulation.py b/src/openflexure_microscope_server/things/camera/simulation.py index 58675f4b..ed2d7e14 100644 --- a/src/openflexure_microscope_server/things/camera/simulation.py +++ b/src/openflexure_microscope_server/things/camera/simulation.py @@ -42,7 +42,7 @@ class SimulatedCamera(BaseCamera): canvas_shape: tuple[int, int, int] = (3000, 4000, 3), frame_interval: float = 0.1, ): - """Initalise the simulated with settings for how images are generated. + """Initialise the simulated with settings for how images are generated. :param shape: The shape (size) of the generated image. :param glyph_shape: The size randomly positioned glyphs. @@ -128,7 +128,7 @@ class SimulatedCamera(BaseCamera): """Wrap the attach_to_server method so the server instance can be stored. Direct access to the server instance is needed to get the stage position while - maintianing the same public API as a real camera that doesn't need this access. + maintaining the same public API as a real camera that doesn't need this access. """ self._server = server return super().attach_to_server(server, path, setting_storage_path) @@ -198,7 +198,7 @@ class SimulatedCamera(BaseCamera): It's likely to be highly inefficient - raw and/or uncompressed captures using binary image formats will be added in due course. """ - logging.warning(f"Simulation camera doen't respect {resolution} setting") + logging.warning(f"Simulation camera doesn't respect {resolution} setting") return self.generate_frame() @lt.thing_action @@ -211,7 +211,7 @@ class SimulatedCamera(BaseCamera): This function will produce a JPEG image. """ - logging.warning(f"Simulation camera doen't respect {resolution} setting") + logging.warning(f"Simulation camera doesn't respect {resolution} setting") frame = self.capture_array() jpeg = cv2.imencode(".jpg", frame)[1].tobytes() exif_dict = { diff --git a/src/openflexure_microscope_server/things/camera_stage_mapping.py b/src/openflexure_microscope_server/things/camera_stage_mapping.py index 0e0ace6f..fa42d9f6 100644 --- a/src/openflexure_microscope_server/things/camera_stage_mapping.py +++ b/src/openflexure_microscope_server/things/camera_stage_mapping.py @@ -186,7 +186,7 @@ class CSMUncalibratedError(HTTPException): """An HTTP Exception raised if camera stage mapping data is needed but unavailable. Camera Stage Mapping data is needed to convert from distances specified in fractions - of the feild of view to distances in motor steps. This is used when clicking on the + of the field of view to distances in motor steps. This is used when clicking on the live preview to move, or when performing a scan. """ diff --git a/src/openflexure_microscope_server/things/smart_scan.py b/src/openflexure_microscope_server/things/smart_scan.py index 4401520b..f7e5d675 100644 --- a/src/openflexure_microscope_server/things/smart_scan.py +++ b/src/openflexure_microscope_server/things/smart_scan.py @@ -1,7 +1,7 @@ """The core sample scanning functionality for the OpenFlexure Microscope. SmartScan provides sample scanning functionality including automatic background -dectection (via the `BackgroundDetectThing`) and automatic path planning via +detection (via the `BackgroundDetectThing`) and automatic path planning via `scan_planners`. It manages the directories of past scans via `scan_directories`. It also controls external processes for live stitching composite images, and the creation of the final stitched images. @@ -229,7 +229,7 @@ class SmartScanThing(lt.Thing): def _move_to_next_point( self, next_point: tuple[int, int], z_estimate: Optional[int] = None ) -> tuple[int, int, int]: - """Move the stage to the next poistion. + """Move the stage to the next position. If no z_estimate is given then the current stage position is used. Must move to the estimated focused position (although moving below would be marginally @@ -256,7 +256,7 @@ class SmartScanThing(lt.Thing): :param overlap: The desired overlap as a fraction of the image. i.e. 0.5 means that each image should overlap its nearest neighbour by 50%. - :returns: (dx, dy) - the x and y displacments in steps + :returns: (dx, dy) - the x and y displacements in steps """ test_jpg = self._cam.grab_jpeg() test_image = np.array(Image.open(test_jpg.open())) @@ -488,7 +488,7 @@ class SmartScanThing(lt.Thing): "max_dist": self._scan_data["max_dist"], } route_planner = scan_planners.SmartSpiral( - intial_position=(self._stage.position["x"], self._stage.position["y"]), + initial_position=(self._stage.position["x"], self._stage.position["y"]), planner_settings=planner_settings, ) @@ -788,7 +788,7 @@ class SmartScanThing(lt.Thing): This uses popen and returns immediately - self._preview_stitch_popen holds the popen for polling - - self._preview_stitch_popen_lock is a lock aquired while interacting + - self._preview_stitch_popen_lock is a lock acquired while interacting with Popen """ # Set minimum overlap to 90% of the scan overlap to catch only images directly adjacent, @@ -856,7 +856,7 @@ class SmartScanThing(lt.Thing): os.set_blocking(process.stdout.fileno(), False) logger.info(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))) - # Poll returns None while running, will return the error code when finnished + # Poll returns None while running, will return the error code when finished while process.poll() is None: log_buffer(process.stdout) # Once buffer is clear sleep for 0.2s before trying again. diff --git a/tests/mock_things/__init__.py b/tests/mock_things/__init__.py index 78ba995c..c65a6219 100644 --- a/tests/mock_things/__init__.py +++ b/tests/mock_things/__init__.py @@ -1,5 +1,5 @@ """A package of test module providing mock Things for testing. -The mock things do not subclass the origninal things to minimise the inflation of +The mock things do not subclass the original things to minimise the inflation of test coverage. """ diff --git a/tests/test_camera_buffer.py b/tests/test_camera_buffer.py index c62252c9..f7dda0c8 100644 --- a/tests/test_camera_buffer.py +++ b/tests/test_camera_buffer.py @@ -113,7 +113,7 @@ def test_buffer_size_changing(): misc_image3 = random_image() buffer_id1 = mem_buf.add_image(misc_image1, buffer_max=3) buffer_id2 = mem_buf.add_image(misc_image2, buffer_max=3) - # Third capture doen't set buffer size, so it will be reset + # Third capture doesn't set buffer size, so it will be reset buffer_id3 = mem_buf.add_image(misc_image3) # As buffer size was reset, images 1 and 2 are deleted with pytest.raises(NoImageInMemoryError): @@ -201,7 +201,7 @@ def test_get_metadata_too(): # Preallocate zipped data, to avoid long confusing lines zipped = zip(images, metadatas, buffer_ids) - # Check both image and metdata + # Check both image and metadata for i, (image, metadata, buffer_id) in enumerate(zipped): returned_image, returned_metadata = mem_buf.get_image(buffer_id) assert image is returned_image diff --git a/tests/test_scan_planners.py b/tests/test_scan_planners.py index dd6bc83a..7a9344f9 100644 --- a/tests/test_scan_planners.py +++ b/tests/test_scan_planners.py @@ -37,24 +37,24 @@ def test_enforce_xyz_tuple(): def test_base_class_not_implemented(): """Check NotImplementedError is raised when initialising ScanPlanner directly.""" - intial_position = (100, 50) + initial_position = (100, 50) with pytest.raises(NotImplementedError): - scan_planners.ScanPlanner(intial_position=intial_position) + scan_planners.ScanPlanner(initial_position=initial_position) def test_v_basic_smart_spiral(): """Check that a SmartSpiral where the first image is not sample completes.""" - intial_position = (100, 50) + initial_position = (100, 50) planner_settings = {"dx": 50, "dy": 50, "max_dist": 10000} planner = scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=planner_settings + initial_position=initial_position, planner_settings=planner_settings ) # 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 + # When we start it should want to stay in the initial pos and have # no z_estimate xy_pos, z_pos = planner.get_next_location_and_z_estimate() - assert xy_pos == intial_position + assert xy_pos == initial_position assert z_pos is None # Try to mark location as imaged with only xy_position @@ -76,11 +76,11 @@ def test_v_basic_smart_spiral(): def test_bad_smart_spiral_settings(): """Check that KeyError is raised when SmartSpiral is given bad settings.""" - intial_position = (100, 50) + initial_position = (100, 50) # Class init should raise error if no planner_settings dictionary set with pytest.raises(ValueError): - scan_planners.SmartSpiral(intial_position=intial_position) + scan_planners.SmartSpiral(initial_position=initial_position) planner_settings = {"dx": 50, "dy": 50, "max_dist": 10000} keys = ["dx", "dy", "max_dist"] @@ -91,7 +91,7 @@ def test_bad_smart_spiral_settings(): del bad_planner_settings[delkey] with pytest.raises(KeyError): scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=bad_planner_settings + initial_position=initial_position, planner_settings=bad_planner_settings ) # Class init should raise error if planner_settings if any value can't be cast @@ -102,7 +102,7 @@ def test_bad_smart_spiral_settings(): bad_planner_settings[badkey] = "I can't be converted to an int" with pytest.raises(ValueError): scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=bad_planner_settings + initial_position=initial_position, planner_settings=bad_planner_settings ) @@ -113,18 +113,18 @@ def test_smart_spiral_first_few_pos(): that data is added correctly for the first few positions in a scan. It is intended to catch basic issues if the algorithm is updated. """ - intial_position = (100, 50) + initial_position = (100, 50) planner_settings = {"dx": 50, "dy": 50, "max_dist": 10000} # Create a planner planner = scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=planner_settings + initial_position=initial_position, planner_settings=planner_settings ) # it shouldn't start complete assert not planner.scan_complete - # When we start it should want to stay in the inital pos and have + # When we start it should want to stay in the initial pos and have # no z_estimate xy_pos1, z_pos1 = planner.get_next_location_and_z_estimate() - assert xy_pos1 == intial_position + assert xy_pos1 == initial_position assert z_pos1 is None # Set a focus value z_focus = 10 @@ -201,11 +201,11 @@ def test_smart_spiral_first_few_pos(): def test_smart_spiral_stops_on_max_dist(): """Test that if max distance is reached smart spiral really does stop.""" - intial_position = (0, 0) + initial_position = (0, 0) planner_settings = {"dx": 100, "dy": 100, "max_dist": 1000} # Create a planner planner = scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=planner_settings + initial_position=initial_position, planner_settings=planner_settings ) while not planner.scan_complete: xy_pos, _ = planner.get_next_location_and_z_estimate() @@ -219,11 +219,11 @@ def test_smart_spiral_stops_on_max_dist(): def test_mark_wrong_location(): """Check that an error is raised if a scan marks the wrong location as visited.""" - intial_position = (100, 50) + initial_position = (100, 50) planner_settings = {"dx": 50, "dy": 50, "max_dist": 10000} # Create a planner planner = scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=planner_settings + initial_position=initial_position, planner_settings=planner_settings ) xy_pos, _ = planner.get_next_location_and_z_estimate() @@ -233,18 +233,18 @@ def test_mark_wrong_location(): planner.mark_location_visited(wrong_xyz_pos, imaged=True, focused=True) -def test_closest_focus_wth_large_numbers(): +def test_closest_focus_with_large_numbers(): """Tests to check that everything works well with huge numbers of steps. The number of steps gets very large on the micorscope. But most of the tests above use smaller numbers for clarity. """ - intial_position = (0, 0) + initial_position = (0, 0) # Set this up, but we won't use the settings planner_settings = {"dx": 10000, "dy": 10000, "max_dist": 100000} # Create a planner planner = scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=planner_settings + initial_position=initial_position, planner_settings=planner_settings ) # Directly overwrite the private focussed locations list for test diff --git a/tests/test_smart_scan.py b/tests/test_smart_scan.py index a3271330..0ec1ae3f 100644 --- a/tests/test_smart_scan.py +++ b/tests/test_smart_scan.py @@ -65,7 +65,7 @@ def test_initial_properties(smart_scan_thing): def test_inaccessible_scan_methods(smart_scan_thing): """Test that method with @_scan_running decorator is inaccessible. - The @_scan_running decorator makes these functions inacessible unless + The @_scan_running decorator makes these functions inaccessible unless a scan is running. """ with pytest.raises(ScanNotRunningError): @@ -151,7 +151,7 @@ def test_delete_all_scans(smart_scan_thing, caplog): assert len(caplog.records) == 0 -def _run_only_outer_scan(adjust_inital_state: Optional[Callable] = None): +def _run_only_outer_scan(adjust_initial_state: Optional[Callable] = None): """Create a subclass of SmartScanThing to mock _run_scan and run sample_scan. This should do all the set up for a scan, move into the mocked @@ -199,8 +199,8 @@ def _run_only_outer_scan(adjust_inital_state: Optional[Callable] = None): # mock smart scan thing mock_ss_thing = MockedSmartScanThing(SCAN_DIR) - if adjust_inital_state is not None: - adjust_inital_state(mock_ss_thing) + if adjust_initial_state is not None: + adjust_initial_state(mock_ss_thing) exec_info = None try: @@ -232,7 +232,7 @@ def _run_only_outer_scan(adjust_inital_state: Optional[Callable] = None): assert mock_ss_thing._scan_images_taken is None # Return the mock thing for further state testing, and the - # exec_info of any uncaught exeptions that were raised + # exec_info of any uncaught exceptions that were raised return mock_ss_thing, exec_info diff --git a/tests/utilities/scan_test_helpers.py b/tests/utilities/scan_test_helpers.py index 2faf4253..8783e9f0 100644 --- a/tests/utilities/scan_test_helpers.py +++ b/tests/utilities/scan_test_helpers.py @@ -90,7 +90,7 @@ def interp_closed_path(xy_points: list[tuple[int, int]], n_points: int) -> MatPa Modified from: https://stackoverflow.com/questions/33962717/interpolating-a-closed-curve-using-scipy """ - # Use zip to seperate x and y points into tuples + # Use zip to separate x and y points into tuples x, y = zip(*xy_points) # Append first point and convert to array @@ -119,10 +119,10 @@ def example_smart_spiral( xy_sample_points = load_sample_points(sample_name) sample = FakeSample(xy_sample_points) img_size = (1000, 1000) - intial_position = (0, 0) + initial_position = (0, 0) planner_settings = {"dx": 1200, "dy": 800, "max_dist": 100000} planner = scan_planners.SmartSpiral( - intial_position=intial_position, planner_settings=planner_settings + initial_position=initial_position, planner_settings=planner_settings ) while not planner.scan_complete: diff --git a/webapp/src/main.js b/webapp/src/main.js index 2b6053ac..d49fbd5d 100644 --- a/webapp/src/main.js +++ b/webapp/src/main.js @@ -97,7 +97,7 @@ Vue.mixin({ } ) .finally(function() { - // Reenable the GPU preview, if it was active before the modal + // Re-enable the GPU preview, if it was active before the modal if (context.$store.state.autoGpuPreview) { context.$root.$emit("globalTogglePreview", true); }