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