ngio 0.5.0__py3-none-any.whl → 0.5.0a1__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 (54) hide show
  1. ngio/__init__.py +2 -5
  2. ngio/common/__init__.py +6 -11
  3. ngio/common/_masking_roi.py +54 -34
  4. ngio/common/_pyramid.py +87 -321
  5. ngio/common/_roi.py +330 -258
  6. ngio/experimental/iterators/_feature.py +3 -3
  7. ngio/experimental/iterators/_rois_utils.py +11 -10
  8. ngio/hcs/_plate.py +136 -192
  9. ngio/images/_abstract_image.py +35 -539
  10. ngio/images/_create.py +283 -0
  11. ngio/images/_create_synt_container.py +43 -40
  12. ngio/images/_image.py +251 -517
  13. ngio/images/_label.py +172 -249
  14. ngio/images/_masked_image.py +2 -2
  15. ngio/images/_ome_zarr_container.py +241 -644
  16. ngio/io_pipes/_io_pipes.py +9 -9
  17. ngio/io_pipes/_io_pipes_masked.py +7 -7
  18. ngio/io_pipes/_io_pipes_roi.py +6 -6
  19. ngio/io_pipes/_io_pipes_types.py +3 -3
  20. ngio/io_pipes/_match_shape.py +8 -6
  21. ngio/io_pipes/_ops_slices_utils.py +5 -8
  22. ngio/ome_zarr_meta/__init__.py +18 -29
  23. ngio/ome_zarr_meta/_meta_handlers.py +708 -392
  24. ngio/ome_zarr_meta/ngio_specs/__init__.py +0 -4
  25. ngio/ome_zarr_meta/ngio_specs/_axes.py +51 -152
  26. ngio/ome_zarr_meta/ngio_specs/_dataset.py +22 -13
  27. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +91 -129
  28. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +68 -57
  29. ngio/ome_zarr_meta/v04/__init__.py +1 -5
  30. ngio/ome_zarr_meta/v04/{_v04_spec.py → _v04_spec_utils.py} +85 -54
  31. ngio/ome_zarr_meta/v05/__init__.py +1 -5
  32. ngio/ome_zarr_meta/v05/{_v05_spec.py → _v05_spec_utils.py} +87 -64
  33. ngio/resources/__init__.py +1 -1
  34. ngio/resources/resource_model.py +1 -1
  35. ngio/tables/_tables_container.py +27 -85
  36. ngio/tables/backends/_anndata.py +8 -58
  37. ngio/tables/backends/_anndata_utils.py +6 -1
  38. ngio/tables/backends/_csv.py +19 -3
  39. ngio/tables/backends/_json.py +13 -10
  40. ngio/tables/backends/_non_zarr_backends.py +196 -0
  41. ngio/tables/backends/_parquet.py +31 -3
  42. ngio/tables/v1/_roi_table.py +27 -44
  43. ngio/utils/__init__.py +12 -8
  44. ngio/utils/_datasets.py +0 -6
  45. ngio/utils/_logger.py +50 -0
  46. ngio/utils/_zarr_utils.py +250 -292
  47. {ngio-0.5.0.dist-info → ngio-0.5.0a1.dist-info}/METADATA +6 -13
  48. ngio-0.5.0a1.dist-info/RECORD +88 -0
  49. {ngio-0.5.0.dist-info → ngio-0.5.0a1.dist-info}/WHEEL +1 -1
  50. ngio/images/_create_utils.py +0 -406
  51. ngio/tables/backends/_py_arrow_backends.py +0 -222
  52. ngio/utils/_cache.py +0 -48
  53. ngio-0.5.0.dist-info/RECORD +0 -88
  54. {ngio-0.5.0.dist-info → ngio-0.5.0a1.dist-info}/licenses/LICENSE +0 -0
ngio/hcs/_plate.py CHANGED
@@ -15,16 +15,15 @@ from ngio.images import (
15
15
  list_image_tables_async,
16
16
  )
17
17
  from ngio.ome_zarr_meta import (
18
- DefaultNgffVersion,
19
18
  ImageInWellPath,
20
19
  NgffVersions,
21
20
  NgioPlateMeta,
22
21
  NgioWellMeta,
23
- PlateMetaHandler,
24
- WellMetaHandler,
22
+ find_plate_meta_handler,
23
+ find_well_meta_handler,
24
+ get_plate_meta_handler,
25
+ get_well_meta_handler,
25
26
  path_in_well_validation,
26
- update_ngio_plate_meta,
27
- update_ngio_well_meta,
28
27
  )
29
28
  from ngio.tables import (
30
29
  ConditionTable,
@@ -41,23 +40,17 @@ from ngio.tables import (
41
40
  )
42
41
  from ngio.utils import (
43
42
  AccessModeLiteral,
44
- NgioCache,
45
- NgioError,
46
43
  NgioValueError,
47
44
  StoreOrGroup,
48
45
  ZarrGroupHandler,
49
46
  )
50
47
 
51
48
 
52
- def _try_get_table_container(
53
- handler: ZarrGroupHandler, create_mode: bool = True
54
- ) -> TablesContainer | None:
49
+ def _default_table_container(handler: ZarrGroupHandler) -> TablesContainer | None:
55
50
  """Return a default table container."""
56
- try:
57
- table_handler = handler.get_handler("tables", create_mode=create_mode)
51
+ success, table_handler = handler.safe_derive_handler("tables")
52
+ if success and isinstance(table_handler, ZarrGroupHandler):
58
53
  return TablesContainer(table_handler)
59
- except NgioError:
60
- return None
61
54
 
62
55
 
63
56
  # Mock lock class that does nothing
@@ -83,7 +76,7 @@ class OmeZarrWell:
83
76
  group_handler: The Zarr group handler that contains the Well.
84
77
  """
85
78
  self._group_handler = group_handler
86
- self._meta_handler = WellMetaHandler(group_handler)
79
+ self._meta_handler = find_well_meta_handler(group_handler)
87
80
 
88
81
  def __repr__(self) -> str:
89
82
  """Return a string representation of the well."""
@@ -97,7 +90,7 @@ class OmeZarrWell:
97
90
  @property
98
91
  def meta(self):
99
92
  """Return the metadata."""
100
- return self._meta_handler.get_meta()
93
+ return self._meta_handler.meta
101
94
 
102
95
  @property
103
96
  def acquisition_ids(self) -> list[int]:
@@ -143,7 +136,7 @@ class OmeZarrWell:
143
136
  Returns:
144
137
  OmeZarrContainer: The image.
145
138
  """
146
- handler = self._group_handler.get_handler(image_path)
139
+ handler = self._group_handler.derive_handler(image_path)
147
140
  return OmeZarrContainer(handler)
148
141
 
149
142
  def _add_image(
@@ -165,7 +158,7 @@ class OmeZarrWell:
165
158
  meta = self.meta.add_image(
166
159
  path=image_path, acquisition=acquisition_id, strict=strict
167
160
  )
168
- self.meta_handler.update_meta(meta)
161
+ self.meta_handler.write_meta(meta)
169
162
  self.meta_handler._group_handler.clean_cache()
170
163
 
171
164
  return self._group_handler.get_group(image_path, create_mode=True)
@@ -244,14 +237,8 @@ class OmeZarrPlate:
244
237
  table_container: The tables container that contains plate level tables.
245
238
  """
246
239
  self._group_handler = group_handler
247
- self._meta_handler = PlateMetaHandler(group_handler)
240
+ self._meta_handler = find_plate_meta_handler(group_handler)
248
241
  self._tables_container = table_container
249
- self._wells_cache: NgioCache[OmeZarrWell] = NgioCache(
250
- use_cache=self._group_handler.use_cache
251
- )
252
- self._images_cache: NgioCache[OmeZarrContainer] = NgioCache(
253
- use_cache=self._group_handler.use_cache
254
- )
255
242
 
256
243
  def __repr__(self) -> str:
257
244
  """Return a string representation of the plate."""
@@ -265,7 +252,7 @@ class OmeZarrPlate:
265
252
  @property
266
253
  def meta(self):
267
254
  """Return the metadata."""
268
- return self._meta_handler.get_meta()
255
+ return self._meta_handler.meta
269
256
 
270
257
  @property
271
258
  def columns(self) -> list[str]:
@@ -369,24 +356,6 @@ class OmeZarrPlate:
369
356
  well = self.get_well(row=row, column=column)
370
357
  return well.get_image_acquisition_id(image_path=image_path)
371
358
 
372
- def _get_well(self, well_path: str) -> OmeZarrWell:
373
- """Get a well from the plate by its path.
374
-
375
- Args:
376
- well_path (str): The path of the well.
377
-
378
- Returns:
379
- OmeZarrWell: The well.
380
-
381
- """
382
- cached_well = self._wells_cache.get(well_path)
383
- if cached_well is not None:
384
- return cached_well
385
-
386
- group_handler = self._group_handler.get_handler(well_path)
387
- self._wells_cache.set(well_path, OmeZarrWell(group_handler))
388
- return OmeZarrWell(group_handler)
389
-
390
359
  def get_well(self, row: str, column: int | str) -> OmeZarrWell:
391
360
  """Get a well from the plate.
392
361
 
@@ -398,7 +367,8 @@ class OmeZarrPlate:
398
367
  OmeZarrWell: The well.
399
368
  """
400
369
  well_path = self._well_path(row=row, column=column)
401
- return self._get_well(well_path=well_path)
370
+ group_handler = self._group_handler.derive_handler(well_path)
371
+ return OmeZarrWell(group_handler)
402
372
 
403
373
  async def get_wells_async(self) -> dict[str, OmeZarrWell]:
404
374
  """Get all wells in the plate asynchronously.
@@ -410,17 +380,26 @@ class OmeZarrPlate:
410
380
  dict[str, OmeZarrWell]: A dictionary of wells, where the key is the well
411
381
  path and the value is the well object.
412
382
  """
383
+ wells = self._group_handler.get_from_cache("wells")
384
+ if wells is not None:
385
+ assert isinstance(wells, dict)
386
+ return wells
387
+
388
+ def process_well(well_path):
389
+ group_handler = self._group_handler.derive_handler(well_path)
390
+ well = OmeZarrWell(group_handler)
391
+ return well_path, well
392
+
413
393
  wells, tasks = {}, []
414
394
  for well_path in self.wells_paths():
415
- task = asyncio.to_thread(
416
- lambda well_path: (well_path, self._get_well(well_path)), well_path
417
- )
395
+ task = asyncio.to_thread(process_well, well_path)
418
396
  tasks.append(task)
419
397
 
420
398
  results = await asyncio.gather(*tasks)
421
399
  for well_path, well in results:
422
400
  wells[well_path] = well
423
401
 
402
+ self._group_handler.add_to_cache("wells", wells)
424
403
  return wells
425
404
 
426
405
  def get_wells(self) -> dict[str, OmeZarrWell]:
@@ -430,24 +409,23 @@ class OmeZarrPlate:
430
409
  dict[str, OmeZarrWell]: A dictionary of wells, where the key is the well
431
410
  path and the value is the well object.
432
411
  """
412
+ wells = self._group_handler.get_from_cache("wells")
413
+ if wells is not None:
414
+ assert isinstance(wells, dict)
415
+ return wells
416
+
417
+ def process_well(well_path):
418
+ group_handler = self._group_handler.derive_handler(well_path)
419
+ well = OmeZarrWell(group_handler)
420
+ return well_path, well
421
+
433
422
  wells = {}
434
423
  for well_path in self.wells_paths():
435
- wells[well_path] = self._get_well(well_path)
436
- return wells
437
-
438
- def _get_image(self, image_path: str) -> OmeZarrContainer:
439
- """Get an image from the plate by its path.
424
+ _, well = process_well(well_path)
425
+ wells[well_path] = well
440
426
 
441
- Args:
442
- image_path (str): The path of the image.
443
- """
444
- cached_image = self._images_cache.get(image_path)
445
- if cached_image is not None:
446
- return cached_image
447
- img_group_handler = self._group_handler.get_handler(image_path)
448
- image = OmeZarrContainer(img_group_handler)
449
- self._images_cache.set(image_path, image)
450
- return image
427
+ self._group_handler.add_to_cache("wells", wells)
428
+ return wells
451
429
 
452
430
  async def get_images_async(
453
431
  self, acquisition: int | None = None
@@ -464,19 +442,30 @@ class OmeZarrPlate:
464
442
  dict[str, OmeZarrContainer]: A dictionary of images, where the key is the
465
443
  image path and the value is the image object.
466
444
  """
445
+ images = self._group_handler.get_from_cache("images")
446
+ if images is not None:
447
+ assert isinstance(images, dict)
448
+ return images
449
+
467
450
  paths = await self.images_paths_async(acquisition=acquisition)
468
451
 
452
+ def process_image(image_path):
453
+ """Process a single image and return the image path and image object."""
454
+ img_group_handler = self._group_handler.derive_handler(image_path)
455
+ image = OmeZarrContainer(img_group_handler)
456
+ return image_path, image
457
+
469
458
  images, tasks = {}, []
470
459
  for image_path in paths:
471
- task = asyncio.to_thread(
472
- lambda image_path: (image_path, self._get_image(image_path)), image_path
473
- )
460
+ task = asyncio.to_thread(process_image, image_path)
474
461
  tasks.append(task)
475
462
 
476
463
  results = await asyncio.gather(*tasks)
477
464
 
478
465
  for image_path, image in results:
479
466
  images[image_path] = image
467
+
468
+ self._group_handler.add_to_cache("images", images)
480
469
  return images
481
470
 
482
471
  def get_images(self, acquisition: int | None = None) -> dict[str, OmeZarrContainer]:
@@ -485,11 +474,24 @@ class OmeZarrPlate:
485
474
  Args:
486
475
  acquisition: The acquisition id to filter the images.
487
476
  """
477
+ images = self._group_handler.get_from_cache("images")
478
+ if images is not None:
479
+ assert isinstance(images, dict)
480
+ return images
488
481
  paths = self.images_paths(acquisition=acquisition)
482
+
483
+ def process_image(image_path):
484
+ """Process a single image and return the image path and image object."""
485
+ img_group_handler = self._group_handler.derive_handler(image_path)
486
+ image = OmeZarrContainer(img_group_handler)
487
+ return image_path, image
488
+
489
489
  images = {}
490
490
  for image_path in paths:
491
- images[image_path] = self._get_image(image_path)
491
+ _, image = process_image(image_path)
492
+ images[image_path] = image
492
493
 
494
+ self._group_handler.add_to_cache("images", images)
493
495
  return images
494
496
 
495
497
  def get_image(
@@ -506,7 +508,8 @@ class OmeZarrPlate:
506
508
  OmeZarrContainer: The image.
507
509
  """
508
510
  image_path = self._image_path(row=row, column=column, path=image_path)
509
- return self._get_image(image_path)
511
+ group_handler = self._group_handler.derive_handler(image_path)
512
+ return OmeZarrContainer(group_handler)
510
513
 
511
514
  def get_image_store(
512
515
  self, row: str, column: int | str, image_path: str
@@ -535,7 +538,7 @@ class OmeZarrPlate:
535
538
  for image_paths in self.well_images_paths(
536
539
  row=row, column=column, acquisition=acquisition
537
540
  ):
538
- group_handler = self._group_handler.get_handler(image_paths)
541
+ group_handler = self._group_handler.derive_handler(image_paths)
539
542
  images[image_paths] = OmeZarrContainer(group_handler)
540
543
  return images
541
544
 
@@ -564,11 +567,11 @@ class OmeZarrPlate:
564
567
  meta = meta.add_acquisition(
565
568
  acquisition_id=acquisition_id, acquisition_name=acquisition_name
566
569
  )
567
- self.meta_handler.update_meta(meta)
570
+ self.meta_handler.write_meta(meta)
568
571
  self.meta_handler._group_handler.clean_cache()
569
572
 
570
573
  well_path = self.meta.get_well_path(row=row, column=column)
571
- group_handler = self._group_handler.get_handler(well_path)
574
+ group_handler = self._group_handler.derive_handler(well_path)
572
575
 
573
576
  if atomic:
574
577
  well_lock = group_handler.lock
@@ -583,19 +586,18 @@ class OmeZarrPlate:
583
586
  well_meta = NgioWellMeta.default_init()
584
587
  version = self.meta.plate.version
585
588
  version = version if version is not None else "0.4"
586
- update_ngio_well_meta(group_handler, well_meta)
587
- meta_handler = WellMetaHandler(group_handler=group_handler)
589
+ meta_handler = get_well_meta_handler(group_handler, version=version)
588
590
  else:
589
- meta_handler = WellMetaHandler(group_handler=group_handler)
590
- well_meta = meta_handler.get_meta()
591
+ meta_handler = find_well_meta_handler(group_handler)
592
+ well_meta = meta_handler.meta
591
593
 
592
- group_handler = self._group_handler.get_handler(well_path)
594
+ group_handler = self._group_handler.derive_handler(well_path)
593
595
 
594
596
  if image_path is not None:
595
597
  well_meta = well_meta.add_image(
596
598
  path=image_path, acquisition=acquisition_id, strict=False
597
599
  )
598
- meta_handler.update_meta(well_meta)
600
+ meta_handler.write_meta(well_meta)
599
601
  meta_handler._group_handler.clean_cache()
600
602
 
601
603
  if image_path is not None:
@@ -672,7 +674,7 @@ class OmeZarrPlate:
672
674
  ) -> "OmeZarrPlate":
673
675
  """Add a column to an ome-zarr plate."""
674
676
  meta, _ = self.meta.add_column(column)
675
- self.meta_handler.update_meta(meta)
677
+ self.meta_handler.write_meta(meta)
676
678
  self.meta_handler._group_handler.clean_cache()
677
679
  return self
678
680
 
@@ -682,7 +684,7 @@ class OmeZarrPlate:
682
684
  ) -> "OmeZarrPlate":
683
685
  """Add a row to an ome-zarr plate."""
684
686
  meta, _ = self.meta.add_row(row)
685
- self.meta_handler.update_meta(meta)
687
+ self.meta_handler.write_meta(meta)
686
688
  self.meta_handler._group_handler.clean_cache()
687
689
  return self
688
690
 
@@ -702,7 +704,7 @@ class OmeZarrPlate:
702
704
  meta = self.meta.add_acquisition(
703
705
  acquisition_id=acquisition_id, acquisition_name=acquisition_name
704
706
  )
705
- self.meta_handler.update_meta(meta)
707
+ self.meta_handler.write_meta(meta)
706
708
  self.meta_handler._group_handler.clean_cache()
707
709
  return self
708
710
 
@@ -721,7 +723,7 @@ class OmeZarrPlate:
721
723
  with plate_lock:
722
724
  meta = self.meta
723
725
  meta = meta.remove_well(row, column)
724
- self.meta_handler.update_meta(meta)
726
+ self.meta_handler.write_meta(meta)
725
727
  self.meta_handler._group_handler.clean_cache()
726
728
 
727
729
  def _remove_image(
@@ -742,7 +744,7 @@ class OmeZarrPlate:
742
744
  with well_lock:
743
745
  well_meta = well.meta
744
746
  well_meta = well_meta.remove_image(path=image_path)
745
- well.meta_handler.update_meta(well_meta)
747
+ well.meta_handler.write_meta(well_meta)
746
748
  well.meta_handler._group_handler.clean_cache()
747
749
  if len(well_meta.paths()) == 0:
748
750
  self._remove_well(row, column, atomic=atomic)
@@ -779,42 +781,41 @@ class OmeZarrPlate:
779
781
  self,
780
782
  store: StoreOrGroup,
781
783
  plate_name: str | None = None,
782
- version: NgffVersions | None = None,
783
- ngff_version: NgffVersions = DefaultNgffVersion,
784
+ version: NgffVersions = "0.4",
784
785
  keep_acquisitions: bool = False,
785
786
  cache: bool = False,
786
787
  overwrite: bool = False,
788
+ parallel_safe: bool = True,
787
789
  ) -> "OmeZarrPlate":
788
790
  """Derive a new OME-Zarr plate from an existing one.
789
791
 
790
792
  Args:
791
793
  store (StoreOrGroup): The Zarr store or group that stores the plate.
792
794
  plate_name (str | None): The name of the new plate.
793
- version (NgffVersion | None): Deprecated. Please use 'ngff_version' instead.
794
- ngff_version (NgffVersion): The NGFF version to use for the new plate.
795
+ version (NgffVersion): The version of the new plate.
795
796
  keep_acquisitions (bool): Whether to keep the acquisitions in the new plate.
796
797
  cache (bool): Whether to use a cache for the zarr group metadata.
797
798
  overwrite (bool): Whether to overwrite the existing plate.
799
+ parallel_safe (bool): Whether the group handler is parallel safe.
798
800
  """
799
801
  return derive_ome_zarr_plate(
800
802
  ome_zarr_plate=self,
801
803
  store=store,
802
804
  plate_name=plate_name,
803
- ngff_version=ngff_version,
804
805
  version=version,
805
806
  keep_acquisitions=keep_acquisitions,
806
807
  cache=cache,
807
808
  overwrite=overwrite,
809
+ parallel_safe=parallel_safe,
808
810
  )
809
811
 
810
- def _get_tables_container(self, create_mode: bool = True) -> TablesContainer | None:
812
+ def _get_tables_container(self) -> TablesContainer | None:
811
813
  """Return the tables container."""
812
- if self._tables_container is not None:
813
- return self._tables_container
814
- _tables_container = _try_get_table_container(
815
- self._group_handler, create_mode=create_mode
816
- )
817
- self._tables_container = _tables_container
814
+ if self._tables_container is None:
815
+ _tables_container = _default_table_container(self._group_handler)
816
+ if _tables_container is None:
817
+ return None
818
+ self._tables_container = _tables_container
818
819
  return self._tables_container
819
820
 
820
821
  @property
@@ -829,20 +830,17 @@ class OmeZarrPlate:
829
830
 
830
831
  def list_tables(self, filter_types: TypedTable | str | None = None) -> list[str]:
831
832
  """List all tables in the image."""
832
- _tables_container = self._get_tables_container(create_mode=False)
833
- if _tables_container is None:
834
- return []
835
833
  return self.tables_container.list(filter_types=filter_types)
836
834
 
837
835
  def list_roi_tables(self) -> list[str]:
838
836
  """List all ROI tables in the image."""
839
- roi = self.tables_container.list(
840
- filter_types="roi_table",
841
- )
842
837
  masking_roi = self.tables_container.list(
843
838
  filter_types="masking_roi_table",
844
839
  )
845
- return roi + masking_roi
840
+ roi = self.tables_container.list(
841
+ filter_types="roi_table",
842
+ )
843
+ return masking_roi + roi
846
844
 
847
845
  def get_roi_table(self, name: str) -> RoiTable:
848
846
  """Get a ROI table from the image.
@@ -919,8 +917,8 @@ class OmeZarrPlate:
919
917
  """
920
918
  if check_type is not None:
921
919
  warnings.warn(
922
- "The 'check_type' argument is deprecated and will be removed in "
923
- "ngio=0.6. Please use 'get_table_as' instead or one of the "
920
+ "The 'check_type' argument is deprecated, and will be removed in "
921
+ "ngio=0.3. Use 'get_table_as' instead or one of the "
924
922
  "type specific get_*table() methods.",
925
923
  DeprecationWarning,
926
924
  stacklevel=2,
@@ -959,25 +957,6 @@ class OmeZarrPlate:
959
957
  name=name, table=table, backend=backend, overwrite=overwrite
960
958
  )
961
959
 
962
- def delete_table(self, name: str, missing_ok: bool = False) -> None:
963
- """Delete a table from the group.
964
-
965
- Args:
966
- name (str): The name of the table to delete.
967
- missing_ok (bool): If True, do not raise an error if the table does not
968
- exist.
969
-
970
- """
971
- table_container = self._get_tables_container(create_mode=False)
972
- if table_container is None and missing_ok:
973
- return
974
- if table_container is None:
975
- raise NgioValueError(
976
- f"No tables found in the image, cannot delete {name}. "
977
- "Set missing_ok=True to ignore this error."
978
- )
979
- table_container.delete(name=name, missing_ok=missing_ok)
980
-
981
960
  def list_image_tables(
982
961
  self,
983
962
  acquisition: int | None = None,
@@ -1164,6 +1143,7 @@ def open_ome_zarr_plate(
1164
1143
  store: StoreOrGroup,
1165
1144
  cache: bool = False,
1166
1145
  mode: AccessModeLiteral = "r+",
1146
+ parallel_safe: bool = True,
1167
1147
  ) -> OmeZarrPlate:
1168
1148
  """Open an OME-Zarr plate.
1169
1149
 
@@ -1172,32 +1152,27 @@ def open_ome_zarr_plate(
1172
1152
  cache (bool): Whether to use a cache for the zarr group metadata.
1173
1153
  mode (AccessModeLiteral): The
1174
1154
  access mode for the image. Defaults to "r+".
1155
+ parallel_safe (bool): Whether the group handler is parallel safe.
1175
1156
  """
1176
- group_handler = ZarrGroupHandler(store=store, cache=cache, mode=mode)
1157
+ group_handler = ZarrGroupHandler(
1158
+ store=store, cache=cache, mode=mode, parallel_safe=parallel_safe
1159
+ )
1177
1160
  return OmeZarrPlate(group_handler)
1178
1161
 
1179
1162
 
1180
1163
  def _create_empty_plate_from_meta(
1181
1164
  store: StoreOrGroup,
1182
1165
  meta: NgioPlateMeta,
1166
+ version: NgffVersions = "0.4",
1183
1167
  overwrite: bool = False,
1184
1168
  ) -> ZarrGroupHandler:
1185
- """Create an empty OME-Zarr plate from metadata.
1186
-
1187
- Args:
1188
- store: The Zarr store or group to create the plate in.
1189
- meta: The plate metadata to use.
1190
- overwrite: Whether to overwrite an existing plate.
1191
-
1192
- Returns:
1193
- The ZarrGroupHandler for the created plate.
1194
- """
1169
+ """Create an empty OME-Zarr plate from metadata."""
1195
1170
  mode = "w" if overwrite else "w-"
1196
- zarr_format = 2 if meta.plate.version == "0.4" else 3
1197
1171
  group_handler = ZarrGroupHandler(
1198
- store=store, cache=True, mode=mode, zarr_format=zarr_format
1172
+ store=store, cache=True, mode=mode, parallel_safe=False
1199
1173
  )
1200
- update_ngio_plate_meta(group_handler, meta)
1174
+ meta_handler = get_plate_meta_handler(group_handler, version=version)
1175
+ meta_handler.write_meta(meta)
1201
1176
  return group_handler
1202
1177
 
1203
1178
 
@@ -1205,38 +1180,20 @@ def create_empty_plate(
1205
1180
  store: StoreOrGroup,
1206
1181
  name: str,
1207
1182
  images: list[ImageInWellPath] | None = None,
1208
- version: NgffVersions | None = None,
1209
- ngff_version: NgffVersions = DefaultNgffVersion,
1183
+ version: NgffVersions = "0.4",
1210
1184
  cache: bool = False,
1211
1185
  overwrite: bool = False,
1186
+ parallel_safe: bool = True,
1212
1187
  ) -> OmeZarrPlate:
1213
- """Initialize and create an empty OME-Zarr plate.
1214
-
1215
- Args:
1216
- store (StoreOrGroup): The Zarr store or group that stores the plate.
1217
- name (str): The name of the plate.
1218
- images (list[ImageInWellPath] | None): A list of images to add to the plate.
1219
- If None, no images are added. Defaults to None.
1220
- version (NgffVersion | None): Deprecated. Please use 'ngff_version' instead.
1221
- ngff_version (NgffVersion): The NGFF version to use for the new plate.
1222
- cache (bool): Whether to use a cache for the zarr group metadata.
1223
- overwrite (bool): Whether to overwrite the existing plate.
1224
- """
1225
- if version is not None:
1226
- warnings.warn(
1227
- "The 'version' argument is deprecated and will be removed in ngio=0.6. "
1228
- "Please use 'ngff_version' instead.",
1229
- DeprecationWarning,
1230
- stacklevel=2,
1231
- )
1232
- ngff_version = version
1188
+ """Initialize and create an empty OME-Zarr plate."""
1233
1189
  plate_meta = NgioPlateMeta.default_init(
1234
1190
  name=name,
1235
- ngff_version=ngff_version,
1191
+ version=version,
1236
1192
  )
1237
1193
  group_handler = _create_empty_plate_from_meta(
1238
1194
  store=store,
1239
1195
  meta=plate_meta,
1196
+ version=version,
1240
1197
  overwrite=overwrite,
1241
1198
  )
1242
1199
 
@@ -1254,6 +1211,7 @@ def create_empty_plate(
1254
1211
  store=store,
1255
1212
  cache=cache,
1256
1213
  mode="r+",
1214
+ parallel_safe=parallel_safe,
1257
1215
  )
1258
1216
 
1259
1217
 
@@ -1261,11 +1219,11 @@ def derive_ome_zarr_plate(
1261
1219
  ome_zarr_plate: OmeZarrPlate,
1262
1220
  store: StoreOrGroup,
1263
1221
  plate_name: str | None = None,
1264
- version: NgffVersions | None = None,
1265
- ngff_version: NgffVersions = DefaultNgffVersion,
1222
+ version: NgffVersions = "0.4",
1266
1223
  keep_acquisitions: bool = False,
1267
1224
  cache: bool = False,
1268
1225
  overwrite: bool = False,
1226
+ parallel_safe: bool = True,
1269
1227
  ) -> OmeZarrPlate:
1270
1228
  """Derive a new OME-Zarr plate from an existing one.
1271
1229
 
@@ -1273,38 +1231,31 @@ def derive_ome_zarr_plate(
1273
1231
  ome_zarr_plate (OmeZarrPlate): The existing OME-Zarr plate.
1274
1232
  store (StoreOrGroup): The Zarr store or group that stores the plate.
1275
1233
  plate_name (str | None): The name of the new plate.
1276
- version (NgffVersion | None): Deprecated. Please use 'ngff_version' instead.
1277
- ngff_version (NgffVersion): The NGFF version to use for the new plate.
1234
+ version (NgffVersion): The version of the new plate.
1278
1235
  keep_acquisitions (bool): Whether to keep the acquisitions in the new plate.
1279
1236
  cache (bool): Whether to use a cache for the zarr group metadata.
1280
1237
  overwrite (bool): Whether to overwrite the existing plate.
1238
+ parallel_safe (bool): Whether the group handler is parallel safe.
1281
1239
  """
1282
- if version is not None:
1283
- warnings.warn(
1284
- "The 'version' argument is deprecated and will be removed in ngio=0.6. "
1285
- "Please use 'ngff_version' instead.",
1286
- DeprecationWarning,
1287
- stacklevel=2,
1288
- )
1289
- ngff_version = version
1290
-
1291
1240
  if plate_name is None:
1292
1241
  plate_name = ome_zarr_plate.meta.plate.name
1293
1242
 
1294
1243
  new_meta = ome_zarr_plate.meta.derive(
1295
1244
  name=plate_name,
1296
- ngff_version=ngff_version,
1245
+ version=version,
1297
1246
  keep_acquisitions=keep_acquisitions,
1298
1247
  )
1299
1248
  _ = _create_empty_plate_from_meta(
1300
1249
  store=store,
1301
1250
  meta=new_meta,
1302
1251
  overwrite=overwrite,
1252
+ version=version,
1303
1253
  )
1304
1254
  return open_ome_zarr_plate(
1305
1255
  store=store,
1306
1256
  cache=cache,
1307
1257
  mode="r+",
1258
+ parallel_safe=parallel_safe,
1308
1259
  )
1309
1260
 
1310
1261
 
@@ -1312,6 +1263,7 @@ def open_ome_zarr_well(
1312
1263
  store: StoreOrGroup,
1313
1264
  cache: bool = False,
1314
1265
  mode: AccessModeLiteral = "r+",
1266
+ parallel_safe: bool = True,
1315
1267
  ) -> OmeZarrWell:
1316
1268
  """Open an OME-Zarr well.
1317
1269
 
@@ -1319,48 +1271,40 @@ def open_ome_zarr_well(
1319
1271
  store (StoreOrGroup): The Zarr store or group that stores the plate.
1320
1272
  cache (bool): Whether to use a cache for the zarr group metadata.
1321
1273
  mode (AccessModeLiteral): The access mode for the image. Defaults to "r+".
1274
+ parallel_safe (bool): Whether the group handler is parallel safe.
1322
1275
  """
1323
1276
  group_handler = ZarrGroupHandler(
1324
- store=store,
1325
- cache=cache,
1326
- mode=mode,
1277
+ store=store, cache=cache, mode=mode, parallel_safe=parallel_safe
1327
1278
  )
1328
1279
  return OmeZarrWell(group_handler)
1329
1280
 
1330
1281
 
1331
1282
  def create_empty_well(
1332
1283
  store: StoreOrGroup,
1333
- version: NgffVersions | None = None,
1334
- ngff_version: NgffVersions = DefaultNgffVersion,
1284
+ version: NgffVersions = "0.4",
1335
1285
  cache: bool = False,
1336
1286
  overwrite: bool = False,
1287
+ parallel_safe: bool = True,
1337
1288
  ) -> OmeZarrWell:
1338
1289
  """Create an empty OME-Zarr well.
1339
1290
 
1340
1291
  Args:
1341
1292
  store (StoreOrGroup): The Zarr store or group that stores the well.
1342
- version (NgffVersion | None): Deprecated. Please use 'ngff_version' instead.
1343
- ngff_version (NgffVersion): The version of the new well.
1293
+ version (NgffVersion): The version of the new well.
1344
1294
  cache (bool): Whether to use a cache for the zarr group metadata.
1345
1295
  overwrite (bool): Whether to overwrite the existing well.
1296
+ parallel_safe (bool): Whether the group handler is parallel safe.
1346
1297
  """
1347
- if version is not None:
1348
- warnings.warn(
1349
- "The 'version' argument is deprecated and will be removed in ngio=0.6. "
1350
- "Please use 'ngff_version' instead.",
1351
- DeprecationWarning,
1352
- stacklevel=2,
1353
- )
1354
- ngff_version = version
1355
1298
  group_handler = ZarrGroupHandler(
1356
- store=store, cache=True, mode="w" if overwrite else "w-"
1357
- )
1358
- update_ngio_well_meta(
1359
- group_handler, NgioWellMeta.default_init(ngff_version=ngff_version)
1299
+ store=store, cache=True, mode="w" if overwrite else "w-", parallel_safe=False
1360
1300
  )
1301
+ meta_handler = get_well_meta_handler(group_handler, version=version)
1302
+ meta = NgioWellMeta.default_init()
1303
+ meta_handler.write_meta(meta)
1361
1304
 
1362
1305
  return open_ome_zarr_well(
1363
1306
  store=store,
1364
1307
  cache=cache,
1365
1308
  mode="r+",
1309
+ parallel_safe=parallel_safe,
1366
1310
  )