ngio 0.4.0a2__py3-none-any.whl → 0.4.0a4__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 +1 -2
- ngio/common/__init__.py +2 -51
- ngio/common/_dimensions.py +223 -64
- ngio/common/_pyramid.py +42 -23
- ngio/common/_roi.py +94 -418
- ngio/common/_zoom.py +32 -7
- ngio/experimental/iterators/_abstract_iterator.py +2 -2
- ngio/experimental/iterators/_feature.py +10 -15
- ngio/experimental/iterators/_image_processing.py +18 -28
- ngio/experimental/iterators/_rois_utils.py +6 -6
- ngio/experimental/iterators/_segmentation.py +38 -54
- ngio/images/_abstract_image.py +136 -94
- ngio/images/_create.py +16 -0
- ngio/images/_create_synt_container.py +10 -0
- ngio/images/_image.py +33 -9
- ngio/images/_label.py +24 -3
- ngio/images/_masked_image.py +60 -81
- ngio/images/_ome_zarr_container.py +34 -1
- ngio/io_pipes/__init__.py +49 -0
- ngio/io_pipes/_io_pipes.py +286 -0
- ngio/io_pipes/_io_pipes_masked.py +481 -0
- ngio/io_pipes/_io_pipes_roi.py +143 -0
- ngio/io_pipes/_io_pipes_utils.py +299 -0
- ngio/io_pipes/_match_shape.py +376 -0
- ngio/io_pipes/_ops_axes.py +146 -0
- ngio/io_pipes/_ops_slices.py +218 -0
- ngio/io_pipes/_ops_transforms.py +104 -0
- ngio/io_pipes/_zoom_transform.py +175 -0
- ngio/ome_zarr_meta/__init__.py +6 -2
- ngio/ome_zarr_meta/ngio_specs/__init__.py +6 -4
- ngio/ome_zarr_meta/ngio_specs/_axes.py +182 -70
- ngio/ome_zarr_meta/ngio_specs/_dataset.py +47 -121
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +30 -22
- ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +17 -1
- ngio/ome_zarr_meta/v04/_v04_spec_utils.py +33 -30
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
- ngio/resources/__init__.py +1 -0
- ngio/resources/resource_model.py +1 -0
- ngio/tables/v1/_roi_table.py +11 -3
- ngio/{common/transforms → transforms}/__init__.py +1 -1
- ngio/transforms/_zoom.py +19 -0
- ngio/utils/_zarr_utils.py +5 -1
- {ngio-0.4.0a2.dist-info → ngio-0.4.0a4.dist-info}/METADATA +1 -1
- ngio-0.4.0a4.dist-info/RECORD +83 -0
- ngio/common/_array_io_pipes.py +0 -554
- ngio/common/_array_io_utils.py +0 -508
- ngio/common/transforms/_label.py +0 -12
- ngio/common/transforms/_zoom.py +0 -109
- ngio-0.4.0a2.dist-info/RECORD +0 -76
- {ngio-0.4.0a2.dist-info → ngio-0.4.0a4.dist-info}/WHEEL +0 -0
- {ngio-0.4.0a2.dist-info → ngio-0.4.0a4.dist-info}/licenses/LICENSE +0 -0
ngio/images/_label.py
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
from collections.abc import Sequence
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
|
+
from zarr.types import DIMENSION_SEPARATOR
|
|
7
|
+
|
|
6
8
|
from ngio.common import compute_masking_roi
|
|
7
9
|
from ngio.images._abstract_image import AbstractImage
|
|
8
10
|
from ngio.images._create import create_empty_label_container
|
|
@@ -94,7 +96,7 @@ class Label(AbstractImage[LabelMetaHandler]):
|
|
|
94
96
|
) -> None:
|
|
95
97
|
"""Consolidate the label on disk."""
|
|
96
98
|
self._consolidate(
|
|
97
|
-
order=
|
|
99
|
+
order="nearest",
|
|
98
100
|
mode=mode,
|
|
99
101
|
)
|
|
100
102
|
|
|
@@ -167,6 +169,8 @@ class LabelsContainer:
|
|
|
167
169
|
axes_names: Sequence[str] | None = None,
|
|
168
170
|
chunks: Sequence[int] | None = None,
|
|
169
171
|
dtype: str = "uint32",
|
|
172
|
+
dimension_separator: DIMENSION_SEPARATOR | None = None,
|
|
173
|
+
compressor=None,
|
|
170
174
|
overwrite: bool = False,
|
|
171
175
|
) -> "Label":
|
|
172
176
|
"""Create an empty OME-Zarr label from a reference image.
|
|
@@ -184,6 +188,10 @@ class LabelsContainer:
|
|
|
184
188
|
For labels, the channel axis is not allowed.
|
|
185
189
|
chunks (Sequence[int] | None): The chunk shape of the new image.
|
|
186
190
|
dtype (str): The data type of the new label.
|
|
191
|
+
dimension_separator (DIMENSION_SEPARATOR | None): The separator to use for
|
|
192
|
+
dimensions. If None it will use the same as the reference image.
|
|
193
|
+
compressor: The compressor to use. If None it will use
|
|
194
|
+
the same as the reference image.
|
|
187
195
|
overwrite (bool): Whether to overwrite an existing image.
|
|
188
196
|
|
|
189
197
|
Returns:
|
|
@@ -226,6 +234,8 @@ def derive_label(
|
|
|
226
234
|
pixel_size: PixelSize | None = None,
|
|
227
235
|
axes_names: Sequence[str] | None = None,
|
|
228
236
|
chunks: Sequence[int] | None = None,
|
|
237
|
+
dimension_separator: DIMENSION_SEPARATOR | None = None,
|
|
238
|
+
compressor=None,
|
|
229
239
|
dtype: str = "uint32",
|
|
230
240
|
overwrite: bool = False,
|
|
231
241
|
) -> None:
|
|
@@ -242,6 +252,10 @@ def derive_label(
|
|
|
242
252
|
For labels, the channel axis is not allowed.
|
|
243
253
|
chunks (Sequence[int] | None): The chunk shape of the new image.
|
|
244
254
|
dtype (str): The data type of the new label.
|
|
255
|
+
dimension_separator (DIMENSION_SEPARATOR | None): The separator to use for
|
|
256
|
+
dimensions. If None it will use the same as the reference image.
|
|
257
|
+
compressor: The compressor to use. If None it will use
|
|
258
|
+
the same as the reference image.
|
|
245
259
|
overwrite (bool): Whether to overwrite an existing image.
|
|
246
260
|
|
|
247
261
|
Returns:
|
|
@@ -257,8 +271,8 @@ def derive_label(
|
|
|
257
271
|
pixel_size = ref_image.pixel_size
|
|
258
272
|
|
|
259
273
|
if axes_names is None:
|
|
260
|
-
axes_names = ref_meta.
|
|
261
|
-
c_axis = ref_meta.
|
|
274
|
+
axes_names = ref_meta.axes_handler.axes_names
|
|
275
|
+
c_axis = ref_meta.axes_handler.get_index("c")
|
|
262
276
|
else:
|
|
263
277
|
if "c" in axes_names:
|
|
264
278
|
raise NgioValidationError(
|
|
@@ -291,6 +305,11 @@ def derive_label(
|
|
|
291
305
|
axes_names = list(axes_names)
|
|
292
306
|
axes_names = axes_names[:c_axis] + axes_names[c_axis + 1 :]
|
|
293
307
|
|
|
308
|
+
if dimension_separator is None:
|
|
309
|
+
dimension_separator = ref_image.zarr_array._dimension_separator # type: ignore
|
|
310
|
+
if compressor is None:
|
|
311
|
+
compressor = ref_image.zarr_array.compressor # type: ignore
|
|
312
|
+
|
|
294
313
|
_ = create_empty_label_container(
|
|
295
314
|
store=store,
|
|
296
315
|
shape=shape,
|
|
@@ -305,6 +324,8 @@ def derive_label(
|
|
|
305
324
|
axes_names=axes_names,
|
|
306
325
|
chunks=chunks,
|
|
307
326
|
dtype=dtype,
|
|
327
|
+
dimension_separator=dimension_separator, # type: ignore
|
|
328
|
+
compressor=compressor, # type: ignore
|
|
308
329
|
overwrite=overwrite,
|
|
309
330
|
version=ref_meta.version,
|
|
310
331
|
name=name,
|
ngio/images/_masked_image.py
CHANGED
|
@@ -6,14 +6,6 @@ from typing import Literal
|
|
|
6
6
|
import dask.array as da
|
|
7
7
|
import numpy as np
|
|
8
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
9
|
from ngio.images._image import (
|
|
18
10
|
ChannelSlicingInputType,
|
|
19
11
|
Image,
|
|
@@ -21,6 +13,13 @@ from ngio.images._image import (
|
|
|
21
13
|
add_channel_selection_to_slicing_dict,
|
|
22
14
|
)
|
|
23
15
|
from ngio.images._label import Label
|
|
16
|
+
from ngio.io_pipes import (
|
|
17
|
+
DaskGetterMasked,
|
|
18
|
+
DaskSetterMasked,
|
|
19
|
+
NumpyGetterMasked,
|
|
20
|
+
NumpySetterMasked,
|
|
21
|
+
TransformProtocol,
|
|
22
|
+
)
|
|
24
23
|
from ngio.ome_zarr_meta import ImageMetaHandler, LabelMetaHandler
|
|
25
24
|
from ngio.tables import MaskingRoiTable
|
|
26
25
|
from ngio.utils import (
|
|
@@ -70,7 +69,7 @@ class MaskedImage(Image):
|
|
|
70
69
|
axes_order: Sequence[str] | None = None,
|
|
71
70
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
72
71
|
**slicing_kwargs: slice | int | Sequence[int],
|
|
73
|
-
) ->
|
|
72
|
+
) -> np.ndarray:
|
|
74
73
|
"""Return the array for a given ROI."""
|
|
75
74
|
roi = self._masking_roi_table.get_label(label)
|
|
76
75
|
roi = roi.zoom(zoom_factor)
|
|
@@ -111,7 +110,7 @@ class MaskedImage(Image):
|
|
|
111
110
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
112
111
|
mode: Literal["numpy", "dask"] = "numpy",
|
|
113
112
|
**slicing_kwargs: slice | int | Sequence[int],
|
|
114
|
-
) ->
|
|
113
|
+
) -> np.ndarray | da.Array:
|
|
115
114
|
"""Return the array for a given ROI."""
|
|
116
115
|
roi = self._masking_roi_table.get_label(label)
|
|
117
116
|
roi = roi.zoom(zoom_factor)
|
|
@@ -127,7 +126,7 @@ class MaskedImage(Image):
|
|
|
127
126
|
def set_roi( # type: ignore (this ignore the method override issue)
|
|
128
127
|
self,
|
|
129
128
|
label: int,
|
|
130
|
-
patch:
|
|
129
|
+
patch: np.ndarray | da.Array,
|
|
131
130
|
zoom_factor: float = 1.0,
|
|
132
131
|
channel_selection: ChannelSlicingInputType | None = None,
|
|
133
132
|
axes_order: Sequence[str] | None = None,
|
|
@@ -153,7 +152,7 @@ class MaskedImage(Image):
|
|
|
153
152
|
zoom_factor: float = 1.0,
|
|
154
153
|
axes_order: Sequence[str] | None = None,
|
|
155
154
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
156
|
-
|
|
155
|
+
allow_rescaling: bool = True,
|
|
157
156
|
**slicing_kwargs: SlicingInputType,
|
|
158
157
|
) -> np.ndarray:
|
|
159
158
|
"""Return the masked array for a given label as a NumPy array."""
|
|
@@ -163,18 +162,16 @@ class MaskedImage(Image):
|
|
|
163
162
|
|
|
164
163
|
roi = self._masking_roi_table.get_label(label)
|
|
165
164
|
roi = roi.zoom(zoom_factor)
|
|
166
|
-
masked_getter =
|
|
165
|
+
masked_getter = NumpyGetterMasked(
|
|
167
166
|
roi=roi,
|
|
168
167
|
zarr_array=self.zarr_array,
|
|
169
168
|
label_zarr_array=self._label.zarr_array,
|
|
170
169
|
dimensions=self.dimensions,
|
|
171
|
-
pixel_size=self.pixel_size,
|
|
172
170
|
label_dimensions=self._label.dimensions,
|
|
173
|
-
label_pixel_size=self._label.pixel_size,
|
|
174
171
|
axes_order=axes_order,
|
|
175
172
|
transforms=transforms,
|
|
176
173
|
slicing_dict=slicing_kwargs,
|
|
177
|
-
|
|
174
|
+
allow_rescaling=allow_rescaling,
|
|
178
175
|
)
|
|
179
176
|
return masked_getter()
|
|
180
177
|
|
|
@@ -185,7 +182,7 @@ class MaskedImage(Image):
|
|
|
185
182
|
zoom_factor: float = 1.0,
|
|
186
183
|
axes_order: Sequence[str] | None = None,
|
|
187
184
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
188
|
-
|
|
185
|
+
allow_rescaling: bool = True,
|
|
189
186
|
**slicing_kwargs: SlicingInputType,
|
|
190
187
|
) -> da.Array:
|
|
191
188
|
"""Return the masked array for a given label as a Dask array."""
|
|
@@ -195,18 +192,16 @@ class MaskedImage(Image):
|
|
|
195
192
|
|
|
196
193
|
roi = self._masking_roi_table.get_label(label)
|
|
197
194
|
roi = roi.zoom(zoom_factor)
|
|
198
|
-
masked_getter =
|
|
195
|
+
masked_getter = DaskGetterMasked(
|
|
199
196
|
roi=roi,
|
|
200
197
|
zarr_array=self.zarr_array,
|
|
201
198
|
label_zarr_array=self._label.zarr_array,
|
|
202
199
|
dimensions=self.dimensions,
|
|
203
|
-
pixel_size=self.pixel_size,
|
|
204
200
|
label_dimensions=self._label.dimensions,
|
|
205
|
-
label_pixel_size=self._label.pixel_size,
|
|
206
201
|
axes_order=axes_order,
|
|
207
202
|
transforms=transforms,
|
|
208
203
|
slicing_dict=slicing_kwargs,
|
|
209
|
-
|
|
204
|
+
allow_rescaling=allow_rescaling,
|
|
210
205
|
)
|
|
211
206
|
return masked_getter()
|
|
212
207
|
|
|
@@ -218,42 +213,38 @@ class MaskedImage(Image):
|
|
|
218
213
|
axes_order: Sequence[str] | None = None,
|
|
219
214
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
220
215
|
mode: Literal["numpy", "dask"] = "numpy",
|
|
221
|
-
|
|
216
|
+
allow_rescaling: bool = True,
|
|
222
217
|
**slicing_kwargs: SlicingInputType,
|
|
223
|
-
) ->
|
|
218
|
+
) -> np.ndarray | da.Array:
|
|
224
219
|
"""Return the masked array for a given label."""
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
**slicing_kwargs,
|
|
244
|
-
)
|
|
245
|
-
else:
|
|
246
|
-
raise ValueError(f"Unknown mode: {mode}")
|
|
220
|
+
slicing_kwargs = add_channel_selection_to_slicing_dict(
|
|
221
|
+
image=self, channel_selection=channel_selection, slicing_dict=slicing_kwargs
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
roi = self._masking_roi_table.get_label(label)
|
|
225
|
+
roi = roi.zoom(zoom_factor)
|
|
226
|
+
masked_getter = NumpyGetterMasked(
|
|
227
|
+
roi=roi,
|
|
228
|
+
zarr_array=self.zarr_array,
|
|
229
|
+
label_zarr_array=self._label.zarr_array,
|
|
230
|
+
dimensions=self.dimensions,
|
|
231
|
+
label_dimensions=self._label.dimensions,
|
|
232
|
+
axes_order=axes_order,
|
|
233
|
+
transforms=transforms,
|
|
234
|
+
slicing_dict=slicing_kwargs,
|
|
235
|
+
allow_rescaling=allow_rescaling,
|
|
236
|
+
)
|
|
237
|
+
return masked_getter()
|
|
247
238
|
|
|
248
239
|
def set_roi_masked(
|
|
249
240
|
self,
|
|
250
241
|
label: int,
|
|
251
|
-
patch:
|
|
242
|
+
patch: np.ndarray | da.Array,
|
|
252
243
|
channel_selection: ChannelSlicingInputType | None = None,
|
|
253
244
|
axes_order: Sequence[str] | None = None,
|
|
254
245
|
zoom_factor: float = 1.0,
|
|
255
246
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
256
|
-
|
|
247
|
+
allow_rescaling: bool = True,
|
|
257
248
|
**slicing_kwargs: SlicingInputType,
|
|
258
249
|
) -> None:
|
|
259
250
|
"""Set the masked array for a given label."""
|
|
@@ -264,33 +255,29 @@ class MaskedImage(Image):
|
|
|
264
255
|
roi = self._masking_roi_table.get_label(label)
|
|
265
256
|
roi = roi.zoom(zoom_factor)
|
|
266
257
|
if isinstance(patch, da.Array):
|
|
267
|
-
path_setter =
|
|
258
|
+
path_setter = DaskSetterMasked(
|
|
268
259
|
roi=roi,
|
|
269
260
|
zarr_array=self.zarr_array,
|
|
270
261
|
label_zarr_array=self._label.zarr_array,
|
|
271
262
|
dimensions=self.dimensions,
|
|
272
|
-
pixel_size=self.pixel_size,
|
|
273
263
|
label_dimensions=self._label.dimensions,
|
|
274
|
-
label_pixel_size=self._label.pixel_size,
|
|
275
264
|
axes_order=axes_order,
|
|
276
265
|
transforms=transforms,
|
|
277
266
|
slicing_dict=slicing_kwargs,
|
|
278
|
-
|
|
267
|
+
allow_rescaling=allow_rescaling,
|
|
279
268
|
)
|
|
280
269
|
path_setter(patch)
|
|
281
270
|
elif isinstance(patch, np.ndarray):
|
|
282
|
-
path_setter =
|
|
271
|
+
path_setter = NumpySetterMasked(
|
|
283
272
|
roi=roi,
|
|
284
273
|
zarr_array=self.zarr_array,
|
|
285
274
|
label_zarr_array=self._label.zarr_array,
|
|
286
275
|
dimensions=self.dimensions,
|
|
287
|
-
pixel_size=self.pixel_size,
|
|
288
276
|
label_dimensions=self._label.dimensions,
|
|
289
|
-
label_pixel_size=self._label.pixel_size,
|
|
290
277
|
axes_order=axes_order,
|
|
291
278
|
transforms=transforms,
|
|
292
279
|
slicing_dict=slicing_kwargs,
|
|
293
|
-
|
|
280
|
+
allow_rescaling=allow_rescaling,
|
|
294
281
|
)
|
|
295
282
|
path_setter(patch)
|
|
296
283
|
else:
|
|
@@ -378,7 +365,7 @@ class MaskedLabel(Label):
|
|
|
378
365
|
mode: Literal["numpy", "dask"] = "numpy",
|
|
379
366
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
380
367
|
**slicing_kwargs: slice | int | Sequence[int],
|
|
381
|
-
) ->
|
|
368
|
+
) -> np.ndarray | da.Array:
|
|
382
369
|
"""Return the array for a given ROI."""
|
|
383
370
|
roi = self._masking_roi_table.get_label(label)
|
|
384
371
|
roi = roi.zoom(zoom_factor)
|
|
@@ -393,7 +380,7 @@ class MaskedLabel(Label):
|
|
|
393
380
|
def set_roi(
|
|
394
381
|
self,
|
|
395
382
|
label: int,
|
|
396
|
-
patch:
|
|
383
|
+
patch: np.ndarray | da.Array,
|
|
397
384
|
zoom_factor: float = 1.0,
|
|
398
385
|
axes_order: Sequence[str] | None = None,
|
|
399
386
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
@@ -416,24 +403,22 @@ class MaskedLabel(Label):
|
|
|
416
403
|
zoom_factor: float = 1.0,
|
|
417
404
|
axes_order: Sequence[str] | None = None,
|
|
418
405
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
419
|
-
|
|
406
|
+
allow_rescaling: bool = True,
|
|
420
407
|
**slicing_kwargs: SlicingInputType,
|
|
421
408
|
) -> np.ndarray:
|
|
422
409
|
"""Return the masked array for a given label as a NumPy array."""
|
|
423
410
|
roi = self._masking_roi_table.get_label(label)
|
|
424
411
|
roi = roi.zoom(zoom_factor)
|
|
425
|
-
masked_getter =
|
|
412
|
+
masked_getter = NumpyGetterMasked(
|
|
426
413
|
roi=roi,
|
|
427
414
|
zarr_array=self.zarr_array,
|
|
428
415
|
label_zarr_array=self._label.zarr_array,
|
|
429
416
|
dimensions=self.dimensions,
|
|
430
|
-
pixel_size=self.pixel_size,
|
|
431
417
|
label_dimensions=self._label.dimensions,
|
|
432
|
-
label_pixel_size=self._label.pixel_size,
|
|
433
418
|
axes_order=axes_order,
|
|
434
419
|
transforms=transforms,
|
|
435
420
|
slicing_dict=slicing_kwargs,
|
|
436
|
-
|
|
421
|
+
allow_rescaling=allow_rescaling,
|
|
437
422
|
)
|
|
438
423
|
return masked_getter()
|
|
439
424
|
|
|
@@ -443,24 +428,22 @@ class MaskedLabel(Label):
|
|
|
443
428
|
zoom_factor: float = 1.0,
|
|
444
429
|
axes_order: Sequence[str] | None = None,
|
|
445
430
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
446
|
-
|
|
431
|
+
allow_rescaling: bool = True,
|
|
447
432
|
**slicing_kwargs: SlicingInputType,
|
|
448
433
|
) -> da.Array:
|
|
449
434
|
"""Return the masked array for a given label as a Dask array."""
|
|
450
435
|
roi = self._masking_roi_table.get_label(label)
|
|
451
436
|
roi = roi.zoom(zoom_factor)
|
|
452
|
-
masked_getter =
|
|
437
|
+
masked_getter = DaskGetterMasked(
|
|
453
438
|
roi=roi,
|
|
454
439
|
zarr_array=self.zarr_array,
|
|
455
440
|
label_zarr_array=self._label.zarr_array,
|
|
456
441
|
dimensions=self.dimensions,
|
|
457
|
-
pixel_size=self.pixel_size,
|
|
458
442
|
label_dimensions=self._label.dimensions,
|
|
459
|
-
label_pixel_size=self._label.pixel_size,
|
|
460
443
|
axes_order=axes_order,
|
|
461
444
|
transforms=transforms,
|
|
462
445
|
slicing_dict=slicing_kwargs,
|
|
463
|
-
|
|
446
|
+
allow_rescaling=allow_rescaling,
|
|
464
447
|
)
|
|
465
448
|
return masked_getter()
|
|
466
449
|
|
|
@@ -471,9 +454,9 @@ class MaskedLabel(Label):
|
|
|
471
454
|
axes_order: Sequence[str] | None = None,
|
|
472
455
|
mode: Literal["numpy", "dask"] = "numpy",
|
|
473
456
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
474
|
-
|
|
457
|
+
allow_rescaling: bool = True,
|
|
475
458
|
**slicing_kwargs: SlicingInputType,
|
|
476
|
-
) ->
|
|
459
|
+
) -> np.ndarray | da.Array:
|
|
477
460
|
"""Return the masked array for a given label."""
|
|
478
461
|
if mode == "numpy":
|
|
479
462
|
return self.get_roi_masked_as_numpy(
|
|
@@ -481,7 +464,7 @@ class MaskedLabel(Label):
|
|
|
481
464
|
zoom_factor=zoom_factor,
|
|
482
465
|
axes_order=axes_order,
|
|
483
466
|
transforms=transforms,
|
|
484
|
-
|
|
467
|
+
allow_rescaling=allow_rescaling,
|
|
485
468
|
**slicing_kwargs,
|
|
486
469
|
)
|
|
487
470
|
|
|
@@ -491,7 +474,7 @@ class MaskedLabel(Label):
|
|
|
491
474
|
zoom_factor=zoom_factor,
|
|
492
475
|
axes_order=axes_order,
|
|
493
476
|
transforms=transforms,
|
|
494
|
-
|
|
477
|
+
allow_rescaling=allow_rescaling,
|
|
495
478
|
**slicing_kwargs,
|
|
496
479
|
)
|
|
497
480
|
else:
|
|
@@ -500,44 +483,40 @@ class MaskedLabel(Label):
|
|
|
500
483
|
def set_roi_masked(
|
|
501
484
|
self,
|
|
502
485
|
label: int,
|
|
503
|
-
patch:
|
|
486
|
+
patch: np.ndarray | da.Array,
|
|
504
487
|
axes_order: Sequence[str] | None = None,
|
|
505
488
|
zoom_factor: float = 1.0,
|
|
506
489
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
507
|
-
|
|
490
|
+
allow_rescaling: bool = True,
|
|
508
491
|
**slicing_kwargs: SlicingInputType,
|
|
509
492
|
) -> None:
|
|
510
493
|
"""Set the masked array for a given label."""
|
|
511
494
|
roi = self._masking_roi_table.get_label(label)
|
|
512
495
|
roi = roi.zoom(zoom_factor)
|
|
513
496
|
if isinstance(patch, da.Array):
|
|
514
|
-
path_setter =
|
|
497
|
+
path_setter = DaskSetterMasked(
|
|
515
498
|
roi=roi,
|
|
516
499
|
zarr_array=self.zarr_array,
|
|
517
500
|
label_zarr_array=self._label.zarr_array,
|
|
518
501
|
dimensions=self.dimensions,
|
|
519
|
-
pixel_size=self.pixel_size,
|
|
520
502
|
label_dimensions=self._label.dimensions,
|
|
521
|
-
label_pixel_size=self._label.pixel_size,
|
|
522
503
|
axes_order=axes_order,
|
|
523
504
|
transforms=transforms,
|
|
524
505
|
slicing_dict=slicing_kwargs,
|
|
525
|
-
|
|
506
|
+
allow_rescaling=allow_rescaling,
|
|
526
507
|
)
|
|
527
508
|
path_setter(patch)
|
|
528
509
|
elif isinstance(patch, np.ndarray):
|
|
529
|
-
path_setter =
|
|
510
|
+
path_setter = NumpySetterMasked(
|
|
530
511
|
roi=roi,
|
|
531
512
|
zarr_array=self.zarr_array,
|
|
532
513
|
label_zarr_array=self._label.zarr_array,
|
|
533
514
|
dimensions=self.dimensions,
|
|
534
|
-
pixel_size=self.pixel_size,
|
|
535
515
|
label_dimensions=self._label.dimensions,
|
|
536
|
-
label_pixel_size=self._label.pixel_size,
|
|
537
516
|
axes_order=axes_order,
|
|
538
517
|
transforms=transforms,
|
|
539
518
|
slicing_dict=slicing_kwargs,
|
|
540
|
-
|
|
519
|
+
allow_rescaling=allow_rescaling,
|
|
541
520
|
)
|
|
542
521
|
path_setter(patch)
|
|
543
522
|
else:
|
|
@@ -4,6 +4,7 @@ import warnings
|
|
|
4
4
|
from collections.abc import Sequence
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
|
+
from zarr.types import DIMENSION_SEPARATOR
|
|
7
8
|
|
|
8
9
|
from ngio.images._create import create_empty_image_container
|
|
9
10
|
from ngio.images._image import Image, ImagesContainer
|
|
@@ -408,6 +409,8 @@ class OmeZarrContainer:
|
|
|
408
409
|
name: str | None = None,
|
|
409
410
|
chunks: Sequence[int] | None = None,
|
|
410
411
|
dtype: str | None = None,
|
|
412
|
+
dimension_separator: DIMENSION_SEPARATOR | None = None,
|
|
413
|
+
compressor=None,
|
|
411
414
|
copy_labels: bool = False,
|
|
412
415
|
copy_tables: bool = False,
|
|
413
416
|
overwrite: bool = False,
|
|
@@ -425,6 +428,11 @@ class OmeZarrContainer:
|
|
|
425
428
|
chunks (Sequence[int] | None): The chunk shape of the new image.
|
|
426
429
|
dtype (str | None): The data type of the new image.
|
|
427
430
|
name (str | None): The name of the new image.
|
|
431
|
+
dimension_separator (DIMENSION_SEPARATOR | None): The dimension
|
|
432
|
+
separator to use. If None, the dimension separator of the
|
|
433
|
+
reference image will be used.
|
|
434
|
+
compressor: The compressor to use. If None, the compressor of the
|
|
435
|
+
reference image will be used.
|
|
428
436
|
copy_labels (bool): Whether to copy the labels from the reference image.
|
|
429
437
|
copy_tables (bool): Whether to copy the tables from the reference image.
|
|
430
438
|
overwrite (bool): Whether to overwrite an existing image.
|
|
@@ -443,6 +451,8 @@ class OmeZarrContainer:
|
|
|
443
451
|
name=name,
|
|
444
452
|
chunks=chunks,
|
|
445
453
|
dtype=dtype,
|
|
454
|
+
dimension_separator=dimension_separator,
|
|
455
|
+
compressor=compressor,
|
|
446
456
|
overwrite=overwrite,
|
|
447
457
|
)
|
|
448
458
|
|
|
@@ -589,7 +599,7 @@ class OmeZarrContainer:
|
|
|
589
599
|
backend=backend,
|
|
590
600
|
)
|
|
591
601
|
|
|
592
|
-
def build_image_roi_table(self, name: str = "image") -> RoiTable:
|
|
602
|
+
def build_image_roi_table(self, name: str | None = "image") -> RoiTable:
|
|
593
603
|
"""Compute the ROI table for an image."""
|
|
594
604
|
return self.get_image().build_image_roi_table(name=name)
|
|
595
605
|
|
|
@@ -683,6 +693,8 @@ class OmeZarrContainer:
|
|
|
683
693
|
axes_names: Sequence[str] | None = None,
|
|
684
694
|
chunks: Sequence[int] | None = None,
|
|
685
695
|
dtype: str = "uint32",
|
|
696
|
+
dimension_separator: DIMENSION_SEPARATOR | None = None,
|
|
697
|
+
compressor=None,
|
|
686
698
|
overwrite: bool = False,
|
|
687
699
|
) -> "Label":
|
|
688
700
|
"""Create an empty OME-Zarr label from a reference image.
|
|
@@ -699,6 +711,11 @@ class OmeZarrContainer:
|
|
|
699
711
|
For labels, the channel axis is not allowed.
|
|
700
712
|
chunks (Sequence[int] | None): The chunk shape of the new image.
|
|
701
713
|
dtype (str): The data type of the new label.
|
|
714
|
+
dimension_separator (DIMENSION_SEPARATOR | None): The dimension
|
|
715
|
+
separator to use. If None, the dimension separator of the
|
|
716
|
+
reference image will be used.
|
|
717
|
+
compressor: The compressor to use. If None, the compressor of the
|
|
718
|
+
reference image will be used.
|
|
702
719
|
overwrite (bool): Whether to overwrite an existing image.
|
|
703
720
|
|
|
704
721
|
Returns:
|
|
@@ -715,6 +732,8 @@ class OmeZarrContainer:
|
|
|
715
732
|
axes_names=axes_names,
|
|
716
733
|
chunks=chunks,
|
|
717
734
|
dtype=dtype,
|
|
735
|
+
dimension_separator=dimension_separator,
|
|
736
|
+
compressor=compressor,
|
|
718
737
|
overwrite=overwrite,
|
|
719
738
|
)
|
|
720
739
|
|
|
@@ -819,6 +838,8 @@ def create_empty_ome_zarr(
|
|
|
819
838
|
name: str | None = None,
|
|
820
839
|
chunks: Sequence[int] | None = None,
|
|
821
840
|
dtype: str = "uint16",
|
|
841
|
+
dimension_separator: DIMENSION_SEPARATOR = "/",
|
|
842
|
+
compressor="default",
|
|
822
843
|
channel_labels: list[str] | None = None,
|
|
823
844
|
channel_wavelengths: list[str] | None = None,
|
|
824
845
|
channel_colors: Sequence[str] | None = None,
|
|
@@ -851,6 +872,9 @@ def create_empty_ome_zarr(
|
|
|
851
872
|
chunks (Sequence[int] | None, optional): The chunk shape. If None the shape
|
|
852
873
|
is used. Defaults to None.
|
|
853
874
|
dtype (str, optional): The data type of the image. Defaults to "uint16".
|
|
875
|
+
dimension_separator (DIMENSION_SEPARATOR): The dimension
|
|
876
|
+
separator to use. Defaults to "/".
|
|
877
|
+
compressor: The compressor to use. Defaults to "default".
|
|
854
878
|
channel_labels (list[str] | None, optional): The labels of the channels.
|
|
855
879
|
Defaults to None.
|
|
856
880
|
channel_wavelengths (list[str] | None, optional): The wavelengths of the
|
|
@@ -879,6 +903,8 @@ def create_empty_ome_zarr(
|
|
|
879
903
|
name=name,
|
|
880
904
|
chunks=chunks,
|
|
881
905
|
dtype=dtype,
|
|
906
|
+
dimension_separator=dimension_separator,
|
|
907
|
+
compressor=compressor,
|
|
882
908
|
overwrite=overwrite,
|
|
883
909
|
version=version,
|
|
884
910
|
)
|
|
@@ -913,6 +939,8 @@ def create_ome_zarr_from_array(
|
|
|
913
939
|
channel_active: Sequence[bool] | None = None,
|
|
914
940
|
name: str | None = None,
|
|
915
941
|
chunks: Sequence[int] | None = None,
|
|
942
|
+
dimension_separator: DIMENSION_SEPARATOR = "/",
|
|
943
|
+
compressor: str = "default",
|
|
916
944
|
overwrite: bool = False,
|
|
917
945
|
version: NgffVersions = DefaultNgffVersion,
|
|
918
946
|
) -> OmeZarrContainer:
|
|
@@ -950,6 +978,9 @@ def create_ome_zarr_from_array(
|
|
|
950
978
|
Defaults to None.
|
|
951
979
|
channel_active (Sequence[bool] | None, optional): Whether the channels are
|
|
952
980
|
active. Defaults to None.
|
|
981
|
+
dimension_separator (DIMENSION_SEPARATOR): The separator to use for
|
|
982
|
+
dimensions. Defaults to "/".
|
|
983
|
+
compressor: The compressor to use. Defaults to "default".
|
|
953
984
|
overwrite (bool, optional): Whether to overwrite an existing image.
|
|
954
985
|
Defaults to True.
|
|
955
986
|
version (str, optional): The version of the OME-Zarr specification.
|
|
@@ -971,6 +1002,8 @@ def create_ome_zarr_from_array(
|
|
|
971
1002
|
chunks=chunks,
|
|
972
1003
|
dtype=str(array.dtype),
|
|
973
1004
|
overwrite=overwrite,
|
|
1005
|
+
dimension_separator=dimension_separator,
|
|
1006
|
+
compressor=compressor,
|
|
974
1007
|
version=version,
|
|
975
1008
|
)
|
|
976
1009
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""I/O pipes for reading and writing data from zarr to numpy and dask arrays."""
|
|
2
|
+
|
|
3
|
+
from ngio.io_pipes._io_pipes import (
|
|
4
|
+
DaskGetter,
|
|
5
|
+
DaskSetter,
|
|
6
|
+
DataGetter,
|
|
7
|
+
DataSetter,
|
|
8
|
+
NumpyGetter,
|
|
9
|
+
NumpySetter,
|
|
10
|
+
)
|
|
11
|
+
from ngio.io_pipes._io_pipes_masked import (
|
|
12
|
+
DaskGetterMasked,
|
|
13
|
+
DaskSetterMasked,
|
|
14
|
+
NumpyGetterMasked,
|
|
15
|
+
NumpySetterMasked,
|
|
16
|
+
)
|
|
17
|
+
from ngio.io_pipes._io_pipes_roi import (
|
|
18
|
+
DaskRoiGetter,
|
|
19
|
+
DaskRoiSetter,
|
|
20
|
+
NumpyRoiGetter,
|
|
21
|
+
NumpyRoiSetter,
|
|
22
|
+
)
|
|
23
|
+
from ngio.io_pipes._io_pipes_utils import SlicingInputType
|
|
24
|
+
from ngio.io_pipes._match_shape import dask_match_shape, numpy_match_shape
|
|
25
|
+
from ngio.io_pipes._ops_slices import SlicingOps, SlicingType
|
|
26
|
+
from ngio.io_pipes._ops_transforms import TransformProtocol
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"DaskGetter",
|
|
30
|
+
"DaskGetterMasked",
|
|
31
|
+
"DaskRoiGetter",
|
|
32
|
+
"DaskRoiSetter",
|
|
33
|
+
"DaskSetter",
|
|
34
|
+
"DaskSetterMasked",
|
|
35
|
+
"DataGetter",
|
|
36
|
+
"DataSetter",
|
|
37
|
+
"NumpyGetter",
|
|
38
|
+
"NumpyGetterMasked",
|
|
39
|
+
"NumpyRoiGetter",
|
|
40
|
+
"NumpyRoiSetter",
|
|
41
|
+
"NumpySetter",
|
|
42
|
+
"NumpySetterMasked",
|
|
43
|
+
"SlicingInputType",
|
|
44
|
+
"SlicingOps",
|
|
45
|
+
"SlicingType",
|
|
46
|
+
"TransformProtocol",
|
|
47
|
+
"dask_match_shape",
|
|
48
|
+
"numpy_match_shape",
|
|
49
|
+
]
|