ngio 0.1.6__py3-none-any.whl → 0.2.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.
- ngio/__init__.py +31 -5
- ngio/common/__init__.py +44 -0
- ngio/common/_array_pipe.py +160 -0
- ngio/common/_axes_transforms.py +63 -0
- ngio/common/_common_types.py +5 -0
- ngio/common/_dimensions.py +113 -0
- ngio/common/_pyramid.py +222 -0
- ngio/{core/roi.py → common/_roi.py} +22 -23
- ngio/common/_slicer.py +97 -0
- ngio/{pipes/_zoom_utils.py → common/_zoom.py} +2 -78
- ngio/hcs/__init__.py +60 -0
- ngio/images/__init__.py +23 -0
- ngio/images/abstract_image.py +240 -0
- ngio/images/create.py +251 -0
- ngio/images/image.py +383 -0
- ngio/images/label.py +96 -0
- ngio/images/omezarr_container.py +512 -0
- ngio/ome_zarr_meta/__init__.py +35 -0
- ngio/ome_zarr_meta/_generic_handlers.py +320 -0
- ngio/ome_zarr_meta/_meta_handlers.py +142 -0
- ngio/ome_zarr_meta/ngio_specs/__init__.py +63 -0
- ngio/ome_zarr_meta/ngio_specs/_axes.py +481 -0
- ngio/ome_zarr_meta/ngio_specs/_channels.py +378 -0
- ngio/ome_zarr_meta/ngio_specs/_dataset.py +134 -0
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +5 -0
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +434 -0
- ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +84 -0
- ngio/ome_zarr_meta/v04/__init__.py +11 -0
- ngio/ome_zarr_meta/v04/_meta_handlers.py +54 -0
- ngio/ome_zarr_meta/v04/_v04_spec_utils.py +412 -0
- ngio/tables/__init__.py +21 -5
- ngio/tables/_validators.py +192 -0
- ngio/tables/backends/__init__.py +8 -0
- ngio/tables/backends/_abstract_backend.py +71 -0
- ngio/tables/backends/_anndata_utils.py +194 -0
- ngio/tables/backends/_anndata_v1.py +75 -0
- ngio/tables/backends/_json_v1.py +56 -0
- ngio/tables/backends/_table_backends.py +102 -0
- ngio/tables/tables_container.py +300 -0
- ngio/tables/v1/__init__.py +6 -5
- ngio/tables/v1/_feature_table.py +161 -0
- ngio/tables/v1/_generic_table.py +99 -182
- ngio/tables/v1/_masking_roi_table.py +175 -0
- ngio/tables/v1/_roi_table.py +226 -0
- ngio/utils/__init__.py +23 -10
- ngio/utils/_datasets.py +51 -0
- ngio/utils/_errors.py +10 -4
- ngio/utils/_zarr_utils.py +378 -0
- {ngio-0.1.6.dist-info → ngio-0.2.0a1.dist-info}/METADATA +18 -39
- ngio-0.2.0a1.dist-info/RECORD +53 -0
- ngio/core/__init__.py +0 -7
- ngio/core/dimensions.py +0 -122
- ngio/core/image_handler.py +0 -228
- ngio/core/image_like_handler.py +0 -549
- ngio/core/label_handler.py +0 -410
- ngio/core/ngff_image.py +0 -387
- ngio/core/utils.py +0 -287
- ngio/io/__init__.py +0 -19
- ngio/io/_zarr.py +0 -88
- ngio/io/_zarr_array_utils.py +0 -0
- ngio/io/_zarr_group_utils.py +0 -60
- ngio/iterators/__init__.py +0 -1
- ngio/ngff_meta/__init__.py +0 -27
- ngio/ngff_meta/fractal_image_meta.py +0 -1267
- ngio/ngff_meta/meta_handler.py +0 -92
- ngio/ngff_meta/utils.py +0 -235
- ngio/ngff_meta/v04/__init__.py +0 -6
- ngio/ngff_meta/v04/specs.py +0 -158
- ngio/ngff_meta/v04/zarr_utils.py +0 -376
- ngio/pipes/__init__.py +0 -7
- ngio/pipes/_slicer_transforms.py +0 -176
- ngio/pipes/_transforms.py +0 -33
- ngio/pipes/data_pipe.py +0 -52
- ngio/tables/_ad_reader.py +0 -80
- ngio/tables/_utils.py +0 -301
- ngio/tables/tables_group.py +0 -252
- ngio/tables/v1/feature_tables.py +0 -182
- ngio/tables/v1/masking_roi_tables.py +0 -243
- ngio/tables/v1/roi_tables.py +0 -285
- ngio/utils/_common_types.py +0 -5
- ngio/utils/_pydantic_utils.py +0 -52
- ngio-0.1.6.dist-info/RECORD +0 -44
- {ngio-0.1.6.dist-info → ngio-0.2.0a1.dist-info}/WHEEL +0 -0
- {ngio-0.1.6.dist-info → ngio-0.2.0a1.dist-info}/licenses/LICENSE +0 -0
ngio/core/dimensions.py
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"""Dimension metadata.
|
|
2
|
-
|
|
3
|
-
This is not related to the NGFF metadata,
|
|
4
|
-
but it is based on the actual metadata of the image data.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from collections import OrderedDict
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Dimensions:
|
|
11
|
-
"""Dimension metadata."""
|
|
12
|
-
|
|
13
|
-
def __init__(
|
|
14
|
-
self,
|
|
15
|
-
on_disk_shape: tuple[int, ...],
|
|
16
|
-
axes_names: list[str],
|
|
17
|
-
axes_order: list[int],
|
|
18
|
-
) -> None:
|
|
19
|
-
"""Create a Dimension object from a Zarr array.
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
on_disk_shape (tuple[int, ...]): The shape of the array on disk.
|
|
23
|
-
axes_names (list[str]): The names of the axes in the canonical order.
|
|
24
|
-
axes_order (list[int]): The mapping between the canonical order and the on
|
|
25
|
-
disk order.
|
|
26
|
-
"""
|
|
27
|
-
self._on_disk_shape = on_disk_shape
|
|
28
|
-
|
|
29
|
-
for s in on_disk_shape:
|
|
30
|
-
if s < 1:
|
|
31
|
-
raise ValueError("The shape must be greater equal to 1.")
|
|
32
|
-
|
|
33
|
-
if len(self._on_disk_shape) != len(axes_names):
|
|
34
|
-
raise ValueError(
|
|
35
|
-
"The number of axes names must match the number of dimensions."
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
self._axes_names = axes_names
|
|
39
|
-
self._axes_order = axes_order
|
|
40
|
-
|
|
41
|
-
self._shape = [self._on_disk_shape[i] for i in axes_order]
|
|
42
|
-
self._shape_dict = OrderedDict(zip(axes_names, self._shape, strict=True))
|
|
43
|
-
|
|
44
|
-
def __str__(self) -> str:
|
|
45
|
-
"""Return the string representation of the object."""
|
|
46
|
-
_dimensions = ", ".join(
|
|
47
|
-
[f"{name}={self._shape_dict[name]}" for name in self._axes_names]
|
|
48
|
-
)
|
|
49
|
-
return f"Dimensions({_dimensions})"
|
|
50
|
-
|
|
51
|
-
def __repr__(self) -> str:
|
|
52
|
-
"""Return the string representation of the object."""
|
|
53
|
-
return str(self)
|
|
54
|
-
|
|
55
|
-
@property
|
|
56
|
-
def shape(self) -> tuple[int, ...]:
|
|
57
|
-
"""Return the shape as a tuple in the canonical order."""
|
|
58
|
-
return tuple(self._shape)
|
|
59
|
-
|
|
60
|
-
@property
|
|
61
|
-
def on_disk_shape(self) -> tuple[int, ...]:
|
|
62
|
-
"""Return the shape as a tuple."""
|
|
63
|
-
return self._on_disk_shape
|
|
64
|
-
|
|
65
|
-
def ad_dict(self) -> dict[str, int]:
|
|
66
|
-
"""Return the shape as a dictionary."""
|
|
67
|
-
return self._shape_dict
|
|
68
|
-
|
|
69
|
-
def get(self, ax_name: str, default: int = 1) -> int:
|
|
70
|
-
"""Return the dimension of the given axis name."""
|
|
71
|
-
return self._shape_dict.get(ax_name, default)
|
|
72
|
-
|
|
73
|
-
@property
|
|
74
|
-
def on_disk_ndim(self) -> int:
|
|
75
|
-
"""Return the number of dimensions on disk."""
|
|
76
|
-
return len(self._on_disk_shape)
|
|
77
|
-
|
|
78
|
-
@property
|
|
79
|
-
def is_time_series(self) -> bool:
|
|
80
|
-
"""Return whether the data is a time series."""
|
|
81
|
-
t = self._shape_dict.get("t", 1)
|
|
82
|
-
if t == 1:
|
|
83
|
-
return False
|
|
84
|
-
return True
|
|
85
|
-
|
|
86
|
-
@property
|
|
87
|
-
def is_2d(self) -> bool:
|
|
88
|
-
"""Return whether the data is 2D."""
|
|
89
|
-
z = self._shape_dict.get("z", 1)
|
|
90
|
-
if z != 1:
|
|
91
|
-
return False
|
|
92
|
-
return True
|
|
93
|
-
|
|
94
|
-
@property
|
|
95
|
-
def is_2d_time_series(self) -> bool:
|
|
96
|
-
"""Return whether the data is a 2D time series."""
|
|
97
|
-
return self.is_2d and self.is_time_series
|
|
98
|
-
|
|
99
|
-
@property
|
|
100
|
-
def is_3d(self) -> bool:
|
|
101
|
-
"""Return whether the data is 3D."""
|
|
102
|
-
return not self.is_2d
|
|
103
|
-
|
|
104
|
-
@property
|
|
105
|
-
def is_3d_time_series(self) -> bool:
|
|
106
|
-
"""Return whether the data is a 3D time series."""
|
|
107
|
-
return self.is_3d and self.is_time_series
|
|
108
|
-
|
|
109
|
-
@property
|
|
110
|
-
def is_multi_channels(self) -> bool:
|
|
111
|
-
"""Return whether the data has multiple channels."""
|
|
112
|
-
c = self._shape_dict.get("c", 1)
|
|
113
|
-
if c == 1:
|
|
114
|
-
return False
|
|
115
|
-
return True
|
|
116
|
-
|
|
117
|
-
def find_axis(self, ax_name: str) -> int | None:
|
|
118
|
-
"""Return the index of the axis name."""
|
|
119
|
-
for i, ax in enumerate(self._axes_names):
|
|
120
|
-
if ax == ax_name:
|
|
121
|
-
return i
|
|
122
|
-
return None
|
ngio/core/image_handler.py
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
"""A module to handle OME-NGFF images stored in Zarr format."""
|
|
2
|
-
|
|
3
|
-
from typing import Any, Literal
|
|
4
|
-
|
|
5
|
-
from ngio.core.image_like_handler import ImageLike
|
|
6
|
-
from ngio.core.roi import WorldCooROI
|
|
7
|
-
from ngio.io import AccessModeLiteral, StoreOrGroup
|
|
8
|
-
from ngio.ngff_meta import PixelSize
|
|
9
|
-
from ngio.ngff_meta.fractal_image_meta import ImageMeta
|
|
10
|
-
from ngio.utils._common_types import ArrayLike
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Image(ImageLike):
|
|
14
|
-
"""A class to handle OME-NGFF images stored in Zarr format.
|
|
15
|
-
|
|
16
|
-
This class provides methods to load image data and metadata from
|
|
17
|
-
an OME-Zarr file.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
def __init__(
|
|
21
|
-
self,
|
|
22
|
-
store: StoreOrGroup,
|
|
23
|
-
*,
|
|
24
|
-
path: str | None = None,
|
|
25
|
-
idx: int | None = None,
|
|
26
|
-
pixel_size: PixelSize | None = None,
|
|
27
|
-
highest_resolution: bool = False,
|
|
28
|
-
strict: bool = True,
|
|
29
|
-
cache: bool = True,
|
|
30
|
-
mode: AccessModeLiteral = "r+",
|
|
31
|
-
label_group: Any = None,
|
|
32
|
-
) -> None:
|
|
33
|
-
"""Initialize the the Image Object.
|
|
34
|
-
|
|
35
|
-
Note: Only one of `path`, `idx`, 'pixel_size' or 'highest_resolution'
|
|
36
|
-
should be provided.
|
|
37
|
-
|
|
38
|
-
store (StoreOrGroup): The Zarr store or group containing the image data.
|
|
39
|
-
path (str | None): The path to the level.
|
|
40
|
-
idx (int | None): The index of the level.
|
|
41
|
-
pixel_size (PixelSize | None): The pixel size of the level.
|
|
42
|
-
highest_resolution (bool): Whether to get the highest resolution level.
|
|
43
|
-
strict (bool): Whether to raise an error where a pixel size is not found
|
|
44
|
-
to match the requested "pixel_size".
|
|
45
|
-
cache (bool): Whether to cache the metadata.
|
|
46
|
-
mode (AccessModeLiteral): The mode to open the group in.
|
|
47
|
-
label_group: The group containing the labels.
|
|
48
|
-
"""
|
|
49
|
-
super().__init__(
|
|
50
|
-
store=store,
|
|
51
|
-
path=path,
|
|
52
|
-
idx=idx,
|
|
53
|
-
pixel_size=pixel_size,
|
|
54
|
-
highest_resolution=highest_resolution,
|
|
55
|
-
strict=strict,
|
|
56
|
-
meta_mode="image",
|
|
57
|
-
cache=cache,
|
|
58
|
-
mode=mode,
|
|
59
|
-
_label_group=label_group,
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
def __repr__(self) -> str:
|
|
63
|
-
"""Return the string representation of the class."""
|
|
64
|
-
name = "Image("
|
|
65
|
-
len_name = len(name)
|
|
66
|
-
return (
|
|
67
|
-
f"{name}"
|
|
68
|
-
f"group_path={self.group_path}, \n"
|
|
69
|
-
f"{' ':>{len_name}}path={self.path},\n"
|
|
70
|
-
f"{' ':>{len_name}}{self.pixel_size},\n"
|
|
71
|
-
f"{' ':>{len_name}}{self.dimensions},\n"
|
|
72
|
-
")"
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
@property
|
|
76
|
-
def metadata(self) -> ImageMeta:
|
|
77
|
-
"""Return the metadata of the image."""
|
|
78
|
-
meta = super().metadata
|
|
79
|
-
assert isinstance(meta, ImageMeta)
|
|
80
|
-
return meta
|
|
81
|
-
|
|
82
|
-
@property
|
|
83
|
-
def channel_labels(self) -> list[str]:
|
|
84
|
-
"""Return the names of the channels in the image."""
|
|
85
|
-
return self.metadata.channel_labels
|
|
86
|
-
|
|
87
|
-
@property
|
|
88
|
-
def num_channels(self) -> int:
|
|
89
|
-
"""Return the number of channels in the image."""
|
|
90
|
-
return self.dimensions.get("c", 1)
|
|
91
|
-
|
|
92
|
-
def get_channel_idx(
|
|
93
|
-
self,
|
|
94
|
-
label: str | None = None,
|
|
95
|
-
wavelength_id: str | None = None,
|
|
96
|
-
) -> int | None:
|
|
97
|
-
"""Return the index of the channel.
|
|
98
|
-
|
|
99
|
-
If the channels are not labelled, the index returned is none
|
|
100
|
-
"""
|
|
101
|
-
return self.metadata.get_channel_idx(label=label, wavelength_id=wavelength_id)
|
|
102
|
-
|
|
103
|
-
def get_array_from_roi(
|
|
104
|
-
self,
|
|
105
|
-
roi: WorldCooROI,
|
|
106
|
-
c: int | str | None = None,
|
|
107
|
-
t: int | slice | None = None,
|
|
108
|
-
mode: Literal["numpy"] | Literal["dask"] = "numpy",
|
|
109
|
-
preserve_dimensions: bool = False,
|
|
110
|
-
) -> ArrayLike:
|
|
111
|
-
"""Return the image data from a region of interest (ROI).
|
|
112
|
-
|
|
113
|
-
Args:
|
|
114
|
-
roi (WorldCooROI): The region of interest.
|
|
115
|
-
c (int | str | None): The channel index or label.
|
|
116
|
-
t (int | slice | None): The time index or slice.
|
|
117
|
-
mode (str): The mode to return the data.
|
|
118
|
-
preserve_dimensions (bool): Whether to preserve the dimensions of the data.
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
ArrayLike: The image data.
|
|
122
|
-
"""
|
|
123
|
-
if isinstance(c, str):
|
|
124
|
-
c = self.get_channel_idx(label=c)
|
|
125
|
-
|
|
126
|
-
return self._get_array_from_roi(
|
|
127
|
-
roi=roi, t=t, c=c, mode=mode, preserve_dimensions=preserve_dimensions
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
def set_array_from_roi(
|
|
131
|
-
self,
|
|
132
|
-
patch: ArrayLike,
|
|
133
|
-
roi: WorldCooROI,
|
|
134
|
-
c: int | str | None = None,
|
|
135
|
-
t: int | slice | None = None,
|
|
136
|
-
preserve_dimensions: bool = False,
|
|
137
|
-
) -> None:
|
|
138
|
-
"""Set the image data from a region of interest (ROI).
|
|
139
|
-
|
|
140
|
-
Args:
|
|
141
|
-
roi (WorldCooROI): The region of interest.
|
|
142
|
-
patch (ArrayLike): The patch to set.
|
|
143
|
-
c (int | str | None): The channel index or label.
|
|
144
|
-
t (int | slice | None): The time index or slice.
|
|
145
|
-
preserve_dimensions (bool): Whether to preserve the dimensions of the data.
|
|
146
|
-
|
|
147
|
-
"""
|
|
148
|
-
if isinstance(c, str):
|
|
149
|
-
c = self.get_channel_idx(label=c)
|
|
150
|
-
|
|
151
|
-
return self._set_array_from_roi(
|
|
152
|
-
patch=patch, roi=roi, t=t, c=c, preserve_dimensions=preserve_dimensions
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
def get_array(
|
|
156
|
-
self,
|
|
157
|
-
*,
|
|
158
|
-
x: int | slice | None = None,
|
|
159
|
-
y: int | slice | None = None,
|
|
160
|
-
z: int | slice | None = None,
|
|
161
|
-
c: int | str | None = None,
|
|
162
|
-
t: int | slice | None = None,
|
|
163
|
-
mode: Literal["numpy"] | Literal["dask"] = "numpy",
|
|
164
|
-
preserve_dimensions: bool = False,
|
|
165
|
-
) -> ArrayLike:
|
|
166
|
-
"""Return the image data.
|
|
167
|
-
|
|
168
|
-
Args:
|
|
169
|
-
x (int | slice | None): The x index or slice.
|
|
170
|
-
y (int | slice | None): The y index or slice.
|
|
171
|
-
z (int | slice | None): The z index or slice.
|
|
172
|
-
c (int | str | None): The channel index or label.
|
|
173
|
-
t (int | slice | None): The time index or slice.
|
|
174
|
-
mode (str): The mode to return the data.
|
|
175
|
-
preserve_dimensions (bool): Whether to preserve the dimensions of the data.
|
|
176
|
-
|
|
177
|
-
Returns:
|
|
178
|
-
ArrayLike: The image data.
|
|
179
|
-
"""
|
|
180
|
-
if isinstance(c, str):
|
|
181
|
-
c = self.get_channel_idx(label=c)
|
|
182
|
-
|
|
183
|
-
return self._get_array(
|
|
184
|
-
x=x,
|
|
185
|
-
y=y,
|
|
186
|
-
z=z,
|
|
187
|
-
t=t,
|
|
188
|
-
c=c,
|
|
189
|
-
mode=mode,
|
|
190
|
-
preserve_dimensions=preserve_dimensions,
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
def set_array(
|
|
194
|
-
self,
|
|
195
|
-
patch: ArrayLike,
|
|
196
|
-
x: int | slice | None = None,
|
|
197
|
-
y: int | slice | None = None,
|
|
198
|
-
z: int | slice | None = None,
|
|
199
|
-
c: int | str | None = None,
|
|
200
|
-
t: int | slice | None = None,
|
|
201
|
-
preserve_dimensions: bool = False,
|
|
202
|
-
) -> None:
|
|
203
|
-
"""Set the image data in the zarr array.
|
|
204
|
-
|
|
205
|
-
Args:
|
|
206
|
-
patch (ArrayLike): The patch to set.
|
|
207
|
-
x (int | slice | None): The x index or slice.
|
|
208
|
-
y (int | slice | None): The y index or slice.
|
|
209
|
-
z (int | slice | None): The z index or slice.
|
|
210
|
-
c (int | str | None): The channel index or label.
|
|
211
|
-
t (int | slice | None): The time index or slice.
|
|
212
|
-
preserve_dimensions (bool): Whether to preserve the dimensions of the data.
|
|
213
|
-
"""
|
|
214
|
-
if isinstance(c, str):
|
|
215
|
-
c = self.get_channel_idx(label=c)
|
|
216
|
-
return self._set_array(
|
|
217
|
-
patch=patch,
|
|
218
|
-
x=x,
|
|
219
|
-
y=y,
|
|
220
|
-
z=z,
|
|
221
|
-
t=t,
|
|
222
|
-
c=c,
|
|
223
|
-
preserve_dimensions=preserve_dimensions,
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
def consolidate(self, order: Literal[0, 1, 2] = 1) -> None:
|
|
227
|
-
"""Consolidate the image."""
|
|
228
|
-
self._consolidate(order=order)
|