ngio 0.5.0b5__py3-none-any.whl → 0.5.0b7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ngio/common/_pyramid.py CHANGED
@@ -1,3 +1,5 @@
1
+ import itertools
2
+ import math
1
3
  from collections.abc import Callable, Mapping, Sequence
2
4
  from typing import Any, Literal
3
5
 
@@ -195,7 +197,7 @@ ChunksLike = tuple[int, ...] | Literal["auto"]
195
197
  ShardsLike = tuple[int, ...] | Literal["auto"]
196
198
 
197
199
 
198
- def shapes_from_scaling_factors(
200
+ def compute_shapes_from_scaling_factors(
199
201
  base_shape: tuple[int, ...],
200
202
  scaling_factors: tuple[float, ...],
201
203
  num_levels: int,
@@ -215,7 +217,7 @@ def shapes_from_scaling_factors(
215
217
  for _ in range(num_levels):
216
218
  shapes.append(current_shape)
217
219
  current_shape = tuple(
218
- max(1, int(s / f))
220
+ max(1, math.floor(s / f))
219
221
  for s, f in zip(current_shape, scaling_factors, strict=True)
220
222
  )
221
223
  return shapes
@@ -233,6 +235,7 @@ class PyramidLevel(BaseModel):
233
235
  path: str
234
236
  shape: tuple[int, ...]
235
237
  scale: tuple[float, ...]
238
+ translation: tuple[float, ...]
236
239
  chunks: ChunksLike = "auto"
237
240
  shards: ShardsLike | None = None
238
241
 
@@ -247,6 +250,12 @@ class PyramidLevel(BaseModel):
247
250
  if any(isinstance(s, float) and s < 0 for s in self.scale):
248
251
  raise NgioValueError("Scale values must be positive.")
249
252
 
253
+ if len(self.translation) != len(self.shape):
254
+ raise NgioValueError(
255
+ "Translation must have the same length as shape "
256
+ f"({len(self.shape)}), got {len(self.translation)}"
257
+ )
258
+
250
259
  if isinstance(self.chunks, tuple):
251
260
  if len(self.chunks) != len(self.shape):
252
261
  raise NgioValueError(
@@ -271,6 +280,63 @@ class PyramidLevel(BaseModel):
271
280
  return self
272
281
 
273
282
 
283
+ def compute_scales_from_shapes(
284
+ shapes: Sequence[tuple[int, ...]],
285
+ base_scale: tuple[float, ...],
286
+ ) -> list[tuple[float, ...]]:
287
+ scales = [base_scale]
288
+ scale_ = base_scale
289
+ for current_shape, next_shape in itertools.pairwise(shapes):
290
+ # This only works for downsampling pyramids
291
+ # The _check_order function (called before) ensures that the
292
+ # shapes are decreasing
293
+ _scaling_factor = tuple(
294
+ s1 / s2
295
+ for s1, s2 in zip(
296
+ current_shape,
297
+ next_shape,
298
+ strict=True,
299
+ )
300
+ )
301
+ scale_ = tuple(s * f for s, f in zip(scale_, _scaling_factor, strict=True))
302
+ scales.append(scale_)
303
+ return scales
304
+
305
+
306
+ def _compute_translations_from_shapes(
307
+ scales: Sequence[tuple[float, ...]],
308
+ base_translation: Sequence[float] | None,
309
+ ) -> list[tuple[float, ...]]:
310
+ translations = []
311
+ if base_translation is None:
312
+ n_dim = len(scales[0])
313
+ base_translation = tuple(0.0 for _ in range(n_dim))
314
+ else:
315
+ base_translation = tuple(base_translation)
316
+
317
+ translation_ = base_translation
318
+ for _ in scales:
319
+ # TBD: How to update translation
320
+ # For now, we keep it constant but we should probably change it
321
+ # to reflect the shift introduced by downsampling
322
+ # translation_ = translation_ + _scaling_factor
323
+ translations.append(translation_)
324
+ return translations
325
+
326
+
327
+ def _compute_scales_from_factors(
328
+ base_scale: tuple[float, ...], scaling_factors: tuple[float, ...], num_levels: int
329
+ ) -> list[tuple[float, ...]]:
330
+ precision_scales = []
331
+ current_scale = base_scale
332
+ for _ in range(num_levels):
333
+ precision_scales.append(current_scale)
334
+ current_scale = tuple(
335
+ s * f for s, f in zip(current_scale, scaling_factors, strict=True)
336
+ )
337
+ return precision_scales
338
+
339
+
274
340
  class ImagePyramidBuilder(BaseModel):
275
341
  levels: list[PyramidLevel]
276
342
  axes: tuple[str, ...]
@@ -290,6 +356,7 @@ class ImagePyramidBuilder(BaseModel):
290
356
  base_shape: tuple[int, ...],
291
357
  base_scale: tuple[float, ...],
292
358
  axes: tuple[str, ...],
359
+ base_translation: Sequence[float] | None = None,
293
360
  chunks: ChunksLike = "auto",
294
361
  shards: ShardsLike | None = None,
295
362
  data_type: str = "uint16",
@@ -297,16 +364,39 @@ class ImagePyramidBuilder(BaseModel):
297
364
  compressors: Any = "auto",
298
365
  zarr_format: Literal[2, 3] = 2,
299
366
  other_array_kwargs: Mapping[str, Any] | None = None,
367
+ precision_scale: bool = True,
300
368
  ) -> "ImagePyramidBuilder":
301
- shapes = shapes_from_scaling_factors(
369
+ # Since shapes needs to be rounded to integers, we compute them here
370
+ # and then pass them to from_shapes
371
+ # This ensures that the shapes and scaling factors are consistent
372
+ # and avoids accumulation of rounding errors
373
+ shapes = compute_shapes_from_scaling_factors(
302
374
  base_shape=base_shape,
303
375
  scaling_factors=scaling_factors,
304
376
  num_levels=len(levels_paths),
305
377
  )
378
+
379
+ if precision_scale:
380
+ # Compute precise scales from shapes
381
+ # Since shapes are rounded to integers, the scaling factors
382
+ # may not be exactly the same as the input scaling factors
383
+ # Thus, we compute the scales from the shapes to ensure consistency
384
+ base_scale_ = compute_scales_from_shapes(
385
+ shapes=shapes,
386
+ base_scale=base_scale,
387
+ )
388
+ else:
389
+ base_scale_ = _compute_scales_from_factors(
390
+ base_scale=base_scale,
391
+ scaling_factors=scaling_factors,
392
+ num_levels=len(levels_paths),
393
+ )
394
+
306
395
  return cls.from_shapes(
307
396
  shapes=shapes,
308
- base_scale=base_scale,
397
+ base_scale=base_scale_,
309
398
  axes=axes,
399
+ base_translation=base_translation,
310
400
  levels_paths=levels_paths,
311
401
  chunks=chunks,
312
402
  shards=shards,
@@ -321,8 +411,9 @@ class ImagePyramidBuilder(BaseModel):
321
411
  def from_shapes(
322
412
  cls,
323
413
  shapes: Sequence[tuple[int, ...]],
324
- base_scale: tuple[float, ...],
414
+ base_scale: tuple[float, ...] | list[tuple[float, ...]],
325
415
  axes: tuple[str, ...],
416
+ base_translation: Sequence[float] | None = None,
326
417
  levels_paths: Sequence[str] | None = None,
327
418
  chunks: ChunksLike = "auto",
328
419
  shards: ShardsLike | None = None,
@@ -335,34 +426,42 @@ class ImagePyramidBuilder(BaseModel):
335
426
  levels = []
336
427
  if levels_paths is None:
337
428
  levels_paths = tuple(str(i) for i in range(len(shapes)))
429
+
338
430
  _check_order(shapes)
339
- scale_ = base_scale
340
- for i, (path, shape) in enumerate(zip(levels_paths, shapes, strict=True)):
341
- levels.append(
342
- PyramidLevel(
343
- path=path,
344
- shape=shape,
345
- scale=scale_,
346
- chunks=chunks,
347
- shards=shards,
431
+ if isinstance(base_scale, tuple) and all(
432
+ isinstance(s, float) for s in base_scale
433
+ ):
434
+ scales = compute_scales_from_shapes(shapes, base_scale)
435
+ elif isinstance(base_scale, list):
436
+ scales = base_scale
437
+ if len(scales) != len(shapes):
438
+ raise NgioValueError(
439
+ "Scales must have the same length as shapes "
440
+ f"({len(shapes)}), got {len(scales)}"
348
441
  )
442
+ else:
443
+ raise NgioValueError(
444
+ "base_scale must be either a tuple of floats or a list of tuples "
445
+ " of floats."
349
446
  )
350
- if i + 1 < len(shapes):
351
- # This only works for downsampling pyramids
352
- # The _check_order function ensures that
353
- # shapes are decreasing
354
- next_shape = shapes[i + 1]
355
- scaling_factor = tuple(
356
- s1 / s2
357
- for s1, s2 in zip(
358
- shape,
359
- next_shape,
360
- strict=True,
361
- )
362
- )
363
- scale_ = tuple(
364
- s * f for s, f in zip(scale_, scaling_factor, strict=True)
365
- )
447
+
448
+ translations = _compute_translations_from_shapes(scales, base_translation)
449
+ for level_path, shape, scale, translation in zip(
450
+ levels_paths,
451
+ shapes,
452
+ scales,
453
+ translations,
454
+ strict=True,
455
+ ):
456
+ level = PyramidLevel(
457
+ path=level_path,
458
+ shape=shape,
459
+ scale=scale,
460
+ translation=translation,
461
+ chunks=chunks,
462
+ shards=shards,
463
+ )
464
+ levels.append(level)
366
465
  other_array_kwargs = other_array_kwargs or {}
367
466
  return cls(
368
467
  levels=levels,
ngio/common/_roi.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Region of interest (ROI) metadata.
2
2
 
3
- These are the interfaces bwteen the ROI tables / masking ROI tables and
3
+ These are the interfaces between the ROI tables / masking ROI tables and
4
4
  the ImageLikeHandler.
5
5
  """
6
6
 
@@ -16,9 +16,15 @@ from ngio.common import (
16
16
  Roi,
17
17
  consolidate_pyramid,
18
18
  )
19
- from ngio.common._pyramid import ChunksLike, ShardsLike, shapes_from_scaling_factors
19
+ from ngio.common._pyramid import (
20
+ ChunksLike,
21
+ ShardsLike,
22
+ compute_scales_from_shapes,
23
+ compute_shapes_from_scaling_factors,
24
+ )
20
25
  from ngio.images._create_utils import (
21
26
  _image_or_label_meta,
27
+ compute_base_scale,
22
28
  init_image_like_from_shapes,
23
29
  )
24
30
  from ngio.io_pipes import (
@@ -602,32 +608,39 @@ def consolidate_image(
602
608
 
603
609
  def _shapes_from_ref_image(
604
610
  ref_image: AbstractImage,
605
- ) -> list[tuple[int, ...]]:
611
+ ) -> tuple[list[tuple[int, ...]], list[tuple[float, ...]]]:
606
612
  """Rebuild base shape based on a new shape."""
607
- paths = ref_image.meta.paths
613
+ meta = ref_image.meta
614
+ paths = meta.paths
608
615
  index_path = paths.index(ref_image.path)
609
616
  sub_paths = paths[index_path:]
610
617
  group_handler = ref_image._group_handler
611
- shapes = []
618
+ shapes, scales = [], []
612
619
  for path in sub_paths:
613
620
  zarr_array = group_handler.get_array(path)
614
621
  shapes.append(zarr_array.shape)
622
+ scales.append(meta.get_dataset(path=path).scale)
615
623
  if len(shapes) == len(paths):
616
- return shapes
624
+ return shapes, scales
617
625
  missing_levels = len(paths) - len(shapes)
618
- extended_shapes = shapes_from_scaling_factors(
626
+ extended_shapes = compute_shapes_from_scaling_factors(
619
627
  base_shape=shapes[-1],
620
628
  scaling_factors=ref_image.meta.scaling_factor(),
621
629
  num_levels=missing_levels + 1,
622
630
  )
623
631
  shapes.extend(extended_shapes[1:])
624
- return shapes
632
+ extended_scales = compute_scales_from_shapes(
633
+ shapes=extended_shapes,
634
+ base_scale=scales[-1],
635
+ )
636
+ scales.extend(extended_scales[1:])
637
+ return shapes, scales
625
638
 
626
639
 
627
640
  def _shapes_from_new_shape(
628
641
  ref_image: AbstractImage,
629
642
  shape: Sequence[int],
630
- ) -> list[tuple[int, ...]]:
643
+ ) -> tuple[list[tuple[int, ...]], list[tuple[float, ...]]]:
631
644
  """Rebuild pyramid shapes based on a new base shape."""
632
645
  if len(shape) != len(ref_image.shape):
633
646
  raise NgioValueError(
@@ -637,27 +650,33 @@ def _shapes_from_new_shape(
637
650
  base_shape = tuple(shape)
638
651
  scaling_factors = ref_image.meta.scaling_factor()
639
652
  num_levels = len(ref_image.meta.paths)
640
- return shapes_from_scaling_factors(
653
+ shapes = compute_shapes_from_scaling_factors(
641
654
  base_shape=base_shape,
642
655
  scaling_factors=scaling_factors,
643
656
  num_levels=num_levels,
644
657
  )
658
+ scales = compute_scales_from_shapes(
659
+ shapes=shapes,
660
+ base_scale=ref_image.dataset.scale,
661
+ )
662
+ return shapes, scales
645
663
 
646
664
 
647
665
  def _compute_pyramid_shapes(
648
666
  ref_image: AbstractImage,
649
667
  shape: Sequence[int] | None,
650
- ) -> list[tuple[int, ...]]:
668
+ ) -> tuple[list[tuple[int, ...]], list[tuple[float, ...]]]:
651
669
  """Rebuild pyramid shapes based on a new base shape."""
652
670
  if shape is None:
653
671
  return _shapes_from_ref_image(ref_image=ref_image)
654
672
  return _shapes_from_new_shape(ref_image=ref_image, shape=shape)
655
673
 
656
674
 
657
- def _check_chunks_and_shards_compatibility(
675
+ def _check_len_compatibility(
658
676
  ref_shape: tuple[int, ...],
659
677
  chunks: ChunksLike,
660
678
  shards: ShardsLike | None,
679
+ translation: Sequence[float] | None = None,
661
680
  ) -> None:
662
681
  """Check if the chunks and shards are compatible with the reference shape.
663
682
 
@@ -665,6 +684,7 @@ def _check_chunks_and_shards_compatibility(
665
684
  ref_shape: The reference shape.
666
685
  chunks: The chunks to check.
667
686
  shards: The shards to check.
687
+ translation: The translation to check.
668
688
  """
669
689
  if chunks != "auto":
670
690
  if len(chunks) != len(ref_shape):
@@ -676,6 +696,12 @@ def _check_chunks_and_shards_compatibility(
676
696
  raise NgioValueError(
677
697
  "The length of the shards must be the same as the number of dimensions."
678
698
  )
699
+ if translation is not None:
700
+ if len(translation) != len(ref_shape):
701
+ raise NgioValueError(
702
+ "The length of the translation must be the same as the number of "
703
+ "dimensions."
704
+ )
679
705
 
680
706
 
681
707
  def _apply_channel_policy(
@@ -685,7 +711,16 @@ def _apply_channel_policy(
685
711
  axes: tuple[str, ...],
686
712
  chunks: ChunksLike,
687
713
  shards: ShardsLike | None,
688
- ) -> tuple[list[tuple[int, ...]], tuple[str, ...], ChunksLike, ShardsLike | None]:
714
+ translation: Sequence[float],
715
+ scales: list[tuple[float, ...]] | tuple[float, ...],
716
+ ) -> tuple[
717
+ list[tuple[int, ...]],
718
+ tuple[str, ...],
719
+ ChunksLike,
720
+ ShardsLike | None,
721
+ tuple[float, ...],
722
+ list[tuple[float, ...]] | tuple[float, ...],
723
+ ]:
689
724
  """Apply the channel policy to the shapes and axes.
690
725
 
691
726
  Args:
@@ -695,12 +730,15 @@ def _apply_channel_policy(
695
730
  axes: The axes of the image.
696
731
  chunks: The chunks of the image.
697
732
  shards: The shards of the image.
733
+ translation: The translation of the image.
734
+ scales: The scales of the image.
698
735
 
699
736
  Returns:
700
737
  The new shapes and axes after applying the channel policy.
701
738
  """
739
+ translation = tuple(translation)
702
740
  if channels_policy == "same":
703
- return shapes, axes, chunks, shards
741
+ return shapes, axes, chunks, shards, translation, scales
704
742
 
705
743
  if channels_policy == "singleton":
706
744
  # Treat 'singleton' as setting channel size to 1
@@ -709,7 +747,7 @@ def _apply_channel_policy(
709
747
  channel_index = ref_image.axes_handler.get_index("c")
710
748
  if channel_index is None:
711
749
  if channels_policy == "squeeze":
712
- return shapes, axes, chunks, shards
750
+ return shapes, axes, chunks, shards, translation, scales
713
751
  raise NgioValueError(
714
752
  f"Cannot apply channel policy {channels_policy=} to an image "
715
753
  "without channels axis."
@@ -719,6 +757,15 @@ def _apply_channel_policy(
719
757
  for shape in shapes:
720
758
  new_shape = shape[:channel_index] + shape[channel_index + 1 :]
721
759
  new_shapes.append(new_shape)
760
+
761
+ if isinstance(scales, tuple):
762
+ new_scales = scales[:channel_index] + scales[channel_index + 1 :]
763
+ else:
764
+ new_scales = []
765
+ for scale in scales:
766
+ new_scale = scale[:channel_index] + scale[channel_index + 1 :]
767
+ new_scales.append(new_scale)
768
+
722
769
  new_axes = axes[:channel_index] + axes[channel_index + 1 :]
723
770
  if chunks == "auto":
724
771
  new_chunks: ChunksLike = "auto"
@@ -728,7 +775,9 @@ def _apply_channel_policy(
728
775
  new_shards: ShardsLike | None = shards
729
776
  else:
730
777
  new_shards = shards[:channel_index] + shards[channel_index + 1 :]
731
- return new_shapes, new_axes, new_chunks, new_shards
778
+
779
+ translation = translation[:channel_index] + translation[channel_index + 1 :]
780
+ return new_shapes, new_axes, new_chunks, new_shards, translation, new_scales
732
781
  elif isinstance(channels_policy, int):
733
782
  new_shapes = []
734
783
  for shape in shapes:
@@ -738,7 +787,7 @@ def _apply_channel_policy(
738
787
  *shape[channel_index + 1 :],
739
788
  )
740
789
  new_shapes.append(new_shape)
741
- return new_shapes, axes, chunks, shards
790
+ return new_shapes, axes, chunks, shards, translation, scales
742
791
  else:
743
792
  raise NgioValueError(
744
793
  f"Invalid channels policy: {channels_policy}. "
@@ -783,6 +832,35 @@ def _check_channels_meta_compatibility(
783
832
  return channels_meta_
784
833
 
785
834
 
835
+ def adapt_scales(
836
+ scales: list[tuple[float, ...]],
837
+ pixelsize: float | tuple[float, float] | None,
838
+ z_spacing: float | None,
839
+ time_spacing: float | None,
840
+ ref_image: AbstractImage,
841
+ ) -> list[tuple[float, ...]] | tuple[float, ...]:
842
+ if pixelsize is None and z_spacing is None and time_spacing is None:
843
+ return scales
844
+ pixel_size = ref_image.pixel_size
845
+ if pixelsize is None:
846
+ pixelsize = (pixel_size.y, pixel_size.x)
847
+ if z_spacing is None:
848
+ z_spacing = pixel_size.z
849
+ else:
850
+ z_spacing = z_spacing
851
+ if time_spacing is None:
852
+ time_spacing = pixel_size.t
853
+ else:
854
+ time_spacing = time_spacing
855
+ base_scale = compute_base_scale(
856
+ pixelsize=pixelsize,
857
+ z_spacing=z_spacing,
858
+ time_spacing=time_spacing,
859
+ axes_handler=ref_image.axes_handler,
860
+ )
861
+ return base_scale
862
+
863
+
786
864
  def abstract_derive(
787
865
  *,
788
866
  ref_image: AbstractImage,
@@ -795,6 +873,7 @@ def abstract_derive(
795
873
  z_spacing: float | None = None,
796
874
  time_spacing: float | None = None,
797
875
  name: str | None = None,
876
+ translation: Sequence[float] | None = None,
798
877
  channels_policy: Literal["squeeze", "same", "singleton"] | int = "same",
799
878
  channels_meta: Sequence[str | Channel] | None = None,
800
879
  ngff_version: NgffVersions | None = None,
@@ -822,8 +901,9 @@ def abstract_derive(
822
901
  pixelsize (float | tuple[float, float] | None): The pixel size of the new image.
823
902
  z_spacing (float | None): The z spacing of the new image.
824
903
  time_spacing (float | None): The time spacing of the new image.
825
- axes_names (Sequence[str] | None): The axes names of the new image.
826
904
  name (str | None): The name of the new image.
905
+ translation (Sequence[float] | None): The translation for each axis
906
+ at the highest resolution level. Defaults to None.
827
907
  channels_policy (Literal["squeeze", "same", "singleton"] | int):
828
908
  Possible policies:
829
909
  - If "squeeze", the channels axis will be removed (no matter its size).
@@ -837,7 +917,7 @@ def abstract_derive(
837
917
  chunks (ChunksLike | None): The chunk shape of the new image.
838
918
  shards (ShardsLike | None): The shard shape of the new image.
839
919
  dtype (str | None): The data type of the new image.
840
- dimension_separator (DIMENSION_SEPARATOR | None): The separator to use for
920
+ dimension_separator (Literal[".", "/"] | None): The separator to use for
841
921
  dimensions.
842
922
  compressors (CompressorLike | None): The compressors to use.
843
923
  extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
@@ -868,40 +948,23 @@ def abstract_derive(
868
948
  DeprecationWarning,
869
949
  stacklevel=2,
870
950
  )
871
- pixelsize_ = (pixel_size.y, pixel_size.x)
872
- z_spacing_ = pixel_size.z
873
- time_spacing_ = pixel_size.t
874
- else:
875
- if pixelsize is None:
876
- pixelsize_ = (ref_image.pixel_size.y, ref_image.pixel_size.x)
877
- else:
878
- pixelsize_ = pixelsize
879
-
880
- if z_spacing is None:
881
- z_spacing_ = ref_image.pixel_size.z
882
- else:
883
- z_spacing_ = z_spacing
884
-
885
- if time_spacing is None:
886
- time_spacing_ = ref_image.pixel_size.t
887
- else:
888
- time_spacing_ = time_spacing
951
+ pixelsize = (pixel_size.y, pixel_size.x)
952
+ # End of deprecated arguments handling
889
953
  ref_meta = ref_image.meta
890
954
 
891
- shapes = _compute_pyramid_shapes(
955
+ shapes, scales = _compute_pyramid_shapes(
892
956
  shape=shape,
893
957
  ref_image=ref_image,
894
958
  )
895
959
  ref_shape = next(iter(shapes))
896
960
 
897
- if pixelsize is None:
898
- pixelsize = (ref_image.pixel_size.y, ref_image.pixel_size.x)
899
-
900
- if z_spacing is None:
901
- z_spacing = ref_image.pixel_size.z
902
-
903
- if time_spacing is None:
904
- time_spacing = ref_image.pixel_size.t
961
+ scales = adapt_scales(
962
+ scales=scales,
963
+ pixelsize=pixelsize,
964
+ z_spacing=z_spacing,
965
+ time_spacing=time_spacing,
966
+ ref_image=ref_image,
967
+ )
905
968
 
906
969
  if name is None:
907
970
  name = ref_meta.name
@@ -915,27 +978,33 @@ def abstract_derive(
915
978
  if compressors is None:
916
979
  compressors = ref_image.zarr_array.compressors # type: ignore
917
980
 
981
+ if translation is None:
982
+ translation = ref_image.dataset.translation
983
+
918
984
  if chunks is None:
919
985
  chunks = ref_image.zarr_array.chunks
920
986
  if shards is None:
921
987
  shards = ref_image.zarr_array.shards
922
988
 
923
- _check_chunks_and_shards_compatibility(
989
+ _check_len_compatibility(
924
990
  ref_shape=ref_shape,
925
991
  chunks=chunks,
926
992
  shards=shards,
993
+ translation=translation,
927
994
  )
928
995
 
929
996
  if ngff_version is None:
930
997
  ngff_version = ref_meta.version
931
998
 
932
- shapes, axes, chunks, shards = _apply_channel_policy(
999
+ shapes, axes, chunks, shards, translation, scales = _apply_channel_policy(
933
1000
  ref_image=ref_image,
934
1001
  channels_policy=channels_policy,
935
1002
  shapes=shapes,
936
1003
  axes=ref_image.axes,
937
1004
  chunks=chunks,
938
1005
  shards=shards,
1006
+ translation=translation,
1007
+ scales=scales,
939
1008
  )
940
1009
  channels_meta_ = _check_channels_meta_compatibility(
941
1010
  meta_type=meta_type,
@@ -947,10 +1016,9 @@ def abstract_derive(
947
1016
  store=store,
948
1017
  meta_type=meta_type,
949
1018
  shapes=shapes,
950
- pixelsize=pixelsize_,
951
- z_spacing=z_spacing_,
952
- time_spacing=time_spacing_,
1019
+ base_scale=scales,
953
1020
  levels=ref_meta.paths,
1021
+ translation=translation,
954
1022
  time_unit=ref_image.time_unit,
955
1023
  space_unit=ref_image.space_unit,
956
1024
  axes_names=axes,
@@ -30,6 +30,7 @@ def create_synthetic_ome_zarr(
30
30
  shape: Sequence[int],
31
31
  reference_sample: AVAILABLE_SAMPLES | SampleInfo = "Cardiomyocyte",
32
32
  levels: int | list[str] = 5,
33
+ translation: Sequence[float] | None = None,
33
34
  table_backend: TableBackend = DefaultTableBackend,
34
35
  scaling_factors: Sequence[float] | Literal["auto"] = "auto",
35
36
  axes_names: Sequence[str] | None = None,
@@ -51,6 +52,8 @@ def create_synthetic_ome_zarr(
51
52
  Defaults to "Cardiomyocyte".
52
53
  levels (int | list[str]): The number of levels in the pyramid or a list of
53
54
  level names. Defaults to 5.
55
+ translation (Sequence[float] | None): The translation for each axis
56
+ at the highest resolution level. Defaults to None.
54
57
  table_backend (TableBackend): Table backend to be used to store tables.
55
58
  Defaults to DefaultTableBackend.
56
59
  scaling_factors (Sequence[float] | Literal["auto"]): The down-scaling factors
@@ -86,6 +89,7 @@ def create_synthetic_ome_zarr(
86
89
  z_spacing=sample_info.z_spacing,
87
90
  time_spacing=sample_info.time_spacing,
88
91
  levels=levels,
92
+ translation=translation,
89
93
  space_unit=sample_info.space_unit,
90
94
  time_unit=sample_info.time_unit,
91
95
  axes_names=axes_names,
@@ -149,7 +149,7 @@ def _compute_scaling_factors(
149
149
  return tuple(scaling_factors)
150
150
 
151
151
 
152
- def _compute_base_scale(
152
+ def compute_base_scale(
153
153
  *,
154
154
  pixelsize: float | tuple[float, float],
155
155
  z_spacing: float,
@@ -243,6 +243,7 @@ def init_image_like(
243
243
  time_spacing: float = 1.0,
244
244
  scaling_factors: Sequence[float] | Literal["auto"] = "auto",
245
245
  levels: int | list[str] = 5,
246
+ translation: Sequence[float] | None = None,
246
247
  space_unit: SpaceUnits | str | None = DefaultSpaceUnit,
247
248
  time_unit: TimeUnits | str | None = DefaultTimeUnit,
248
249
  axes_names: Sequence[str] | None = None,
@@ -283,7 +284,7 @@ def init_image_like(
283
284
  allow_non_canonical_axes=allow_non_canonical_axes,
284
285
  strict_canonical_order=strict_canonical_order,
285
286
  )
286
- base_scale = _compute_base_scale(
287
+ base_scale = compute_base_scale(
287
288
  pixelsize=pixelsize,
288
289
  z_spacing=z_spacing,
289
290
  time_spacing=time_spacing,
@@ -306,6 +307,7 @@ def init_image_like(
306
307
  scaling_factors=scaling_factors,
307
308
  base_shape=shape,
308
309
  base_scale=base_scale,
310
+ base_translation=translation,
309
311
  axes=axes_handler.axes_names,
310
312
  chunks=chunks,
311
313
  data_type=dtype,
@@ -319,7 +321,7 @@ def init_image_like(
319
321
  levels=[p.path for p in pyramid_builder.levels],
320
322
  axes_handler=axes_handler,
321
323
  scales=[p.scale for p in pyramid_builder.levels],
322
- translations=[None for _ in pyramid_builder.levels],
324
+ translations=[p.translation for p in pyramid_builder.levels],
323
325
  name=name,
324
326
  version=ngff_version,
325
327
  )
@@ -340,10 +342,9 @@ def init_image_like_from_shapes(
340
342
  # Ngff image parameters
341
343
  meta_type: type[_image_or_label_meta],
342
344
  shapes: Sequence[tuple[int, ...]],
343
- pixelsize: float | tuple[float, float],
344
- z_spacing: float = 1.0,
345
- time_spacing: float = 1.0,
345
+ base_scale: tuple[float, ...] | list[tuple[float, ...]],
346
346
  levels: list[str] | None = None,
347
+ translation: Sequence[float] | None = None,
347
348
  space_unit: SpaceUnits | str | None = DefaultSpaceUnit,
348
349
  time_unit: TimeUnits | str | None = DefaultTimeUnit,
349
350
  axes_names: Sequence[str] | None = None,
@@ -381,12 +382,6 @@ def init_image_like_from_shapes(
381
382
  allow_non_canonical_axes=allow_non_canonical_axes,
382
383
  strict_canonical_order=strict_canonical_order,
383
384
  )
384
- base_scale = _compute_base_scale(
385
- pixelsize=pixelsize,
386
- z_spacing=z_spacing,
387
- time_spacing=time_spacing,
388
- axes_handler=axes_handler,
389
- )
390
385
  if levels is None:
391
386
  levels_paths = tuple(str(i) for i in range(len(shapes)))
392
387
  else:
@@ -395,6 +390,7 @@ def init_image_like_from_shapes(
395
390
  pyramid_builder = ImagePyramidBuilder.from_shapes(
396
391
  shapes=shapes,
397
392
  base_scale=base_scale,
393
+ base_translation=translation,
398
394
  levels_paths=levels_paths,
399
395
  axes=axes_handler.axes_names,
400
396
  chunks=chunks,
@@ -409,7 +405,7 @@ def init_image_like_from_shapes(
409
405
  levels=[p.path for p in pyramid_builder.levels],
410
406
  axes_handler=axes_handler,
411
407
  scales=[p.scale for p in pyramid_builder.levels],
412
- translations=[None for _ in pyramid_builder.levels],
408
+ translations=[p.translation for p in pyramid_builder.levels],
413
409
  name=name,
414
410
  version=ngff_version,
415
411
  )
ngio/images/_image.py CHANGED
@@ -612,6 +612,7 @@ class ImagesContainer:
612
612
  z_spacing: float | None = None,
613
613
  time_spacing: float | None = None,
614
614
  name: str | None = None,
615
+ translation: Sequence[float] | None = None,
615
616
  channels_meta: Sequence[str | Channel] | None = None,
616
617
  channels_policy: Literal["same", "squeeze", "singleton"] | int = "same",
617
618
  ngff_version: NgffVersions | None = None,
@@ -643,6 +644,8 @@ class ImagesContainer:
643
644
  z_spacing (float | None): The z spacing of the new image.
644
645
  time_spacing (float | None): The time spacing of the new image.
645
646
  name (str | None): The name of the new image.
647
+ translation (Sequence[float] | None): The translation for each axis
648
+ at the highest resolution level. Defaults to None.
646
649
  channels_meta (Sequence[str | Channel] | None): The channels metadata
647
650
  of the new image.
648
651
  channels_policy (Literal["same", "squeeze", "singleton"] | int):
@@ -656,7 +659,7 @@ class ImagesContainer:
656
659
  chunks (ChunksLike | None): The chunk shape of the new image.
657
660
  shards (ShardsLike | None): The shard shape of the new image.
658
661
  dtype (str | None): The data type of the new image.
659
- dimension_separator (DIMENSION_SEPARATOR | None): The separator to use for
662
+ dimension_separator (Literal[".", "/"] | None): The separator to use for
660
663
  dimensions.
661
664
  compressors (CompressorLike | None): The compressors to use.
662
665
  extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
@@ -681,6 +684,7 @@ class ImagesContainer:
681
684
  z_spacing=z_spacing,
682
685
  time_spacing=time_spacing,
683
686
  name=name,
687
+ translation=translation,
684
688
  channels_meta=channels_meta,
685
689
  channels_policy=channels_policy,
686
690
  ngff_version=ngff_version,
@@ -774,6 +778,7 @@ def derive_image_container(
774
778
  z_spacing: float | None = None,
775
779
  time_spacing: float | None = None,
776
780
  name: str | None = None,
781
+ translation: Sequence[float] | None = None,
777
782
  channels_policy: Literal["same", "squeeze", "singleton"] | int = "same",
778
783
  channels_meta: Sequence[str | Channel] | None = None,
779
784
  ngff_version: NgffVersions | None = None,
@@ -803,6 +808,8 @@ def derive_image_container(
803
808
  z_spacing (float | None): The z spacing of the new image.
804
809
  time_spacing (float | None): The time spacing of the new image.
805
810
  name (str | None): The name of the new image.
811
+ translation (Sequence[float] | None): The translation for each axis
812
+ at the highest resolution level. Defaults to None.
806
813
  channels_policy (Literal["squeeze", "same", "singleton"] | int): Possible
807
814
  policies:
808
815
  - If "squeeze", the channels axis will be removed (no matter its size).
@@ -842,6 +849,7 @@ def derive_image_container(
842
849
  z_spacing=z_spacing,
843
850
  time_spacing=time_spacing,
844
851
  name=name,
852
+ translation=translation,
845
853
  channels_meta=channels_meta,
846
854
  channels_policy=channels_policy,
847
855
  ngff_version=ngff_version,
ngio/images/_label.py CHANGED
@@ -218,6 +218,7 @@ class LabelsContainer:
218
218
  pixelsize: float | tuple[float, float] | None = None,
219
219
  z_spacing: float | None = None,
220
220
  time_spacing: float | None = None,
221
+ translation: Sequence[float] | None = None,
221
222
  channels_policy: Literal["same", "squeeze", "singleton"] | int = "squeeze",
222
223
  ngff_version: NgffVersions | None = None,
223
224
  # Zarr Array parameters
@@ -232,24 +233,20 @@ class LabelsContainer:
232
233
  labels: Sequence[str] | None = None,
233
234
  pixel_size: PixelSize | None = None,
234
235
  ) -> "Label":
235
- """Create an empty OME-Zarr image from an existing image.
236
+ """Create an empty OME-Zarr label from an existing image or label.
236
237
 
237
238
  If a kwarg is not provided, the value from the reference image will be used.
238
239
 
239
240
  Args:
240
- store (StoreOrGroup): The Zarr store or group to create the image in.
241
- ref_image (Image | Label): The reference image to derive the new image from.
242
- shape (Sequence[int] | None): The shape of the new image.
241
+ name (str): The name of the new label.
242
+ ref_image (Image | Label): The reference image to derive the new label from.
243
+ shape (Sequence[int] | None): The shape of the new label.
243
244
  pixelsize (float | tuple[float, float] | None): The pixel size of the new
244
- image.
245
- z_spacing (float | None): The z spacing of the new image.
246
- time_spacing (float | None): The time spacing of the new image.
247
- scaling_factors (Sequence[float] | Literal["auto"] | None): The scaling
248
- factors of the new image.
249
- axes_names (Sequence[str] | None): The axes names of the new image.
250
- name (str | None): The name of the new image.
251
- channels_meta (Sequence[str | Channel] | None): The channels metadata
252
- of the new image.
245
+ label.
246
+ z_spacing (float | None): The z spacing of the new label.
247
+ time_spacing (float | None): The time spacing of the new label.
248
+ translation (Sequence[float] | None): The translation for each axis
249
+ at the highest resolution level. Defaults to None.
253
250
  channels_policy (Literal["squeeze", "same", "singleton"] | int):
254
251
  Possible policies:
255
252
  - If "squeeze", the channels axis will be removed (no matter its size).
@@ -258,19 +255,19 @@ class LabelsContainer:
258
255
  - If an integer is provided, the channels axis will be changed to have
259
256
  that size.
260
257
  ngff_version (NgffVersions | None): The NGFF version to use.
261
- chunks (ChunksLike | None): The chunk shape of the new image.
262
- shards (ShardsLike | None): The shard shape of the new image.
263
- dtype (str | None): The data type of the new image.
264
- dimension_separator (DIMENSION_SEPARATOR | None): The separator to use for
258
+ chunks (ChunksLike | None): The chunk shape of the new label.
259
+ shards (ShardsLike | None): The shard shape of the new label.
260
+ dtype (str | None): The data type of the new label.
261
+ dimension_separator (Literal[".", "/"] | None): The separator to use for
265
262
  dimensions.
266
263
  compressors (CompressorLike | None): The compressors to use.
267
264
  extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
268
265
  the zarr array creation.
269
- overwrite (bool): Whether to overwrite an existing image.
270
- labels (Sequence[str] | None): The labels of the new image.
271
- This argument is deprecated please use channels_meta instead.
272
- pixel_size (PixelSize | None): The pixel size of the new image.
273
- This argument is deprecated please use pixelsize, z_spacing,
266
+ overwrite (bool): Whether to overwrite an existing label.
267
+ labels (Sequence[str] | None): Deprecated. This argument is deprecated,
268
+ please use channels_meta instead.
269
+ pixel_size (PixelSize | None): Deprecated. The pixel size of the new label.
270
+ This argument is deprecated, please use pixelsize, z_spacing,
274
271
  and time_spacing instead.
275
272
 
276
273
  Returns:
@@ -294,6 +291,7 @@ class LabelsContainer:
294
291
  z_spacing=z_spacing,
295
292
  time_spacing=time_spacing,
296
293
  name=name,
294
+ translation=translation,
297
295
  channels_policy=channels_policy,
298
296
  ngff_version=ngff_version,
299
297
  chunks=chunks,
@@ -327,6 +325,7 @@ def derive_label(
327
325
  z_spacing: float | None = None,
328
326
  time_spacing: float | None = None,
329
327
  name: str | None = None,
328
+ translation: Sequence[float] | None = None,
330
329
  channels_policy: Literal["same", "squeeze", "singleton"] | int = "squeeze",
331
330
  ngff_version: NgffVersions | None = None,
332
331
  # Zarr Array parameters
@@ -353,6 +352,8 @@ def derive_label(
353
352
  z_spacing (float | None): The z spacing of the new label.
354
353
  time_spacing (float | None): The time spacing of the new label.
355
354
  name (str | None): The name of the new label.
355
+ translation (Sequence[float] | None): The translation for each axis
356
+ at the highest resolution level. Defaults to None.
356
357
  channels_policy (Literal["squeeze", "same", "singleton"] | int): Possible
357
358
  policies:
358
359
  - If "squeeze", the channels axis will be removed (no matter its size).
@@ -391,6 +392,7 @@ def derive_label(
391
392
  z_spacing=z_spacing,
392
393
  time_spacing=time_spacing,
393
394
  name=name,
395
+ translation=translation,
394
396
  channels_meta=None,
395
397
  channels_policy=channels_policy,
396
398
  ngff_version=ngff_version,
@@ -266,8 +266,8 @@ class OmeZarrContainer:
266
266
 
267
267
  def set_channel_meta(
268
268
  self,
269
- labels: Sequence[str] | int | None = None,
270
- wavelength_id: Sequence[str] | None = None,
269
+ labels: Sequence[str | None] | int | None = None,
270
+ wavelength_id: Sequence[str | None] | None = None,
271
271
  percentiles: tuple[float, float] | None = None,
272
272
  colors: Sequence[str] | None = None,
273
273
  active: Sequence[bool] | None = None,
@@ -430,6 +430,7 @@ class OmeZarrContainer:
430
430
  z_spacing: float | None = None,
431
431
  time_spacing: float | None = None,
432
432
  name: str | None = None,
433
+ translation: Sequence[float] | None = None,
433
434
  channels_policy: Literal["squeeze", "same", "singleton"] | int = "same",
434
435
  channels_meta: Sequence[str | Channel] | None = None,
435
436
  ngff_version: NgffVersions | None = None,
@@ -462,7 +463,10 @@ class OmeZarrContainer:
462
463
  z_spacing (float | None): The z spacing of the new image.
463
464
  time_spacing (float | None): The time spacing of the new image.
464
465
  name (str | None): The name of the new image.
465
- channels_policy (Literal["squeeze", "same"] | int): Possible policies:
466
+ translation (Sequence[float] | None): The translation for each axis
467
+ at the highest resolution level. Defaults to None.
468
+ channels_policy (Literal["squeeze", "same", "singleton"] | int): Possible
469
+ policies:
466
470
  - If "squeeze", the channels axis will be removed (no matter its size).
467
471
  - If "same", the channels axis will be kept as is (if it exists).
468
472
  - If "singleton", the channels axis will be set to size 1.
@@ -502,6 +506,7 @@ class OmeZarrContainer:
502
506
  z_spacing=z_spacing,
503
507
  time_spacing=time_spacing,
504
508
  name=name,
509
+ translation=translation,
505
510
  channels_meta=channels_meta,
506
511
  channels_policy=channels_policy,
507
512
  ngff_version=ngff_version,
@@ -787,6 +792,7 @@ class OmeZarrContainer:
787
792
  pixelsize: float | tuple[float, float] | None = None,
788
793
  z_spacing: float | None = None,
789
794
  time_spacing: float | None = None,
795
+ translation: Sequence[float] | None = None,
790
796
  channels_policy: Literal["same", "squeeze", "singleton"] | int = "squeeze",
791
797
  ngff_version: NgffVersions | None = None,
792
798
  # Zarr Array parameters
@@ -814,7 +820,10 @@ class OmeZarrContainer:
814
820
  label.
815
821
  z_spacing (float | None): The z spacing of the new label.
816
822
  time_spacing (float | None): The time spacing of the new label.
817
- channels_policy (Literal["same", "squeeze"] | int): Possible policies:
823
+ translation (Sequence[float] | None): The translation for each axis
824
+ at the highest resolution level. Defaults to None.
825
+ channels_policy (Literal["same", "squeeze", "singleton"] | int): Possible
826
+ policies:
818
827
  - If "squeeze", the channels axis will be removed (no matter its size).
819
828
  - If "same", the channels axis will be kept as is (if it exists).
820
829
  - If "singleton", the channels axis will be set to size 1.
@@ -850,6 +859,7 @@ class OmeZarrContainer:
850
859
  pixelsize=pixelsize,
851
860
  z_spacing=z_spacing,
852
861
  time_spacing=time_spacing,
862
+ translation=translation,
853
863
  channels_policy=channels_policy,
854
864
  ngff_version=ngff_version,
855
865
  chunks=chunks,
@@ -959,6 +969,7 @@ def create_empty_ome_zarr(
959
969
  time_spacing: float = 1.0,
960
970
  scaling_factors: Sequence[float] | Literal["auto"] = "auto",
961
971
  levels: int | list[str] = 5,
972
+ translation: Sequence[float] | None = None,
962
973
  space_unit: SpaceUnits = DefaultSpaceUnit,
963
974
  time_unit: TimeUnits = DefaultTimeUnit,
964
975
  axes_names: Sequence[str] | None = None,
@@ -994,6 +1005,8 @@ def create_empty_ome_zarr(
994
1005
  for the pyramid levels. Defaults to "auto".
995
1006
  levels (int | list[str]): The number of levels in the pyramid or a list of
996
1007
  level names. Defaults to 5.
1008
+ translation (Sequence[float] | None): The translation for each axis.
1009
+ at the highest resolution level. Defaults to None.
997
1010
  space_unit (SpaceUnits): The unit of space. Defaults to DefaultSpaceUnit.
998
1011
  time_unit (TimeUnits): The unit of time. Defaults to DefaultTimeUnit.
999
1012
  axes_names (Sequence[str] | None): The names of the axes. If None the
@@ -1086,6 +1099,7 @@ def create_empty_ome_zarr(
1086
1099
  time_spacing=time_spacing,
1087
1100
  scaling_factors=scaling_factors,
1088
1101
  levels=levels,
1102
+ translation=translation,
1089
1103
  space_unit=space_unit,
1090
1104
  time_unit=time_unit,
1091
1105
  axes_names=axes_names,
@@ -1131,6 +1145,7 @@ def create_ome_zarr_from_array(
1131
1145
  time_spacing: float = 1.0,
1132
1146
  scaling_factors: Sequence[float] | Literal["auto"] = "auto",
1133
1147
  levels: int | list[str] = 5,
1148
+ translation: Sequence[float] | None = None,
1134
1149
  space_unit: SpaceUnits = DefaultSpaceUnit,
1135
1150
  time_unit: TimeUnits = DefaultTimeUnit,
1136
1151
  axes_names: Sequence[str] | None = None,
@@ -1166,6 +1181,8 @@ def create_ome_zarr_from_array(
1166
1181
  for the pyramid levels. Defaults to "auto".
1167
1182
  levels (int | list[str]): The number of levels in the pyramid or a list of
1168
1183
  level names. Defaults to 5.
1184
+ translation (Sequence[float] | None): The translation for each axis.
1185
+ at the highest resolution level. Defaults to None.
1169
1186
  space_unit (SpaceUnits): The unit of space. Defaults to DefaultSpaceUnit.
1170
1187
  time_unit (TimeUnits): The unit of time. Defaults to DefaultTimeUnit.
1171
1188
  axes_names (Sequence[str] | None): The names of the axes. If None the
@@ -1201,6 +1218,7 @@ def create_ome_zarr_from_array(
1201
1218
  time_spacing=time_spacing,
1202
1219
  scaling_factors=scaling_factors,
1203
1220
  levels=levels,
1221
+ translation=translation,
1204
1222
  space_unit=space_unit,
1205
1223
  time_unit=time_unit,
1206
1224
  axes_names=axes_names,
@@ -15,6 +15,9 @@ from ngio.ome_zarr_meta._meta_handlers import (
15
15
  )
16
16
  from ngio.ome_zarr_meta.ngio_specs import (
17
17
  AxesHandler,
18
+ Channel,
19
+ ChannelsMeta,
20
+ ChannelVisualisation,
18
21
  Dataset,
19
22
  DefaultNgffVersion,
20
23
  ImageInWellPath,
@@ -31,6 +34,9 @@ from ngio.ome_zarr_meta.ngio_specs import (
31
34
 
32
35
  __all__ = [
33
36
  "AxesHandler",
37
+ "Channel",
38
+ "ChannelVisualisation",
39
+ "ChannelsMeta",
34
40
  "Dataset",
35
41
  "DefaultNgffVersion",
36
42
  "ImageInWellPath",
@@ -9,6 +9,9 @@ For Images and Labels implements the following functionalities:
9
9
  - A function to convert a ngio image metadata to a v04 image metadata.
10
10
  """
11
11
 
12
+ from ome_zarr_models.common.coordinate_transformations import (
13
+ ValidTransform as ValidTransformV04,
14
+ )
12
15
  from ome_zarr_models.v04.axes import Axis as AxisV04
13
16
  from ome_zarr_models.v04.coordinate_transformations import VectorScale as VectorScaleV04
14
17
  from ome_zarr_models.v04.coordinate_transformations import (
@@ -20,7 +23,6 @@ from ome_zarr_models.v04.image_label import ImageLabelAttrs as ImageLabelAttrsV0
20
23
  from ome_zarr_models.v04.labels import LabelsAttrs as LabelsAttrsV04
21
24
  from ome_zarr_models.v04.multiscales import Dataset as DatasetV04
22
25
  from ome_zarr_models.v04.multiscales import Multiscale as MultiscaleV04
23
- from ome_zarr_models.v04.multiscales import ValidTransform as ValidTransformV04
24
26
  from ome_zarr_models.v04.omero import Channel as ChannelV04
25
27
  from ome_zarr_models.v04.omero import Omero as OmeroV04
26
28
  from ome_zarr_models.v04.omero import Window as WindowV04
@@ -9,6 +9,9 @@ For Images and Labels implements the following functionalities:
9
9
  - A function to convert a ngio image metadata to a v05 image metadata.
10
10
  """
11
11
 
12
+ from ome_zarr_models.common.coordinate_transformations import (
13
+ ValidTransform as ValidTransformV05,
14
+ )
12
15
  from ome_zarr_models.common.omero import Channel as ChannelV05
13
16
  from ome_zarr_models.common.omero import Omero as OmeroV05
14
17
  from ome_zarr_models.common.omero import Window as WindowV05
@@ -24,7 +27,6 @@ from ome_zarr_models.v05.labels import Labels as Labels
24
27
  from ome_zarr_models.v05.labels import LabelsAttrs as LabelsAttrsV05
25
28
  from ome_zarr_models.v05.multiscales import Dataset as DatasetV05
26
29
  from ome_zarr_models.v05.multiscales import Multiscale as MultiscaleV05
27
- from ome_zarr_models.v05.multiscales import ValidTransform as ValidTransformV05
28
30
  from pydantic import BaseModel
29
31
 
30
32
  from ngio.ome_zarr_meta.ngio_specs import (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngio
3
- Version: 0.5.0b5
3
+ Version: 0.5.0b7
4
4
  Summary: Next Generation file format IO
5
5
  Project-URL: homepage, https://github.com/BioVisionCenter/ngio
6
6
  Project-URL: repository, https://github.com/BioVisionCenter/ngio
@@ -2,8 +2,8 @@ ngio/__init__.py,sha256=kyInohhWrBs4qkbMYFIQeAiy1CDpvbSOtXB4buFocbw,1535
2
2
  ngio/common/__init__.py,sha256=F3zAHQIhwig1xUA-SpmFVRtMeOrEj926-nHWhj-wS6c,684
3
3
  ngio/common/_dimensions.py,sha256=w8PYgyWxA8hgJETjFbw5CXf7WrasCL5FbzgfL1in86M,11361
4
4
  ngio/common/_masking_roi.py,sha256=rWOvhT08KfxX5djvUsX6LsUVofyU0Fq5LcUmpOYElDg,4757
5
- ngio/common/_pyramid.py,sha256=kvtacAhJb8zcV5ungNPYRDBShgti-kxtD_4LdBpnyDw,14012
6
- ngio/common/_roi.py,sha256=G2KICRbxlYenbc1qmKmdxLrfJRmqYSUbeaBdEuUYW-Q,11415
5
+ ngio/common/_pyramid.py,sha256=7kbvCY4J0hLl_iV5oT267j_h3UTkbqIdltqHcrwicvw,17571
6
+ ngio/common/_roi.py,sha256=IM0rYaekNvEDSMctYbAEZkeG9iPaJ1qjtnJ9kOVV8as,11416
7
7
  ngio/common/_synt_images_utils.py,sha256=B6uYOW1NyrM06YMR-csca3_YnAAkPRTbvnbLdy9tk9E,3188
8
8
  ngio/common/_zoom.py,sha256=U01c-vqXjzZkrpd9Yvs24frVfTls_xPJeeaFCGmUwYI,6727
9
9
  ngio/experimental/__init__.py,sha256=3pmBtHi-i8bKjTsvrOJM56ZyRX3Pv_dceCdt88-8COQ,147
@@ -17,13 +17,13 @@ ngio/experimental/iterators/_segmentation.py,sha256=xzotGvTn04HPeMeXZ_URnQqWco6d
17
17
  ngio/hcs/__init__.py,sha256=G8j9vD-liLeB_UeGtKYIgshWvJnUA6ks9GwjvWBLdHs,357
18
18
  ngio/hcs/_plate.py,sha256=l2a2ZMniutxRzZ88HOYwajug-svr6OanREG5mTy39x0,45773
19
19
  ngio/images/__init__.py,sha256=9Whvt7GTiCgT_vXaEEqGnDaY1-UsRk3dhLTv091F_g4,1211
20
- ngio/images/_abstract_image.py,sha256=n7xIURa3QCfTuBZz-g58y0Q2maG41AL79C9Ae8I08Ko,31864
21
- ngio/images/_create_synt_container.py,sha256=Cvg_J0KSxK0PH8IBzlKLIcCwH2vRTuBj-nZo5uOKXXk,5182
22
- ngio/images/_create_utils.py,sha256=hXVbFM8D_0mZTfBAhcZiuGX2lLXSJCep8THuxpH4d4E,14374
23
- ngio/images/_image.py,sha256=A2dE9O3L1dLU3gdjQrNCFUYDF_NuxTxVm8klmBfmPCc,34792
24
- ngio/images/_label.py,sha256=P4m6K6xaYoE7XrpCxbxHQwJOHncXdmXY057ZUv4a76E,15856
20
+ ngio/images/_abstract_image.py,sha256=SmVuFLrtqj2IVAFYrO6rWshsTO2G_wKd0WgW5TzQA18,34186
21
+ ngio/images/_create_synt_container.py,sha256=gCuT1SqZXJ_s7WRI_KbcoG1zrmEqFYKxKVZX04bR__A,5402
22
+ ngio/images/_create_utils.py,sha256=KohLQppIqECB65VzHaOejH3xHo9YcugmKIJ0WKam8fI,14348
23
+ ngio/images/_image.py,sha256=z5M4cfT_XmAGBQSHoUFn7BvwrmzwV0WjMIMcSIoKfPA,35246
24
+ ngio/images/_label.py,sha256=6H_nUobvmO2wvI_r0BJtBK47sprYtIzuoxSn8zVKET8,15905
25
25
  ngio/images/_masked_image.py,sha256=YhbBzgPZMav6rX0WYue1BaxAzEIsfaQrxUIOK6ZWZcw,18848
26
- ngio/images/_ome_zarr_container.py,sha256=mD1PEos33EfapkUVMJnSZdQiQI57cZa_bB2hdEEJQuM,48276
26
+ ngio/images/_ome_zarr_container.py,sha256=YheAO5nGRdZv_FT-ue-wJ0Cjz2aWhR4aIkJGo-tXgcE,49262
27
27
  ngio/images/_table_ops.py,sha256=jFv_AMqoB4JBpoWsMtZppZVW7dAOC_u-JpfNm8b33kY,15292
28
28
  ngio/io_pipes/__init__.py,sha256=arW_7GWzZs82kPNKdm_6B1sIDFV0lWwp-ZaORr9Q1FQ,2412
29
29
  ngio/io_pipes/_io_pipes.py,sha256=l85mmjj1l0uYU3qzsSHg9l8cMIEevInm_MTD-8MlXgw,10603
@@ -36,7 +36,7 @@ ngio/io_pipes/_ops_slices.py,sha256=hHMIOQ_niUSK9uFl8P2-10dP_K4GX3Do6vivN4fGRE0,
36
36
  ngio/io_pipes/_ops_slices_utils.py,sha256=mps_I0eTI4gdBVM9MCKsd8rCyefdo9bIK9fEmqwr23E,6633
37
37
  ngio/io_pipes/_ops_transforms.py,sha256=uITs6v6sZ7DQ_Hpw3JdX8MuPOzir-bihvGzY84Qn4wY,2934
38
38
  ngio/io_pipes/_zoom_transform.py,sha256=WBY1tO6_Qhf8FaDujfTdipuuqFf7PSi204wx5VKKs88,6884
39
- ngio/ome_zarr_meta/__init__.py,sha256=0VVB0r5CTjVqOsC8pa_Jf9H8ctPzTLRmC6LJqWWAs7Q,1371
39
+ ngio/ome_zarr_meta/__init__.py,sha256=7VDrX-ev5Gg2zQfGsrlj-YPTeIGzbplxbptxw1u-vU0,1491
40
40
  ngio/ome_zarr_meta/_meta_handlers.py,sha256=M8bHeWUjSgPCg-JTvnbwoL5sTPyGrWb2j8d-3r0Ua6Q,16172
41
41
  ngio/ome_zarr_meta/ngio_specs/__init__.py,sha256=sYGlV2-0-z-a1gDFlk_pCjgcdRsgbwBf72vM2ZAVTtQ,1750
42
42
  ngio/ome_zarr_meta/ngio_specs/_axes.py,sha256=CY63mWf7_ALoi7o_1QDVK1lAG56xN0gvgwfcuNRmMIg,16446
@@ -47,10 +47,10 @@ ngio/ome_zarr_meta/ngio_specs/_ngio_image.py,sha256=g32ytm4jxDR5duHyO6_kU0MrcE2N
47
47
  ngio/ome_zarr_meta/ngio_specs/_pixel_size.py,sha256=4VF1djY9T5tp6GCJXppFrUJwALI1XgIm0imoM5rNvdE,3876
48
48
  ngio/ome_zarr_meta/v04/__init__.py,sha256=tRt3zGelL948EoLfy_gW-LKvJcBbSkbT9kwIgU0hQV8,721
49
49
  ngio/ome_zarr_meta/v04/_custom_models.py,sha256=5GxiDERvLuvq4QvApcA6EiKLS6hLFX1R0R_9rSaa85A,530
50
- ngio/ome_zarr_meta/v04/_v04_spec.py,sha256=PRkxNeIDCCxG4J5HD3hQPrV-iPW_KAs4HyjyrT4i_NI,15362
50
+ ngio/ome_zarr_meta/v04/_v04_spec.py,sha256=W8XPtMhDUuISPpwT41dZDMSSUCtdgLhTWJPj1WqJ7i0,15389
51
51
  ngio/ome_zarr_meta/v05/__init__.py,sha256=B6VIUkrm5W4lcrvy4R7c7NZ6dEx-0a1AhqhZ7snCnCo,721
52
52
  ngio/ome_zarr_meta/v05/_custom_models.py,sha256=ZN3bE9nwx4y3tElhsYafI4S2zp_WzdkQKcyuuBiaXXo,530
53
- ngio/ome_zarr_meta/v05/_v05_spec.py,sha256=qjSRSkz20jQwd47tzHjeX5ECYBbZoU6q8lnALFeAZts,16285
53
+ ngio/ome_zarr_meta/v05/_v05_spec.py,sha256=avix0AIcRS143gKTb_C8Ab2BOhRU7tKlWdwj9jy6XTw,16312
54
54
  ngio/resources/__init__.py,sha256=4E4TXTNYEgRHt26C1XcC4pPobJJsmZRYm1Ml4uAuAkE,1664
55
55
  ngio/resources/resource_model.py,sha256=eE1m0dyk-2psPC4X8Ifyan524QHUOd52TEQdvoU0m8I,861
56
56
  ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png,sha256=g3QmxQdmeciAtBe5cTCRfR6yw3keG9cBYfjizMo6EGo,11890
@@ -82,7 +82,7 @@ ngio/utils/_datasets.py,sha256=YOV367skFA8nbKAqbyK0EsUU7E9UId_u5ButuLesrzk,5896
82
82
  ngio/utils/_errors.py,sha256=pKQ12LUjQLYE1nUawemA5h7HsgznjaSvV1n2PQU33N0,759
83
83
  ngio/utils/_fractal_fsspec_store.py,sha256=RdcCFOgHexRKX9zZvJV5RI-5OPc7VOPS6q_IeRxm24I,1548
84
84
  ngio/utils/_zarr_utils.py,sha256=MVbW-a0S3iuzMaknqkliJa_lp8i6mEO4Q2YN2XxmeDw,18158
85
- ngio-0.5.0b5.dist-info/METADATA,sha256=kDswYTjCsCUVZUZc2TA-tNK9CZZ4PhncumU74hE8vXc,6382
86
- ngio-0.5.0b5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
87
- ngio-0.5.0b5.dist-info/licenses/LICENSE,sha256=UgN_a1QCeNh9rZWfz-wORQFxE3elQzLWPQaoK6N6fxQ,1502
88
- ngio-0.5.0b5.dist-info/RECORD,,
85
+ ngio-0.5.0b7.dist-info/METADATA,sha256=LRMT4aboyJ5z66FSJvBwrXkFxEz2YTX7Diu340KSc8Y,6382
86
+ ngio-0.5.0b7.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
87
+ ngio-0.5.0b7.dist-info/licenses/LICENSE,sha256=UgN_a1QCeNh9rZWfz-wORQFxE3elQzLWPQaoK6N6fxQ,1502
88
+ ngio-0.5.0b7.dist-info/RECORD,,
File without changes