ngio 0.4.0a1__py3-none-any.whl → 0.4.0a3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ngio/common/_array_io_pipes.py +11 -6
- ngio/common/_roi.py +59 -7
- ngio/experimental/iterators/_feature.py +1 -1
- ngio/experimental/iterators/_image_processing.py +1 -1
- ngio/experimental/iterators/_rois_utils.py +2 -2
- ngio/experimental/iterators/_segmentation.py +5 -1
- ngio/images/_abstract_image.py +2 -2
- ngio/images/_ome_zarr_container.py +1 -1
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
- ngio/tables/v1/_roi_table.py +11 -3
- {ngio-0.4.0a1.dist-info → ngio-0.4.0a3.dist-info}/METADATA +1 -1
- {ngio-0.4.0a1.dist-info → ngio-0.4.0a3.dist-info}/RECORD +14 -14
- {ngio-0.4.0a1.dist-info → ngio-0.4.0a3.dist-info}/WHEEL +0 -0
- {ngio-0.4.0a1.dist-info → ngio-0.4.0a3.dist-info}/licenses/LICENSE +0 -0
ngio/common/_array_io_pipes.py
CHANGED
|
@@ -87,6 +87,7 @@ def build_numpy_getter(
|
|
|
87
87
|
slicing_dict=slicing_dict,
|
|
88
88
|
remove_channel_selection=remove_channel_selection,
|
|
89
89
|
)
|
|
90
|
+
|
|
90
91
|
return lambda: _numpy_get_pipe(
|
|
91
92
|
zarr_array=zarr_array,
|
|
92
93
|
slicing_ops=slicing_ops,
|
|
@@ -285,6 +286,7 @@ def build_masked_numpy_getter(
|
|
|
285
286
|
label_slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
286
287
|
fill_value: int | float = 0,
|
|
287
288
|
allow_scaling: bool = True,
|
|
289
|
+
remove_channel_selection: bool = False,
|
|
288
290
|
) -> Callable[[], np.ndarray]:
|
|
289
291
|
"""Get a numpy array from the zarr array with the given slice kwargs."""
|
|
290
292
|
slicing_dict = slicing_dict or {}
|
|
@@ -296,7 +298,7 @@ def build_masked_numpy_getter(
|
|
|
296
298
|
axes_order=axes_order,
|
|
297
299
|
transforms=transforms,
|
|
298
300
|
slicing_dict=slicing_dict,
|
|
299
|
-
remove_channel_selection=
|
|
301
|
+
remove_channel_selection=remove_channel_selection,
|
|
300
302
|
)
|
|
301
303
|
|
|
302
304
|
label_data_getter = build_numpy_getter(
|
|
@@ -379,6 +381,7 @@ def build_masked_dask_getter(
|
|
|
379
381
|
label_slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
380
382
|
fill_value: int | float = 0,
|
|
381
383
|
allow_scaling: bool = True,
|
|
384
|
+
remove_channel_selection: bool = False,
|
|
382
385
|
) -> Callable[[], DaskArray]:
|
|
383
386
|
"""Get a dask array from the zarr array with the given slice kwargs."""
|
|
384
387
|
slicing_dict = slicing_dict or {}
|
|
@@ -390,7 +393,7 @@ def build_masked_dask_getter(
|
|
|
390
393
|
axes_order=axes_order,
|
|
391
394
|
transforms=transforms,
|
|
392
395
|
slicing_dict=slicing_dict,
|
|
393
|
-
remove_channel_selection=
|
|
396
|
+
remove_channel_selection=remove_channel_selection,
|
|
394
397
|
)
|
|
395
398
|
|
|
396
399
|
label_data_getter = build_dask_getter(
|
|
@@ -433,6 +436,7 @@ def build_masked_numpy_setter(
|
|
|
433
436
|
data_getter: Callable[[], np.ndarray] | None = None,
|
|
434
437
|
label_data_getter: Callable[[], np.ndarray] | None = None,
|
|
435
438
|
allow_scaling: bool = True,
|
|
439
|
+
remove_channel_selection: bool = False,
|
|
436
440
|
) -> Callable[[np.ndarray], None]:
|
|
437
441
|
"""Set a numpy array to the zarr array with the given slice kwargs."""
|
|
438
442
|
slicing_dict = slicing_dict or {}
|
|
@@ -445,7 +449,7 @@ def build_masked_numpy_setter(
|
|
|
445
449
|
axes_order=axes_order,
|
|
446
450
|
transforms=transforms,
|
|
447
451
|
slicing_dict=slicing_dict,
|
|
448
|
-
remove_channel_selection=
|
|
452
|
+
remove_channel_selection=remove_channel_selection,
|
|
449
453
|
)
|
|
450
454
|
|
|
451
455
|
if label_data_getter is None:
|
|
@@ -464,7 +468,7 @@ def build_masked_numpy_setter(
|
|
|
464
468
|
axes_order=axes_order,
|
|
465
469
|
transforms=transforms,
|
|
466
470
|
slicing_dict=slicing_dict,
|
|
467
|
-
remove_channel_selection=
|
|
471
|
+
remove_channel_selection=remove_channel_selection,
|
|
468
472
|
)
|
|
469
473
|
|
|
470
474
|
def set_patch_masked_as_numpy(patch: np.ndarray) -> None:
|
|
@@ -498,6 +502,7 @@ def build_masked_dask_setter(
|
|
|
498
502
|
data_getter: Callable[[], DaskArray] | None = None,
|
|
499
503
|
label_data_getter: Callable[[], DaskArray] | None = None,
|
|
500
504
|
allow_scaling: bool = True,
|
|
505
|
+
remove_channel_selection: bool = False,
|
|
501
506
|
) -> Callable[[DaskArray], None]:
|
|
502
507
|
"""Set a dask array to the zarr array with the given slice kwargs."""
|
|
503
508
|
slicing_dict = slicing_dict or {}
|
|
@@ -510,7 +515,7 @@ def build_masked_dask_setter(
|
|
|
510
515
|
axes_order=axes_order,
|
|
511
516
|
transforms=transforms,
|
|
512
517
|
slicing_dict=slicing_dict,
|
|
513
|
-
remove_channel_selection=
|
|
518
|
+
remove_channel_selection=remove_channel_selection,
|
|
514
519
|
)
|
|
515
520
|
|
|
516
521
|
if label_data_getter is None:
|
|
@@ -529,7 +534,7 @@ def build_masked_dask_setter(
|
|
|
529
534
|
axes_order=axes_order,
|
|
530
535
|
transforms=transforms,
|
|
531
536
|
slicing_dict=slicing_dict,
|
|
532
|
-
remove_channel_selection=
|
|
537
|
+
remove_channel_selection=remove_channel_selection,
|
|
533
538
|
)
|
|
534
539
|
|
|
535
540
|
def set_patch_masked_as_dask(patch: DaskArray) -> None:
|
ngio/common/_roi.py
CHANGED
|
@@ -49,7 +49,7 @@ T = TypeVar("T", int, float)
|
|
|
49
49
|
class GenericRoi(BaseModel, Generic[T]):
|
|
50
50
|
"""A generic Region of Interest (ROI) model."""
|
|
51
51
|
|
|
52
|
-
name: str
|
|
52
|
+
name: str | None
|
|
53
53
|
x: T
|
|
54
54
|
y: T
|
|
55
55
|
z: T | None = None
|
|
@@ -67,6 +67,38 @@ class GenericRoi(BaseModel, Generic[T]):
|
|
|
67
67
|
"""Calculate the intersection of this ROI with another ROI."""
|
|
68
68
|
return roi_intersection(self, other)
|
|
69
69
|
|
|
70
|
+
def _nice_str(self) -> str:
|
|
71
|
+
if self.t is not None:
|
|
72
|
+
t_str = f"t={self.t}->{self.t_length}"
|
|
73
|
+
else:
|
|
74
|
+
t_str = "t=None"
|
|
75
|
+
if self.z is not None:
|
|
76
|
+
z_str = f"z={self.z}->{self.z_length}"
|
|
77
|
+
else:
|
|
78
|
+
z_str = "z=None"
|
|
79
|
+
|
|
80
|
+
y_str = f"y={self.y}->{self.y_length}"
|
|
81
|
+
x_str = f"x={self.x}->{self.x_length}"
|
|
82
|
+
|
|
83
|
+
if self.label is not None:
|
|
84
|
+
label_str = f", label={self.label}"
|
|
85
|
+
else:
|
|
86
|
+
label_str = ""
|
|
87
|
+
cls_name = self.__class__.__name__
|
|
88
|
+
return f"{cls_name}({t_str}, {z_str}, {y_str}, {x_str}{label_str})"
|
|
89
|
+
|
|
90
|
+
def get_name(self) -> str:
|
|
91
|
+
"""Get the name of the ROI, or a default if not set."""
|
|
92
|
+
if self.name is not None:
|
|
93
|
+
return self.name
|
|
94
|
+
return self._nice_str()
|
|
95
|
+
|
|
96
|
+
def __repr__(self) -> str:
|
|
97
|
+
return self._nice_str()
|
|
98
|
+
|
|
99
|
+
def __str__(self) -> str:
|
|
100
|
+
return self._nice_str()
|
|
101
|
+
|
|
70
102
|
|
|
71
103
|
def _1d_intersection(
|
|
72
104
|
a: T | None, a_length: T | None, b: T | None, b_length: T | None
|
|
@@ -113,11 +145,17 @@ def roi_intersection(
|
|
|
113
145
|
x, x_length = _1d_intersection(
|
|
114
146
|
ref_roi.x, ref_roi.x_length, other_roi.x, other_roi.x_length
|
|
115
147
|
)
|
|
148
|
+
if x is None and x_length is None:
|
|
149
|
+
# No intersection
|
|
150
|
+
return None
|
|
116
151
|
assert x is not None and x_length is not None
|
|
117
152
|
|
|
118
153
|
y, y_length = _1d_intersection(
|
|
119
154
|
ref_roi.y, ref_roi.y_length, other_roi.y, other_roi.y_length
|
|
120
155
|
)
|
|
156
|
+
if y is None and y_length is None:
|
|
157
|
+
# No intersection
|
|
158
|
+
return None
|
|
121
159
|
assert y is not None and y_length is not None
|
|
122
160
|
|
|
123
161
|
z, z_length = _1d_intersection(
|
|
@@ -127,11 +165,8 @@ def roi_intersection(
|
|
|
127
165
|
ref_roi.t, ref_roi.t_length, other_roi.t, other_roi.t_length
|
|
128
166
|
)
|
|
129
167
|
|
|
130
|
-
if (
|
|
131
|
-
|
|
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)
|
|
168
|
+
if (z_length is not None and z_length <= 0) or (
|
|
169
|
+
t_length is not None and t_length <= 0
|
|
135
170
|
):
|
|
136
171
|
# No intersection
|
|
137
172
|
return None
|
|
@@ -144,9 +179,14 @@ def roi_intersection(
|
|
|
144
179
|
)
|
|
145
180
|
label = ref_roi.label or other_roi.label
|
|
146
181
|
|
|
182
|
+
if ref_roi.name is not None and other_roi.name is not None:
|
|
183
|
+
name = f"{ref_roi.name}:{other_roi.name}"
|
|
184
|
+
else:
|
|
185
|
+
name = ref_roi.name or other_roi.name
|
|
186
|
+
|
|
147
187
|
cls_ref = ref_roi.__class__
|
|
148
188
|
return cls_ref(
|
|
149
|
-
name=
|
|
189
|
+
name=name,
|
|
150
190
|
x=x,
|
|
151
191
|
y=y,
|
|
152
192
|
z=z,
|
|
@@ -412,6 +452,7 @@ def build_roi_numpy_setter(
|
|
|
412
452
|
axes_order: Sequence[str] | None = None,
|
|
413
453
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
414
454
|
slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
455
|
+
remove_channel_selection: bool = False,
|
|
415
456
|
) -> Callable[[np.ndarray], None]:
|
|
416
457
|
"""Prepare slice kwargs for setting an array."""
|
|
417
458
|
input_slice_kwargs = roi_to_slicing_dict(
|
|
@@ -426,6 +467,7 @@ def build_roi_numpy_setter(
|
|
|
426
467
|
axes_order=axes_order,
|
|
427
468
|
transforms=transforms,
|
|
428
469
|
slicing_dict=input_slice_kwargs,
|
|
470
|
+
remove_channel_selection=remove_channel_selection,
|
|
429
471
|
)
|
|
430
472
|
|
|
431
473
|
|
|
@@ -464,6 +506,7 @@ def build_roi_dask_setter(
|
|
|
464
506
|
axes_order: Sequence[str] | None = None,
|
|
465
507
|
transforms: Sequence[TransformProtocol] | None = None,
|
|
466
508
|
slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
509
|
+
remove_channel_selection: bool = False,
|
|
467
510
|
) -> Callable[[da.Array], None]:
|
|
468
511
|
"""Prepare slice kwargs for setting an array."""
|
|
469
512
|
input_slice_kwargs = roi_to_slicing_dict(
|
|
@@ -478,6 +521,7 @@ def build_roi_dask_setter(
|
|
|
478
521
|
axes_order=axes_order,
|
|
479
522
|
transforms=transforms,
|
|
480
523
|
slicing_dict=input_slice_kwargs,
|
|
524
|
+
remove_channel_selection=remove_channel_selection,
|
|
481
525
|
)
|
|
482
526
|
|
|
483
527
|
|
|
@@ -504,6 +548,7 @@ def build_roi_masked_numpy_getter(
|
|
|
504
548
|
label_slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
505
549
|
fill_value: int | float = 0,
|
|
506
550
|
allow_scaling: bool = True,
|
|
551
|
+
remove_channel_selection: bool = False,
|
|
507
552
|
) -> Callable[[], np.ndarray]:
|
|
508
553
|
"""Prepare slice kwargs for getting a masked array."""
|
|
509
554
|
input_slice_kwargs = roi_to_slicing_dict(
|
|
@@ -531,6 +576,7 @@ def build_roi_masked_numpy_getter(
|
|
|
531
576
|
label_slicing_dict=label_slice_kwargs,
|
|
532
577
|
fill_value=fill_value,
|
|
533
578
|
allow_scaling=allow_scaling,
|
|
579
|
+
remove_channel_selection=remove_channel_selection,
|
|
534
580
|
)
|
|
535
581
|
|
|
536
582
|
|
|
@@ -549,6 +595,7 @@ def build_roi_masked_numpy_setter(
|
|
|
549
595
|
slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
550
596
|
label_slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
551
597
|
allow_scaling: bool = True,
|
|
598
|
+
remove_channel_selection: bool = False,
|
|
552
599
|
) -> Callable[[np.ndarray], None]:
|
|
553
600
|
"""Prepare slice kwargs for setting a masked array."""
|
|
554
601
|
input_slice_kwargs = roi_to_slicing_dict(
|
|
@@ -575,6 +622,7 @@ def build_roi_masked_numpy_setter(
|
|
|
575
622
|
slicing_dict=input_slice_kwargs,
|
|
576
623
|
label_slicing_dict=label_slice_kwargs,
|
|
577
624
|
allow_scaling=allow_scaling,
|
|
625
|
+
remove_channel_selection=remove_channel_selection,
|
|
578
626
|
)
|
|
579
627
|
|
|
580
628
|
|
|
@@ -593,6 +641,7 @@ def build_roi_masked_dask_getter(
|
|
|
593
641
|
slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
594
642
|
label_slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
595
643
|
allow_scaling: bool = True,
|
|
644
|
+
remove_channel_selection: bool = False,
|
|
596
645
|
) -> Callable[[], da.Array]:
|
|
597
646
|
"""Prepare slice kwargs for getting a masked array."""
|
|
598
647
|
input_slice_kwargs = roi_to_slicing_dict(
|
|
@@ -619,6 +668,7 @@ def build_roi_masked_dask_getter(
|
|
|
619
668
|
slicing_dict=input_slice_kwargs,
|
|
620
669
|
label_slicing_dict=label_slice_kwargs,
|
|
621
670
|
allow_scaling=allow_scaling,
|
|
671
|
+
remove_channel_selection=remove_channel_selection,
|
|
622
672
|
)
|
|
623
673
|
|
|
624
674
|
|
|
@@ -637,6 +687,7 @@ def build_roi_masked_dask_setter(
|
|
|
637
687
|
slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
638
688
|
label_slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
639
689
|
allow_scaling: bool = True,
|
|
690
|
+
remove_channel_selection: bool = False,
|
|
640
691
|
) -> Callable[[da.Array], None]:
|
|
641
692
|
"""Prepare slice kwargs for setting a masked array."""
|
|
642
693
|
input_slice_kwargs = roi_to_slicing_dict(
|
|
@@ -663,4 +714,5 @@ def build_roi_masked_dask_setter(
|
|
|
663
714
|
slicing_dict=input_slice_kwargs,
|
|
664
715
|
label_slicing_dict=label_slice_kwargs,
|
|
665
716
|
allow_scaling=allow_scaling,
|
|
717
|
+
remove_channel_selection=remove_channel_selection,
|
|
666
718
|
)
|
|
@@ -47,7 +47,7 @@ class FeatureExtractorIterator(AbstractIteratorBuilder):
|
|
|
47
47
|
self._input = input_image
|
|
48
48
|
self._input_label = input_label
|
|
49
49
|
self._ref_image = input_image
|
|
50
|
-
self._rois = input_image.build_image_roi_table().rois()
|
|
50
|
+
self._rois = input_image.build_image_roi_table(name=None).rois()
|
|
51
51
|
|
|
52
52
|
# Set iteration parameters
|
|
53
53
|
self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
|
|
@@ -53,7 +53,7 @@ class ImageProcessingIterator(AbstractIteratorBuilder):
|
|
|
53
53
|
self._input = input_image
|
|
54
54
|
self._output = output_image
|
|
55
55
|
self._ref_image = input_image
|
|
56
|
-
self._rois = input_image.build_image_roi_table().rois()
|
|
56
|
+
self._rois = input_image.build_image_roi_table(name=None).rois()
|
|
57
57
|
|
|
58
58
|
# Set iteration parameters
|
|
59
59
|
self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
|
|
@@ -24,7 +24,7 @@ def grid(
|
|
|
24
24
|
stride_y: int | None = None,
|
|
25
25
|
stride_z: int | None = None,
|
|
26
26
|
stride_t: int | None = None,
|
|
27
|
-
base_name: str =
|
|
27
|
+
base_name: str | None = None,
|
|
28
28
|
) -> list[Roi]:
|
|
29
29
|
"""This method is a placeholder for creating a regular grid of ROIs."""
|
|
30
30
|
t_dim = ref_image.dimensions.get("t", default=1)
|
|
@@ -49,7 +49,7 @@ def grid(
|
|
|
49
49
|
for y in range(0, y_dim, stride_y):
|
|
50
50
|
for x in range(0, x_dim, stride_x):
|
|
51
51
|
roi = RoiPixels(
|
|
52
|
-
name=
|
|
52
|
+
name=base_name,
|
|
53
53
|
x=x,
|
|
54
54
|
y=y,
|
|
55
55
|
z=z,
|
|
@@ -55,7 +55,7 @@ class SegmentationIterator(AbstractIteratorBuilder):
|
|
|
55
55
|
self._input = input_image
|
|
56
56
|
self._output = output_label
|
|
57
57
|
self._ref_image = input_image
|
|
58
|
-
self._rois = input_image.build_image_roi_table().rois()
|
|
58
|
+
self._rois = input_image.build_image_roi_table(name=None).rois()
|
|
59
59
|
|
|
60
60
|
# Set iteration parameters
|
|
61
61
|
self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
|
|
@@ -103,6 +103,7 @@ class SegmentationIterator(AbstractIteratorBuilder):
|
|
|
103
103
|
transforms=self._output_transforms,
|
|
104
104
|
pixel_size=self._output.pixel_size,
|
|
105
105
|
roi=roi,
|
|
106
|
+
remove_channel_selection=True,
|
|
106
107
|
)
|
|
107
108
|
|
|
108
109
|
def build_dask_getter(self, roi: Roi):
|
|
@@ -124,6 +125,7 @@ class SegmentationIterator(AbstractIteratorBuilder):
|
|
|
124
125
|
transforms=self._output_transforms,
|
|
125
126
|
pixel_size=self._output.pixel_size,
|
|
126
127
|
roi=roi,
|
|
128
|
+
remove_channel_selection=True,
|
|
127
129
|
)
|
|
128
130
|
|
|
129
131
|
def post_consolidate(self):
|
|
@@ -245,6 +247,7 @@ class MaskedSegmentationIterator(SegmentationIterator):
|
|
|
245
247
|
axes_order=self._axes_order,
|
|
246
248
|
transforms=self._output_transforms,
|
|
247
249
|
pixel_size=self._output.pixel_size,
|
|
250
|
+
remove_channel_selection=True,
|
|
248
251
|
)
|
|
249
252
|
|
|
250
253
|
def build_dask_getter(self, roi: Roi):
|
|
@@ -272,6 +275,7 @@ class MaskedSegmentationIterator(SegmentationIterator):
|
|
|
272
275
|
axes_order=self._axes_order,
|
|
273
276
|
transforms=self._output_transforms,
|
|
274
277
|
pixel_size=self._output.pixel_size,
|
|
278
|
+
remove_channel_selection=True,
|
|
275
279
|
)
|
|
276
280
|
|
|
277
281
|
def post_consolidate(self):
|
ngio/images/_abstract_image.py
CHANGED
|
@@ -445,7 +445,7 @@ class AbstractImage(Generic[_image_handler]):
|
|
|
445
445
|
"""
|
|
446
446
|
consolidate_image(image=self, order=order, mode=mode)
|
|
447
447
|
|
|
448
|
-
def build_image_roi_table(self, name: str = "image") -> RoiTable:
|
|
448
|
+
def build_image_roi_table(self, name: str | None = "image") -> RoiTable:
|
|
449
449
|
"""Build the ROI table for an image."""
|
|
450
450
|
return build_image_roi_table(image=self, name=name)
|
|
451
451
|
|
|
@@ -467,7 +467,7 @@ def consolidate_image(
|
|
|
467
467
|
)
|
|
468
468
|
|
|
469
469
|
|
|
470
|
-
def build_image_roi_table(image: AbstractImage, name: str = "image") -> RoiTable:
|
|
470
|
+
def build_image_roi_table(image: AbstractImage, name: str | None = "image") -> RoiTable:
|
|
471
471
|
"""Build the ROI table for an image."""
|
|
472
472
|
dim_x = image.dimensions.get("x")
|
|
473
473
|
dim_y = image.dimensions.get("y")
|
|
@@ -589,7 +589,7 @@ class OmeZarrContainer:
|
|
|
589
589
|
backend=backend,
|
|
590
590
|
)
|
|
591
591
|
|
|
592
|
-
def build_image_roi_table(self, name: str = "image") -> RoiTable:
|
|
592
|
+
def build_image_roi_table(self, name: str | None = "image") -> RoiTable:
|
|
593
593
|
"""Compute the ROI table for an image."""
|
|
594
594
|
return self.get_image().build_image_roi_table(name=name)
|
|
595
595
|
|
|
Binary file
|
ngio/tables/v1/_roi_table.py
CHANGED
|
@@ -6,6 +6,7 @@ https://fractal-analytics-platform.github.io/fractal-tasks-core/tables/
|
|
|
6
6
|
|
|
7
7
|
from collections.abc import Iterable
|
|
8
8
|
from typing import Literal
|
|
9
|
+
from uuid import uuid4
|
|
9
10
|
|
|
10
11
|
import pandas as pd
|
|
11
12
|
from pydantic import BaseModel
|
|
@@ -146,7 +147,7 @@ def _rois_to_dataframe(rois: dict[str, Roi], index_key: str | None) -> pd.DataFr
|
|
|
146
147
|
len_z_micrometer = roi.z_length if roi.z_length is not None else 1.0
|
|
147
148
|
|
|
148
149
|
row = {
|
|
149
|
-
index_key: roi.
|
|
150
|
+
index_key: roi.get_name(),
|
|
150
151
|
"x_micrometer": roi.x,
|
|
151
152
|
"y_micrometer": roi.y,
|
|
152
153
|
"z_micrometer": z_micrometer,
|
|
@@ -179,8 +180,15 @@ class RoiDictWrapper:
|
|
|
179
180
|
"""A wrapper for a dictionary of ROIs to provide a consistent interface."""
|
|
180
181
|
|
|
181
182
|
def __init__(self, rois: Iterable[Roi]) -> None:
|
|
182
|
-
self._rois_by_name = {
|
|
183
|
-
self._rois_by_label = {
|
|
183
|
+
self._rois_by_name = {}
|
|
184
|
+
self._rois_by_label = {}
|
|
185
|
+
for roi in rois:
|
|
186
|
+
name = roi.get_name()
|
|
187
|
+
if name in self._rois_by_name:
|
|
188
|
+
name = f"{name}_{uuid4().hex[:8]}"
|
|
189
|
+
self._rois_by_name[name] = roi
|
|
190
|
+
if roi.label is not None:
|
|
191
|
+
self._rois_by_label[roi.label] = roi
|
|
184
192
|
|
|
185
193
|
def get_by_name(self, name: str, default: Roi | None = None) -> Roi | None:
|
|
186
194
|
"""Get an ROI by its name."""
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
ngio/__init__.py,sha256=clqwRwmkalSwXvmNLGwtI-385gwvBTnJjohEk3Xp5cE,1463
|
|
2
2
|
ngio/common/__init__.py,sha256=t5FUH7kSTqTT1jHmL_qYiEUCHHwMEKNfcZ6EbrkcpNg,1958
|
|
3
|
-
ngio/common/_array_io_pipes.py,sha256=
|
|
3
|
+
ngio/common/_array_io_pipes.py,sha256=zxZIVRtPjWUQ8J09_s5RcwoTgCOHDGmYYrkdPQbOPlM,18221
|
|
4
4
|
ngio/common/_array_io_utils.py,sha256=LktLM2_2LkjYkwzyJXHZ0LyuwrQN4GYTqgpByBxNmlg,16303
|
|
5
5
|
ngio/common/_dimensions.py,sha256=ubBSmnQmZOmen1jUn3LWZlNXCjUuV9FTjZWzUYidOwk,4852
|
|
6
6
|
ngio/common/_masking_roi.py,sha256=ZZTXordEZoq_ADk0OzADvq-5dPOwUBSuNobzFR8fpTw,5697
|
|
7
7
|
ngio/common/_pyramid.py,sha256=ElY_nBcchN3eeD9obLZ31IIo42HVlDn8R-legQpNxzQ,7503
|
|
8
|
-
ngio/common/_roi.py,sha256=
|
|
8
|
+
ngio/common/_roi.py,sha256=x5HHudELvYjOmoLJulk2cNrgfOZ0o1Q1OFtldZAKIKU,22360
|
|
9
9
|
ngio/common/_synt_images_utils.py,sha256=B6uYOW1NyrM06YMR-csca3_YnAAkPRTbvnbLdy9tk9E,3188
|
|
10
10
|
ngio/common/_zoom.py,sha256=p_trkLLrNM6hYvchJQJOHfYpzSlzzdDJmcyTx6K5J1M,6030
|
|
11
11
|
ngio/common/transforms/__init__.py,sha256=Dn8SpMw_e_bg9kx4ZVPrGHJIu_yOK1FkIlePlN_C7FQ,120
|
|
@@ -14,20 +14,20 @@ ngio/common/transforms/_zoom.py,sha256=mbnPnJZsCCms5x1Tq2akvsRDbsDYomiNRGqiF6KY2
|
|
|
14
14
|
ngio/experimental/__init__.py,sha256=3pmBtHi-i8bKjTsvrOJM56ZyRX3Pv_dceCdt88-8COQ,147
|
|
15
15
|
ngio/experimental/iterators/__init__.py,sha256=on_sUvuRhHBb7-r5u3Ojvu6K9FGjUOrWGUkLQ4aRzbs,556
|
|
16
16
|
ngio/experimental/iterators/_abstract_iterator.py,sha256=p8ZxQuoqPGLZCp79FprhgV-QsN5uuqadffoXnEqSdys,5533
|
|
17
|
-
ngio/experimental/iterators/_feature.py,sha256=
|
|
18
|
-
ngio/experimental/iterators/_image_processing.py,sha256=
|
|
19
|
-
ngio/experimental/iterators/_rois_utils.py,sha256=
|
|
20
|
-
ngio/experimental/iterators/_segmentation.py,sha256=
|
|
17
|
+
ngio/experimental/iterators/_feature.py,sha256=5MI0hgcR2lFUQLI4RpVCL2SDJNhmunW33tIUQhPWl_s,5996
|
|
18
|
+
ngio/experimental/iterators/_image_processing.py,sha256=fkD8PDm-3RaKpsRIRzvkeEkvDJ-fzcSWqrMXI3DBM4w,6648
|
|
19
|
+
ngio/experimental/iterators/_rois_utils.py,sha256=yFIlUAsSuh9ArUakJv7kTIiO2yG5r7kuDw-ljmtHj5Y,4359
|
|
20
|
+
ngio/experimental/iterators/_segmentation.py,sha256=NMzHcny2aUCRiSa9dROQ0kMzllYqIEwMh-fUmekw7dY,11229
|
|
21
21
|
ngio/hcs/__init__.py,sha256=G8j9vD-liLeB_UeGtKYIgshWvJnUA6ks9GwjvWBLdHs,357
|
|
22
22
|
ngio/hcs/_plate.py,sha256=qfRwbCKaoz_AWTi8RDFFwOxy5geSknfJrPcqFVno9zI,44288
|
|
23
23
|
ngio/images/__init__.py,sha256=9Whvt7GTiCgT_vXaEEqGnDaY1-UsRk3dhLTv091F_g4,1211
|
|
24
|
-
ngio/images/_abstract_image.py,sha256=
|
|
24
|
+
ngio/images/_abstract_image.py,sha256=DfKz2xjB4QKMTYn8K9YorQSiPyzcwe9QCDtzzgsCnHE,15615
|
|
25
25
|
ngio/images/_create.py,sha256=X0EalQgrcdh_RVgSxIkv0YNQydKXNRpCXHlgn1oVpI0,9445
|
|
26
26
|
ngio/images/_create_synt_container.py,sha256=XjsQjBEnEGiqrfyKBdp_h4dJmScBMpMg1yUEqObo7Nw,5004
|
|
27
27
|
ngio/images/_image.py,sha256=4PwHsD0KiiJwcyuVX4-iuLCv6V05N6JlCDlEggyLJkw,31742
|
|
28
28
|
ngio/images/_label.py,sha256=rv6-oigkpa5mUTdogdPhfC3JYkEbdjXxY6Y6f1oD-RI,10603
|
|
29
29
|
ngio/images/_masked_image.py,sha256=oFApCcPejfapzilh3ecO2NmI_FReU1FJPc-8XJqsYYU,19619
|
|
30
|
-
ngio/images/_ome_zarr_container.py,sha256=
|
|
30
|
+
ngio/images/_ome_zarr_container.py,sha256=WvvqH73pQkIIyiJTM6Fyzz6wjLs57V3hdEM7YBWzpOo,36712
|
|
31
31
|
ngio/images/_table_ops.py,sha256=jFv_AMqoB4JBpoWsMtZppZVW7dAOC_u-JpfNm8b33kY,15292
|
|
32
32
|
ngio/ome_zarr_meta/__init__.py,sha256=oZ8PEsWM7U0KwzpsnvVfX9k4UfuTz5sZ8B6B9eY5hyY,1193
|
|
33
33
|
ngio/ome_zarr_meta/_meta_handlers.py,sha256=ctknNDT8jxwyvxQf9on5gW31H1tRRsnneO38GT2UXoE,25880
|
|
@@ -43,7 +43,7 @@ ngio/ome_zarr_meta/v04/_custom_models.py,sha256=5GxiDERvLuvq4QvApcA6EiKLS6hLFX1R
|
|
|
43
43
|
ngio/ome_zarr_meta/v04/_v04_spec_utils.py,sha256=YKBVVWb3mnuE-5L5k1i85WpHmcrbKl9k5KU2jNqt5yg,15868
|
|
44
44
|
ngio/resources/__init__.py,sha256=Hry2odzDaC471_qgVfAQVnWDMK0Io9F8m9_JBNNm4e0,1633
|
|
45
45
|
ngio/resources/resource_model.py,sha256=0Egs0QAJ5PNknqECHuBd_-ZTdi8EDNirt5VyuPdbg30,835
|
|
46
|
-
ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png,sha256=
|
|
46
|
+
ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png,sha256=g3QmxQdmeciAtBe5cTCRfR6yw3keG9cBYfjizMo6EGo,11890
|
|
47
47
|
ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png,sha256=QhZ4XiFX7r-8-fbX8wSeUymktX85Ap3Nw1MqeOfRrF8,21649
|
|
48
48
|
ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg,sha256=82lejQAIokj5w9g-qqhysDTWpHtNvJTkdURG_BjqIxQ,37743
|
|
49
49
|
ngio/tables/__init__.py,sha256=_BV3sclNMLITu_J8_3DkkUrCB6Kro0HzeWLDCD1ivKM,877
|
|
@@ -63,14 +63,14 @@ ngio/tables/v1/__init__.py,sha256=Wr1_9RZFpaN8FYMTnxT9Yjkw4AS7y9FMWailmB_uj5g,61
|
|
|
63
63
|
ngio/tables/v1/_condition_table.py,sha256=T0Uq5BKkmMoEspt_Rx0U99Ow6S9GAMZDHqvUO5obCAM,1780
|
|
64
64
|
ngio/tables/v1/_feature_table.py,sha256=n9uMHwoBh-_dlOhUXCFbmAjXFVXncNCR3SjE2qzXI68,3821
|
|
65
65
|
ngio/tables/v1/_generic_table.py,sha256=1ktJHeuv7U1g5Z8PFUuTkCjOzcYMQd8xegKHKUedJB8,1240
|
|
66
|
-
ngio/tables/v1/_roi_table.py,sha256=
|
|
66
|
+
ngio/tables/v1/_roi_table.py,sha256=g7UpMmpf3uAfaG59WYRnimUBgiB_T1qUJRwMZpMt9cI,17099
|
|
67
67
|
ngio/utils/__init__.py,sha256=XPYh8ehC7uXNU2cFFXZAw-S3DpWpX1Yq2xGkffZv5vI,1142
|
|
68
68
|
ngio/utils/_datasets.py,sha256=2g-Neg78dNcqyDz39QQw-Ifp9GITHjVHisdqgvvDNDE,5475
|
|
69
69
|
ngio/utils/_errors.py,sha256=pKQ12LUjQLYE1nUawemA5h7HsgznjaSvV1n2PQU33N0,759
|
|
70
70
|
ngio/utils/_fractal_fsspec_store.py,sha256=RdcCFOgHexRKX9zZvJV5RI-5OPc7VOPS6q_IeRxm24I,1548
|
|
71
71
|
ngio/utils/_logger.py,sha256=N5W0a_xwze4blS1MolidBkTMbjTbg8GPguJZNun3mAE,1392
|
|
72
72
|
ngio/utils/_zarr_utils.py,sha256=aYHhjHWGy5Jx7IkPb4nt9N0-HgyvJnyvK9GGqnccZkE,13606
|
|
73
|
-
ngio-0.4.
|
|
74
|
-
ngio-0.4.
|
|
75
|
-
ngio-0.4.
|
|
76
|
-
ngio-0.4.
|
|
73
|
+
ngio-0.4.0a3.dist-info/METADATA,sha256=PrG0TduDw2_iog0OKt2wF_gse3DW0oshBq158P6BS34,5868
|
|
74
|
+
ngio-0.4.0a3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
75
|
+
ngio-0.4.0a3.dist-info/licenses/LICENSE,sha256=UgN_a1QCeNh9rZWfz-wORQFxE3elQzLWPQaoK6N6fxQ,1502
|
|
76
|
+
ngio-0.4.0a3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|