ngio 0.2.0b3__py3-none-any.whl → 0.2.2__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 +30 -10
- ngio/common/__init__.py +3 -3
- ngio/common/_array_pipe.py +7 -1
- ngio/common/_masking_roi.py +4 -4
- ngio/common/_roi.py +14 -14
- ngio/hcs/__init__.py +16 -2
- ngio/hcs/plate.py +465 -54
- ngio/images/__init__.py +7 -7
- ngio/images/abstract_image.py +30 -10
- ngio/images/create.py +25 -35
- ngio/images/image.py +40 -8
- ngio/images/label.py +33 -8
- ngio/images/masked_image.py +19 -5
- ngio/images/{omezarr_container.py → ome_zarr_container.py} +84 -47
- ngio/ome_zarr_meta/__init__.py +5 -0
- ngio/ome_zarr_meta/ngio_specs/__init__.py +10 -0
- ngio/ome_zarr_meta/ngio_specs/_axes.py +90 -65
- ngio/ome_zarr_meta/ngio_specs/_dataset.py +46 -8
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +242 -69
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +53 -19
- ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +28 -11
- ngio/ome_zarr_meta/v04/_custom_models.py +18 -0
- ngio/ome_zarr_meta/v04/_v04_spec_utils.py +3 -4
- 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.0b3.dist-info → ngio-0.2.2.dist-info}/METADATA +8 -5
- ngio-0.2.2.dist-info/RECORD +55 -0
- ngio-0.2.0b3.dist-info/RECORD +0 -54
- {ngio-0.2.0b3.dist-info → ngio-0.2.2.dist-info}/WHEEL +0 -0
- {ngio-0.2.0b3.dist-info → ngio-0.2.2.dist-info}/licenses/LICENSE +0 -0
ngio/hcs/plate.py
CHANGED
|
@@ -3,18 +3,16 @@
|
|
|
3
3
|
from ngio.images import OmeZarrContainer
|
|
4
4
|
from ngio.ome_zarr_meta import (
|
|
5
5
|
ImageInWellPath,
|
|
6
|
+
NgffVersions,
|
|
6
7
|
NgioPlateMeta,
|
|
7
8
|
NgioWellMeta,
|
|
8
9
|
find_plate_meta_handler,
|
|
9
10
|
find_well_meta_handler,
|
|
10
11
|
get_plate_meta_handler,
|
|
11
12
|
get_well_meta_handler,
|
|
13
|
+
path_in_well_validation,
|
|
12
14
|
)
|
|
13
|
-
from ngio.utils import
|
|
14
|
-
AccessModeLiteral,
|
|
15
|
-
StoreOrGroup,
|
|
16
|
-
ZarrGroupHandler,
|
|
17
|
-
)
|
|
15
|
+
from ngio.utils import AccessModeLiteral, StoreOrGroup, ZarrGroupHandler
|
|
18
16
|
|
|
19
17
|
|
|
20
18
|
# Mock lock class that does nothing
|
|
@@ -42,6 +40,10 @@ class OmeZarrWell:
|
|
|
42
40
|
self._group_handler = group_handler
|
|
43
41
|
self._meta_handler = find_well_meta_handler(group_handler)
|
|
44
42
|
|
|
43
|
+
def __repr__(self) -> str:
|
|
44
|
+
"""Return a string representation of the well."""
|
|
45
|
+
return f"Well(#images: {len(self.paths())})"
|
|
46
|
+
|
|
45
47
|
@property
|
|
46
48
|
def meta_handler(self):
|
|
47
49
|
"""Return the metadata handler."""
|
|
@@ -52,6 +54,11 @@ class OmeZarrWell:
|
|
|
52
54
|
"""Return the metadata."""
|
|
53
55
|
return self._meta_handler.meta
|
|
54
56
|
|
|
57
|
+
@property
|
|
58
|
+
def acquisition_ids(self) -> list[int]:
|
|
59
|
+
"""Return the acquisitions ids in the well."""
|
|
60
|
+
return self.meta.acquisition_ids
|
|
61
|
+
|
|
55
62
|
def paths(self, acquisition: int | None = None) -> list[str]:
|
|
56
63
|
"""Return the images paths in the well.
|
|
57
64
|
|
|
@@ -63,6 +70,97 @@ class OmeZarrWell:
|
|
|
63
70
|
"""
|
|
64
71
|
return self.meta.paths(acquisition)
|
|
65
72
|
|
|
73
|
+
def get_image_store(self, image_path: str) -> StoreOrGroup:
|
|
74
|
+
"""Get the image store from the well.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
image_path (str): The path of the image.
|
|
78
|
+
"""
|
|
79
|
+
return self._group_handler.get_group(image_path, create_mode=True)
|
|
80
|
+
|
|
81
|
+
def get_image_acquisition_id(self, image_path: str) -> int | None:
|
|
82
|
+
"""Get the acquisition id of an image in the well.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
image_path (str): The path of the image.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
int | None: The acquisition id of the image.
|
|
89
|
+
"""
|
|
90
|
+
return self.meta.get_image_acquisition_id(image_path=image_path)
|
|
91
|
+
|
|
92
|
+
def get_image(self, image_path: str) -> OmeZarrContainer:
|
|
93
|
+
"""Get an image from the well.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
image_path (str): The path of the image.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
OmeZarrContainer: The image.
|
|
100
|
+
"""
|
|
101
|
+
handler = self._group_handler.derive_handler(image_path)
|
|
102
|
+
return OmeZarrContainer(handler)
|
|
103
|
+
|
|
104
|
+
def _add_image(
|
|
105
|
+
self,
|
|
106
|
+
image_path: str,
|
|
107
|
+
acquisition_id: int | None = None,
|
|
108
|
+
strict: bool = True,
|
|
109
|
+
atomic: bool = False,
|
|
110
|
+
) -> StoreOrGroup:
|
|
111
|
+
"""Add an image to an ome-zarr well."""
|
|
112
|
+
image_path = path_in_well_validation(path=image_path)
|
|
113
|
+
|
|
114
|
+
if atomic:
|
|
115
|
+
well_lock = self._group_handler.lock
|
|
116
|
+
else:
|
|
117
|
+
well_lock = MockLock()
|
|
118
|
+
|
|
119
|
+
with well_lock:
|
|
120
|
+
meta = self.meta.add_image(
|
|
121
|
+
path=image_path, acquisition=acquisition_id, strict=strict
|
|
122
|
+
)
|
|
123
|
+
self.meta_handler.write_meta(meta)
|
|
124
|
+
self.meta_handler._group_handler.clean_cache()
|
|
125
|
+
|
|
126
|
+
return self._group_handler.get_group(image_path, create_mode=True)
|
|
127
|
+
|
|
128
|
+
def atomic_add_image(
|
|
129
|
+
self,
|
|
130
|
+
image_path: str,
|
|
131
|
+
acquisition_id: int | None = None,
|
|
132
|
+
strict: bool = True,
|
|
133
|
+
) -> StoreOrGroup:
|
|
134
|
+
"""Parallel safe version of add_image."""
|
|
135
|
+
return self._add_image(
|
|
136
|
+
image_path=image_path,
|
|
137
|
+
acquisition_id=acquisition_id,
|
|
138
|
+
atomic=True,
|
|
139
|
+
strict=strict,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
def add_image(
|
|
143
|
+
self,
|
|
144
|
+
image_path: str,
|
|
145
|
+
acquisition_id: int | None = None,
|
|
146
|
+
strict: bool = True,
|
|
147
|
+
) -> StoreOrGroup:
|
|
148
|
+
"""Add an image to an ome-zarr well.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
image_path (str): The path of the image.
|
|
152
|
+
acquisition_id (int | None): The acquisition id to filter the images.
|
|
153
|
+
strict (bool): Whether to check if the acquisition id is already exists
|
|
154
|
+
in the well. Defaults to True. If False this might lead to
|
|
155
|
+
acquision in a well that does not exist at the plate level.
|
|
156
|
+
"""
|
|
157
|
+
return self._add_image(
|
|
158
|
+
image_path=image_path,
|
|
159
|
+
acquisition_id=acquisition_id,
|
|
160
|
+
atomic=False,
|
|
161
|
+
strict=strict,
|
|
162
|
+
)
|
|
163
|
+
|
|
66
164
|
|
|
67
165
|
class OmeZarrPlate:
|
|
68
166
|
"""A class to handle the Plate Collection in an OME-Zarr file."""
|
|
@@ -78,7 +176,7 @@ class OmeZarrPlate:
|
|
|
78
176
|
|
|
79
177
|
def __repr__(self) -> str:
|
|
80
178
|
"""Return a string representation of the plate."""
|
|
81
|
-
return f"Plate([rows x columns] ({len(self.rows)} x {len(self.columns)})"
|
|
179
|
+
return f"Plate([rows x columns] ({len(self.rows)} x {len(self.columns)}))"
|
|
82
180
|
|
|
83
181
|
@property
|
|
84
182
|
def meta_handler(self):
|
|
@@ -106,25 +204,74 @@ class OmeZarrPlate:
|
|
|
106
204
|
return self.meta.acquisitions_names
|
|
107
205
|
|
|
108
206
|
@property
|
|
109
|
-
def
|
|
207
|
+
def acquisition_ids(self) -> list[int]:
|
|
110
208
|
"""Return the acquisitions ids in the plate."""
|
|
111
|
-
return self.meta.
|
|
209
|
+
return self.meta.acquisition_ids
|
|
112
210
|
|
|
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:
|
|
211
|
+
def _well_path(self, row: str, column: int | str) -> str:
|
|
119
212
|
"""Return the well path in the plate."""
|
|
120
213
|
return self.meta.get_well_path(row=row, column=column)
|
|
121
214
|
|
|
122
|
-
def
|
|
215
|
+
def _image_path(self, row: str, column: int | str, path: str) -> str:
|
|
123
216
|
"""Return the image path in the plate."""
|
|
124
217
|
well = self.get_well(row, column)
|
|
125
218
|
if path not in well.paths():
|
|
126
219
|
raise ValueError(f"Image {path} does not exist in well {row}{column}")
|
|
127
|
-
return f"{self.
|
|
220
|
+
return f"{self._well_path(row, column)}/{path}"
|
|
221
|
+
|
|
222
|
+
def wells_paths(self) -> list[str]:
|
|
223
|
+
"""Return the wells paths in the plate."""
|
|
224
|
+
return self.meta.wells_paths
|
|
225
|
+
|
|
226
|
+
def images_paths(self, acquisition: int | None = None) -> list[str]:
|
|
227
|
+
"""Return the images paths in the plate.
|
|
228
|
+
|
|
229
|
+
If acquisition is None, return all images paths in the plate.
|
|
230
|
+
Else, return the images paths in the plate for the given acquisition.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
acquisition (int | None): The acquisition id to filter the images.
|
|
234
|
+
"""
|
|
235
|
+
images = []
|
|
236
|
+
for well_path, wells in self.get_wells().items():
|
|
237
|
+
for img_path in wells.paths(acquisition):
|
|
238
|
+
images.append(f"{well_path}/{img_path}")
|
|
239
|
+
return images
|
|
240
|
+
|
|
241
|
+
def well_images_paths(
|
|
242
|
+
self, row: str, column: int | str, acquisition: int | None = None
|
|
243
|
+
) -> list[str]:
|
|
244
|
+
"""Return the images paths in a well.
|
|
245
|
+
|
|
246
|
+
If acquisition is None, return all images paths in the well.
|
|
247
|
+
Else, return the images paths in the well for the given acquisition.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
row (str): The row of the well.
|
|
251
|
+
column (int | str): The column of the well.
|
|
252
|
+
acquisition (int | None): The acquisition id to filter the images.
|
|
253
|
+
"""
|
|
254
|
+
images = []
|
|
255
|
+
well = self.get_well(row=row, column=column)
|
|
256
|
+
for path in well.paths(acquisition):
|
|
257
|
+
images.append(self._image_path(row=row, column=column, path=path))
|
|
258
|
+
return images
|
|
259
|
+
|
|
260
|
+
def get_image_acquisition_id(
|
|
261
|
+
self, row: str, column: int | str, image_path: str
|
|
262
|
+
) -> int | None:
|
|
263
|
+
"""Get the acquisition id of an image in a well.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
row (str): The row of the well.
|
|
267
|
+
column (int | str): The column of the well.
|
|
268
|
+
image_path (str): The path of the image.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
int | None: The acquisition id of the image.
|
|
272
|
+
"""
|
|
273
|
+
well = self.get_well(row=row, column=column)
|
|
274
|
+
return well.get_image_acquisition_id(image_path=image_path)
|
|
128
275
|
|
|
129
276
|
def get_well(self, row: str, column: int | str) -> OmeZarrWell:
|
|
130
277
|
"""Get a well from the plate.
|
|
@@ -136,36 +283,69 @@ class OmeZarrPlate:
|
|
|
136
283
|
Returns:
|
|
137
284
|
OmeZarrWell: The well.
|
|
138
285
|
"""
|
|
139
|
-
well_path = self.
|
|
286
|
+
well_path = self._well_path(row=row, column=column)
|
|
140
287
|
group_handler = self._group_handler.derive_handler(well_path)
|
|
141
288
|
return OmeZarrWell(group_handler)
|
|
142
289
|
|
|
143
290
|
def get_wells(self) -> dict[str, OmeZarrWell]:
|
|
144
|
-
"""Get all wells in the plate.
|
|
291
|
+
"""Get all wells in the plate.
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
dict[str, OmeZarrWell]: A dictionary of wells, where the key is the well
|
|
295
|
+
path and the value is the well object.
|
|
296
|
+
"""
|
|
145
297
|
wells = {}
|
|
146
|
-
for well_path in self.wells_paths:
|
|
298
|
+
for well_path in self.wells_paths():
|
|
147
299
|
group_handler = self._group_handler.derive_handler(well_path)
|
|
148
300
|
well = OmeZarrWell(group_handler)
|
|
149
301
|
wells[well_path] = well
|
|
150
302
|
return wells
|
|
151
303
|
|
|
152
|
-
def get_images(self, acquisition: int | None = None) ->
|
|
304
|
+
def get_images(self, acquisition: int | None = None) -> dict[str, OmeZarrContainer]:
|
|
153
305
|
"""Get all images in the plate.
|
|
154
306
|
|
|
155
307
|
Args:
|
|
156
308
|
acquisition: The acquisition id to filter the images.
|
|
157
309
|
"""
|
|
158
|
-
images =
|
|
159
|
-
for
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
img_group_handler = self._group_handler.derive_handler(full_path)
|
|
163
|
-
images.append(OmeZarrContainer(img_group_handler))
|
|
310
|
+
images = {}
|
|
311
|
+
for image_path in self.images_paths(acquisition):
|
|
312
|
+
img_group_handler = self._group_handler.derive_handler(image_path)
|
|
313
|
+
images[image_path] = OmeZarrContainer(img_group_handler)
|
|
164
314
|
return images
|
|
165
315
|
|
|
316
|
+
def get_image(
|
|
317
|
+
self, row: str, column: int | str, image_path: str
|
|
318
|
+
) -> OmeZarrContainer:
|
|
319
|
+
"""Get an image from the plate.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
row (str): The row of the well.
|
|
323
|
+
column (int | str): The column of the well.
|
|
324
|
+
image_path (str): The path of the image.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
OmeZarrContainer: The image.
|
|
328
|
+
"""
|
|
329
|
+
image_path = self._image_path(row=row, column=column, path=image_path)
|
|
330
|
+
group_handler = self._group_handler.derive_handler(image_path)
|
|
331
|
+
return OmeZarrContainer(group_handler)
|
|
332
|
+
|
|
333
|
+
def get_image_store(
|
|
334
|
+
self, row: str, column: int | str, image_path: str
|
|
335
|
+
) -> StoreOrGroup:
|
|
336
|
+
"""Get the image store from the plate.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
row (str): The row of the well.
|
|
340
|
+
column (int | str): The column of the well.
|
|
341
|
+
image_path (str): The path of the image.
|
|
342
|
+
"""
|
|
343
|
+
well = self.get_well(row=row, column=column)
|
|
344
|
+
return well.get_image_store(image_path=image_path)
|
|
345
|
+
|
|
166
346
|
def get_well_images(
|
|
167
347
|
self, row: str, column: str | int, acquisition: int | None = None
|
|
168
|
-
) ->
|
|
348
|
+
) -> dict[str, OmeZarrContainer]:
|
|
169
349
|
"""Get all images in a well.
|
|
170
350
|
|
|
171
351
|
Args:
|
|
@@ -173,28 +353,27 @@ class OmeZarrPlate:
|
|
|
173
353
|
column: The column of the well.
|
|
174
354
|
acquisition: The acquisition id to filter the images.
|
|
175
355
|
"""
|
|
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
|
-
|
|
356
|
+
images = {}
|
|
357
|
+
for image_paths in self.well_images_paths(
|
|
358
|
+
row=row, column=column, acquisition=acquisition
|
|
359
|
+
):
|
|
360
|
+
group_handler = self._group_handler.derive_handler(image_paths)
|
|
361
|
+
images[image_paths] = OmeZarrContainer(group_handler)
|
|
186
362
|
return images
|
|
187
363
|
|
|
188
364
|
def _add_image(
|
|
189
365
|
self,
|
|
190
366
|
row: str,
|
|
191
367
|
column: int | str,
|
|
192
|
-
image_path: str,
|
|
368
|
+
image_path: str | None = None,
|
|
193
369
|
acquisition_id: int | None = None,
|
|
194
370
|
acquisition_name: str | None = None,
|
|
195
371
|
atomic: bool = False,
|
|
196
|
-
) -> StoreOrGroup:
|
|
372
|
+
) -> StoreOrGroup | None:
|
|
197
373
|
"""Add an image to an ome-zarr plate."""
|
|
374
|
+
if image_path is not None:
|
|
375
|
+
image_path = path_in_well_validation(path=image_path)
|
|
376
|
+
|
|
198
377
|
if atomic:
|
|
199
378
|
plate_lock = self._group_handler.lock
|
|
200
379
|
else:
|
|
@@ -202,7 +381,11 @@ class OmeZarrPlate:
|
|
|
202
381
|
|
|
203
382
|
with plate_lock:
|
|
204
383
|
meta = self.meta
|
|
205
|
-
meta = meta.add_well(row, column
|
|
384
|
+
meta = meta.add_well(row=row, column=column)
|
|
385
|
+
if acquisition_id is not None:
|
|
386
|
+
meta = meta.add_acquisition(
|
|
387
|
+
acquisition_id=acquisition_id, acquisition_name=acquisition_name
|
|
388
|
+
)
|
|
206
389
|
self.meta_handler.write_meta(meta)
|
|
207
390
|
self.meta_handler._group_handler.clean_cache()
|
|
208
391
|
|
|
@@ -220,18 +403,25 @@ class OmeZarrPlate:
|
|
|
220
403
|
# Initialize the well metadata
|
|
221
404
|
# if the group is empty
|
|
222
405
|
well_meta = NgioWellMeta.default_init()
|
|
223
|
-
|
|
406
|
+
version = self.meta.plate.version
|
|
407
|
+
version = version if version is not None else "0.4"
|
|
408
|
+
meta_handler = get_well_meta_handler(group_handler, version=version)
|
|
224
409
|
else:
|
|
225
410
|
meta_handler = find_well_meta_handler(group_handler)
|
|
226
411
|
well_meta = meta_handler.meta
|
|
227
412
|
|
|
228
413
|
group_handler = self._group_handler.derive_handler(well_path)
|
|
229
414
|
|
|
230
|
-
|
|
415
|
+
if image_path is not None:
|
|
416
|
+
well_meta = well_meta.add_image(
|
|
417
|
+
path=image_path, acquisition=acquisition_id, strict=False
|
|
418
|
+
)
|
|
231
419
|
meta_handler.write_meta(well_meta)
|
|
232
420
|
meta_handler._group_handler.clean_cache()
|
|
233
421
|
|
|
234
|
-
|
|
422
|
+
if image_path is not None:
|
|
423
|
+
return group_handler.get_group(image_path, create_mode=True)
|
|
424
|
+
return None
|
|
235
425
|
|
|
236
426
|
def atomic_add_image(
|
|
237
427
|
self,
|
|
@@ -242,7 +432,12 @@ class OmeZarrPlate:
|
|
|
242
432
|
acquisition_name: str | None = None,
|
|
243
433
|
) -> StoreOrGroup:
|
|
244
434
|
"""Parallel safe version of add_image."""
|
|
245
|
-
|
|
435
|
+
if image_path is None:
|
|
436
|
+
raise ValueError(
|
|
437
|
+
"Image path cannot be None for atomic add_image. "
|
|
438
|
+
"If your intent is to add a well, use add_well instead."
|
|
439
|
+
)
|
|
440
|
+
group = self._add_image(
|
|
246
441
|
row=row,
|
|
247
442
|
column=column,
|
|
248
443
|
image_path=image_path,
|
|
@@ -250,6 +445,12 @@ class OmeZarrPlate:
|
|
|
250
445
|
acquisition_name=acquisition_name,
|
|
251
446
|
atomic=True,
|
|
252
447
|
)
|
|
448
|
+
if group is None:
|
|
449
|
+
raise ValueError(
|
|
450
|
+
f"Some error occurred while adding image {image_path} "
|
|
451
|
+
f"to well {row}{column}."
|
|
452
|
+
)
|
|
453
|
+
return group
|
|
253
454
|
|
|
254
455
|
def add_image(
|
|
255
456
|
self,
|
|
@@ -260,7 +461,12 @@ class OmeZarrPlate:
|
|
|
260
461
|
acquisition_name: str | None = None,
|
|
261
462
|
) -> StoreOrGroup:
|
|
262
463
|
"""Add an image to an ome-zarr plate."""
|
|
263
|
-
|
|
464
|
+
if image_path is None:
|
|
465
|
+
raise ValueError(
|
|
466
|
+
"Image path cannot be None for atomic add_image. "
|
|
467
|
+
"If your intent is to add a well, use add_well instead."
|
|
468
|
+
)
|
|
469
|
+
group = self._add_image(
|
|
264
470
|
row=row,
|
|
265
471
|
column=column,
|
|
266
472
|
image_path=image_path,
|
|
@@ -268,6 +474,68 @@ class OmeZarrPlate:
|
|
|
268
474
|
acquisition_name=acquisition_name,
|
|
269
475
|
atomic=False,
|
|
270
476
|
)
|
|
477
|
+
if group is None:
|
|
478
|
+
raise ValueError(
|
|
479
|
+
f"Some error occurred while adding image {image_path} "
|
|
480
|
+
f"to well {row}{column}."
|
|
481
|
+
)
|
|
482
|
+
return group
|
|
483
|
+
|
|
484
|
+
def add_well(
|
|
485
|
+
self,
|
|
486
|
+
row: str,
|
|
487
|
+
column: int | str,
|
|
488
|
+
) -> OmeZarrWell:
|
|
489
|
+
"""Add a well to an ome-zarr plate."""
|
|
490
|
+
_ = self._add_image(
|
|
491
|
+
row=row,
|
|
492
|
+
column=column,
|
|
493
|
+
image_path=None,
|
|
494
|
+
acquisition_id=None,
|
|
495
|
+
acquisition_name=None,
|
|
496
|
+
atomic=False,
|
|
497
|
+
)
|
|
498
|
+
return self.get_well(row=row, column=column)
|
|
499
|
+
|
|
500
|
+
def add_column(
|
|
501
|
+
self,
|
|
502
|
+
column: int | str,
|
|
503
|
+
) -> "OmeZarrPlate":
|
|
504
|
+
"""Add a column to an ome-zarr plate."""
|
|
505
|
+
meta, _ = self.meta.add_column(column)
|
|
506
|
+
self.meta_handler.write_meta(meta)
|
|
507
|
+
self.meta_handler._group_handler.clean_cache()
|
|
508
|
+
return self
|
|
509
|
+
|
|
510
|
+
def add_row(
|
|
511
|
+
self,
|
|
512
|
+
row: str,
|
|
513
|
+
) -> "OmeZarrPlate":
|
|
514
|
+
"""Add a row to an ome-zarr plate."""
|
|
515
|
+
meta, _ = self.meta.add_row(row)
|
|
516
|
+
self.meta_handler.write_meta(meta)
|
|
517
|
+
self.meta_handler._group_handler.clean_cache()
|
|
518
|
+
return self
|
|
519
|
+
|
|
520
|
+
def add_acquisition(
|
|
521
|
+
self,
|
|
522
|
+
acquisition_id: int,
|
|
523
|
+
acquisition_name: str,
|
|
524
|
+
) -> "OmeZarrPlate":
|
|
525
|
+
"""Add an acquisition to an ome-zarr plate.
|
|
526
|
+
|
|
527
|
+
Be aware that this is not a parallel safe operation.
|
|
528
|
+
|
|
529
|
+
Args:
|
|
530
|
+
acquisition_id (int): The acquisition id.
|
|
531
|
+
acquisition_name (str): The acquisition name.
|
|
532
|
+
"""
|
|
533
|
+
meta = self.meta.add_acquisition(
|
|
534
|
+
acquisition_id=acquisition_id, acquisition_name=acquisition_name
|
|
535
|
+
)
|
|
536
|
+
self.meta_handler.write_meta(meta)
|
|
537
|
+
self.meta_handler._group_handler.clean_cache()
|
|
538
|
+
return self
|
|
271
539
|
|
|
272
540
|
def _remove_well(
|
|
273
541
|
self,
|
|
@@ -338,8 +606,40 @@ class OmeZarrPlate:
|
|
|
338
606
|
atomic=False,
|
|
339
607
|
)
|
|
340
608
|
|
|
609
|
+
def derive_plate(
|
|
610
|
+
self,
|
|
611
|
+
store: StoreOrGroup,
|
|
612
|
+
plate_name: str | None = None,
|
|
613
|
+
version: NgffVersions = "0.4",
|
|
614
|
+
keep_acquisitions: bool = False,
|
|
615
|
+
cache: bool = False,
|
|
616
|
+
overwrite: bool = False,
|
|
617
|
+
parallel_safe: bool = True,
|
|
618
|
+
) -> "OmeZarrPlate":
|
|
619
|
+
"""Derive a new OME-Zarr plate from an existing one.
|
|
341
620
|
|
|
342
|
-
|
|
621
|
+
Args:
|
|
622
|
+
store (StoreOrGroup): The Zarr store or group that stores the plate.
|
|
623
|
+
plate_name (str | None): The name of the new plate.
|
|
624
|
+
version (NgffVersion): The version of the new plate.
|
|
625
|
+
keep_acquisitions (bool): Whether to keep the acquisitions in the new plate.
|
|
626
|
+
cache (bool): Whether to use a cache for the zarr group metadata.
|
|
627
|
+
overwrite (bool): Whether to overwrite the existing plate.
|
|
628
|
+
parallel_safe (bool): Whether the group handler is parallel safe.
|
|
629
|
+
"""
|
|
630
|
+
return derive_ome_zarr_plate(
|
|
631
|
+
ome_zarr_plate=self,
|
|
632
|
+
store=store,
|
|
633
|
+
plate_name=plate_name,
|
|
634
|
+
version=version,
|
|
635
|
+
keep_acquisitions=keep_acquisitions,
|
|
636
|
+
cache=cache,
|
|
637
|
+
overwrite=overwrite,
|
|
638
|
+
parallel_safe=parallel_safe,
|
|
639
|
+
)
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def open_ome_zarr_plate(
|
|
343
643
|
store: StoreOrGroup,
|
|
344
644
|
cache: bool = False,
|
|
345
645
|
mode: AccessModeLiteral = "r+",
|
|
@@ -360,26 +660,42 @@ def open_omezarr_plate(
|
|
|
360
660
|
return OmeZarrPlate(group_handler)
|
|
361
661
|
|
|
362
662
|
|
|
663
|
+
def _create_empty_plate_from_meta(
|
|
664
|
+
store: StoreOrGroup,
|
|
665
|
+
meta: NgioPlateMeta,
|
|
666
|
+
version: NgffVersions = "0.4",
|
|
667
|
+
overwrite: bool = False,
|
|
668
|
+
) -> ZarrGroupHandler:
|
|
669
|
+
"""Create an empty OME-Zarr plate from metadata."""
|
|
670
|
+
mode = "w" if overwrite else "w-"
|
|
671
|
+
group_handler = ZarrGroupHandler(
|
|
672
|
+
store=store, cache=True, mode=mode, parallel_safe=False
|
|
673
|
+
)
|
|
674
|
+
meta_handler = get_plate_meta_handler(group_handler, version=version)
|
|
675
|
+
meta_handler.write_meta(meta)
|
|
676
|
+
return group_handler
|
|
677
|
+
|
|
678
|
+
|
|
363
679
|
def create_empty_plate(
|
|
364
680
|
store: StoreOrGroup,
|
|
365
681
|
name: str,
|
|
366
682
|
images: list[ImageInWellPath] | None = None,
|
|
367
|
-
version:
|
|
683
|
+
version: NgffVersions = "0.4",
|
|
368
684
|
cache: bool = False,
|
|
369
685
|
overwrite: bool = False,
|
|
370
686
|
parallel_safe: bool = True,
|
|
371
687
|
) -> OmeZarrPlate:
|
|
372
688
|
"""Initialize and create an empty OME-Zarr plate."""
|
|
373
|
-
mode = "w" if overwrite else "w-"
|
|
374
|
-
group_handler = ZarrGroupHandler(
|
|
375
|
-
store=store, cache=True, mode=mode, parallel_safe=False
|
|
376
|
-
)
|
|
377
|
-
meta_handler = get_plate_meta_handler(group_handler, version=version)
|
|
378
689
|
plate_meta = NgioPlateMeta.default_init(
|
|
379
690
|
name=name,
|
|
380
691
|
version=version,
|
|
381
692
|
)
|
|
382
|
-
|
|
693
|
+
group_handler = _create_empty_plate_from_meta(
|
|
694
|
+
store=store,
|
|
695
|
+
meta=plate_meta,
|
|
696
|
+
version=version,
|
|
697
|
+
overwrite=overwrite,
|
|
698
|
+
)
|
|
383
699
|
|
|
384
700
|
if images is not None:
|
|
385
701
|
plate = OmeZarrPlate(group_handler)
|
|
@@ -391,7 +707,102 @@ def create_empty_plate(
|
|
|
391
707
|
acquisition_id=image.acquisition_id,
|
|
392
708
|
acquisition_name=image.acquisition_name,
|
|
393
709
|
)
|
|
394
|
-
return
|
|
710
|
+
return open_ome_zarr_plate(
|
|
711
|
+
store=store,
|
|
712
|
+
cache=cache,
|
|
713
|
+
mode="r+",
|
|
714
|
+
parallel_safe=parallel_safe,
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
def derive_ome_zarr_plate(
|
|
719
|
+
ome_zarr_plate: OmeZarrPlate,
|
|
720
|
+
store: StoreOrGroup,
|
|
721
|
+
plate_name: str | None = None,
|
|
722
|
+
version: NgffVersions = "0.4",
|
|
723
|
+
keep_acquisitions: bool = False,
|
|
724
|
+
cache: bool = False,
|
|
725
|
+
overwrite: bool = False,
|
|
726
|
+
parallel_safe: bool = True,
|
|
727
|
+
) -> OmeZarrPlate:
|
|
728
|
+
"""Derive a new OME-Zarr plate from an existing one.
|
|
729
|
+
|
|
730
|
+
Args:
|
|
731
|
+
ome_zarr_plate (OmeZarrPlate): The existing OME-Zarr plate.
|
|
732
|
+
store (StoreOrGroup): The Zarr store or group that stores the plate.
|
|
733
|
+
plate_name (str | None): The name of the new plate.
|
|
734
|
+
version (NgffVersion): The version of the new plate.
|
|
735
|
+
keep_acquisitions (bool): Whether to keep the acquisitions in the new plate.
|
|
736
|
+
cache (bool): Whether to use a cache for the zarr group metadata.
|
|
737
|
+
overwrite (bool): Whether to overwrite the existing plate.
|
|
738
|
+
parallel_safe (bool): Whether the group handler is parallel safe.
|
|
739
|
+
"""
|
|
740
|
+
if plate_name is None:
|
|
741
|
+
plate_name = ome_zarr_plate.meta.plate.name
|
|
742
|
+
|
|
743
|
+
new_meta = ome_zarr_plate.meta.derive(
|
|
744
|
+
name=plate_name,
|
|
745
|
+
version=version,
|
|
746
|
+
keep_acquisitions=keep_acquisitions,
|
|
747
|
+
)
|
|
748
|
+
_ = _create_empty_plate_from_meta(
|
|
749
|
+
store=store,
|
|
750
|
+
meta=new_meta,
|
|
751
|
+
overwrite=overwrite,
|
|
752
|
+
version=version,
|
|
753
|
+
)
|
|
754
|
+
return open_ome_zarr_plate(
|
|
755
|
+
store=store,
|
|
756
|
+
cache=cache,
|
|
757
|
+
mode="r+",
|
|
758
|
+
parallel_safe=parallel_safe,
|
|
759
|
+
)
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
def open_ome_zarr_well(
|
|
763
|
+
store: StoreOrGroup,
|
|
764
|
+
cache: bool = False,
|
|
765
|
+
mode: AccessModeLiteral = "r+",
|
|
766
|
+
parallel_safe: bool = True,
|
|
767
|
+
) -> OmeZarrWell:
|
|
768
|
+
"""Open an OME-Zarr well.
|
|
769
|
+
|
|
770
|
+
Args:
|
|
771
|
+
store (StoreOrGroup): The Zarr store or group that stores the plate.
|
|
772
|
+
cache (bool): Whether to use a cache for the zarr group metadata.
|
|
773
|
+
mode (AccessModeLiteral): The access mode for the image. Defaults to "r+".
|
|
774
|
+
parallel_safe (bool): Whether the group handler is parallel safe.
|
|
775
|
+
"""
|
|
776
|
+
group_handler = ZarrGroupHandler(
|
|
777
|
+
store=store, cache=cache, mode=mode, parallel_safe=parallel_safe
|
|
778
|
+
)
|
|
779
|
+
return OmeZarrWell(group_handler)
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
def create_empty_well(
|
|
783
|
+
store: StoreOrGroup,
|
|
784
|
+
version: NgffVersions = "0.4",
|
|
785
|
+
cache: bool = False,
|
|
786
|
+
overwrite: bool = False,
|
|
787
|
+
parallel_safe: bool = True,
|
|
788
|
+
) -> OmeZarrWell:
|
|
789
|
+
"""Create an empty OME-Zarr well.
|
|
790
|
+
|
|
791
|
+
Args:
|
|
792
|
+
store (StoreOrGroup): The Zarr store or group that stores the well.
|
|
793
|
+
version (NgffVersion): The version of the new well.
|
|
794
|
+
cache (bool): Whether to use a cache for the zarr group metadata.
|
|
795
|
+
overwrite (bool): Whether to overwrite the existing well.
|
|
796
|
+
parallel_safe (bool): Whether the group handler is parallel safe.
|
|
797
|
+
"""
|
|
798
|
+
group_handler = ZarrGroupHandler(
|
|
799
|
+
store=store, cache=True, mode="w" if overwrite else "w-", parallel_safe=False
|
|
800
|
+
)
|
|
801
|
+
meta_handler = get_well_meta_handler(group_handler, version=version)
|
|
802
|
+
meta = NgioWellMeta.default_init()
|
|
803
|
+
meta_handler.write_meta(meta)
|
|
804
|
+
|
|
805
|
+
return open_ome_zarr_well(
|
|
395
806
|
store=store,
|
|
396
807
|
cache=cache,
|
|
397
808
|
mode="r+",
|