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
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
"""Base class for handling OME-NGFF metadata in Zarr groups."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
|
|
3
|
+
from typing import Generic, Protocol, TypeVar
|
|
4
|
+
|
|
5
|
+
from pydantic import ValidationError
|
|
5
6
|
|
|
6
7
|
from ngio.ome_zarr_meta.ngio_specs import (
|
|
7
8
|
AxesSetup,
|
|
8
9
|
NgioImageMeta,
|
|
9
10
|
NgioLabelMeta,
|
|
10
|
-
NgioLabelsGroupMeta,
|
|
11
11
|
NgioPlateMeta,
|
|
12
12
|
NgioWellMeta,
|
|
13
13
|
)
|
|
14
|
-
from ngio.ome_zarr_meta.ngio_specs._ngio_image import NgffVersions
|
|
15
14
|
from ngio.ome_zarr_meta.v04 import (
|
|
16
15
|
ngio_to_v04_image_meta,
|
|
17
16
|
ngio_to_v04_label_meta,
|
|
18
|
-
ngio_to_v04_labels_group_meta,
|
|
19
17
|
ngio_to_v04_plate_meta,
|
|
20
18
|
ngio_to_v04_well_meta,
|
|
21
19
|
v04_to_ngio_image_meta,
|
|
22
20
|
v04_to_ngio_label_meta,
|
|
23
|
-
v04_to_ngio_labels_group_meta,
|
|
24
21
|
v04_to_ngio_plate_meta,
|
|
25
22
|
v04_to_ngio_well_meta,
|
|
26
23
|
)
|
|
27
24
|
from ngio.ome_zarr_meta.v05 import (
|
|
28
25
|
ngio_to_v05_image_meta,
|
|
29
26
|
ngio_to_v05_label_meta,
|
|
30
|
-
ngio_to_v05_labels_group_meta,
|
|
31
27
|
ngio_to_v05_plate_meta,
|
|
32
28
|
ngio_to_v05_well_meta,
|
|
33
29
|
v05_to_ngio_image_meta,
|
|
34
30
|
v05_to_ngio_label_meta,
|
|
35
|
-
v05_to_ngio_labels_group_meta,
|
|
36
31
|
v05_to_ngio_plate_meta,
|
|
37
32
|
v05_to_ngio_well_meta,
|
|
38
33
|
)
|
|
@@ -42,471 +37,792 @@ from ngio.utils import (
|
|
|
42
37
|
ZarrGroupHandler,
|
|
43
38
|
)
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
_image_encoder_registry = {"0.4": ngio_to_v04_image_meta, "0.5": ngio_to_v05_image_meta}
|
|
47
|
-
_image_decoder_registry = {"0.4": v04_to_ngio_image_meta, "0.5": v05_to_ngio_image_meta}
|
|
48
|
-
_label_encoder_registry = {"0.4": ngio_to_v04_label_meta, "0.5": ngio_to_v05_label_meta}
|
|
49
|
-
_label_decoder_registry = {"0.4": v04_to_ngio_label_meta, "0.5": v05_to_ngio_label_meta}
|
|
50
|
-
_plate_encoder_registry = {"0.4": ngio_to_v04_plate_meta, "0.5": ngio_to_v05_plate_meta}
|
|
51
|
-
_plate_decoder_registry = {"0.4": v04_to_ngio_plate_meta, "0.5": v05_to_ngio_plate_meta}
|
|
52
|
-
_well_encoder_registry = {"0.4": ngio_to_v04_well_meta, "0.5": ngio_to_v05_well_meta}
|
|
53
|
-
_well_decoder_registry = {"0.4": v04_to_ngio_well_meta, "0.5": v05_to_ngio_well_meta}
|
|
54
|
-
_labels_group_encoder_registry = {
|
|
55
|
-
"0.4": ngio_to_v04_labels_group_meta,
|
|
56
|
-
"0.5": ngio_to_v05_labels_group_meta,
|
|
57
|
-
}
|
|
58
|
-
_labels_group_decoder_registry = {
|
|
59
|
-
"0.4": v04_to_ngio_labels_group_meta,
|
|
60
|
-
"0.5": v05_to_ngio_labels_group_meta,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
_meta_type = TypeVar(
|
|
64
|
-
"_meta_type",
|
|
65
|
-
NgioImageMeta,
|
|
66
|
-
NgioLabelMeta,
|
|
67
|
-
NgioLabelsGroupMeta,
|
|
68
|
-
NgioPlateMeta,
|
|
69
|
-
NgioWellMeta,
|
|
70
|
-
)
|
|
40
|
+
ConverterError = ValidationError | Exception | None
|
|
71
41
|
|
|
42
|
+
###########################################################################
|
|
43
|
+
#
|
|
44
|
+
# The code below implements a generic class for handling OME-Zarr metadata
|
|
45
|
+
# in Zarr groups.
|
|
46
|
+
#
|
|
47
|
+
###########################################################################
|
|
72
48
|
|
|
73
|
-
def _find_encoder_registry(
|
|
74
|
-
ngio_meta: _meta_type,
|
|
75
|
-
) -> dict[str, Callable]:
|
|
76
|
-
if isinstance(ngio_meta, NgioImageMeta):
|
|
77
|
-
return _image_encoder_registry
|
|
78
|
-
elif isinstance(ngio_meta, NgioLabelMeta):
|
|
79
|
-
return _label_encoder_registry
|
|
80
|
-
elif isinstance(ngio_meta, NgioPlateMeta):
|
|
81
|
-
return _plate_encoder_registry
|
|
82
|
-
elif isinstance(ngio_meta, NgioWellMeta):
|
|
83
|
-
return _well_encoder_registry
|
|
84
|
-
elif isinstance(ngio_meta, NgioLabelsGroupMeta):
|
|
85
|
-
return _labels_group_encoder_registry
|
|
86
|
-
else:
|
|
87
|
-
raise NgioValueError(f"Unsupported NGIO metadata type: {type(ngio_meta)}")
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def update_ngio_meta(
|
|
91
|
-
group_handler: ZarrGroupHandler,
|
|
92
|
-
ngio_meta: _meta_type,
|
|
93
|
-
) -> None:
|
|
94
|
-
"""Update the metadata in the Zarr group.
|
|
95
|
-
|
|
96
|
-
Args:
|
|
97
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
98
|
-
ngio_meta (_meta_type): The new NGIO metadata.
|
|
99
|
-
|
|
100
|
-
"""
|
|
101
|
-
registry = _find_encoder_registry(ngio_meta)
|
|
102
|
-
exporter = registry.get(ngio_meta.version)
|
|
103
|
-
if exporter is None:
|
|
104
|
-
raise NgioValueError(f"Unsupported NGFF version: {ngio_meta.version}")
|
|
105
|
-
|
|
106
|
-
zarr_meta = exporter(ngio_meta)
|
|
107
|
-
group_handler.write_attrs(zarr_meta)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def _find_decoder_registry(
|
|
111
|
-
meta_type: type[_meta_type],
|
|
112
|
-
) -> dict[str, Callable]:
|
|
113
|
-
if meta_type is NgioImageMeta:
|
|
114
|
-
return _image_decoder_registry
|
|
115
|
-
elif meta_type is NgioLabelMeta:
|
|
116
|
-
return _label_decoder_registry
|
|
117
|
-
elif meta_type is NgioPlateMeta:
|
|
118
|
-
return _plate_decoder_registry
|
|
119
|
-
elif meta_type is NgioWellMeta:
|
|
120
|
-
return _well_decoder_registry
|
|
121
|
-
elif meta_type is NgioLabelsGroupMeta:
|
|
122
|
-
return _labels_group_decoder_registry
|
|
123
|
-
else:
|
|
124
|
-
raise NgioValueError(f"Unsupported NGIO metadata type: {meta_type}")
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def get_ngio_meta(
|
|
128
|
-
group_handler: ZarrGroupHandler,
|
|
129
|
-
meta_type: type[_meta_type],
|
|
130
|
-
version: str | None = None,
|
|
131
|
-
**kwargs,
|
|
132
|
-
) -> _meta_type:
|
|
133
|
-
"""Retrieve the NGIO metadata from the Zarr group.
|
|
134
|
-
|
|
135
|
-
Args:
|
|
136
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
137
|
-
meta_type (type[_meta_type]): The type of NGIO metadata to retrieve.
|
|
138
|
-
version (str | None): Optional NGFF version to use for decoding.
|
|
139
|
-
**kwargs: Additional arguments to pass to the decoder.
|
|
140
|
-
|
|
141
|
-
Returns:
|
|
142
|
-
_meta_type: The NGIO metadata.
|
|
143
|
-
"""
|
|
144
|
-
registry = _find_decoder_registry(meta_type)
|
|
145
|
-
if version is not None:
|
|
146
|
-
decoder = registry.get(version)
|
|
147
|
-
if decoder is None:
|
|
148
|
-
raise NgioValueError(f"Unsupported NGFF version: {version}")
|
|
149
|
-
versions_to_try = {version: decoder}
|
|
150
|
-
else:
|
|
151
|
-
versions_to_try = registry
|
|
152
|
-
|
|
153
|
-
attrs = group_handler.load_attrs()
|
|
154
|
-
all_errors = []
|
|
155
|
-
for version, decoder in versions_to_try.items():
|
|
156
|
-
try:
|
|
157
|
-
ngio_meta = decoder(attrs, **kwargs)
|
|
158
|
-
return ngio_meta
|
|
159
|
-
except Exception as e:
|
|
160
|
-
all_errors.append(f"Version {version}: {e}")
|
|
161
|
-
error_message = (
|
|
162
|
-
f"Failed to decode NGIO {meta_type.__name__} metadata:\n"
|
|
163
|
-
+ "\n".join(all_errors)
|
|
164
|
-
)
|
|
165
|
-
raise NgioValidationError(error_message)
|
|
166
49
|
|
|
50
|
+
class ImageMetaImporter(Protocol):
|
|
51
|
+
@staticmethod
|
|
52
|
+
def __call__(
|
|
53
|
+
metadata: dict,
|
|
54
|
+
axes_setup: AxesSetup | None = None,
|
|
55
|
+
allow_non_canonical_axes: bool = False,
|
|
56
|
+
strict_canonical_order: bool = True,
|
|
57
|
+
) -> tuple[bool, NgioImageMeta | ConverterError]:
|
|
58
|
+
"""Convert the metadata to a NgioImageMeta object.
|
|
167
59
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
60
|
+
Args:
|
|
61
|
+
metadata (dict): The metadata (typically from a Zarr group .attrs).
|
|
62
|
+
axes_setup (AxesSetup, optional): The axes setup.
|
|
63
|
+
This is used to map axes with non-canonical names.
|
|
64
|
+
allow_non_canonical_axes (bool, optional): Whether to allow non-canonical
|
|
65
|
+
axes.
|
|
66
|
+
strict_canonical_order (bool, optional): Whether to enforce a strict
|
|
67
|
+
canonical order.
|
|
173
68
|
|
|
69
|
+
Returns:
|
|
70
|
+
tuple[bool, NgioImageMeta | ConverterError]: A tuple with a boolean
|
|
71
|
+
indicating whether the conversion was successful and the
|
|
72
|
+
NgioImageMeta object or an error.
|
|
174
73
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
version: str | None = None,
|
|
178
|
-
axes_setup: AxesSetup | None = None,
|
|
179
|
-
) -> NgioImageMeta:
|
|
180
|
-
"""Retrieve the NGIO image metadata from the Zarr group.
|
|
181
|
-
|
|
182
|
-
Args:
|
|
183
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
184
|
-
version (str | None): Optional NGFF version to use for decoding.
|
|
185
|
-
axes_setup (AxesSetup | None): Optional axes setup for validation.
|
|
186
|
-
|
|
187
|
-
Returns:
|
|
188
|
-
NgioImageMeta: The NGIO image metadata.
|
|
189
|
-
"""
|
|
190
|
-
# axes_setup = axes_setup or AxesSetup(x="XX")
|
|
191
|
-
return get_ngio_meta(
|
|
192
|
-
group_handler=group_handler,
|
|
193
|
-
meta_type=NgioImageMeta,
|
|
194
|
-
version=version,
|
|
195
|
-
axes_setup=axes_setup,
|
|
196
|
-
)
|
|
74
|
+
"""
|
|
75
|
+
...
|
|
197
76
|
|
|
198
77
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
ngio_meta: NgioImageMeta,
|
|
202
|
-
) -> None:
|
|
203
|
-
"""Update the NGIO image metadata in the Zarr group.
|
|
78
|
+
class ImageMetaExporter(Protocol):
|
|
79
|
+
def __call__(self, metadata: NgioImageMeta) -> dict: ...
|
|
204
80
|
|
|
205
|
-
Args:
|
|
206
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
207
|
-
ngio_meta (NgioImageMeta): The new NGIO image metadata.
|
|
208
81
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
82
|
+
class LabelMetaImporter(Protocol):
|
|
83
|
+
@staticmethod
|
|
84
|
+
def __call__(
|
|
85
|
+
metadata: dict,
|
|
86
|
+
axes_setup: AxesSetup | None = None,
|
|
87
|
+
allow_non_canonical_axes: bool = False,
|
|
88
|
+
strict_canonical_order: bool = True,
|
|
89
|
+
) -> tuple[bool, NgioLabelMeta | ConverterError]:
|
|
90
|
+
"""Convert the metadata to a NgioLabelMeta object.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
metadata (dict): The metadata (typically from a Zarr group .attrs).
|
|
94
|
+
axes_setup (AxesSetup, optional): The axes setup.
|
|
95
|
+
This is used to map axes with non-canonical names.
|
|
96
|
+
allow_non_canonical_axes (bool, optional): Whether to allow non-canonical
|
|
97
|
+
axes.
|
|
98
|
+
strict_canonical_order (bool, optional): Whether to enforce a strict
|
|
99
|
+
canonical order.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
tuple[bool, NgioLabelMeta | ConverterError]: A tuple with a boolean
|
|
103
|
+
indicating whether the conversion was successful and the
|
|
104
|
+
NgioLabelMeta object or an error.
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
...
|
|
214
108
|
|
|
215
109
|
|
|
216
|
-
class
|
|
110
|
+
class LabelMetaExporter(Protocol):
|
|
111
|
+
def __call__(self, metadata: NgioLabelMeta) -> dict: ...
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class WellMetaImporter(Protocol):
|
|
115
|
+
def __call__(
|
|
116
|
+
self, metadata: dict
|
|
117
|
+
) -> tuple[bool, NgioWellMeta | ConverterError]: ...
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class WellMetaExporter(Protocol):
|
|
121
|
+
def __call__(self, metadata: NgioWellMeta) -> dict: ...
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class PlateMetaImporter(Protocol):
|
|
125
|
+
def __call__(
|
|
126
|
+
self, metadata: dict
|
|
127
|
+
) -> tuple[bool, NgioPlateMeta | ConverterError]: ...
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class PlateMetaExporter(Protocol):
|
|
131
|
+
def __call__(self, metadata: NgioPlateMeta) -> dict: ...
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
###########################################################################
|
|
135
|
+
#
|
|
136
|
+
# Image and label metadata handlers
|
|
137
|
+
#
|
|
138
|
+
###########################################################################
|
|
139
|
+
|
|
140
|
+
_image_meta = TypeVar("_image_meta", NgioImageMeta, NgioLabelMeta)
|
|
141
|
+
_image_meta_importer = TypeVar(
|
|
142
|
+
"_image_meta_importer", ImageMetaImporter, LabelMetaImporter
|
|
143
|
+
)
|
|
144
|
+
_image_meta_exporter = TypeVar(
|
|
145
|
+
"_image_meta_exporter", ImageMetaExporter, LabelMetaExporter
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class GenericMetaHandler(
|
|
150
|
+
Generic[_image_meta, _image_meta_importer, _image_meta_exporter]
|
|
151
|
+
):
|
|
152
|
+
"""Generic class for handling OME-Zarr metadata in Zarr groups."""
|
|
153
|
+
|
|
217
154
|
def __init__(
|
|
218
155
|
self,
|
|
156
|
+
meta_importer: _image_meta_importer,
|
|
157
|
+
meta_exporter: _image_meta_exporter,
|
|
219
158
|
group_handler: ZarrGroupHandler,
|
|
220
|
-
version: str | None = None,
|
|
221
159
|
axes_setup: AxesSetup | None = None,
|
|
160
|
+
allow_non_canonical_axes: bool = False,
|
|
161
|
+
strict_canonical_order: bool = True,
|
|
222
162
|
):
|
|
163
|
+
"""Initialize the handler.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
meta_importer (MetaImporter): The metadata importer.
|
|
167
|
+
meta_exporter (MetaExporter): The metadata exporter.
|
|
168
|
+
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
169
|
+
axes_setup (AxesSetup, optional): The axes setup.
|
|
170
|
+
This is used to map axes with non-canonical names.
|
|
171
|
+
allow_non_canonical_axes (bool, optional): Whether to allow non-canonical
|
|
172
|
+
axes.
|
|
173
|
+
strict_canonical_order (bool, optional): Whether to enforce a strict
|
|
174
|
+
canonical order.
|
|
175
|
+
"""
|
|
223
176
|
self._group_handler = group_handler
|
|
224
|
-
self.
|
|
177
|
+
self._meta_importer = meta_importer
|
|
178
|
+
self._meta_exporter = meta_exporter
|
|
225
179
|
self._axes_setup = axes_setup
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
group_handler=self._group_handler,
|
|
235
|
-
version=self._version,
|
|
180
|
+
self._allow_non_canonical_axes = allow_non_canonical_axes
|
|
181
|
+
self._strict_canonical_order = strict_canonical_order
|
|
182
|
+
|
|
183
|
+
def _load_meta(self, return_error: bool = False):
|
|
184
|
+
"""Load the metadata from the store."""
|
|
185
|
+
attrs = self._group_handler.load_attrs()
|
|
186
|
+
is_valid, meta_or_error = self._meta_importer(
|
|
187
|
+
metadata=attrs,
|
|
236
188
|
axes_setup=self._axes_setup,
|
|
189
|
+
allow_non_canonical_axes=self._allow_non_canonical_axes,
|
|
190
|
+
strict_canonical_order=self._strict_canonical_order,
|
|
237
191
|
)
|
|
192
|
+
if is_valid:
|
|
193
|
+
return meta_or_error
|
|
238
194
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
update_ngio_meta(
|
|
242
|
-
group_handler=self._group_handler,
|
|
243
|
-
ngio_meta=ngio_meta,
|
|
244
|
-
)
|
|
195
|
+
if return_error:
|
|
196
|
+
return meta_or_error
|
|
245
197
|
|
|
198
|
+
raise NgioValueError(f"Could not load metadata: {meta_or_error}")
|
|
246
199
|
|
|
247
|
-
def
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
) -> NgioLabelMeta:
|
|
252
|
-
"""Retrieve the NGIO label metadata from the Zarr group.
|
|
253
|
-
|
|
254
|
-
Args:
|
|
255
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
256
|
-
version (str | None): Optional NGFF version to use for decoding.
|
|
257
|
-
axes_setup (AxesSetup | None): Optional axes setup for validation.
|
|
258
|
-
|
|
259
|
-
Returns:
|
|
260
|
-
NgioLabelMeta: The NGIO label metadata.
|
|
261
|
-
"""
|
|
262
|
-
return get_ngio_meta(
|
|
263
|
-
group_handler=group_handler,
|
|
264
|
-
meta_type=NgioLabelMeta,
|
|
265
|
-
version=version,
|
|
266
|
-
axes_setup=axes_setup,
|
|
267
|
-
)
|
|
200
|
+
def _write_meta(self, meta) -> None:
|
|
201
|
+
"""Write the metadata to the store."""
|
|
202
|
+
_meta = self._meta_exporter(metadata=meta)
|
|
203
|
+
self._group_handler.write_attrs(_meta)
|
|
268
204
|
|
|
205
|
+
def write_meta(self, meta: _image_meta) -> None:
|
|
206
|
+
self._write_meta(meta)
|
|
269
207
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
"""Update the NGIO label metadata in the Zarr group.
|
|
208
|
+
@property
|
|
209
|
+
def meta(self) -> _image_meta:
|
|
210
|
+
"""Return the metadata."""
|
|
211
|
+
raise NotImplementedError("This method should be implemented in a subclass.")
|
|
275
212
|
|
|
276
|
-
Args:
|
|
277
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
278
|
-
ngio_meta (NgioLabelMeta): The new NGIO label metadata.
|
|
279
213
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
214
|
+
class ImageMetaHandler(
|
|
215
|
+
GenericMetaHandler[NgioImageMeta, ImageMetaImporter, ImageMetaExporter]
|
|
216
|
+
):
|
|
217
|
+
"""Generic class for handling OME-Zarr metadata in Zarr groups."""
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def meta(self) -> NgioImageMeta:
|
|
221
|
+
meta = self._load_meta()
|
|
222
|
+
if isinstance(meta, NgioImageMeta):
|
|
223
|
+
return meta
|
|
224
|
+
raise NgioValueError(f"Could not load metadata: {meta}")
|
|
225
|
+
|
|
226
|
+
def safe_load_meta(self) -> NgioImageMeta | ConverterError:
|
|
227
|
+
"""Load the metadata from the store."""
|
|
228
|
+
return self._load_meta(return_error=True)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class LabelMetaHandler(
|
|
232
|
+
GenericMetaHandler[NgioLabelMeta, LabelMetaImporter, LabelMetaExporter]
|
|
233
|
+
):
|
|
234
|
+
"""Generic class for handling OME-Zarr metadata in Zarr groups."""
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def meta(self) -> NgioLabelMeta:
|
|
238
|
+
meta = self._load_meta()
|
|
239
|
+
if isinstance(meta, NgioLabelMeta):
|
|
240
|
+
return meta
|
|
241
|
+
raise NgioValueError(f"Could not load metadata: {meta}")
|
|
242
|
+
|
|
243
|
+
def safe_load_meta(self) -> NgioLabelMeta | ConverterError:
|
|
244
|
+
"""Load the metadata from the store."""
|
|
245
|
+
return self._load_meta(return_error=True)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
###########################################################################
|
|
249
|
+
#
|
|
250
|
+
# Well and plate metadata handlers
|
|
251
|
+
#
|
|
252
|
+
###########################################################################
|
|
253
|
+
|
|
254
|
+
_hcs_meta = TypeVar("_hcs_meta", NgioWellMeta, NgioPlateMeta)
|
|
255
|
+
_hcs_meta_importer = TypeVar("_hcs_meta_importer", WellMetaImporter, PlateMetaImporter)
|
|
256
|
+
_hcs_meta_exporter = TypeVar("_hcs_meta_exporter", WellMetaExporter, PlateMetaExporter)
|
|
257
|
+
|
|
285
258
|
|
|
259
|
+
class GenericHCSMetaHandler(Generic[_hcs_meta, _hcs_meta_importer, _hcs_meta_exporter]):
|
|
260
|
+
"""Generic class for handling OME-Zarr metadata in Zarr groups."""
|
|
286
261
|
|
|
287
|
-
class LabelMetaHandler:
|
|
288
262
|
def __init__(
|
|
289
263
|
self,
|
|
264
|
+
meta_importer: _hcs_meta_importer,
|
|
265
|
+
meta_exporter: _hcs_meta_exporter,
|
|
290
266
|
group_handler: ZarrGroupHandler,
|
|
291
|
-
axes_setup: AxesSetup | None = None,
|
|
292
|
-
version: str | None = None,
|
|
293
267
|
):
|
|
294
268
|
self._group_handler = group_handler
|
|
295
|
-
self.
|
|
296
|
-
self.
|
|
269
|
+
self._meta_importer = meta_importer
|
|
270
|
+
self._meta_exporter = meta_exporter
|
|
297
271
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
272
|
+
def _load_meta(self, return_error: bool = False):
|
|
273
|
+
"""Load the metadata from the store."""
|
|
274
|
+
attrs = self._group_handler.load_attrs()
|
|
275
|
+
is_valid, meta_or_error = self._meta_importer(metadata=attrs)
|
|
276
|
+
if is_valid:
|
|
277
|
+
return meta_or_error
|
|
302
278
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
return get_ngio_label_meta(
|
|
306
|
-
group_handler=self._group_handler,
|
|
307
|
-
version=self._version,
|
|
308
|
-
axes_setup=self._axes_setup,
|
|
309
|
-
)
|
|
279
|
+
if return_error:
|
|
280
|
+
return meta_or_error
|
|
310
281
|
|
|
311
|
-
|
|
312
|
-
"""Update the NGIO label metadata."""
|
|
313
|
-
update_ngio_meta(
|
|
314
|
-
group_handler=self._group_handler,
|
|
315
|
-
ngio_meta=ngio_meta,
|
|
316
|
-
)
|
|
282
|
+
raise NgioValueError(f"Could not load metadata: {meta_or_error}")
|
|
317
283
|
|
|
284
|
+
def _write_meta(self, meta) -> None:
|
|
285
|
+
_meta = self._meta_exporter(metadata=meta)
|
|
286
|
+
self._group_handler.write_attrs(_meta)
|
|
318
287
|
|
|
319
|
-
def
|
|
320
|
-
|
|
321
|
-
version: str | None = None,
|
|
322
|
-
) -> NgioPlateMeta:
|
|
323
|
-
"""Retrieve the NGIO plate metadata from the Zarr group.
|
|
324
|
-
|
|
325
|
-
Args:
|
|
326
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
327
|
-
version (str | None): Optional NGFF version to use for decoding.
|
|
328
|
-
|
|
329
|
-
Returns:
|
|
330
|
-
NgioPlateMeta: The NGIO plate metadata.
|
|
331
|
-
"""
|
|
332
|
-
return get_ngio_meta(
|
|
333
|
-
group_handler=group_handler,
|
|
334
|
-
meta_type=NgioPlateMeta,
|
|
335
|
-
version=version,
|
|
336
|
-
)
|
|
288
|
+
def write_meta(self, meta: _hcs_meta) -> None:
|
|
289
|
+
self._write_meta(meta)
|
|
337
290
|
|
|
291
|
+
@property
|
|
292
|
+
def meta(self) -> _hcs_meta:
|
|
293
|
+
raise NotImplementedError("This method should be implemented in a subclass.")
|
|
338
294
|
|
|
339
|
-
def update_ngio_plate_meta(
|
|
340
|
-
group_handler: ZarrGroupHandler,
|
|
341
|
-
ngio_meta: NgioPlateMeta,
|
|
342
|
-
) -> None:
|
|
343
|
-
"""Update the NGIO plate metadata in the Zarr group.
|
|
344
295
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
296
|
+
class WellMetaHandler(
|
|
297
|
+
GenericHCSMetaHandler[NgioWellMeta, WellMetaImporter, WellMetaExporter]
|
|
298
|
+
):
|
|
299
|
+
"""Generic class for handling OME-Zarr metadata in Zarr groups."""
|
|
348
300
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
301
|
+
@property
|
|
302
|
+
def meta(self) -> NgioWellMeta:
|
|
303
|
+
meta = self._load_meta()
|
|
304
|
+
if isinstance(meta, NgioWellMeta):
|
|
305
|
+
return meta
|
|
306
|
+
raise NgioValueError(f"Could not load metadata: {meta}")
|
|
307
|
+
|
|
308
|
+
def safe_load_meta(self) -> NgioWellMeta | ConverterError:
|
|
309
|
+
"""Load the metadata from the store."""
|
|
310
|
+
return self._load_meta(return_error=True)
|
|
354
311
|
|
|
355
312
|
|
|
356
|
-
class PlateMetaHandler
|
|
313
|
+
class PlateMetaHandler(
|
|
314
|
+
GenericHCSMetaHandler[NgioPlateMeta, PlateMetaImporter, PlateMetaExporter]
|
|
315
|
+
):
|
|
316
|
+
"""Generic class for handling OME-Zarr metadata in Zarr groups."""
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def meta(self) -> NgioPlateMeta:
|
|
320
|
+
meta = self._load_meta()
|
|
321
|
+
if isinstance(meta, NgioPlateMeta):
|
|
322
|
+
return meta
|
|
323
|
+
raise NgioValueError(f"Could not load metadata: {meta}")
|
|
324
|
+
|
|
325
|
+
def safe_load_meta(self) -> NgioPlateMeta | ConverterError:
|
|
326
|
+
"""Load the metadata from the store."""
|
|
327
|
+
return self._load_meta(return_error=True)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
###########################################################################
|
|
331
|
+
#
|
|
332
|
+
# Metadata importer/exporter registration & builder classes
|
|
333
|
+
#
|
|
334
|
+
###########################################################################
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
_meta_exporter = TypeVar(
|
|
338
|
+
"_meta_exporter",
|
|
339
|
+
ImageMetaExporter,
|
|
340
|
+
LabelMetaExporter,
|
|
341
|
+
WellMetaExporter,
|
|
342
|
+
PlateMetaExporter,
|
|
343
|
+
)
|
|
344
|
+
_meta_importer = TypeVar(
|
|
345
|
+
"_meta_importer",
|
|
346
|
+
ImageMetaImporter,
|
|
347
|
+
LabelMetaImporter,
|
|
348
|
+
WellMetaImporter,
|
|
349
|
+
PlateMetaImporter,
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
class _ImporterExporter(Generic[_meta_importer, _meta_exporter]):
|
|
357
354
|
def __init__(
|
|
358
355
|
self,
|
|
359
|
-
|
|
360
|
-
|
|
356
|
+
version: str,
|
|
357
|
+
importer: _meta_importer,
|
|
358
|
+
exporter: _meta_exporter,
|
|
361
359
|
):
|
|
362
|
-
self.
|
|
363
|
-
self.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
360
|
+
self.importer = importer
|
|
361
|
+
self.exporter = exporter
|
|
362
|
+
self.version = version
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
ImageImporterExporter = _ImporterExporter[ImageMetaImporter, ImageMetaExporter]
|
|
366
|
+
LabelImporterExporter = _ImporterExporter[LabelMetaImporter, LabelMetaExporter]
|
|
367
|
+
WellImporterExporter = _ImporterExporter[WellMetaImporter, WellMetaExporter]
|
|
368
|
+
PlateImporterExporter = _ImporterExporter[PlateMetaImporter, PlateMetaExporter]
|
|
369
|
+
|
|
370
|
+
_importer_exporter = TypeVar(
|
|
371
|
+
"_importer_exporter",
|
|
372
|
+
ImageImporterExporter,
|
|
373
|
+
LabelImporterExporter,
|
|
374
|
+
WellImporterExporter,
|
|
375
|
+
PlateImporterExporter,
|
|
376
|
+
)
|
|
377
|
+
_image_handler = TypeVar("_image_handler", ImageMetaHandler, LabelMetaHandler)
|
|
378
|
+
_hcs_handler = TypeVar("_hcs_handler", WellMetaHandler, PlateMetaHandler)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
class ImplementedMetaImporterExporter:
|
|
382
|
+
_instance = None
|
|
383
|
+
_image_ie: dict[str, ImageImporterExporter]
|
|
384
|
+
_label_ie: dict[str, LabelImporterExporter]
|
|
385
|
+
_well_ie: dict[str, WellImporterExporter]
|
|
386
|
+
_plate_ie: dict[str, PlateImporterExporter]
|
|
387
|
+
|
|
388
|
+
def __new__(cls):
|
|
389
|
+
"""Create a new instance of the class if it does not exist."""
|
|
390
|
+
if cls._instance is None:
|
|
391
|
+
cls._instance = super().__new__(cls)
|
|
392
|
+
cls._image_ie = {}
|
|
393
|
+
cls._label_ie = {}
|
|
394
|
+
cls._well_ie = {}
|
|
395
|
+
cls._plate_ie = {}
|
|
396
|
+
return cls._instance
|
|
397
|
+
|
|
398
|
+
def _find_image_handler(
|
|
399
|
+
self,
|
|
400
|
+
group_handler: ZarrGroupHandler,
|
|
401
|
+
axes_setup: AxesSetup | None = None,
|
|
402
|
+
allow_non_canonical_axes: bool = False,
|
|
403
|
+
strict_canonical_order: bool = True,
|
|
404
|
+
_ie_name: str = "_image_ie",
|
|
405
|
+
_handler: type[_image_handler] = ImageMetaHandler,
|
|
406
|
+
) -> _image_handler:
|
|
407
|
+
"""Get an image metadata handler."""
|
|
408
|
+
_errors = {}
|
|
409
|
+
|
|
410
|
+
dict_ie = self.__getattribute__(_ie_name)
|
|
411
|
+
|
|
412
|
+
for ie in reversed(dict_ie.values()):
|
|
413
|
+
handler = _handler(
|
|
414
|
+
meta_importer=ie.importer,
|
|
415
|
+
meta_exporter=ie.exporter,
|
|
416
|
+
group_handler=group_handler,
|
|
417
|
+
axes_setup=axes_setup,
|
|
418
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
419
|
+
strict_canonical_order=strict_canonical_order,
|
|
420
|
+
)
|
|
421
|
+
meta = handler.safe_load_meta()
|
|
422
|
+
if isinstance(meta, ValidationError):
|
|
423
|
+
_errors[ie.version] = meta
|
|
424
|
+
continue
|
|
425
|
+
return handler
|
|
426
|
+
|
|
427
|
+
raise NgioValidationError(
|
|
428
|
+
f"Could not load metadata from any known version. Errors: {_errors}"
|
|
375
429
|
)
|
|
376
430
|
|
|
377
|
-
def
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
431
|
+
def find_image_handler(
|
|
432
|
+
self,
|
|
433
|
+
group_handler: ZarrGroupHandler,
|
|
434
|
+
axes_setup: AxesSetup | None = None,
|
|
435
|
+
allow_non_canonical_axes: bool = False,
|
|
436
|
+
strict_canonical_order: bool = True,
|
|
437
|
+
) -> ImageMetaHandler:
|
|
438
|
+
"""Get an image metadata handler."""
|
|
439
|
+
return self._find_image_handler(
|
|
440
|
+
group_handler=group_handler,
|
|
441
|
+
axes_setup=axes_setup,
|
|
442
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
443
|
+
strict_canonical_order=strict_canonical_order,
|
|
444
|
+
_ie_name="_image_ie",
|
|
445
|
+
_handler=ImageMetaHandler,
|
|
382
446
|
)
|
|
383
447
|
|
|
448
|
+
def get_image_meta_handler(
|
|
449
|
+
self,
|
|
450
|
+
group_handler: ZarrGroupHandler,
|
|
451
|
+
version: str,
|
|
452
|
+
axes_setup: AxesSetup | None = None,
|
|
453
|
+
allow_non_canonical_axes: bool = False,
|
|
454
|
+
strict_canonical_order: bool = True,
|
|
455
|
+
) -> ImageMetaHandler:
|
|
456
|
+
"""Get an image metadata handler."""
|
|
457
|
+
if version not in self._image_ie:
|
|
458
|
+
raise NgioValueError(f"Image handler for version {version} does not exist.")
|
|
459
|
+
|
|
460
|
+
image_ie = self._image_ie[version]
|
|
461
|
+
return ImageMetaHandler(
|
|
462
|
+
meta_importer=image_ie.importer,
|
|
463
|
+
meta_exporter=image_ie.exporter,
|
|
464
|
+
group_handler=group_handler,
|
|
465
|
+
axes_setup=axes_setup,
|
|
466
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
467
|
+
strict_canonical_order=strict_canonical_order,
|
|
468
|
+
)
|
|
384
469
|
|
|
385
|
-
def
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
470
|
+
def _register(
|
|
471
|
+
self,
|
|
472
|
+
version: str,
|
|
473
|
+
importer: _importer_exporter,
|
|
474
|
+
overwrite: bool = False,
|
|
475
|
+
_ie_name: str = "_image_ie",
|
|
476
|
+
):
|
|
477
|
+
"""Register an importer/exporter."""
|
|
478
|
+
ie_dict = self.__getattribute__(_ie_name)
|
|
479
|
+
if version in ie_dict and not overwrite:
|
|
480
|
+
raise NgioValueError(
|
|
481
|
+
f"Importer/exporter for version {version} already exists. "
|
|
482
|
+
"Use 'overwrite=True' to overwrite."
|
|
483
|
+
)
|
|
484
|
+
ie_dict[version] = importer
|
|
485
|
+
|
|
486
|
+
def register_image_ie(
|
|
487
|
+
self,
|
|
488
|
+
version: str,
|
|
489
|
+
importer: ImageMetaImporter,
|
|
490
|
+
exporter: ImageMetaExporter,
|
|
491
|
+
overwrite: bool = False,
|
|
492
|
+
):
|
|
493
|
+
"""Register an importer/exporter."""
|
|
494
|
+
importer_exporter = ImageImporterExporter(
|
|
495
|
+
version=version, importer=importer, exporter=exporter
|
|
496
|
+
)
|
|
497
|
+
self._register(
|
|
498
|
+
version=version,
|
|
499
|
+
importer=importer_exporter,
|
|
500
|
+
overwrite=overwrite,
|
|
501
|
+
_ie_name="_image_ie",
|
|
502
|
+
)
|
|
403
503
|
|
|
504
|
+
def find_label_handler(
|
|
505
|
+
self,
|
|
506
|
+
group_handler: ZarrGroupHandler,
|
|
507
|
+
axes_setup: AxesSetup | None = None,
|
|
508
|
+
allow_non_canonical_axes: bool = False,
|
|
509
|
+
strict_canonical_order: bool = True,
|
|
510
|
+
) -> LabelMetaHandler:
|
|
511
|
+
"""Get a label metadata handler."""
|
|
512
|
+
return self._find_image_handler(
|
|
513
|
+
group_handler=group_handler,
|
|
514
|
+
axes_setup=axes_setup,
|
|
515
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
516
|
+
strict_canonical_order=strict_canonical_order,
|
|
517
|
+
_ie_name="_label_ie",
|
|
518
|
+
_handler=LabelMetaHandler,
|
|
519
|
+
)
|
|
404
520
|
|
|
405
|
-
def
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
521
|
+
def get_label_meta_handler(
|
|
522
|
+
self,
|
|
523
|
+
group_handler: ZarrGroupHandler,
|
|
524
|
+
version: str,
|
|
525
|
+
axes_setup: AxesSetup | None = None,
|
|
526
|
+
allow_non_canonical_axes: bool = False,
|
|
527
|
+
strict_canonical_order: bool = True,
|
|
528
|
+
) -> LabelMetaHandler:
|
|
529
|
+
"""Get a label metadata handler."""
|
|
530
|
+
if version not in self._label_ie:
|
|
531
|
+
raise NgioValueError(f"Label handler for version {version} does not exist.")
|
|
532
|
+
|
|
533
|
+
label_ie = self._label_ie[version]
|
|
534
|
+
return LabelMetaHandler(
|
|
535
|
+
meta_importer=label_ie.importer,
|
|
536
|
+
meta_exporter=label_ie.exporter,
|
|
537
|
+
group_handler=group_handler,
|
|
538
|
+
axes_setup=axes_setup,
|
|
539
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
540
|
+
strict_canonical_order=strict_canonical_order,
|
|
541
|
+
)
|
|
410
542
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
543
|
+
def register_label_ie(
|
|
544
|
+
self,
|
|
545
|
+
version: str,
|
|
546
|
+
importer: LabelMetaImporter,
|
|
547
|
+
exporter: LabelMetaExporter,
|
|
548
|
+
overwrite: bool = False,
|
|
549
|
+
):
|
|
550
|
+
"""Register an importer/exporter."""
|
|
551
|
+
importer_exporter = LabelImporterExporter(
|
|
552
|
+
version=version, importer=importer, exporter=exporter
|
|
553
|
+
)
|
|
554
|
+
self._register(
|
|
555
|
+
version=version,
|
|
556
|
+
importer=importer_exporter,
|
|
557
|
+
overwrite=overwrite,
|
|
558
|
+
_ie_name="_label_ie",
|
|
559
|
+
)
|
|
414
560
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
group_handler
|
|
418
|
-
|
|
419
|
-
|
|
561
|
+
def _find_hcs_handler(
|
|
562
|
+
self,
|
|
563
|
+
group_handler: ZarrGroupHandler,
|
|
564
|
+
_ie_name: str = "_well_ie",
|
|
565
|
+
_handler: type[_hcs_handler] = WellMetaHandler,
|
|
566
|
+
) -> _hcs_handler:
|
|
567
|
+
"""Get a handler for a HCS metadata."""
|
|
568
|
+
_errors = {}
|
|
569
|
+
|
|
570
|
+
dict_ie = self.__getattribute__(_ie_name)
|
|
571
|
+
|
|
572
|
+
for ie in reversed(dict_ie.values()):
|
|
573
|
+
handler = _handler(
|
|
574
|
+
meta_importer=ie.importer,
|
|
575
|
+
meta_exporter=ie.exporter,
|
|
576
|
+
group_handler=group_handler,
|
|
577
|
+
)
|
|
578
|
+
meta = handler.safe_load_meta()
|
|
579
|
+
if isinstance(meta, ValidationError):
|
|
580
|
+
_errors[ie.version] = meta
|
|
581
|
+
continue
|
|
582
|
+
return handler
|
|
583
|
+
|
|
584
|
+
raise NgioValidationError(
|
|
585
|
+
f"Could not load metadata from any known version. Errors: {_errors}"
|
|
586
|
+
)
|
|
420
587
|
|
|
588
|
+
def find_well_handler(
|
|
589
|
+
self,
|
|
590
|
+
group_handler: ZarrGroupHandler,
|
|
591
|
+
) -> WellMetaHandler:
|
|
592
|
+
"""Get a well metadata handler."""
|
|
593
|
+
return self._find_hcs_handler(
|
|
594
|
+
group_handler=group_handler,
|
|
595
|
+
_ie_name="_well_ie",
|
|
596
|
+
_handler=WellMetaHandler,
|
|
597
|
+
)
|
|
421
598
|
|
|
422
|
-
|
|
423
|
-
def __init__(
|
|
599
|
+
def get_well_meta_handler(
|
|
424
600
|
self,
|
|
425
601
|
group_handler: ZarrGroupHandler,
|
|
426
|
-
version: str
|
|
602
|
+
version: str,
|
|
603
|
+
) -> WellMetaHandler:
|
|
604
|
+
"""Get a well metadata handler."""
|
|
605
|
+
if version not in self._well_ie:
|
|
606
|
+
raise NgioValueError(f"Well handler for version {version} does not exist.")
|
|
607
|
+
|
|
608
|
+
well_ie = self._well_ie[version]
|
|
609
|
+
return WellMetaHandler(
|
|
610
|
+
meta_importer=well_ie.importer,
|
|
611
|
+
meta_exporter=well_ie.exporter,
|
|
612
|
+
group_handler=group_handler,
|
|
613
|
+
)
|
|
614
|
+
|
|
615
|
+
def register_well_ie(
|
|
616
|
+
self,
|
|
617
|
+
version: str,
|
|
618
|
+
importer: WellMetaImporter,
|
|
619
|
+
exporter: WellMetaExporter,
|
|
620
|
+
overwrite: bool = False,
|
|
427
621
|
):
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
622
|
+
"""Register an importer/exporter."""
|
|
623
|
+
importer_exporter = WellImporterExporter(
|
|
624
|
+
version=version, importer=importer, exporter=exporter
|
|
625
|
+
)
|
|
626
|
+
self._register(
|
|
627
|
+
version=version,
|
|
628
|
+
importer=importer_exporter,
|
|
629
|
+
overwrite=overwrite,
|
|
630
|
+
_ie_name="_well_ie",
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
def find_plate_handler(
|
|
634
|
+
self,
|
|
635
|
+
group_handler: ZarrGroupHandler,
|
|
636
|
+
) -> PlateMetaHandler:
|
|
637
|
+
"""Get a plate metadata handler."""
|
|
638
|
+
return self._find_hcs_handler(
|
|
639
|
+
group_handler=group_handler,
|
|
640
|
+
_ie_name="_plate_ie",
|
|
641
|
+
_handler=PlateMetaHandler,
|
|
441
642
|
)
|
|
442
643
|
|
|
443
|
-
def
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
644
|
+
def get_plate_meta_handler(
|
|
645
|
+
self,
|
|
646
|
+
group_handler: ZarrGroupHandler,
|
|
647
|
+
version: str,
|
|
648
|
+
) -> PlateMetaHandler:
|
|
649
|
+
"""Get a plate metadata handler."""
|
|
650
|
+
if version not in self._plate_ie:
|
|
651
|
+
raise NgioValueError(f"Plate handler for version {version} does not exist.")
|
|
652
|
+
|
|
653
|
+
plate_ie = self._plate_ie[version]
|
|
654
|
+
return PlateMetaHandler(
|
|
655
|
+
meta_importer=plate_ie.importer,
|
|
656
|
+
meta_exporter=plate_ie.exporter,
|
|
657
|
+
group_handler=group_handler,
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
def register_plate_ie(
|
|
661
|
+
self,
|
|
662
|
+
version: str,
|
|
663
|
+
importer: PlateMetaImporter,
|
|
664
|
+
exporter: PlateMetaExporter,
|
|
665
|
+
overwrite: bool = False,
|
|
666
|
+
):
|
|
667
|
+
"""Register an importer/exporter."""
|
|
668
|
+
importer_exporter = PlateImporterExporter(
|
|
669
|
+
version=version, importer=importer, exporter=exporter
|
|
670
|
+
)
|
|
671
|
+
self._register(
|
|
672
|
+
version=version,
|
|
673
|
+
importer=importer_exporter,
|
|
674
|
+
overwrite=overwrite,
|
|
675
|
+
_ie_name="_plate_ie",
|
|
448
676
|
)
|
|
449
677
|
|
|
450
678
|
|
|
451
|
-
|
|
679
|
+
###########################################################################
|
|
680
|
+
#
|
|
681
|
+
# Register metadata importers/exporters
|
|
682
|
+
#
|
|
683
|
+
###########################################################################
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
ImplementedMetaImporterExporter().register_image_ie(
|
|
687
|
+
version="0.4",
|
|
688
|
+
importer=v04_to_ngio_image_meta,
|
|
689
|
+
exporter=ngio_to_v04_image_meta,
|
|
690
|
+
)
|
|
691
|
+
|
|
692
|
+
ImplementedMetaImporterExporter().register_label_ie(
|
|
693
|
+
version="0.5",
|
|
694
|
+
importer=v05_to_ngio_label_meta,
|
|
695
|
+
exporter=ngio_to_v05_label_meta,
|
|
696
|
+
)
|
|
697
|
+
|
|
698
|
+
ImplementedMetaImporterExporter().register_label_ie(
|
|
699
|
+
version="0.4",
|
|
700
|
+
importer=v04_to_ngio_label_meta,
|
|
701
|
+
exporter=ngio_to_v04_label_meta,
|
|
702
|
+
)
|
|
703
|
+
ImplementedMetaImporterExporter().register_image_ie(
|
|
704
|
+
version="0.5",
|
|
705
|
+
importer=v05_to_ngio_image_meta,
|
|
706
|
+
exporter=ngio_to_v05_image_meta,
|
|
707
|
+
)
|
|
708
|
+
|
|
709
|
+
ImplementedMetaImporterExporter().register_well_ie(
|
|
710
|
+
version="0.4", importer=v04_to_ngio_well_meta, exporter=ngio_to_v04_well_meta
|
|
711
|
+
)
|
|
712
|
+
ImplementedMetaImporterExporter().register_well_ie(
|
|
713
|
+
version="0.5", importer=v05_to_ngio_well_meta, exporter=ngio_to_v05_well_meta
|
|
714
|
+
)
|
|
715
|
+
ImplementedMetaImporterExporter().register_plate_ie(
|
|
716
|
+
version="0.4", importer=v04_to_ngio_plate_meta, exporter=ngio_to_v04_plate_meta
|
|
717
|
+
)
|
|
718
|
+
ImplementedMetaImporterExporter().register_plate_ie(
|
|
719
|
+
version="0.5", importer=v05_to_ngio_plate_meta, exporter=ngio_to_v05_plate_meta
|
|
720
|
+
)
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
###########################################################################
|
|
724
|
+
#
|
|
725
|
+
# Public functions to avoid direct access to the importer/exporter
|
|
726
|
+
# registration methods
|
|
727
|
+
#
|
|
728
|
+
###########################################################################
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
def find_image_meta_handler(
|
|
452
732
|
group_handler: ZarrGroupHandler,
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
733
|
+
axes_setup: AxesSetup | None = None,
|
|
734
|
+
allow_non_canonical_axes: bool = False,
|
|
735
|
+
strict_canonical_order: bool = True,
|
|
736
|
+
) -> ImageMetaHandler:
|
|
737
|
+
"""Open an image metadata handler."""
|
|
738
|
+
return ImplementedMetaImporterExporter().find_image_handler(
|
|
739
|
+
group_handler=group_handler,
|
|
740
|
+
axes_setup=axes_setup,
|
|
741
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
742
|
+
strict_canonical_order=strict_canonical_order,
|
|
743
|
+
)
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
def get_image_meta_handler(
|
|
747
|
+
group_handler: ZarrGroupHandler,
|
|
748
|
+
version: str,
|
|
749
|
+
axes_setup: AxesSetup | None = None,
|
|
750
|
+
allow_non_canonical_axes: bool = False,
|
|
751
|
+
strict_canonical_order: bool = True,
|
|
752
|
+
) -> ImageMetaHandler:
|
|
753
|
+
"""Open an image metadata handler."""
|
|
754
|
+
return ImplementedMetaImporterExporter().get_image_meta_handler(
|
|
465
755
|
group_handler=group_handler,
|
|
466
|
-
meta_type=NgioLabelsGroupMeta,
|
|
467
756
|
version=version,
|
|
757
|
+
axes_setup=axes_setup,
|
|
758
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
759
|
+
strict_canonical_order=strict_canonical_order,
|
|
468
760
|
)
|
|
469
761
|
|
|
470
762
|
|
|
471
|
-
def
|
|
763
|
+
def find_label_meta_handler(
|
|
472
764
|
group_handler: ZarrGroupHandler,
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
765
|
+
axes_setup: AxesSetup | None = None,
|
|
766
|
+
allow_non_canonical_axes: bool = False,
|
|
767
|
+
strict_canonical_order: bool = True,
|
|
768
|
+
) -> LabelMetaHandler:
|
|
769
|
+
"""Open a label metadata handler."""
|
|
770
|
+
return ImplementedMetaImporterExporter().find_label_handler(
|
|
771
|
+
group_handler=group_handler,
|
|
772
|
+
axes_setup=axes_setup,
|
|
773
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
774
|
+
strict_canonical_order=strict_canonical_order,
|
|
775
|
+
)
|
|
476
776
|
|
|
477
|
-
Args:
|
|
478
|
-
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
479
|
-
ngio_meta (NgioLabelsGroupMeta): The new NGIO labels group metadata.
|
|
480
777
|
|
|
481
|
-
|
|
482
|
-
|
|
778
|
+
def get_label_meta_handler(
|
|
779
|
+
group_handler: ZarrGroupHandler,
|
|
780
|
+
version: str,
|
|
781
|
+
axes_setup: AxesSetup | None = None,
|
|
782
|
+
allow_non_canonical_axes: bool = False,
|
|
783
|
+
strict_canonical_order: bool = True,
|
|
784
|
+
) -> LabelMetaHandler:
|
|
785
|
+
"""Open a label metadata handler."""
|
|
786
|
+
return ImplementedMetaImporterExporter().get_label_meta_handler(
|
|
483
787
|
group_handler=group_handler,
|
|
484
|
-
|
|
788
|
+
version=version,
|
|
789
|
+
axes_setup=axes_setup,
|
|
790
|
+
allow_non_canonical_axes=allow_non_canonical_axes,
|
|
791
|
+
strict_canonical_order=strict_canonical_order,
|
|
485
792
|
)
|
|
486
793
|
|
|
487
794
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
group_handler
|
|
492
|
-
|
|
493
|
-
):
|
|
494
|
-
self._group_handler = group_handler
|
|
495
|
-
self._version = version
|
|
795
|
+
def find_well_meta_handler(group_handler: ZarrGroupHandler) -> WellMetaHandler:
|
|
796
|
+
"""Open a well metadata handler."""
|
|
797
|
+
return ImplementedMetaImporterExporter().find_well_handler(
|
|
798
|
+
group_handler=group_handler,
|
|
799
|
+
)
|
|
496
800
|
|
|
497
|
-
meta = self.get_meta()
|
|
498
|
-
self._version = meta.version
|
|
499
801
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
802
|
+
def get_well_meta_handler(
|
|
803
|
+
group_handler: ZarrGroupHandler,
|
|
804
|
+
version: str,
|
|
805
|
+
) -> WellMetaHandler:
|
|
806
|
+
"""Open a well metadata handler."""
|
|
807
|
+
return ImplementedMetaImporterExporter().get_well_meta_handler(
|
|
808
|
+
group_handler=group_handler,
|
|
809
|
+
version=version,
|
|
810
|
+
)
|
|
506
811
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
812
|
+
|
|
813
|
+
def find_plate_meta_handler(group_handler: ZarrGroupHandler) -> PlateMetaHandler:
|
|
814
|
+
"""Open a plate metadata handler."""
|
|
815
|
+
return ImplementedMetaImporterExporter().find_plate_handler(
|
|
816
|
+
group_handler=group_handler
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
def get_plate_meta_handler(
|
|
821
|
+
group_handler: ZarrGroupHandler,
|
|
822
|
+
version: str,
|
|
823
|
+
) -> PlateMetaHandler:
|
|
824
|
+
"""Open a plate metadata handler."""
|
|
825
|
+
return ImplementedMetaImporterExporter().get_plate_meta_handler(
|
|
826
|
+
group_handler=group_handler,
|
|
827
|
+
version=version,
|
|
828
|
+
)
|