ngio 0.4.0a3__py3-none-any.whl → 0.4.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 (54) hide show
  1. ngio/__init__.py +1 -2
  2. ngio/common/__init__.py +2 -51
  3. ngio/common/_dimensions.py +253 -74
  4. ngio/common/_pyramid.py +42 -23
  5. ngio/common/_roi.py +49 -413
  6. ngio/common/_zoom.py +32 -7
  7. ngio/experimental/iterators/__init__.py +0 -2
  8. ngio/experimental/iterators/_abstract_iterator.py +246 -26
  9. ngio/experimental/iterators/_feature.py +90 -52
  10. ngio/experimental/iterators/_image_processing.py +24 -63
  11. ngio/experimental/iterators/_mappers.py +48 -0
  12. ngio/experimental/iterators/_rois_utils.py +4 -4
  13. ngio/experimental/iterators/_segmentation.py +38 -85
  14. ngio/images/_abstract_image.py +192 -95
  15. ngio/images/_create.py +16 -0
  16. ngio/images/_create_synt_container.py +10 -0
  17. ngio/images/_image.py +35 -9
  18. ngio/images/_label.py +26 -3
  19. ngio/images/_masked_image.py +45 -61
  20. ngio/images/_ome_zarr_container.py +33 -0
  21. ngio/io_pipes/__init__.py +75 -0
  22. ngio/io_pipes/_io_pipes.py +361 -0
  23. ngio/io_pipes/_io_pipes_masked.py +488 -0
  24. ngio/io_pipes/_io_pipes_roi.py +152 -0
  25. ngio/io_pipes/_io_pipes_types.py +56 -0
  26. ngio/io_pipes/_match_shape.py +376 -0
  27. ngio/io_pipes/_ops_axes.py +344 -0
  28. ngio/io_pipes/_ops_slices.py +446 -0
  29. ngio/io_pipes/_ops_slices_utils.py +196 -0
  30. ngio/io_pipes/_ops_transforms.py +104 -0
  31. ngio/io_pipes/_zoom_transform.py +175 -0
  32. ngio/ome_zarr_meta/__init__.py +4 -2
  33. ngio/ome_zarr_meta/ngio_specs/__init__.py +4 -4
  34. ngio/ome_zarr_meta/ngio_specs/_axes.py +129 -141
  35. ngio/ome_zarr_meta/ngio_specs/_dataset.py +47 -121
  36. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +30 -22
  37. ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +17 -1
  38. ngio/ome_zarr_meta/v04/_v04_spec_utils.py +33 -30
  39. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  40. ngio/resources/__init__.py +1 -0
  41. ngio/resources/resource_model.py +1 -0
  42. ngio/{common/transforms → transforms}/__init__.py +1 -1
  43. ngio/transforms/_zoom.py +19 -0
  44. ngio/utils/_datasets.py +5 -0
  45. ngio/utils/_zarr_utils.py +5 -1
  46. {ngio-0.4.0a3.dist-info → ngio-0.4.0b1.dist-info}/METADATA +1 -1
  47. ngio-0.4.0b1.dist-info/RECORD +85 -0
  48. ngio/common/_array_io_pipes.py +0 -554
  49. ngio/common/_array_io_utils.py +0 -508
  50. ngio/common/transforms/_label.py +0 -12
  51. ngio/common/transforms/_zoom.py +0 -109
  52. ngio-0.4.0a3.dist-info/RECORD +0 -76
  53. {ngio-0.4.0a3.dist-info → ngio-0.4.0b1.dist-info}/WHEEL +0 -0
  54. {ngio-0.4.0a3.dist-info → ngio-0.4.0b1.dist-info}/licenses/LICENSE +0 -0
@@ -8,24 +8,26 @@ import numpy as np
8
8
  import zarr
9
9
 
10
10
  from ngio.common import (
11
- ArrayLike,
12
11
  Dimensions,
12
+ InterpolationOrder,
13
13
  Roi,
14
14
  RoiPixels,
15
+ consolidate_pyramid,
16
+ )
17
+ from ngio.io_pipes import (
18
+ DaskGetter,
19
+ DaskRoiGetter,
20
+ DaskRoiSetter,
21
+ DaskSetter,
22
+ NumpyGetter,
23
+ NumpyRoiGetter,
24
+ NumpyRoiSetter,
25
+ NumpySetter,
15
26
  SlicingInputType,
16
27
  TransformProtocol,
17
- build_dask_getter,
18
- build_dask_setter,
19
- build_numpy_getter,
20
- build_numpy_setter,
21
- build_roi_dask_getter,
22
- build_roi_dask_setter,
23
- build_roi_numpy_getter,
24
- build_roi_numpy_setter,
25
- consolidate_pyramid,
26
28
  )
27
29
  from ngio.ome_zarr_meta import (
28
- AxesMapper,
30
+ AxesHandler,
29
31
  Dataset,
30
32
  ImageMetaHandler,
31
33
  LabelMetaHandler,
@@ -61,29 +63,54 @@ class AbstractImage(Generic[_image_handler]):
61
63
  self._group_handler = group_handler
62
64
  self._meta_handler = meta_handler
63
65
 
64
- self._dataset = self._meta_handler.meta.get_dataset(path=path)
65
- self._pixel_size = self._dataset.pixel_size
66
-
67
66
  try:
68
- self._zarr_array = self._group_handler.get_array(self._dataset.path)
67
+ self._zarr_array = self._group_handler.get_array(self._path)
69
68
  except NgioFileExistsError as e:
70
69
  raise NgioFileExistsError(f"Could not find the dataset at {path}.") from e
71
70
 
72
- self._dimensions = Dimensions(
73
- shape=self._zarr_array.shape, axes_mapper=self._dataset.axes_mapper
74
- )
75
-
76
- self._axes_mapper = self._dataset.axes_mapper
77
-
78
71
  def __repr__(self) -> str:
79
72
  """Return a string representation of the image."""
80
73
  return f"Image(path={self.path}, {self.dimensions})"
81
74
 
75
+ @property
76
+ def path(self) -> str:
77
+ """Return the path of the image."""
78
+ return self._path
79
+
82
80
  @property
83
81
  def meta_handler(self) -> _image_handler:
84
82
  """Return the metadata."""
85
83
  return self._meta_handler
86
84
 
85
+ @property
86
+ def dataset(self) -> Dataset:
87
+ """Return the dataset of the image."""
88
+ return self.meta_handler.meta.get_dataset(path=self.path)
89
+
90
+ @property
91
+ def dimensions(self) -> Dimensions:
92
+ """Return the dimensions of the image."""
93
+ return Dimensions(
94
+ shape=self.zarr_array.shape,
95
+ chunks=self.zarr_array.chunks,
96
+ dataset=self.dataset,
97
+ )
98
+
99
+ @property
100
+ def pixel_size(self) -> PixelSize:
101
+ """Return the pixel size of the image."""
102
+ return self.dataset.pixel_size
103
+
104
+ @property
105
+ def axes_handler(self) -> AxesHandler:
106
+ """Return the axes handler of the image."""
107
+ return self.dataset.axes_handler
108
+
109
+ @property
110
+ def axes(self) -> tuple[str, ...]:
111
+ """Return the axes of the image."""
112
+ return self.dimensions.axes
113
+
87
114
  @property
88
115
  def zarr_array(self) -> zarr.Array:
89
116
  """Return the Zarr array."""
@@ -104,16 +131,6 @@ class AbstractImage(Generic[_image_handler]):
104
131
  """Return the chunks of the image."""
105
132
  return self.zarr_array.chunks
106
133
 
107
- @property
108
- def dimensions(self) -> Dimensions:
109
- """Return the dimensions of the image."""
110
- return self._dimensions
111
-
112
- @property
113
- def axes_mapper(self) -> AxesMapper:
114
- """Return the axes mapper of the image."""
115
- return self._axes_mapper
116
-
117
134
  @property
118
135
  def is_3d(self) -> bool:
119
136
  """Return True if the image is 3D."""
@@ -147,32 +164,16 @@ class AbstractImage(Generic[_image_handler]):
147
164
  @property
148
165
  def space_unit(self) -> str | None:
149
166
  """Return the space unit of the image."""
150
- return self.meta_handler.meta.space_unit
167
+ return self.axes_handler.space_unit
151
168
 
152
169
  @property
153
170
  def time_unit(self) -> str | None:
154
171
  """Return the time unit of the image."""
155
- return self.meta_handler.meta.time_unit
156
-
157
- @property
158
- def pixel_size(self) -> PixelSize:
159
- """Return the pixel size of the image."""
160
- return self._pixel_size
161
-
162
- @property
163
- def dataset(self) -> Dataset:
164
- """Return the dataset of the image."""
165
- return self._dataset
166
-
167
- @property
168
- def path(self) -> str:
169
- """Return the path of the image."""
170
- return self._dataset.path
172
+ return self.axes_handler.time_unit
171
173
 
172
174
  def has_axis(self, axis: str) -> bool:
173
175
  """Return True if the image has the given axis."""
174
- self.axes_mapper.get_index("x")
175
- return self.dimensions.has_axis(axis)
176
+ return self.axes_handler.has_axis(axis)
176
177
 
177
178
  def _get_as_numpy(
178
179
  self,
@@ -190,7 +191,7 @@ class AbstractImage(Generic[_image_handler]):
190
191
  Returns:
191
192
  The array of the region of interest.
192
193
  """
193
- numpy_getter = build_numpy_getter(
194
+ numpy_getter = NumpyGetter(
194
195
  zarr_array=self.zarr_array,
195
196
  dimensions=self.dimensions,
196
197
  axes_order=axes_order,
@@ -217,11 +218,10 @@ class AbstractImage(Generic[_image_handler]):
217
218
  Returns:
218
219
  The array of the region of interest.
219
220
  """
220
- numpy_roi_getter = build_roi_numpy_getter(
221
+ numpy_roi_getter = NumpyRoiGetter(
221
222
  zarr_array=self.zarr_array,
222
223
  dimensions=self.dimensions,
223
224
  roi=roi,
224
- pixel_size=self.pixel_size,
225
225
  axes_order=axes_order,
226
226
  transforms=transforms,
227
227
  slicing_dict=slicing_kwargs,
@@ -241,7 +241,7 @@ class AbstractImage(Generic[_image_handler]):
241
241
  transforms: The transforms to apply to the array.
242
242
  **slicing_kwargs: The slices to get the array.
243
243
  """
244
- dask_getter = build_dask_getter(
244
+ dask_getter = DaskGetter(
245
245
  zarr_array=self.zarr_array,
246
246
  dimensions=self.dimensions,
247
247
  axes_order=axes_order,
@@ -265,11 +265,10 @@ class AbstractImage(Generic[_image_handler]):
265
265
  transforms: The transforms to apply to the array.
266
266
  **slicing_kwargs: The slices to get the array.
267
267
  """
268
- roi_dask_getter = build_roi_dask_getter(
268
+ roi_dask_getter = DaskRoiGetter(
269
269
  zarr_array=self.zarr_array,
270
270
  dimensions=self.dimensions,
271
271
  roi=roi,
272
- pixel_size=self.pixel_size,
273
272
  axes_order=axes_order,
274
273
  transforms=transforms,
275
274
  slicing_dict=slicing_kwargs,
@@ -282,7 +281,7 @@ class AbstractImage(Generic[_image_handler]):
282
281
  transforms: Sequence[TransformProtocol] | None = None,
283
282
  mode: Literal["numpy", "dask"] = "numpy",
284
283
  **slicing_kwargs: SlicingInputType,
285
- ) -> ArrayLike:
284
+ ) -> np.ndarray | da.Array:
286
285
  """Get a slice of the image.
287
286
 
288
287
  Args:
@@ -305,7 +304,7 @@ class AbstractImage(Generic[_image_handler]):
305
304
  )
306
305
  else:
307
306
  raise ValueError(
308
- f"Unknown mode: {mode}. Choose from 'numpy', 'dask', or 'delayed'."
307
+ f"Unsupported mode: {mode}. Supported modes are: numpy, dask."
309
308
  )
310
309
 
311
310
  def _get_roi(
@@ -315,7 +314,7 @@ class AbstractImage(Generic[_image_handler]):
315
314
  transforms: Sequence[TransformProtocol] | None = None,
316
315
  mode: Literal["numpy", "dask"] = "numpy",
317
316
  **slice_kwargs: SlicingInputType,
318
- ) -> ArrayLike:
317
+ ) -> np.ndarray | da.Array:
319
318
  """Get a slice of the image.
320
319
 
321
320
  Args:
@@ -339,12 +338,12 @@ class AbstractImage(Generic[_image_handler]):
339
338
  )
340
339
  else:
341
340
  raise ValueError(
342
- f"Unknown mode: {mode}. Choose from 'numpy', 'dask', or 'delayed'."
341
+ f"Unsupported mode: {mode}. Supported modes are: numpy, dask."
343
342
  )
344
343
 
345
344
  def _set_array(
346
345
  self,
347
- patch: ArrayLike,
346
+ patch: np.ndarray | da.Array,
348
347
  axes_order: Sequence[str] | None = None,
349
348
  transforms: Sequence[TransformProtocol] | None = None,
350
349
  **slicing_kwargs: SlicingInputType,
@@ -359,7 +358,7 @@ class AbstractImage(Generic[_image_handler]):
359
358
 
360
359
  """
361
360
  if isinstance(patch, np.ndarray):
362
- numpy_setter = build_numpy_setter(
361
+ numpy_setter = NumpySetter(
363
362
  zarr_array=self.zarr_array,
364
363
  dimensions=self.dimensions,
365
364
  axes_order=axes_order,
@@ -369,7 +368,7 @@ class AbstractImage(Generic[_image_handler]):
369
368
  numpy_setter(patch)
370
369
 
371
370
  elif isinstance(patch, da.Array):
372
- dask_setter = build_dask_setter(
371
+ dask_setter = DaskSetter(
373
372
  zarr_array=self.zarr_array,
374
373
  dimensions=self.dimensions,
375
374
  axes_order=axes_order,
@@ -387,7 +386,7 @@ class AbstractImage(Generic[_image_handler]):
387
386
  def _set_roi(
388
387
  self,
389
388
  roi: Roi | RoiPixels,
390
- patch: ArrayLike,
389
+ patch: np.ndarray | da.Array,
391
390
  axes_order: Sequence[str] | None = None,
392
391
  transforms: Sequence[TransformProtocol] | None = None,
393
392
  **slicing_kwargs: SlicingInputType,
@@ -403,11 +402,10 @@ class AbstractImage(Generic[_image_handler]):
403
402
 
404
403
  """
405
404
  if isinstance(patch, np.ndarray):
406
- roi_numpy_setter = build_roi_numpy_setter(
405
+ roi_numpy_setter = NumpyRoiSetter(
407
406
  zarr_array=self.zarr_array,
408
407
  dimensions=self.dimensions,
409
408
  roi=roi,
410
- pixel_size=self.pixel_size,
411
409
  axes_order=axes_order,
412
410
  transforms=transforms,
413
411
  slicing_dict=slicing_kwargs,
@@ -415,11 +413,10 @@ class AbstractImage(Generic[_image_handler]):
415
413
  roi_numpy_setter(patch)
416
414
 
417
415
  elif isinstance(patch, da.Array):
418
- roi_dask_setter = build_roi_dask_setter(
416
+ roi_dask_setter = DaskRoiSetter(
419
417
  zarr_array=self.zarr_array,
420
418
  dimensions=self.dimensions,
421
419
  roi=roi,
422
- pixel_size=self.pixel_size,
423
420
  axes_order=axes_order,
424
421
  transforms=transforms,
425
422
  slicing_dict=slicing_kwargs,
@@ -434,7 +431,7 @@ class AbstractImage(Generic[_image_handler]):
434
431
 
435
432
  def _consolidate(
436
433
  self,
437
- order: Literal[0, 1, 2] = 1,
434
+ order: InterpolationOrder = "linear",
438
435
  mode: Literal["dask", "numpy", "coarsen"] = "dask",
439
436
  ) -> None:
440
437
  """Consolidate the image on disk.
@@ -445,14 +442,137 @@ class AbstractImage(Generic[_image_handler]):
445
442
  """
446
443
  consolidate_image(image=self, order=order, mode=mode)
447
444
 
445
+ def roi(self, name: str | None = "image") -> Roi:
446
+ """Return the ROI covering the entire image."""
447
+ dim_x = self.dimensions.get("x")
448
+ dim_y = self.dimensions.get("y")
449
+ assert dim_x is not None and dim_y is not None
450
+ dim_z = self.dimensions.get("z")
451
+ z = None if dim_z is None else 0
452
+ dim_t = self.dimensions.get("t")
453
+ t = None if dim_t is None else 0
454
+ roi_px = RoiPixels(
455
+ name=name,
456
+ x=0,
457
+ y=0,
458
+ z=z,
459
+ t=t,
460
+ x_length=dim_x,
461
+ y_length=dim_y,
462
+ z_length=dim_z,
463
+ t_length=dim_t,
464
+ )
465
+ return roi_px.to_roi(pixel_size=self.pixel_size)
466
+
448
467
  def build_image_roi_table(self, name: str | None = "image") -> RoiTable:
449
- """Build the ROI table for an image."""
450
- return build_image_roi_table(image=self, name=name)
468
+ """Build the ROI table containing the ROI covering the entire image."""
469
+ return RoiTable(rois=[self.roi(name=name)])
470
+
471
+ def require_dimensions_match(
472
+ self,
473
+ other: "AbstractImage",
474
+ allow_singleton: bool = False,
475
+ ) -> None:
476
+ """Assert that two images have matching spatial dimensions.
477
+
478
+ Args:
479
+ other: The other image to compare to.
480
+ allow_singleton: If True, allow singleton dimensions to be
481
+ compatible with non-singleton dimensions.
482
+
483
+ Raises:
484
+ NgioValueError: If the images do not have compatible dimensions.
485
+ """
486
+ self.dimensions.require_dimensions_match(
487
+ other.dimensions, allow_singleton=allow_singleton
488
+ )
489
+
490
+ def check_if_dimensions_match(
491
+ self,
492
+ other: "AbstractImage",
493
+ allow_singleton: bool = False,
494
+ ) -> bool:
495
+ """Check if two images have matching spatial dimensions.
496
+
497
+ Args:
498
+ other: The other image to compare to.
499
+ allow_singleton: If True, allow singleton dimensions to be
500
+ compatible with non-singleton dimensions.
501
+
502
+ Returns:
503
+ bool: True if the images have matching dimensions, False otherwise.
504
+ """
505
+ return self.dimensions.check_if_dimensions_match(
506
+ other.dimensions, allow_singleton=allow_singleton
507
+ )
508
+
509
+ def require_axes_match(
510
+ self,
511
+ other: "AbstractImage",
512
+ ) -> None:
513
+ """Assert that two images have compatible axes.
514
+
515
+ Args:
516
+ other: The other image to compare to.
517
+
518
+ Raises:
519
+ NgioValueError: If the images do not have compatible axes.
520
+ """
521
+ self.dimensions.require_axes_match(other.dimensions)
522
+
523
+ def check_if_axes_match(
524
+ self,
525
+ other: "AbstractImage",
526
+ ) -> bool:
527
+ """Check if two images have compatible axes.
528
+
529
+ Args:
530
+ other: The other image to compare to.
531
+
532
+ Returns:
533
+ bool: True if the images have compatible axes, False otherwise.
534
+
535
+ """
536
+ return self.dimensions.check_if_axes_match(other.dimensions)
537
+
538
+ def require_rescalable(
539
+ self,
540
+ other: "AbstractImage",
541
+ ) -> None:
542
+ """Assert that two images can be rescaled to each other.
543
+
544
+ For this to be true, the images must have the same axes, and
545
+ the pixel sizes must be compatible (i.e. one can be scaled to the other).
546
+
547
+ Args:
548
+ other: The other image to compare to.
549
+
550
+ Raises:
551
+ NgioValueError: If the images cannot be scaled to each other.
552
+ """
553
+ self.dimensions.require_rescalable(other.dimensions)
554
+
555
+ def check_if_rescalable(
556
+ self,
557
+ other: "AbstractImage",
558
+ ) -> bool:
559
+ """Check if two images can be rescaled to each other.
560
+
561
+ For this to be true, the images must have the same axes, and
562
+ the pixel sizes must be compatible (i.e. one can be scaled to the other).
563
+
564
+ Args:
565
+ other: The other image to compare to.
566
+
567
+ Returns:
568
+ bool: True if the images can be rescaled to each other, False otherwise.
569
+ """
570
+ return self.dimensions.check_if_rescalable(other.dimensions)
451
571
 
452
572
 
453
573
  def consolidate_image(
454
574
  image: AbstractImage,
455
- order: Literal[0, 1, 2] = 1,
575
+ order: InterpolationOrder = "linear",
456
576
  mode: Literal["dask", "numpy", "coarsen"] = "dask",
457
577
  ) -> None:
458
578
  """Consolidate the image on disk."""
@@ -465,26 +585,3 @@ def consolidate_image(
465
585
  consolidate_pyramid(
466
586
  source=image.zarr_array, targets=targets, order=order, mode=mode
467
587
  )
468
-
469
-
470
- def build_image_roi_table(image: AbstractImage, name: str | None = "image") -> RoiTable:
471
- """Build the ROI table for an image."""
472
- dim_x = image.dimensions.get("x")
473
- dim_y = image.dimensions.get("y")
474
- assert dim_x is not None and dim_y is not None
475
- dim_z = image.dimensions.get("z")
476
- z = None if dim_z is None else 0
477
- dim_t = image.dimensions.get("t")
478
- t = None if dim_t is None else 0
479
- image_roi = RoiPixels(
480
- name=name,
481
- x=0,
482
- y=0,
483
- z=z,
484
- t=t,
485
- x_length=dim_x,
486
- y_length=dim_y,
487
- z_length=dim_z,
488
- t_length=dim_t,
489
- )
490
- return RoiTable(rois=[image_roi.to_roi(pixel_size=image.pixel_size)])
ngio/images/_create.py CHANGED
@@ -3,6 +3,8 @@
3
3
  from collections.abc import Sequence
4
4
  from typing import TypeVar
5
5
 
6
+ from zarr.types import DIMENSION_SEPARATOR
7
+
6
8
  from ngio.common._pyramid import init_empty_pyramid
7
9
  from ngio.ome_zarr_meta import (
8
10
  NgioImageMeta,
@@ -93,6 +95,8 @@ def create_empty_label_container(
93
95
  name: str | None = None,
94
96
  chunks: Sequence[int] | None = None,
95
97
  dtype: str = "uint32",
98
+ dimension_separator: DIMENSION_SEPARATOR = "/",
99
+ compressor="default",
96
100
  overwrite: bool = False,
97
101
  version: NgffVersions = DefaultNgffVersion,
98
102
  ) -> ZarrGroupHandler:
@@ -120,6 +124,9 @@ def create_empty_label_container(
120
124
  name (str | None, optional): The name of the image. Defaults to None.
121
125
  chunks (Sequence[int] | None, optional): The chunk shape. If None the shape
122
126
  is used. Defaults to None.
127
+ dimension_separator (DIMENSION_SEPARATOR): The separator to use for
128
+ dimensions. Defaults to "/".
129
+ compressor: The compressor to use. Defaults to "default".
123
130
  dtype (str, optional): The data type of the image. Defaults to "uint16".
124
131
  overwrite (bool, optional): Whether to overwrite an existing image.
125
132
  Defaults to True.
@@ -164,6 +171,8 @@ def create_empty_label_container(
164
171
  chunks=chunks,
165
172
  dtype=dtype,
166
173
  mode="a",
174
+ dimension_separator=dimension_separator,
175
+ compressor=compressor,
167
176
  )
168
177
  group_handler._mode = "r+"
169
178
  return group_handler
@@ -184,6 +193,8 @@ def create_empty_image_container(
184
193
  name: str | None = None,
185
194
  chunks: Sequence[int] | None = None,
186
195
  dtype: str = "uint16",
196
+ dimension_separator: DIMENSION_SEPARATOR = "/",
197
+ compressor="default",
187
198
  overwrite: bool = False,
188
199
  version: NgffVersions = DefaultNgffVersion,
189
200
  ) -> ZarrGroupHandler:
@@ -212,6 +223,9 @@ def create_empty_image_container(
212
223
  chunks (Sequence[int] | None, optional): The chunk shape. If None the shape
213
224
  is used. Defaults to None.
214
225
  dtype (str, optional): The data type of the image. Defaults to "uint16".
226
+ dimension_separator (DIMENSION_SEPARATOR): The separator to use for
227
+ dimensions. Defaults to "/".
228
+ compressor: The compressor to use. Defaults to "default".
215
229
  overwrite (bool, optional): Whether to overwrite an existing image.
216
230
  Defaults to True.
217
231
  version (str, optional): The version of the OME-Zarr specification.
@@ -254,6 +268,8 @@ def create_empty_image_container(
254
268
  chunks=chunks,
255
269
  dtype=dtype,
256
270
  mode="a",
271
+ dimension_separator=dimension_separator,
272
+ compressor=compressor,
257
273
  )
258
274
 
259
275
  group_handler._mode = "r+"
@@ -4,6 +4,7 @@ from collections.abc import Sequence
4
4
 
5
5
  import numpy as np
6
6
  import PIL.Image
7
+ from zarr.types import DIMENSION_SEPARATOR
7
8
 
8
9
  from ngio.common._synt_images_utils import fit_to_shape
9
10
  from ngio.images._ome_zarr_container import OmeZarrContainer, create_ome_zarr_from_array
@@ -35,6 +36,8 @@ def create_synthetic_ome_zarr(
35
36
  channel_colors: Sequence[str] | None = None,
36
37
  channel_active: Sequence[bool] | None = None,
37
38
  table_backend: TableBackend = DefaultTableBackend,
39
+ dimension_separator: DIMENSION_SEPARATOR = "/",
40
+ compressor="default",
38
41
  overwrite: bool = False,
39
42
  version: NgffVersions = DefaultNgffVersion,
40
43
  ) -> OmeZarrContainer:
@@ -63,6 +66,9 @@ def create_synthetic_ome_zarr(
63
66
  channel_active (Sequence[bool] | None, optional): Whether the channels are
64
67
  active. Defaults to None.
65
68
  table_backend (TableBackend): Table backend to be used to store tables
69
+ dimension_separator (DIMENSION_SEPARATOR): The separator to use for
70
+ dimensions. Defaults to "/".
71
+ compressor: The compressor to use. Defaults to "default".
66
72
  overwrite (bool, optional): Whether to overwrite an existing image.
67
73
  Defaults to True.
68
74
  version (NgffVersion, optional): The version of the OME-Zarr specification.
@@ -96,6 +102,8 @@ def create_synthetic_ome_zarr(
96
102
  name=sample_info.name,
97
103
  chunks=chunks,
98
104
  overwrite=overwrite,
105
+ dimension_separator=dimension_separator,
106
+ compressor=compressor,
99
107
  version=version,
100
108
  )
101
109
 
@@ -108,6 +116,8 @@ def create_synthetic_ome_zarr(
108
116
  label = ome_zarr.get_label(name=label_info.name)
109
117
 
110
118
  ref_label = np.asarray(PIL.Image.open(label_info.label_path))
119
+ ref_label = ref_label.astype(label_info.dtype)
120
+
111
121
  ref_label = fit_to_shape(
112
122
  arr=ref_label,
113
123
  out_shape=label.shape,