ngio 0.5.0a2__py3-none-any.whl → 0.5.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.
Files changed (49) 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 +206 -76
  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 +50 -43
  9. ngio/images/_abstract_image.py +418 -35
  10. ngio/images/_create_synt_container.py +35 -42
  11. ngio/images/_create_utils.py +423 -0
  12. ngio/images/_image.py +162 -176
  13. ngio/images/_label.py +182 -137
  14. ngio/images/_ome_zarr_container.py +372 -197
  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 +21 -18
  22. ngio/ome_zarr_meta/_meta_handlers.py +409 -701
  23. ngio/ome_zarr_meta/ngio_specs/__init__.py +2 -0
  24. ngio/ome_zarr_meta/ngio_specs/_axes.py +1 -0
  25. ngio/ome_zarr_meta/ngio_specs/_dataset.py +13 -22
  26. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +54 -61
  27. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +21 -68
  28. ngio/ome_zarr_meta/v04/__init__.py +5 -1
  29. ngio/ome_zarr_meta/v04/{_v04_spec_utils.py → _v04_spec.py} +49 -63
  30. ngio/ome_zarr_meta/v05/__init__.py +5 -1
  31. ngio/ome_zarr_meta/v05/{_v05_spec_utils.py → _v05_spec.py} +57 -64
  32. ngio/tables/_tables_container.py +2 -4
  33. ngio/tables/backends/_anndata.py +58 -8
  34. ngio/tables/backends/_anndata_utils.py +1 -6
  35. ngio/tables/backends/_csv.py +3 -19
  36. ngio/tables/backends/_json.py +10 -13
  37. ngio/tables/backends/_parquet.py +3 -31
  38. ngio/tables/backends/_py_arrow_backends.py +222 -0
  39. ngio/tables/v1/_roi_table.py +41 -24
  40. ngio/utils/__init__.py +4 -12
  41. ngio/utils/_zarr_utils.py +163 -53
  42. {ngio-0.5.0a2.dist-info → ngio-0.5.0b1.dist-info}/METADATA +6 -2
  43. ngio-0.5.0b1.dist-info/RECORD +88 -0
  44. {ngio-0.5.0a2.dist-info → ngio-0.5.0b1.dist-info}/WHEEL +1 -1
  45. ngio/images/_create.py +0 -287
  46. ngio/tables/backends/_non_zarr_backends.py +0 -196
  47. ngio/utils/_logger.py +0 -50
  48. ngio-0.5.0a2.dist-info/RECORD +0 -89
  49. {ngio-0.5.0a2.dist-info → ngio-0.5.0b1.dist-info}/licenses/LICENSE +0 -0
@@ -40,6 +40,7 @@ from ngio.ome_zarr_meta.ngio_specs._ngio_image import (
40
40
  NgioImageLabelMeta,
41
41
  NgioImageMeta,
42
42
  NgioLabelMeta,
43
+ NgioLabelsGroupMeta,
43
44
  )
44
45
  from ngio.ome_zarr_meta.ngio_specs._pixel_size import PixelSize
45
46
 
@@ -62,6 +63,7 @@ __all__ = [
62
63
  "NgioImageLabelMeta",
63
64
  "NgioImageMeta",
64
65
  "NgioLabelMeta",
66
+ "NgioLabelsGroupMeta",
65
67
  "NgioPlateMeta",
66
68
  "NgioWellMeta",
67
69
  "PixelSize",
@@ -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
@@ -41,6 +41,13 @@ class ImageLabelSource(BaseModel):
41
41
  return cls(version=version, source={"image": "../../"})
42
42
 
43
43
 
44
+ class NgioLabelsGroupMeta(BaseModel):
45
+ """Metadata model for the /labels group in OME-NGFF."""
46
+
47
+ version: NgffVersions
48
+ labels: list[str]
49
+
50
+
44
51
  class AbstractNgioImageMeta:
45
52
  """Base class for ImageMeta and LabelMeta."""
46
53
 
@@ -66,42 +73,23 @@ class AbstractNgioImageMeta:
66
73
  @classmethod
67
74
  def default_init(
68
75
  cls,
69
- levels: int | Sequence[str],
70
- axes_names: Sequence[str],
71
- pixel_size: PixelSize,
72
- scaling_factors: Sequence[float] | None = None,
76
+ levels: Sequence[str],
77
+ axes_handler: AxesHandler,
78
+ scales: Sequence[tuple[float, ...]],
79
+ translations: Sequence[tuple[float, ...] | None],
73
80
  name: str | None = None,
74
81
  version: NgffVersions = DefaultNgffVersion,
75
82
  ):
76
83
  """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
84
  datasets = []
96
- for level in levels:
85
+ for level, scale, translation in zip(levels, scales, translations, strict=True):
97
86
  dataset = Dataset(
98
87
  path=level,
99
88
  axes_handler=axes_handler,
100
89
  scale=scale,
101
- translation=None,
90
+ translation=translation,
102
91
  )
103
92
  datasets.append(dataset)
104
- scale = [s * f for s, f in zip(scale, scaling_factors, strict=True)]
105
93
 
106
94
  return cls(
107
95
  version=version,
@@ -337,50 +325,15 @@ class AbstractNgioImageMeta:
337
325
  )
338
326
  return dataset, lr_dataset
339
327
 
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."""
328
+ def scaling_factor(self, path: str | None = None) -> tuple[float, ...]:
329
+ """Get the scaling factors to downscale to the next lower resolution dataset."""
355
330
  if self.levels == 1:
356
- return 1.0, 1.0
331
+ return (1.0,) * len(self.axes_handler.axes_names)
357
332
  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."""
377
- if self.levels == 1:
378
- return 1.0
379
- 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
333
+ scale = dataset.scale
334
+ lr_scale = lr_dataset.scale
335
+ scaling_factors = [s / s_lr for s_lr, s in zip(scale, lr_scale, strict=True)]
336
+ return tuple(scaling_factors)
384
337
 
385
338
 
386
339
  class NgioLabelMeta(AbstractNgioImageMeta):
@@ -1,12 +1,14 @@
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
+ ngio_to_v04_labels_group_meta,
6
7
  ngio_to_v04_plate_meta,
7
8
  ngio_to_v04_well_meta,
8
9
  v04_to_ngio_image_meta,
9
10
  v04_to_ngio_label_meta,
11
+ v04_to_ngio_labels_group_meta,
10
12
  v04_to_ngio_plate_meta,
11
13
  v04_to_ngio_well_meta,
12
14
  )
@@ -14,10 +16,12 @@ from ngio.ome_zarr_meta.v04._v04_spec_utils import (
14
16
  __all__ = [
15
17
  "ngio_to_v04_image_meta",
16
18
  "ngio_to_v04_label_meta",
19
+ "ngio_to_v04_labels_group_meta",
17
20
  "ngio_to_v04_plate_meta",
18
21
  "ngio_to_v04_well_meta",
19
22
  "v04_to_ngio_image_meta",
20
23
  "v04_to_ngio_label_meta",
24
+ "v04_to_ngio_labels_group_meta",
21
25
  "v04_to_ngio_plate_meta",
22
26
  "v04_to_ngio_well_meta",
23
27
  ]