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
@@ -16,14 +16,14 @@ from ome_zarr_models.v04.coordinate_transformations import (
16
16
  )
17
17
  from ome_zarr_models.v04.hcs import HCSAttrs as HCSAttrsV04
18
18
  from ome_zarr_models.v04.image import ImageAttrs as ImageAttrsV04
19
- from ome_zarr_models.v04.image_label import ImageLabelAttrs as LabelAttrsV04
19
+ from ome_zarr_models.v04.image_label import ImageLabelAttrs as ImageLabelAttrsV04
20
+ from ome_zarr_models.v04.labels import LabelsAttrs as LabelsAttrsV04
20
21
  from ome_zarr_models.v04.multiscales import Dataset as DatasetV04
21
22
  from ome_zarr_models.v04.multiscales import Multiscale as MultiscaleV04
22
23
  from ome_zarr_models.v04.multiscales import ValidTransform as ValidTransformV04
23
24
  from ome_zarr_models.v04.omero import Channel as ChannelV04
24
25
  from ome_zarr_models.v04.omero import Omero as OmeroV04
25
26
  from ome_zarr_models.v04.omero import Window as WindowV04
26
- from pydantic import ValidationError
27
27
 
28
28
  from ngio.ome_zarr_meta.ngio_specs import (
29
29
  AxesHandler,
@@ -37,6 +37,7 @@ from ngio.ome_zarr_meta.ngio_specs import (
37
37
  ImageLabelSource,
38
38
  NgioImageMeta,
39
39
  NgioLabelMeta,
40
+ NgioLabelsGroupMeta,
40
41
  NgioPlateMeta,
41
42
  NgioWellMeta,
42
43
  default_channel_name,
@@ -44,37 +45,6 @@ from ngio.ome_zarr_meta.ngio_specs import (
44
45
  from ngio.ome_zarr_meta.v04._custom_models import CustomWellAttrs as WellAttrsV04
45
46
 
46
47
 
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
48
  def _v04_omero_to_channels(v04_omero: OmeroV04 | None) -> ChannelsMeta | None:
79
49
  if v04_omero is None:
80
50
  return None
@@ -203,7 +173,7 @@ def v04_to_ngio_image_meta(
203
173
  axes_setup: AxesSetup | None = None,
204
174
  allow_non_canonical_axes: bool = False,
205
175
  strict_canonical_order: bool = True,
206
- ) -> tuple[bool, NgioImageMeta | ValidationError]:
176
+ ) -> NgioImageMeta:
207
177
  """Convert a v04 image metadata to a ngio image metadata.
208
178
 
209
179
  Args:
@@ -216,9 +186,7 @@ def v04_to_ngio_image_meta(
216
186
  Returns:
217
187
  NgioImageMeta: The ngio image metadata.
218
188
  """
219
- v04_image = _is_v04_image_meta(metadata)
220
- if isinstance(v04_image, ValidationError):
221
- return False, v04_image
189
+ v04_image = ImageAttrsV04(**metadata)
222
190
 
223
191
  if len(v04_image.multiscales) > 1:
224
192
  raise NotImplementedError(
@@ -239,7 +207,7 @@ def v04_to_ngio_image_meta(
239
207
  name = v04_muliscale.name
240
208
  if name is not None and not isinstance(name, str):
241
209
  name = str(name)
242
- return True, NgioImageMeta(
210
+ return NgioImageMeta(
243
211
  version="0.4",
244
212
  name=name,
245
213
  datasets=datasets,
@@ -252,7 +220,7 @@ def v04_to_ngio_label_meta(
252
220
  axes_setup: AxesSetup | None = None,
253
221
  allow_non_canonical_axes: bool = False,
254
222
  strict_canonical_order: bool = True,
255
- ) -> tuple[bool, NgioLabelMeta | ValidationError]:
223
+ ) -> NgioLabelMeta:
256
224
  """Convert a v04 image metadata to a ngio image metadata.
257
225
 
258
226
  Args:
@@ -265,9 +233,7 @@ def v04_to_ngio_label_meta(
265
233
  Returns:
266
234
  NgioImageMeta: The ngio image metadata.
267
235
  """
268
- v04_label = _is_v04_label_meta(metadata)
269
- if isinstance(v04_label, ValidationError):
270
- return False, v04_label
236
+ v04_label = ImageLabelAttrsV04(**metadata)
271
237
 
272
238
  if len(v04_label.multiscales) > 1:
273
239
  raise NotImplementedError(
@@ -301,7 +267,7 @@ def v04_to_ngio_label_meta(
301
267
  if name is not None and not isinstance(name, str):
302
268
  name = str(name)
303
269
 
304
- return True, NgioLabelMeta(
270
+ return NgioLabelMeta(
305
271
  version="0.4",
306
272
  name=name,
307
273
  datasets=datasets,
@@ -417,48 +383,55 @@ def ngio_to_v04_label_meta(metadata: NgioLabelMeta) -> dict:
417
383
  "multiscales": [v04_muliscale],
418
384
  "image-label": metadata.image_label.model_dump(),
419
385
  }
420
- v04_label = LabelAttrsV04(**labels_meta)
386
+ v04_label = ImageLabelAttrsV04(**labels_meta)
421
387
  return v04_label.model_dump(exclude_none=True, by_alias=True)
422
388
 
423
389
 
390
+ def v04_to_ngio_labels_group_meta(
391
+ metadata: dict,
392
+ ) -> NgioLabelsGroupMeta:
393
+ """Convert a v04 label group metadata to a ngio label group metadata.
394
+
395
+ Args:
396
+ metadata (dict): The v04 label group metadata.
397
+
398
+ Returns:
399
+ NgioLabelGroupMeta: The ngio label group metadata.
400
+ """
401
+ v04_label_group = LabelsAttrsV04(**metadata).model_dump()
402
+ labels = v04_label_group.get("labels", [])
403
+ return NgioLabelsGroupMeta(labels=labels, version="0.4")
404
+
405
+
424
406
  def v04_to_ngio_well_meta(
425
407
  metadata: dict,
426
- ) -> tuple[bool, NgioWellMeta | ValidationError]:
408
+ ) -> NgioWellMeta:
427
409
  """Convert a v04 well metadata to a ngio well metadata.
428
410
 
429
411
  Args:
430
412
  metadata (dict): The v04 well metadata.
431
413
 
432
414
  Returns:
433
- result (bool): True if the conversion was successful, False otherwise.
434
- ngio_well_meta (NgioWellMeta): The ngio well metadata.
415
+ NgioWellMeta: The ngio well metadata.
435
416
  """
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())
417
+ v04_well = WellAttrsV04(**metadata).well.model_dump()
418
+ images = v04_well.get("images", [])
419
+ return NgioWellMeta(images=images, version="0.4")
442
420
 
443
421
 
444
422
  def v04_to_ngio_plate_meta(
445
423
  metadata: dict,
446
- ) -> tuple[bool, NgioPlateMeta | ValidationError]:
424
+ ) -> NgioPlateMeta:
447
425
  """Convert a v04 plate metadata to a ngio plate metadata.
448
426
 
449
427
  Args:
450
428
  metadata (dict): The v04 plate metadata.
451
429
 
452
430
  Returns:
453
- result (bool): True if the conversion was successful, False otherwise.
454
- ngio_plate_meta (NgioPlateMeta): The ngio plate metadata.
431
+ NgioPlateMeta: The ngio plate metadata.
455
432
  """
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())
433
+ v04_plate = HCSAttrsV04(**metadata).plate.model_dump()
434
+ return NgioPlateMeta(plate=v04_plate, version="0.4") # type: ignore
462
435
 
463
436
 
464
437
  def ngio_to_v04_well_meta(metadata: NgioWellMeta) -> dict:
@@ -470,7 +443,7 @@ def ngio_to_v04_well_meta(metadata: NgioWellMeta) -> dict:
470
443
  Returns:
471
444
  dict: The v04 well metadata.
472
445
  """
473
- v04_well = WellAttrsV04(**metadata.model_dump())
446
+ v04_well = WellAttrsV04(well=metadata.model_dump()) # type: ignore
474
447
  return v04_well.model_dump(exclude_none=True, by_alias=True)
475
448
 
476
449
 
@@ -485,3 +458,16 @@ def ngio_to_v04_plate_meta(metadata: NgioPlateMeta) -> dict:
485
458
  """
486
459
  v04_plate = HCSAttrsV04(**metadata.model_dump())
487
460
  return v04_plate.model_dump(exclude_none=True, by_alias=True)
461
+
462
+
463
+ def ngio_to_v04_labels_group_meta(metadata: NgioLabelsGroupMeta) -> dict:
464
+ """Convert a ngio label group metadata to a v04 label group metadata.
465
+
466
+ Args:
467
+ metadata (NgioLabelsGroupMeta): The ngio label group metadata.
468
+
469
+ Returns:
470
+ dict: The v04 label group metadata.
471
+ """
472
+ v04_label_group = LabelsAttrsV04(labels=metadata.labels)
473
+ return v04_label_group.model_dump(exclude_none=True, by_alias=True)
@@ -1,12 +1,14 @@
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
+ ngio_to_v05_labels_group_meta,
6
7
  ngio_to_v05_plate_meta,
7
8
  ngio_to_v05_well_meta,
8
9
  v05_to_ngio_image_meta,
9
10
  v05_to_ngio_label_meta,
11
+ v05_to_ngio_labels_group_meta,
10
12
  v05_to_ngio_plate_meta,
11
13
  v05_to_ngio_well_meta,
12
14
  )
@@ -14,10 +16,12 @@ from ngio.ome_zarr_meta.v05._v05_spec_utils import (
14
16
  __all__ = [
15
17
  "ngio_to_v05_image_meta",
16
18
  "ngio_to_v05_label_meta",
19
+ "ngio_to_v05_labels_group_meta",
17
20
  "ngio_to_v05_plate_meta",
18
21
  "ngio_to_v05_well_meta",
19
22
  "v05_to_ngio_image_meta",
20
23
  "v05_to_ngio_label_meta",
24
+ "v05_to_ngio_labels_group_meta",
21
25
  "v05_to_ngio_plate_meta",
22
26
  "v05_to_ngio_well_meta",
23
27
  ]
@@ -19,11 +19,13 @@ from ome_zarr_models.v05.coordinate_transformations import (
19
19
  )
20
20
  from ome_zarr_models.v05.hcs import HCSAttrs as HCSAttrsV05
21
21
  from ome_zarr_models.v05.image import ImageAttrs as ImageAttrsV05
22
- from ome_zarr_models.v05.image_label import ImageLabelAttrs as LabelAttrsV05
22
+ from ome_zarr_models.v05.image_label import ImageLabelAttrs as ImageLabelAttrsV05
23
+ from ome_zarr_models.v05.labels import Labels as Labels
24
+ from ome_zarr_models.v05.labels import LabelsAttrs as LabelsAttrsV05
23
25
  from ome_zarr_models.v05.multiscales import Dataset as DatasetV05
24
26
  from ome_zarr_models.v05.multiscales import Multiscale as MultiscaleV05
25
27
  from ome_zarr_models.v05.multiscales import ValidTransform as ValidTransformV05
26
- from pydantic import BaseModel, ValidationError
28
+ from pydantic import BaseModel
27
29
 
28
30
  from ngio.ome_zarr_meta.ngio_specs import (
29
31
  AxesHandler,
@@ -37,6 +39,7 @@ from ngio.ome_zarr_meta.ngio_specs import (
37
39
  ImageLabelSource,
38
40
  NgioImageMeta,
39
41
  NgioLabelMeta,
42
+ NgioLabelsGroupMeta,
40
43
  NgioPlateMeta,
41
44
  NgioWellMeta,
42
45
  default_channel_name,
@@ -53,37 +56,7 @@ class ImageV05WithOmero(BaseModel):
53
56
 
54
57
 
55
58
  class ImageLabelV05(BaseModel):
56
- ome: LabelAttrsV05
57
-
58
-
59
- def _is_v05_image_meta(metadata: dict) -> ImageV05WithOmero | ValidationError:
60
- """Check if the metadata is a valid OME-Zarr v05 metadata.
61
-
62
- Args:
63
- metadata (dict): The metadata to check.
64
-
65
- Returns:
66
- bool: True if the metadata is a valid OME-Zarr v05 metadata, False otherwise.
67
- """
68
- try:
69
- return ImageV05WithOmero(**metadata)
70
- except ValidationError as e:
71
- return e
72
-
73
-
74
- def _is_v05_label_meta(metadata: dict) -> ImageLabelV05 | ValidationError:
75
- """Check if the metadata is a valid OME-Zarr v05 metadata.
76
-
77
- Args:
78
- metadata (dict): The metadata to check.
79
-
80
- Returns:
81
- bool: True if the metadata is a valid OME-Zarr v05 metadata, False otherwise.
82
- """
83
- try:
84
- return ImageLabelV05(**metadata)
85
- except ValidationError as e:
86
- return e
59
+ ome: ImageLabelAttrsV05
87
60
 
88
61
 
89
62
  def _v05_omero_to_channels(v05_omero: OmeroV05 | None) -> ChannelsMeta | None:
@@ -214,7 +187,7 @@ def v05_to_ngio_image_meta(
214
187
  axes_setup: AxesSetup | None = None,
215
188
  allow_non_canonical_axes: bool = False,
216
189
  strict_canonical_order: bool = True,
217
- ) -> tuple[bool, NgioImageMeta | ValidationError]:
190
+ ) -> NgioImageMeta:
218
191
  """Convert a v05 image metadata to a ngio image metadata.
219
192
 
220
193
  Args:
@@ -227,9 +200,7 @@ def v05_to_ngio_image_meta(
227
200
  Returns:
228
201
  NgioImageMeta: The ngio image metadata.
229
202
  """
230
- v05_image = _is_v05_image_meta(metadata)
231
- if isinstance(v05_image, ValidationError):
232
- return False, v05_image
203
+ v05_image = ImageV05WithOmero(**metadata)
233
204
  v05_image = v05_image.ome
234
205
  if len(v05_image.multiscales) > 1:
235
206
  raise NotImplementedError(
@@ -250,7 +221,7 @@ def v05_to_ngio_image_meta(
250
221
  name = v05_multiscale.name
251
222
  if name is not None and not isinstance(name, str):
252
223
  name = str(name)
253
- return True, NgioImageMeta(
224
+ return NgioImageMeta(
254
225
  version="0.5",
255
226
  name=name,
256
227
  datasets=datasets,
@@ -263,7 +234,7 @@ def v05_to_ngio_label_meta(
263
234
  axes_setup: AxesSetup | None = None,
264
235
  allow_non_canonical_axes: bool = False,
265
236
  strict_canonical_order: bool = True,
266
- ) -> tuple[bool, NgioLabelMeta | ValidationError]:
237
+ ) -> NgioLabelMeta:
267
238
  """Convert a v05 image metadata to a ngio image metadata.
268
239
 
269
240
  Args:
@@ -274,11 +245,9 @@ def v05_to_ngio_label_meta(
274
245
  strict_canonical_order (bool, optional): Strict canonical order.
275
246
 
276
247
  Returns:
277
- NgioImageMeta: The ngio image metadata.
248
+ NgioLabelMeta: The ngio label metadata.
278
249
  """
279
- v05_label = _is_v05_label_meta(metadata)
280
- if isinstance(v05_label, ValidationError):
281
- return False, v05_label
250
+ v05_label = ImageLabelV05(**metadata)
282
251
  v05_label = v05_label.ome
283
252
 
284
253
  if len(v05_label.multiscales) > 1:
@@ -316,7 +285,7 @@ def v05_to_ngio_label_meta(
316
285
  if name is not None and not isinstance(name, str):
317
286
  name = str(name)
318
287
 
319
- return True, NgioLabelMeta(
288
+ return NgioLabelMeta(
320
289
  version="0.5",
321
290
  name=name,
322
291
  datasets=datasets,
@@ -435,7 +404,7 @@ def ngio_to_v05_label_meta(metadata: NgioLabelMeta) -> dict:
435
404
  "multiscales": [v05_muliscale],
436
405
  "image-label": metadata.image_label.model_dump(),
437
406
  }
438
- v05_label = LabelAttrsV05(**labels_meta, version="0.5")
407
+ v05_label = ImageLabelAttrsV05(**labels_meta, version="0.5")
439
408
  v05_label = ImageLabelV05(
440
409
  ome=v05_label,
441
410
  )
@@ -452,42 +421,33 @@ class HCSV05(BaseModel):
452
421
 
453
422
  def v05_to_ngio_well_meta(
454
423
  metadata: dict,
455
- ) -> tuple[bool, NgioWellMeta | ValidationError]:
424
+ ) -> NgioWellMeta:
456
425
  """Convert a v05 well metadata to a ngio well metadata.
457
426
 
458
427
  Args:
459
428
  metadata (dict): The v05 well metadata.
460
429
 
461
430
  Returns:
462
- result (bool): True if the conversion was successful, False otherwise.
463
- ngio_well_meta (NgioWellMeta): The ngio well metadata.
431
+ NgioWellMeta: The ngio well metadata.
464
432
  """
465
- try:
466
- v05_well = WellV05(**metadata)
467
- except ValidationError as e:
468
- return False, e
469
-
470
- return True, NgioWellMeta(**v05_well.ome.model_dump())
433
+ v05_well = WellV05(**metadata).ome.well.model_dump()
434
+ images = v05_well.get("images", [])
435
+ return NgioWellMeta(images=images, version="0.5")
471
436
 
472
437
 
473
438
  def v05_to_ngio_plate_meta(
474
439
  metadata: dict,
475
- ) -> tuple[bool, NgioPlateMeta | ValidationError]:
440
+ ) -> NgioPlateMeta:
476
441
  """Convert a v05 plate metadata to a ngio plate metadata.
477
442
 
478
443
  Args:
479
444
  metadata (dict): The v05 plate metadata.
480
445
 
481
446
  Returns:
482
- result (bool): True if the conversion was successful, False otherwise.
483
- ngio_plate_meta (NgioPlateMeta): The ngio plate metadata.
447
+ NgioPlateMeta: The ngio plate metadata.
484
448
  """
485
- try:
486
- v05_plate = HCSV05(**metadata)
487
- except ValidationError as e:
488
- return False, e
489
-
490
- return True, NgioPlateMeta(**v05_plate.ome.model_dump())
449
+ v05_plate = HCSV05(**metadata).ome.plate.model_dump()
450
+ return NgioPlateMeta(plate=v05_plate, version="0.5") # type: ignore
491
451
 
492
452
 
493
453
  def ngio_to_v05_well_meta(metadata: NgioWellMeta) -> dict:
@@ -499,7 +459,7 @@ def ngio_to_v05_well_meta(metadata: NgioWellMeta) -> dict:
499
459
  Returns:
500
460
  dict: The v05 well metadata.
501
461
  """
502
- v05_well = WellAttrsV05(**metadata.model_dump())
462
+ v05_well = WellAttrsV05(well=metadata.model_dump()) # type: ignore
503
463
  v05_well = WellV05(ome=v05_well)
504
464
  return v05_well.model_dump(exclude_none=True, by_alias=True)
505
465
 
@@ -516,3 +476,36 @@ def ngio_to_v05_plate_meta(metadata: NgioPlateMeta) -> dict:
516
476
  v05_plate = HCSAttrsV05(**metadata.model_dump())
517
477
  v05_plate = HCSV05(ome=v05_plate)
518
478
  return v05_plate.model_dump(exclude_none=True, by_alias=True)
479
+
480
+
481
+ class LabelsV05(BaseModel):
482
+ ome: LabelsAttrsV05
483
+
484
+
485
+ def v05_to_ngio_labels_group_meta(
486
+ metadata: dict,
487
+ ) -> NgioLabelsGroupMeta:
488
+ """Convert a v04 label group metadata to a ngio label group metadata.
489
+
490
+ Args:
491
+ metadata (dict): The v04 label group metadata.
492
+
493
+ Returns:
494
+ NgioLabelGroupMeta: The ngio label group metadata.
495
+ """
496
+ v05_label_group = LabelsV05(**metadata)
497
+ return NgioLabelsGroupMeta(labels=v05_label_group.ome.labels, version="0.5")
498
+
499
+
500
+ def ngio_to_v05_labels_group_meta(metadata: NgioLabelsGroupMeta) -> dict:
501
+ """Convert a ngio label group metadata to a v05 label group metadata.
502
+
503
+ Args:
504
+ metadata (NgioLabelsGroupMeta): The ngio label group metadata.
505
+
506
+ Returns:
507
+ dict: The v05 label group metadata.
508
+ """
509
+ v05_labels_attrs = LabelsAttrsV05(labels=metadata.labels, version="0.5")
510
+ v05_labels_group = LabelsV05(ome=v05_labels_attrs)
511
+ return v05_labels_group.model_dump(exclude_none=True, by_alias=True)
@@ -258,7 +258,7 @@ class TablesContainer:
258
258
 
259
259
  def _get_table_group_handler(self, name: str) -> ZarrGroupHandler:
260
260
  """Get the group handler for a table."""
261
- handler = self._group_handler.derive_handler(path=name)
261
+ handler = self._group_handler.get_handler(path=name)
262
262
  return handler
263
263
 
264
264
  def list(self, filter_types: TypedTable | str | None = None) -> list[str]:
@@ -326,9 +326,7 @@ class TablesContainer:
326
326
  "Use overwrite=True to replace it."
327
327
  )
328
328
 
329
- table_handler = self._group_handler.derive_handler(
330
- path=name, overwrite=overwrite
331
- )
329
+ table_handler = self._group_handler.get_handler(path=name, overwrite=overwrite)
332
330
 
333
331
  if backend is None:
334
332
  backend = table.backend_name
@@ -1,8 +1,10 @@
1
+ import zarr
1
2
  from anndata import AnnData
2
3
  from anndata._settings import settings
3
4
  from pandas import DataFrame
4
5
  from polars import DataFrame as PolarsDataFrame
5
6
  from polars import LazyFrame
7
+ from zarr.storage import FsspecStore, LocalStore, MemoryStore
6
8
 
7
9
  from ngio.tables.backends._abstract_backend import AbstractTableBackend
8
10
  from ngio.tables.backends._anndata_utils import (
@@ -13,7 +15,7 @@ from ngio.tables.backends._utils import (
13
15
  convert_polars_to_anndata,
14
16
  normalize_anndata,
15
17
  )
16
- from ngio.utils import NgioValueError
18
+ from ngio.utils import NgioValueError, copy_group
17
19
 
18
20
 
19
21
  class AnnDataBackend(AbstractTableBackend):
@@ -50,18 +52,66 @@ class AnnDataBackend(AbstractTableBackend):
50
52
  """Load the table as an AnnData object."""
51
53
  return self.load_as_anndata()
52
54
 
55
+ def _write_to_local_store(
56
+ self, store: LocalStore, path: str, table: AnnData
57
+ ) -> None:
58
+ """Write the AnnData table to a LocalStore."""
59
+ store_path = f"{store.root}/{path}"
60
+ table.write_zarr(store_path)
61
+
62
+ def _write_to_fsspec_store(
63
+ self, store: FsspecStore, path: str, table: AnnData
64
+ ) -> None:
65
+ """Write the AnnData table to a FsspecStore."""
66
+ full_url = f"{store.path}/{path}"
67
+ fs = store.fs
68
+ mapper = fs.get_mapper(full_url)
69
+ table.write_zarr(mapper)
70
+
71
+ def _write_to_memory_store(
72
+ self, store: MemoryStore, path: str, table: AnnData
73
+ ) -> None:
74
+ """Write the AnnData table to a MemoryStore."""
75
+ store = MemoryStore()
76
+ table.write_zarr(store)
77
+ anndata_group = zarr.open_group(store, mode="r")
78
+ copy_group(
79
+ anndata_group,
80
+ self._group_handler._group,
81
+ suppress_warnings=True,
82
+ )
83
+
53
84
  def write_from_anndata(self, table: AnnData) -> None:
54
85
  """Serialize the table from an AnnData object."""
55
- full_url = self._group_handler.full_url
56
- if full_url is None:
86
+ # Make sure to use the correct zarr format
87
+ settings.zarr_write_format = self._group_handler.zarr_format
88
+ store = self._group_handler.store
89
+ path = self._group_handler.group.path
90
+ if isinstance(store, LocalStore):
91
+ self._write_to_local_store(
92
+ store,
93
+ path,
94
+ table,
95
+ )
96
+ elif isinstance(store, FsspecStore):
97
+ self._write_to_fsspec_store(
98
+ store,
99
+ path,
100
+ table,
101
+ )
102
+ elif isinstance(store, MemoryStore):
103
+ self._write_to_memory_store(
104
+ store,
105
+ path,
106
+ table,
107
+ )
108
+ else:
57
109
  raise NgioValueError(
58
- f"Ngio does not support writing file from a "
59
- f"store of type {type(self._group_handler)}. "
110
+ f"Ngio does not support writing an AnnData table to a "
111
+ f"store of type {type(store)}. "
60
112
  "Please make sure to use a compatible "
61
- "store like a zarr.DirectoryStore."
113
+ "store like a LocalStore, or FsspecStore."
62
114
  )
63
- settings.zarr_write_format = self._group_handler.zarr_format
64
- table.write_zarr(full_url)
65
115
 
66
116
  def write_from_pandas(self, table: DataFrame) -> None:
67
117
  """Serialize the table from a pandas DataFrame."""
@@ -9,7 +9,6 @@ from anndata._io.utils import _read_legacy_raw
9
9
  from anndata._io.zarr import read_dataframe
10
10
  from anndata.compat import _clean_uns
11
11
  from anndata.experimental import read_dispatched
12
- from zarr.storage import LocalStore
13
12
 
14
13
  from ngio.utils import (
15
14
  NgioValueError,
@@ -35,10 +34,6 @@ def custom_anndata_read_zarr(
35
34
  elem_to_read (Sequence[str] | None): The elements to read from the store.
36
35
  """
37
36
  group = open_group_wrapper(store=store, mode="r")
38
-
39
- if not isinstance(group.store, LocalStore):
40
- elem_to_read = ["X", "obs", "var"]
41
-
42
37
  if elem_to_read is None:
43
38
  elem_to_read = [
44
39
  "X",
@@ -89,7 +84,7 @@ def custom_anndata_read_zarr(
89
84
  _clean_uns(adata)
90
85
 
91
86
  if isinstance(adata, dict):
92
- adata = AnnData(**adata)
87
+ adata = AnnData(**adata) # type: ignore
93
88
  if not isinstance(adata, AnnData):
94
89
  raise NgioValueError(f"Expected an AnnData object, but got {type(adata)}")
95
90
  return adata
@@ -1,20 +1,7 @@
1
- import pandas as pd
2
- import polars as pl
1
+ from ngio.tables.backends._py_arrow_backends import PyArrowBackend
3
2
 
4
- from ngio.tables.backends._non_zarr_backends import NonZarrBaseBackend
5
3
 
6
-
7
- def write_lf_to_csv(path: str, table: pl.DataFrame) -> None:
8
- """Write a polars DataFrame to a CSV file."""
9
- table.write_csv(path)
10
-
11
-
12
- def write_df_to_csv(path: str, table: pd.DataFrame) -> None:
13
- """Write a pandas DataFrame to a CSV file."""
14
- table.to_csv(path, index=False)
15
-
16
-
17
- class CsvTableBackend(NonZarrBaseBackend):
4
+ class CsvTableBackend(PyArrowBackend):
18
5
  """A class to load and write small tables in CSV format."""
19
6
 
20
7
  def __init__(
@@ -22,11 +9,8 @@ class CsvTableBackend(NonZarrBaseBackend):
22
9
  ):
23
10
  """Initialize the CsvTableBackend."""
24
11
  super().__init__(
25
- lf_reader=pl.scan_csv,
26
- df_reader=pd.read_csv,
27
- lf_writer=write_lf_to_csv,
28
- df_writer=write_df_to_csv,
29
12
  table_name="table.csv",
13
+ table_format="csv",
30
14
  )
31
15
 
32
16
  @staticmethod