Skip to content

Commit

Permalink
update for v1.20
Browse files Browse the repository at this point in the history
  • Loading branch information
hanjinliu committed Aug 9, 2021
1 parent 19cbfba commit d090a28
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 22 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ In `impy`, there are several ways to efficiently deal with large datasets. See [

Affine transformation, deconvolution and many filter functions are automatically conducted with GPU if accessible. On importing `impy`, it checks if `cupy` and GPU are correctly installed, so that you don't have to change your code. See [Image Analysis Tools](#image-analysis-tools) for details.

#### 8. Fit Your Function into GUI (WIP)
#### 8. Fit Your Function into GUI

In image analysis, you usually want to set parameters using manually drawn shapes or points. You don't have to do that by getting properties of the viewer for every function call. Just decorate your function with `@ip.gui.bind` and call function with keybind "F1". You can also plot on the figure canvas inside `napari`. See [Bind Your Function to Napari](#bind-your-function-to-napari) for an example.

Expand Down Expand Up @@ -331,7 +331,7 @@ See [documentation](https://hanjinliu.github.io/impy/) for details. `napari` is

The bottleneck of GUI is that it is difficult to make smooth interaction between the GUI and the scripts. What we want to do is, whenever we come up with any ideas, try it right away on GUI, without spending too much time on debugging GUI implementation.

Using `@ip.gui.bind` decorator, you can use your function as is to make your custom widget in `napari`. Here's an example of calculating the centroid of single molecule puncta around the cursor position.
Using `@ip.gui.bind` decorator, you can use your function "as is" to make your custom widget in `napari`. Here's an example of calculating the centroid of single molecule puncta around the cursor position.

```python
from skimage.measure import moments
Expand All @@ -355,4 +355,4 @@ def func(gui):

![](Figs/bind.gif)

All the properties in `ip.gui` are accessible from the first argument `gui`, and you can plot on the figure widget in `napari` via the second argument `ax`. All the results are appended in `ip.gui.results` so that you can analyze them afterward.
All the properties in `ip.gui` are accessible from the first argument `gui`, and you can plot on the figure widget in `napari` via `gui.ax`. All the results are appended in `ip.gui.results` so that you can analyze them afterward.
60 changes: 57 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,74 @@ or
git clone https://github.com/hanjinliu/impy
Major Classes
-------------

Contents
--------
Array
^^^^^

.. blockdiag::

blockdiag {
numpy.ndarray -> MetaArray -> HistoryArray -> LabeledArray -> ImgArray;
AxesMixin -> MetaArray;
MetaArray -> PropArray;
HistoryArray -> Label;
LabeledArray -> PhaseArray;

PropArray [color = pink];
Label [color = pink];
ImgArray [color = pink];
PhaseArray [color = pink];
}

- ``AxesMixin``: An abstract class that axes, scale and shape are defined.
- ``PropArray``: Array object with properties stored in it. Always made from an ``ImgArray``.
- ``Label``: Array object of image labels that is attached to ``ImgArray``.
- ``ImgArray``: Array object with many image processing functions.
- ``PhaseArray``: Array object with periodic values and specific processing functions.


Array-like
^^^^^^^^^^

.. blockdiag::

blockdiag {

AxesMixin -> LazyImgArray;

LazyImgArray [color = pink];
}

- ``LazyImgArray``: Array-like object with image processing functions like ``ImgArray``, but evaluated lazily.


Data Frame
^^^^^^^^^^

.. blockdiag::

blockdiag {

pandas.DataFrame -> AxesFrame -> MarkerFrame;
AxesFrame -> TrackFrame;
AxesFrame -> PathFrame;

MarkerFrame [color = pink];
TrackFrame [color = pink];
PathFrame [color = pink];
}

- ``AxesFrame``: DataFrame with similar properties as ``AxesMixin``.
- ``MarkerFrame``: ``AxesFrame`` for markers, such as coordinates.
- ``TrackFrame``: ``AxesFrame`` for tracks.
- ``PathFrame``: ``AxesFrame`` for paths.



Contents
--------

.. toctree::
:maxdepth: 1
Expand Down
18 changes: 11 additions & 7 deletions docs/tutorial_viewer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,18 @@ Functions Menu

There is a custom menu called "Functions" added in the menu bar.

- "Threshold/Label"
- "Threshold/Label": Make binary image or label an image with thresholded binary image by sweeping threshold
value.

- "Filters"
- "Filters": Run filter functions by sweeping the first parameter.

- "Measure Region Properties"
- "Measure Region Properties": Call ``regionprops`` and add the result as properties in ``Label`` layer.

- "Rectangle Editor"
- "Rectangle Editor": Edit selected rectangles pixelwise.

- "Template Matcher"
- "Template Matcher": Match a template layer to a reference layer.

- "Function Handler"
- "Function Handler": Call ``impy`` functions inside the viewer.

Others
------
Expand All @@ -176,7 +177,10 @@ Others
Fit Custom Functions into GUI
-----------------------------

``impy`` provides easier way to integrate your function to ``napari``.
In image analysis, you usually want to set parameters using manually drawn shapes or points. You don't have
to do that by getting properties of the viewer for every function call. ``impy`` provides easier way to integrate
your function to ``napari``. Just decorate your function with `@ip.gui.bind` and call function with keybind "F1".
You can also plot on the figure canvas inside `napari`.

*Example*: Fit filament tips to sigmoid function

Expand Down
2 changes: 1 addition & 1 deletion impy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.19.7"
__version__ = "1.20.0"

import logging
from ._const import Const, SetConst
Expand Down
28 changes: 20 additions & 8 deletions impy/viewer/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def change_theme(viewer):
viewer.theme = "night"

class napariViewers:

"""
The controller of ``napari.Viewer``s from ``impy``. Always access by ``ip.gui``.
"""
def __init__(self):
self._viewers = {}
self._front_viewer = None
Expand Down Expand Up @@ -74,7 +76,7 @@ def viewer(self):
@property
def layers(self):
"""
Napari layer list.
Napari layer list. Identical to ``ip.gui.viewer.layers``.
"""
return self.viewer.layers

Expand All @@ -100,21 +102,24 @@ def results(self):
return self.viewer.window.results

@property
def selection(self) -> list:
def selection(self) -> list[Any]:
"""
Return selected layers' data as impy objects.
Return selected layers' data as a list of impy objects.
"""
return [layer_to_impy_object(self.viewer, layer)
for layer in self.viewer.layers.selection]

@property
def axes(self) -> str:
"""
Axes information of current viewer. Defined to make compatible with ``ImgArray``.
"""
return "".join(self.viewer.dims.axis_labels)

@property
def scale(self) -> dict[str: float]:
"""
Dimension scales of the current viewer.
Scale information of current viewer. Defined to make compatible with ``ImgArray``.
"""
d = self.viewer.dims
return {a: r[2] for a, r in zip(d.axis_labels, d.range)}
Expand Down Expand Up @@ -156,6 +161,7 @@ def get(self, kind:str="image", layer_state:str="none", returns:str="last") -> A
----------
kind : str, optional
Kind of layers/shapes to return.
- "image": Image layer.
- "labels": Labels layer
- "points": Points layer.
Expand All @@ -166,13 +172,17 @@ def get(self, kind:str="image", layer_state:str="none", returns:str="last") -> A
- "path": Path shapes in Shapes layer.
- "polygon": Polygon shapes in Shapes layer.
- "ellipse": Ellipse shapes in Shapes layer.
layer_state : {"selected", "visible", "none"}, default is "none"
How to filter layer list.
- "selected": Only selected layers will be searched.
- "visible": Only visible layers will be searched.
- "none": All the layers will be searched.
returns : {"first", "last", "all"}
What will be returned in case that there are multiple layers/shapes.
- "first": Only the first object will be returned.
- "last": Only the last object will be returned.
- "all": All the objects will be returned as a list.
Expand Down Expand Up @@ -230,14 +240,16 @@ def get(self, kind:str="image", layer_state:str="none", returns:str="last") -> A
return out


def add(self, obj=None, title=None, **kwargs):
def add(self, obj:Any=None, title:str=None, **kwargs):
"""
Add images, points, labels, tracks etc to viewer.
Parameters
----------
obj : Any
Object to add.
title : str, optional
Title (key) of the viewer to add object(s).
"""
if title is None:
if self._front_viewer is None:
Expand Down Expand Up @@ -322,7 +334,7 @@ def preview(self, path:str, downsample_factor=4, dims=None, title=None, **kwargs
dims : str or int, optional
Axes along which values will be down-sampled.
title : str, optional
Title of the new viewer.
Title (key) of the viewer to add object(s).
"""
if title is None:
if self._front_viewer is None:
Expand Down Expand Up @@ -373,7 +385,7 @@ def add_surface(self, image3d:LabeledArray, level:float=None, step_size:int=1, m
self.viewer.add_surface((verts, faces, values), **kw)
return None

def bind(self, func=None, key="F1", progress:bool=False):
def bind(self, func=None, key:str="F1", progress:bool=False):
"""
Decorator that makes it easy to call custom function on the viewer. Every time "F1" is pushed,
``func(self)`` or `func(self, self.ax)` will be called. Returned values will appeded to
Expand Down

0 comments on commit d090a28

Please sign in to comment.