impy-array 2.5.2__tar.gz → 2.5.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {impy_array-2.5.2 → impy_array-2.5.3}/PKG-INFO +1 -1
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/__init__.py +1 -1
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/array_api.py +2 -2
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_corr.py +3 -3
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_zarr.py +2 -4
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/viewer/utils.py +13 -16
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/viewer/viewer.py +107 -109
- {impy_array-2.5.2 → impy_array-2.5.3}/.gitignore +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/LICENSE +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/README.md +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/__main__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/_const.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/_types.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_imshow.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_deconv.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_docs.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_filters.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_glcm.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_linalg.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_misc.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_plot.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_process_numba.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_skimage.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_structures.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/_utils/_transform.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/axesmixin.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/bases/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/bases/metaarray.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/bases/overload.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/big.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/imgarray.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/label.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/labeledarray.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/lazy.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/phasearray.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/specials.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/arrays/tiled.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/axes/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/axes/_axes.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/axes/_axes_tuple.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/axes/_axis.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/axes/_slicer.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/binder.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/collections.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/core.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/correlation.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/frame/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/frame/frames.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_czi.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_mrc.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_nd2.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_npy.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_registry.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_tiff.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/io/_utils.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/lazy/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/lazy/core.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/lazy/random.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/random.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/roi.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/utils/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/utils/axesop.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/utils/deco.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/utils/gauss.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/utils/misc.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/utils/slicer.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/utils/utilcls.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/impy/viewer/__init__.py +0 -0
- {impy_array-2.5.2 → impy_array-2.5.3}/pyproject.toml +0 -0
|
@@ -97,7 +97,7 @@ class XP:
|
|
|
97
97
|
self.angle = np.angle
|
|
98
98
|
self.abs = np.abs
|
|
99
99
|
self.mod = np.mod
|
|
100
|
-
self.
|
|
100
|
+
self.trunc = np.trunc
|
|
101
101
|
self.round = np.round
|
|
102
102
|
self.gradient = np.gradient
|
|
103
103
|
self.tensordot = np.tensordot
|
|
@@ -165,7 +165,7 @@ class XP:
|
|
|
165
165
|
self.angle = cp.angle
|
|
166
166
|
self.abs = cp.abs
|
|
167
167
|
self.mod = cp.mod
|
|
168
|
-
self.
|
|
168
|
+
self.trunc = cp.trunc
|
|
169
169
|
self.round = cp.round
|
|
170
170
|
try:
|
|
171
171
|
self.gradient = cp.gradient
|
|
@@ -38,16 +38,16 @@ def subpixel_pcc(
|
|
|
38
38
|
):
|
|
39
39
|
power, product = _pcc_and_power_spec(f0, f1, max_shifts)
|
|
40
40
|
maxima = xp.unravel_index(xp.argmax(power), power.shape)
|
|
41
|
-
midpoints = xp.array([np.
|
|
41
|
+
midpoints = xp.array([np.trunc(axis_size / 2) for axis_size in power.shape])
|
|
42
42
|
|
|
43
43
|
shifts = xp.asarray(maxima, dtype=np.float32)
|
|
44
44
|
shifts[shifts > midpoints] -= xp.array(power.shape)[shifts > midpoints]
|
|
45
45
|
# Initial shift estimate in upsampled grid
|
|
46
|
-
shifts = xp.
|
|
46
|
+
shifts = xp.trunc(shifts * upsample_factor) / upsample_factor
|
|
47
47
|
if upsample_factor > 1:
|
|
48
48
|
upsampled_region_size = np.ceil(upsample_factor * 1.5)
|
|
49
49
|
# Center of output array at dftshift + 1
|
|
50
|
-
dftshift = xp.
|
|
50
|
+
dftshift = xp.trunc(upsampled_region_size / 2.0)
|
|
51
51
|
upsample_factor = xp.array(upsample_factor, dtype=np.float32)
|
|
52
52
|
# Matrix multiply DFT around the current shift estimate
|
|
53
53
|
sample_region_offset = dftshift - shifts*upsample_factor
|
|
@@ -5,8 +5,6 @@ import numpy as np
|
|
|
5
5
|
from impy.io._registry import IO
|
|
6
6
|
from impy.io._utils import get_channel_labels, ImpyArray, ImageData
|
|
7
7
|
|
|
8
|
-
from impy.axes import ImageAxesError
|
|
9
|
-
|
|
10
8
|
|
|
11
9
|
@IO.mark_reader(".zarr")
|
|
12
10
|
def _(path: str, memmap: bool = False) -> ImageData:
|
|
@@ -32,6 +30,7 @@ def _(path: str, memmap: bool = False) -> ImageData:
|
|
|
32
30
|
def _(path: str, img: ImpyArray, lazy: bool = False):
|
|
33
31
|
"""The zarr writer."""
|
|
34
32
|
import zarr
|
|
33
|
+
from dask import array as da
|
|
35
34
|
|
|
36
35
|
f = zarr.open(path, mode="w")
|
|
37
36
|
metadata = img.metadata.copy()
|
|
@@ -44,6 +43,5 @@ def _(path: str, img: ImpyArray, lazy: bool = False):
|
|
|
44
43
|
if lazy:
|
|
45
44
|
img.value.to_zarr(url=os.path.join(path, "data"))
|
|
46
45
|
else:
|
|
47
|
-
|
|
48
|
-
f.array("data", z)
|
|
46
|
+
da.from_array(img.value).to_zarr(url=os.path.join(path, "data"))
|
|
49
47
|
return None
|
|
@@ -127,19 +127,10 @@ def add_labeledarray(viewer: napari.Viewer, img: LabeledArray, **kwargs):
|
|
|
127
127
|
channel_axis=chn_ax,
|
|
128
128
|
scale=scale,
|
|
129
129
|
name=name if len(name) > 1 else name[0],
|
|
130
|
+
units=[a.unit for a in img.axes],
|
|
130
131
|
**kwargs
|
|
131
132
|
)
|
|
132
133
|
|
|
133
|
-
if viewer.scale_bar.unit:
|
|
134
|
-
if viewer.scale_bar.unit != img.scale_unit:
|
|
135
|
-
msg = (
|
|
136
|
-
f"Incompatible scales. Viewer is {viewer.scale_bar.unit} while "
|
|
137
|
-
f"image is {img.scale_unit}."
|
|
138
|
-
)
|
|
139
|
-
warnings.warn(msg)
|
|
140
|
-
else:
|
|
141
|
-
viewer.scale_bar.unit = img.scale_unit
|
|
142
|
-
|
|
143
134
|
new_axes = [str(a) for a in img.axes if a != "c"]
|
|
144
135
|
# add axis labels to slide bars and image orientation.
|
|
145
136
|
if len(new_axes) >= len(viewer.dims.axis_labels):
|
|
@@ -173,7 +164,7 @@ def add_labels(
|
|
|
173
164
|
|
|
174
165
|
out_layers = []
|
|
175
166
|
for lbl, name in zip(lbls, names):
|
|
176
|
-
layer = viewer.add_labels(lbl.value, name=name, **kw)
|
|
167
|
+
layer = viewer.add_labels(lbl.value, name=name, units=[a.unit for a in lbl.axes], **kw)
|
|
177
168
|
out_layers.append(layer)
|
|
178
169
|
return out_layers
|
|
179
170
|
|
|
@@ -188,17 +179,23 @@ def add_dask(viewer: napari.Viewer, img: LazyImgArray, **kwargs):
|
|
|
188
179
|
else:
|
|
189
180
|
name = ["[Lazy]" + name]
|
|
190
181
|
|
|
191
|
-
layer = viewer.add_image(
|
|
192
|
-
|
|
193
|
-
|
|
182
|
+
layer = viewer.add_image(
|
|
183
|
+
img,
|
|
184
|
+
channel_axis=chn_ax,
|
|
185
|
+
scale=scale,
|
|
186
|
+
name=name if len(name)>1 else name[0],
|
|
187
|
+
units=[a.unit for a in img.axes],
|
|
188
|
+
**kwargs
|
|
189
|
+
)
|
|
194
190
|
new_axes = [str(a) for a in img.axes if a != "c"]
|
|
195
191
|
# add axis labels to slide bars and image orientation.
|
|
196
192
|
if len(new_axes) >= len(viewer.dims.axis_labels):
|
|
197
193
|
viewer.dims.axis_labels = new_axes
|
|
198
194
|
return layer
|
|
199
195
|
|
|
200
|
-
def add_points(viewer:napari.Viewer, points: AxesFrame, **kwargs):
|
|
196
|
+
def add_points(viewer: napari.Viewer, points: AxesFrame, **kwargs):
|
|
201
197
|
from ..frame import MarkerFrame
|
|
198
|
+
|
|
202
199
|
if isinstance(points, MarkerFrame):
|
|
203
200
|
scale = make_world_scale(points)
|
|
204
201
|
points = points.get_coords()
|
|
@@ -382,4 +379,4 @@ class ComplexArrayView:
|
|
|
382
379
|
return self._data.nbytes
|
|
383
380
|
|
|
384
381
|
def __getitem__(self, key):
|
|
385
|
-
return self.__class__(self._data[key])
|
|
382
|
+
return self.__class__(self._data[key])
|
|
@@ -8,7 +8,7 @@ import numpy as np
|
|
|
8
8
|
|
|
9
9
|
from .utils import (
|
|
10
10
|
layer_to_impy_object,
|
|
11
|
-
add_dask,
|
|
11
|
+
add_dask,
|
|
12
12
|
add_labeledarray,
|
|
13
13
|
add_labels,
|
|
14
14
|
add_paths,
|
|
@@ -31,8 +31,8 @@ if TYPE_CHECKING:
|
|
|
31
31
|
import pandas as pd
|
|
32
32
|
from numpy.typing import ArrayLike
|
|
33
33
|
|
|
34
|
-
# TODO:
|
|
35
|
-
# - Layer does not remember the original data after c-split ... this will be solved after
|
|
34
|
+
# TODO:
|
|
35
|
+
# - Layer does not remember the original data after c-split ... this will be solved after
|
|
36
36
|
# layer group is implemented in napari.
|
|
37
37
|
# - channel axis will be dropped in the future: https://github.com/napari/napari/issues/3019
|
|
38
38
|
|
|
@@ -41,16 +41,16 @@ ImpyObject = NewType("ImpyObject", Any)
|
|
|
41
41
|
class napariViewers:
|
|
42
42
|
"""
|
|
43
43
|
The controller of ``napari.Viewer``s from ``impy``. Always access by ``ip.gui``.
|
|
44
|
-
"""
|
|
44
|
+
"""
|
|
45
45
|
def __init__(self):
|
|
46
|
-
self._viewers: WeakValueDictionary[str,
|
|
46
|
+
self._viewers: WeakValueDictionary[str, napari.Viewer] = WeakValueDictionary()
|
|
47
47
|
self._front_viewer: str = None
|
|
48
48
|
self._axes: Axes = None
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
def __repr__(self):
|
|
51
51
|
w = "".join([f"<{k}>" for k in self._viewers.keys()])
|
|
52
52
|
return f"{self.__class__}{w}"
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
def __getitem__(self, key: str) -> napariViewers:
|
|
55
55
|
"""
|
|
56
56
|
This method looks strange but intuitive because you can access the last viewer by
|
|
@@ -62,33 +62,33 @@ class napariViewers:
|
|
|
62
62
|
----------
|
|
63
63
|
key : str
|
|
64
64
|
Viewer's title
|
|
65
|
-
"""
|
|
65
|
+
"""
|
|
66
66
|
if key in self._viewers.keys():
|
|
67
67
|
self._front_viewer = key
|
|
68
68
|
else:
|
|
69
69
|
self.start(key)
|
|
70
70
|
return self
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
@property
|
|
73
|
-
def viewer(self) ->
|
|
73
|
+
def viewer(self) -> napari.Viewer:
|
|
74
74
|
"""The most front viewer you're using"""
|
|
75
75
|
if self._front_viewer not in self._viewers.keys():
|
|
76
76
|
self.start()
|
|
77
77
|
return self._viewers[self._front_viewer]
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
@property
|
|
80
|
-
def layers(self) ->
|
|
81
|
-
"""Napari layer list. Identical to ``ip.gui.viewer.layers``."""
|
|
80
|
+
def layers(self) -> LayerList:
|
|
81
|
+
"""Napari layer list. Identical to ``ip.gui.viewer.layers``."""
|
|
82
82
|
return self.viewer.layers
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
@property
|
|
85
85
|
def current_slice(self) -> tuple[slice | int, ...]:
|
|
86
86
|
"""
|
|
87
|
-
Return a tuple of slicer that corresponds to current field of view.
|
|
88
|
-
|
|
89
|
-
For instance, when the viewer is displaying yx-plane at t=1, then this property
|
|
87
|
+
Return a tuple of slicer that corresponds to current field of view.
|
|
88
|
+
|
|
89
|
+
For instance, when the viewer is displaying yx-plane at t=1, then this property
|
|
90
90
|
returns ``(1, slice(None), slice(None))``.
|
|
91
|
-
"""
|
|
91
|
+
"""
|
|
92
92
|
current_step = list(self.viewer.dims.current_step)
|
|
93
93
|
ndim = min(self.viewer.dims.ndisplay, self.viewer.dims.ndim)
|
|
94
94
|
active_plane = list(self.viewer.dims.order[-ndim:])
|
|
@@ -96,60 +96,58 @@ class napariViewers:
|
|
|
96
96
|
current_step[i] = slice(None)
|
|
97
97
|
return tuple(current_step)
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
@property
|
|
101
101
|
def selection(self) -> list[ImpyObject]:
|
|
102
|
-
"""Return selected layers' data as a list of impy objects."""
|
|
103
|
-
return [layer_to_impy_object(self.viewer, layer)
|
|
102
|
+
"""Return selected layers' data as a list of impy objects."""
|
|
103
|
+
return [layer_to_impy_object(self.viewer, layer)
|
|
104
104
|
for layer in self.viewer.layers.selection]
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
@property
|
|
107
107
|
def cursor_pos(self) -> np.ndarray:
|
|
108
108
|
"""Return cursor position. Scale is considered."""
|
|
109
109
|
return np.array(self.viewer.cursor.position) / self.scale
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
@property
|
|
112
112
|
def axes(self) -> Axes:
|
|
113
113
|
"""
|
|
114
|
-
Axes information of current viewer.
|
|
115
|
-
|
|
114
|
+
Axes information of current viewer.
|
|
115
|
+
|
|
116
116
|
Defined to make compatible with ``ImgArray``.
|
|
117
117
|
"""
|
|
118
118
|
d = self.viewer.dims
|
|
119
|
-
unit = self.viewer.scale_bar.unit
|
|
120
119
|
axes: list[Axis] = []
|
|
121
120
|
for a, r in zip(d.axis_labels, d.range):
|
|
122
121
|
if a in ["z", "y", "x"]:
|
|
123
|
-
axis = Axis(a, {"scale": r[2]
|
|
122
|
+
axis = Axis(a, {"scale": r[2]})
|
|
124
123
|
else:
|
|
125
124
|
axis = Axis(a)
|
|
126
125
|
axes.append(axis)
|
|
127
126
|
self._axes = Axes(axes) # because scale-view uses a weakref
|
|
128
127
|
return self._axes
|
|
129
|
-
|
|
128
|
+
|
|
130
129
|
@property
|
|
131
130
|
def scale(self) -> ScaleView:
|
|
132
|
-
"""
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
"""Scale information of current viewer.
|
|
132
|
+
|
|
135
133
|
Defined to make compatible with ``ImgArray``.
|
|
136
|
-
"""
|
|
134
|
+
"""
|
|
137
135
|
return self.axes.scale
|
|
138
|
-
|
|
136
|
+
|
|
139
137
|
def start(self, key: str = "impy"):
|
|
140
138
|
"""Create a napari window with name ``key``."""
|
|
141
139
|
if not isinstance(key, str):
|
|
142
140
|
raise TypeError("`key` must be str.")
|
|
143
141
|
if key in self._viewers.keys():
|
|
144
142
|
raise ValueError(f"Key {key} already exists.")
|
|
145
|
-
|
|
143
|
+
|
|
146
144
|
viewer = napari.Viewer(title=key)
|
|
147
145
|
self._viewers[key] = viewer
|
|
148
146
|
self._front_viewer = key
|
|
149
147
|
return None
|
|
150
148
|
|
|
151
149
|
def get(
|
|
152
|
-
self,
|
|
150
|
+
self,
|
|
153
151
|
kind: str = "image",
|
|
154
152
|
layer_state: str = "visible",
|
|
155
153
|
returns: str = "last"
|
|
@@ -161,7 +159,7 @@ class napariViewers:
|
|
|
161
159
|
----------
|
|
162
160
|
kind : str, optional
|
|
163
161
|
Kind of layers/shapes to return.
|
|
164
|
-
|
|
162
|
+
|
|
165
163
|
- "image": Image layer.
|
|
166
164
|
- "labels": Labels layer
|
|
167
165
|
- "points": Points layer.
|
|
@@ -174,41 +172,41 @@ class napariViewers:
|
|
|
174
172
|
- "path": Path shapes in Shapes layer.
|
|
175
173
|
- "polygon": Polygon shapes in Shapes layer.
|
|
176
174
|
- "ellipse": Ellipse shapes in Shapes layer.
|
|
177
|
-
|
|
175
|
+
|
|
178
176
|
layer_state : {"selected", "visible", "any"}, default is "any"
|
|
179
177
|
How to filter layer list.
|
|
180
|
-
|
|
178
|
+
|
|
181
179
|
- "selected": Only selected layers will be searched.
|
|
182
180
|
- "visible": Only visible layers will be searched.
|
|
183
|
-
- "any": All the layers will be searched.
|
|
184
|
-
|
|
181
|
+
- "any": All the layers will be searched.
|
|
182
|
+
|
|
185
183
|
returns : {"first", "last", "all"}
|
|
186
184
|
What will be returned in case that there are multiple layers/shapes.
|
|
187
|
-
|
|
185
|
+
|
|
188
186
|
- "first": Only the first object will be returned.
|
|
189
187
|
- "last": Only the last object will be returned.
|
|
190
188
|
- "all": All the objects will be returned as a list.
|
|
191
|
-
|
|
189
|
+
|
|
192
190
|
Returns
|
|
193
191
|
-------
|
|
194
192
|
ImgArray, Label, MarkerFrame or TrackFrame, np.ndarray, or list of one of them.
|
|
195
193
|
impy object(s) that satisfies the options.
|
|
196
|
-
|
|
194
|
+
|
|
197
195
|
Examples
|
|
198
196
|
--------
|
|
199
197
|
1. Get the front image.
|
|
200
|
-
|
|
198
|
+
|
|
201
199
|
>>> ip.gui.get("image")
|
|
202
|
-
|
|
200
|
+
|
|
203
201
|
2. Get all the selected images as a list.
|
|
204
|
-
|
|
202
|
+
|
|
205
203
|
>>> ip.gui.get("image", layer_state="selected", returns="all")
|
|
206
|
-
|
|
204
|
+
|
|
207
205
|
3. Get all the lines from the front visible shapes layer.
|
|
208
|
-
|
|
209
|
-
>>> ip.gui.get("line", layer_state="visible")
|
|
210
|
-
|
|
211
|
-
"""
|
|
206
|
+
|
|
207
|
+
>>> ip.gui.get("line", layer_state="visible")
|
|
208
|
+
|
|
209
|
+
"""
|
|
212
210
|
if layer_state == "selected":
|
|
213
211
|
layer_list = list(self.viewer.layers.selection)
|
|
214
212
|
elif layer_state == "visible":
|
|
@@ -217,16 +215,16 @@ class napariViewers:
|
|
|
217
215
|
layer_list = self.viewer.layers
|
|
218
216
|
else:
|
|
219
217
|
raise ValueError("`filter` must be 'selected', 'visible' or 'any'")
|
|
220
|
-
|
|
218
|
+
|
|
221
219
|
kind = kind.capitalize()
|
|
222
220
|
out = []
|
|
223
221
|
if kind in ("Image", "Labels", "Points", "Shapes", "Tracks", "Vectors", "Surface"):
|
|
224
222
|
layer_type = getattr(napari.layers, kind)
|
|
225
|
-
|
|
223
|
+
|
|
226
224
|
for layer in layer_list:
|
|
227
225
|
if isinstance(layer, layer_type):
|
|
228
226
|
out.append(layer_to_impy_object(self.viewer, layer))
|
|
229
|
-
|
|
227
|
+
|
|
230
228
|
elif kind in ("Line", "Rectangle", "Path", "Polygon", "Ellipse"):
|
|
231
229
|
layer_type = napari.layers.Shapes
|
|
232
230
|
shape_type = kind.lower()
|
|
@@ -236,10 +234,10 @@ class napariViewers:
|
|
|
236
234
|
for s, t in zip(layer.data, layer.shape_type):
|
|
237
235
|
if t == shape_type:
|
|
238
236
|
out.append(s)
|
|
239
|
-
|
|
237
|
+
|
|
240
238
|
else:
|
|
241
239
|
raise TypeError(f"Cannot interpret type {kind}")
|
|
242
|
-
|
|
240
|
+
|
|
243
241
|
try:
|
|
244
242
|
if returns == "first":
|
|
245
243
|
out = out[0]
|
|
@@ -247,19 +245,19 @@ class napariViewers:
|
|
|
247
245
|
out = out[-1]
|
|
248
246
|
elif returns != "all":
|
|
249
247
|
raise ValueError("`returns` must be 'first', 'last' or 'all'")
|
|
250
|
-
|
|
248
|
+
|
|
251
249
|
except IndexError:
|
|
252
250
|
if layer_state != "none":
|
|
253
251
|
msg = f"No {layer_state} {kind.lower()} found in the viewer layer list."
|
|
254
252
|
else:
|
|
255
253
|
msg = f"No {kind.lower()} found in the viewer layer list."
|
|
256
254
|
raise IndexError(msg)
|
|
257
|
-
|
|
255
|
+
|
|
258
256
|
return out
|
|
259
|
-
|
|
257
|
+
|
|
260
258
|
def cursor_to_pixel(
|
|
261
|
-
self,
|
|
262
|
-
ref:
|
|
259
|
+
self,
|
|
260
|
+
ref: napari.layers.Image | int | str | LabeledArray | LazyImgArray,
|
|
263
261
|
ndim: int = None
|
|
264
262
|
) -> np.ndarray:
|
|
265
263
|
"""
|
|
@@ -269,17 +267,17 @@ class napariViewers:
|
|
|
269
267
|
Parameters
|
|
270
268
|
----------
|
|
271
269
|
ref : napari.layers.Image, int, str, LabeledArray or LazyImgArray
|
|
272
|
-
Reference layer or its identifier. To determine the reference layer, this parameter is interpreted in
|
|
270
|
+
Reference layer or its identifier. To determine the reference layer, this parameter is interpreted in
|
|
273
271
|
different ways depending on its type:
|
|
274
272
|
|
|
275
|
-
- napari.layers.Image ... layer itself
|
|
273
|
+
- napari.layers.Image ... layer itself
|
|
276
274
|
- int ... the index of layer list
|
|
277
275
|
- str ... the name of layer list
|
|
278
276
|
- LabeledArray or LazyImgArray ... layer that has same object as data
|
|
279
|
-
|
|
277
|
+
|
|
280
278
|
ndim : int, optional
|
|
281
279
|
If specified, the last ndim coordinates will be returned.
|
|
282
|
-
|
|
280
|
+
|
|
283
281
|
Returns
|
|
284
282
|
-------
|
|
285
283
|
np.ndarray
|
|
@@ -295,13 +293,13 @@ class napariViewers:
|
|
|
295
293
|
break
|
|
296
294
|
else:
|
|
297
295
|
raise ValueError("Input image was not found in napari layer list.")
|
|
298
|
-
|
|
296
|
+
|
|
299
297
|
elif isinstance(ref, (Image, Labels)):
|
|
300
298
|
layer = ref
|
|
301
299
|
else:
|
|
302
300
|
raise TypeError("`layer` must be an image layer, int, str or impy's LabeledArray, "
|
|
303
301
|
f"but got {type(ref)}")
|
|
304
|
-
|
|
302
|
+
|
|
305
303
|
if not isinstance(layer, (Image, Labels)):
|
|
306
304
|
raise TypeError(f"Layer {layer} is not an image or labels layer.")
|
|
307
305
|
|
|
@@ -309,7 +307,7 @@ class napariViewers:
|
|
|
309
307
|
cursor_coords = np.array(self.viewer.cursor.position[-ndim:])
|
|
310
308
|
pos = (cursor_coords - layer.translate)/layer.scale
|
|
311
309
|
return (pos + 0.5).astype(np.int64)
|
|
312
|
-
|
|
310
|
+
|
|
313
311
|
def add(self, obj: ImpyObject, **kwargs):
|
|
314
312
|
"""
|
|
315
313
|
Add images, points, labels, tracks etc to viewer.
|
|
@@ -318,76 +316,76 @@ class napariViewers:
|
|
|
318
316
|
----------
|
|
319
317
|
obj : ImpyObject
|
|
320
318
|
Object to add.
|
|
321
|
-
"""
|
|
319
|
+
"""
|
|
322
320
|
import pandas as pd
|
|
323
321
|
from dask import array as da
|
|
324
322
|
from impy.frame import MarkerFrame, TrackFrame, PathFrame
|
|
325
|
-
|
|
323
|
+
|
|
326
324
|
try:
|
|
327
325
|
self.viewer.window.activate()
|
|
328
326
|
except RuntimeError:
|
|
329
327
|
# Restart viewer
|
|
330
328
|
viewer = napari.Viewer(title=self._front_viewer)
|
|
331
329
|
self._viewers[self._front_viewer] = viewer
|
|
332
|
-
|
|
330
|
+
|
|
333
331
|
# Add image and its labels
|
|
334
332
|
if isinstance(obj, LabeledArray):
|
|
335
333
|
self._add_image(obj, **kwargs)
|
|
336
|
-
|
|
334
|
+
|
|
337
335
|
# Add points
|
|
338
336
|
elif isinstance(obj, MarkerFrame):
|
|
339
337
|
add_points(self.viewer, obj, **kwargs)
|
|
340
|
-
|
|
338
|
+
|
|
341
339
|
# Add labels
|
|
342
340
|
elif isinstance(obj, Label):
|
|
343
341
|
add_labels(self.viewer, obj, **kwargs)
|
|
344
|
-
|
|
342
|
+
|
|
345
343
|
# Add tracks
|
|
346
344
|
elif isinstance(obj, TrackFrame):
|
|
347
345
|
add_tracks(self.viewer, obj, **kwargs)
|
|
348
|
-
|
|
346
|
+
|
|
349
347
|
# Add path
|
|
350
348
|
elif isinstance(obj, PathFrame):
|
|
351
349
|
add_paths(self.viewer, obj, **kwargs)
|
|
352
|
-
|
|
350
|
+
|
|
353
351
|
# Add a table
|
|
354
352
|
elif isinstance(obj, (pd.DataFrame, PropArray)):
|
|
355
353
|
self.add_table(obj, **kwargs)
|
|
356
|
-
|
|
354
|
+
|
|
357
355
|
# Add a lazy-loaded image
|
|
358
356
|
elif isinstance(obj, LazyImgArray):
|
|
359
357
|
if obj.gb > Const["MAX_GB"] and self.viewer.dims.ndisplay == 3:
|
|
360
358
|
raise MemoryError("Cannot send large files while the viewer is 3D mode.")
|
|
361
359
|
add_dask(self.viewer, obj, **kwargs)
|
|
362
|
-
|
|
360
|
+
|
|
363
361
|
# Add an array as an image
|
|
364
362
|
elif type(obj) is np.ndarray:
|
|
365
363
|
self._add_image(ip_array(obj))
|
|
366
|
-
|
|
364
|
+
|
|
367
365
|
# Add an dask array as an image
|
|
368
366
|
elif type(obj) is da.core.Array:
|
|
369
367
|
self._add_image(ip_aslazy(obj))
|
|
370
|
-
|
|
368
|
+
|
|
371
369
|
# Add an image from a path
|
|
372
370
|
elif isinstance(obj, (str, Path)):
|
|
373
371
|
viewer_imread(self.viewer, obj)
|
|
374
|
-
|
|
372
|
+
|
|
375
373
|
# Add many objects of same type
|
|
376
374
|
elif isinstance(obj, DataList):
|
|
377
375
|
[self.add(each, **kwargs) for each in obj]
|
|
378
|
-
|
|
376
|
+
|
|
379
377
|
# Add a RoiList object as a shapes
|
|
380
378
|
elif type(obj).__name__ == "RoiList":
|
|
381
379
|
add_rois(self.viewer, obj, **kwargs)
|
|
382
|
-
|
|
380
|
+
|
|
383
381
|
# Add a Roi object as a shape
|
|
384
382
|
elif hasattr(obj, "from_imagejroi"):
|
|
385
383
|
add_rois(self.viewer, [obj], **kwargs)
|
|
386
|
-
|
|
384
|
+
|
|
387
385
|
else:
|
|
388
386
|
raise TypeError(f"Could not interpret type: {type(obj)}")
|
|
389
|
-
|
|
390
|
-
|
|
387
|
+
|
|
388
|
+
|
|
391
389
|
def add_surface(
|
|
392
390
|
self,
|
|
393
391
|
image3d: LabeledArray,
|
|
@@ -403,11 +401,11 @@ class napariViewers:
|
|
|
403
401
|
----------
|
|
404
402
|
image3d : LabeledArray
|
|
405
403
|
3D image from which surface will be generated
|
|
406
|
-
level, step_size, mask :
|
|
404
|
+
level, step_size, mask :
|
|
407
405
|
Passed to ``skimage.measure.marching_cubes``
|
|
408
|
-
"""
|
|
406
|
+
"""
|
|
409
407
|
from skimage.measure import marching_cubes
|
|
410
|
-
verts, faces, _, values = marching_cubes(image3d, level=level,
|
|
408
|
+
verts, faces, _, values = marching_cubes(image3d, level=level,
|
|
411
409
|
step_size=step_size, mask=mask)
|
|
412
410
|
scale = make_world_scale(image3d)
|
|
413
411
|
name = f"[Surf]{image3d.name}"
|
|
@@ -417,8 +415,8 @@ class napariViewers:
|
|
|
417
415
|
warnings.simplefilter("ignore")
|
|
418
416
|
self.viewer.add_surface((verts, faces, values), **kw)
|
|
419
417
|
return None
|
|
420
|
-
|
|
421
|
-
|
|
418
|
+
|
|
419
|
+
|
|
422
420
|
def goto(self, **kwargs) -> tuple[int, ...]:
|
|
423
421
|
"""
|
|
424
422
|
Change the current step of the viewer.
|
|
@@ -426,24 +424,24 @@ class napariViewers:
|
|
|
426
424
|
Examples
|
|
427
425
|
--------
|
|
428
426
|
1. Go to t=3.
|
|
429
|
-
|
|
427
|
+
|
|
430
428
|
>>> ip.gui.goto(t=3)
|
|
431
|
-
|
|
432
|
-
2. Go to t=3 and last z.
|
|
433
|
-
|
|
429
|
+
|
|
430
|
+
2. Go to t=3 and last z.
|
|
431
|
+
|
|
434
432
|
>>> ip.gui.goto(t=3, z=-1)
|
|
435
|
-
|
|
436
|
-
"""
|
|
433
|
+
|
|
434
|
+
"""
|
|
437
435
|
step = list(self.viewer.dims.current_step)
|
|
438
436
|
for axis, ind in kwargs.items():
|
|
439
437
|
i = self.axisof(axis)
|
|
440
438
|
if ind < 0:
|
|
441
439
|
ind = self.viewer.dims.nsteps[i] + ind # support minus indexing
|
|
442
440
|
step[i] = min(max(int(ind), 0), self.viewer.dims.nsteps[i]-1) # between min/max
|
|
443
|
-
|
|
441
|
+
|
|
444
442
|
self.viewer.dims.current_step = step
|
|
445
443
|
return step
|
|
446
|
-
|
|
444
|
+
|
|
447
445
|
def stepof(self, symbol: AxisLike) -> int:
|
|
448
446
|
"""
|
|
449
447
|
Get the current step of certain axis.
|
|
@@ -452,13 +450,13 @@ class napariViewers:
|
|
|
452
450
|
----------
|
|
453
451
|
symbol : AxisLike
|
|
454
452
|
Axis symbol
|
|
455
|
-
"""
|
|
453
|
+
"""
|
|
456
454
|
i = self.axes.find(symbol)
|
|
457
455
|
return self.viewer.dims.current_step[i]
|
|
458
456
|
|
|
459
457
|
def axisof(self, symbol: AxisLike) -> int:
|
|
460
458
|
return self.axes.find(symbol)
|
|
461
|
-
|
|
459
|
+
|
|
462
460
|
def _add_image(self, img: LabeledArray, **kwargs):
|
|
463
461
|
layer = add_labeledarray(self.viewer, img, **kwargs)
|
|
464
462
|
if isinstance(layer, list):
|
|
@@ -468,30 +466,30 @@ class napariViewers:
|
|
|
468
466
|
if img.labels is not None:
|
|
469
467
|
add_labels(self.viewer, img.labels, name=name, metadata={"destination_image": img})
|
|
470
468
|
return None
|
|
471
|
-
|
|
469
|
+
|
|
472
470
|
def add_table(self, table: pd.DataFrame | dict[str, ArrayLike], **kwargs):
|
|
473
471
|
from magicgui.widgets import Table
|
|
474
472
|
table = Table(value=table)
|
|
475
473
|
self.viewer.window.add_dock_widget(table, **kwargs)
|
|
476
474
|
return table
|
|
477
|
-
|
|
475
|
+
|
|
478
476
|
def add_image(self, *args, **kwargs):
|
|
479
477
|
return self.viewer.add_image(*args, **kwargs)
|
|
480
|
-
|
|
478
|
+
|
|
481
479
|
def add_shapes(self, *args, **kwargs):
|
|
482
480
|
return self.viewer.add_shapes(*args, **kwargs)
|
|
483
|
-
|
|
481
|
+
|
|
484
482
|
def add_surface(self, *args, **kwargs):
|
|
485
483
|
return self.viewer.add_surface(*args, **kwargs)
|
|
486
|
-
|
|
484
|
+
|
|
487
485
|
def add_points(self, *args, **kwargs):
|
|
488
486
|
return self.viewer.add_points(*args, **kwargs)
|
|
489
|
-
|
|
487
|
+
|
|
490
488
|
def add_labels(self, *args, **kwargs):
|
|
491
489
|
return self.viewer.add_labels(*args, **kwargs)
|
|
492
|
-
|
|
490
|
+
|
|
493
491
|
def add_vectors(self, *args, **kwargs):
|
|
494
492
|
return self.viewer.add_vectors(*args, **kwargs)
|
|
495
|
-
|
|
493
|
+
|
|
496
494
|
def add_tracks(self, *args, **kwargs):
|
|
497
495
|
return self.viewer.add_tracks(*args, **kwargs)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|