diff --git a/README.md b/README.md index e9f2216..d1ddc3a 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![tests](https://github.com/sommerc/napari-correct-drift/workflows/tests/badge.svg)](https://github.com/sommerc/napari-correct-drift/actions) [![codecov](https://codecov.io/gh/sommerc/napari-correct-drift/branch/main/graph/badge.svg)](https://codecov.io/gh/sommerc/napari-correct-drift) [![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-correct-drift)](https://napari-hub.org/plugins/napari-correct-drift) +[![Documentation Status](https://readthedocs.org/projects/napari-correct-drift/badge/?version=latest)](https://napari-correct-drift.readthedocs.io/en/latest/?badge=latest) Napari-correct-drift brings the functionality of Fiji’s popular Correct-3D-drift macro to Napari for flexible and efficient correction of stage and sample drift common in time-lapse microscopy. diff --git a/docs/requirements.txt b/docs/requirements.txt index 18b833b..9183d28 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -300,6 +300,9 @@ sphinx==4.5.0 sphinx-rtd-theme # via # myself +sphinx-autodoc-typehints + # via + # myself sphinxcontrib-applehelp==1.0.4 # via sphinx sphinxcontrib-devhelp==1.0.2 diff --git a/docs/source/api.rst b/docs/source/api.rst index 5c58d68..2521df6 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -1,5 +1,5 @@ API reference ============= -.. automodule:: napari_correct_drift._core +.. automodule:: napari_correct_drift :members: diff --git a/docs/source/conf.py b/docs/source/conf.py index 2f5bba1..2635179 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -41,6 +41,7 @@ extensions = [ "sphinx.ext.autodoc", + "sphinx_autodoc_typehints", "sphinx.ext.coverage", "sphinx.ext.napoleon", ] diff --git a/docs/source/index.rst b/docs/source/index.rst index d129d49..5963e3c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,13 +1,13 @@ Napari-Correct-Drift's doc ========================== -Fiji’s Correct-3D-drift macro for Napari +Fiji's Correct-3D-drift macro for Napari ---------------------------------------- In time-lapse imaging, a motorized microscope repeatedly captures images at specified positions for long periods. However, microscope stages exhibit *drift*, causing the sample to move, or to appear moving. The reasons are complex and manifold, but it typically results from error propagation in odometry, thermal expansion, and mechanical movement. Drift poses problems for subsequent image analysis and needs to be corrected. -With Napari-correct-drift provides an extensible solution with similar functionality as Fiji’s Correct-3D-drift macro. It offers efficient cross-correlation using Fourier phase correlationmethod, improved key frame selection, and outlier handling. In Napari users can provide a regions-of-interest (ROI) to effectively stabilize objects in up-to 3D-multi-channel images. Additionally, estimated drifts can be exported, imported, or edited before applying the correction. +With Napari-correct-drift provides an extensible solution with similar functionality as Fiji's Correct-3D-drift macro. It offers efficient cross-correlation using Fourier phase correlation method, improved key frame selection, and outlier handling. In Napari users can provide a regions-of-interest (ROI) to effectively stabilize objects in up-to 3D-multi-channel images. Additionally, estimated drifts can be exported, imported, or edited before applying the correction. When to use this plugin ----------------------- @@ -34,6 +34,15 @@ Napari-Correct-Drift can also be used without starting the Napari viewer. # correct drift img_cor = cd.apply_drifts(drifts) +With Napari viewer (using ROI) +-------------------------------------- +Stabilizing an growing `root-tip `_ using an ROI. + +.. raw:: html + + + + Test data --------- diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 19549b6..2998a5b 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -1,16 +1,9 @@ Introduction ============ -Example -------- -Let's start with an example of an growing `root-tip `_ imaged in a vertical microscope: - -.. raw:: html - - - Main widget ----------- + The main widget is structured in several groups: .. image:: _static/widget_02.png @@ -36,16 +29,60 @@ Run Napari-Correct-Drift using the set parameters. One can **Estimate Drift** or Select **Correct Drift** to apply the drifts from the table widget to your image data. A new image layer containing the corrected image will be created. -One can follow the progress of the estimation and the correctiong step in the Napari notifications. +One can follow the progress of the estimation and the correction step in the Napari *notifications* panel. Key Frames ^^^^^^^^^^ +* **Relative to:** + Choose *previous frame* to estimate drift on consecutive frames or *absolute frame* when using an absolute reference frame: + + Mode for drift estimation: + + 1. previous frame: estimate from previous frame. (ROI will move along!) + 2. absolute frame: estimate against absolute frame + +* **Key frame:** + The frame index to use. Note, when computing the drifts relative to *previous frame*, the key frame will be the frame with zero drifts applied. When **Use ROI** is enabled, the value is inferred from the ROI. + +* **Key channel:** + Channel index to use for the drift computation. When **Use ROI** is enabled, the value is inferred from the ROI. + +* **Use ROI:** + When enabled Napari-Correct-Drift expects an ROI in a shape layer named *ROI*. If such a layer is not yet present, it will be automatically created. Add an ROI (e. g. Rectangle shape) at desired channel and key frame. + +* **ROI z-min** and **ROI z-max:** + Minimum and maximum z-slice indecies for 3D-bounding box Parameters ^^^^^^^^^^ +* **Increment** + Frame increment step for drift estimation. Useful for faster processing and slow drifts. Skipped frames will be linearly interpolated. +* **Upsample factor** + Subpixel accurate drift estimation. Images will be registered to within 1 / *upsample_factor* of a pixel. Useful for slow drifts. + +* **Extend output** + Correct drifts with extended spatial dimensions. The raw image frames will be fully contained in the output + +* **Use phase normalization** + Phase normalization (recommended) works well in registering images under different illumination . In a high noise scenario, the un-normalized method may be preferable. + Outliers ^^^^^^^^ +* **Remove & Interpolate** + Remove large shifts in consecutive time frames (in mode *previous frame*) and linearly interpolate from other time points. + +* **Max shift Z,Y,Z** + Maximum relative shift allowed in X,Y, or Z. If estimated shift exceeds set value the exceeding shift is removed and linearly interpolated (in pixel). Table Widget ------------ +The Table Widget will display a table of estimated or loaded drifts. It contains 4 columns: frame, Z, Y, X. For 2D images Z will always contain 0. + +**Note**, the displayed drifts can be edited by clicking into a cell. + +* **Copy to clipboard** + Copy the drift table to your system clipboard + +* **Save as csv** + Create a comma separated value file (.csv) containing the drift values. diff --git a/src/napari_correct_drift/_core.py b/src/napari_correct_drift/_core.py index 7d4e779..078d7e7 100644 --- a/src/napari_correct_drift/_core.py +++ b/src/napari_correct_drift/_core.py @@ -9,53 +9,14 @@ class ArrayAxesStandardizer: - """ - A class designed to standardize the axes of numpy arrays. + """A class designed to standardize the axes of numpy arrays. Attributes: - out_order (str): string representing the desired output - order of the array axes in_order (str): string representing - the current order of the array axes - - out_order and in_order are given as string containing - t,c,z,y,x - - Methods: - __init__(self, out_order: str, in_order: str): - Initializes the class and checks for any invalid inputs. - - _check_order_str(self, order: str): - Checks for any duplicates in the input order. - - __call__(self, data: np.array): - Takes in an input numpy array and standardizes the - axes according to the output order. - It returns the standardized array view. - - inv(self, data: np.array): - Takes in a standardized numpy array and reverts the - axes back to the original order. - It returns the reverted array. - - inverse_permutation(a): - A static method that returns the inverse permutation - of an input permutation. - - Parameters: - out_order (str): a string representing the desired output - order of the array axes. - in_order (str): a string representing the current order - of the array axes. - data (np.array): a numpy array that needs to be - standardized or reverted. - a (np.array): an input permutation. - - Return Value: - __call__(self, data: np.array): A standardized numpy array. - inv(self, data: np.array): A numpy array with the original - axis order. - inverse_permutation(a): An inverse permutation of the input - permutation. + out_order (str): A string representing the desired output + order of the array axes. + in_order (str): A string representing the current order of + the array axes. + """ def __init__(self, out_order: str, in_order: str): @@ -64,13 +25,13 @@ def __init__(self, out_order: str, in_order: str): Args: out_order (str): A string representing the desired output - order of the array axes. + order of the array axes. in_order (str): A string representing the current order of - the array axes. + the array axes. Raises: AssertionError: If in_order contains any elements not in - out_order or if out_order or in_order contains duplicates. + out_order or if out_order or in_order contains duplicates. """ self._check_order_str(out_order) self._check_order_str(in_order) @@ -83,16 +44,6 @@ def __init__(self, out_order: str, in_order: str): self.in_order = in_order def _check_order_str(self, order: str): - """ - Checks for any duplicates in the input order. - - Args: - order (str): A string representing the current order of - the array axes. - - Raises: - AssertionError: If order contains duplicates. - """ assert len(set(order)) == len( order ), f"Duplicates in order found: '{order}'" @@ -171,7 +122,18 @@ def inverse_permutation(a): class ROIRect: - """Helper classes for 3D bounding-box, localized in channels and time""" + """Helper classes for 3D bounding-box, localized in channels and time + + Args: + x_min (int): x min + x_max (int): x max + y_min (int): y min + y_max (int): y max + z_min (int): z min + z_max (int): z max + t0 (int): frame index + c0 (int): channel index + """ def __init__( self, @@ -184,18 +146,6 @@ def __init__( t0: int, c0: int, ): - """_summary_ - - Args: - x_min (int): x min - x_max (int): x max - y_min (int): y min - y_max (int): y max - z_min (int): z min - z_max (int): z max - t0 (int): frame index - c0 (int): channel index - """ self.x_min = x_min self.x_max = x_max