ngio 0.5.0__py3-none-any.whl → 0.5.0a2__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/__init__.py +2 -5
- ngio/common/__init__.py +6 -11
- ngio/common/_masking_roi.py +54 -34
- ngio/common/_pyramid.py +85 -309
- ngio/common/_roi.py +330 -258
- ngio/experimental/iterators/_feature.py +3 -3
- ngio/experimental/iterators/_rois_utils.py +11 -10
- ngio/hcs/_plate.py +60 -132
- ngio/images/_abstract_image.py +35 -539
- ngio/images/_create.py +287 -0
- ngio/images/_create_synt_container.py +42 -39
- ngio/images/_image.py +250 -516
- ngio/images/_label.py +172 -249
- ngio/images/_masked_image.py +2 -2
- ngio/images/_ome_zarr_container.py +241 -644
- ngio/io_pipes/_io_pipes.py +9 -9
- ngio/io_pipes/_io_pipes_masked.py +7 -7
- ngio/io_pipes/_io_pipes_roi.py +6 -6
- ngio/io_pipes/_io_pipes_types.py +3 -3
- ngio/io_pipes/_match_shape.py +8 -6
- ngio/io_pipes/_ops_slices_utils.py +5 -8
- ngio/ome_zarr_meta/__init__.py +18 -29
- ngio/ome_zarr_meta/_meta_handlers.py +708 -392
- ngio/ome_zarr_meta/ngio_specs/__init__.py +0 -4
- ngio/ome_zarr_meta/ngio_specs/_axes.py +51 -152
- ngio/ome_zarr_meta/ngio_specs/_dataset.py +22 -13
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +91 -129
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +68 -57
- ngio/ome_zarr_meta/v04/__init__.py +1 -5
- ngio/ome_zarr_meta/v04/{_v04_spec.py → _v04_spec_utils.py} +85 -54
- ngio/ome_zarr_meta/v05/__init__.py +1 -5
- ngio/ome_zarr_meta/v05/{_v05_spec.py → _v05_spec_utils.py} +87 -64
- ngio/resources/__init__.py +1 -1
- ngio/resources/resource_model.py +1 -1
- ngio/tables/_tables_container.py +11 -62
- ngio/tables/backends/_anndata.py +8 -58
- ngio/tables/backends/_anndata_utils.py +6 -1
- ngio/tables/backends/_csv.py +19 -3
- ngio/tables/backends/_json.py +13 -10
- ngio/tables/backends/_non_zarr_backends.py +196 -0
- ngio/tables/backends/_parquet.py +31 -3
- ngio/tables/v1/_roi_table.py +24 -41
- ngio/utils/__init__.py +12 -6
- ngio/utils/_datasets.py +0 -6
- ngio/utils/_logger.py +50 -0
- ngio/utils/_zarr_utils.py +58 -167
- {ngio-0.5.0.dist-info → ngio-0.5.0a2.dist-info}/METADATA +4 -11
- ngio-0.5.0a2.dist-info/RECORD +89 -0
- {ngio-0.5.0.dist-info → ngio-0.5.0a2.dist-info}/WHEEL +1 -1
- ngio/images/_create_utils.py +0 -406
- ngio/tables/backends/_py_arrow_backends.py +0 -222
- ngio-0.5.0.dist-info/RECORD +0 -88
- {ngio-0.5.0.dist-info → ngio-0.5.0a2.dist-info}/licenses/LICENSE +0 -0
ngio/images/_label.py
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
"""A module for handling label images in OME-NGFF files."""
|
|
2
2
|
|
|
3
|
-
from collections.abc import
|
|
4
|
-
from typing import
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import Literal
|
|
5
5
|
|
|
6
6
|
from zarr.core.array import CompressorLike
|
|
7
7
|
|
|
8
8
|
from ngio.common import compute_masking_roi
|
|
9
|
-
from ngio.
|
|
10
|
-
from ngio.images.
|
|
9
|
+
from ngio.images._abstract_image import AbstractImage
|
|
10
|
+
from ngio.images._create import create_empty_label_container
|
|
11
11
|
from ngio.images._image import Image
|
|
12
12
|
from ngio.ome_zarr_meta import (
|
|
13
13
|
LabelMetaHandler,
|
|
14
|
-
LabelsGroupMetaHandler,
|
|
15
14
|
NgioLabelMeta,
|
|
16
|
-
NgioLabelsGroupMeta,
|
|
17
15
|
PixelSize,
|
|
18
|
-
|
|
16
|
+
find_label_meta_handler,
|
|
19
17
|
)
|
|
20
18
|
from ngio.ome_zarr_meta.ngio_specs import (
|
|
21
|
-
|
|
19
|
+
DefaultSpaceUnit,
|
|
20
|
+
DefaultTimeUnit,
|
|
21
|
+
SpaceUnits,
|
|
22
|
+
TimeUnits,
|
|
22
23
|
)
|
|
23
|
-
from ngio.ome_zarr_meta.ngio_specs._axes import AxesSetup
|
|
24
24
|
from ngio.tables import MaskingRoiTable
|
|
25
25
|
from ngio.utils import (
|
|
26
26
|
NgioValidationError,
|
|
@@ -28,9 +28,10 @@ from ngio.utils import (
|
|
|
28
28
|
StoreOrGroup,
|
|
29
29
|
ZarrGroupHandler,
|
|
30
30
|
)
|
|
31
|
+
from ngio.utils._zarr_utils import find_dimension_separator
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
class Label(AbstractImage):
|
|
34
|
+
class Label(AbstractImage[LabelMetaHandler]):
|
|
34
35
|
"""Placeholder class for a label."""
|
|
35
36
|
|
|
36
37
|
get_as_numpy = AbstractImage._get_as_numpy
|
|
@@ -46,7 +47,7 @@ class Label(AbstractImage):
|
|
|
46
47
|
self,
|
|
47
48
|
group_handler: ZarrGroupHandler,
|
|
48
49
|
path: str,
|
|
49
|
-
meta_handler: LabelMetaHandler,
|
|
50
|
+
meta_handler: LabelMetaHandler | None,
|
|
50
51
|
) -> None:
|
|
51
52
|
"""Initialize the Image at a single level.
|
|
52
53
|
|
|
@@ -56,6 +57,8 @@ class Label(AbstractImage):
|
|
|
56
57
|
meta_handler: The image metadata handler.
|
|
57
58
|
|
|
58
59
|
"""
|
|
60
|
+
if meta_handler is None:
|
|
61
|
+
meta_handler = find_label_meta_handler(group_handler)
|
|
59
62
|
super().__init__(
|
|
60
63
|
group_handler=group_handler, path=path, meta_handler=meta_handler
|
|
61
64
|
)
|
|
@@ -64,24 +67,29 @@ class Label(AbstractImage):
|
|
|
64
67
|
"""Return the string representation of the label."""
|
|
65
68
|
return f"Label(path={self.path}, {self.dimensions})"
|
|
66
69
|
|
|
67
|
-
@property
|
|
68
|
-
def meta_handler(self) -> LabelMetaHandler:
|
|
69
|
-
"""Return the metadata handler."""
|
|
70
|
-
assert isinstance(self._meta_handler, LabelMetaHandler)
|
|
71
|
-
return self._meta_handler
|
|
72
|
-
|
|
73
70
|
@property
|
|
74
71
|
def meta(self) -> NgioLabelMeta:
|
|
75
72
|
"""Return the metadata."""
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
return self._meta_handler.meta
|
|
74
|
+
|
|
75
|
+
def set_axes_unit(
|
|
76
|
+
self,
|
|
77
|
+
space_unit: SpaceUnits = DefaultSpaceUnit,
|
|
78
|
+
time_unit: TimeUnits = DefaultTimeUnit,
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Set the axes unit of the image.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
space_unit (SpaceUnits): The space unit of the image.
|
|
84
|
+
time_unit (TimeUnits): The time unit of the image.
|
|
85
|
+
"""
|
|
86
|
+
meta = self.meta
|
|
87
|
+
meta = meta.to_units(space_unit=space_unit, time_unit=time_unit)
|
|
88
|
+
self._meta_handler.write_meta(meta)
|
|
79
89
|
|
|
80
|
-
def build_masking_roi_table(
|
|
81
|
-
self, axes_order: Sequence[str] | None = None
|
|
82
|
-
) -> MaskingRoiTable:
|
|
90
|
+
def build_masking_roi_table(self) -> MaskingRoiTable:
|
|
83
91
|
"""Compute the masking ROI table."""
|
|
84
|
-
return build_masking_roi_table(self
|
|
92
|
+
return build_masking_roi_table(self)
|
|
85
93
|
|
|
86
94
|
def consolidate(
|
|
87
95
|
self,
|
|
@@ -97,46 +105,29 @@ class Label(AbstractImage):
|
|
|
97
105
|
class LabelsContainer:
|
|
98
106
|
"""A class to handle the /labels group in an OME-NGFF file."""
|
|
99
107
|
|
|
100
|
-
def __init__(
|
|
101
|
-
self,
|
|
102
|
-
group_handler: ZarrGroupHandler,
|
|
103
|
-
axes_setup: AxesSetup | None = None,
|
|
104
|
-
ngff_version: NgffVersions | None = None,
|
|
105
|
-
) -> None:
|
|
108
|
+
def __init__(self, group_handler: ZarrGroupHandler) -> None:
|
|
106
109
|
"""Initialize the LabelGroupHandler."""
|
|
107
110
|
self._group_handler = group_handler
|
|
108
|
-
|
|
109
|
-
#
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
111
|
+
# Validate the group
|
|
112
|
+
# Either contains a labels attribute or is empty
|
|
113
|
+
attrs = self._group_handler.load_attrs()
|
|
114
|
+
if len(attrs) == 0:
|
|
115
|
+
# It's an empty group
|
|
116
|
+
pass
|
|
117
|
+
elif "labels" in attrs and isinstance(attrs["labels"], list):
|
|
118
|
+
# It's a valid group
|
|
119
|
+
pass
|
|
120
|
+
else:
|
|
121
|
+
raise NgioValidationError(
|
|
122
|
+
f"Invalid /labels group. "
|
|
123
|
+
f"Expected a single labels attribute with a list of label names. "
|
|
124
|
+
f"Found: {attrs}"
|
|
122
125
|
)
|
|
123
|
-
self._group_handler = self._group_handler.reopen_handler()
|
|
124
|
-
self._meta_handler = LabelsGroupMetaHandler(group_handler)
|
|
125
|
-
|
|
126
|
-
@property
|
|
127
|
-
def meta(self) -> NgioLabelsGroupMeta:
|
|
128
|
-
"""Return the metadata."""
|
|
129
|
-
meta = self._meta_handler.get_meta()
|
|
130
|
-
return meta
|
|
131
|
-
|
|
132
|
-
@property
|
|
133
|
-
def axes_setup(self) -> AxesSetup:
|
|
134
|
-
"""Return the axes setup."""
|
|
135
|
-
return self._axes_setup
|
|
136
126
|
|
|
137
127
|
def list(self) -> list[str]:
|
|
138
|
-
"""
|
|
139
|
-
|
|
128
|
+
"""Create the /labels group if it doesn't exist."""
|
|
129
|
+
attrs = self._group_handler.load_attrs()
|
|
130
|
+
return attrs.get("labels", [])
|
|
140
131
|
|
|
141
132
|
def get(
|
|
142
133
|
self,
|
|
@@ -162,107 +153,49 @@ class LabelsContainer:
|
|
|
162
153
|
f"Available labels: {self.list()}"
|
|
163
154
|
)
|
|
164
155
|
|
|
165
|
-
group_handler = self._group_handler.
|
|
166
|
-
label_meta_handler =
|
|
167
|
-
path = (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
)
|
|
172
|
-
return Label(
|
|
173
|
-
group_handler=group_handler,
|
|
174
|
-
path=path,
|
|
175
|
-
meta_handler=label_meta_handler,
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
def delete(self, name: str, missing_ok: bool = False) -> None:
|
|
179
|
-
"""Delete a label from the group.
|
|
180
|
-
|
|
181
|
-
Args:
|
|
182
|
-
name (str): The name of the label to delete.
|
|
183
|
-
missing_ok (bool): If True, do not raise an error if the label does not
|
|
184
|
-
exist.
|
|
185
|
-
|
|
186
|
-
"""
|
|
187
|
-
existing_labels = self.list()
|
|
188
|
-
if name not in existing_labels:
|
|
189
|
-
if missing_ok:
|
|
190
|
-
return
|
|
191
|
-
raise NgioValueError(
|
|
192
|
-
f"Label '{name}' not found in the Labels group. "
|
|
193
|
-
f"Available labels: {existing_labels}"
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
self._group_handler.delete_group(name)
|
|
197
|
-
existing_labels.remove(name)
|
|
198
|
-
update_meta = NgioLabelsGroupMeta(
|
|
199
|
-
labels=existing_labels, version=self.meta.version
|
|
200
|
-
)
|
|
201
|
-
self._meta_handler.update_meta(update_meta)
|
|
156
|
+
group_handler = self._group_handler.derive_handler(name)
|
|
157
|
+
label_meta_handler = find_label_meta_handler(group_handler)
|
|
158
|
+
path = label_meta_handler.meta.get_dataset(
|
|
159
|
+
path=path, pixel_size=pixel_size, strict=strict
|
|
160
|
+
).path
|
|
161
|
+
return Label(group_handler, path, label_meta_handler)
|
|
202
162
|
|
|
203
163
|
def derive(
|
|
204
164
|
self,
|
|
205
165
|
name: str,
|
|
206
166
|
ref_image: Image | Label,
|
|
207
|
-
# Metadata parameters
|
|
208
167
|
shape: Sequence[int] | None = None,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
channels_policy: Literal["same", "squeeze", "singleton"] | int = "squeeze",
|
|
214
|
-
ngff_version: NgffVersions | None = None,
|
|
215
|
-
# Zarr Array parameters
|
|
216
|
-
chunks: ChunksLike | None = None,
|
|
217
|
-
shards: ShardsLike | None = None,
|
|
218
|
-
dtype: str | None = None,
|
|
168
|
+
pixel_size: PixelSize | None = None,
|
|
169
|
+
axes_names: Sequence[str] | None = None,
|
|
170
|
+
chunks: Sequence[int] | None = None,
|
|
171
|
+
dtype: str = "uint32",
|
|
219
172
|
dimension_separator: Literal[".", "/"] | None = None,
|
|
220
173
|
compressors: CompressorLike | None = None,
|
|
221
|
-
extra_array_kwargs: Mapping[str, Any] | None = None,
|
|
222
174
|
overwrite: bool = False,
|
|
223
|
-
# Deprecated arguments
|
|
224
|
-
labels: Sequence[str] | None = None,
|
|
225
|
-
pixel_size: PixelSize | None = None,
|
|
226
175
|
) -> "Label":
|
|
227
|
-
"""Create an empty OME-Zarr label from
|
|
176
|
+
"""Create an empty OME-Zarr label from a reference image.
|
|
228
177
|
|
|
229
|
-
|
|
178
|
+
And add the label to the /labels group.
|
|
230
179
|
|
|
231
180
|
Args:
|
|
232
|
-
|
|
233
|
-
ref_image (Image | Label):
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
that size.
|
|
248
|
-
ngff_version (NgffVersions | None): The NGFF version to use.
|
|
249
|
-
chunks (ChunksLike | None): The chunk shape of the new label.
|
|
250
|
-
shards (ShardsLike | None): The shard shape of the new label.
|
|
251
|
-
dtype (str | None): The data type of the new label.
|
|
252
|
-
dimension_separator (Literal[".", "/"] | None): The separator to use for
|
|
253
|
-
dimensions.
|
|
254
|
-
compressors (CompressorLike | None): The compressors to use.
|
|
255
|
-
extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
|
|
256
|
-
the zarr array creation.
|
|
257
|
-
overwrite (bool): Whether to overwrite an existing label.
|
|
258
|
-
labels (Sequence[str] | None): Deprecated. This argument is deprecated,
|
|
259
|
-
please use channels_meta instead.
|
|
260
|
-
pixel_size (PixelSize | None): Deprecated. The pixel size of the new label.
|
|
261
|
-
This argument is deprecated, please use pixelsize, z_spacing,
|
|
262
|
-
and time_spacing instead.
|
|
181
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
182
|
+
ref_image (Image | Label): A reference image that will be used to create
|
|
183
|
+
the new image.
|
|
184
|
+
name (str): The name of the new image.
|
|
185
|
+
shape (Sequence[int] | None): The shape of the new image.
|
|
186
|
+
pixel_size (PixelSize | None): The pixel size of the new image.
|
|
187
|
+
axes_names (Sequence[str] | None): The axes names of the new image.
|
|
188
|
+
For labels, the channel axis is not allowed.
|
|
189
|
+
chunks (Sequence[int] | None): The chunk shape of the new image.
|
|
190
|
+
dtype (str): The data type of the new label.
|
|
191
|
+
dimension_separator (DIMENSION_SEPARATOR | None): The separator to use for
|
|
192
|
+
dimensions. If None it will use the same as the reference image.
|
|
193
|
+
compressors (CompressorLike | None): The compressors to use. If None it will
|
|
194
|
+
use the same as the reference image.
|
|
195
|
+
overwrite (bool): Whether to overwrite an existing image.
|
|
263
196
|
|
|
264
197
|
Returns:
|
|
265
|
-
Label: The new
|
|
198
|
+
Label: The new label.
|
|
266
199
|
|
|
267
200
|
"""
|
|
268
201
|
existing_labels = self.list()
|
|
@@ -273,147 +206,137 @@ class LabelsContainer:
|
|
|
273
206
|
)
|
|
274
207
|
|
|
275
208
|
label_group = self._group_handler.get_group(name, create_mode=True)
|
|
209
|
+
|
|
276
210
|
derive_label(
|
|
277
|
-
ref_image=ref_image,
|
|
278
211
|
store=label_group,
|
|
279
|
-
|
|
280
|
-
pixelsize=pixelsize,
|
|
281
|
-
z_spacing=z_spacing,
|
|
282
|
-
time_spacing=time_spacing,
|
|
212
|
+
ref_image=ref_image,
|
|
283
213
|
name=name,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
214
|
+
shape=shape,
|
|
215
|
+
pixel_size=pixel_size,
|
|
216
|
+
axes_names=axes_names,
|
|
287
217
|
chunks=chunks,
|
|
288
|
-
shards=shards,
|
|
289
218
|
dtype=dtype,
|
|
290
219
|
dimension_separator=dimension_separator,
|
|
291
220
|
compressors=compressors,
|
|
292
|
-
extra_array_kwargs=extra_array_kwargs,
|
|
293
221
|
overwrite=overwrite,
|
|
294
|
-
labels=labels,
|
|
295
|
-
pixel_size=pixel_size,
|
|
296
222
|
)
|
|
297
223
|
|
|
298
224
|
if name not in existing_labels:
|
|
299
225
|
existing_labels.append(name)
|
|
226
|
+
self._group_handler.write_attrs({"labels": existing_labels})
|
|
300
227
|
|
|
301
|
-
update_meta = NgioLabelsGroupMeta(
|
|
302
|
-
labels=existing_labels, version=self.meta.version
|
|
303
|
-
)
|
|
304
|
-
self._meta_handler.update_meta(update_meta)
|
|
305
228
|
return self.get(name)
|
|
306
229
|
|
|
307
230
|
|
|
308
231
|
def derive_label(
|
|
309
|
-
*,
|
|
310
232
|
store: StoreOrGroup,
|
|
311
233
|
ref_image: Image | Label,
|
|
312
|
-
|
|
234
|
+
name: str,
|
|
313
235
|
shape: Sequence[int] | None = None,
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
name: str | None = None,
|
|
318
|
-
translation: Sequence[float] | None = None,
|
|
319
|
-
channels_policy: Literal["same", "squeeze", "singleton"] | int = "squeeze",
|
|
320
|
-
ngff_version: NgffVersions | None = None,
|
|
321
|
-
# Zarr Array parameters
|
|
322
|
-
chunks: ChunksLike | None = None,
|
|
323
|
-
shards: ShardsLike | None = None,
|
|
324
|
-
dtype: str | None = None,
|
|
236
|
+
pixel_size: PixelSize | None = None,
|
|
237
|
+
axes_names: Sequence[str] | None = None,
|
|
238
|
+
chunks: Sequence[int] | None = None,
|
|
325
239
|
dimension_separator: Literal[".", "/"] | None = None,
|
|
326
240
|
compressors: CompressorLike | None = None,
|
|
327
|
-
|
|
241
|
+
dtype: str = "uint32",
|
|
328
242
|
overwrite: bool = False,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
pixel_size: PixelSize | None = None,
|
|
332
|
-
) -> tuple[ZarrGroupHandler, AxesSetup]:
|
|
333
|
-
"""Derive a new OME-Zarr label from an existing image or label.
|
|
334
|
-
|
|
335
|
-
If a kwarg is not provided, the value from the reference image will be used.
|
|
243
|
+
) -> None:
|
|
244
|
+
"""Create an empty OME-Zarr label from a reference image.
|
|
336
245
|
|
|
337
246
|
Args:
|
|
338
|
-
store (StoreOrGroup): The Zarr store or group to create the
|
|
339
|
-
ref_image (Image | Label):
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
size.
|
|
354
|
-
ngff_version (NgffVersions | None): The NGFF version to use.
|
|
355
|
-
chunks (ChunksLike | None): The chunk shape of the new label.
|
|
356
|
-
shards (ShardsLike | None): The shard shape of the new label.
|
|
357
|
-
dtype (str | None): The data type of the new label.
|
|
358
|
-
dimension_separator (Literal[".", "/"] | None): The separator to use for
|
|
359
|
-
dimensions.
|
|
360
|
-
compressors (CompressorLike | None): The compressors to use.
|
|
361
|
-
extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
|
|
362
|
-
the zarr array creation.
|
|
363
|
-
overwrite (bool): Whether to overwrite an existing label. Defaults to False.
|
|
364
|
-
labels (Sequence[str] | None): Deprecated. This argument is deprecated,
|
|
365
|
-
please use channels_meta instead.
|
|
366
|
-
pixel_size (PixelSize | None): Deprecated. The pixel size of the new label.
|
|
367
|
-
This argument is deprecated, please use pixelsize, z_spacing,
|
|
368
|
-
and time_spacing instead.
|
|
247
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
248
|
+
ref_image (Image | Label): A reference image that will be used to
|
|
249
|
+
create the new image.
|
|
250
|
+
name (str): The name of the new image.
|
|
251
|
+
shape (Sequence[int] | None): The shape of the new image.
|
|
252
|
+
pixel_size (PixelSize | None): The pixel size of the new image.
|
|
253
|
+
axes_names (Sequence[str] | None): The axes names of the new image.
|
|
254
|
+
For labels, the channel axis is not allowed.
|
|
255
|
+
chunks (Sequence[int] | None): The chunk shape of the new image.
|
|
256
|
+
dtype (str): The data type of the new label.
|
|
257
|
+
dimension_separator (DIMENSION_SEPARATOR | None): The separator to use for
|
|
258
|
+
dimensions. If None it will use the same as the reference image.
|
|
259
|
+
compressors (CompressorLike | None): The compressor to use. If None it will use
|
|
260
|
+
the same as the reference image.
|
|
261
|
+
overwrite (bool): Whether to overwrite an existing image.
|
|
369
262
|
|
|
370
263
|
Returns:
|
|
371
|
-
|
|
372
|
-
and the axes setup.
|
|
264
|
+
None
|
|
373
265
|
|
|
374
266
|
"""
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
267
|
+
ref_meta = ref_image.meta
|
|
268
|
+
|
|
269
|
+
if shape is None:
|
|
270
|
+
shape = ref_image.shape
|
|
271
|
+
|
|
272
|
+
if pixel_size is None:
|
|
273
|
+
pixel_size = ref_image.pixel_size
|
|
274
|
+
|
|
275
|
+
if axes_names is None:
|
|
276
|
+
axes_names = ref_meta.axes_handler.axes_names
|
|
277
|
+
c_axis = ref_meta.axes_handler.get_index("c")
|
|
278
|
+
else:
|
|
279
|
+
if "c" in axes_names:
|
|
280
|
+
raise NgioValidationError(
|
|
281
|
+
"Labels cannot have a channel axis. "
|
|
282
|
+
"Please remove the channel axis from the axes names."
|
|
283
|
+
)
|
|
284
|
+
c_axis = None
|
|
285
|
+
|
|
286
|
+
if len(axes_names) != len(shape):
|
|
287
|
+
raise NgioValidationError(
|
|
288
|
+
"The axes names of the new image does not match the reference image."
|
|
289
|
+
f"Got {axes_names} for shape {shape}."
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
if chunks is None:
|
|
293
|
+
chunks = ref_image.chunks
|
|
294
|
+
|
|
295
|
+
if len(chunks) != len(shape):
|
|
296
|
+
raise NgioValidationError(
|
|
297
|
+
"The chunks of the new image does not match the reference image."
|
|
298
|
+
f"Got {chunks} for shape {shape}."
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
if c_axis is not None:
|
|
302
|
+
# remove channel if present
|
|
303
|
+
shape = list(shape)
|
|
304
|
+
shape = shape[:c_axis] + shape[c_axis + 1 :]
|
|
305
|
+
chunks = list(chunks)
|
|
306
|
+
chunks = chunks[:c_axis] + chunks[c_axis + 1 :]
|
|
307
|
+
axes_names = list(axes_names)
|
|
308
|
+
axes_names = axes_names[:c_axis] + axes_names[c_axis + 1 :]
|
|
309
|
+
|
|
310
|
+
if dimension_separator is None:
|
|
311
|
+
dimension_separator = find_dimension_separator(ref_image.zarr_array)
|
|
312
|
+
if compressors is None:
|
|
313
|
+
compressors = ref_image.zarr_array.compressors # type: ignore
|
|
314
|
+
|
|
315
|
+
_ = create_empty_label_container(
|
|
380
316
|
store=store,
|
|
381
317
|
shape=shape,
|
|
382
|
-
pixelsize=
|
|
383
|
-
z_spacing=
|
|
384
|
-
time_spacing=
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
318
|
+
pixelsize=ref_image.pixel_size.x,
|
|
319
|
+
z_spacing=ref_image.pixel_size.z,
|
|
320
|
+
time_spacing=ref_image.pixel_size.t,
|
|
321
|
+
levels=ref_meta.paths,
|
|
322
|
+
yx_scaling_factor=ref_meta.yx_scaling(),
|
|
323
|
+
z_scaling_factor=ref_meta.z_scaling(),
|
|
324
|
+
time_unit=ref_image.pixel_size.time_unit,
|
|
325
|
+
space_unit=ref_image.pixel_size.space_unit,
|
|
326
|
+
axes_names=axes_names,
|
|
390
327
|
chunks=chunks,
|
|
391
|
-
shards=shards,
|
|
392
328
|
dtype=dtype,
|
|
393
329
|
dimension_separator=dimension_separator,
|
|
394
330
|
compressors=compressors,
|
|
395
|
-
extra_array_kwargs=extra_array_kwargs,
|
|
396
331
|
overwrite=overwrite,
|
|
397
|
-
|
|
398
|
-
|
|
332
|
+
ngff_version=ref_meta.version,
|
|
333
|
+
name=name,
|
|
399
334
|
)
|
|
400
|
-
return
|
|
335
|
+
return None
|
|
401
336
|
|
|
402
337
|
|
|
403
|
-
def build_masking_roi_table(
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
Args:
|
|
409
|
-
label: The label to compute the masking ROI table for.
|
|
410
|
-
axes_order: The order of axes for the computation. If None,
|
|
411
|
-
uses the label's default axes order.
|
|
412
|
-
|
|
413
|
-
Returns:
|
|
414
|
-
A MaskingRoiTable containing ROIs for each label in the segmentation.
|
|
415
|
-
"""
|
|
416
|
-
axes_order = axes_order or label.axes
|
|
417
|
-
array = label.get_as_dask(axes_order=axes_order)
|
|
418
|
-
rois = compute_masking_roi(array, label.pixel_size, axes_order=axes_order)
|
|
338
|
+
def build_masking_roi_table(label: Label) -> MaskingRoiTable:
|
|
339
|
+
"""Compute the masking ROI table for a label."""
|
|
340
|
+
array = label.get_as_dask(axes_order=["t", "z", "y", "x"])
|
|
341
|
+
rois = compute_masking_roi(array, label.pixel_size)
|
|
419
342
|
return MaskingRoiTable(rois, reference_label=label.meta.name)
|
ngio/images/_masked_image.py
CHANGED
|
@@ -34,7 +34,7 @@ class MaskedImage(Image):
|
|
|
34
34
|
self,
|
|
35
35
|
group_handler: ZarrGroupHandler,
|
|
36
36
|
path: str,
|
|
37
|
-
meta_handler: ImageMetaHandler,
|
|
37
|
+
meta_handler: ImageMetaHandler | None,
|
|
38
38
|
label: Label,
|
|
39
39
|
masking_roi_table: MaskingRoiTable,
|
|
40
40
|
) -> None:
|
|
@@ -299,7 +299,7 @@ class MaskedLabel(Label):
|
|
|
299
299
|
self,
|
|
300
300
|
group_handler: ZarrGroupHandler,
|
|
301
301
|
path: str,
|
|
302
|
-
meta_handler: LabelMetaHandler,
|
|
302
|
+
meta_handler: LabelMetaHandler | None,
|
|
303
303
|
label: Label,
|
|
304
304
|
masking_roi_table: MaskingRoiTable,
|
|
305
305
|
) -> None:
|