ngio 0.2.0a3__py3-none-any.whl → 0.2.0b2__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 +4 -4
- ngio/common/__init__.py +12 -2
- ngio/common/_array_pipe.py +106 -0
- ngio/common/_axes_transforms.py +3 -2
- ngio/common/_dimensions.py +7 -0
- ngio/common/_masking_roi.py +158 -0
- ngio/common/_pyramid.py +16 -11
- ngio/common/_roi.py +74 -0
- ngio/common/_slicer.py +1 -2
- ngio/common/_zoom.py +5 -3
- ngio/hcs/__init__.py +2 -57
- ngio/hcs/plate.py +399 -0
- ngio/images/abstract_image.py +97 -28
- ngio/images/create.py +48 -29
- ngio/images/image.py +99 -46
- ngio/images/label.py +109 -92
- ngio/images/masked_image.py +259 -0
- ngio/images/omezarr_container.py +201 -64
- ngio/ome_zarr_meta/__init__.py +25 -13
- ngio/ome_zarr_meta/_meta_handlers.py +718 -69
- ngio/ome_zarr_meta/ngio_specs/__init__.py +8 -0
- ngio/ome_zarr_meta/ngio_specs/_channels.py +11 -0
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +374 -2
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +169 -119
- ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +35 -3
- ngio/ome_zarr_meta/v04/__init__.py +17 -5
- ngio/ome_zarr_meta/v04/_v04_spec_utils.py +85 -12
- ngio/tables/__init__.py +2 -0
- ngio/tables/_validators.py +2 -4
- ngio/tables/backends/_anndata_utils.py +5 -1
- ngio/tables/backends/_anndata_v1.py +2 -1
- ngio/tables/backends/_json_v1.py +1 -1
- ngio/tables/tables_container.py +12 -2
- ngio/tables/v1/__init__.py +1 -2
- ngio/tables/v1/_feature_table.py +7 -5
- ngio/tables/v1/_generic_table.py +65 -11
- ngio/tables/v1/_roi_table.py +145 -27
- ngio/utils/_datasets.py +4 -2
- ngio/utils/_fractal_fsspec_store.py +3 -2
- ngio/utils/_logger.py +3 -1
- ngio/utils/_zarr_utils.py +25 -2
- {ngio-0.2.0a3.dist-info → ngio-0.2.0b2.dist-info}/METADATA +6 -2
- ngio-0.2.0b2.dist-info/RECORD +54 -0
- ngio/ome_zarr_meta/_generic_handlers.py +0 -320
- ngio/ome_zarr_meta/v04/_meta_handlers.py +0 -54
- ngio/tables/v1/_masking_roi_table.py +0 -175
- ngio-0.2.0a3.dist-info/RECORD +0 -54
- {ngio-0.2.0a3.dist-info → ngio-0.2.0b2.dist-info}/WHEEL +0 -0
- {ngio-0.2.0a3.dist-info → ngio-0.2.0b2.dist-info}/licenses/LICENSE +0 -0
ngio/images/label.py
CHANGED
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
from collections.abc import Collection
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
|
+
from ngio.common import compute_masking_roi
|
|
6
7
|
from ngio.images.abstract_image import AbstractImage, consolidate_image
|
|
7
8
|
from ngio.images.create import _create_empty_label
|
|
8
9
|
from ngio.images.image import Image
|
|
9
10
|
from ngio.ome_zarr_meta import (
|
|
10
|
-
ImplementedLabelMetaHandlers,
|
|
11
11
|
LabelMetaHandler,
|
|
12
12
|
NgioLabelMeta,
|
|
13
13
|
PixelSize,
|
|
14
|
+
find_label_meta_handler,
|
|
14
15
|
)
|
|
15
|
-
from ngio.
|
|
16
|
+
from ngio.tables import MaskingROITable
|
|
16
17
|
from ngio.utils import (
|
|
17
18
|
NgioValidationError,
|
|
18
19
|
NgioValueError,
|
|
@@ -39,9 +40,7 @@ class Label(AbstractImage[LabelMetaHandler]):
|
|
|
39
40
|
|
|
40
41
|
"""
|
|
41
42
|
if meta_handler is None:
|
|
42
|
-
meta_handler =
|
|
43
|
-
group_handler
|
|
44
|
-
)
|
|
43
|
+
meta_handler = find_label_meta_handler(group_handler)
|
|
45
44
|
super().__init__(
|
|
46
45
|
group_handler=group_handler, path=path, meta_handler=meta_handler
|
|
47
46
|
)
|
|
@@ -51,6 +50,10 @@ class Label(AbstractImage[LabelMetaHandler]):
|
|
|
51
50
|
"""Return the metadata."""
|
|
52
51
|
return self._meta_handler.meta
|
|
53
52
|
|
|
53
|
+
def build_masking_roi_table(self) -> MaskingROITable:
|
|
54
|
+
"""Compute the masking ROI table."""
|
|
55
|
+
return build_masking_roi_table(self)
|
|
56
|
+
|
|
54
57
|
def consolidate(
|
|
55
58
|
self,
|
|
56
59
|
mode: Literal["dask", "numpy", "coarsen"] = "dask",
|
|
@@ -87,11 +90,6 @@ class LabelsContainer:
|
|
|
87
90
|
attrs = self._group_handler.load_attrs()
|
|
88
91
|
return attrs.get("labels", [])
|
|
89
92
|
|
|
90
|
-
def _get(self, name: str, path: str) -> Label:
|
|
91
|
-
"""Get a label from the group."""
|
|
92
|
-
group_handler = self._group_handler.derive_handler(name)
|
|
93
|
-
return Label(group_handler, path, None)
|
|
94
|
-
|
|
95
93
|
def get(
|
|
96
94
|
self,
|
|
97
95
|
name: str,
|
|
@@ -111,9 +109,7 @@ class LabelsContainer:
|
|
|
111
109
|
|
|
112
110
|
"""
|
|
113
111
|
group_handler = self._group_handler.derive_handler(name)
|
|
114
|
-
label_meta_handler =
|
|
115
|
-
group_handler
|
|
116
|
-
)
|
|
112
|
+
label_meta_handler = find_label_meta_handler(group_handler)
|
|
117
113
|
path = label_meta_handler.meta.get_dataset(
|
|
118
114
|
path=path, pixel_size=pixel_size, strict=strict
|
|
119
115
|
).path
|
|
@@ -124,56 +120,32 @@ class LabelsContainer:
|
|
|
124
120
|
name: str,
|
|
125
121
|
ref_image: Image,
|
|
126
122
|
shape: Collection[int] | None = None,
|
|
123
|
+
pixel_size: PixelSize | None = None,
|
|
124
|
+
axes_names: Collection[str] | None = None,
|
|
127
125
|
chunks: Collection[int] | None = None,
|
|
128
|
-
dtype: str =
|
|
129
|
-
xy_scaling_factor=2.0,
|
|
130
|
-
z_scaling_factor=1.0,
|
|
126
|
+
dtype: str | None = None,
|
|
131
127
|
overwrite: bool = False,
|
|
132
|
-
) ->
|
|
133
|
-
"""
|
|
134
|
-
existing_labels = self.list()
|
|
135
|
-
if name in existing_labels and not overwrite:
|
|
136
|
-
raise NgioValueError(
|
|
137
|
-
f"Table '{name}' already exists in the group. "
|
|
138
|
-
"Use overwrite=True to replace it."
|
|
139
|
-
)
|
|
128
|
+
) -> "Label":
|
|
129
|
+
"""Create an empty OME-Zarr label from a reference image.
|
|
140
130
|
|
|
141
|
-
|
|
131
|
+
And add the label to the /labels group.
|
|
142
132
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
133
|
+
Args:
|
|
134
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
135
|
+
ref_image (Image): The reference image.
|
|
136
|
+
name (str): The name of the new image.
|
|
137
|
+
shape (Collection[int] | None): The shape of the new image.
|
|
138
|
+
pixel_size (PixelSize | None): The pixel size of the new image.
|
|
139
|
+
axes_names (Collection[str] | None): The axes names of the new image.
|
|
140
|
+
For labels, the channel axis is not allowed.
|
|
141
|
+
chunks (Collection[int] | None): The chunk shape of the new image.
|
|
142
|
+
dtype (str | None): The data type of the new image.
|
|
143
|
+
overwrite (bool): Whether to overwrite an existing image.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
Label: The new label.
|
|
157
147
|
|
|
158
|
-
|
|
159
|
-
self,
|
|
160
|
-
name: str,
|
|
161
|
-
shape: Collection[int],
|
|
162
|
-
xy_pixelsize: float,
|
|
163
|
-
z_spacing: float = 1.0,
|
|
164
|
-
time_spacing: float = 1.0,
|
|
165
|
-
levels: "int | list[str]" = 5,
|
|
166
|
-
xy_scaling_factor: float = 2.0,
|
|
167
|
-
z_scaling_factor: float = 1.0,
|
|
168
|
-
space_unit: SpaceUnits | str | None = None,
|
|
169
|
-
time_unit: TimeUnits | str | None = None,
|
|
170
|
-
axes_names: Collection[str] | None = None,
|
|
171
|
-
chunks: Collection[int] | None = None,
|
|
172
|
-
dtype: str = "uint16",
|
|
173
|
-
overwrite: bool = False,
|
|
174
|
-
version: str = "0.4",
|
|
175
|
-
) -> None:
|
|
176
|
-
"""Add a label to the group."""
|
|
148
|
+
"""
|
|
177
149
|
existing_labels = self.list()
|
|
178
150
|
if name in existing_labels and not overwrite:
|
|
179
151
|
raise NgioValueError(
|
|
@@ -183,82 +155,127 @@ class LabelsContainer:
|
|
|
183
155
|
|
|
184
156
|
label_group = self._group_handler.get_group(name, create_mode=True)
|
|
185
157
|
|
|
186
|
-
|
|
158
|
+
_derive_label(
|
|
187
159
|
store=label_group,
|
|
160
|
+
ref_image=ref_image,
|
|
161
|
+
name=name,
|
|
188
162
|
shape=shape,
|
|
189
|
-
|
|
190
|
-
z_spacing=z_spacing,
|
|
191
|
-
time_spacing=time_spacing,
|
|
192
|
-
levels=levels,
|
|
193
|
-
xy_scaling_factor=xy_scaling_factor,
|
|
194
|
-
z_scaling_factor=z_scaling_factor,
|
|
195
|
-
space_unit=space_unit,
|
|
196
|
-
time_unit=time_unit,
|
|
163
|
+
pixel_size=pixel_size,
|
|
197
164
|
axes_names=axes_names,
|
|
198
165
|
chunks=chunks,
|
|
199
166
|
dtype=dtype,
|
|
200
167
|
overwrite=overwrite,
|
|
201
|
-
version=version,
|
|
202
168
|
)
|
|
203
169
|
|
|
204
170
|
if name not in existing_labels:
|
|
205
171
|
existing_labels.append(name)
|
|
206
172
|
self._group_handler.write_attrs({"labels": existing_labels})
|
|
207
173
|
|
|
174
|
+
return self.get(name)
|
|
175
|
+
|
|
208
176
|
|
|
209
177
|
def _derive_label(
|
|
210
|
-
ref_image: Image,
|
|
211
178
|
store: StoreOrGroup,
|
|
179
|
+
ref_image: Image,
|
|
180
|
+
name: str,
|
|
212
181
|
shape: Collection[int] | None = None,
|
|
182
|
+
pixel_size: PixelSize | None = None,
|
|
183
|
+
axes_names: Collection[str] | None = None,
|
|
213
184
|
chunks: Collection[int] | None = None,
|
|
214
|
-
dtype: str =
|
|
215
|
-
xy_scaling_factor=2.0,
|
|
216
|
-
z_scaling_factor=1.0,
|
|
185
|
+
dtype: str | None = None,
|
|
217
186
|
overwrite: bool = False,
|
|
218
187
|
) -> None:
|
|
219
|
-
"""Create an OME-Zarr
|
|
188
|
+
"""Create an empty OME-Zarr label from a reference image.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
192
|
+
ref_image (Image): The reference image.
|
|
193
|
+
name (str): The name of the new image.
|
|
194
|
+
shape (Collection[int] | None): The shape of the new image.
|
|
195
|
+
pixel_size (PixelSize | None): The pixel size of the new image.
|
|
196
|
+
axes_names (Collection[str] | None): The axes names of the new image.
|
|
197
|
+
For labels, the channel axis is not allowed.
|
|
198
|
+
chunks (Collection[int] | None): The chunk shape of the new image.
|
|
199
|
+
dtype (str | None): The data type of the new image.
|
|
200
|
+
overwrite (bool): Whether to overwrite an existing image.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
None
|
|
204
|
+
|
|
205
|
+
"""
|
|
220
206
|
ref_meta = ref_image.meta
|
|
221
|
-
# remove channls if present
|
|
222
|
-
shape_ref = ref_image.shape
|
|
223
|
-
chunks_ref = ref_image.chunks
|
|
224
|
-
axes_names_ref = ref_image.dataset.axes_mapper.on_disk_axes_names
|
|
225
|
-
c_axis = ref_image.dataset.axes_mapper.get_index("c")
|
|
226
|
-
if c_axis is not None:
|
|
227
|
-
shape_ref = shape_ref[:c_axis] + shape_ref[c_axis + 1 :]
|
|
228
|
-
chunks_ref = chunks_ref[:c_axis] + chunks_ref[c_axis + 1 :]
|
|
229
|
-
axes_names_ref = axes_names_ref[:c_axis] + axes_names_ref[c_axis + 1 :]
|
|
230
207
|
|
|
231
208
|
if shape is None:
|
|
232
|
-
shape =
|
|
209
|
+
shape = ref_image.shape
|
|
233
210
|
|
|
234
|
-
if
|
|
235
|
-
|
|
211
|
+
if pixel_size is None:
|
|
212
|
+
pixel_size = ref_image.pixel_size
|
|
213
|
+
|
|
214
|
+
if axes_names is None:
|
|
215
|
+
axes_names = ref_meta.axes_mapper.on_disk_axes_names
|
|
216
|
+
c_axis = ref_meta.axes_mapper.get_index("c")
|
|
217
|
+
else:
|
|
218
|
+
if "c" in axes_names:
|
|
219
|
+
raise NgioValidationError(
|
|
220
|
+
"Labels cannot have a channel axis. "
|
|
221
|
+
"Please remove the channel axis from the axes names."
|
|
222
|
+
)
|
|
223
|
+
c_axis = None
|
|
236
224
|
|
|
237
|
-
if len(
|
|
225
|
+
if len(axes_names) != len(shape):
|
|
238
226
|
raise NgioValidationError(
|
|
239
|
-
"The
|
|
227
|
+
"The axes names of the new image does not match the reference image."
|
|
228
|
+
f"Got {axes_names} for shape {shape}."
|
|
240
229
|
)
|
|
241
230
|
|
|
242
|
-
if
|
|
231
|
+
if chunks is None:
|
|
232
|
+
chunks = ref_image.chunks
|
|
233
|
+
|
|
234
|
+
if len(chunks) != len(shape):
|
|
243
235
|
raise NgioValidationError(
|
|
244
236
|
"The chunks of the new image does not match the reference image."
|
|
237
|
+
f"Got {chunks} for shape {shape}."
|
|
245
238
|
)
|
|
246
239
|
|
|
240
|
+
if dtype is None:
|
|
241
|
+
dtype = ref_image.dtype
|
|
242
|
+
|
|
243
|
+
if c_axis is not None:
|
|
244
|
+
# remove channel if present
|
|
245
|
+
shape = list(shape)
|
|
246
|
+
shape = shape[:c_axis] + shape[c_axis + 1 :]
|
|
247
|
+
chunks = list(chunks)
|
|
248
|
+
chunks = chunks[:c_axis] + chunks[c_axis + 1 :]
|
|
249
|
+
axes_names = list(axes_names)
|
|
250
|
+
axes_names = axes_names[:c_axis] + axes_names[c_axis + 1 :]
|
|
251
|
+
|
|
247
252
|
_ = _create_empty_label(
|
|
248
253
|
store=store,
|
|
249
254
|
shape=shape,
|
|
250
|
-
|
|
255
|
+
pixelsize=ref_image.pixel_size.x,
|
|
251
256
|
z_spacing=ref_image.pixel_size.z,
|
|
252
257
|
time_spacing=ref_image.pixel_size.t,
|
|
253
258
|
levels=ref_meta.levels,
|
|
254
|
-
|
|
255
|
-
z_scaling_factor=
|
|
259
|
+
yx_scaling_factor=ref_meta.yx_scaling(),
|
|
260
|
+
z_scaling_factor=ref_meta.z_scaling(),
|
|
256
261
|
time_unit=ref_image.pixel_size.time_unit,
|
|
257
262
|
space_unit=ref_image.pixel_size.space_unit,
|
|
258
|
-
axes_names=
|
|
263
|
+
axes_names=axes_names,
|
|
259
264
|
chunks=chunks,
|
|
260
265
|
dtype=dtype,
|
|
261
266
|
overwrite=overwrite,
|
|
262
267
|
version=ref_meta.version,
|
|
268
|
+
name=name,
|
|
263
269
|
)
|
|
264
270
|
return None
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def build_masking_roi_table(label: Label) -> MaskingROITable:
|
|
274
|
+
"""Compute the masking ROI table for a label."""
|
|
275
|
+
if label.dimensions.is_time_series:
|
|
276
|
+
raise NgioValueError("Time series labels are not supported.")
|
|
277
|
+
|
|
278
|
+
array = label.get_array(axes_order=["z", "y", "x"], mode="dask")
|
|
279
|
+
|
|
280
|
+
rois = compute_masking_roi(array, label.pixel_size)
|
|
281
|
+
return MaskingROITable(rois, reference_label=label.meta.name)
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"""A module for handling label images in OME-NGFF files."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Collection, Iterable
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
from ngio.common import ArrayLike, get_masked_pipe, roi_to_slice_kwargs, set_masked_pipe
|
|
7
|
+
from ngio.images.image import Image
|
|
8
|
+
from ngio.images.label import Label
|
|
9
|
+
from ngio.ome_zarr_meta import ImageMetaHandler, LabelMetaHandler
|
|
10
|
+
from ngio.tables import MaskingROITable
|
|
11
|
+
from ngio.utils import (
|
|
12
|
+
ZarrGroupHandler,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MaskedImage(Image):
|
|
17
|
+
"""Placeholder class for a label."""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
group_handler: ZarrGroupHandler,
|
|
22
|
+
path: str,
|
|
23
|
+
meta_handler: ImageMetaHandler | None,
|
|
24
|
+
label: Label,
|
|
25
|
+
masking_roi_table: MaskingROITable,
|
|
26
|
+
) -> None:
|
|
27
|
+
"""Initialize the Image at a single level.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
group_handler: The Zarr group handler.
|
|
31
|
+
path: The path to the image in the omezarr file.
|
|
32
|
+
meta_handler: The image metadata handler.
|
|
33
|
+
label: The label image.
|
|
34
|
+
masking_roi_table: The masking ROI table.
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
super().__init__(
|
|
38
|
+
group_handler=group_handler, path=path, meta_handler=meta_handler
|
|
39
|
+
)
|
|
40
|
+
self._label = label
|
|
41
|
+
self._masking_roi_table = masking_roi_table
|
|
42
|
+
|
|
43
|
+
def get_roi(
|
|
44
|
+
self,
|
|
45
|
+
label: int,
|
|
46
|
+
zoom_factor: float = 1.0,
|
|
47
|
+
axes_order: Collection[str] | None = None,
|
|
48
|
+
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
49
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
50
|
+
) -> ArrayLike:
|
|
51
|
+
"""Return the array for a given ROI."""
|
|
52
|
+
roi = self._masking_roi_table.get(label)
|
|
53
|
+
roi = roi.zoom(zoom_factor)
|
|
54
|
+
return super().get_roi(
|
|
55
|
+
roi=roi, axes_order=axes_order, mode=mode, **slice_kwargs
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def set_roi(
|
|
59
|
+
self,
|
|
60
|
+
label: int,
|
|
61
|
+
patch: ArrayLike,
|
|
62
|
+
zoom_factor: float = 1.0,
|
|
63
|
+
axes_order: Collection[str] | None = None,
|
|
64
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
65
|
+
) -> None:
|
|
66
|
+
"""Set the array for a given ROI."""
|
|
67
|
+
roi = self._masking_roi_table.get(label)
|
|
68
|
+
roi = roi.zoom(zoom_factor)
|
|
69
|
+
return super().set_roi(
|
|
70
|
+
roi=roi, patch=patch, axes_order=axes_order, **slice_kwargs
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def get_roi_masked(
|
|
74
|
+
self,
|
|
75
|
+
label: int,
|
|
76
|
+
axes_order: Collection[str] | None = None,
|
|
77
|
+
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
78
|
+
zoom_factor: float = 1.0,
|
|
79
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
80
|
+
) -> ArrayLike:
|
|
81
|
+
"""Return the masked array for a given label."""
|
|
82
|
+
return get_masked_roi_pipe(
|
|
83
|
+
image=self,
|
|
84
|
+
label=label,
|
|
85
|
+
axes_order=axes_order,
|
|
86
|
+
mode=mode,
|
|
87
|
+
zoom_factor=zoom_factor,
|
|
88
|
+
**slice_kwargs,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def set_roi_masked(
|
|
92
|
+
self,
|
|
93
|
+
label: int,
|
|
94
|
+
patch: ArrayLike,
|
|
95
|
+
axes_order: Collection[str] | None = None,
|
|
96
|
+
zoom_factor: float = 1.0,
|
|
97
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
98
|
+
) -> None:
|
|
99
|
+
"""Set the masked array for a given label."""
|
|
100
|
+
return set_masked_roi_pipe(
|
|
101
|
+
image=self,
|
|
102
|
+
label=label,
|
|
103
|
+
patch=patch,
|
|
104
|
+
axes_order=axes_order,
|
|
105
|
+
zoom_factor=zoom_factor,
|
|
106
|
+
**slice_kwargs,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class MaskedLabel(Label):
|
|
111
|
+
"""Placeholder class for a label."""
|
|
112
|
+
|
|
113
|
+
def __init__(
|
|
114
|
+
self,
|
|
115
|
+
group_handler: ZarrGroupHandler,
|
|
116
|
+
path: str,
|
|
117
|
+
meta_handler: LabelMetaHandler | None,
|
|
118
|
+
label: Label,
|
|
119
|
+
masking_roi_table: MaskingROITable,
|
|
120
|
+
) -> None:
|
|
121
|
+
"""Initialize the Image at a single level.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
group_handler: The Zarr group handler.
|
|
125
|
+
path: The path to the image in the omezarr file.
|
|
126
|
+
meta_handler: The image metadata handler.
|
|
127
|
+
label: The label image.
|
|
128
|
+
masking_roi_table: The masking ROI table.
|
|
129
|
+
|
|
130
|
+
"""
|
|
131
|
+
super().__init__(
|
|
132
|
+
group_handler=group_handler, path=path, meta_handler=meta_handler
|
|
133
|
+
)
|
|
134
|
+
self._label = label
|
|
135
|
+
self._masking_roi_table = masking_roi_table
|
|
136
|
+
|
|
137
|
+
def get_roi(
|
|
138
|
+
self,
|
|
139
|
+
label: int,
|
|
140
|
+
zoom_factor: float = 1.0,
|
|
141
|
+
axes_order: Collection[str] | None = None,
|
|
142
|
+
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
143
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
144
|
+
) -> ArrayLike:
|
|
145
|
+
"""Return the array for a given ROI."""
|
|
146
|
+
roi = self._masking_roi_table.get(label)
|
|
147
|
+
roi = roi.zoom(zoom_factor)
|
|
148
|
+
return super().get_roi(
|
|
149
|
+
roi=roi, axes_order=axes_order, mode=mode, **slice_kwargs
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def set_roi(
|
|
153
|
+
self,
|
|
154
|
+
label: int,
|
|
155
|
+
patch: ArrayLike,
|
|
156
|
+
zoom_factor: float = 1.0,
|
|
157
|
+
axes_order: Collection[str] | None = None,
|
|
158
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
159
|
+
) -> None:
|
|
160
|
+
"""Set the array for a given ROI."""
|
|
161
|
+
roi = self._masking_roi_table.get(label)
|
|
162
|
+
roi = roi.zoom(zoom_factor)
|
|
163
|
+
return super().set_roi(
|
|
164
|
+
roi=roi, patch=patch, axes_order=axes_order, **slice_kwargs
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def get_roi_masked(
|
|
168
|
+
self,
|
|
169
|
+
label: int,
|
|
170
|
+
axes_order: Collection[str] | None = None,
|
|
171
|
+
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
172
|
+
zoom_factor: float = 1.0,
|
|
173
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
174
|
+
) -> ArrayLike:
|
|
175
|
+
"""Return the masked array for a given label."""
|
|
176
|
+
return get_masked_roi_pipe(
|
|
177
|
+
image=self,
|
|
178
|
+
label=label,
|
|
179
|
+
axes_order=axes_order,
|
|
180
|
+
mode=mode,
|
|
181
|
+
zoom_factor=zoom_factor,
|
|
182
|
+
**slice_kwargs,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def set_roi_masked(
|
|
186
|
+
self,
|
|
187
|
+
label: int,
|
|
188
|
+
patch: ArrayLike,
|
|
189
|
+
axes_order: Collection[str] | None = None,
|
|
190
|
+
zoom_factor: float = 1.0,
|
|
191
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
192
|
+
) -> None:
|
|
193
|
+
"""Set the masked array for a given label."""
|
|
194
|
+
return set_masked_roi_pipe(
|
|
195
|
+
image=self,
|
|
196
|
+
label=label,
|
|
197
|
+
patch=patch,
|
|
198
|
+
axes_order=axes_order,
|
|
199
|
+
zoom_factor=zoom_factor,
|
|
200
|
+
**slice_kwargs,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def get_masked_roi_pipe(
|
|
205
|
+
image: MaskedImage | MaskedLabel,
|
|
206
|
+
label: int,
|
|
207
|
+
axes_order: Collection[str] | None = None,
|
|
208
|
+
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
209
|
+
zoom_factor: float = 1.0,
|
|
210
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
211
|
+
) -> ArrayLike:
|
|
212
|
+
"""Return the masked array for a given label."""
|
|
213
|
+
roi = image._masking_roi_table.get(label)
|
|
214
|
+
roi = roi.zoom(zoom_factor)
|
|
215
|
+
slice_kwargs = roi_to_slice_kwargs(
|
|
216
|
+
roi=roi,
|
|
217
|
+
pixel_size=image.pixel_size,
|
|
218
|
+
dimensions=image.dimensions,
|
|
219
|
+
**slice_kwargs,
|
|
220
|
+
)
|
|
221
|
+
return get_masked_pipe(
|
|
222
|
+
array=image.zarr_array,
|
|
223
|
+
label_array=image._label.zarr_array,
|
|
224
|
+
label=label,
|
|
225
|
+
dimensions_array=image.dimensions,
|
|
226
|
+
dimensions_label=image._label.dimensions,
|
|
227
|
+
axes_order=axes_order,
|
|
228
|
+
mode=mode,
|
|
229
|
+
**slice_kwargs,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def set_masked_roi_pipe(
|
|
234
|
+
image: MaskedImage | MaskedLabel,
|
|
235
|
+
label: int,
|
|
236
|
+
patch: ArrayLike,
|
|
237
|
+
axes_order: Collection[str] | None = None,
|
|
238
|
+
zoom_factor: float = 1.0,
|
|
239
|
+
**slice_kwargs: slice | int | Iterable[int],
|
|
240
|
+
) -> None:
|
|
241
|
+
"""Set the masked array for a given label."""
|
|
242
|
+
roi = image._masking_roi_table.get(label)
|
|
243
|
+
roi = roi.zoom(zoom_factor)
|
|
244
|
+
slice_kwargs = roi_to_slice_kwargs(
|
|
245
|
+
roi=roi,
|
|
246
|
+
pixel_size=image.pixel_size,
|
|
247
|
+
dimensions=image.dimensions,
|
|
248
|
+
**slice_kwargs,
|
|
249
|
+
)
|
|
250
|
+
return set_masked_pipe(
|
|
251
|
+
array=image.zarr_array,
|
|
252
|
+
label_array=image._label.zarr_array,
|
|
253
|
+
label=label,
|
|
254
|
+
patch=patch,
|
|
255
|
+
dimensions_array=image.dimensions,
|
|
256
|
+
dimensions_label=image._label.dimensions,
|
|
257
|
+
axes_order=axes_order,
|
|
258
|
+
**slice_kwargs,
|
|
259
|
+
)
|