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
ngio/common/_roi.py CHANGED
@@ -4,41 +4,32 @@ These are the interfaces bwteen the ROI tables / masking ROI tables and
4
4
  the ImageLikeHandler.
5
5
  """
6
6
 
7
- from collections.abc import Callable, Sequence
8
- from typing import Generic, TypeVar
7
+ from typing import TypeVar
9
8
  from warnings import warn
10
9
 
11
- import dask.array as da
12
- import numpy as np
13
- import zarr
14
10
  from pydantic import BaseModel, ConfigDict
15
11
 
16
- from ngio.common._array_io_pipes import (
17
- build_dask_getter,
18
- build_dask_setter,
19
- build_masked_dask_getter,
20
- build_masked_dask_setter,
21
- build_masked_numpy_getter,
22
- build_masked_numpy_setter,
23
- build_numpy_getter,
24
- build_numpy_setter,
25
- )
26
- from ngio.common._array_io_utils import SlicingInputType, TransformProtocol
27
12
  from ngio.common._dimensions import Dimensions
28
13
  from ngio.ome_zarr_meta.ngio_specs import DefaultSpaceUnit, PixelSize, SpaceUnits
29
14
  from ngio.utils import NgioValueError
30
15
 
31
16
 
32
- def _to_raster(value: float, pixel_size: float, max_shape: int | None) -> int:
33
- """Convert to raster coordinates."""
34
- round_value = int(np.round(value / pixel_size))
35
- # Ensure the value is within the image shape boundaries
36
- if max_shape is not None:
37
- return max(0, min(round_value, max_shape))
38
- return round_value
17
+ def _to_raster(value: float, length: float, pixel_size: float) -> tuple[float, float]:
18
+ raster_value = value / pixel_size
19
+ raster_length = length / pixel_size
20
+ return raster_value, raster_length
39
21
 
40
22
 
41
- def _to_world(value: int, pixel_size: float) -> float:
23
+ def _to_slice(start: float | None, length: float | None) -> slice:
24
+ if length is not None:
25
+ assert start is not None
26
+ end = start + length
27
+ else:
28
+ end = None
29
+ return slice(start, end)
30
+
31
+
32
+ def _to_world(value: int | float, pixel_size: float) -> float:
42
33
  """Convert to world coordinates."""
43
34
  return value * pixel_size
44
35
 
@@ -46,27 +37,59 @@ def _to_world(value: int, pixel_size: float) -> float:
46
37
  T = TypeVar("T", int, float)
47
38
 
48
39
 
49
- class GenericRoi(BaseModel, Generic[T]):
40
+ class GenericRoi(BaseModel):
50
41
  """A generic Region of Interest (ROI) model."""
51
42
 
52
- name: str
53
- x: T
54
- y: T
55
- z: T | None = None
56
- t: T | None = None
57
- x_length: T
58
- y_length: T
59
- z_length: T | None = None
60
- t_length: T | None = None
43
+ name: str | None
44
+ x: float
45
+ y: float
46
+ z: float | None = None
47
+ t: float | None = None
48
+ x_length: float
49
+ y_length: float
50
+ z_length: float | None = None
51
+ t_length: float | None = None
61
52
  label: int | None = None
62
53
  unit: SpaceUnits | str | None = None
63
54
 
64
55
  model_config = ConfigDict(extra="allow")
65
56
 
66
- def intersection(self, other: "GenericRoi[T]") -> "GenericRoi[T] | None":
57
+ def intersection(self, other: "GenericRoi") -> "GenericRoi | None":
67
58
  """Calculate the intersection of this ROI with another ROI."""
68
59
  return roi_intersection(self, other)
69
60
 
61
+ def _nice_str(self) -> str:
62
+ if self.t is not None:
63
+ t_str = f"t={self.t}->{self.t_length}"
64
+ else:
65
+ t_str = "t=None"
66
+ if self.z is not None:
67
+ z_str = f"z={self.z}->{self.z_length}"
68
+ else:
69
+ z_str = "z=None"
70
+
71
+ y_str = f"y={self.y}->{self.y_length}"
72
+ x_str = f"x={self.x}->{self.x_length}"
73
+
74
+ if self.label is not None:
75
+ label_str = f", label={self.label}"
76
+ else:
77
+ label_str = ""
78
+ cls_name = self.__class__.__name__
79
+ return f"{cls_name}({t_str}, {z_str}, {y_str}, {x_str}{label_str})"
80
+
81
+ def get_name(self) -> str:
82
+ """Get the name of the ROI, or a default if not set."""
83
+ if self.name is not None:
84
+ return self.name
85
+ return self._nice_str()
86
+
87
+ def __repr__(self) -> str:
88
+ return self._nice_str()
89
+
90
+ def __str__(self) -> str:
91
+ return self._nice_str()
92
+
70
93
 
71
94
  def _1d_intersection(
72
95
  a: T | None, a_length: T | None, b: T | None, b_length: T | None
@@ -97,9 +120,7 @@ def _1d_intersection(
97
120
  return start, length
98
121
 
99
122
 
100
- def roi_intersection(
101
- ref_roi: GenericRoi[T], other_roi: GenericRoi[T]
102
- ) -> GenericRoi[T] | None:
123
+ def roi_intersection(ref_roi: GenericRoi, other_roi: GenericRoi) -> GenericRoi | None:
103
124
  """Calculate the intersection of two ROIs."""
104
125
  if (
105
126
  ref_roi.unit is not None
@@ -113,11 +134,17 @@ def roi_intersection(
113
134
  x, x_length = _1d_intersection(
114
135
  ref_roi.x, ref_roi.x_length, other_roi.x, other_roi.x_length
115
136
  )
137
+ if x is None and x_length is None:
138
+ # No intersection
139
+ return None
116
140
  assert x is not None and x_length is not None
117
141
 
118
142
  y, y_length = _1d_intersection(
119
143
  ref_roi.y, ref_roi.y_length, other_roi.y, other_roi.y_length
120
144
  )
145
+ if y is None and y_length is None:
146
+ # No intersection
147
+ return None
121
148
  assert y is not None and y_length is not None
122
149
 
123
150
  z, z_length = _1d_intersection(
@@ -127,11 +154,8 @@ def roi_intersection(
127
154
  ref_roi.t, ref_roi.t_length, other_roi.t, other_roi.t_length
128
155
  )
129
156
 
130
- if (
131
- x_length <= 0
132
- or y_length <= 0
133
- or (z_length is not None and z_length <= 0)
134
- or (t_length is not None and t_length <= 0)
157
+ if (z_length is not None and z_length <= 0) or (
158
+ t_length is not None and t_length <= 0
135
159
  ):
136
160
  # No intersection
137
161
  return None
@@ -144,9 +168,14 @@ def roi_intersection(
144
168
  )
145
169
  label = ref_roi.label or other_roi.label
146
170
 
171
+ if ref_roi.name is not None and other_roi.name is not None:
172
+ name = f"{ref_roi.name}:{other_roi.name}"
173
+ else:
174
+ name = ref_roi.name or other_roi.name
175
+
147
176
  cls_ref = ref_roi.__class__
148
177
  return cls_ref(
149
- name=f"[{ref_roi.name}_x_{other_roi.name}]",
178
+ name=name,
150
179
  x=x,
151
180
  y=y,
152
181
  z=z,
@@ -160,52 +189,29 @@ def roi_intersection(
160
189
  )
161
190
 
162
191
 
163
- class Roi(GenericRoi[float]):
192
+ class Roi(GenericRoi):
164
193
  x: float = 0.0
165
194
  y: float = 0.0
166
195
  unit: SpaceUnits | str | None = DefaultSpaceUnit
167
196
 
168
- def to_roi_pixels(
169
- self, pixel_size: PixelSize, dimensions: Dimensions | None = None
170
- ) -> "RoiPixels":
197
+ def to_roi_pixels(self, pixel_size: PixelSize) -> "RoiPixels":
171
198
  """Convert to raster coordinates."""
172
- if dimensions is None:
173
- # No check for dimensions
174
- dim_x, dim_y, dim_z, dim_t = None, None, None, None
175
- else:
176
- dim_x, dim_y, dim_z, dim_t = (
177
- dimensions.get("x"),
178
- dimensions.get("y"),
179
- dimensions.get("z"),
180
- dimensions.get("t"),
181
- )
182
-
183
- x = _to_raster(self.x, pixel_size.x, dim_x)
184
- x_length = _to_raster(self.x_length, pixel_size.x, dim_x)
185
- y = _to_raster(self.y, pixel_size.y, dim_y)
186
- y_length = _to_raster(self.y_length, pixel_size.y, dim_y)
199
+ x, x_length = _to_raster(self.x, self.x_length, pixel_size.x)
200
+ y, y_length = _to_raster(self.y, self.y_length, pixel_size.y)
187
201
 
188
202
  if self.z is None:
189
- z = None
203
+ z, z_length = None, None
190
204
  else:
191
- z = _to_raster(self.z, pixel_size.z, dim_z)
192
-
193
- if self.z_length is None:
194
- z_length = None
195
- else:
196
- z_length = _to_raster(self.z_length, pixel_size.z, dim_z)
205
+ assert self.z_length is not None
206
+ z, z_length = _to_raster(self.z, self.z_length, pixel_size.z)
197
207
 
198
208
  if self.t is None:
199
- t = None
209
+ t, t_length = None, None
200
210
  else:
201
- t = _to_raster(self.t, pixel_size.t, dim_t)
202
-
203
- if self.t_length is None:
204
- t_length = None
205
- else:
206
- t_length = _to_raster(self.t_length, pixel_size.t, dim_t)
207
-
211
+ assert self.t_length is not None
212
+ t, t_length = _to_raster(self.t, self.t_length, pixel_size.t)
208
213
  extra_dict = self.model_extra if self.model_extra else {}
214
+
209
215
  return RoiPixels(
210
216
  name=self.name,
211
217
  x=x,
@@ -232,7 +238,7 @@ class Roi(GenericRoi[float]):
232
238
  stacklevel=2,
233
239
  )
234
240
 
235
- return self.to_roi_pixels(pixel_size=pixel_size, dimensions=dimensions)
241
+ return self.to_roi_pixels(pixel_size=pixel_size)
236
242
 
237
243
  def zoom(self, zoom_factor: float = 1) -> "Roi":
238
244
  """Zoom the ROI by a factor.
@@ -246,11 +252,11 @@ class Roi(GenericRoi[float]):
246
252
  return zoom_roi(self, zoom_factor)
247
253
 
248
254
 
249
- class RoiPixels(GenericRoi[int]):
255
+ class RoiPixels(GenericRoi):
250
256
  """Region of interest (ROI) in pixel coordinates."""
251
257
 
252
- x: int = 0
253
- y: int = 0
258
+ x: float = 0
259
+ y: float = 0
254
260
  unit: SpaceUnits | str | None = None
255
261
 
256
262
  def to_roi(self, pixel_size: PixelSize) -> "Roi":
@@ -296,17 +302,12 @@ class RoiPixels(GenericRoi[int]):
296
302
  **extra_dict,
297
303
  )
298
304
 
299
- def to_slicing_dict(self) -> dict[str, SlicingInputType]:
300
- x_slice = slice(self.x, self.x + self.x_length)
301
- y_slice = slice(self.y, self.y + self.y_length)
302
- if self.z is not None and self.z_length is not None:
303
- z_slice = slice(self.z, self.z + self.z_length)
304
- else:
305
- z_slice = slice(None)
306
- if self.t is not None and self.t_length is not None:
307
- t_slice = slice(self.t, self.t + self.t_length)
308
- else:
309
- t_slice = slice(None)
305
+ def to_slicing_dict(self) -> dict[str, slice]:
306
+ """Convert to a slicing dictionary."""
307
+ x_slice = _to_slice(self.x, self.x_length)
308
+ y_slice = _to_slice(self.y, self.y_length)
309
+ z_slice = _to_slice(self.z, self.z_length)
310
+ t_slice = _to_slice(self.t, self.t_length)
310
311
  return {
311
312
  "x": x_slice,
312
313
  "y": y_slice,
@@ -351,328 +352,3 @@ def zoom_roi(roi: Roi, zoom_factor: float = 1) -> Roi:
351
352
  unit=roi.unit,
352
353
  )
353
354
  return new_roi
354
-
355
-
356
- def roi_to_slicing_dict(
357
- roi: Roi | RoiPixels,
358
- dimensions: Dimensions,
359
- pixel_size: PixelSize | None = None,
360
- slicing_dict: dict[str, SlicingInputType] | None = None,
361
- ) -> dict[str, SlicingInputType]:
362
- """Convert a ROI to a slicing dictionary."""
363
- if isinstance(roi, Roi):
364
- if pixel_size is None:
365
- raise NgioValueError(
366
- "pixel_size must be provided when converting a Roi to slice_kwargs."
367
- )
368
- roi = roi.to_roi_pixels(pixel_size=pixel_size, dimensions=dimensions)
369
-
370
- roi_slicing_dict = roi.to_slicing_dict()
371
- if slicing_dict is None:
372
- return roi_slicing_dict
373
-
374
- # Additional slice kwargs can be provided
375
- # and will override the ones from the ROI
376
- roi_slicing_dict.update(slicing_dict)
377
- return roi_slicing_dict
378
-
379
-
380
- def build_roi_numpy_getter(
381
- zarr_array: zarr.Array,
382
- dimensions: Dimensions,
383
- roi: Roi | RoiPixels,
384
- pixel_size: PixelSize | None = None,
385
- axes_order: Sequence[str] | None = None,
386
- transforms: Sequence[TransformProtocol] | None = None,
387
- slicing_dict: dict[str, SlicingInputType] | None = None,
388
- remove_channel_selection: bool = False,
389
- ) -> Callable[[], np.ndarray]:
390
- """Prepare slice kwargs for setting an array."""
391
- input_slice_kwargs = roi_to_slicing_dict(
392
- roi=roi,
393
- dimensions=dimensions,
394
- pixel_size=pixel_size,
395
- slicing_dict=slicing_dict,
396
- )
397
- return build_numpy_getter(
398
- zarr_array=zarr_array,
399
- dimensions=dimensions,
400
- axes_order=axes_order,
401
- transforms=transforms,
402
- slicing_dict=input_slice_kwargs,
403
- remove_channel_selection=remove_channel_selection,
404
- )
405
-
406
-
407
- def build_roi_numpy_setter(
408
- zarr_array: zarr.Array,
409
- dimensions: Dimensions,
410
- roi: Roi | RoiPixels,
411
- pixel_size: PixelSize | None = None,
412
- axes_order: Sequence[str] | None = None,
413
- transforms: Sequence[TransformProtocol] | None = None,
414
- slicing_dict: dict[str, SlicingInputType] | None = None,
415
- remove_channel_selection: bool = False,
416
- ) -> Callable[[np.ndarray], None]:
417
- """Prepare slice kwargs for setting an array."""
418
- input_slice_kwargs = roi_to_slicing_dict(
419
- roi=roi,
420
- dimensions=dimensions,
421
- pixel_size=pixel_size,
422
- slicing_dict=slicing_dict,
423
- )
424
- return build_numpy_setter(
425
- zarr_array=zarr_array,
426
- dimensions=dimensions,
427
- axes_order=axes_order,
428
- transforms=transforms,
429
- slicing_dict=input_slice_kwargs,
430
- remove_channel_selection=remove_channel_selection,
431
- )
432
-
433
-
434
- def build_roi_dask_getter(
435
- zarr_array: zarr.Array,
436
- dimensions: Dimensions,
437
- roi: Roi | RoiPixels,
438
- pixel_size: PixelSize | None = None,
439
- axes_order: Sequence[str] | None = None,
440
- transforms: Sequence[TransformProtocol] | None = None,
441
- slicing_dict: dict[str, SlicingInputType] | None = None,
442
- remove_channel_selection: bool = False,
443
- ) -> Callable[[], da.Array]:
444
- """Prepare slice kwargs for getting an array."""
445
- input_slice_kwargs = roi_to_slicing_dict(
446
- roi=roi,
447
- dimensions=dimensions,
448
- pixel_size=pixel_size,
449
- slicing_dict=slicing_dict,
450
- )
451
- return build_dask_getter(
452
- zarr_array=zarr_array,
453
- dimensions=dimensions,
454
- axes_order=axes_order,
455
- transforms=transforms,
456
- slicing_dict=input_slice_kwargs,
457
- remove_channel_selection=remove_channel_selection,
458
- )
459
-
460
-
461
- def build_roi_dask_setter(
462
- zarr_array: zarr.Array,
463
- dimensions: Dimensions,
464
- roi: Roi | RoiPixels,
465
- pixel_size: PixelSize | None = None,
466
- axes_order: Sequence[str] | None = None,
467
- transforms: Sequence[TransformProtocol] | None = None,
468
- slicing_dict: dict[str, SlicingInputType] | None = None,
469
- remove_channel_selection: bool = False,
470
- ) -> Callable[[da.Array], None]:
471
- """Prepare slice kwargs for setting an array."""
472
- input_slice_kwargs = roi_to_slicing_dict(
473
- roi=roi,
474
- dimensions=dimensions,
475
- pixel_size=pixel_size,
476
- slicing_dict=slicing_dict,
477
- )
478
- return build_dask_setter(
479
- zarr_array=zarr_array,
480
- dimensions=dimensions,
481
- axes_order=axes_order,
482
- transforms=transforms,
483
- slicing_dict=input_slice_kwargs,
484
- remove_channel_selection=remove_channel_selection,
485
- )
486
-
487
-
488
- ################################################################
489
- #
490
- # Masked ROIs array pipes
491
- #
492
- ################################################################
493
-
494
-
495
- def build_roi_masked_numpy_getter(
496
- *,
497
- roi: Roi | RoiPixels,
498
- zarr_array: zarr.Array,
499
- dimensions: Dimensions,
500
- pixel_size: PixelSize | None = None,
501
- label_zarr_array: zarr.Array,
502
- label_dimensions: Dimensions,
503
- label_pixel_size: PixelSize | None = None,
504
- axes_order: Sequence[str] | None = None,
505
- transforms: Sequence[TransformProtocol] | None = None,
506
- label_transforms: Sequence[TransformProtocol] | None = None,
507
- slicing_dict: dict[str, SlicingInputType] | None = None,
508
- label_slicing_dict: dict[str, SlicingInputType] | None = None,
509
- fill_value: int | float = 0,
510
- allow_scaling: bool = True,
511
- remove_channel_selection: bool = False,
512
- ) -> Callable[[], np.ndarray]:
513
- """Prepare slice kwargs for getting a masked array."""
514
- input_slice_kwargs = roi_to_slicing_dict(
515
- roi=roi,
516
- dimensions=dimensions,
517
- pixel_size=pixel_size,
518
- slicing_dict=slicing_dict,
519
- )
520
- label_slice_kwargs = roi_to_slicing_dict(
521
- roi=roi,
522
- dimensions=label_dimensions,
523
- pixel_size=label_pixel_size,
524
- slicing_dict=label_slicing_dict,
525
- )
526
- return build_masked_numpy_getter(
527
- zarr_array=zarr_array,
528
- dimensions=dimensions,
529
- label_zarr_array=label_zarr_array,
530
- label_dimensions=label_dimensions,
531
- label_id=roi.label,
532
- axes_order=axes_order,
533
- transforms=transforms,
534
- label_transforms=label_transforms,
535
- slicing_dict=input_slice_kwargs,
536
- label_slicing_dict=label_slice_kwargs,
537
- fill_value=fill_value,
538
- allow_scaling=allow_scaling,
539
- remove_channel_selection=remove_channel_selection,
540
- )
541
-
542
-
543
- def build_roi_masked_numpy_setter(
544
- *,
545
- roi: Roi | RoiPixels,
546
- zarr_array: zarr.Array,
547
- dimensions: Dimensions,
548
- pixel_size: PixelSize | None = None,
549
- label_zarr_array: zarr.Array,
550
- label_dimensions: Dimensions,
551
- label_pixel_size: PixelSize | None = None,
552
- axes_order: Sequence[str] | None = None,
553
- transforms: Sequence[TransformProtocol] | None = None,
554
- label_transforms: Sequence[TransformProtocol] | None = None,
555
- slicing_dict: dict[str, SlicingInputType] | None = None,
556
- label_slicing_dict: dict[str, SlicingInputType] | None = None,
557
- allow_scaling: bool = True,
558
- remove_channel_selection: bool = False,
559
- ) -> Callable[[np.ndarray], None]:
560
- """Prepare slice kwargs for setting a masked array."""
561
- input_slice_kwargs = roi_to_slicing_dict(
562
- roi=roi,
563
- dimensions=dimensions,
564
- pixel_size=pixel_size,
565
- slicing_dict=slicing_dict,
566
- )
567
- label_slice_kwargs = roi_to_slicing_dict(
568
- roi=roi,
569
- dimensions=label_dimensions,
570
- pixel_size=label_pixel_size,
571
- slicing_dict=label_slicing_dict,
572
- )
573
- return build_masked_numpy_setter(
574
- zarr_array=zarr_array,
575
- dimensions=dimensions,
576
- label_zarr_array=label_zarr_array,
577
- label_dimensions=label_dimensions,
578
- label_id=roi.label,
579
- axes_order=axes_order,
580
- transforms=transforms,
581
- label_transforms=label_transforms,
582
- slicing_dict=input_slice_kwargs,
583
- label_slicing_dict=label_slice_kwargs,
584
- allow_scaling=allow_scaling,
585
- remove_channel_selection=remove_channel_selection,
586
- )
587
-
588
-
589
- def build_roi_masked_dask_getter(
590
- *,
591
- roi: Roi | RoiPixels,
592
- zarr_array: zarr.Array,
593
- dimensions: Dimensions,
594
- pixel_size: PixelSize | None = None,
595
- label_zarr_array: zarr.Array,
596
- label_dimensions: Dimensions,
597
- label_pixel_size: PixelSize | None = None,
598
- axes_order: Sequence[str] | None = None,
599
- transforms: Sequence[TransformProtocol] | None = None,
600
- label_transforms: Sequence[TransformProtocol] | None = None,
601
- slicing_dict: dict[str, SlicingInputType] | None = None,
602
- label_slicing_dict: dict[str, SlicingInputType] | None = None,
603
- allow_scaling: bool = True,
604
- remove_channel_selection: bool = False,
605
- ) -> Callable[[], da.Array]:
606
- """Prepare slice kwargs for getting a masked array."""
607
- input_slice_kwargs = roi_to_slicing_dict(
608
- roi=roi,
609
- dimensions=dimensions,
610
- pixel_size=pixel_size,
611
- slicing_dict=slicing_dict,
612
- )
613
- label_slice_kwargs = roi_to_slicing_dict(
614
- roi=roi,
615
- dimensions=label_dimensions,
616
- pixel_size=label_pixel_size,
617
- slicing_dict=label_slicing_dict,
618
- )
619
- return build_masked_dask_getter(
620
- zarr_array=zarr_array,
621
- dimensions=dimensions,
622
- label_zarr_array=label_zarr_array,
623
- label_dimensions=label_dimensions,
624
- label_id=roi.label,
625
- axes_order=axes_order,
626
- transforms=transforms,
627
- label_transforms=label_transforms,
628
- slicing_dict=input_slice_kwargs,
629
- label_slicing_dict=label_slice_kwargs,
630
- allow_scaling=allow_scaling,
631
- remove_channel_selection=remove_channel_selection,
632
- )
633
-
634
-
635
- def build_roi_masked_dask_setter(
636
- *,
637
- roi: Roi | RoiPixels,
638
- zarr_array: zarr.Array,
639
- dimensions: Dimensions,
640
- pixel_size: PixelSize | None = None,
641
- label_zarr_array: zarr.Array,
642
- label_dimensions: Dimensions,
643
- label_pixel_size: PixelSize | None = None,
644
- axes_order: Sequence[str] | None = None,
645
- transforms: Sequence[TransformProtocol] | None = None,
646
- label_transforms: Sequence[TransformProtocol] | None = None,
647
- slicing_dict: dict[str, SlicingInputType] | None = None,
648
- label_slicing_dict: dict[str, SlicingInputType] | None = None,
649
- allow_scaling: bool = True,
650
- remove_channel_selection: bool = False,
651
- ) -> Callable[[da.Array], None]:
652
- """Prepare slice kwargs for setting a masked array."""
653
- input_slice_kwargs = roi_to_slicing_dict(
654
- roi=roi,
655
- dimensions=dimensions,
656
- pixel_size=pixel_size,
657
- slicing_dict=slicing_dict,
658
- )
659
- label_slice_kwargs = roi_to_slicing_dict(
660
- roi=roi,
661
- dimensions=label_dimensions,
662
- pixel_size=label_pixel_size,
663
- slicing_dict=label_slicing_dict,
664
- )
665
- return build_masked_dask_setter(
666
- zarr_array=zarr_array,
667
- dimensions=dimensions,
668
- label_zarr_array=label_zarr_array,
669
- label_dimensions=label_dimensions,
670
- label_id=roi.label,
671
- axes_order=axes_order,
672
- transforms=transforms,
673
- label_transforms=label_transforms,
674
- slicing_dict=input_slice_kwargs,
675
- label_slicing_dict=label_slice_kwargs,
676
- allow_scaling=allow_scaling,
677
- remove_channel_selection=remove_channel_selection,
678
- )