ngio 0.4.0a2__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/_roi.py +47 -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 +1 -1
- ngio/images/_abstract_image.py +2 -2
- ngio/images/_ome_zarr_container.py +1 -1
- ngio/tables/v1/_roi_table.py +11 -3
- {ngio-0.4.0a2.dist-info → ngio-0.4.0a3.dist-info}/METADATA +1 -1
- {ngio-0.4.0a2.dist-info → ngio-0.4.0a3.dist-info}/RECORD +12 -12
- {ngio-0.4.0a2.dist-info → ngio-0.4.0a3.dist-info}/WHEEL +0 -0
- {ngio-0.4.0a2.dist-info → ngio-0.4.0a3.dist-info}/licenses/LICENSE +0 -0
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,
|
|
@@ -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(
|
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
|
|
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."""
|
|
@@ -5,7 +5,7 @@ ngio/common/_array_io_utils.py,sha256=LktLM2_2LkjYkwzyJXHZ0LyuwrQN4GYTqgpByBxNml
|
|
|
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
|
|
@@ -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
|