ngio 0.5.0a1__py3-none-any.whl → 0.5.0a3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. ngio/__init__.py +2 -2
  2. ngio/common/__init__.py +11 -6
  3. ngio/common/_masking_roi.py +12 -41
  4. ngio/common/_pyramid.py +218 -78
  5. ngio/common/_roi.py +257 -329
  6. ngio/experimental/iterators/_feature.py +3 -3
  7. ngio/experimental/iterators/_rois_utils.py +10 -11
  8. ngio/hcs/_plate.py +114 -123
  9. ngio/images/_abstract_image.py +417 -35
  10. ngio/images/_create_synt_container.py +36 -43
  11. ngio/images/_create_utils.py +423 -0
  12. ngio/images/_image.py +155 -177
  13. ngio/images/_label.py +144 -119
  14. ngio/images/_ome_zarr_container.py +361 -196
  15. ngio/io_pipes/_io_pipes.py +9 -9
  16. ngio/io_pipes/_io_pipes_masked.py +7 -7
  17. ngio/io_pipes/_io_pipes_roi.py +6 -6
  18. ngio/io_pipes/_io_pipes_types.py +3 -3
  19. ngio/io_pipes/_match_shape.py +5 -4
  20. ngio/io_pipes/_ops_slices_utils.py +8 -5
  21. ngio/ome_zarr_meta/__init__.py +15 -18
  22. ngio/ome_zarr_meta/_meta_handlers.py +334 -713
  23. ngio/ome_zarr_meta/ngio_specs/_axes.py +1 -0
  24. ngio/ome_zarr_meta/ngio_specs/_dataset.py +13 -22
  25. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +54 -61
  26. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +14 -68
  27. ngio/ome_zarr_meta/v04/__init__.py +1 -1
  28. ngio/ome_zarr_meta/v04/{_v04_spec_utils.py → _v04_spec.py} +16 -61
  29. ngio/ome_zarr_meta/v05/__init__.py +1 -1
  30. ngio/ome_zarr_meta/v05/{_v05_spec_utils.py → _v05_spec.py} +18 -61
  31. ngio/tables/_tables_container.py +25 -20
  32. ngio/tables/backends/_anndata.py +57 -8
  33. ngio/tables/backends/_anndata_utils.py +1 -6
  34. ngio/tables/backends/_csv.py +3 -19
  35. ngio/tables/backends/_json.py +10 -13
  36. ngio/tables/backends/_parquet.py +3 -31
  37. ngio/tables/backends/_py_arrow_backends.py +222 -0
  38. ngio/tables/v1/_roi_table.py +44 -27
  39. ngio/utils/__init__.py +6 -12
  40. ngio/utils/_cache.py +48 -0
  41. ngio/utils/_zarr_utils.py +285 -245
  42. {ngio-0.5.0a1.dist-info → ngio-0.5.0a3.dist-info}/METADATA +8 -4
  43. {ngio-0.5.0a1.dist-info → ngio-0.5.0a3.dist-info}/RECORD +45 -45
  44. {ngio-0.5.0a1.dist-info → ngio-0.5.0a3.dist-info}/WHEEL +1 -1
  45. ngio/images/_create.py +0 -283
  46. ngio/tables/backends/_non_zarr_backends.py +0 -196
  47. ngio/utils/_logger.py +0 -50
  48. {ngio-0.5.0a1.dist-info → ngio-0.5.0a3.dist-info}/licenses/LICENSE +0 -0
@@ -352,6 +352,7 @@ class AxesHandler:
352
352
 
353
353
  @property
354
354
  def axes_names(self) -> tuple[str, ...]:
355
+ """On disk axes names."""
355
356
  return tuple(ax.name for ax in self._axes)
356
357
 
357
358
  @property
@@ -60,11 +60,20 @@ class Dataset:
60
60
  @property
61
61
  def pixel_size(self) -> PixelSize:
62
62
  """Return the pixel size for the dataset."""
63
+ scale = self._scale
64
+ pix_size_dict = {}
65
+ # Mandatory axes: x, y
66
+ for ax in ["x", "y"]:
67
+ index = self.axes_handler.get_index(ax)
68
+ assert index is not None
69
+ pix_size_dict[ax] = scale[index]
70
+
71
+ for ax in ["z", "t"]:
72
+ index = self.axes_handler.get_index(ax)
73
+ pix_size_dict[ax] = scale[index] if index is not None else 1.0
74
+
63
75
  return PixelSize(
64
- x=self.get_scale("x", default=1.0),
65
- y=self.get_scale("y", default=1.0),
66
- z=self.get_scale("z", default=1.0),
67
- t=self.get_scale("t", default=1.0),
76
+ **pix_size_dict,
68
77
  space_unit=self.axes_handler.space_unit,
69
78
  time_unit=self.axes_handler.time_unit,
70
79
  )
@@ -78,21 +87,3 @@ class Dataset:
78
87
  def translation(self) -> tuple[float, ...]:
79
88
  """Return the translation as a tuple."""
80
89
  return tuple(self._translation)
81
-
82
- def get_scale(self, axis_name: str, default: float | None = None) -> float:
83
- """Return the scale for a given axis."""
84
- idx = self.axes_handler.get_index(axis_name)
85
- if idx is None:
86
- if default is not None:
87
- return default
88
- raise ValueError(f"Axis {axis_name} not found in axes {self.axes_handler}.")
89
- return self._scale[idx]
90
-
91
- def get_translation(self, axis_name: str, default: float | None = None) -> float:
92
- """Return the translation for a given axis."""
93
- idx = self.axes_handler.get_index(axis_name)
94
- if idx is None:
95
- if default is not None:
96
- return default
97
- raise ValueError(f"Axis {axis_name} not found in axes {self.axes_handler}.")
98
- return self._translation[idx]
@@ -1,32 +1,31 @@
1
1
  """HCS (High Content Screening) specific metadata classes for NGIO."""
2
2
 
3
+ import warnings
3
4
  from typing import Annotated
4
5
 
5
- from ome_zarr_models.v04.hcs import HCSAttrs
6
- from ome_zarr_models.v04.plate import (
6
+ from ome_zarr_models.common.plate import (
7
7
  Acquisition,
8
8
  Column,
9
- Plate,
9
+ PlateBase,
10
10
  Row,
11
11
  WellInPlate,
12
12
  )
13
- from ome_zarr_models.v04.well import WellAttrs as WellAttrs04
14
- from ome_zarr_models.v04.well_types import WellImage as WellImage04
15
- from ome_zarr_models.v04.well_types import WellMeta as WellMeta04
13
+ from ome_zarr_models.common.well_types import WellImage as WellImageCommon
16
14
  from pydantic import BaseModel, SkipValidation, field_serializer
17
15
 
18
16
  from ngio.ome_zarr_meta.ngio_specs._ngio_image import DefaultNgffVersion, NgffVersions
19
- from ngio.utils import NgioValueError, ngio_logger
17
+ from ngio.utils import NgioValueError
20
18
 
21
19
 
22
20
  def path_in_well_validation(path: str) -> str:
23
21
  """Validate the path in the well."""
24
22
  # Check if the value contains only alphanumeric characters
25
23
  if not path.isalnum():
26
- ngio_logger.warning(
24
+ warnings.warn(
27
25
  f"Path '{path}' contains non-alphanumeric characters. "
28
26
  "This may cause issues with some tools. "
29
- "Consider using only alphanumeric characters in the path."
27
+ "Consider using only alphanumeric characters in the path.",
28
+ stacklevel=2,
30
29
  )
31
30
  return path
32
31
 
@@ -41,7 +40,7 @@ class ImageInWellPath(BaseModel):
41
40
  acquisition_name: str | None = None
42
41
 
43
42
 
44
- class CustomWellImage(WellImage04):
43
+ class CustomWellImage(WellImageCommon):
45
44
  path: Annotated[str, SkipValidation]
46
45
 
47
46
  @field_serializer("path")
@@ -50,32 +49,29 @@ class CustomWellImage(WellImage04):
50
49
  return path_in_well_validation(value)
51
50
 
52
51
 
53
- class CustomWellMeta(WellMeta04):
54
- images: list[CustomWellImage] # type: ignore (override of WellMeta04.images)
55
-
56
-
57
- class CustomWellAttrs(WellAttrs04):
58
- well: CustomWellMeta # type: ignore (override of WellAttrs04.well)
52
+ class PlateWithVersion(PlateBase):
53
+ version: NgffVersions
59
54
 
60
55
 
61
- class NgioWellMeta(CustomWellAttrs):
56
+ class NgioWellMeta(BaseModel):
62
57
  """HCS well metadata."""
63
58
 
59
+ images: list[CustomWellImage] # type: ignore (override of WellMeta04.images)
60
+ version: NgffVersions
61
+
64
62
  @classmethod
65
63
  def default_init(
66
64
  cls,
67
- version: NgffVersions | None = None,
65
+ version: NgffVersions = DefaultNgffVersion,
68
66
  ) -> "NgioWellMeta":
69
- if version is None:
70
- version = DefaultNgffVersion
71
- well = cls(well=CustomWellMeta(images=[], version=version))
67
+ well = cls(images=[], version=version)
72
68
  return well
73
69
 
74
70
  @property
75
71
  def acquisition_ids(self) -> list[int]:
76
72
  """Return the acquisition ids in the well."""
77
73
  acquisitions = []
78
- for images in self.well.images:
74
+ for images in self.images:
79
75
  if (
80
76
  images.acquisition is not None
81
77
  and images.acquisition not in acquisitions
@@ -85,7 +81,7 @@ class NgioWellMeta(CustomWellAttrs):
85
81
 
86
82
  def get_image_acquisition_id(self, image_path: str) -> int | None:
87
83
  """Return the acquisition id for the given image path."""
88
- for images in self.well.images:
84
+ for images in self.images:
89
85
  if images.path == image_path:
90
86
  return images.acquisition
91
87
  raise NgioValueError(f"Image at path {image_path} not found in the well.")
@@ -100,11 +96,9 @@ class NgioWellMeta(CustomWellAttrs):
100
96
  acquisition (int | None): The acquisition id to filter the images.
101
97
  """
102
98
  if acquisition is None:
103
- return [images.path for images in self.well.images]
99
+ return [images.path for images in self.images]
104
100
  return [
105
- images.path
106
- for images in self.well.images
107
- if images.acquisition == acquisition
101
+ images.path for images in self.images if images.acquisition == acquisition
108
102
  ]
109
103
 
110
104
  def add_image(
@@ -118,7 +112,7 @@ class NgioWellMeta(CustomWellAttrs):
118
112
  strict (bool): If True, check if the image already exists in the well.
119
113
  If False, do not check if the image already exists in the well.
120
114
  """
121
- list_of_images = self.well.images
115
+ list_of_images = self.images
122
116
  for image in list_of_images:
123
117
  if image.path == path:
124
118
  raise NgioValueError(
@@ -137,9 +131,7 @@ class NgioWellMeta(CustomWellAttrs):
137
131
 
138
132
  new_image = CustomWellImage(path=path, acquisition=acquisition)
139
133
  list_of_images.append(new_image)
140
- return NgioWellMeta(
141
- well=CustomWellMeta(images=list_of_images, version=self.well.version)
142
- )
134
+ return NgioWellMeta(images=list_of_images, version=self.version)
143
135
 
144
136
  def remove_image(self, path: str) -> "NgioWellMeta":
145
137
  """Remove an image from the well.
@@ -147,15 +139,11 @@ class NgioWellMeta(CustomWellAttrs):
147
139
  Args:
148
140
  path (str): The path of the image.
149
141
  """
150
- list_of_images = self.well.images
142
+ list_of_images = self.images
151
143
  for image in list_of_images:
152
144
  if image.path == path:
153
145
  list_of_images.remove(image)
154
- return NgioWellMeta(
155
- well=CustomWellMeta(
156
- images=list_of_images, version=self.well.version
157
- )
158
- )
146
+ return NgioWellMeta(images=list_of_images, version=self.version)
159
147
  raise NgioValueError(f"Image at path {path} not found in the well.")
160
148
 
161
149
 
@@ -218,26 +206,30 @@ def _relabel_wells(
218
206
  return new_wells
219
207
 
220
208
 
221
- class NgioPlateMeta(HCSAttrs):
209
+ class NgioPlateMeta(BaseModel):
222
210
  """HCS plate metadata."""
223
211
 
212
+ plate: PlateWithVersion
213
+ version: NgffVersions
214
+
224
215
  @classmethod
225
216
  def default_init(
226
217
  cls,
227
218
  images: list[ImageInWellPath] | None = None,
228
219
  name: str | None = None,
229
- version: NgffVersions | None = None,
220
+ version: NgffVersions = DefaultNgffVersion,
230
221
  ) -> "NgioPlateMeta":
231
222
  plate = cls(
232
- plate=Plate(
223
+ plate=PlateWithVersion(
233
224
  rows=[],
234
225
  columns=[],
235
226
  acquisitions=None,
236
227
  wells=[],
237
228
  field_count=None,
238
- version=version,
239
229
  name=name,
240
- )
230
+ version=version,
231
+ ),
232
+ version=version,
241
233
  )
242
234
 
243
235
  if images is None:
@@ -346,16 +338,16 @@ class NgioPlateMeta(HCSAttrs):
346
338
  else:
347
339
  wells = self.plate.wells
348
340
 
349
- new_plate = Plate(
341
+ new_plate = PlateWithVersion(
350
342
  rows=rows,
351
343
  columns=self.plate.columns,
352
344
  acquisitions=self.plate.acquisitions,
353
345
  wells=wells,
354
346
  field_count=self.plate.field_count,
355
347
  name=self.plate.name,
356
- version=self.plate.version,
348
+ version=self.version,
357
349
  )
358
- return NgioPlateMeta(plate=new_plate), row_idx
350
+ return NgioPlateMeta(plate=new_plate, version=self.version), row_idx
359
351
 
360
352
  def add_column(self, column: str | int) -> "tuple[NgioPlateMeta, int]":
361
353
  """Add a column to the plate.
@@ -384,16 +376,16 @@ class NgioPlateMeta(HCSAttrs):
384
376
  else:
385
377
  wells = self.plate.wells
386
378
 
387
- new_plate = Plate(
379
+ new_plate = PlateWithVersion(
388
380
  rows=self.plate.rows,
389
381
  columns=columns,
390
382
  acquisitions=self.plate.acquisitions,
391
383
  wells=wells,
392
384
  field_count=self.plate.field_count,
393
385
  name=self.plate.name,
394
- version=self.plate.version,
386
+ version=self.version,
395
387
  )
396
- return NgioPlateMeta(plate=new_plate), column_idx
388
+ return NgioPlateMeta(plate=new_plate, version=self.version), column_idx
397
389
 
398
390
  def add_well(
399
391
  self,
@@ -422,16 +414,16 @@ class NgioPlateMeta(HCSAttrs):
422
414
  )
423
415
  )
424
416
 
425
- new_plate = Plate(
417
+ new_plate = PlateWithVersion(
426
418
  rows=plate.plate.rows,
427
419
  columns=plate.plate.columns,
428
420
  acquisitions=plate.plate.acquisitions,
429
421
  wells=wells,
430
422
  field_count=plate.plate.field_count,
431
423
  name=plate.plate.name,
432
- version=plate.plate.version,
424
+ version=plate.version,
433
425
  )
434
- return NgioPlateMeta(plate=new_plate)
426
+ return NgioPlateMeta(plate=new_plate, version=plate.version)
435
427
 
436
428
  def add_acquisition(
437
429
  self,
@@ -461,16 +453,16 @@ class NgioPlateMeta(HCSAttrs):
461
453
  Acquisition(id=acquisition_id, name=acquisition_name, **acquisition_kwargs)
462
454
  )
463
455
 
464
- new_plate = Plate(
456
+ new_plate = PlateWithVersion(
465
457
  rows=self.plate.rows,
466
458
  columns=self.plate.columns,
467
459
  acquisitions=acquisitions,
468
460
  wells=self.plate.wells,
469
461
  field_count=self.plate.field_count,
470
462
  name=self.plate.name,
471
- version=self.plate.version,
463
+ version=self.version,
472
464
  )
473
- return NgioPlateMeta(plate=new_plate)
465
+ return NgioPlateMeta(plate=new_plate, version=self.version)
474
466
 
475
467
  def remove_well(self, row: str, column: str | int) -> "NgioPlateMeta":
476
468
  """Remove a well from the plate.
@@ -497,16 +489,16 @@ class NgioPlateMeta(HCSAttrs):
497
489
  f"Well at row {row} and column {column} not found in the plate."
498
490
  )
499
491
 
500
- new_plate = Plate(
492
+ new_plate = PlateWithVersion(
501
493
  rows=self.plate.rows,
502
494
  columns=self.plate.columns,
503
495
  acquisitions=self.plate.acquisitions,
504
496
  wells=wells,
505
497
  field_count=self.plate.field_count,
506
498
  name=self.plate.name,
507
- version=self.plate.version,
499
+ version=self.version,
508
500
  )
509
- return NgioPlateMeta(plate=new_plate)
501
+ return NgioPlateMeta(plate=new_plate, version=self.version)
510
502
 
511
503
  def derive(
512
504
  self,
@@ -531,16 +523,17 @@ class NgioPlateMeta(HCSAttrs):
531
523
  acquisitions = None
532
524
 
533
525
  if version is None:
534
- version = self.plate.version # type: ignore (version is NgffVersions or None)
526
+ version = self.version
535
527
 
536
528
  return NgioPlateMeta(
537
- plate=Plate(
529
+ plate=PlateWithVersion(
538
530
  rows=rows,
539
531
  columns=columns,
540
532
  acquisitions=acquisitions,
541
533
  wells=[],
542
534
  field_count=self.plate.field_count,
543
- version=version,
544
535
  name=name,
545
- )
536
+ version=version,
537
+ ),
538
+ version=version,
546
539
  )
@@ -13,11 +13,11 @@ import numpy as np
13
13
  from pydantic import BaseModel
14
14
 
15
15
  from ngio.ome_zarr_meta.ngio_specs._axes import (
16
+ AxesHandler,
16
17
  DefaultSpaceUnit,
17
18
  DefaultTimeUnit,
18
19
  SpaceUnits,
19
20
  TimeUnits,
20
- build_canonical_axes_handler,
21
21
  )
22
22
  from ngio.ome_zarr_meta.ngio_specs._channels import ChannelsMeta
23
23
  from ngio.ome_zarr_meta.ngio_specs._dataset import Dataset
@@ -66,42 +66,23 @@ class AbstractNgioImageMeta:
66
66
  @classmethod
67
67
  def default_init(
68
68
  cls,
69
- levels: int | Sequence[str],
70
- axes_names: Sequence[str],
71
- pixel_size: PixelSize,
72
- scaling_factors: Sequence[float] | None = None,
69
+ levels: Sequence[str],
70
+ axes_handler: AxesHandler,
71
+ scales: Sequence[tuple[float, ...]],
72
+ translations: Sequence[tuple[float, ...] | None],
73
73
  name: str | None = None,
74
74
  version: NgffVersions = DefaultNgffVersion,
75
75
  ):
76
76
  """Initialize the ImageMeta object."""
77
- axes_handler = build_canonical_axes_handler(
78
- axes_names,
79
- space_units=pixel_size.space_unit,
80
- time_units=pixel_size.time_unit,
81
- )
82
-
83
- px_size_dict = pixel_size.as_dict()
84
- scale = [px_size_dict.get(name, 1.0) for name in axes_handler.axes_names]
85
-
86
- if scaling_factors is None:
87
- _default = {"x": 2.0, "y": 2.0}
88
- scaling_factors = [
89
- _default.get(name, 1.0) for name in axes_handler.axes_names
90
- ]
91
-
92
- if isinstance(levels, int):
93
- levels = [str(i) for i in range(levels)]
94
-
95
77
  datasets = []
96
- for level in levels:
78
+ for level, scale, translation in zip(levels, scales, translations, strict=True):
97
79
  dataset = Dataset(
98
80
  path=level,
99
81
  axes_handler=axes_handler,
100
82
  scale=scale,
101
- translation=None,
83
+ translation=translation,
102
84
  )
103
85
  datasets.append(dataset)
104
- scale = [s * f for s, f in zip(scale, scaling_factors, strict=True)]
105
86
 
106
87
  return cls(
107
88
  version=version,
@@ -337,50 +318,15 @@ class AbstractNgioImageMeta:
337
318
  )
338
319
  return dataset, lr_dataset
339
320
 
340
- def scaling_factor(self, path: str | None = None) -> list[float]:
341
- """Get the scaling factors from a dataset to its lower resolution."""
342
- if self.levels == 1:
343
- return [1.0] * len(self.axes_handler.axes_names)
344
- dataset, lr_dataset = self._get_closest_datasets(path=path)
345
-
346
- scaling_factors = []
347
- for ax_name in self.axes_handler.axes_names:
348
- s_d = dataset.get_scale(ax_name)
349
- s_lr_d = lr_dataset.get_scale(ax_name)
350
- scaling_factors.append(s_lr_d / s_d)
351
- return scaling_factors
352
-
353
- def yx_scaling(self, path: str | None = None) -> tuple[float, float]:
354
- """Get the scaling factor from a dataset to its lower resolution."""
355
- if self.levels == 1:
356
- return 1.0, 1.0
357
- dataset, lr_dataset = self._get_closest_datasets(path=path)
358
-
359
- if lr_dataset is None:
360
- raise NgioValueError(
361
- "No lower resolution dataset found. "
362
- "This is the lowest resolution dataset."
363
- )
364
-
365
- s_d = dataset.get_scale("y")
366
- s_lr_d = lr_dataset.get_scale("y")
367
- scale_y = s_lr_d / s_d
368
-
369
- s_d = dataset.get_scale("x")
370
- s_lr_d = lr_dataset.get_scale("x")
371
- scale_x = s_lr_d / s_d
372
-
373
- return scale_y, scale_x
374
-
375
- def z_scaling(self, path: str | None = None) -> float:
376
- """Get the scaling factor from a dataset to its lower resolution."""
321
+ def scaling_factor(self, path: str | None = None) -> tuple[float, ...]:
322
+ """Get the scaling factors to downscale to the next lower resolution dataset."""
377
323
  if self.levels == 1:
378
- return 1.0
324
+ return (1.0,) * len(self.axes_handler.axes_names)
379
325
  dataset, lr_dataset = self._get_closest_datasets(path=path)
380
-
381
- s_d = dataset.get_scale("z", default=1.0)
382
- s_lr_d = lr_dataset.get_scale("z", default=1.0)
383
- return s_lr_d / s_d
326
+ scale = dataset.scale
327
+ lr_scale = lr_dataset.scale
328
+ scaling_factors = [s / s_lr for s_lr, s in zip(scale, lr_scale, strict=True)]
329
+ return tuple(scaling_factors)
384
330
 
385
331
 
386
332
  class NgioLabelMeta(AbstractNgioImageMeta):
@@ -1,6 +1,6 @@
1
1
  """Utility to read/write OME-Zarr metadata v0.4."""
2
2
 
3
- from ngio.ome_zarr_meta.v04._v04_spec_utils import (
3
+ from ngio.ome_zarr_meta.v04._v04_spec import (
4
4
  ngio_to_v04_image_meta,
5
5
  ngio_to_v04_label_meta,
6
6
  ngio_to_v04_plate_meta,
@@ -23,7 +23,6 @@ from ome_zarr_models.v04.multiscales import ValidTransform as ValidTransformV04
23
23
  from ome_zarr_models.v04.omero import Channel as ChannelV04
24
24
  from ome_zarr_models.v04.omero import Omero as OmeroV04
25
25
  from ome_zarr_models.v04.omero import Window as WindowV04
26
- from pydantic import ValidationError
27
26
 
28
27
  from ngio.ome_zarr_meta.ngio_specs import (
29
28
  AxesHandler,
@@ -44,37 +43,6 @@ from ngio.ome_zarr_meta.ngio_specs import (
44
43
  from ngio.ome_zarr_meta.v04._custom_models import CustomWellAttrs as WellAttrsV04
45
44
 
46
45
 
47
- def _is_v04_image_meta(metadata: dict) -> ImageAttrsV04 | ValidationError:
48
- """Check if the metadata is a valid OME-Zarr v04 metadata.
49
-
50
- Args:
51
- metadata (dict): The metadata to check.
52
-
53
- Returns:
54
- bool: True if the metadata is a valid OME-Zarr v04 metadata, False otherwise.
55
- """
56
- try:
57
- return ImageAttrsV04(**metadata)
58
- except ValidationError as e:
59
- return e
60
-
61
-
62
- def _is_v04_label_meta(metadata: dict) -> LabelAttrsV04 | ValidationError:
63
- """Check if the metadata is a valid OME-Zarr v04 metadata.
64
-
65
- Args:
66
- metadata (dict): The metadata to check.
67
-
68
- Returns:
69
- bool: True if the metadata is a valid OME-Zarr v04 metadata, False otherwise.
70
- """
71
- try:
72
- return LabelAttrsV04(**metadata)
73
- except ValidationError as e:
74
- return e
75
- raise RuntimeError("Unreachable code")
76
-
77
-
78
46
  def _v04_omero_to_channels(v04_omero: OmeroV04 | None) -> ChannelsMeta | None:
79
47
  if v04_omero is None:
80
48
  return None
@@ -203,7 +171,7 @@ def v04_to_ngio_image_meta(
203
171
  axes_setup: AxesSetup | None = None,
204
172
  allow_non_canonical_axes: bool = False,
205
173
  strict_canonical_order: bool = True,
206
- ) -> tuple[bool, NgioImageMeta | ValidationError]:
174
+ ) -> NgioImageMeta:
207
175
  """Convert a v04 image metadata to a ngio image metadata.
208
176
 
209
177
  Args:
@@ -216,9 +184,7 @@ def v04_to_ngio_image_meta(
216
184
  Returns:
217
185
  NgioImageMeta: The ngio image metadata.
218
186
  """
219
- v04_image = _is_v04_image_meta(metadata)
220
- if isinstance(v04_image, ValidationError):
221
- return False, v04_image
187
+ v04_image = ImageAttrsV04(**metadata)
222
188
 
223
189
  if len(v04_image.multiscales) > 1:
224
190
  raise NotImplementedError(
@@ -239,7 +205,7 @@ def v04_to_ngio_image_meta(
239
205
  name = v04_muliscale.name
240
206
  if name is not None and not isinstance(name, str):
241
207
  name = str(name)
242
- return True, NgioImageMeta(
208
+ return NgioImageMeta(
243
209
  version="0.4",
244
210
  name=name,
245
211
  datasets=datasets,
@@ -252,7 +218,7 @@ def v04_to_ngio_label_meta(
252
218
  axes_setup: AxesSetup | None = None,
253
219
  allow_non_canonical_axes: bool = False,
254
220
  strict_canonical_order: bool = True,
255
- ) -> tuple[bool, NgioLabelMeta | ValidationError]:
221
+ ) -> NgioLabelMeta:
256
222
  """Convert a v04 image metadata to a ngio image metadata.
257
223
 
258
224
  Args:
@@ -265,9 +231,7 @@ def v04_to_ngio_label_meta(
265
231
  Returns:
266
232
  NgioImageMeta: The ngio image metadata.
267
233
  """
268
- v04_label = _is_v04_label_meta(metadata)
269
- if isinstance(v04_label, ValidationError):
270
- return False, v04_label
234
+ v04_label = LabelAttrsV04(**metadata)
271
235
 
272
236
  if len(v04_label.multiscales) > 1:
273
237
  raise NotImplementedError(
@@ -301,7 +265,7 @@ def v04_to_ngio_label_meta(
301
265
  if name is not None and not isinstance(name, str):
302
266
  name = str(name)
303
267
 
304
- return True, NgioLabelMeta(
268
+ return NgioLabelMeta(
305
269
  version="0.4",
306
270
  name=name,
307
271
  datasets=datasets,
@@ -423,42 +387,33 @@ def ngio_to_v04_label_meta(metadata: NgioLabelMeta) -> dict:
423
387
 
424
388
  def v04_to_ngio_well_meta(
425
389
  metadata: dict,
426
- ) -> tuple[bool, NgioWellMeta | ValidationError]:
390
+ ) -> NgioWellMeta:
427
391
  """Convert a v04 well metadata to a ngio well metadata.
428
392
 
429
393
  Args:
430
394
  metadata (dict): The v04 well metadata.
431
395
 
432
396
  Returns:
433
- result (bool): True if the conversion was successful, False otherwise.
434
- ngio_well_meta (NgioWellMeta): The ngio well metadata.
397
+ NgioWellMeta: The ngio well metadata.
435
398
  """
436
- try:
437
- v04_well = WellAttrsV04(**metadata)
438
- except ValidationError as e:
439
- return False, e
440
-
441
- return True, NgioWellMeta(**v04_well.model_dump())
399
+ v04_well = WellAttrsV04(**metadata).well.model_dump()
400
+ images = v04_well.get("images", [])
401
+ return NgioWellMeta(images=images, version="0.4")
442
402
 
443
403
 
444
404
  def v04_to_ngio_plate_meta(
445
405
  metadata: dict,
446
- ) -> tuple[bool, NgioPlateMeta | ValidationError]:
406
+ ) -> NgioPlateMeta:
447
407
  """Convert a v04 plate metadata to a ngio plate metadata.
448
408
 
449
409
  Args:
450
410
  metadata (dict): The v04 plate metadata.
451
411
 
452
412
  Returns:
453
- result (bool): True if the conversion was successful, False otherwise.
454
- ngio_plate_meta (NgioPlateMeta): The ngio plate metadata.
413
+ NgioPlateMeta: The ngio plate metadata.
455
414
  """
456
- try:
457
- v04_plate = HCSAttrsV04(**metadata)
458
- except ValidationError as e:
459
- return False, e
460
-
461
- return True, NgioPlateMeta(**v04_plate.model_dump())
415
+ v04_plate = HCSAttrsV04(**metadata).plate.model_dump()
416
+ return NgioPlateMeta(plate=v04_plate, version="0.4") # type: ignore
462
417
 
463
418
 
464
419
  def ngio_to_v04_well_meta(metadata: NgioWellMeta) -> dict:
@@ -470,7 +425,7 @@ def ngio_to_v04_well_meta(metadata: NgioWellMeta) -> dict:
470
425
  Returns:
471
426
  dict: The v04 well metadata.
472
427
  """
473
- v04_well = WellAttrsV04(**metadata.model_dump())
428
+ v04_well = WellAttrsV04(well=metadata.model_dump()) # type: ignore
474
429
  return v04_well.model_dump(exclude_none=True, by_alias=True)
475
430
 
476
431
 
@@ -1,6 +1,6 @@
1
1
  """Utility to read/write OME-Zarr metadata v0.4."""
2
2
 
3
- from ngio.ome_zarr_meta.v05._v05_spec_utils import (
3
+ from ngio.ome_zarr_meta.v05._v05_spec import (
4
4
  ngio_to_v05_image_meta,
5
5
  ngio_to_v05_label_meta,
6
6
  ngio_to_v05_plate_meta,