ngio 0.2.0a2__py3-none-any.whl → 0.5.0b4__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 +40 -12
- ngio/common/__init__.py +16 -32
- ngio/common/_dimensions.py +270 -48
- ngio/common/_masking_roi.py +153 -0
- ngio/common/_pyramid.py +267 -73
- ngio/common/_roi.py +290 -66
- ngio/common/_synt_images_utils.py +101 -0
- ngio/common/_zoom.py +54 -22
- ngio/experimental/__init__.py +5 -0
- ngio/experimental/iterators/__init__.py +15 -0
- ngio/experimental/iterators/_abstract_iterator.py +390 -0
- ngio/experimental/iterators/_feature.py +189 -0
- ngio/experimental/iterators/_image_processing.py +130 -0
- ngio/experimental/iterators/_mappers.py +48 -0
- ngio/experimental/iterators/_rois_utils.py +126 -0
- ngio/experimental/iterators/_segmentation.py +235 -0
- ngio/hcs/__init__.py +17 -58
- ngio/hcs/_plate.py +1354 -0
- ngio/images/__init__.py +30 -9
- ngio/images/_abstract_image.py +968 -0
- ngio/images/_create_synt_container.py +132 -0
- ngio/images/_create_utils.py +423 -0
- ngio/images/_image.py +926 -0
- ngio/images/_label.py +417 -0
- ngio/images/_masked_image.py +531 -0
- ngio/images/_ome_zarr_container.py +1235 -0
- ngio/images/_table_ops.py +471 -0
- ngio/io_pipes/__init__.py +75 -0
- ngio/io_pipes/_io_pipes.py +361 -0
- ngio/io_pipes/_io_pipes_masked.py +488 -0
- ngio/io_pipes/_io_pipes_roi.py +146 -0
- ngio/io_pipes/_io_pipes_types.py +56 -0
- ngio/io_pipes/_match_shape.py +377 -0
- ngio/io_pipes/_ops_axes.py +344 -0
- ngio/io_pipes/_ops_slices.py +411 -0
- ngio/io_pipes/_ops_slices_utils.py +199 -0
- ngio/io_pipes/_ops_transforms.py +104 -0
- ngio/io_pipes/_zoom_transform.py +180 -0
- ngio/ome_zarr_meta/__init__.py +39 -15
- ngio/ome_zarr_meta/_meta_handlers.py +490 -96
- ngio/ome_zarr_meta/ngio_specs/__init__.py +24 -10
- ngio/ome_zarr_meta/ngio_specs/_axes.py +268 -234
- ngio/ome_zarr_meta/ngio_specs/_channels.py +125 -41
- ngio/ome_zarr_meta/ngio_specs/_dataset.py +42 -87
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +536 -2
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +202 -198
- ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +72 -34
- ngio/ome_zarr_meta/v04/__init__.py +21 -5
- ngio/ome_zarr_meta/v04/_custom_models.py +18 -0
- ngio/ome_zarr_meta/v04/{_v04_spec_utils.py → _v04_spec.py} +151 -90
- ngio/ome_zarr_meta/v05/__init__.py +27 -0
- ngio/ome_zarr_meta/v05/_custom_models.py +18 -0
- ngio/ome_zarr_meta/v05/_v05_spec.py +511 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
- ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
- ngio/resources/__init__.py +55 -0
- ngio/resources/resource_model.py +36 -0
- ngio/tables/__init__.py +20 -4
- ngio/tables/_abstract_table.py +270 -0
- ngio/tables/_tables_container.py +449 -0
- ngio/tables/backends/__init__.py +50 -1
- ngio/tables/backends/_abstract_backend.py +200 -31
- ngio/tables/backends/_anndata.py +139 -0
- ngio/tables/backends/_anndata_utils.py +10 -114
- ngio/tables/backends/_csv.py +19 -0
- ngio/tables/backends/_json.py +92 -0
- ngio/tables/backends/_parquet.py +19 -0
- ngio/tables/backends/_py_arrow_backends.py +222 -0
- ngio/tables/backends/_table_backends.py +162 -38
- ngio/tables/backends/_utils.py +608 -0
- ngio/tables/v1/__init__.py +19 -4
- ngio/tables/v1/_condition_table.py +71 -0
- ngio/tables/v1/_feature_table.py +79 -115
- ngio/tables/v1/_generic_table.py +21 -90
- ngio/tables/v1/_roi_table.py +486 -137
- ngio/transforms/__init__.py +5 -0
- ngio/transforms/_zoom.py +19 -0
- ngio/utils/__init__.py +16 -14
- ngio/utils/_cache.py +48 -0
- ngio/utils/_datasets.py +121 -13
- ngio/utils/_fractal_fsspec_store.py +42 -0
- ngio/utils/_zarr_utils.py +374 -218
- ngio-0.5.0b4.dist-info/METADATA +147 -0
- ngio-0.5.0b4.dist-info/RECORD +88 -0
- {ngio-0.2.0a2.dist-info → ngio-0.5.0b4.dist-info}/WHEEL +1 -1
- ngio/common/_array_pipe.py +0 -160
- ngio/common/_axes_transforms.py +0 -63
- ngio/common/_common_types.py +0 -5
- ngio/common/_slicer.py +0 -97
- ngio/images/abstract_image.py +0 -240
- ngio/images/create.py +0 -251
- ngio/images/image.py +0 -389
- ngio/images/label.py +0 -236
- ngio/images/omezarr_container.py +0 -535
- ngio/ome_zarr_meta/_generic_handlers.py +0 -320
- ngio/ome_zarr_meta/v04/_meta_handlers.py +0 -54
- ngio/tables/_validators.py +0 -192
- ngio/tables/backends/_anndata_v1.py +0 -75
- ngio/tables/backends/_json_v1.py +0 -56
- ngio/tables/tables_container.py +0 -300
- ngio/tables/v1/_masking_roi_table.py +0 -175
- ngio/utils/_logger.py +0 -29
- ngio-0.2.0a2.dist-info/METADATA +0 -95
- ngio-0.2.0a2.dist-info/RECORD +0 -53
- {ngio-0.2.0a2.dist-info → ngio-0.5.0b4.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,1235 @@
|
|
|
1
|
+
"""Abstract class for handling OME-NGFF images."""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
from collections.abc import Mapping, Sequence
|
|
5
|
+
from typing import Any, Literal
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from zarr.core.array import CompressorLike
|
|
9
|
+
|
|
10
|
+
from ngio.common._pyramid import ChunksLike, ShardsLike
|
|
11
|
+
from ngio.images._create_utils import init_image_like
|
|
12
|
+
from ngio.images._image import Image, ImagesContainer
|
|
13
|
+
from ngio.images._label import Label, LabelsContainer
|
|
14
|
+
from ngio.images._masked_image import MaskedImage, MaskedLabel
|
|
15
|
+
from ngio.ome_zarr_meta import (
|
|
16
|
+
LabelMetaHandler,
|
|
17
|
+
NgioImageMeta,
|
|
18
|
+
PixelSize,
|
|
19
|
+
)
|
|
20
|
+
from ngio.ome_zarr_meta.ngio_specs import (
|
|
21
|
+
Channel,
|
|
22
|
+
DefaultNgffVersion,
|
|
23
|
+
DefaultSpaceUnit,
|
|
24
|
+
DefaultTimeUnit,
|
|
25
|
+
NgffVersions,
|
|
26
|
+
SpaceUnits,
|
|
27
|
+
TimeUnits,
|
|
28
|
+
)
|
|
29
|
+
from ngio.tables import (
|
|
30
|
+
ConditionTable,
|
|
31
|
+
DefaultTableBackend,
|
|
32
|
+
FeatureTable,
|
|
33
|
+
GenericRoiTable,
|
|
34
|
+
MaskingRoiTable,
|
|
35
|
+
RoiTable,
|
|
36
|
+
Table,
|
|
37
|
+
TableBackend,
|
|
38
|
+
TablesContainer,
|
|
39
|
+
TableType,
|
|
40
|
+
TypedTable,
|
|
41
|
+
)
|
|
42
|
+
from ngio.utils import (
|
|
43
|
+
AccessModeLiteral,
|
|
44
|
+
NgioError,
|
|
45
|
+
NgioValidationError,
|
|
46
|
+
NgioValueError,
|
|
47
|
+
StoreOrGroup,
|
|
48
|
+
ZarrGroupHandler,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _try_get_table_container(
|
|
53
|
+
handler: ZarrGroupHandler, create_mode: bool = True
|
|
54
|
+
) -> TablesContainer | None:
|
|
55
|
+
"""Return a default table container."""
|
|
56
|
+
try:
|
|
57
|
+
table_handler = handler.get_handler("tables", create_mode=create_mode)
|
|
58
|
+
return TablesContainer(table_handler)
|
|
59
|
+
except NgioError:
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _try_get_label_container(
|
|
64
|
+
handler: ZarrGroupHandler, ngff_version: NgffVersions, create_mode: bool = True
|
|
65
|
+
) -> LabelsContainer | None:
|
|
66
|
+
"""Return a default label container."""
|
|
67
|
+
try:
|
|
68
|
+
label_handler = handler.get_handler("labels", create_mode=create_mode)
|
|
69
|
+
return LabelsContainer(label_handler, ngff_version=ngff_version)
|
|
70
|
+
except FileNotFoundError:
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class OmeZarrContainer:
|
|
75
|
+
"""This class is an object representation of an OME-Zarr image.
|
|
76
|
+
|
|
77
|
+
It provides methods to access:
|
|
78
|
+
- The multiscale image metadata
|
|
79
|
+
- To open images at different levels of resolution
|
|
80
|
+
- To access labels and tables associated with the image.
|
|
81
|
+
- To derive new images, labels, and add tables to the image.
|
|
82
|
+
- To modify the image metadata, such as axes units and channel metadata.
|
|
83
|
+
|
|
84
|
+
Attributes:
|
|
85
|
+
images_container (ImagesContainer): The container for the images.
|
|
86
|
+
labels_container (LabelsContainer): The container for the labels.
|
|
87
|
+
tables_container (TablesContainer): The container for the tables.
|
|
88
|
+
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
_images_container: ImagesContainer
|
|
92
|
+
_labels_container: LabelsContainer | None
|
|
93
|
+
_tables_container: TablesContainer | None
|
|
94
|
+
|
|
95
|
+
def __init__(
|
|
96
|
+
self,
|
|
97
|
+
group_handler: ZarrGroupHandler,
|
|
98
|
+
table_container: TablesContainer | None = None,
|
|
99
|
+
label_container: LabelsContainer | None = None,
|
|
100
|
+
validate_paths: bool = False,
|
|
101
|
+
) -> None:
|
|
102
|
+
"""Initialize the OmeZarrContainer.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
group_handler (ZarrGroupHandler): The Zarr group handler.
|
|
106
|
+
table_container (TablesContainer | None): The tables container.
|
|
107
|
+
label_container (LabelsContainer | None): The labels container.
|
|
108
|
+
validate_paths (bool): Whether to validate the paths of the image multiscale
|
|
109
|
+
"""
|
|
110
|
+
self._group_handler = group_handler
|
|
111
|
+
self._images_container = ImagesContainer(self._group_handler)
|
|
112
|
+
|
|
113
|
+
self._labels_container = label_container
|
|
114
|
+
self._tables_container = table_container
|
|
115
|
+
|
|
116
|
+
if validate_paths:
|
|
117
|
+
for level_path in self._images_container.levels_paths:
|
|
118
|
+
self.get_image(path=level_path)
|
|
119
|
+
|
|
120
|
+
def __repr__(self) -> str:
|
|
121
|
+
"""Return a string representation of the image."""
|
|
122
|
+
num_labels = len(self.list_labels())
|
|
123
|
+
num_tables = len(self.list_tables())
|
|
124
|
+
|
|
125
|
+
base_str = f"OmeZarrContainer(levels={self.levels}"
|
|
126
|
+
if num_labels > 0 and num_labels < 3:
|
|
127
|
+
base_str += f", labels={self.list_labels()}"
|
|
128
|
+
elif num_labels >= 3:
|
|
129
|
+
base_str += f", #labels={num_labels}"
|
|
130
|
+
if num_tables > 0 and num_tables < 3:
|
|
131
|
+
base_str += f", tables={self.list_tables()}"
|
|
132
|
+
elif num_tables >= 3:
|
|
133
|
+
base_str += f", #tables={num_tables}"
|
|
134
|
+
base_str += ")"
|
|
135
|
+
return base_str
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def images_container(self) -> ImagesContainer:
|
|
139
|
+
"""Return the images container.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
ImagesContainer: The images container.
|
|
143
|
+
"""
|
|
144
|
+
return self._images_container
|
|
145
|
+
|
|
146
|
+
def _get_labels_container(self, create_mode: bool = True) -> LabelsContainer | None:
|
|
147
|
+
"""Return the labels container."""
|
|
148
|
+
if self._labels_container is not None:
|
|
149
|
+
return self._labels_container
|
|
150
|
+
|
|
151
|
+
_labels_container = _try_get_label_container(
|
|
152
|
+
self._group_handler,
|
|
153
|
+
create_mode=create_mode,
|
|
154
|
+
ngff_version=self.image_meta.version,
|
|
155
|
+
)
|
|
156
|
+
self._labels_container = _labels_container
|
|
157
|
+
return self._labels_container
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def labels_container(self) -> LabelsContainer:
|
|
161
|
+
"""Return the labels container."""
|
|
162
|
+
_labels_container = self._get_labels_container()
|
|
163
|
+
if _labels_container is None:
|
|
164
|
+
raise NgioValidationError("No labels found in the image.")
|
|
165
|
+
return _labels_container
|
|
166
|
+
|
|
167
|
+
def _get_tables_container(self, create_mode: bool = True) -> TablesContainer | None:
|
|
168
|
+
"""Return the tables container."""
|
|
169
|
+
if self._tables_container is not None:
|
|
170
|
+
return self._tables_container
|
|
171
|
+
|
|
172
|
+
_tables_container = _try_get_table_container(
|
|
173
|
+
self._group_handler, create_mode=create_mode
|
|
174
|
+
)
|
|
175
|
+
self._tables_container = _tables_container
|
|
176
|
+
return self._tables_container
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
def tables_container(self) -> TablesContainer:
|
|
180
|
+
"""Return the tables container."""
|
|
181
|
+
_tables_container = self._get_tables_container()
|
|
182
|
+
if _tables_container is None:
|
|
183
|
+
raise NgioValidationError("No tables found in the image.")
|
|
184
|
+
return _tables_container
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def image_meta(self) -> NgioImageMeta:
|
|
188
|
+
"""Return the image metadata."""
|
|
189
|
+
return self._images_container.meta
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def levels(self) -> int:
|
|
193
|
+
"""Return the number of levels in the image."""
|
|
194
|
+
return self._images_container.levels
|
|
195
|
+
|
|
196
|
+
@property
|
|
197
|
+
def levels_paths(self) -> list[str]:
|
|
198
|
+
"""Return the paths of the levels in the image."""
|
|
199
|
+
return self._images_container.levels_paths
|
|
200
|
+
|
|
201
|
+
@property
|
|
202
|
+
def is_3d(self) -> bool:
|
|
203
|
+
"""Return True if the image is 3D."""
|
|
204
|
+
return self.get_image().is_3d
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def is_2d(self) -> bool:
|
|
208
|
+
"""Return True if the image is 2D."""
|
|
209
|
+
return self.get_image().is_2d
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def is_time_series(self) -> bool:
|
|
213
|
+
"""Return True if the image is a time series."""
|
|
214
|
+
return self.get_image().is_time_series
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def is_2d_time_series(self) -> bool:
|
|
218
|
+
"""Return True if the image is a 2D time series."""
|
|
219
|
+
return self.get_image().is_2d_time_series
|
|
220
|
+
|
|
221
|
+
@property
|
|
222
|
+
def is_3d_time_series(self) -> bool:
|
|
223
|
+
"""Return True if the image is a 3D time series."""
|
|
224
|
+
return self.get_image().is_3d_time_series
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def is_multi_channels(self) -> bool:
|
|
228
|
+
"""Return True if the image is multichannel."""
|
|
229
|
+
return self.get_image().is_multi_channels
|
|
230
|
+
|
|
231
|
+
@property
|
|
232
|
+
def space_unit(self) -> str | None:
|
|
233
|
+
"""Return the space unit of the image."""
|
|
234
|
+
return self.image_meta.space_unit
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def time_unit(self) -> str | None:
|
|
238
|
+
"""Return the time unit of the image."""
|
|
239
|
+
return self.image_meta.time_unit
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def channel_labels(self) -> list[str]:
|
|
243
|
+
"""Return the channels of the image."""
|
|
244
|
+
image = self.get_image()
|
|
245
|
+
return image.channel_labels
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def wavelength_ids(self) -> list[str | None]:
|
|
249
|
+
"""Return the list of wavelength of the image."""
|
|
250
|
+
image = self.get_image()
|
|
251
|
+
return image.wavelength_ids
|
|
252
|
+
|
|
253
|
+
@property
|
|
254
|
+
def num_channels(self) -> int:
|
|
255
|
+
"""Return the number of channels."""
|
|
256
|
+
return len(self.channel_labels)
|
|
257
|
+
|
|
258
|
+
def get_channel_idx(
|
|
259
|
+
self, channel_label: str | None = None, wavelength_id: str | None = None
|
|
260
|
+
) -> int:
|
|
261
|
+
"""Get the index of a channel by its label or wavelength ID."""
|
|
262
|
+
image = self.get_image()
|
|
263
|
+
return image.channels_meta.get_channel_idx(
|
|
264
|
+
channel_label=channel_label, wavelength_id=wavelength_id
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def set_channel_meta(
|
|
268
|
+
self,
|
|
269
|
+
labels: Sequence[str] | int | None = None,
|
|
270
|
+
wavelength_id: Sequence[str] | None = None,
|
|
271
|
+
percentiles: tuple[float, float] | None = None,
|
|
272
|
+
colors: Sequence[str] | None = None,
|
|
273
|
+
active: Sequence[bool] | None = None,
|
|
274
|
+
**omero_kwargs: dict,
|
|
275
|
+
) -> None:
|
|
276
|
+
"""Create a ChannelsMeta object with the default unit."""
|
|
277
|
+
self._images_container.set_channel_meta(
|
|
278
|
+
labels=labels,
|
|
279
|
+
wavelength_id=wavelength_id,
|
|
280
|
+
start=None,
|
|
281
|
+
end=None,
|
|
282
|
+
percentiles=percentiles,
|
|
283
|
+
colors=colors,
|
|
284
|
+
active=active,
|
|
285
|
+
**omero_kwargs,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
def set_channel_percentiles(
|
|
289
|
+
self,
|
|
290
|
+
start_percentile: float = 0.1,
|
|
291
|
+
end_percentile: float = 99.9,
|
|
292
|
+
) -> None:
|
|
293
|
+
"""Update the percentiles of the image."""
|
|
294
|
+
self._images_container.set_channel_percentiles(
|
|
295
|
+
start_percentile=start_percentile, end_percentile=end_percentile
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
def set_axes_units(
|
|
299
|
+
self,
|
|
300
|
+
space_unit: SpaceUnits = DefaultSpaceUnit,
|
|
301
|
+
time_unit: TimeUnits = DefaultTimeUnit,
|
|
302
|
+
set_labels: bool = True,
|
|
303
|
+
) -> None:
|
|
304
|
+
"""Set the units of the image.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
space_unit (SpaceUnits): The unit of space.
|
|
308
|
+
time_unit (TimeUnits): The unit of time.
|
|
309
|
+
set_labels (bool): Whether to set the units for the labels as well.
|
|
310
|
+
"""
|
|
311
|
+
self._images_container.set_axes_unit(space_unit=space_unit, time_unit=time_unit)
|
|
312
|
+
if not set_labels:
|
|
313
|
+
return
|
|
314
|
+
for label_name in self.list_labels():
|
|
315
|
+
label = self.get_label(label_name)
|
|
316
|
+
label.set_axes_unit(space_unit=space_unit, time_unit=time_unit)
|
|
317
|
+
|
|
318
|
+
def get_image(
|
|
319
|
+
self,
|
|
320
|
+
path: str | None = None,
|
|
321
|
+
pixel_size: PixelSize | None = None,
|
|
322
|
+
strict: bool = False,
|
|
323
|
+
) -> Image:
|
|
324
|
+
"""Get an image at a specific level.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
328
|
+
pixel_size (PixelSize | None): The pixel size of the image.
|
|
329
|
+
strict (bool): Only used if the pixel size is provided. If True, the
|
|
330
|
+
pixel size must match the image pixel size exactly. If False, the
|
|
331
|
+
closest pixel size level will be returned.
|
|
332
|
+
|
|
333
|
+
"""
|
|
334
|
+
return self._images_container.get(
|
|
335
|
+
path=path, pixel_size=pixel_size, strict=strict
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
def _find_matching_masking_label(
|
|
339
|
+
self,
|
|
340
|
+
masking_label_name: str | None = None,
|
|
341
|
+
masking_table_name: str | None = None,
|
|
342
|
+
pixel_size: PixelSize | None = None,
|
|
343
|
+
) -> tuple[Label, MaskingRoiTable]:
|
|
344
|
+
if masking_label_name is not None and masking_table_name is not None:
|
|
345
|
+
# Both provided
|
|
346
|
+
masking_label = self.get_label(
|
|
347
|
+
name=masking_label_name, pixel_size=pixel_size, strict=False
|
|
348
|
+
)
|
|
349
|
+
masking_table = self.get_masking_roi_table(name=masking_table_name)
|
|
350
|
+
|
|
351
|
+
elif masking_label_name is not None and masking_table_name is None:
|
|
352
|
+
# Only the label provided
|
|
353
|
+
masking_label = self.get_label(
|
|
354
|
+
name=masking_label_name, pixel_size=pixel_size, strict=False
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
for table_name in self.list_roi_tables():
|
|
358
|
+
table = self.get_generic_roi_table(name=table_name)
|
|
359
|
+
if isinstance(table, MaskingRoiTable):
|
|
360
|
+
if table.reference_label == masking_label_name:
|
|
361
|
+
masking_table = table
|
|
362
|
+
break
|
|
363
|
+
else:
|
|
364
|
+
masking_table = masking_label.build_masking_roi_table()
|
|
365
|
+
|
|
366
|
+
elif masking_table_name is not None and masking_label_name is None:
|
|
367
|
+
# Only the table provided
|
|
368
|
+
masking_table = self.get_masking_roi_table(name=masking_table_name)
|
|
369
|
+
|
|
370
|
+
if masking_table.reference_label is None:
|
|
371
|
+
raise NgioValueError(
|
|
372
|
+
f"Masking table {masking_table_name} does not have a reference "
|
|
373
|
+
"label. Please provide the masking_label_name explicitly."
|
|
374
|
+
)
|
|
375
|
+
masking_label = self.get_label(
|
|
376
|
+
name=masking_table.reference_label,
|
|
377
|
+
pixel_size=pixel_size,
|
|
378
|
+
strict=False,
|
|
379
|
+
)
|
|
380
|
+
else:
|
|
381
|
+
raise NgioValueError(
|
|
382
|
+
"Neither masking_label_name nor masking_table_name were provided."
|
|
383
|
+
)
|
|
384
|
+
return masking_label, masking_table
|
|
385
|
+
|
|
386
|
+
def get_masked_image(
|
|
387
|
+
self,
|
|
388
|
+
masking_label_name: str | None = None,
|
|
389
|
+
masking_table_name: str | None = None,
|
|
390
|
+
path: str | None = None,
|
|
391
|
+
pixel_size: PixelSize | None = None,
|
|
392
|
+
strict: bool = False,
|
|
393
|
+
) -> MaskedImage:
|
|
394
|
+
"""Get a masked image at a specific level.
|
|
395
|
+
|
|
396
|
+
Args:
|
|
397
|
+
masking_label_name (str | None): The name of the masking label to use.
|
|
398
|
+
If None, the masking table must be provided.
|
|
399
|
+
masking_table_name (str | None): The name of the masking table to use.
|
|
400
|
+
If None, the masking label must be provided.
|
|
401
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
402
|
+
If None, the first level will be used.
|
|
403
|
+
pixel_size (PixelSize | None): The pixel size of the image.
|
|
404
|
+
This is only used if path is None.
|
|
405
|
+
strict (bool): Only used if the pixel size is provided. If True, the
|
|
406
|
+
pixel size must match the image pixel size exactly. If False, the
|
|
407
|
+
closest pixel size level will be returned.
|
|
408
|
+
"""
|
|
409
|
+
image = self.get_image(path=path, pixel_size=pixel_size, strict=strict)
|
|
410
|
+
masking_label, masking_table = self._find_matching_masking_label(
|
|
411
|
+
masking_label_name=masking_label_name,
|
|
412
|
+
masking_table_name=masking_table_name,
|
|
413
|
+
pixel_size=pixel_size,
|
|
414
|
+
)
|
|
415
|
+
return MaskedImage(
|
|
416
|
+
group_handler=image._group_handler,
|
|
417
|
+
path=image.path,
|
|
418
|
+
meta_handler=image.meta_handler,
|
|
419
|
+
label=masking_label,
|
|
420
|
+
masking_roi_table=masking_table,
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
def derive_image(
|
|
424
|
+
self,
|
|
425
|
+
store: StoreOrGroup,
|
|
426
|
+
ref_path: str | None = None,
|
|
427
|
+
# Metadata parameters
|
|
428
|
+
shape: Sequence[int] | None = None,
|
|
429
|
+
pixelsize: float | tuple[float, float] | None = None,
|
|
430
|
+
z_spacing: float | None = None,
|
|
431
|
+
time_spacing: float | None = None,
|
|
432
|
+
name: str | None = None,
|
|
433
|
+
channels_policy: Literal["squeeze", "same", "singleton"] | int = "same",
|
|
434
|
+
channels_meta: Sequence[str | Channel] | None = None,
|
|
435
|
+
ngff_version: NgffVersions | None = None,
|
|
436
|
+
# Zarr Array parameters
|
|
437
|
+
chunks: ChunksLike | None = None,
|
|
438
|
+
shards: ShardsLike | None = None,
|
|
439
|
+
dtype: str = "uint16",
|
|
440
|
+
dimension_separator: Literal[".", "/"] = "/",
|
|
441
|
+
compressors: CompressorLike = "auto",
|
|
442
|
+
extra_array_kwargs: Mapping[str, Any] | None = None,
|
|
443
|
+
overwrite: bool = False,
|
|
444
|
+
# Copy from current image
|
|
445
|
+
copy_labels: bool = False,
|
|
446
|
+
copy_tables: bool = False,
|
|
447
|
+
# Deprecated arguments
|
|
448
|
+
labels: Sequence[str] | None = None,
|
|
449
|
+
pixel_size: PixelSize | None = None,
|
|
450
|
+
) -> "OmeZarrContainer":
|
|
451
|
+
"""Derive a new OME-Zarr container from the current image.
|
|
452
|
+
|
|
453
|
+
If a kwarg is not provided, the value from the reference image will be used.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
457
|
+
ref_path (str | None): The path to the reference image in the image
|
|
458
|
+
container.
|
|
459
|
+
shape (Sequence[int] | None): The shape of the new image.
|
|
460
|
+
pixelsize (float | tuple[float, float] | None): The pixel size of the new
|
|
461
|
+
image.
|
|
462
|
+
z_spacing (float | None): The z spacing of the new image.
|
|
463
|
+
time_spacing (float | None): The time spacing of the new image.
|
|
464
|
+
name (str | None): The name of the new image.
|
|
465
|
+
channels_policy (Literal["squeeze", "same"] | int): Possible policies:
|
|
466
|
+
- If "squeeze", the channels axis will be removed (no matter its size).
|
|
467
|
+
- If "same", the channels axis will be kept as is (if it exists).
|
|
468
|
+
- If "singleton", the channels axis will be set to size 1.
|
|
469
|
+
- If an integer is provided, the channels axis will be changed to have
|
|
470
|
+
that size.
|
|
471
|
+
channels_meta (Sequence[str | Channel] | None): The channels metadata
|
|
472
|
+
of the new image.
|
|
473
|
+
ngff_version (NgffVersions | None): The NGFF version to use.
|
|
474
|
+
chunks (ChunksLike | None): The chunk shape of the new image.
|
|
475
|
+
shards (ShardsLike | None): The shard shape of the new image.
|
|
476
|
+
dtype (str): The data type of the new image. Defaults to "uint16".
|
|
477
|
+
dimension_separator (Literal[".", "/"]): The separator to use for
|
|
478
|
+
dimensions. Defaults to "/".
|
|
479
|
+
compressors (CompressorLike): The compressors to use. Defaults to "auto".
|
|
480
|
+
extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
|
|
481
|
+
the zarr array creation.
|
|
482
|
+
overwrite (bool): Whether to overwrite an existing image. Defaults to False.
|
|
483
|
+
copy_labels (bool): Whether to copy the labels from the current image.
|
|
484
|
+
Defaults to False.
|
|
485
|
+
copy_tables (bool): Whether to copy the tables from the current image.
|
|
486
|
+
Defaults to False.
|
|
487
|
+
labels (Sequence[str] | None): Deprecated. This argument is deprecated,
|
|
488
|
+
please use channels_meta instead.
|
|
489
|
+
pixel_size (PixelSize | None): Deprecated. The pixel size of the new image.
|
|
490
|
+
This argument is deprecated, please use pixelsize, z_spacing,
|
|
491
|
+
and time_spacing instead.
|
|
492
|
+
|
|
493
|
+
Returns:
|
|
494
|
+
OmeZarrContainer: The new derived OME-Zarr container.
|
|
495
|
+
|
|
496
|
+
"""
|
|
497
|
+
new_container = self._images_container.derive(
|
|
498
|
+
store=store,
|
|
499
|
+
ref_path=ref_path,
|
|
500
|
+
shape=shape,
|
|
501
|
+
pixelsize=pixelsize,
|
|
502
|
+
z_spacing=z_spacing,
|
|
503
|
+
time_spacing=time_spacing,
|
|
504
|
+
name=name,
|
|
505
|
+
channels_meta=channels_meta,
|
|
506
|
+
channels_policy=channels_policy,
|
|
507
|
+
ngff_version=ngff_version,
|
|
508
|
+
chunks=chunks,
|
|
509
|
+
shards=shards,
|
|
510
|
+
dtype=dtype,
|
|
511
|
+
dimension_separator=dimension_separator,
|
|
512
|
+
compressors=compressors,
|
|
513
|
+
extra_array_kwargs=extra_array_kwargs,
|
|
514
|
+
overwrite=overwrite,
|
|
515
|
+
labels=labels,
|
|
516
|
+
pixel_size=pixel_size,
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
new_ome_zarr = OmeZarrContainer(
|
|
520
|
+
group_handler=new_container._group_handler,
|
|
521
|
+
validate_paths=False,
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
if copy_labels:
|
|
525
|
+
self.labels_container._group_handler.copy_group(
|
|
526
|
+
new_ome_zarr.labels_container._group_handler.group
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
if copy_tables:
|
|
530
|
+
self.tables_container._group_handler.copy_group(
|
|
531
|
+
new_ome_zarr.tables_container._group_handler.group
|
|
532
|
+
)
|
|
533
|
+
return new_ome_zarr
|
|
534
|
+
|
|
535
|
+
def list_tables(self, filter_types: TypedTable | str | None = None) -> list[str]:
|
|
536
|
+
"""List all tables in the image."""
|
|
537
|
+
table_container = self._get_tables_container(create_mode=False)
|
|
538
|
+
if table_container is None:
|
|
539
|
+
return []
|
|
540
|
+
|
|
541
|
+
return table_container.list(
|
|
542
|
+
filter_types=filter_types,
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
def list_roi_tables(self) -> list[str]:
|
|
546
|
+
"""List all ROI tables in the image."""
|
|
547
|
+
masking_roi = self.tables_container.list(
|
|
548
|
+
filter_types="masking_roi_table",
|
|
549
|
+
)
|
|
550
|
+
roi = self.tables_container.list(
|
|
551
|
+
filter_types="roi_table",
|
|
552
|
+
)
|
|
553
|
+
return masking_roi + roi
|
|
554
|
+
|
|
555
|
+
def get_roi_table(self, name: str) -> RoiTable:
|
|
556
|
+
"""Get a ROI table from the image.
|
|
557
|
+
|
|
558
|
+
Args:
|
|
559
|
+
name (str): The name of the table.
|
|
560
|
+
"""
|
|
561
|
+
table = self.tables_container.get(name=name, strict=True)
|
|
562
|
+
if not isinstance(table, RoiTable):
|
|
563
|
+
raise NgioValueError(f"Table {name} is not a ROI table. Got {type(table)}")
|
|
564
|
+
return table
|
|
565
|
+
|
|
566
|
+
def get_masking_roi_table(self, name: str) -> MaskingRoiTable:
|
|
567
|
+
"""Get a masking ROI table from the image.
|
|
568
|
+
|
|
569
|
+
Args:
|
|
570
|
+
name (str): The name of the table.
|
|
571
|
+
"""
|
|
572
|
+
table = self.tables_container.get(name=name, strict=True)
|
|
573
|
+
if not isinstance(table, MaskingRoiTable):
|
|
574
|
+
raise NgioValueError(
|
|
575
|
+
f"Table {name} is not a masking ROI table. Got {type(table)}"
|
|
576
|
+
)
|
|
577
|
+
return table
|
|
578
|
+
|
|
579
|
+
def get_feature_table(self, name: str) -> FeatureTable:
|
|
580
|
+
"""Get a feature table from the image.
|
|
581
|
+
|
|
582
|
+
Args:
|
|
583
|
+
name (str): The name of the table.
|
|
584
|
+
"""
|
|
585
|
+
table = self.tables_container.get(name=name, strict=True)
|
|
586
|
+
if not isinstance(table, FeatureTable):
|
|
587
|
+
raise NgioValueError(
|
|
588
|
+
f"Table {name} is not a feature table. Got {type(table)}"
|
|
589
|
+
)
|
|
590
|
+
return table
|
|
591
|
+
|
|
592
|
+
def get_generic_roi_table(self, name: str) -> GenericRoiTable:
|
|
593
|
+
"""Get a generic ROI table from the image.
|
|
594
|
+
|
|
595
|
+
Args:
|
|
596
|
+
name (str): The name of the table.
|
|
597
|
+
"""
|
|
598
|
+
table = self.tables_container.get(name=name, strict=True)
|
|
599
|
+
if not isinstance(table, GenericRoiTable):
|
|
600
|
+
raise NgioValueError(
|
|
601
|
+
f"Table {name} is not a generic ROI table. Got {type(table)}"
|
|
602
|
+
)
|
|
603
|
+
return table
|
|
604
|
+
|
|
605
|
+
def get_condition_table(self, name: str) -> ConditionTable:
|
|
606
|
+
"""Get a condition table from the image.
|
|
607
|
+
|
|
608
|
+
Args:
|
|
609
|
+
name (str): The name of the table.
|
|
610
|
+
"""
|
|
611
|
+
table = self.tables_container.get(name=name, strict=True)
|
|
612
|
+
if not isinstance(table, ConditionTable):
|
|
613
|
+
raise NgioValueError(
|
|
614
|
+
f"Table {name} is not a condition table. Got {type(table)}"
|
|
615
|
+
)
|
|
616
|
+
return table
|
|
617
|
+
|
|
618
|
+
def get_table(self, name: str, check_type: TypedTable | None = None) -> Table:
|
|
619
|
+
"""Get a table from the image.
|
|
620
|
+
|
|
621
|
+
Args:
|
|
622
|
+
name (str): The name of the table.
|
|
623
|
+
check_type (TypedTable | None): Deprecated. Please use
|
|
624
|
+
'get_table_as' instead, or one of the type specific
|
|
625
|
+
get_*table() methods.
|
|
626
|
+
|
|
627
|
+
"""
|
|
628
|
+
if check_type is not None:
|
|
629
|
+
warnings.warn(
|
|
630
|
+
"The 'check_type' argument is deprecated, and will be removed in "
|
|
631
|
+
"ngio=0.3. Use 'get_table_as' instead or one of the "
|
|
632
|
+
"type specific get_*table() methods.",
|
|
633
|
+
DeprecationWarning,
|
|
634
|
+
stacklevel=2,
|
|
635
|
+
)
|
|
636
|
+
return self.tables_container.get(name=name, strict=False)
|
|
637
|
+
|
|
638
|
+
def get_table_as(
|
|
639
|
+
self,
|
|
640
|
+
name: str,
|
|
641
|
+
table_cls: type[TableType],
|
|
642
|
+
backend: TableBackend | None = None,
|
|
643
|
+
) -> TableType:
|
|
644
|
+
"""Get a table from the image as a specific type.
|
|
645
|
+
|
|
646
|
+
Args:
|
|
647
|
+
name (str): The name of the table.
|
|
648
|
+
table_cls (type[TableType]): The type of the table.
|
|
649
|
+
backend (TableBackend | None): The backend to use. If None,
|
|
650
|
+
the default backend is used.
|
|
651
|
+
"""
|
|
652
|
+
return self.tables_container.get_as(
|
|
653
|
+
name=name,
|
|
654
|
+
table_cls=table_cls,
|
|
655
|
+
backend=backend,
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
def build_image_roi_table(self, name: str | None = "image") -> RoiTable:
|
|
659
|
+
"""Compute the ROI table for an image."""
|
|
660
|
+
return self.get_image().build_image_roi_table(name=name)
|
|
661
|
+
|
|
662
|
+
def build_masking_roi_table(self, label: str) -> MaskingRoiTable:
|
|
663
|
+
"""Compute the masking ROI table for a label."""
|
|
664
|
+
return self.get_label(label).build_masking_roi_table()
|
|
665
|
+
|
|
666
|
+
def add_table(
|
|
667
|
+
self,
|
|
668
|
+
name: str,
|
|
669
|
+
table: Table,
|
|
670
|
+
backend: TableBackend = DefaultTableBackend,
|
|
671
|
+
overwrite: bool = False,
|
|
672
|
+
) -> None:
|
|
673
|
+
"""Add a table to the image."""
|
|
674
|
+
self.tables_container.add(
|
|
675
|
+
name=name, table=table, backend=backend, overwrite=overwrite
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
def delete_table(self, name: str, missing_ok: bool = False) -> None:
|
|
679
|
+
"""Delete a table from the group.
|
|
680
|
+
|
|
681
|
+
Args:
|
|
682
|
+
name (str): The name of the table to delete.
|
|
683
|
+
missing_ok (bool): If True, do not raise an error if the table does not
|
|
684
|
+
exist.
|
|
685
|
+
|
|
686
|
+
"""
|
|
687
|
+
table_container = self._get_tables_container(create_mode=False)
|
|
688
|
+
if table_container is None and missing_ok:
|
|
689
|
+
return
|
|
690
|
+
if table_container is None:
|
|
691
|
+
raise NgioValueError(
|
|
692
|
+
f"No tables found in the image, cannot delete {name}. "
|
|
693
|
+
"Set missing_ok=True to ignore this error."
|
|
694
|
+
)
|
|
695
|
+
table_container.delete(name=name, missing_ok=missing_ok)
|
|
696
|
+
|
|
697
|
+
def list_labels(self) -> list[str]:
|
|
698
|
+
"""List all labels in the image."""
|
|
699
|
+
label_container = self._get_labels_container(create_mode=False)
|
|
700
|
+
if label_container is None:
|
|
701
|
+
return []
|
|
702
|
+
return label_container.list()
|
|
703
|
+
|
|
704
|
+
def get_label(
|
|
705
|
+
self,
|
|
706
|
+
name: str,
|
|
707
|
+
path: str | None = None,
|
|
708
|
+
pixel_size: PixelSize | None = None,
|
|
709
|
+
strict: bool = False,
|
|
710
|
+
) -> Label:
|
|
711
|
+
"""Get a label from the group.
|
|
712
|
+
|
|
713
|
+
Args:
|
|
714
|
+
name (str): The name of the label.
|
|
715
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
716
|
+
pixel_size (PixelSize | None): The pixel size of the image.
|
|
717
|
+
strict (bool): Only used if the pixel size is provided. If True, the
|
|
718
|
+
pixel size must match the image pixel size exactly. If False, the
|
|
719
|
+
closest pixel size level will be returned.
|
|
720
|
+
"""
|
|
721
|
+
return self.labels_container.get(
|
|
722
|
+
name=name, path=path, pixel_size=pixel_size, strict=strict
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
def get_masked_label(
|
|
726
|
+
self,
|
|
727
|
+
label_name: str,
|
|
728
|
+
masking_label_name: str | None = None,
|
|
729
|
+
masking_table_name: str | None = None,
|
|
730
|
+
path: str | None = None,
|
|
731
|
+
pixel_size: PixelSize | None = None,
|
|
732
|
+
strict: bool = False,
|
|
733
|
+
) -> MaskedLabel:
|
|
734
|
+
"""Get a masked image at a specific level.
|
|
735
|
+
|
|
736
|
+
Args:
|
|
737
|
+
label_name (str): The name of the label.
|
|
738
|
+
masking_label_name (str | None): The name of the masking label.
|
|
739
|
+
masking_table_name (str | None): The name of the masking table.
|
|
740
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
741
|
+
pixel_size (PixelSize | None): The pixel size of the image.
|
|
742
|
+
strict (bool): Only used if the pixel size is provided. If True, the
|
|
743
|
+
pixel size must match the image pixel size exactly. If False, the
|
|
744
|
+
closest pixel size level will be returned.
|
|
745
|
+
"""
|
|
746
|
+
label = self.get_label(
|
|
747
|
+
name=label_name, path=path, pixel_size=pixel_size, strict=strict
|
|
748
|
+
)
|
|
749
|
+
masking_label, masking_table = self._find_matching_masking_label(
|
|
750
|
+
masking_label_name=masking_label_name,
|
|
751
|
+
masking_table_name=masking_table_name,
|
|
752
|
+
pixel_size=pixel_size,
|
|
753
|
+
)
|
|
754
|
+
return MaskedLabel(
|
|
755
|
+
group_handler=label._group_handler,
|
|
756
|
+
path=label.path,
|
|
757
|
+
meta_handler=label.meta_handler,
|
|
758
|
+
label=masking_label,
|
|
759
|
+
masking_roi_table=masking_table,
|
|
760
|
+
)
|
|
761
|
+
|
|
762
|
+
def delete_label(self, name: str, missing_ok: bool = False) -> None:
|
|
763
|
+
"""Delete a label from the group.
|
|
764
|
+
|
|
765
|
+
Args:
|
|
766
|
+
name (str): The name of the label to delete.
|
|
767
|
+
missing_ok (bool): If True, do not raise an error if the label does not
|
|
768
|
+
exist.
|
|
769
|
+
|
|
770
|
+
"""
|
|
771
|
+
label_container = self._get_labels_container(create_mode=False)
|
|
772
|
+
if label_container is None and missing_ok:
|
|
773
|
+
return
|
|
774
|
+
if label_container is None:
|
|
775
|
+
raise NgioValueError(
|
|
776
|
+
f"No labels found in the image, cannot delete {name}. "
|
|
777
|
+
"Set missing_ok=True to ignore this error."
|
|
778
|
+
)
|
|
779
|
+
label_container.delete(name=name, missing_ok=missing_ok)
|
|
780
|
+
|
|
781
|
+
def derive_label(
|
|
782
|
+
self,
|
|
783
|
+
name: str,
|
|
784
|
+
ref_image: Image | Label | None = None,
|
|
785
|
+
# Metadata parameters
|
|
786
|
+
shape: Sequence[int] | None = None,
|
|
787
|
+
pixelsize: float | tuple[float, float] | None = None,
|
|
788
|
+
z_spacing: float | None = None,
|
|
789
|
+
time_spacing: float | None = None,
|
|
790
|
+
channels_policy: Literal["same", "squeeze", "singleton"] | int = "squeeze",
|
|
791
|
+
ngff_version: NgffVersions | None = None,
|
|
792
|
+
# Zarr Array parameters
|
|
793
|
+
chunks: ChunksLike | None = None,
|
|
794
|
+
shards: ShardsLike | None = None,
|
|
795
|
+
dtype: str | None = None,
|
|
796
|
+
dimension_separator: Literal[".", "/"] | None = None,
|
|
797
|
+
compressors: CompressorLike | None = None,
|
|
798
|
+
extra_array_kwargs: Mapping[str, Any] | None = None,
|
|
799
|
+
overwrite: bool = False,
|
|
800
|
+
# Deprecated arguments
|
|
801
|
+
labels: Sequence[str] | None = None,
|
|
802
|
+
pixel_size: PixelSize | None = None,
|
|
803
|
+
) -> "Label":
|
|
804
|
+
"""Derive a new label from an existing image or label.
|
|
805
|
+
|
|
806
|
+
If a kwarg is not provided, the value from the reference image will be used.
|
|
807
|
+
|
|
808
|
+
Args:
|
|
809
|
+
name (str): The name of the new label.
|
|
810
|
+
ref_image (Image | Label | None): The reference image to derive the new
|
|
811
|
+
label from. If None, the first level image will be used.
|
|
812
|
+
shape (Sequence[int] | None): The shape of the new label.
|
|
813
|
+
pixelsize (float | tuple[float, float] | None): The pixel size of the new
|
|
814
|
+
label.
|
|
815
|
+
z_spacing (float | None): The z spacing of the new label.
|
|
816
|
+
time_spacing (float | None): The time spacing of the new label.
|
|
817
|
+
channels_policy (Literal["same", "squeeze"] | int): Possible policies:
|
|
818
|
+
- If "squeeze", the channels axis will be removed (no matter its size).
|
|
819
|
+
- If "same", the channels axis will be kept as is (if it exists).
|
|
820
|
+
- If "singleton", the channels axis will be set to size 1.
|
|
821
|
+
- If an integer is provided, the channels axis will be changed to have
|
|
822
|
+
that size.
|
|
823
|
+
Defaults to "squeeze".
|
|
824
|
+
ngff_version (NgffVersions | None): The NGFF version to use.
|
|
825
|
+
chunks (ChunksLike | None): The chunk shape of the new label.
|
|
826
|
+
shards (ShardsLike | None): The shard shape of the new label.
|
|
827
|
+
dtype (str | None): The data type of the new label.
|
|
828
|
+
dimension_separator (Literal[".", "/"] | None): The separator to use for
|
|
829
|
+
dimensions.
|
|
830
|
+
compressors (CompressorLike | None): The compressors to use.
|
|
831
|
+
extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
|
|
832
|
+
the zarr array creation.
|
|
833
|
+
overwrite (bool): Whether to overwrite an existing label. Defaults to False.
|
|
834
|
+
labels (Sequence[str] | None): Deprecated. This argument is deprecated,
|
|
835
|
+
please use channels_meta instead.
|
|
836
|
+
pixel_size (PixelSize | None): Deprecated. The pixel size of the new label.
|
|
837
|
+
This argument is deprecated, please use pixelsize, z_spacing,
|
|
838
|
+
and time_spacing instead.
|
|
839
|
+
|
|
840
|
+
Returns:
|
|
841
|
+
Label: The new derived label.
|
|
842
|
+
|
|
843
|
+
"""
|
|
844
|
+
if ref_image is None:
|
|
845
|
+
ref_image = self.get_image()
|
|
846
|
+
return self.labels_container.derive(
|
|
847
|
+
name=name,
|
|
848
|
+
ref_image=ref_image,
|
|
849
|
+
shape=shape,
|
|
850
|
+
pixelsize=pixelsize,
|
|
851
|
+
z_spacing=z_spacing,
|
|
852
|
+
time_spacing=time_spacing,
|
|
853
|
+
channels_policy=channels_policy,
|
|
854
|
+
ngff_version=ngff_version,
|
|
855
|
+
chunks=chunks,
|
|
856
|
+
shards=shards,
|
|
857
|
+
dtype=dtype,
|
|
858
|
+
dimension_separator=dimension_separator,
|
|
859
|
+
compressors=compressors,
|
|
860
|
+
extra_array_kwargs=extra_array_kwargs,
|
|
861
|
+
overwrite=overwrite,
|
|
862
|
+
labels=labels,
|
|
863
|
+
pixel_size=pixel_size,
|
|
864
|
+
)
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
def open_ome_zarr_container(
|
|
868
|
+
store: StoreOrGroup,
|
|
869
|
+
cache: bool = False,
|
|
870
|
+
mode: AccessModeLiteral = "r+",
|
|
871
|
+
validate_arrays: bool = True,
|
|
872
|
+
) -> OmeZarrContainer:
|
|
873
|
+
"""Open an OME-Zarr image."""
|
|
874
|
+
handler = ZarrGroupHandler(store=store, cache=cache, mode=mode)
|
|
875
|
+
return OmeZarrContainer(
|
|
876
|
+
group_handler=handler,
|
|
877
|
+
validate_paths=validate_arrays,
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
def open_image(
|
|
882
|
+
store: StoreOrGroup,
|
|
883
|
+
path: str | None = None,
|
|
884
|
+
pixel_size: PixelSize | None = None,
|
|
885
|
+
strict: bool = True,
|
|
886
|
+
cache: bool = False,
|
|
887
|
+
mode: AccessModeLiteral = "r+",
|
|
888
|
+
) -> Image:
|
|
889
|
+
"""Open a single level image from an OME-Zarr image.
|
|
890
|
+
|
|
891
|
+
Args:
|
|
892
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
893
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
894
|
+
pixel_size (PixelSize | None): The pixel size of the image.
|
|
895
|
+
strict (bool): Only used if the pixel size is provided. If True, the
|
|
896
|
+
pixel size must match the image pixel size exactly. If False, the
|
|
897
|
+
closest pixel size level will be returned.
|
|
898
|
+
cache (bool): Whether to use a cache for the zarr group metadata.
|
|
899
|
+
mode (AccessModeLiteral): The
|
|
900
|
+
access mode for the image. Defaults to "r+".
|
|
901
|
+
"""
|
|
902
|
+
group_handler = ZarrGroupHandler(store=store, cache=cache, mode=mode)
|
|
903
|
+
images_container = ImagesContainer(group_handler)
|
|
904
|
+
return images_container.get(
|
|
905
|
+
path=path,
|
|
906
|
+
pixel_size=pixel_size,
|
|
907
|
+
strict=strict,
|
|
908
|
+
)
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
def open_label(
|
|
912
|
+
store: StoreOrGroup,
|
|
913
|
+
name: str | None = None,
|
|
914
|
+
path: str | None = None,
|
|
915
|
+
pixel_size: PixelSize | None = None,
|
|
916
|
+
strict: bool = True,
|
|
917
|
+
cache: bool = False,
|
|
918
|
+
mode: AccessModeLiteral = "r+",
|
|
919
|
+
) -> Label:
|
|
920
|
+
"""Open a single level label from an OME-Zarr Label group.
|
|
921
|
+
|
|
922
|
+
Args:
|
|
923
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
924
|
+
name (str | None): The name of the label. If None,
|
|
925
|
+
we will try to open the store as a multiscale label.
|
|
926
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
927
|
+
pixel_size (PixelSize | None): The pixel size of the image.
|
|
928
|
+
strict (bool): Only used if the pixel size is provided. If True, the
|
|
929
|
+
pixel size must match the image pixel size exactly. If False, the
|
|
930
|
+
closest pixel size level will be returned.
|
|
931
|
+
cache (bool): Whether to use a cache for the zarr group metadata.
|
|
932
|
+
mode (AccessModeLiteral): The access mode for the image. Defaults to "r+".
|
|
933
|
+
|
|
934
|
+
"""
|
|
935
|
+
group_handler = ZarrGroupHandler(store=store, cache=cache, mode=mode)
|
|
936
|
+
if name is None:
|
|
937
|
+
label_meta_handler = LabelMetaHandler(group_handler)
|
|
938
|
+
path = (
|
|
939
|
+
label_meta_handler.get_meta()
|
|
940
|
+
.get_dataset(path=path, pixel_size=pixel_size, strict=strict)
|
|
941
|
+
.path
|
|
942
|
+
)
|
|
943
|
+
return Label(group_handler, path, label_meta_handler)
|
|
944
|
+
|
|
945
|
+
labels_container = LabelsContainer(group_handler)
|
|
946
|
+
return labels_container.get(
|
|
947
|
+
name=name,
|
|
948
|
+
path=path,
|
|
949
|
+
pixel_size=pixel_size,
|
|
950
|
+
strict=strict,
|
|
951
|
+
)
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
def create_empty_ome_zarr(
|
|
955
|
+
store: StoreOrGroup,
|
|
956
|
+
shape: Sequence[int],
|
|
957
|
+
pixelsize: float | tuple[float, float] | None = None,
|
|
958
|
+
z_spacing: float = 1.0,
|
|
959
|
+
time_spacing: float = 1.0,
|
|
960
|
+
scaling_factors: Sequence[float] | Literal["auto"] = "auto",
|
|
961
|
+
levels: int | list[str] = 5,
|
|
962
|
+
space_unit: SpaceUnits = DefaultSpaceUnit,
|
|
963
|
+
time_unit: TimeUnits = DefaultTimeUnit,
|
|
964
|
+
axes_names: Sequence[str] | None = None,
|
|
965
|
+
channels_meta: Sequence[str | Channel] | None = None,
|
|
966
|
+
name: str | None = None,
|
|
967
|
+
ngff_version: NgffVersions = DefaultNgffVersion,
|
|
968
|
+
chunks: ChunksLike = "auto",
|
|
969
|
+
shards: ShardsLike | None = None,
|
|
970
|
+
dtype: str = "uint16",
|
|
971
|
+
dimension_separator: Literal[".", "/"] = "/",
|
|
972
|
+
compressors: CompressorLike = "auto",
|
|
973
|
+
extra_array_kwargs: Mapping[str, Any] | None = None,
|
|
974
|
+
overwrite: bool = False,
|
|
975
|
+
# Deprecated arguments
|
|
976
|
+
xy_pixelsize: float | None = None,
|
|
977
|
+
xy_scaling_factor: float | None = None,
|
|
978
|
+
z_scaling_factor: float | None = None,
|
|
979
|
+
channel_labels: list[str] | None = None,
|
|
980
|
+
channel_wavelengths: list[str] | None = None,
|
|
981
|
+
channel_colors: Sequence[str] | None = None,
|
|
982
|
+
channel_active: Sequence[bool] | None = None,
|
|
983
|
+
) -> OmeZarrContainer:
|
|
984
|
+
"""Create an empty OME-Zarr image with the given shape and metadata.
|
|
985
|
+
|
|
986
|
+
Args:
|
|
987
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
988
|
+
shape (Sequence[int]): The shape of the image.
|
|
989
|
+
pixelsize (float | tuple[float, float] | None): The pixel size in x and y
|
|
990
|
+
dimensions.
|
|
991
|
+
z_spacing (float): The spacing between z slices. Defaults to 1.0.
|
|
992
|
+
time_spacing (float): The spacing between time points. Defaults to 1.0.
|
|
993
|
+
scaling_factors (Sequence[float] | Literal["auto"]): The down-scaling factors
|
|
994
|
+
for the pyramid levels. Defaults to "auto".
|
|
995
|
+
levels (int | list[str]): The number of levels in the pyramid or a list of
|
|
996
|
+
level names. Defaults to 5.
|
|
997
|
+
space_unit (SpaceUnits): The unit of space. Defaults to DefaultSpaceUnit.
|
|
998
|
+
time_unit (TimeUnits): The unit of time. Defaults to DefaultTimeUnit.
|
|
999
|
+
axes_names (Sequence[str] | None): The names of the axes. If None the
|
|
1000
|
+
canonical names are used. Defaults to None.
|
|
1001
|
+
channels_meta (Sequence[str | Channel] | None): The channels metadata.
|
|
1002
|
+
Defaults to None.
|
|
1003
|
+
name (str | None): The name of the image. Defaults to None.
|
|
1004
|
+
ngff_version (NgffVersions): The version of the OME-Zarr specification.
|
|
1005
|
+
Defaults to DefaultNgffVersion.
|
|
1006
|
+
chunks (ChunksLike): The chunk shape. Defaults to "auto".
|
|
1007
|
+
shards (ShardsLike | None): The shard shape. Defaults to None.
|
|
1008
|
+
dtype (str): The data type of the image. Defaults to "uint16".
|
|
1009
|
+
dimension_separator (Literal[".", "/"]): The dimension separator to use.
|
|
1010
|
+
Defaults to "/".
|
|
1011
|
+
compressors (CompressorLike): The compressor to use. Defaults to "auto".
|
|
1012
|
+
extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
|
|
1013
|
+
the zarr array creation. Defaults to None.
|
|
1014
|
+
overwrite (bool): Whether to overwrite an existing image. Defaults to False.
|
|
1015
|
+
xy_pixelsize (float | None): Deprecated. Use pixelsize instead.
|
|
1016
|
+
xy_scaling_factor (float | None): Deprecated. Use scaling_factors instead.
|
|
1017
|
+
z_scaling_factor (float | None): Deprecated. Use scaling_factors instead.
|
|
1018
|
+
channel_labels (list[str] | None): Deprecated. Use channels_meta instead.
|
|
1019
|
+
channel_wavelengths (list[str] | None): Deprecated. Use channels_meta instead.
|
|
1020
|
+
channel_colors (Sequence[str] | None): Deprecated. Use channels_meta instead.
|
|
1021
|
+
channel_active (Sequence[bool] | None): Deprecated. Use channels_meta instead.
|
|
1022
|
+
"""
|
|
1023
|
+
if xy_pixelsize is not None:
|
|
1024
|
+
warnings.warn(
|
|
1025
|
+
"'xy_pixelsize' is deprecated and will be removed in a future "
|
|
1026
|
+
"version. Please use 'pixelsize' instead.",
|
|
1027
|
+
DeprecationWarning,
|
|
1028
|
+
stacklevel=2,
|
|
1029
|
+
)
|
|
1030
|
+
pixelsize = xy_pixelsize
|
|
1031
|
+
if xy_scaling_factor is not None or z_scaling_factor is not None:
|
|
1032
|
+
warnings.warn(
|
|
1033
|
+
"'xy_scaling_factor' and 'z_scaling_factor' are deprecated and will be "
|
|
1034
|
+
"removed in a future version. Please use 'scaling_factors' instead.",
|
|
1035
|
+
DeprecationWarning,
|
|
1036
|
+
stacklevel=2,
|
|
1037
|
+
)
|
|
1038
|
+
xy_scaling_factor_ = xy_scaling_factor or 2.0
|
|
1039
|
+
z_scaling_factor_ = z_scaling_factor or 1.0
|
|
1040
|
+
if len(shape) == 2:
|
|
1041
|
+
scaling_factors = (xy_scaling_factor_, xy_scaling_factor_)
|
|
1042
|
+
else:
|
|
1043
|
+
zyx_factors = (z_scaling_factor_, xy_scaling_factor_, xy_scaling_factor_)
|
|
1044
|
+
scaling_factors = (1.0,) * (len(shape) - 3) + zyx_factors
|
|
1045
|
+
|
|
1046
|
+
if channel_labels is not None:
|
|
1047
|
+
warnings.warn(
|
|
1048
|
+
"'channel_labels' is deprecated and will be removed in a future "
|
|
1049
|
+
"version. Please use 'channels_meta' instead.",
|
|
1050
|
+
DeprecationWarning,
|
|
1051
|
+
stacklevel=2,
|
|
1052
|
+
)
|
|
1053
|
+
channels_meta = channel_labels
|
|
1054
|
+
|
|
1055
|
+
if channel_wavelengths is not None:
|
|
1056
|
+
warnings.warn(
|
|
1057
|
+
"'channel_wavelengths' is deprecated and will be removed in a future "
|
|
1058
|
+
"version. Please use 'channels_meta' instead.",
|
|
1059
|
+
DeprecationWarning,
|
|
1060
|
+
stacklevel=2,
|
|
1061
|
+
)
|
|
1062
|
+
if channel_colors is not None:
|
|
1063
|
+
warnings.warn(
|
|
1064
|
+
"'channel_colors' is deprecated and will be removed in a future "
|
|
1065
|
+
"version. Please use 'channels_meta' instead.",
|
|
1066
|
+
DeprecationWarning,
|
|
1067
|
+
stacklevel=2,
|
|
1068
|
+
)
|
|
1069
|
+
if channel_active is not None:
|
|
1070
|
+
warnings.warn(
|
|
1071
|
+
"'channel_active' is deprecated and will be removed in a future "
|
|
1072
|
+
"version. Please use 'channels_meta' instead.",
|
|
1073
|
+
DeprecationWarning,
|
|
1074
|
+
stacklevel=2,
|
|
1075
|
+
)
|
|
1076
|
+
|
|
1077
|
+
if pixelsize is None:
|
|
1078
|
+
raise NgioValueError("pixelsize must be provided.")
|
|
1079
|
+
|
|
1080
|
+
handler = init_image_like(
|
|
1081
|
+
store=store,
|
|
1082
|
+
meta_type=NgioImageMeta,
|
|
1083
|
+
shape=shape,
|
|
1084
|
+
pixelsize=pixelsize,
|
|
1085
|
+
z_spacing=z_spacing,
|
|
1086
|
+
time_spacing=time_spacing,
|
|
1087
|
+
scaling_factors=scaling_factors,
|
|
1088
|
+
levels=levels,
|
|
1089
|
+
space_unit=space_unit,
|
|
1090
|
+
time_unit=time_unit,
|
|
1091
|
+
axes_names=axes_names,
|
|
1092
|
+
channels_meta=channels_meta,
|
|
1093
|
+
name=name,
|
|
1094
|
+
ngff_version=ngff_version,
|
|
1095
|
+
chunks=chunks,
|
|
1096
|
+
shards=shards,
|
|
1097
|
+
dtype=dtype,
|
|
1098
|
+
dimension_separator=dimension_separator,
|
|
1099
|
+
compressors=compressors,
|
|
1100
|
+
extra_array_kwargs=extra_array_kwargs,
|
|
1101
|
+
overwrite=overwrite,
|
|
1102
|
+
)
|
|
1103
|
+
|
|
1104
|
+
ome_zarr = OmeZarrContainer(group_handler=handler)
|
|
1105
|
+
if (
|
|
1106
|
+
channel_wavelengths is not None
|
|
1107
|
+
or channel_colors is not None
|
|
1108
|
+
or channel_active is not None
|
|
1109
|
+
):
|
|
1110
|
+
channel_names = ome_zarr.channel_labels
|
|
1111
|
+
ome_zarr.set_channel_meta(
|
|
1112
|
+
labels=channel_names,
|
|
1113
|
+
wavelength_id=channel_wavelengths,
|
|
1114
|
+
percentiles=None,
|
|
1115
|
+
colors=channel_colors,
|
|
1116
|
+
active=channel_active,
|
|
1117
|
+
)
|
|
1118
|
+
else:
|
|
1119
|
+
ome_zarr.set_channel_meta(
|
|
1120
|
+
labels=ome_zarr.channel_labels,
|
|
1121
|
+
percentiles=None,
|
|
1122
|
+
)
|
|
1123
|
+
return ome_zarr
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
def create_ome_zarr_from_array(
|
|
1127
|
+
store: StoreOrGroup,
|
|
1128
|
+
array: np.ndarray,
|
|
1129
|
+
pixelsize: float | tuple[float, float] | None = None,
|
|
1130
|
+
z_spacing: float = 1.0,
|
|
1131
|
+
time_spacing: float = 1.0,
|
|
1132
|
+
scaling_factors: Sequence[float] | Literal["auto"] = "auto",
|
|
1133
|
+
levels: int | list[str] = 5,
|
|
1134
|
+
space_unit: SpaceUnits = DefaultSpaceUnit,
|
|
1135
|
+
time_unit: TimeUnits = DefaultTimeUnit,
|
|
1136
|
+
axes_names: Sequence[str] | None = None,
|
|
1137
|
+
channels_meta: Sequence[str | Channel] | None = None,
|
|
1138
|
+
percentiles: tuple[float, float] = (0.1, 99.9),
|
|
1139
|
+
name: str | None = None,
|
|
1140
|
+
ngff_version: NgffVersions = DefaultNgffVersion,
|
|
1141
|
+
chunks: ChunksLike = "auto",
|
|
1142
|
+
shards: ShardsLike | None = None,
|
|
1143
|
+
dimension_separator: Literal[".", "/"] = "/",
|
|
1144
|
+
compressors: CompressorLike = "auto",
|
|
1145
|
+
extra_array_kwargs: Mapping[str, Any] | None = None,
|
|
1146
|
+
overwrite: bool = False,
|
|
1147
|
+
# Deprecated arguments
|
|
1148
|
+
xy_pixelsize: float | None = None,
|
|
1149
|
+
xy_scaling_factor: float | None = None,
|
|
1150
|
+
z_scaling_factor: float | None = None,
|
|
1151
|
+
channel_labels: list[str] | None = None,
|
|
1152
|
+
channel_wavelengths: list[str] | None = None,
|
|
1153
|
+
channel_colors: Sequence[str] | None = None,
|
|
1154
|
+
channel_active: Sequence[bool] | None = None,
|
|
1155
|
+
) -> OmeZarrContainer:
|
|
1156
|
+
"""Create an OME-Zarr image from a numpy array.
|
|
1157
|
+
|
|
1158
|
+
Args:
|
|
1159
|
+
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
1160
|
+
array (np.ndarray): The image data.
|
|
1161
|
+
pixelsize (float | tuple[float, float] | None): The pixel size in x and y
|
|
1162
|
+
dimensions.
|
|
1163
|
+
z_spacing (float): The spacing between z slices. Defaults to 1.0.
|
|
1164
|
+
time_spacing (float): The spacing between time points. Defaults to 1.0.
|
|
1165
|
+
scaling_factors (Sequence[float] | Literal["auto"]): The down-scaling factors
|
|
1166
|
+
for the pyramid levels. Defaults to "auto".
|
|
1167
|
+
levels (int | list[str]): The number of levels in the pyramid or a list of
|
|
1168
|
+
level names. Defaults to 5.
|
|
1169
|
+
space_unit (SpaceUnits): The unit of space. Defaults to DefaultSpaceUnit.
|
|
1170
|
+
time_unit (TimeUnits): The unit of time. Defaults to DefaultTimeUnit.
|
|
1171
|
+
axes_names (Sequence[str] | None): The names of the axes. If None the
|
|
1172
|
+
canonical names are used. Defaults to None.
|
|
1173
|
+
channels_meta (Sequence[str | Channel] | None): The channels metadata.
|
|
1174
|
+
Defaults to None.
|
|
1175
|
+
percentiles (tuple[float, float]): The percentiles of the channels for
|
|
1176
|
+
computing display ranges. Defaults to (0.1, 99.9).
|
|
1177
|
+
name (str | None): The name of the image. Defaults to None.
|
|
1178
|
+
ngff_version (NgffVersions): The version of the OME-Zarr specification.
|
|
1179
|
+
Defaults to DefaultNgffVersion.
|
|
1180
|
+
chunks (ChunksLike): The chunk shape. Defaults to "auto".
|
|
1181
|
+
shards (ShardsLike | None): The shard shape. Defaults to None.
|
|
1182
|
+
dimension_separator (Literal[".", "/"]): The separator to use for
|
|
1183
|
+
dimensions. Defaults to "/".
|
|
1184
|
+
compressors (CompressorLike): The compressors to use. Defaults to "auto".
|
|
1185
|
+
extra_array_kwargs (Mapping[str, Any] | None): Extra arguments to pass to
|
|
1186
|
+
the zarr array creation. Defaults to None.
|
|
1187
|
+
overwrite (bool): Whether to overwrite an existing image. Defaults to False.
|
|
1188
|
+
xy_pixelsize (float | None): Deprecated. Use pixelsize instead.
|
|
1189
|
+
xy_scaling_factor (float | None): Deprecated. Use scaling_factors instead.
|
|
1190
|
+
z_scaling_factor (float | None): Deprecated. Use scaling_factors instead.
|
|
1191
|
+
channel_labels (list[str] | None): Deprecated. Use channels_meta instead.
|
|
1192
|
+
channel_wavelengths (list[str] | None): Deprecated. Use channels_meta instead.
|
|
1193
|
+
channel_colors (Sequence[str] | None): Deprecated. Use channels_meta instead.
|
|
1194
|
+
channel_active (Sequence[bool] | None): Deprecated. Use channels_meta instead.
|
|
1195
|
+
"""
|
|
1196
|
+
ome_zarr = create_empty_ome_zarr(
|
|
1197
|
+
store=store,
|
|
1198
|
+
shape=array.shape,
|
|
1199
|
+
pixelsize=pixelsize,
|
|
1200
|
+
z_spacing=z_spacing,
|
|
1201
|
+
time_spacing=time_spacing,
|
|
1202
|
+
scaling_factors=scaling_factors,
|
|
1203
|
+
levels=levels,
|
|
1204
|
+
space_unit=space_unit,
|
|
1205
|
+
time_unit=time_unit,
|
|
1206
|
+
axes_names=axes_names,
|
|
1207
|
+
channels_meta=channels_meta,
|
|
1208
|
+
name=name,
|
|
1209
|
+
ngff_version=ngff_version,
|
|
1210
|
+
chunks=chunks,
|
|
1211
|
+
shards=shards,
|
|
1212
|
+
dimension_separator=dimension_separator,
|
|
1213
|
+
compressors=compressors,
|
|
1214
|
+
extra_array_kwargs=extra_array_kwargs,
|
|
1215
|
+
overwrite=overwrite,
|
|
1216
|
+
xy_pixelsize=xy_pixelsize,
|
|
1217
|
+
xy_scaling_factor=xy_scaling_factor,
|
|
1218
|
+
z_scaling_factor=z_scaling_factor,
|
|
1219
|
+
channel_labels=channel_labels,
|
|
1220
|
+
channel_wavelengths=channel_wavelengths,
|
|
1221
|
+
channel_colors=channel_colors,
|
|
1222
|
+
channel_active=channel_active,
|
|
1223
|
+
)
|
|
1224
|
+
image = ome_zarr.get_image()
|
|
1225
|
+
image.set_array(array)
|
|
1226
|
+
image.consolidate()
|
|
1227
|
+
if len(percentiles) != 2:
|
|
1228
|
+
raise NgioValueError(
|
|
1229
|
+
f"'percentiles' must be a tuple of two values. Got {percentiles}"
|
|
1230
|
+
)
|
|
1231
|
+
ome_zarr.set_channel_percentiles(
|
|
1232
|
+
start_percentile=percentiles[0],
|
|
1233
|
+
end_percentile=percentiles[1],
|
|
1234
|
+
)
|
|
1235
|
+
return ome_zarr
|