ngio 0.3.4__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.
Files changed (61) hide show
  1. ngio/__init__.py +6 -0
  2. ngio/common/__init__.py +50 -48
  3. ngio/common/_array_io_pipes.py +549 -0
  4. ngio/common/_array_io_utils.py +508 -0
  5. ngio/common/_dimensions.py +63 -27
  6. ngio/common/_masking_roi.py +38 -10
  7. ngio/common/_pyramid.py +9 -7
  8. ngio/common/_roi.py +571 -72
  9. ngio/common/_synt_images_utils.py +101 -0
  10. ngio/common/_zoom.py +17 -12
  11. ngio/common/transforms/__init__.py +5 -0
  12. ngio/common/transforms/_label.py +12 -0
  13. ngio/common/transforms/_zoom.py +109 -0
  14. ngio/experimental/__init__.py +5 -0
  15. ngio/experimental/iterators/__init__.py +17 -0
  16. ngio/experimental/iterators/_abstract_iterator.py +170 -0
  17. ngio/experimental/iterators/_feature.py +151 -0
  18. ngio/experimental/iterators/_image_processing.py +169 -0
  19. ngio/experimental/iterators/_rois_utils.py +127 -0
  20. ngio/experimental/iterators/_segmentation.py +278 -0
  21. ngio/hcs/_plate.py +41 -36
  22. ngio/images/__init__.py +22 -1
  23. ngio/images/_abstract_image.py +247 -117
  24. ngio/images/_create.py +15 -15
  25. ngio/images/_create_synt_container.py +128 -0
  26. ngio/images/_image.py +425 -62
  27. ngio/images/_label.py +33 -30
  28. ngio/images/_masked_image.py +396 -122
  29. ngio/images/_ome_zarr_container.py +203 -66
  30. ngio/{common → images}/_table_ops.py +41 -41
  31. ngio/ome_zarr_meta/ngio_specs/__init__.py +2 -8
  32. ngio/ome_zarr_meta/ngio_specs/_axes.py +151 -128
  33. ngio/ome_zarr_meta/ngio_specs/_channels.py +55 -18
  34. ngio/ome_zarr_meta/ngio_specs/_dataset.py +7 -7
  35. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +6 -15
  36. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +11 -68
  37. ngio/ome_zarr_meta/v04/_v04_spec_utils.py +1 -1
  38. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
  39. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  40. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
  41. ngio/resources/__init__.py +54 -0
  42. ngio/resources/resource_model.py +35 -0
  43. ngio/tables/backends/_abstract_backend.py +5 -6
  44. ngio/tables/backends/_anndata.py +1 -2
  45. ngio/tables/backends/_anndata_utils.py +3 -3
  46. ngio/tables/backends/_non_zarr_backends.py +1 -1
  47. ngio/tables/backends/_table_backends.py +0 -1
  48. ngio/tables/backends/_utils.py +3 -3
  49. ngio/tables/v1/_roi_table.py +156 -69
  50. ngio/utils/__init__.py +2 -3
  51. ngio/utils/_logger.py +19 -0
  52. ngio/utils/_zarr_utils.py +1 -5
  53. {ngio-0.3.4.dist-info → ngio-0.4.0a1.dist-info}/METADATA +12 -10
  54. ngio-0.4.0a1.dist-info/RECORD +76 -0
  55. ngio/common/_array_pipe.py +0 -288
  56. ngio/common/_axes_transforms.py +0 -64
  57. ngio/common/_common_types.py +0 -5
  58. ngio/common/_slicer.py +0 -96
  59. ngio-0.3.4.dist-info/RECORD +0 -61
  60. {ngio-0.3.4.dist-info → ngio-0.4.0a1.dist-info}/WHEEL +0 -0
  61. {ngio-0.3.4.dist-info → ngio-0.4.0a1.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +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.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 get_roi(
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: Collection[str] | None = None,
55
- mode: Literal["numpy", "dask", "delayed"] = "numpy",
56
- **slice_kwargs: slice | int | Iterable[int],
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.get(label)
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, axes_order=axes_order, mode=mode, **slice_kwargs
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
- axes_order: Collection[str] | None = None,
71
- **slice_kwargs: slice | int | Iterable[int],
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.get(label)
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, patch=patch, axes_order=axes_order, **slice_kwargs
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
- axes_order: Collection[str] | None = None,
84
- mode: Literal["numpy", "dask", "delayed"] = "numpy",
216
+ channel_selection: ChannelSlicingInputType | None = None,
85
217
  zoom_factor: float = 1.0,
86
- **slice_kwargs: slice | int | Iterable[int],
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
- return get_masked_roi_pipe(
90
- image=self,
91
- label=label,
92
- axes_order=axes_order,
93
- mode=mode,
94
- zoom_factor=zoom_factor,
95
- **slice_kwargs,
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
- axes_order: Collection[str] | None = None,
252
+ channel_selection: ChannelSlicingInputType | None = None,
253
+ axes_order: Sequence[str] | None = None,
103
254
  zoom_factor: float = 1.0,
104
- **slice_kwargs: slice | int | Iterable[int],
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
- 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,
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: Collection[str] | None = None,
156
- mode: Literal["numpy", "dask", "delayed"] = "numpy",
157
- **slice_kwargs: slice | int | Iterable[int],
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.get(label)
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, axes_order=axes_order, mode=mode, **slice_kwargs
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: Collection[str] | None = None,
172
- **slice_kwargs: slice | int | Iterable[int],
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.get(label)
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, patch=patch, axes_order=axes_order, **slice_kwargs
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
- **slice_kwargs: slice | int | Iterable[int],
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
- return get_masked_roi_pipe(
191
- image=self,
192
- label=label,
193
- axes_order=axes_order,
194
- mode=mode,
195
- zoom_factor=zoom_factor,
196
- **slice_kwargs,
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: Collection[str] | None = None,
504
+ axes_order: Sequence[str] | None = None,
204
505
  zoom_factor: float = 1.0,
205
- **slice_kwargs: slice | int | Iterable[int],
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
- return set_masked_roi_pipe(
209
- image=self,
210
- label=label,
211
- patch=patch,
212
- axes_order=axes_order,
213
- zoom_factor=zoom_factor,
214
- **slice_kwargs,
215
- )
216
-
217
-
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
- )
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
+ )