ngio 0.2.0b2__py3-none-any.whl → 0.2.1__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 +11 -9
- ngio/common/__init__.py +3 -3
- ngio/common/_array_pipe.py +6 -7
- ngio/common/_masking_roi.py +4 -4
- ngio/common/_roi.py +12 -12
- ngio/hcs/__init__.py +2 -2
- ngio/hcs/plate.py +86 -34
- ngio/images/__init__.py +7 -7
- ngio/images/abstract_image.py +50 -10
- ngio/images/create.py +4 -3
- ngio/images/image.py +2 -2
- ngio/images/label.py +10 -6
- ngio/images/masked_image.py +19 -5
- ngio/images/{omezarr_container.py → ome_zarr_container.py} +57 -30
- ngio/ome_zarr_meta/__init__.py +3 -0
- ngio/ome_zarr_meta/ngio_specs/__init__.py +2 -0
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +5 -4
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +9 -19
- ngio/ome_zarr_meta/v04/_v04_spec_utils.py +1 -2
- ngio/tables/__init__.py +2 -2
- ngio/tables/tables_container.py +3 -3
- ngio/tables/v1/__init__.py +2 -2
- ngio/tables/v1/_feature_table.py +20 -1
- ngio/tables/v1/_generic_table.py +10 -0
- ngio/tables/v1/_roi_table.py +35 -13
- {ngio-0.2.0b2.dist-info → ngio-0.2.1.dist-info}/METADATA +9 -5
- ngio-0.2.1.dist-info/RECORD +54 -0
- ngio-0.2.0b2.dist-info/RECORD +0 -54
- {ngio-0.2.0b2.dist-info → ngio-0.2.1.dist-info}/WHEEL +0 -0
- {ngio-0.2.0b2.dist-info → ngio-0.2.1.dist-info}/licenses/LICENSE +0 -0
ngio/__init__.py
CHANGED
|
@@ -9,16 +9,16 @@ except PackageNotFoundError: # pragma: no cover
|
|
|
9
9
|
__author__ = "Lorenzo Cerrone"
|
|
10
10
|
__email__ = "lorenzo.cerrone@uzh.ch"
|
|
11
11
|
|
|
12
|
-
from ngio.common import ArrayLike, Dimensions
|
|
13
|
-
from ngio.hcs import OmeZarrPlate, create_empty_plate,
|
|
12
|
+
from ngio.common import ArrayLike, Dimensions, Roi, RoiPixels
|
|
13
|
+
from ngio.hcs import OmeZarrPlate, create_empty_plate, open_ome_zarr_plate
|
|
14
14
|
from ngio.images import (
|
|
15
15
|
Image,
|
|
16
16
|
Label,
|
|
17
17
|
OmeZarrContainer,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
create_empty_ome_zarr,
|
|
19
|
+
create_ome_zarr_from_array,
|
|
20
20
|
open_image,
|
|
21
|
-
|
|
21
|
+
open_ome_zarr_container,
|
|
22
22
|
)
|
|
23
23
|
from ngio.ome_zarr_meta.ngio_specs import AxesSetup, ImageInWellPath, PixelSize
|
|
24
24
|
|
|
@@ -32,10 +32,12 @@ __all__ = [
|
|
|
32
32
|
"OmeZarrContainer",
|
|
33
33
|
"OmeZarrPlate",
|
|
34
34
|
"PixelSize",
|
|
35
|
-
"
|
|
35
|
+
"Roi",
|
|
36
|
+
"RoiPixels",
|
|
37
|
+
"create_empty_ome_zarr",
|
|
36
38
|
"create_empty_plate",
|
|
37
|
-
"
|
|
39
|
+
"create_ome_zarr_from_array",
|
|
38
40
|
"open_image",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
+
"open_ome_zarr_container",
|
|
42
|
+
"open_ome_zarr_plate",
|
|
41
43
|
]
|
ngio/common/__init__.py
CHANGED
|
@@ -15,7 +15,7 @@ from ngio.common._common_types import ArrayLike
|
|
|
15
15
|
from ngio.common._dimensions import Dimensions
|
|
16
16
|
from ngio.common._masking_roi import compute_masking_roi
|
|
17
17
|
from ngio.common._pyramid import consolidate_pyramid, init_empty_pyramid, on_disk_zoom
|
|
18
|
-
from ngio.common._roi import
|
|
18
|
+
from ngio.common._roi import Roi, RoiPixels, roi_to_slice_kwargs
|
|
19
19
|
from ngio.common._slicer import (
|
|
20
20
|
SliceTransform,
|
|
21
21
|
compute_and_slices,
|
|
@@ -29,9 +29,9 @@ from ngio.common._zoom import dask_zoom, numpy_zoom
|
|
|
29
29
|
__all__ = [
|
|
30
30
|
"ArrayLike",
|
|
31
31
|
"Dimensions",
|
|
32
|
-
"
|
|
32
|
+
"Roi",
|
|
33
|
+
"RoiPixels",
|
|
33
34
|
"SliceTransform",
|
|
34
|
-
"WorldCooROI",
|
|
35
35
|
"compute_and_slices",
|
|
36
36
|
"compute_masking_roi",
|
|
37
37
|
"consolidate_pyramid",
|
ngio/common/_array_pipe.py
CHANGED
|
@@ -124,7 +124,7 @@ def get_pipe(
|
|
|
124
124
|
case "dask":
|
|
125
125
|
return _dask_get_pipe(array, slices, transformations)
|
|
126
126
|
|
|
127
|
-
case "
|
|
127
|
+
case "delayed":
|
|
128
128
|
return _delayed_numpy_get_pipe(array, slices, transformations)
|
|
129
129
|
|
|
130
130
|
case _:
|
|
@@ -179,12 +179,11 @@ def _mask_pipe_common(
|
|
|
179
179
|
**slice_kwargs,
|
|
180
180
|
)
|
|
181
181
|
|
|
182
|
-
if "c"
|
|
183
|
-
#
|
|
184
|
-
#
|
|
185
|
-
#
|
|
186
|
-
|
|
187
|
-
slice_kwargs.pop("c")
|
|
182
|
+
if not dimensions_label.has_axis("c"):
|
|
183
|
+
# Remove the 'c' from the slice_kwargs
|
|
184
|
+
# This will not work if the query uses non-default
|
|
185
|
+
# axes names for channel
|
|
186
|
+
slice_kwargs = {k: v for k, v in slice_kwargs.items() if k != "c"}
|
|
188
187
|
|
|
189
188
|
label_patch = get_pipe(
|
|
190
189
|
label_array,
|
ngio/common/_masking_roi.py
CHANGED
|
@@ -8,7 +8,7 @@ import dask.delayed
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import scipy.ndimage as ndi
|
|
10
10
|
|
|
11
|
-
from ngio.common._roi import
|
|
11
|
+
from ngio.common._roi import Roi, RoiPixels
|
|
12
12
|
from ngio.ome_zarr_meta import PixelSize
|
|
13
13
|
from ngio.utils import NgioValueError
|
|
14
14
|
|
|
@@ -117,7 +117,7 @@ def lazy_compute_slices(segmentation: da.Array) -> dict[int, tuple[slice, ...]]:
|
|
|
117
117
|
|
|
118
118
|
def compute_masking_roi(
|
|
119
119
|
segmentation: np.ndarray | da.Array, pixel_size: PixelSize
|
|
120
|
-
) -> list[
|
|
120
|
+
) -> list[Roi]:
|
|
121
121
|
"""Compute a ROIs for each label in a segmentation.
|
|
122
122
|
|
|
123
123
|
This function expects a 2D or 3D segmentation array.
|
|
@@ -143,7 +143,7 @@ def compute_masking_roi(
|
|
|
143
143
|
max_z, max_y, max_x = slice_[0].stop, slice_[1].stop, slice_[2].stop
|
|
144
144
|
else:
|
|
145
145
|
raise ValueError("Invalid slice length.")
|
|
146
|
-
roi =
|
|
146
|
+
roi = RoiPixels(
|
|
147
147
|
name=str(label),
|
|
148
148
|
x_length=max_x - min_x,
|
|
149
149
|
y_length=max_y - min_y,
|
|
@@ -153,6 +153,6 @@ def compute_masking_roi(
|
|
|
153
153
|
z=min_z,
|
|
154
154
|
)
|
|
155
155
|
|
|
156
|
-
roi = roi.
|
|
156
|
+
roi = roi.to_roi(pixel_size)
|
|
157
157
|
rois.append(roi)
|
|
158
158
|
return rois
|
ngio/common/_roi.py
CHANGED
|
@@ -26,7 +26,7 @@ def _to_world(value: int, pixel_size: float) -> float:
|
|
|
26
26
|
return value * pixel_size
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class
|
|
29
|
+
class Roi(BaseModel):
|
|
30
30
|
"""Region of interest (ROI) metadata."""
|
|
31
31
|
|
|
32
32
|
name: str
|
|
@@ -40,16 +40,16 @@ class WorldCooROI(BaseModel):
|
|
|
40
40
|
|
|
41
41
|
model_config = ConfigDict(extra="allow")
|
|
42
42
|
|
|
43
|
-
def
|
|
43
|
+
def to_pixel_roi(
|
|
44
44
|
self, pixel_size: PixelSize, dimensions: Dimensions
|
|
45
|
-
) -> "
|
|
45
|
+
) -> "RoiPixels":
|
|
46
46
|
"""Convert to raster coordinates."""
|
|
47
47
|
dim_x = dimensions.get("x")
|
|
48
48
|
dim_y = dimensions.get("y")
|
|
49
49
|
# Will default to 1 if z does not exist
|
|
50
50
|
dim_z = dimensions.get("z", strict=False)
|
|
51
51
|
|
|
52
|
-
return
|
|
52
|
+
return RoiPixels(
|
|
53
53
|
name=self.name,
|
|
54
54
|
x=_to_raster(self.x, pixel_size.x, dim_x),
|
|
55
55
|
y=_to_raster(self.y, pixel_size.y, dim_y),
|
|
@@ -59,7 +59,7 @@ class WorldCooROI(BaseModel):
|
|
|
59
59
|
z_length=_to_raster(self.z_length, pixel_size.z, dim_z),
|
|
60
60
|
)
|
|
61
61
|
|
|
62
|
-
def zoom(self, zoom_factor: float = 1) -> "
|
|
62
|
+
def zoom(self, zoom_factor: float = 1) -> "Roi":
|
|
63
63
|
"""Zoom the ROI by a factor.
|
|
64
64
|
|
|
65
65
|
Args:
|
|
@@ -71,7 +71,7 @@ class WorldCooROI(BaseModel):
|
|
|
71
71
|
return zoom_roi(self, zoom_factor)
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
class
|
|
74
|
+
class RoiPixels(BaseModel):
|
|
75
75
|
"""Region of interest (ROI) metadata."""
|
|
76
76
|
|
|
77
77
|
name: str
|
|
@@ -83,9 +83,9 @@ class RasterCooROI(BaseModel):
|
|
|
83
83
|
z_length: int
|
|
84
84
|
model_config = ConfigDict(extra="allow")
|
|
85
85
|
|
|
86
|
-
def
|
|
86
|
+
def to_roi(self, pixel_size: PixelSize) -> Roi:
|
|
87
87
|
"""Convert to world coordinates."""
|
|
88
|
-
return
|
|
88
|
+
return Roi(
|
|
89
89
|
name=self.name,
|
|
90
90
|
x=_to_world(self.x, pixel_size.x),
|
|
91
91
|
y=_to_world(self.y, pixel_size.y),
|
|
@@ -105,7 +105,7 @@ class RasterCooROI(BaseModel):
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
def zoom_roi(roi:
|
|
108
|
+
def zoom_roi(roi: Roi, zoom_factor: float = 1) -> Roi:
|
|
109
109
|
"""Zoom the ROI by a factor.
|
|
110
110
|
|
|
111
111
|
Args:
|
|
@@ -127,7 +127,7 @@ def zoom_roi(roi: WorldCooROI, zoom_factor: float = 1) -> WorldCooROI:
|
|
|
127
127
|
new_x = max(roi.x - diff_x / 2, 0)
|
|
128
128
|
new_y = max(roi.y - diff_y / 2, 0)
|
|
129
129
|
|
|
130
|
-
new_roi =
|
|
130
|
+
new_roi = Roi(
|
|
131
131
|
name=roi.name,
|
|
132
132
|
x=new_x,
|
|
133
133
|
y=new_y,
|
|
@@ -142,13 +142,13 @@ def zoom_roi(roi: WorldCooROI, zoom_factor: float = 1) -> WorldCooROI:
|
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
def roi_to_slice_kwargs(
|
|
145
|
-
roi:
|
|
145
|
+
roi: Roi,
|
|
146
146
|
pixel_size: PixelSize,
|
|
147
147
|
dimensions: Dimensions,
|
|
148
148
|
**slice_kwargs: slice | int | Iterable[int],
|
|
149
149
|
) -> dict[str, slice | int | Iterable[int]]:
|
|
150
150
|
"""Convert a WorldCooROI to slice_kwargs."""
|
|
151
|
-
raster_roi = roi.
|
|
151
|
+
raster_roi = roi.to_pixel_roi(
|
|
152
152
|
pixel_size=pixel_size, dimensions=dimensions
|
|
153
153
|
).to_slices()
|
|
154
154
|
|
ngio/hcs/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""OME-Zarr HCS objects models."""
|
|
2
2
|
|
|
3
|
-
from ngio.hcs.plate import OmeZarrPlate, create_empty_plate,
|
|
3
|
+
from ngio.hcs.plate import OmeZarrPlate, create_empty_plate, open_ome_zarr_plate
|
|
4
4
|
|
|
5
|
-
__all__ = ["OmeZarrPlate", "create_empty_plate", "
|
|
5
|
+
__all__ = ["OmeZarrPlate", "create_empty_plate", "open_ome_zarr_plate"]
|
ngio/hcs/plate.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from ngio.images import OmeZarrContainer
|
|
4
4
|
from ngio.ome_zarr_meta import (
|
|
5
5
|
ImageInWellPath,
|
|
6
|
+
NgffVersion,
|
|
6
7
|
NgioPlateMeta,
|
|
7
8
|
NgioWellMeta,
|
|
8
9
|
find_plate_meta_handler,
|
|
@@ -78,7 +79,7 @@ class OmeZarrPlate:
|
|
|
78
79
|
|
|
79
80
|
def __repr__(self) -> str:
|
|
80
81
|
"""Return a string representation of the plate."""
|
|
81
|
-
return f"Plate([rows x columns] ({len(self.rows)} x {len(self.columns)})"
|
|
82
|
+
return f"Plate([rows x columns] ({len(self.rows)} x {len(self.columns)}))"
|
|
82
83
|
|
|
83
84
|
@property
|
|
84
85
|
def meta_handler(self):
|
|
@@ -110,21 +111,54 @@ class OmeZarrPlate:
|
|
|
110
111
|
"""Return the acquisitions ids in the plate."""
|
|
111
112
|
return self.meta.acquisitions_ids
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
def wells_paths(self) -> list[str]:
|
|
115
|
-
"""Return the wells paths in the plate."""
|
|
116
|
-
return self.meta.wells_paths
|
|
117
|
-
|
|
118
|
-
def get_well_path(self, row: str, column: int | str) -> str:
|
|
114
|
+
def _well_path(self, row: str, column: int | str) -> str:
|
|
119
115
|
"""Return the well path in the plate."""
|
|
120
116
|
return self.meta.get_well_path(row=row, column=column)
|
|
121
117
|
|
|
122
|
-
def
|
|
118
|
+
def _image_path(self, row: str, column: int | str, path: str) -> str:
|
|
123
119
|
"""Return the image path in the plate."""
|
|
124
120
|
well = self.get_well(row, column)
|
|
125
121
|
if path not in well.paths():
|
|
126
122
|
raise ValueError(f"Image {path} does not exist in well {row}{column}")
|
|
127
|
-
return f"{self.
|
|
123
|
+
return f"{self._well_path(row, column)}/{path}"
|
|
124
|
+
|
|
125
|
+
def wells_paths(self) -> list[str]:
|
|
126
|
+
"""Return the wells paths in the plate."""
|
|
127
|
+
return self.meta.wells_paths
|
|
128
|
+
|
|
129
|
+
def images_paths(self, acquisition: int | None = None) -> list[str]:
|
|
130
|
+
"""Return the images paths in the plate.
|
|
131
|
+
|
|
132
|
+
If acquisition is None, return all images paths in the plate.
|
|
133
|
+
Else, return the images paths in the plate for the given acquisition.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
acquisition (int | None): The acquisition id to filter the images.
|
|
137
|
+
"""
|
|
138
|
+
images = []
|
|
139
|
+
for well_path, wells in self.get_wells().items():
|
|
140
|
+
for img_path in wells.paths(acquisition):
|
|
141
|
+
images.append(f"{well_path}/{img_path}")
|
|
142
|
+
return images
|
|
143
|
+
|
|
144
|
+
def well_images_paths(
|
|
145
|
+
self, row: str, column: int | str, acquisition: int | None = None
|
|
146
|
+
) -> list[str]:
|
|
147
|
+
"""Return the images paths in a well.
|
|
148
|
+
|
|
149
|
+
If acquisition is None, return all images paths in the well.
|
|
150
|
+
Else, return the images paths in the well for the given acquisition.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
row (str): The row of the well.
|
|
154
|
+
column (int | str): The column of the well.
|
|
155
|
+
acquisition (int | None): The acquisition id to filter the images.
|
|
156
|
+
"""
|
|
157
|
+
images = []
|
|
158
|
+
well = self.get_well(row=row, column=column)
|
|
159
|
+
for path in well.paths(acquisition):
|
|
160
|
+
images.append(self._image_path(row=row, column=column, path=path))
|
|
161
|
+
return images
|
|
128
162
|
|
|
129
163
|
def get_well(self, row: str, column: int | str) -> OmeZarrWell:
|
|
130
164
|
"""Get a well from the plate.
|
|
@@ -136,36 +170,56 @@ class OmeZarrPlate:
|
|
|
136
170
|
Returns:
|
|
137
171
|
OmeZarrWell: The well.
|
|
138
172
|
"""
|
|
139
|
-
well_path = self.
|
|
173
|
+
well_path = self._well_path(row=row, column=column)
|
|
140
174
|
group_handler = self._group_handler.derive_handler(well_path)
|
|
141
175
|
return OmeZarrWell(group_handler)
|
|
142
176
|
|
|
143
177
|
def get_wells(self) -> dict[str, OmeZarrWell]:
|
|
144
|
-
"""Get all wells in the plate.
|
|
178
|
+
"""Get all wells in the plate.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
dict[str, OmeZarrWell]: A dictionary of wells, where the key is the well
|
|
182
|
+
path and the value is the well object.
|
|
183
|
+
"""
|
|
145
184
|
wells = {}
|
|
146
|
-
for well_path in self.wells_paths:
|
|
185
|
+
for well_path in self.wells_paths():
|
|
147
186
|
group_handler = self._group_handler.derive_handler(well_path)
|
|
148
187
|
well = OmeZarrWell(group_handler)
|
|
149
188
|
wells[well_path] = well
|
|
150
189
|
return wells
|
|
151
190
|
|
|
152
|
-
def get_images(self, acquisition: int | None = None) ->
|
|
191
|
+
def get_images(self, acquisition: int | None = None) -> dict[str, OmeZarrContainer]:
|
|
153
192
|
"""Get all images in the plate.
|
|
154
193
|
|
|
155
194
|
Args:
|
|
156
195
|
acquisition: The acquisition id to filter the images.
|
|
157
196
|
"""
|
|
158
|
-
images =
|
|
159
|
-
for
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
img_group_handler = self._group_handler.derive_handler(full_path)
|
|
163
|
-
images.append(OmeZarrContainer(img_group_handler))
|
|
197
|
+
images = {}
|
|
198
|
+
for image_path in self.images_paths(acquisition):
|
|
199
|
+
img_group_handler = self._group_handler.derive_handler(image_path)
|
|
200
|
+
images[image_path] = OmeZarrContainer(img_group_handler)
|
|
164
201
|
return images
|
|
165
202
|
|
|
203
|
+
def get_image(
|
|
204
|
+
self, row: str, column: int | str, image_path: str
|
|
205
|
+
) -> OmeZarrContainer:
|
|
206
|
+
"""Get an image from the plate.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
row (str): The row of the well.
|
|
210
|
+
column (int | str): The column of the well.
|
|
211
|
+
image_path (str): The path of the image.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
OmeZarrContainer: The image.
|
|
215
|
+
"""
|
|
216
|
+
image_path = self._image_path(row=row, column=column, path=image_path)
|
|
217
|
+
group_handler = self._group_handler.derive_handler(image_path)
|
|
218
|
+
return OmeZarrContainer(group_handler)
|
|
219
|
+
|
|
166
220
|
def get_well_images(
|
|
167
221
|
self, row: str, column: str | int, acquisition: int | None = None
|
|
168
|
-
) ->
|
|
222
|
+
) -> dict[str, OmeZarrContainer]:
|
|
169
223
|
"""Get all images in a well.
|
|
170
224
|
|
|
171
225
|
Args:
|
|
@@ -173,16 +227,12 @@ class OmeZarrPlate:
|
|
|
173
227
|
column: The column of the well.
|
|
174
228
|
acquisition: The acquisition id to filter the images.
|
|
175
229
|
"""
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
image_path = f"{well_path}/{path}"
|
|
183
|
-
group_handler = self._group_handler.derive_handler(image_path)
|
|
184
|
-
images.append(OmeZarrContainer(group_handler))
|
|
185
|
-
|
|
230
|
+
images = {}
|
|
231
|
+
for image_paths in self.well_images_paths(
|
|
232
|
+
row=row, column=column, acquisition=acquisition
|
|
233
|
+
):
|
|
234
|
+
group_handler = self._group_handler.derive_handler(image_paths)
|
|
235
|
+
images[image_paths] = OmeZarrContainer(group_handler)
|
|
186
236
|
return images
|
|
187
237
|
|
|
188
238
|
def _add_image(
|
|
@@ -220,7 +270,9 @@ class OmeZarrPlate:
|
|
|
220
270
|
# Initialize the well metadata
|
|
221
271
|
# if the group is empty
|
|
222
272
|
well_meta = NgioWellMeta.default_init()
|
|
223
|
-
|
|
273
|
+
version = self.meta.plate.version
|
|
274
|
+
version = version if version is not None else "0.4"
|
|
275
|
+
meta_handler = get_well_meta_handler(group_handler, version=version)
|
|
224
276
|
else:
|
|
225
277
|
meta_handler = find_well_meta_handler(group_handler)
|
|
226
278
|
well_meta = meta_handler.meta
|
|
@@ -339,7 +391,7 @@ class OmeZarrPlate:
|
|
|
339
391
|
)
|
|
340
392
|
|
|
341
393
|
|
|
342
|
-
def
|
|
394
|
+
def open_ome_zarr_plate(
|
|
343
395
|
store: StoreOrGroup,
|
|
344
396
|
cache: bool = False,
|
|
345
397
|
mode: AccessModeLiteral = "r+",
|
|
@@ -364,7 +416,7 @@ def create_empty_plate(
|
|
|
364
416
|
store: StoreOrGroup,
|
|
365
417
|
name: str,
|
|
366
418
|
images: list[ImageInWellPath] | None = None,
|
|
367
|
-
version:
|
|
419
|
+
version: NgffVersion = "0.4",
|
|
368
420
|
cache: bool = False,
|
|
369
421
|
overwrite: bool = False,
|
|
370
422
|
parallel_safe: bool = True,
|
|
@@ -391,7 +443,7 @@ def create_empty_plate(
|
|
|
391
443
|
acquisition_id=image.acquisition_id,
|
|
392
444
|
acquisition_name=image.acquisition_name,
|
|
393
445
|
)
|
|
394
|
-
return
|
|
446
|
+
return open_ome_zarr_plate(
|
|
395
447
|
store=store,
|
|
396
448
|
cache=cache,
|
|
397
449
|
mode="r+",
|
ngio/images/__init__.py
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from ngio.images.image import Image, ImagesContainer
|
|
4
4
|
from ngio.images.label import Label, LabelsContainer
|
|
5
|
-
from ngio.images.
|
|
5
|
+
from ngio.images.ome_zarr_container import (
|
|
6
6
|
OmeZarrContainer,
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
create_empty_ome_zarr,
|
|
8
|
+
create_ome_zarr_from_array,
|
|
9
9
|
open_image,
|
|
10
|
-
|
|
10
|
+
open_ome_zarr_container,
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
__all__ = [
|
|
@@ -16,8 +16,8 @@ __all__ = [
|
|
|
16
16
|
"Label",
|
|
17
17
|
"LabelsContainer",
|
|
18
18
|
"OmeZarrContainer",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
19
|
+
"create_empty_ome_zarr",
|
|
20
|
+
"create_ome_zarr_from_array",
|
|
21
21
|
"open_image",
|
|
22
|
-
"
|
|
22
|
+
"open_ome_zarr_container",
|
|
23
23
|
]
|
ngio/images/abstract_image.py
CHANGED
|
@@ -8,14 +8,15 @@ import zarr
|
|
|
8
8
|
from ngio.common import (
|
|
9
9
|
ArrayLike,
|
|
10
10
|
Dimensions,
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Roi,
|
|
12
|
+
RoiPixels,
|
|
13
13
|
consolidate_pyramid,
|
|
14
14
|
get_pipe,
|
|
15
15
|
roi_to_slice_kwargs,
|
|
16
16
|
set_pipe,
|
|
17
17
|
)
|
|
18
18
|
from ngio.ome_zarr_meta import (
|
|
19
|
+
AxesMapper,
|
|
19
20
|
Dataset,
|
|
20
21
|
ImageMetaHandler,
|
|
21
22
|
LabelMetaHandler,
|
|
@@ -43,7 +44,7 @@ class AbstractImage(Generic[_image_handler]):
|
|
|
43
44
|
|
|
44
45
|
Args:
|
|
45
46
|
group_handler: The Zarr group handler.
|
|
46
|
-
path: The path to the image in the
|
|
47
|
+
path: The path to the image in the ome_zarr file.
|
|
47
48
|
meta_handler: The image metadata handler.
|
|
48
49
|
|
|
49
50
|
"""
|
|
@@ -63,7 +64,7 @@ class AbstractImage(Generic[_image_handler]):
|
|
|
63
64
|
shape=self._zarr_array.shape, axes_mapper=self._dataset.axes_mapper
|
|
64
65
|
)
|
|
65
66
|
|
|
66
|
-
self.
|
|
67
|
+
self._axes_mapper = self._dataset.axes_mapper
|
|
67
68
|
|
|
68
69
|
def __repr__(self) -> str:
|
|
69
70
|
"""Return a string representation of the image."""
|
|
@@ -99,6 +100,41 @@ class AbstractImage(Generic[_image_handler]):
|
|
|
99
100
|
"""Return the dimensions of the image."""
|
|
100
101
|
return self._dimensions
|
|
101
102
|
|
|
103
|
+
@property
|
|
104
|
+
def axes_mapper(self) -> AxesMapper:
|
|
105
|
+
"""Return the axes mapper of the image."""
|
|
106
|
+
return self._axes_mapper
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def is_3d(self) -> bool:
|
|
110
|
+
"""Return True if the image is 3D."""
|
|
111
|
+
return self.dimensions.is_3d
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def is_2d(self) -> bool:
|
|
115
|
+
"""Return True if the image is 2D."""
|
|
116
|
+
return self.dimensions.is_2d
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def is_time_series(self) -> bool:
|
|
120
|
+
"""Return True if the image is a time series."""
|
|
121
|
+
return self.dimensions.is_time_series
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def is_2d_time_series(self) -> bool:
|
|
125
|
+
"""Return True if the image is a 2D time series."""
|
|
126
|
+
return self.dimensions.is_2d_time_series
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def is_3d_time_series(self) -> bool:
|
|
130
|
+
"""Return True if the image is a 3D time series."""
|
|
131
|
+
return self.dimensions.is_3d_time_series
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def is_multi_channels(self) -> bool:
|
|
135
|
+
"""Return True if the image is multichannel."""
|
|
136
|
+
return self.dimensions.is_multi_channels
|
|
137
|
+
|
|
102
138
|
@property
|
|
103
139
|
def pixel_size(self) -> PixelSize:
|
|
104
140
|
"""Return the pixel size of the image."""
|
|
@@ -114,6 +150,10 @@ class AbstractImage(Generic[_image_handler]):
|
|
|
114
150
|
"""Return the path of the image."""
|
|
115
151
|
return self._dataset.path
|
|
116
152
|
|
|
153
|
+
def has_axis(self, axis: str) -> bool:
|
|
154
|
+
"""Return True if the image has the given axis."""
|
|
155
|
+
return self.dimensions.has_axis(axis)
|
|
156
|
+
|
|
117
157
|
def get_array(
|
|
118
158
|
self,
|
|
119
159
|
axes_order: Collection[str] | None = None,
|
|
@@ -140,7 +180,7 @@ class AbstractImage(Generic[_image_handler]):
|
|
|
140
180
|
|
|
141
181
|
def get_roi(
|
|
142
182
|
self,
|
|
143
|
-
roi:
|
|
183
|
+
roi: Roi,
|
|
144
184
|
axes_order: Collection[str] | None = None,
|
|
145
185
|
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
146
186
|
**slice_kwargs: slice | int | Iterable[int],
|
|
@@ -184,7 +224,7 @@ class AbstractImage(Generic[_image_handler]):
|
|
|
184
224
|
|
|
185
225
|
def set_roi(
|
|
186
226
|
self,
|
|
187
|
-
roi:
|
|
227
|
+
roi: Roi,
|
|
188
228
|
patch: ArrayLike,
|
|
189
229
|
axes_order: Collection[str] | None = None,
|
|
190
230
|
**slice_kwargs: slice | int | Iterable[int],
|
|
@@ -226,7 +266,7 @@ def consolidate_image(
|
|
|
226
266
|
|
|
227
267
|
def get_roi_pipe(
|
|
228
268
|
image: AbstractImage,
|
|
229
|
-
roi:
|
|
269
|
+
roi: Roi,
|
|
230
270
|
axes_order: Collection[str] | None = None,
|
|
231
271
|
mode: Literal["numpy", "dask", "delayed"] = "numpy",
|
|
232
272
|
**slice_kwargs: slice | int | Iterable[int],
|
|
@@ -260,7 +300,7 @@ def get_roi_pipe(
|
|
|
260
300
|
|
|
261
301
|
def set_roi_pipe(
|
|
262
302
|
image: AbstractImage,
|
|
263
|
-
roi:
|
|
303
|
+
roi: Roi,
|
|
264
304
|
patch: ArrayLike,
|
|
265
305
|
axes_order: Collection[str] | None = None,
|
|
266
306
|
**slice_kwargs: slice | int | Iterable[int],
|
|
@@ -297,7 +337,7 @@ def build_image_roi_table(image: AbstractImage, name: str = "image") -> RoiTable
|
|
|
297
337
|
image.dimensions.get("y"),
|
|
298
338
|
image.dimensions.get("x"),
|
|
299
339
|
)
|
|
300
|
-
image_roi =
|
|
340
|
+
image_roi = RoiPixels(
|
|
301
341
|
name=name,
|
|
302
342
|
x=0,
|
|
303
343
|
y=0,
|
|
@@ -306,4 +346,4 @@ def build_image_roi_table(image: AbstractImage, name: str = "image") -> RoiTable
|
|
|
306
346
|
y_length=dim_y,
|
|
307
347
|
z_length=dim_z,
|
|
308
348
|
)
|
|
309
|
-
return RoiTable(rois=[image_roi.
|
|
349
|
+
return RoiTable(rois=[image_roi.to_roi(pixel_size=image.pixel_size)])
|
ngio/images/create.py
CHANGED
|
@@ -12,6 +12,7 @@ from ngio.ome_zarr_meta import (
|
|
|
12
12
|
get_label_meta_handler,
|
|
13
13
|
)
|
|
14
14
|
from ngio.ome_zarr_meta.ngio_specs import (
|
|
15
|
+
NgffVersion,
|
|
15
16
|
SpaceUnits,
|
|
16
17
|
TimeUnits,
|
|
17
18
|
canonical_axes_order,
|
|
@@ -34,7 +35,7 @@ def _init_generic_meta(
|
|
|
34
35
|
space_unit: SpaceUnits | str | None = None,
|
|
35
36
|
time_unit: TimeUnits | str | None = None,
|
|
36
37
|
name: str | None = None,
|
|
37
|
-
version:
|
|
38
|
+
version: NgffVersion = "0.4",
|
|
38
39
|
) -> tuple[_image_or_label_meta, list[float]]:
|
|
39
40
|
"""Initialize the metadata for an image or label."""
|
|
40
41
|
scaling_factors = []
|
|
@@ -104,7 +105,7 @@ def _create_empty_label(
|
|
|
104
105
|
chunks: Collection[int] | None = None,
|
|
105
106
|
dtype: str = "uint16",
|
|
106
107
|
overwrite: bool = False,
|
|
107
|
-
version:
|
|
108
|
+
version: NgffVersion = "0.4",
|
|
108
109
|
) -> ZarrGroupHandler:
|
|
109
110
|
"""Create an empty label with the given shape and metadata.
|
|
110
111
|
|
|
@@ -195,7 +196,7 @@ def _create_empty_image(
|
|
|
195
196
|
chunks: Collection[int] | None = None,
|
|
196
197
|
dtype: str = "uint16",
|
|
197
198
|
overwrite: bool = False,
|
|
198
|
-
version:
|
|
199
|
+
version: NgffVersion = "0.4",
|
|
199
200
|
) -> ZarrGroupHandler:
|
|
200
201
|
"""Create an empty OME-Zarr image with the given shape and metadata.
|
|
201
202
|
|
ngio/images/image.py
CHANGED
|
@@ -55,7 +55,7 @@ class Image(AbstractImage[ImageMetaHandler]):
|
|
|
55
55
|
|
|
56
56
|
Args:
|
|
57
57
|
group_handler: The Zarr group handler.
|
|
58
|
-
path: The path to the image in the
|
|
58
|
+
path: The path to the image in the ome_zarr file.
|
|
59
59
|
meta_handler: The image metadata handler.
|
|
60
60
|
|
|
61
61
|
"""
|
|
@@ -281,7 +281,7 @@ class ImagesContainer:
|
|
|
281
281
|
"""Get an image at a specific level.
|
|
282
282
|
|
|
283
283
|
Args:
|
|
284
|
-
path (str | None): The path to the image in the
|
|
284
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
285
285
|
pixel_size (PixelSize | None): The pixel size of the image.
|
|
286
286
|
strict (bool): Only used if the pixel size is provided. If True, the
|
|
287
287
|
pixel size must match the image pixel size exactly. If False, the
|