class documentation

class SmartScanThing(lt.Thing): (source)

Constructor: SmartScanThing(scans_folder)

View In Hierarchy

A Thing for scanning samples and interacting with past scans.

SmartScanThing exposes all functionality for automatically scanning samples, previewing live stitching, retrieving data from past scans, and for deleting past scans.

Method __init__ Initialise a SmartScanThing saving to and loading from the input directory.
Method delete_all_scans Delete all the scans on the microscope.
Method delete_scan Delete the folder for the specified scan.
Method download_zip Return zip after including any files left until the end.
Method get_latest_preview Retrieve the latest preview image.
Method get_scan_thumbnail Retrieve a file from a scan.
Method get_stitch_file Return the stitched image corresponding to a given scan name, if it exists.
Method purge_empty_scans Delete all scan folders containing no images at the top level.
Method sample_scan Move the stage to cover an area, taking images that can be tiled together.
Method stitch_all_scans Check the list of scans, and stitch any that don't have a DZI associated with it.
Method stitch_scan Generate a stitched image based on stage position metadata.
Class Variable autofocus_dz The z distance to perform an autofocus in steps.
Class Variable max_range The maximum distance in steps from the centre of the scan.
Class Variable overlap The fraction (0-1) that adjacent images should overlap in x or y.
Class Variable save_resolution A tuple of the image resolution to capture.
Class Variable skip_background Whether to detect and skip empty fields of view.
Class Variable stitch_automatically Whether to run a final stitch at the end of a successful scan.
Class Variable stitch_tiff Whether or not to also produce a pyramidal tiff at the end of a scan.
Property latest_preview_stitch_path The path of the latest preview stitched image, or None if not available.
Property latest_preview_stitch_time The modification time of the latest preview image, to allow live updating.
Property latest_scan_name The name of the last scan to be started.
Property scans All the available scans.
Method _calc_displacement_from_test_image Take a test image and use camera stage mapping to calculate x and y displacement.
Method _check_background_and_csm_set Before starting a scan, check that background and camera-stage-mapping are set.
Method _collect_scan_data Collect and return the data for this scan so it cannot be changed mid-scan.
Method _delete_scan Delete a scan.
Method _main_scan_loop Run the main loop of the scan.
Method _manage_stitching_threads Manage the stitching threads, starting them if needed and not already running.
Method _move_to_next_point Move the stage to the next position.
Method _perform_final_stitch Update the scan zip and perform final stitch of the data.
Method _return_to_starting_position Return to the initial scan position, if set.
Method _run_scan Prepare and run the main scan, and perform final actions on completion.
Method _save_final_scan_data Update scan data JSON file with data only known at the end of the scan.
Instance Variable _autofocus Undocumented
Instance Variable _cam Undocumented
Instance Variable _cancel Undocumented
Instance Variable _csm Undocumented
Instance Variable _latest_scan_name Undocumented
Instance Variable _ongoing_scan Undocumented
Instance Variable _preview_stitcher Undocumented
Instance Variable _scan_data Undocumented
Instance Variable _scan_dir_manager Undocumented
Instance Variable _scan_lock Undocumented
Instance Variable _scan_logger Undocumented
Instance Variable _stage Undocumented
def __init__(self, scans_folder: str): (source)

Initialise a SmartScanThing saving to and loading from the input directory.

Parameters
scans_folder:strThis is the path to the directory where all scans will be saved. Any scans already in this directory will be accessible through the HTTP interface.
@lt.fastapi_endpoint('delete', 'scans')
def delete_all_scans(self, logger: lt.deps.InvocationLogger): (source)

Delete all the scans on the microscope.

This will irreversibly remove all scanned data from the microscope! Use with extreme caution.

@lt.fastapi_endpoint('delete', 'scans/{scan_name}', responses={200: {'description': 'Successfully deleted scan'}, 400: {'description': 'An error occurred while trying to delete scan'}})
def delete_scan(self, scan_name: str, logger: lt.deps.InvocationLogger): (source)

Delete the folder for the specified scan.

This endpoint allows scans to be deleted from disk.

Takes the scan name to delete, and the Invocation Logger

@lt.thing_action
def download_zip(self, scan_name: str): (source)

Return zip after including any files left until the end.

The zipfile is returned as a Blob.

@lt.fastapi_endpoint('get', 'latest_preview_stitch.jpg', responses={200: {'description': 'A preview-quality stitched image', 'content': {'image/jpeg': {}}}, 404: {'description': 'File not found'}})
def get_latest_preview(self) -> FileResponse: (source)

Retrieve the latest preview image.

@lt.fastapi_endpoint('get', 'scans/stitched_thumbnail.jpg', responses={200: {'description': 'A thumbnail-quality stitched image', 'content': {'image/jpeg': {}}}, 404: {'description': 'File not found'}})
def get_scan_thumbnail(self, scan_name: str) -> FileResponse: (source)

Retrieve a file from a scan.

This endpoint allows files to be downloaded from a scan.

@lt.fastapi_endpoint('get', 'get_stitch/{scan_name}', responses={200: {'description': 'Successfully downloading file', 'content': {'*/*': {}}}, 403: {'description': 'Filename not permitted'}, 404: {'description': 'File not found'}})
def get_stitch_file(self, scan_name: str) -> FileResponse: (source)

Return the stitched image corresponding to a given scan name, if it exists.

Will only return a file ending in suffix STITCH_SUFFIX Note: when downloading this, the default filename will be scan_name.jpeg

@lt.thing_action
def purge_empty_scans(self, logger: lt.deps.InvocationLogger): (source)

Delete all scan folders containing no images at the top level.

@lt.thing_action
def sample_scan(self, cancel: lt.deps.CancelHook, logger: lt.deps.InvocationLogger, autofocus: AutofocusDep, stage: StageDep, cam: CameraClient, csm: CSMDep, scan_name: str = ''): (source)

Move the stage to cover an area, taking images that can be tiled together.

The stage will move in a pattern that grows outwards from the starting point, stopping once it is surrounded by "background" (as detected by the camera Thing) or reaches the "max_range" measured in steps.

@lt.thing_action
def stitch_all_scans(self, logger: lt.deps.InvocationLogger, cancel: lt.deps.CancelHook): (source)

Check the list of scans, and stitch any that don't have a DZI associated with it.

Raises
RuntimeErrorif the microscope is currently running a scan
@lt.thing_action
def stitch_scan(self, logger: lt.deps.InvocationLogger, cancel: lt.deps.CancelHook, scan_name: str, correlation_resize: float | None = None, overlap: float | None = None): (source)

Generate a stitched image based on stage position metadata.

Note that as this is a lt.thing_action it needs the logger passed as a variable if called from another thing action

autofocus_dz = (source)

The z distance to perform an autofocus in steps.

max_range = (source)

The maximum distance in steps from the centre of the scan.

The fraction (0-1) that adjacent images should overlap in x or y.

save_resolution = (source)

A tuple of the image resolution to capture.

skip_background = (source)

Whether to detect and skip empty fields of view.

This uses the settings from the BackgroundDetectThing.

stitch_automatically = (source)

Whether to run a final stitch at the end of a successful scan.

stitch_tiff = (source)

Whether or not to also produce a pyramidal tiff at the end of a scan.

@property
latest_preview_stitch_path: str | None = (source)

The path of the latest preview stitched image, or None if not available.

@lt.thing_property
latest_preview_stitch_time: float | None = (source)

The modification time of the latest preview image, to allow live updating.

This will return None (null to JS) if there is no preview image to return.

This is used for two reasons:

  1. If all caching was turned off this stitch would be sent over the network repeatedly
  2. If caching was is on, then the stitch will not update when needed.
@lt.thing_property
latest_scan_name: str | None = (source)

The name of the last scan to be started.

@lt.thing_property
scans: list[scan_directories.ScanInfo] = (source)

All the available scans.

Each scan has a name (which can be used to access it), along with its modified and created times (according to the filesystem) and the number of items in the images folder. Note that image count uses a regular expression, and changes to the naming scheme will break it.

def _calc_displacement_from_test_image(self, overlap: int) -> tuple[int, int]: (source)

Take a test image and use camera stage mapping to calculate x and y displacement.

Parameters
overlap:intThe desired overlap as a fraction of the image. i.e. 0.5 means that each image should overlap its nearest neighbour by 50%.
Returns
tuple[int, int](dx, dy) - the x and y displacements in steps
def _check_background_and_csm_set(self): (source)

Before starting a scan, check that background and camera-stage-mapping are set.

Raise error if:
  • background is to be skipped but is not set
  • camera stage mapping is not set

Raise warning if not using background detect that scan will go on until max steps reached

def _collect_scan_data(self) -> scan_directories.ScanData: (source)

Collect and return the data for this scan so it cannot be changed mid-scan.

def _delete_scan(self, scan_name, logger: lt.deps.InvocationLogger) -> bool: (source)

Delete a scan.

This is a wrapper around scan manager's delete_scan that logs to the invocation logger id there is a problem.

def _main_scan_loop(self): (source)

Run the main loop of the scan.

This loop runs during a scan, until no more scan x,y positions are remaining.

def _manage_stitching_threads(self): (source)

Manage the stitching threads, starting them if needed and not already running.

def _move_to_next_point(self, next_point: tuple[int, int], z_estimate: int | None = None) -> tuple[int, int, int]: (source)

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 faster) because background detect is most reliable at the focused position.

Returns
tuple[int, int, int]the (x,y,z) with the chosen z_estimate
def _perform_final_stitch(self): (source)

Update the scan zip and perform final stitch of the data.

def _return_to_starting_position(self): (source)

Return to the initial scan position, if set.

def _run_scan(self): (source)

Prepare and run the main scan, and perform final actions on completion.

The result (or exception) from the main scan loop determines whether the scan should be stitched and whether the microscope should return to the starting x,y,z position.

def _save_final_scan_data(self, scan_result: str): (source)

Update scan data JSON file with data only known at the end of the scan.

Takes scan_result, a string that is either "success", "cancelled by user", or the error that ended the scan.

_autofocus: AutofocusDep | None = (source)

Undocumented

Undocumented

_cancel: lt.deps.CancelHook | None = (source)

Undocumented

_csm: CSMDep | None = (source)

Undocumented

_latest_scan_name: str | None = (source)

Undocumented

Undocumented

_preview_stitcher: stitching.PreviewStitcher | None = (source)

Undocumented

Undocumented

_scan_dir_manager = (source)

Undocumented

_scan_lock = (source)

Undocumented

_scan_logger: lt.deps.InvocationLogger | None = (source)

Undocumented

_stage: StageDep | None = (source)

Undocumented