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.
Files changed (51) hide show
  1. ngio/__init__.py +1 -2
  2. ngio/common/__init__.py +2 -51
  3. ngio/common/_dimensions.py +223 -64
  4. ngio/common/_pyramid.py +42 -23
  5. ngio/common/_roi.py +94 -418
  6. ngio/common/_zoom.py +32 -7
  7. ngio/experimental/iterators/_abstract_iterator.py +2 -2
  8. ngio/experimental/iterators/_feature.py +10 -15
  9. ngio/experimental/iterators/_image_processing.py +18 -28
  10. ngio/experimental/iterators/_rois_utils.py +6 -6
  11. ngio/experimental/iterators/_segmentation.py +38 -54
  12. ngio/images/_abstract_image.py +136 -94
  13. ngio/images/_create.py +16 -0
  14. ngio/images/_create_synt_container.py +10 -0
  15. ngio/images/_image.py +33 -9
  16. ngio/images/_label.py +24 -3
  17. ngio/images/_masked_image.py +60 -81
  18. ngio/images/_ome_zarr_container.py +34 -1
  19. ngio/io_pipes/__init__.py +49 -0
  20. ngio/io_pipes/_io_pipes.py +286 -0
  21. ngio/io_pipes/_io_pipes_masked.py +481 -0
  22. ngio/io_pipes/_io_pipes_roi.py +143 -0
  23. ngio/io_pipes/_io_pipes_utils.py +299 -0
  24. ngio/io_pipes/_match_shape.py +376 -0
  25. ngio/io_pipes/_ops_axes.py +146 -0
  26. ngio/io_pipes/_ops_slices.py +218 -0
  27. ngio/io_pipes/_ops_transforms.py +104 -0
  28. ngio/io_pipes/_zoom_transform.py +175 -0
  29. ngio/ome_zarr_meta/__init__.py +6 -2
  30. ngio/ome_zarr_meta/ngio_specs/__init__.py +6 -4
  31. ngio/ome_zarr_meta/ngio_specs/_axes.py +182 -70
  32. ngio/ome_zarr_meta/ngio_specs/_dataset.py +47 -121
  33. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +30 -22
  34. ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +17 -1
  35. ngio/ome_zarr_meta/v04/_v04_spec_utils.py +33 -30
  36. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  37. ngio/resources/__init__.py +1 -0
  38. ngio/resources/resource_model.py +1 -0
  39. ngio/tables/v1/_roi_table.py +11 -3
  40. ngio/{common/transforms → transforms}/__init__.py +1 -1
  41. ngio/transforms/_zoom.py +19 -0
  42. ngio/utils/_zarr_utils.py +5 -1
  43. {ngio-0.4.0a2.dist-info → ngio-0.4.0a4.dist-info}/METADATA +1 -1
  44. ngio-0.4.0a4.dist-info/RECORD +83 -0
  45. ngio/common/_array_io_pipes.py +0 -554
  46. ngio/common/_array_io_utils.py +0 -508
  47. ngio/common/transforms/_label.py +0 -12
  48. ngio/common/transforms/_zoom.py +0 -109
  49. ngio-0.4.0a2.dist-info/RECORD +0 -76
  50. {ngio-0.4.0a2.dist-info → ngio-0.4.0a4.dist-info}/WHEEL +0 -0
  51. {ngio-0.4.0a2.dist-info → ngio-0.4.0a4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,481 @@
1
+ from collections.abc import Sequence
2
+
3
+ import dask.array as da
4
+ import numpy as np
5
+ import zarr
6
+ from dask.array import Array as DaskArray
7
+
8
+ from ngio.common._dimensions import Dimensions
9
+ from ngio.common._roi import Roi, RoiPixels
10
+ from ngio.io_pipes._io_pipes import (
11
+ DaskGetter,
12
+ DaskSetter,
13
+ DataGetter,
14
+ DataSetter,
15
+ NumpyGetter,
16
+ NumpySetter,
17
+ )
18
+ from ngio.io_pipes._io_pipes_roi import roi_to_slicing_dict
19
+ from ngio.io_pipes._io_pipes_utils import SlicingInputType
20
+ from ngio.io_pipes._match_shape import dask_match_shape, numpy_match_shape
21
+ from ngio.io_pipes._ops_transforms import TransformProtocol
22
+ from ngio.io_pipes._zoom_transform import BaseZoomTransform
23
+
24
+ ##############################################################
25
+ #
26
+ # Numpy Pipes
27
+ #
28
+ ##############################################################
29
+
30
+
31
+ def _numpy_label_to_bool_mask(
32
+ label_data: np.ndarray,
33
+ label: int | None,
34
+ data_shape: tuple[int, ...],
35
+ label_axes: tuple[str, ...],
36
+ data_axes: tuple[str, ...],
37
+ allow_rescaling: bool = True,
38
+ ) -> np.ndarray:
39
+ """Convert label data to a boolean mask."""
40
+ if label is not None:
41
+ bool_mask = label_data == label
42
+ else:
43
+ bool_mask = label_data != 0
44
+
45
+ bool_mask = numpy_match_shape(
46
+ array=bool_mask,
47
+ reference_shape=data_shape,
48
+ array_axes=label_axes,
49
+ reference_axes=data_axes,
50
+ allow_rescaling=allow_rescaling,
51
+ )
52
+ return bool_mask
53
+
54
+
55
+ def _setup_numpy_getters(
56
+ zarr_array: zarr.Array,
57
+ dimensions: Dimensions,
58
+ label_zarr_array: zarr.Array,
59
+ label_dimensions: Dimensions,
60
+ roi: Roi | RoiPixels,
61
+ axes_order: Sequence[str] | None = None,
62
+ transforms: Sequence[TransformProtocol] | None = None,
63
+ label_transforms: Sequence[TransformProtocol] | None = None,
64
+ slicing_dict: dict[str, SlicingInputType] | None = None,
65
+ label_slicing_dict: dict[str, SlicingInputType] | None = None,
66
+ allow_rescaling: bool = True,
67
+ remove_channel_selection: bool = False,
68
+ ) -> tuple[NumpyGetter, NumpyGetter, dict[str, SlicingInputType]]:
69
+ """Prepare slice kwargs for getting a masked array."""
70
+ slicing_dict = roi_to_slicing_dict(
71
+ roi=roi,
72
+ pixel_size=dimensions.pixel_size,
73
+ slicing_dict=slicing_dict,
74
+ )
75
+
76
+ data_getter = NumpyGetter(
77
+ zarr_array=zarr_array,
78
+ dimensions=dimensions,
79
+ axes_order=axes_order,
80
+ transforms=transforms,
81
+ slicing_dict=slicing_dict,
82
+ remove_channel_selection=remove_channel_selection,
83
+ )
84
+
85
+ if allow_rescaling:
86
+ _zoom_transform = BaseZoomTransform(
87
+ input_dimensions=dimensions,
88
+ target_dimensions=label_dimensions,
89
+ order="nearest",
90
+ )
91
+ if label_transforms is None or len(label_transforms) == 0:
92
+ label_transforms = [_zoom_transform]
93
+ else:
94
+ label_transforms = [_zoom_transform, *label_transforms]
95
+
96
+ label_slicing_dict = roi_to_slicing_dict(
97
+ roi=roi,
98
+ pixel_size=label_dimensions.pixel_size,
99
+ slicing_dict=label_slicing_dict,
100
+ )
101
+ label_data_getter = NumpyGetter(
102
+ zarr_array=label_zarr_array,
103
+ dimensions=label_dimensions,
104
+ axes_order=axes_order,
105
+ transforms=label_transforms,
106
+ slicing_dict=label_slicing_dict,
107
+ remove_channel_selection=True,
108
+ )
109
+ return data_getter, label_data_getter, slicing_dict
110
+
111
+
112
+ class NumpyGetterMasked(DataGetter[np.ndarray]):
113
+ def __init__(
114
+ self,
115
+ zarr_array: zarr.Array,
116
+ dimensions: Dimensions,
117
+ label_zarr_array: zarr.Array,
118
+ label_dimensions: Dimensions,
119
+ roi: Roi | RoiPixels,
120
+ axes_order: Sequence[str] | None = None,
121
+ transforms: Sequence[TransformProtocol] | None = None,
122
+ label_transforms: Sequence[TransformProtocol] | None = None,
123
+ slicing_dict: dict[str, SlicingInputType] | None = None,
124
+ label_slicing_dict: dict[str, SlicingInputType] | None = None,
125
+ fill_value: int | float = 0,
126
+ allow_rescaling: bool = True,
127
+ remove_channel_selection: bool = False,
128
+ ):
129
+ """Prepare slice kwargs for getting a masked array."""
130
+ data_getter, label_data_getter, slicing_dict = _setup_numpy_getters(
131
+ zarr_array=zarr_array,
132
+ dimensions=dimensions,
133
+ label_zarr_array=label_zarr_array,
134
+ label_dimensions=label_dimensions,
135
+ roi=roi,
136
+ axes_order=axes_order,
137
+ transforms=transforms,
138
+ label_transforms=label_transforms,
139
+ slicing_dict=slicing_dict,
140
+ label_slicing_dict=label_slicing_dict,
141
+ allow_rescaling=allow_rescaling,
142
+ remove_channel_selection=remove_channel_selection,
143
+ )
144
+ self._data_getter = data_getter
145
+ self._label_data_getter = label_data_getter
146
+
147
+ self._label_id = roi.label
148
+ self._fill_value = fill_value
149
+ self._allow_rescaling = allow_rescaling
150
+ super().__init__(
151
+ zarr_array=zarr_array,
152
+ slicing_ops=self._data_getter.slicing_ops,
153
+ axes_ops=self._data_getter.axes_ops,
154
+ transforms=self._data_getter.transforms,
155
+ )
156
+
157
+ @property
158
+ def label_id(self) -> int | None:
159
+ return self._label_id
160
+
161
+ def get(self) -> np.ndarray:
162
+ """Get the masked data as a numpy array."""
163
+ data = self._data_getter()
164
+ label_data = self._label_data_getter()
165
+
166
+ bool_mask = _numpy_label_to_bool_mask(
167
+ label_data=label_data,
168
+ label=self.label_id,
169
+ data_shape=data.shape,
170
+ label_axes=self._label_data_getter.axes_ops.in_memory_axes,
171
+ data_axes=self._data_getter.axes_ops.in_memory_axes,
172
+ allow_rescaling=self._allow_rescaling,
173
+ )
174
+ if bool_mask.shape != data.shape:
175
+ bool_mask = np.broadcast_to(bool_mask, data.shape)
176
+ masked_data = np.where(bool_mask, data, self._fill_value)
177
+ return masked_data
178
+
179
+
180
+ class NumpySetterMasked(DataSetter[np.ndarray]):
181
+ def __init__(
182
+ self,
183
+ zarr_array: zarr.Array,
184
+ dimensions: Dimensions,
185
+ label_zarr_array: zarr.Array,
186
+ label_dimensions: Dimensions,
187
+ roi: Roi | RoiPixels,
188
+ axes_order: Sequence[str] | None = None,
189
+ transforms: Sequence[TransformProtocol] | None = None,
190
+ label_transforms: Sequence[TransformProtocol] | None = None,
191
+ slicing_dict: dict[str, SlicingInputType] | None = None,
192
+ label_slicing_dict: dict[str, SlicingInputType] | None = None,
193
+ allow_rescaling: bool = True,
194
+ remove_channel_selection: bool = False,
195
+ ):
196
+ """Prepare slice kwargs for setting a masked array."""
197
+ _data_getter, _label_data_getter, slicing_dict = _setup_numpy_getters(
198
+ zarr_array=zarr_array,
199
+ dimensions=dimensions,
200
+ label_zarr_array=label_zarr_array,
201
+ label_dimensions=label_dimensions,
202
+ roi=roi,
203
+ axes_order=axes_order,
204
+ transforms=transforms,
205
+ label_transforms=label_transforms,
206
+ slicing_dict=slicing_dict,
207
+ label_slicing_dict=label_slicing_dict,
208
+ allow_rescaling=allow_rescaling,
209
+ remove_channel_selection=remove_channel_selection,
210
+ )
211
+ self._data_getter = _data_getter
212
+ self._label_data_getter = _label_data_getter
213
+ self._label_id = roi.label
214
+ self._allow_rescaling = allow_rescaling
215
+
216
+ self._data_setter = NumpySetter(
217
+ zarr_array=zarr_array,
218
+ dimensions=dimensions,
219
+ axes_order=axes_order,
220
+ transforms=transforms,
221
+ slicing_dict=slicing_dict,
222
+ remove_channel_selection=remove_channel_selection,
223
+ )
224
+ super().__init__(
225
+ zarr_array=zarr_array,
226
+ slicing_ops=self._data_setter.slicing_ops,
227
+ axes_ops=self._data_setter.axes_ops,
228
+ transforms=self._data_setter.transforms,
229
+ )
230
+
231
+ @property
232
+ def label_id(self) -> int | None:
233
+ return self._label_id
234
+
235
+ def set(self, patch: np.ndarray) -> None:
236
+ data = self._data_getter()
237
+ label_data = self._label_data_getter()
238
+ print(data.shape, label_data.shape)
239
+
240
+ bool_mask = _numpy_label_to_bool_mask(
241
+ label_data=label_data,
242
+ label=self.label_id,
243
+ data_shape=data.shape,
244
+ label_axes=self._label_data_getter.axes_ops.in_memory_axes,
245
+ data_axes=self._data_getter.axes_ops.in_memory_axes,
246
+ allow_rescaling=self._allow_rescaling,
247
+ )
248
+ if bool_mask.shape != data.shape:
249
+ bool_mask = np.broadcast_to(bool_mask, data.shape)
250
+ masked_patch = np.where(bool_mask, patch, data)
251
+ self._data_setter(masked_patch)
252
+
253
+
254
+ ##############################################################
255
+ #
256
+ # Dask Pipes
257
+ #
258
+ ##############################################################
259
+
260
+
261
+ def _dask_label_to_bool_mask(
262
+ label_data: DaskArray,
263
+ label: int | None,
264
+ data_shape: tuple[int, ...],
265
+ label_axes: tuple[str, ...],
266
+ data_axes: tuple[str, ...],
267
+ allow_rescaling: bool = True,
268
+ ) -> DaskArray:
269
+ """Convert label data to a boolean mask."""
270
+ if label is not None:
271
+ bool_mask = label_data == label
272
+ else:
273
+ bool_mask = label_data != 0
274
+
275
+ bool_mask = dask_match_shape(
276
+ array=bool_mask,
277
+ reference_shape=data_shape,
278
+ array_axes=label_axes,
279
+ reference_axes=data_axes,
280
+ allow_rescaling=allow_rescaling,
281
+ )
282
+ return bool_mask
283
+
284
+
285
+ def _setup_dask_getters(
286
+ zarr_array: zarr.Array,
287
+ dimensions: Dimensions,
288
+ label_zarr_array: zarr.Array,
289
+ label_dimensions: Dimensions,
290
+ roi: Roi | RoiPixels,
291
+ axes_order: Sequence[str] | None = None,
292
+ transforms: Sequence[TransformProtocol] | None = None,
293
+ label_transforms: Sequence[TransformProtocol] | None = None,
294
+ slicing_dict: dict[str, SlicingInputType] | None = None,
295
+ label_slicing_dict: dict[str, SlicingInputType] | None = None,
296
+ allow_rescaling: bool = True,
297
+ remove_channel_selection: bool = False,
298
+ ) -> tuple[DaskGetter, DaskGetter, dict[str, SlicingInputType]]:
299
+ """Prepare slice kwargs for getting a masked array."""
300
+ slicing_dict = roi_to_slicing_dict(
301
+ roi=roi,
302
+ pixel_size=dimensions.pixel_size,
303
+ slicing_dict=slicing_dict,
304
+ )
305
+
306
+ data_getter = DaskGetter(
307
+ zarr_array=zarr_array,
308
+ dimensions=dimensions,
309
+ axes_order=axes_order,
310
+ transforms=transforms,
311
+ slicing_dict=slicing_dict,
312
+ remove_channel_selection=remove_channel_selection,
313
+ )
314
+
315
+ if allow_rescaling:
316
+ _zoom_transform = BaseZoomTransform(
317
+ input_dimensions=dimensions,
318
+ target_dimensions=label_dimensions,
319
+ order="nearest",
320
+ )
321
+ if label_transforms is None or len(label_transforms) == 0:
322
+ label_transforms = [_zoom_transform]
323
+ else:
324
+ label_transforms = [_zoom_transform, *label_transforms]
325
+
326
+ label_slicing_dict = roi_to_slicing_dict(
327
+ roi=roi,
328
+ pixel_size=label_dimensions.pixel_size,
329
+ slicing_dict=label_slicing_dict,
330
+ )
331
+ label_data_getter = DaskGetter(
332
+ zarr_array=label_zarr_array,
333
+ dimensions=label_dimensions,
334
+ axes_order=axes_order,
335
+ transforms=label_transforms,
336
+ slicing_dict=label_slicing_dict,
337
+ remove_channel_selection=True,
338
+ )
339
+ return data_getter, label_data_getter, slicing_dict
340
+
341
+
342
+ class DaskGetterMasked(DataGetter[DaskArray]):
343
+ def __init__(
344
+ self,
345
+ zarr_array: zarr.Array,
346
+ dimensions: Dimensions,
347
+ label_zarr_array: zarr.Array,
348
+ label_dimensions: Dimensions,
349
+ roi: Roi | RoiPixels,
350
+ axes_order: Sequence[str] | None = None,
351
+ transforms: Sequence[TransformProtocol] | None = None,
352
+ label_transforms: Sequence[TransformProtocol] | None = None,
353
+ slicing_dict: dict[str, SlicingInputType] | None = None,
354
+ label_slicing_dict: dict[str, SlicingInputType] | None = None,
355
+ fill_value: int | float = 0,
356
+ allow_rescaling: bool = True,
357
+ remove_channel_selection: bool = False,
358
+ ):
359
+ """Prepare slice kwargs for getting a masked array."""
360
+ _data_getter, _label_data_getter, slicing_dict = _setup_dask_getters(
361
+ zarr_array=zarr_array,
362
+ dimensions=dimensions,
363
+ label_zarr_array=label_zarr_array,
364
+ label_dimensions=label_dimensions,
365
+ roi=roi,
366
+ axes_order=axes_order,
367
+ transforms=transforms,
368
+ label_transforms=label_transforms,
369
+ slicing_dict=slicing_dict,
370
+ label_slicing_dict=label_slicing_dict,
371
+ allow_rescaling=allow_rescaling,
372
+ remove_channel_selection=remove_channel_selection,
373
+ )
374
+ self._data_getter = _data_getter
375
+ self._label_data_getter = _label_data_getter
376
+ self._label_id = roi.label
377
+ self._fill_value = fill_value
378
+ self._allow_rescaling = allow_rescaling
379
+ super().__init__(
380
+ zarr_array=zarr_array,
381
+ slicing_ops=self._data_getter.slicing_ops,
382
+ axes_ops=self._data_getter.axes_ops,
383
+ transforms=self._data_getter.transforms,
384
+ )
385
+
386
+ @property
387
+ def label_id(self) -> int | None:
388
+ return self._label_id
389
+
390
+ def get(self) -> DaskArray:
391
+ data = self._data_getter()
392
+ label_data = self._label_data_getter()
393
+ data_shape = tuple(int(dim) for dim in data.shape)
394
+ bool_mask = _dask_label_to_bool_mask(
395
+ label_data=label_data,
396
+ label=self.label_id,
397
+ data_shape=data_shape,
398
+ label_axes=self._label_data_getter.axes_ops.in_memory_axes,
399
+ data_axes=self._data_getter.axes_ops.in_memory_axes,
400
+ allow_rescaling=self._allow_rescaling,
401
+ )
402
+ if bool_mask.shape != data.shape:
403
+ bool_mask = da.broadcast_to(bool_mask, data.shape)
404
+ masked_data = da.where(bool_mask, data, self._fill_value)
405
+ return masked_data
406
+
407
+
408
+ class DaskSetterMasked(DataSetter[DaskArray]):
409
+ def __init__(
410
+ self,
411
+ zarr_array: zarr.Array,
412
+ dimensions: Dimensions,
413
+ label_zarr_array: zarr.Array,
414
+ label_dimensions: Dimensions,
415
+ roi: Roi | RoiPixels,
416
+ axes_order: Sequence[str] | None = None,
417
+ transforms: Sequence[TransformProtocol] | None = None,
418
+ label_transforms: Sequence[TransformProtocol] | None = None,
419
+ slicing_dict: dict[str, SlicingInputType] | None = None,
420
+ label_slicing_dict: dict[str, SlicingInputType] | None = None,
421
+ allow_rescaling: bool = True,
422
+ remove_channel_selection: bool = False,
423
+ ):
424
+ """Prepare slice kwargs for setting a masked array."""
425
+ _data_getter, _label_data_getter, slicing_dict = _setup_dask_getters(
426
+ zarr_array=zarr_array,
427
+ dimensions=dimensions,
428
+ label_zarr_array=label_zarr_array,
429
+ label_dimensions=label_dimensions,
430
+ roi=roi,
431
+ axes_order=axes_order,
432
+ transforms=transforms,
433
+ label_transforms=label_transforms,
434
+ slicing_dict=slicing_dict,
435
+ label_slicing_dict=label_slicing_dict,
436
+ allow_rescaling=allow_rescaling,
437
+ remove_channel_selection=remove_channel_selection,
438
+ )
439
+ self._data_getter = _data_getter
440
+ self._label_data_getter = _label_data_getter
441
+
442
+ self._label_id = roi.label
443
+ self._allow_rescaling = allow_rescaling
444
+
445
+ self._data_setter = DaskSetter(
446
+ zarr_array=zarr_array,
447
+ dimensions=dimensions,
448
+ axes_order=axes_order,
449
+ transforms=transforms,
450
+ slicing_dict=slicing_dict,
451
+ remove_channel_selection=remove_channel_selection,
452
+ )
453
+
454
+ super().__init__(
455
+ zarr_array=zarr_array,
456
+ slicing_ops=self._data_setter.slicing_ops,
457
+ axes_ops=self._data_setter.axes_ops,
458
+ transforms=self._data_setter.transforms,
459
+ )
460
+
461
+ @property
462
+ def label_id(self) -> int | None:
463
+ return self._label_id
464
+
465
+ def set(self, patch: DaskArray) -> None:
466
+ data = self._data_getter()
467
+ label_data = self._label_data_getter()
468
+ data_shape = tuple(int(dim) for dim in data.shape)
469
+
470
+ bool_mask = _dask_label_to_bool_mask(
471
+ label_data=label_data,
472
+ label=self.label_id,
473
+ data_shape=data_shape,
474
+ label_axes=self._label_data_getter.axes_ops.in_memory_axes,
475
+ data_axes=self._data_getter.axes_ops.in_memory_axes,
476
+ allow_rescaling=self._allow_rescaling,
477
+ )
478
+ if bool_mask.shape != data.shape:
479
+ bool_mask = da.broadcast_to(bool_mask, data.shape)
480
+ masked_patch = da.where(bool_mask, patch, data)
481
+ self._data_setter(masked_patch)
@@ -0,0 +1,143 @@
1
+ from collections.abc import Sequence
2
+
3
+ import zarr
4
+
5
+ from ngio.common._dimensions import Dimensions
6
+ from ngio.common._roi import Roi, RoiPixels
7
+ from ngio.io_pipes._io_pipes import (
8
+ DaskGetter,
9
+ DaskSetter,
10
+ NumpyGetter,
11
+ NumpySetter,
12
+ )
13
+ from ngio.io_pipes._io_pipes_utils import SlicingInputType
14
+ from ngio.io_pipes._ops_transforms import TransformProtocol
15
+ from ngio.ome_zarr_meta.ngio_specs._pixel_size import PixelSize
16
+ from ngio.utils import NgioValueError
17
+
18
+
19
+ def roi_to_slicing_dict(
20
+ roi: Roi | RoiPixels,
21
+ pixel_size: PixelSize | None = None,
22
+ slicing_dict: dict[str, SlicingInputType] | None = None,
23
+ ) -> dict[str, SlicingInputType]:
24
+ """Convert a ROI to a slicing dictionary."""
25
+ if isinstance(roi, Roi):
26
+ if pixel_size is None:
27
+ raise NgioValueError(
28
+ "pixel_size must be provided when converting a Roi to slice_kwargs."
29
+ )
30
+ roi = roi.to_roi_pixels(pixel_size=pixel_size)
31
+
32
+ roi_slicing_dict: dict[str, SlicingInputType] = roi.to_slicing_dict() # type: ignore
33
+ if slicing_dict is None:
34
+ return roi_slicing_dict
35
+
36
+ # Additional slice kwargs can be provided
37
+ # and will override the ones from the ROI
38
+ roi_slicing_dict.update(slicing_dict)
39
+ return roi_slicing_dict
40
+
41
+
42
+ class NumpyRoiGetter(NumpyGetter):
43
+ def __init__(
44
+ self,
45
+ zarr_array: zarr.Array,
46
+ dimensions: Dimensions,
47
+ roi: Roi | RoiPixels,
48
+ axes_order: Sequence[str] | None = None,
49
+ transforms: Sequence[TransformProtocol] | None = None,
50
+ slicing_dict: dict[str, SlicingInputType] | None = None,
51
+ remove_channel_selection: bool = False,
52
+ ) -> None:
53
+ input_slice_kwargs = roi_to_slicing_dict(
54
+ roi=roi,
55
+ pixel_size=dimensions.pixel_size,
56
+ slicing_dict=slicing_dict,
57
+ )
58
+ super().__init__(
59
+ zarr_array=zarr_array,
60
+ dimensions=dimensions,
61
+ axes_order=axes_order,
62
+ transforms=transforms,
63
+ slicing_dict=input_slice_kwargs,
64
+ remove_channel_selection=remove_channel_selection,
65
+ )
66
+
67
+
68
+ class DaskRoiGetter(DaskGetter):
69
+ def __init__(
70
+ self,
71
+ zarr_array: zarr.Array,
72
+ dimensions: Dimensions,
73
+ roi: Roi | RoiPixels,
74
+ axes_order: Sequence[str] | None = None,
75
+ transforms: Sequence[TransformProtocol] | None = None,
76
+ slicing_dict: dict[str, SlicingInputType] | None = None,
77
+ remove_channel_selection: bool = False,
78
+ ) -> None:
79
+ input_slice_kwargs = roi_to_slicing_dict(
80
+ roi=roi,
81
+ pixel_size=dimensions.pixel_size,
82
+ slicing_dict=slicing_dict,
83
+ )
84
+ super().__init__(
85
+ zarr_array=zarr_array,
86
+ dimensions=dimensions,
87
+ axes_order=axes_order,
88
+ transforms=transforms,
89
+ slicing_dict=input_slice_kwargs,
90
+ remove_channel_selection=remove_channel_selection,
91
+ )
92
+
93
+
94
+ class NumpyRoiSetter(NumpySetter):
95
+ def __init__(
96
+ self,
97
+ zarr_array: zarr.Array,
98
+ dimensions: Dimensions,
99
+ roi: Roi | RoiPixels,
100
+ axes_order: Sequence[str] | None = None,
101
+ transforms: Sequence[TransformProtocol] | None = None,
102
+ slicing_dict: dict[str, SlicingInputType] | None = None,
103
+ remove_channel_selection: bool = False,
104
+ ) -> None:
105
+ input_slice_kwargs = roi_to_slicing_dict(
106
+ roi=roi,
107
+ pixel_size=dimensions.pixel_size,
108
+ slicing_dict=slicing_dict,
109
+ )
110
+ super().__init__(
111
+ zarr_array=zarr_array,
112
+ dimensions=dimensions,
113
+ axes_order=axes_order,
114
+ transforms=transforms,
115
+ slicing_dict=input_slice_kwargs,
116
+ remove_channel_selection=remove_channel_selection,
117
+ )
118
+
119
+
120
+ class DaskRoiSetter(DaskSetter):
121
+ def __init__(
122
+ self,
123
+ zarr_array: zarr.Array,
124
+ dimensions: Dimensions,
125
+ roi: Roi | RoiPixels,
126
+ axes_order: Sequence[str] | None = None,
127
+ transforms: Sequence[TransformProtocol] | None = None,
128
+ slicing_dict: dict[str, SlicingInputType] | None = None,
129
+ remove_channel_selection: bool = False,
130
+ ) -> None:
131
+ input_slice_kwargs = roi_to_slicing_dict(
132
+ roi=roi,
133
+ pixel_size=dimensions.pixel_size,
134
+ slicing_dict=slicing_dict,
135
+ )
136
+ super().__init__(
137
+ zarr_array=zarr_array,
138
+ dimensions=dimensions,
139
+ axes_order=axes_order,
140
+ transforms=transforms,
141
+ slicing_dict=input_slice_kwargs,
142
+ remove_channel_selection=remove_channel_selection,
143
+ )