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