ngio 0.3.5__py3-none-any.whl → 0.4.0a1__py3-none-any.whl
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.
- ngio/__init__.py +6 -0
- ngio/common/__init__.py +50 -48
- ngio/common/_array_io_pipes.py +549 -0
- ngio/common/_array_io_utils.py +508 -0
- ngio/common/_dimensions.py +63 -27
- ngio/common/_masking_roi.py +38 -10
- ngio/common/_pyramid.py +9 -7
- ngio/common/_roi.py +571 -72
- ngio/common/_synt_images_utils.py +101 -0
- ngio/common/_zoom.py +17 -12
- ngio/common/transforms/__init__.py +5 -0
- ngio/common/transforms/_label.py +12 -0
- ngio/common/transforms/_zoom.py +109 -0
- ngio/experimental/__init__.py +5 -0
- ngio/experimental/iterators/__init__.py +17 -0
- ngio/experimental/iterators/_abstract_iterator.py +170 -0
- ngio/experimental/iterators/_feature.py +151 -0
- ngio/experimental/iterators/_image_processing.py +169 -0
- ngio/experimental/iterators/_rois_utils.py +127 -0
- ngio/experimental/iterators/_segmentation.py +278 -0
- ngio/hcs/_plate.py +41 -36
- ngio/images/__init__.py +22 -1
- ngio/images/_abstract_image.py +247 -117
- ngio/images/_create.py +15 -15
- ngio/images/_create_synt_container.py +128 -0
- ngio/images/_image.py +425 -62
- ngio/images/_label.py +33 -30
- ngio/images/_masked_image.py +396 -122
- ngio/images/_ome_zarr_container.py +203 -66
- ngio/{common → images}/_table_ops.py +41 -41
- ngio/ome_zarr_meta/ngio_specs/__init__.py +2 -8
- ngio/ome_zarr_meta/ngio_specs/_axes.py +151 -128
- ngio/ome_zarr_meta/ngio_specs/_channels.py +55 -18
- ngio/ome_zarr_meta/ngio_specs/_dataset.py +7 -7
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +3 -3
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +11 -68
- ngio/ome_zarr_meta/v04/_v04_spec_utils.py +1 -1
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
- ngio/resources/__init__.py +54 -0
- ngio/resources/resource_model.py +35 -0
- ngio/tables/backends/_abstract_backend.py +5 -6
- ngio/tables/backends/_anndata.py +1 -1
- ngio/tables/backends/_anndata_utils.py +3 -3
- ngio/tables/backends/_non_zarr_backends.py +1 -1
- ngio/tables/backends/_table_backends.py +0 -1
- ngio/tables/backends/_utils.py +3 -3
- ngio/tables/v1/_roi_table.py +156 -69
- ngio/utils/__init__.py +2 -3
- ngio/utils/_logger.py +19 -0
- ngio/utils/_zarr_utils.py +1 -5
- {ngio-0.3.5.dist-info → ngio-0.4.0a1.dist-info}/METADATA +3 -1
- ngio-0.4.0a1.dist-info/RECORD +76 -0
- ngio/common/_array_pipe.py +0 -288
- ngio/common/_axes_transforms.py +0 -64
- ngio/common/_common_types.py +0 -5
- ngio/common/_slicer.py +0 -96
- ngio-0.3.5.dist-info/RECORD +0 -61
- {ngio-0.3.5.dist-info → ngio-0.4.0a1.dist-info}/WHEEL +0 -0
- {ngio-0.3.5.dist-info → ngio-0.4.0a1.dist-info}/licenses/LICENSE +0 -0
ngio/images/_masked_image.py
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
"""A module for handling label images in OME-NGFF files."""
|
|
2
2
|
|
|
3
|
-
from collections.abc import
|
|
3
|
+
from collections.abc import Sequence
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import dask.array as da
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from ngio.common import (
|
|
10
|
+
ArrayLike,
|
|
11
|
+
TransformProtocol,
|
|
12
|
+
build_roi_masked_dask_getter,
|
|
13
|
+
build_roi_masked_dask_setter,
|
|
14
|
+
build_roi_masked_numpy_getter,
|
|
15
|
+
build_roi_masked_numpy_setter,
|
|
16
|
+
)
|
|
17
|
+
from ngio.images._image import (
|
|
18
|
+
ChannelSlicingInputType,
|
|
19
|
+
Image,
|
|
20
|
+
SlicingInputType,
|
|
21
|
+
add_channel_selection_to_slicing_dict,
|
|
22
|
+
)
|
|
8
23
|
from ngio.images._label import Label
|
|
9
24
|
from ngio.ome_zarr_meta import ImageMetaHandler, LabelMetaHandler
|
|
10
25
|
from ngio.tables import MaskingRoiTable
|
|
@@ -47,72 +62,243 @@ class MaskedImage(Image):
|
|
|
47
62
|
label_name = self._masking_roi_table.reference_label
|
|
48
63
|
return f"MaskedImage(path={self.path}, {self.dimensions}, {label_name})"
|
|
49
64
|
|
|
50
|
-
def
|
|
65
|
+
def get_roi_as_numpy( # type: ignore (this ignore the method override issue)
|
|
51
66
|
self,
|
|
52
67
|
label: int,
|
|
68
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
53
69
|
zoom_factor: float = 1.0,
|
|
54
|
-
axes_order:
|
|
55
|
-
|
|
56
|
-
**
|
|
70
|
+
axes_order: Sequence[str] | None = None,
|
|
71
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
72
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
57
73
|
) -> ArrayLike:
|
|
58
74
|
"""Return the array for a given ROI."""
|
|
59
|
-
roi = self._masking_roi_table.
|
|
75
|
+
roi = self._masking_roi_table.get_label(label)
|
|
76
|
+
roi = roi.zoom(zoom_factor)
|
|
77
|
+
return super().get_roi_as_numpy(
|
|
78
|
+
roi=roi,
|
|
79
|
+
channel_selection=channel_selection,
|
|
80
|
+
axes_order=axes_order,
|
|
81
|
+
transforms=transforms,
|
|
82
|
+
**slicing_kwargs,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def get_roi_as_dask( # type: ignore (this ignore the method override issue)
|
|
86
|
+
self,
|
|
87
|
+
label: int,
|
|
88
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
89
|
+
zoom_factor: float = 1.0,
|
|
90
|
+
axes_order: Sequence[str] | None = None,
|
|
91
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
92
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
93
|
+
) -> da.Array:
|
|
94
|
+
"""Return the array for a given ROI as a Dask array."""
|
|
95
|
+
roi = self._masking_roi_table.get_label(label)
|
|
96
|
+
roi = roi.zoom(zoom_factor)
|
|
97
|
+
return super().get_roi_as_dask(
|
|
98
|
+
roi=roi,
|
|
99
|
+
channel_selection=channel_selection,
|
|
100
|
+
axes_order=axes_order,
|
|
101
|
+
transforms=transforms,
|
|
102
|
+
**slicing_kwargs,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def get_roi( # type: ignore (this ignore the method override issue)
|
|
106
|
+
self,
|
|
107
|
+
label: int,
|
|
108
|
+
zoom_factor: float = 1.0,
|
|
109
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
110
|
+
axes_order: Sequence[str] | None = None,
|
|
111
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
112
|
+
mode: Literal["numpy", "dask"] = "numpy",
|
|
113
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
114
|
+
) -> ArrayLike:
|
|
115
|
+
"""Return the array for a given ROI."""
|
|
116
|
+
roi = self._masking_roi_table.get_label(label)
|
|
60
117
|
roi = roi.zoom(zoom_factor)
|
|
61
118
|
return super().get_roi(
|
|
62
|
-
roi=roi,
|
|
119
|
+
roi=roi,
|
|
120
|
+
channel_selection=channel_selection,
|
|
121
|
+
axes_order=axes_order,
|
|
122
|
+
transforms=transforms,
|
|
123
|
+
mode=mode,
|
|
124
|
+
**slicing_kwargs,
|
|
63
125
|
)
|
|
64
126
|
|
|
65
|
-
def set_roi(
|
|
127
|
+
def set_roi( # type: ignore (this ignore the method override issue)
|
|
66
128
|
self,
|
|
67
129
|
label: int,
|
|
68
130
|
patch: ArrayLike,
|
|
69
131
|
zoom_factor: float = 1.0,
|
|
70
|
-
|
|
71
|
-
|
|
132
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
133
|
+
axes_order: Sequence[str] | None = None,
|
|
134
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
135
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
72
136
|
) -> None:
|
|
73
137
|
"""Set the array for a given ROI."""
|
|
74
|
-
roi = self._masking_roi_table.
|
|
138
|
+
roi = self._masking_roi_table.get_label(label)
|
|
75
139
|
roi = roi.zoom(zoom_factor)
|
|
76
140
|
return super().set_roi(
|
|
77
|
-
roi=roi,
|
|
141
|
+
roi=roi,
|
|
142
|
+
patch=patch,
|
|
143
|
+
channel_selection=channel_selection,
|
|
144
|
+
axes_order=axes_order,
|
|
145
|
+
transforms=transforms,
|
|
146
|
+
**slicing_kwargs,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
def get_roi_masked_as_numpy(
|
|
150
|
+
self,
|
|
151
|
+
label: int,
|
|
152
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
153
|
+
zoom_factor: float = 1.0,
|
|
154
|
+
axes_order: Sequence[str] | None = None,
|
|
155
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
156
|
+
allow_scaling: bool = True,
|
|
157
|
+
**slicing_kwargs: SlicingInputType,
|
|
158
|
+
) -> np.ndarray:
|
|
159
|
+
"""Return the masked array for a given label as a NumPy array."""
|
|
160
|
+
slicing_kwargs = add_channel_selection_to_slicing_dict(
|
|
161
|
+
image=self, channel_selection=channel_selection, slicing_dict=slicing_kwargs
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
roi = self._masking_roi_table.get_label(label)
|
|
165
|
+
roi = roi.zoom(zoom_factor)
|
|
166
|
+
masked_getter = build_roi_masked_numpy_getter(
|
|
167
|
+
roi=roi,
|
|
168
|
+
zarr_array=self.zarr_array,
|
|
169
|
+
label_zarr_array=self._label.zarr_array,
|
|
170
|
+
dimensions=self.dimensions,
|
|
171
|
+
pixel_size=self.pixel_size,
|
|
172
|
+
label_dimensions=self._label.dimensions,
|
|
173
|
+
label_pixel_size=self._label.pixel_size,
|
|
174
|
+
axes_order=axes_order,
|
|
175
|
+
transforms=transforms,
|
|
176
|
+
slicing_dict=slicing_kwargs,
|
|
177
|
+
allow_scaling=allow_scaling,
|
|
78
178
|
)
|
|
179
|
+
return masked_getter()
|
|
180
|
+
|
|
181
|
+
def get_roi_masked_as_dask(
|
|
182
|
+
self,
|
|
183
|
+
label: int,
|
|
184
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
185
|
+
zoom_factor: float = 1.0,
|
|
186
|
+
axes_order: Sequence[str] | None = None,
|
|
187
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
188
|
+
allow_scaling: bool = True,
|
|
189
|
+
**slicing_kwargs: SlicingInputType,
|
|
190
|
+
) -> da.Array:
|
|
191
|
+
"""Return the masked array for a given label as a Dask array."""
|
|
192
|
+
slicing_kwargs = add_channel_selection_to_slicing_dict(
|
|
193
|
+
image=self, channel_selection=channel_selection, slicing_dict=slicing_kwargs
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
roi = self._masking_roi_table.get_label(label)
|
|
197
|
+
roi = roi.zoom(zoom_factor)
|
|
198
|
+
masked_getter = build_roi_masked_dask_getter(
|
|
199
|
+
roi=roi,
|
|
200
|
+
zarr_array=self.zarr_array,
|
|
201
|
+
label_zarr_array=self._label.zarr_array,
|
|
202
|
+
dimensions=self.dimensions,
|
|
203
|
+
pixel_size=self.pixel_size,
|
|
204
|
+
label_dimensions=self._label.dimensions,
|
|
205
|
+
label_pixel_size=self._label.pixel_size,
|
|
206
|
+
axes_order=axes_order,
|
|
207
|
+
transforms=transforms,
|
|
208
|
+
slicing_dict=slicing_kwargs,
|
|
209
|
+
allow_scaling=allow_scaling,
|
|
210
|
+
)
|
|
211
|
+
return masked_getter()
|
|
79
212
|
|
|
80
213
|
def get_roi_masked(
|
|
81
214
|
self,
|
|
82
215
|
label: int,
|
|
83
|
-
|
|
84
|
-
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
216
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
85
217
|
zoom_factor: float = 1.0,
|
|
86
|
-
|
|
218
|
+
axes_order: Sequence[str] | None = None,
|
|
219
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
220
|
+
mode: Literal["numpy", "dask"] = "numpy",
|
|
221
|
+
allow_scaling: bool = True,
|
|
222
|
+
**slicing_kwargs: SlicingInputType,
|
|
87
223
|
) -> ArrayLike:
|
|
88
224
|
"""Return the masked array for a given label."""
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
225
|
+
if mode == "numpy":
|
|
226
|
+
return self.get_roi_masked_as_numpy(
|
|
227
|
+
label=label,
|
|
228
|
+
channel_selection=channel_selection,
|
|
229
|
+
zoom_factor=zoom_factor,
|
|
230
|
+
axes_order=axes_order,
|
|
231
|
+
transforms=transforms,
|
|
232
|
+
allow_scaling=allow_scaling,
|
|
233
|
+
**slicing_kwargs,
|
|
234
|
+
)
|
|
235
|
+
elif mode == "dask":
|
|
236
|
+
return self.get_roi_masked_as_dask(
|
|
237
|
+
label=label,
|
|
238
|
+
channel_selection=channel_selection,
|
|
239
|
+
zoom_factor=zoom_factor,
|
|
240
|
+
axes_order=axes_order,
|
|
241
|
+
transforms=transforms,
|
|
242
|
+
allow_scaling=allow_scaling,
|
|
243
|
+
**slicing_kwargs,
|
|
244
|
+
)
|
|
245
|
+
else:
|
|
246
|
+
raise ValueError(f"Unknown mode: {mode}")
|
|
97
247
|
|
|
98
248
|
def set_roi_masked(
|
|
99
249
|
self,
|
|
100
250
|
label: int,
|
|
101
251
|
patch: ArrayLike,
|
|
102
|
-
|
|
252
|
+
channel_selection: ChannelSlicingInputType | None = None,
|
|
253
|
+
axes_order: Sequence[str] | None = None,
|
|
103
254
|
zoom_factor: float = 1.0,
|
|
104
|
-
|
|
255
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
256
|
+
allow_scaling: bool = True,
|
|
257
|
+
**slicing_kwargs: SlicingInputType,
|
|
105
258
|
) -> None:
|
|
106
259
|
"""Set the masked array for a given label."""
|
|
107
|
-
|
|
108
|
-
image=self,
|
|
109
|
-
label=label,
|
|
110
|
-
patch=patch,
|
|
111
|
-
axes_order=axes_order,
|
|
112
|
-
zoom_factor=zoom_factor,
|
|
113
|
-
**slice_kwargs,
|
|
260
|
+
slicing_kwargs = add_channel_selection_to_slicing_dict(
|
|
261
|
+
image=self, channel_selection=channel_selection, slicing_dict=slicing_kwargs
|
|
114
262
|
)
|
|
115
263
|
|
|
264
|
+
roi = self._masking_roi_table.get_label(label)
|
|
265
|
+
roi = roi.zoom(zoom_factor)
|
|
266
|
+
if isinstance(patch, da.Array):
|
|
267
|
+
path_setter = build_roi_masked_dask_setter(
|
|
268
|
+
roi=roi,
|
|
269
|
+
zarr_array=self.zarr_array,
|
|
270
|
+
label_zarr_array=self._label.zarr_array,
|
|
271
|
+
dimensions=self.dimensions,
|
|
272
|
+
pixel_size=self.pixel_size,
|
|
273
|
+
label_dimensions=self._label.dimensions,
|
|
274
|
+
label_pixel_size=self._label.pixel_size,
|
|
275
|
+
axes_order=axes_order,
|
|
276
|
+
transforms=transforms,
|
|
277
|
+
slicing_dict=slicing_kwargs,
|
|
278
|
+
allow_scaling=allow_scaling,
|
|
279
|
+
)
|
|
280
|
+
path_setter(patch)
|
|
281
|
+
elif isinstance(patch, np.ndarray):
|
|
282
|
+
path_setter = build_roi_masked_numpy_setter(
|
|
283
|
+
roi=roi,
|
|
284
|
+
zarr_array=self.zarr_array,
|
|
285
|
+
label_zarr_array=self._label.zarr_array,
|
|
286
|
+
dimensions=self.dimensions,
|
|
287
|
+
pixel_size=self.pixel_size,
|
|
288
|
+
label_dimensions=self._label.dimensions,
|
|
289
|
+
label_pixel_size=self._label.pixel_size,
|
|
290
|
+
axes_order=axes_order,
|
|
291
|
+
transforms=transforms,
|
|
292
|
+
slicing_dict=slicing_kwargs,
|
|
293
|
+
allow_scaling=allow_scaling,
|
|
294
|
+
)
|
|
295
|
+
path_setter(patch)
|
|
296
|
+
else:
|
|
297
|
+
raise TypeError(
|
|
298
|
+
f"Unsupported patch type: {type(patch)}. "
|
|
299
|
+
"Expected numpy.ndarray or dask.array.Array."
|
|
300
|
+
)
|
|
301
|
+
|
|
116
302
|
|
|
117
303
|
class MaskedLabel(Label):
|
|
118
304
|
"""Placeholder class for a label."""
|
|
@@ -148,19 +334,60 @@ class MaskedLabel(Label):
|
|
|
148
334
|
label_name = self._masking_roi_table.reference_label
|
|
149
335
|
return f"MaskedLabel(path={self.path}, {self.dimensions}, {label_name})"
|
|
150
336
|
|
|
337
|
+
def get_roi_as_numpy(
|
|
338
|
+
self,
|
|
339
|
+
label: int,
|
|
340
|
+
zoom_factor: float = 1.0,
|
|
341
|
+
axes_order: Sequence[str] | None = None,
|
|
342
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
343
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
344
|
+
) -> np.ndarray:
|
|
345
|
+
"""Return the ROI as a NumPy array."""
|
|
346
|
+
roi = self._masking_roi_table.get_label(label)
|
|
347
|
+
roi = roi.zoom(zoom_factor)
|
|
348
|
+
return super().get_roi_as_numpy(
|
|
349
|
+
roi=roi,
|
|
350
|
+
axes_order=axes_order,
|
|
351
|
+
transforms=transforms,
|
|
352
|
+
**slicing_kwargs,
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
def get_roi_as_dask(
|
|
356
|
+
self,
|
|
357
|
+
label: int,
|
|
358
|
+
zoom_factor: float = 1.0,
|
|
359
|
+
axes_order: Sequence[str] | None = None,
|
|
360
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
361
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
362
|
+
) -> da.Array:
|
|
363
|
+
"""Return the ROI as a Dask array."""
|
|
364
|
+
roi = self._masking_roi_table.get_label(label)
|
|
365
|
+
roi = roi.zoom(zoom_factor)
|
|
366
|
+
return super().get_roi_as_dask(
|
|
367
|
+
roi=roi,
|
|
368
|
+
axes_order=axes_order,
|
|
369
|
+
transforms=transforms,
|
|
370
|
+
**slicing_kwargs,
|
|
371
|
+
)
|
|
372
|
+
|
|
151
373
|
def get_roi(
|
|
152
374
|
self,
|
|
153
375
|
label: int,
|
|
154
376
|
zoom_factor: float = 1.0,
|
|
155
|
-
axes_order:
|
|
156
|
-
mode: Literal["numpy", "dask"
|
|
157
|
-
|
|
377
|
+
axes_order: Sequence[str] | None = None,
|
|
378
|
+
mode: Literal["numpy", "dask"] = "numpy",
|
|
379
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
380
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
158
381
|
) -> ArrayLike:
|
|
159
382
|
"""Return the array for a given ROI."""
|
|
160
|
-
roi = self._masking_roi_table.
|
|
383
|
+
roi = self._masking_roi_table.get_label(label)
|
|
161
384
|
roi = roi.zoom(zoom_factor)
|
|
162
385
|
return super().get_roi(
|
|
163
|
-
roi=roi,
|
|
386
|
+
roi=roi,
|
|
387
|
+
axes_order=axes_order,
|
|
388
|
+
mode=mode,
|
|
389
|
+
transforms=transforms,
|
|
390
|
+
**slicing_kwargs,
|
|
164
391
|
)
|
|
165
392
|
|
|
166
393
|
def set_roi(
|
|
@@ -168,106 +395,153 @@ class MaskedLabel(Label):
|
|
|
168
395
|
label: int,
|
|
169
396
|
patch: ArrayLike,
|
|
170
397
|
zoom_factor: float = 1.0,
|
|
171
|
-
axes_order:
|
|
172
|
-
|
|
398
|
+
axes_order: Sequence[str] | None = None,
|
|
399
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
400
|
+
**slicing_kwargs: slice | int | Sequence[int],
|
|
173
401
|
) -> None:
|
|
174
402
|
"""Set the array for a given ROI."""
|
|
175
|
-
roi = self._masking_roi_table.
|
|
403
|
+
roi = self._masking_roi_table.get_label(label)
|
|
176
404
|
roi = roi.zoom(zoom_factor)
|
|
177
405
|
return super().set_roi(
|
|
178
|
-
roi=roi,
|
|
406
|
+
roi=roi,
|
|
407
|
+
patch=patch,
|
|
408
|
+
axes_order=axes_order,
|
|
409
|
+
transforms=transforms,
|
|
410
|
+
**slicing_kwargs,
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
def get_roi_masked_as_numpy(
|
|
414
|
+
self,
|
|
415
|
+
label: int,
|
|
416
|
+
zoom_factor: float = 1.0,
|
|
417
|
+
axes_order: Sequence[str] | None = None,
|
|
418
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
419
|
+
allow_scaling: bool = True,
|
|
420
|
+
**slicing_kwargs: SlicingInputType,
|
|
421
|
+
) -> np.ndarray:
|
|
422
|
+
"""Return the masked array for a given label as a NumPy array."""
|
|
423
|
+
roi = self._masking_roi_table.get_label(label)
|
|
424
|
+
roi = roi.zoom(zoom_factor)
|
|
425
|
+
masked_getter = build_roi_masked_numpy_getter(
|
|
426
|
+
roi=roi,
|
|
427
|
+
zarr_array=self.zarr_array,
|
|
428
|
+
label_zarr_array=self._label.zarr_array,
|
|
429
|
+
dimensions=self.dimensions,
|
|
430
|
+
pixel_size=self.pixel_size,
|
|
431
|
+
label_dimensions=self._label.dimensions,
|
|
432
|
+
label_pixel_size=self._label.pixel_size,
|
|
433
|
+
axes_order=axes_order,
|
|
434
|
+
transforms=transforms,
|
|
435
|
+
slicing_dict=slicing_kwargs,
|
|
436
|
+
allow_scaling=allow_scaling,
|
|
179
437
|
)
|
|
438
|
+
return masked_getter()
|
|
439
|
+
|
|
440
|
+
def get_roi_masked_as_dask(
|
|
441
|
+
self,
|
|
442
|
+
label: int,
|
|
443
|
+
zoom_factor: float = 1.0,
|
|
444
|
+
axes_order: Sequence[str] | None = None,
|
|
445
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
446
|
+
allow_scaling: bool = True,
|
|
447
|
+
**slicing_kwargs: SlicingInputType,
|
|
448
|
+
) -> da.Array:
|
|
449
|
+
"""Return the masked array for a given label as a Dask array."""
|
|
450
|
+
roi = self._masking_roi_table.get_label(label)
|
|
451
|
+
roi = roi.zoom(zoom_factor)
|
|
452
|
+
masked_getter = build_roi_masked_dask_getter(
|
|
453
|
+
roi=roi,
|
|
454
|
+
zarr_array=self.zarr_array,
|
|
455
|
+
label_zarr_array=self._label.zarr_array,
|
|
456
|
+
dimensions=self.dimensions,
|
|
457
|
+
pixel_size=self.pixel_size,
|
|
458
|
+
label_dimensions=self._label.dimensions,
|
|
459
|
+
label_pixel_size=self._label.pixel_size,
|
|
460
|
+
axes_order=axes_order,
|
|
461
|
+
transforms=transforms,
|
|
462
|
+
slicing_dict=slicing_kwargs,
|
|
463
|
+
allow_scaling=allow_scaling,
|
|
464
|
+
)
|
|
465
|
+
return masked_getter()
|
|
180
466
|
|
|
181
467
|
def get_roi_masked(
|
|
182
468
|
self,
|
|
183
469
|
label: int,
|
|
184
|
-
axes_order: Collection[str] | None = None,
|
|
185
|
-
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
186
470
|
zoom_factor: float = 1.0,
|
|
187
|
-
|
|
471
|
+
axes_order: Sequence[str] | None = None,
|
|
472
|
+
mode: Literal["numpy", "dask"] = "numpy",
|
|
473
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
474
|
+
allow_scaling: bool = True,
|
|
475
|
+
**slicing_kwargs: SlicingInputType,
|
|
188
476
|
) -> ArrayLike:
|
|
189
477
|
"""Return the masked array for a given label."""
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
478
|
+
if mode == "numpy":
|
|
479
|
+
return self.get_roi_masked_as_numpy(
|
|
480
|
+
label=label,
|
|
481
|
+
zoom_factor=zoom_factor,
|
|
482
|
+
axes_order=axes_order,
|
|
483
|
+
transforms=transforms,
|
|
484
|
+
allow_scaling=allow_scaling,
|
|
485
|
+
**slicing_kwargs,
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
elif mode == "dask":
|
|
489
|
+
return self.get_roi_masked_as_dask(
|
|
490
|
+
label=label,
|
|
491
|
+
zoom_factor=zoom_factor,
|
|
492
|
+
axes_order=axes_order,
|
|
493
|
+
transforms=transforms,
|
|
494
|
+
allow_scaling=allow_scaling,
|
|
495
|
+
**slicing_kwargs,
|
|
496
|
+
)
|
|
497
|
+
else:
|
|
498
|
+
raise ValueError(f"Unknown mode: {mode}")
|
|
198
499
|
|
|
199
500
|
def set_roi_masked(
|
|
200
501
|
self,
|
|
201
502
|
label: int,
|
|
202
503
|
patch: ArrayLike,
|
|
203
|
-
axes_order:
|
|
504
|
+
axes_order: Sequence[str] | None = None,
|
|
204
505
|
zoom_factor: float = 1.0,
|
|
205
|
-
|
|
506
|
+
transforms: Sequence[TransformProtocol] | None = None,
|
|
507
|
+
allow_scaling: bool = True,
|
|
508
|
+
**slicing_kwargs: SlicingInputType,
|
|
206
509
|
) -> None:
|
|
207
510
|
"""Set the masked array for a given label."""
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
def set_masked_roi_pipe(
|
|
248
|
-
image: MaskedImage | MaskedLabel,
|
|
249
|
-
label: int,
|
|
250
|
-
patch: ArrayLike,
|
|
251
|
-
axes_order: Collection[str] | None = None,
|
|
252
|
-
zoom_factor: float = 1.0,
|
|
253
|
-
**slice_kwargs: slice | int | Iterable[int],
|
|
254
|
-
) -> None:
|
|
255
|
-
"""Set the masked array for a given label."""
|
|
256
|
-
roi = image._masking_roi_table.get(label)
|
|
257
|
-
roi = roi.zoom(zoom_factor)
|
|
258
|
-
slice_kwargs = roi_to_slice_kwargs(
|
|
259
|
-
roi=roi,
|
|
260
|
-
pixel_size=image.pixel_size,
|
|
261
|
-
dimensions=image.dimensions,
|
|
262
|
-
**slice_kwargs,
|
|
263
|
-
)
|
|
264
|
-
return set_masked_pipe(
|
|
265
|
-
array=image.zarr_array,
|
|
266
|
-
label_array=image._label.zarr_array,
|
|
267
|
-
label=label,
|
|
268
|
-
patch=patch,
|
|
269
|
-
dimensions_array=image.dimensions,
|
|
270
|
-
dimensions_label=image._label.dimensions,
|
|
271
|
-
axes_order=axes_order,
|
|
272
|
-
**slice_kwargs,
|
|
273
|
-
)
|
|
511
|
+
roi = self._masking_roi_table.get_label(label)
|
|
512
|
+
roi = roi.zoom(zoom_factor)
|
|
513
|
+
if isinstance(patch, da.Array):
|
|
514
|
+
path_setter = build_roi_masked_dask_setter(
|
|
515
|
+
roi=roi,
|
|
516
|
+
zarr_array=self.zarr_array,
|
|
517
|
+
label_zarr_array=self._label.zarr_array,
|
|
518
|
+
dimensions=self.dimensions,
|
|
519
|
+
pixel_size=self.pixel_size,
|
|
520
|
+
label_dimensions=self._label.dimensions,
|
|
521
|
+
label_pixel_size=self._label.pixel_size,
|
|
522
|
+
axes_order=axes_order,
|
|
523
|
+
transforms=transforms,
|
|
524
|
+
slicing_dict=slicing_kwargs,
|
|
525
|
+
allow_scaling=allow_scaling,
|
|
526
|
+
)
|
|
527
|
+
path_setter(patch)
|
|
528
|
+
elif isinstance(patch, np.ndarray):
|
|
529
|
+
path_setter = build_roi_masked_numpy_setter(
|
|
530
|
+
roi=roi,
|
|
531
|
+
zarr_array=self.zarr_array,
|
|
532
|
+
label_zarr_array=self._label.zarr_array,
|
|
533
|
+
dimensions=self.dimensions,
|
|
534
|
+
pixel_size=self.pixel_size,
|
|
535
|
+
label_dimensions=self._label.dimensions,
|
|
536
|
+
label_pixel_size=self._label.pixel_size,
|
|
537
|
+
axes_order=axes_order,
|
|
538
|
+
transforms=transforms,
|
|
539
|
+
slicing_dict=slicing_kwargs,
|
|
540
|
+
allow_scaling=allow_scaling,
|
|
541
|
+
)
|
|
542
|
+
path_setter(patch)
|
|
543
|
+
else:
|
|
544
|
+
raise TypeError(
|
|
545
|
+
f"Unsupported patch type: {type(patch)}. "
|
|
546
|
+
"Expected numpy.ndarray or dask.array.Array."
|
|
547
|
+
)
|