ngio 0.3.4__py3-none-any.whl → 0.4.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 (61) hide show
  1. ngio/__init__.py +6 -0
  2. ngio/common/__init__.py +50 -48
  3. ngio/common/_array_io_pipes.py +549 -0
  4. ngio/common/_array_io_utils.py +508 -0
  5. ngio/common/_dimensions.py +63 -27
  6. ngio/common/_masking_roi.py +38 -10
  7. ngio/common/_pyramid.py +9 -7
  8. ngio/common/_roi.py +571 -72
  9. ngio/common/_synt_images_utils.py +101 -0
  10. ngio/common/_zoom.py +17 -12
  11. ngio/common/transforms/__init__.py +5 -0
  12. ngio/common/transforms/_label.py +12 -0
  13. ngio/common/transforms/_zoom.py +109 -0
  14. ngio/experimental/__init__.py +5 -0
  15. ngio/experimental/iterators/__init__.py +17 -0
  16. ngio/experimental/iterators/_abstract_iterator.py +170 -0
  17. ngio/experimental/iterators/_feature.py +151 -0
  18. ngio/experimental/iterators/_image_processing.py +169 -0
  19. ngio/experimental/iterators/_rois_utils.py +127 -0
  20. ngio/experimental/iterators/_segmentation.py +278 -0
  21. ngio/hcs/_plate.py +41 -36
  22. ngio/images/__init__.py +22 -1
  23. ngio/images/_abstract_image.py +247 -117
  24. ngio/images/_create.py +15 -15
  25. ngio/images/_create_synt_container.py +128 -0
  26. ngio/images/_image.py +425 -62
  27. ngio/images/_label.py +33 -30
  28. ngio/images/_masked_image.py +396 -122
  29. ngio/images/_ome_zarr_container.py +203 -66
  30. ngio/{common → images}/_table_ops.py +41 -41
  31. ngio/ome_zarr_meta/ngio_specs/__init__.py +2 -8
  32. ngio/ome_zarr_meta/ngio_specs/_axes.py +151 -128
  33. ngio/ome_zarr_meta/ngio_specs/_channels.py +55 -18
  34. ngio/ome_zarr_meta/ngio_specs/_dataset.py +7 -7
  35. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +6 -15
  36. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +11 -68
  37. ngio/ome_zarr_meta/v04/_v04_spec_utils.py +1 -1
  38. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
  39. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  40. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
  41. ngio/resources/__init__.py +54 -0
  42. ngio/resources/resource_model.py +35 -0
  43. ngio/tables/backends/_abstract_backend.py +5 -6
  44. ngio/tables/backends/_anndata.py +1 -2
  45. ngio/tables/backends/_anndata_utils.py +3 -3
  46. ngio/tables/backends/_non_zarr_backends.py +1 -1
  47. ngio/tables/backends/_table_backends.py +0 -1
  48. ngio/tables/backends/_utils.py +3 -3
  49. ngio/tables/v1/_roi_table.py +156 -69
  50. ngio/utils/__init__.py +2 -3
  51. ngio/utils/_logger.py +19 -0
  52. ngio/utils/_zarr_utils.py +1 -5
  53. {ngio-0.3.4.dist-info → ngio-0.4.0a1.dist-info}/METADATA +12 -10
  54. ngio-0.4.0a1.dist-info/RECORD +76 -0
  55. ngio/common/_array_pipe.py +0 -288
  56. ngio/common/_axes_transforms.py +0 -64
  57. ngio/common/_common_types.py +0 -5
  58. ngio/common/_slicer.py +0 -96
  59. ngio-0.3.4.dist-info/RECORD +0 -61
  60. {ngio-0.3.4.dist-info → ngio-0.4.0a1.dist-info}/WHEEL +0 -0
  61. {ngio-0.3.4.dist-info → ngio-0.4.0a1.dist-info}/licenses/LICENSE +0 -0
@@ -2,11 +2,10 @@
2
2
 
3
3
  import itertools
4
4
 
5
- import dask
6
5
  import dask.array as da
7
- import dask.delayed
8
6
  import numpy as np
9
7
  import scipy.ndimage as ndi
8
+ from dask.delayed import delayed
10
9
 
11
10
  from ngio.common._roi import Roi, RoiPixels
12
11
  from ngio.ome_zarr_meta import PixelSize
@@ -39,7 +38,7 @@ def _adjust_slices(slices, offset):
39
38
  return adjusted_slices
40
39
 
41
40
 
42
- @dask.delayed
41
+ @delayed
43
42
  def _process_chunk(chunk, offset):
44
43
  """Process a single chunk.
45
44
 
@@ -63,7 +62,7 @@ def _merge_slices(
63
62
  return tuple(merged)
64
63
 
65
64
 
66
- @dask.delayed
65
+ @delayed
67
66
  def _collect_slices(
68
67
  local_slices: list[dict[int, tuple[slice, ...]]],
69
68
  ) -> dict[int, tuple[slice]]:
@@ -101,7 +100,7 @@ def compute_slices(segmentation: np.ndarray) -> dict[int, tuple[slice, ...]]:
101
100
  def lazy_compute_slices(segmentation: da.Array) -> dict[int, tuple[slice, ...]]:
102
101
  """Compute slices for each label in a segmentation."""
103
102
  global_offsets = _compute_offsets(segmentation.chunks)
104
- delayed_chunks = segmentation.to_delayed()
103
+ delayed_chunks = segmentation.to_delayed() # type: ignore
105
104
 
106
105
  grid_shape = tuple(len(c) for c in segmentation.chunks)
107
106
 
@@ -125,8 +124,8 @@ def compute_masking_roi(
125
124
  Other axes orders are not supported.
126
125
 
127
126
  """
128
- if segmentation.ndim not in [2, 3]:
129
- raise NgioValueError("Only 2D and 3D segmentations are supported.")
127
+ if segmentation.ndim not in [2, 3, 4]:
128
+ raise NgioValueError("Only 2D, 3D, and 4D segmentations are supported.")
130
129
 
131
130
  if isinstance(segmentation, da.Array):
132
131
  slices = lazy_compute_slices(segmentation)
@@ -136,21 +135,50 @@ def compute_masking_roi(
136
135
  rois = []
137
136
  for label, slice_ in slices.items():
138
137
  if len(slice_) == 2:
139
- min_z, min_y, min_x = 0, slice_[0].start, slice_[1].start
140
- max_z, max_y, max_x = 1, slice_[0].stop, slice_[1].stop
138
+ min_t, max_t = None, None
139
+ min_z, max_z = None, None
140
+ min_y, min_x = slice_[0].start, slice_[1].start
141
+ max_y, max_x = slice_[0].stop, slice_[1].stop
141
142
  elif len(slice_) == 3:
143
+ min_t, max_t = None, None
142
144
  min_z, min_y, min_x = slice_[0].start, slice_[1].start, slice_[2].start
143
145
  max_z, max_y, max_x = slice_[0].stop, slice_[1].stop, slice_[2].stop
146
+ elif len(slice_) == 4:
147
+ min_t, min_z, min_y, min_x = (
148
+ slice_[0].start,
149
+ slice_[1].start,
150
+ slice_[2].start,
151
+ slice_[3].start,
152
+ )
153
+ max_t, max_z, max_y, max_x = (
154
+ slice_[0].stop,
155
+ slice_[1].stop,
156
+ slice_[2].stop,
157
+ slice_[3].stop,
158
+ )
144
159
  else:
145
160
  raise ValueError("Invalid slice length.")
161
+
162
+ if max_t is None:
163
+ t_length = None
164
+ else:
165
+ t_length = max_t - min_t
166
+
167
+ if max_z is None:
168
+ z_length = None
169
+ else:
170
+ z_length = max_z - min_z
171
+
146
172
  roi = RoiPixels(
147
173
  name=str(label),
148
174
  x_length=max_x - min_x,
149
175
  y_length=max_y - min_y,
150
- z_length=max_z - min_z,
176
+ z_length=z_length,
177
+ t_length=t_length,
151
178
  x=min_x,
152
179
  y=min_y,
153
180
  z=min_z,
181
+ label=label,
154
182
  )
155
183
 
156
184
  roi = roi.to_roi(pixel_size)
ngio/common/_pyramid.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import math
2
- from collections.abc import Collection
2
+ from collections.abc import Callable, Sequence
3
3
  from typing import Literal
4
4
 
5
5
  import dask.array as da
@@ -40,7 +40,7 @@ def _on_disk_coarsen(
40
40
  source: zarr.Array,
41
41
  target: zarr.Array,
42
42
  _order: Literal[0, 1] = 1,
43
- aggregation_function: np.ufunc | None = None,
43
+ aggregation_function: Callable | None = None,
44
44
  ) -> None:
45
45
  """Apply a coarsening operation from a source zarr array to a target zarr array.
46
46
 
@@ -132,7 +132,7 @@ def on_disk_zoom(
132
132
 
133
133
  def _find_closest_arrays(
134
134
  processed: list[zarr.Array], to_be_processed: list[zarr.Array]
135
- ) -> tuple[int, int]:
135
+ ) -> tuple[np.intp, np.intp]:
136
136
  dist_matrix = np.zeros((len(processed), len(to_be_processed)))
137
137
  for i, arr_to_proc in enumerate(to_be_processed):
138
138
  for j, proc_arr in enumerate(processed):
@@ -147,7 +147,9 @@ def _find_closest_arrays(
147
147
  )
148
148
  )
149
149
 
150
- return np.unravel_index(dist_matrix.argmin(), dist_matrix.shape)
150
+ indices = np.unravel_index(dist_matrix.argmin(), dist_matrix.shape)
151
+ assert len(indices) == 2, "Indices must be of length 2"
152
+ return indices
151
153
 
152
154
 
153
155
  def consolidate_pyramid(
@@ -178,9 +180,9 @@ def consolidate_pyramid(
178
180
  def init_empty_pyramid(
179
181
  store: StoreOrGroup,
180
182
  paths: list[str],
181
- ref_shape: Collection[int],
182
- scaling_factors: Collection[float],
183
- chunks: Collection[int] | None = None,
183
+ ref_shape: Sequence[int],
184
+ scaling_factors: Sequence[float],
185
+ chunks: Sequence[int] | None = None,
184
186
  dtype: str = "uint16",
185
187
  mode: AccessModeLiteral = "a",
186
188
  ) -> None: