ngio 0.2.2__py3-none-any.whl → 0.2.3__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/common/_pyramid.py +5 -1
- ngio/hcs/plate.py +121 -2
- ngio/images/abstract_image.py +1 -0
- ngio/images/image.py +42 -0
- ngio/images/label.py +15 -7
- ngio/images/ome_zarr_container.py +4 -7
- ngio/tables/_validators.py +1 -83
- ngio/tables/backends/__init__.py +27 -1
- ngio/tables/backends/_abstract_backend.py +207 -22
- ngio/tables/backends/_anndata_utils.py +3 -109
- ngio/tables/backends/_anndata_v1.py +43 -46
- ngio/tables/backends/_csv_v1.py +162 -0
- ngio/tables/backends/_json_v1.py +54 -18
- ngio/tables/backends/_table_backends.py +98 -18
- ngio/tables/backends/_utils.py +458 -0
- ngio/tables/tables_container.py +3 -1
- ngio/tables/v1/_feature_table.py +20 -11
- ngio/tables/v1/_generic_table.py +20 -15
- ngio/tables/v1/_roi_table.py +7 -9
- ngio/utils/_zarr_utils.py +46 -32
- {ngio-0.2.2.dist-info → ngio-0.2.3.dist-info}/METADATA +3 -1
- {ngio-0.2.2.dist-info → ngio-0.2.3.dist-info}/RECORD +24 -22
- {ngio-0.2.2.dist-info → ngio-0.2.3.dist-info}/WHEEL +0 -0
- {ngio-0.2.2.dist-info → ngio-0.2.3.dist-info}/licenses/LICENSE +0 -0
ngio/utils/_zarr_utils.py
CHANGED
|
@@ -8,7 +8,7 @@ import fsspec
|
|
|
8
8
|
import zarr
|
|
9
9
|
from filelock import BaseFileLock, FileLock
|
|
10
10
|
from zarr.errors import ContainsGroupError, GroupNotFoundError
|
|
11
|
-
from zarr.storage import DirectoryStore, FSStore, Store
|
|
11
|
+
from zarr.storage import DirectoryStore, FSStore, MemoryStore, Store, StoreLike
|
|
12
12
|
|
|
13
13
|
from ngio.utils import NgioFileExistsError, NgioFileNotFoundError, NgioValueError
|
|
14
14
|
from ngio.utils._errors import NgioError
|
|
@@ -17,7 +17,9 @@ AccessModeLiteral = Literal["r", "r+", "w", "w-", "a"]
|
|
|
17
17
|
# StoreLike is more restrictive than it could be
|
|
18
18
|
# but to make sure we can handle the store correctly
|
|
19
19
|
# we need to be more restrictive
|
|
20
|
-
NgioSupportedStore =
|
|
20
|
+
NgioSupportedStore = (
|
|
21
|
+
str | Path | fsspec.mapping.FSMap | FSStore | DirectoryStore | MemoryStore
|
|
22
|
+
)
|
|
21
23
|
GenericStore = Store | NgioSupportedStore
|
|
22
24
|
StoreOrGroup = GenericStore | zarr.Group
|
|
23
25
|
|
|
@@ -48,9 +50,7 @@ def _check_group(group: zarr.Group, mode: AccessModeLiteral) -> zarr.Group:
|
|
|
48
50
|
return group
|
|
49
51
|
|
|
50
52
|
|
|
51
|
-
def open_group_wrapper(
|
|
52
|
-
store: StoreOrGroup, mode: AccessModeLiteral
|
|
53
|
-
) -> tuple[zarr.Group, NgioSupportedStore]:
|
|
53
|
+
def open_group_wrapper(store: StoreOrGroup, mode: AccessModeLiteral) -> zarr.Group:
|
|
54
54
|
"""Wrapper around zarr.open_group with some additional checks.
|
|
55
55
|
|
|
56
56
|
Args:
|
|
@@ -62,18 +62,11 @@ def open_group_wrapper(
|
|
|
62
62
|
"""
|
|
63
63
|
if isinstance(store, zarr.Group):
|
|
64
64
|
group = _check_group(store, mode)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if isinstance(group.store, DirectoryStore):
|
|
68
|
-
_store = group.store.path
|
|
69
|
-
else:
|
|
70
|
-
_store = group.store
|
|
71
|
-
|
|
72
|
-
_store = _check_store(_store)
|
|
73
|
-
return group, _store
|
|
65
|
+
_check_store(group.store)
|
|
66
|
+
return group
|
|
74
67
|
|
|
75
68
|
try:
|
|
76
|
-
|
|
69
|
+
_check_store(store)
|
|
77
70
|
group = zarr.open_group(store=store, mode=mode)
|
|
78
71
|
|
|
79
72
|
except ContainsGroupError as e:
|
|
@@ -84,7 +77,7 @@ def open_group_wrapper(
|
|
|
84
77
|
except GroupNotFoundError as e:
|
|
85
78
|
raise NgioFileNotFoundError(f"No Zarr group found at {store}") from e
|
|
86
79
|
|
|
87
|
-
return group
|
|
80
|
+
return group
|
|
88
81
|
|
|
89
82
|
|
|
90
83
|
class ZarrGroupHandler:
|
|
@@ -119,27 +112,29 @@ class ZarrGroupHandler:
|
|
|
119
112
|
"If you want to use the lock mechanism, you should not use the cache."
|
|
120
113
|
)
|
|
121
114
|
|
|
122
|
-
|
|
115
|
+
group = open_group_wrapper(store, mode)
|
|
116
|
+
_store = group.store
|
|
123
117
|
|
|
124
118
|
# Make sure the cache is set in the attrs
|
|
125
119
|
# in the same way as the cache in the handler
|
|
126
|
-
|
|
120
|
+
group.attrs.cache = cache
|
|
127
121
|
|
|
128
122
|
if parallel_safe:
|
|
129
|
-
if not isinstance(_store,
|
|
123
|
+
if not isinstance(_store, DirectoryStore):
|
|
130
124
|
raise NgioValueError(
|
|
131
|
-
"The store needs to be a
|
|
125
|
+
"The store needs to be a DirectoryStore to use the lock mechanism. "
|
|
126
|
+
f"Instead, got {_store.__class__.__name__}."
|
|
132
127
|
)
|
|
133
|
-
|
|
128
|
+
store_path = Path(_store.path) / group.path
|
|
129
|
+
self._lock_path = store_path.with_suffix(".lock")
|
|
134
130
|
self._lock = FileLock(self._lock_path, timeout=10)
|
|
135
131
|
|
|
136
132
|
else:
|
|
137
133
|
self._lock_path = None
|
|
138
134
|
self._lock = None
|
|
139
135
|
|
|
140
|
-
self._group =
|
|
136
|
+
self._group = group
|
|
141
137
|
self._mode = mode
|
|
142
|
-
self._store = _store
|
|
143
138
|
self.use_cache = cache
|
|
144
139
|
self._parallel_safe = parallel_safe
|
|
145
140
|
self._cache = {}
|
|
@@ -148,19 +143,23 @@ class ZarrGroupHandler:
|
|
|
148
143
|
def __repr__(self) -> str:
|
|
149
144
|
"""Return a string representation of the handler."""
|
|
150
145
|
return (
|
|
151
|
-
f"ZarrGroupHandler(
|
|
146
|
+
f"ZarrGroupHandler(full_url={self.full_url}, mode={self.mode}, "
|
|
152
147
|
f"cache={self.use_cache}"
|
|
153
148
|
)
|
|
154
149
|
|
|
155
150
|
@property
|
|
156
|
-
def store(self) ->
|
|
151
|
+
def store(self) -> StoreLike:
|
|
157
152
|
"""Return the store of the group."""
|
|
158
|
-
return self.
|
|
153
|
+
return self.group.store
|
|
159
154
|
|
|
160
155
|
@property
|
|
161
|
-
def
|
|
156
|
+
def full_url(self) -> str | None:
|
|
162
157
|
"""Return the store path."""
|
|
163
|
-
|
|
158
|
+
if isinstance(self.store, DirectoryStore | FSStore):
|
|
159
|
+
_store_path = str(self.store.path)
|
|
160
|
+
_store_path = _store_path.rstrip("/")
|
|
161
|
+
return f"{self.store.path}/{self._group.path}"
|
|
162
|
+
return None
|
|
164
163
|
|
|
165
164
|
@property
|
|
166
165
|
def mode(self) -> AccessModeLiteral:
|
|
@@ -275,17 +274,25 @@ class ZarrGroupHandler:
|
|
|
275
274
|
self,
|
|
276
275
|
path: str,
|
|
277
276
|
create_mode: bool = False,
|
|
277
|
+
overwrite: bool = False,
|
|
278
278
|
) -> zarr.Group:
|
|
279
279
|
"""Get a group from the group.
|
|
280
280
|
|
|
281
281
|
Args:
|
|
282
282
|
path (str): The path to the group.
|
|
283
283
|
create_mode (bool): If True, create the group if it does not exist.
|
|
284
|
+
overwrite (bool): If True, overwrite the group if it exists.
|
|
284
285
|
|
|
285
286
|
Returns:
|
|
286
287
|
zarr.Group: The Zarr group.
|
|
287
288
|
|
|
288
289
|
"""
|
|
290
|
+
if overwrite and not create_mode:
|
|
291
|
+
raise NgioValueError("Cannot overwrite a group without create_mode=True.")
|
|
292
|
+
|
|
293
|
+
if overwrite:
|
|
294
|
+
return self.create_group(path, overwrite=overwrite)
|
|
295
|
+
|
|
289
296
|
group = self._obj_get(path)
|
|
290
297
|
if isinstance(group, zarr.Group):
|
|
291
298
|
return group
|
|
@@ -361,9 +368,15 @@ class ZarrGroupHandler:
|
|
|
361
368
|
def derive_handler(
|
|
362
369
|
self,
|
|
363
370
|
path: str,
|
|
371
|
+
overwrite: bool = False,
|
|
364
372
|
) -> "ZarrGroupHandler":
|
|
365
|
-
"""Derive a new handler from the current handler.
|
|
366
|
-
|
|
373
|
+
"""Derive a new handler from the current handler.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
path (str): The path to the group.
|
|
377
|
+
overwrite (bool): If True, overwrite the group if it exists.
|
|
378
|
+
"""
|
|
379
|
+
group = self.get_group(path, create_mode=True, overwrite=overwrite)
|
|
367
380
|
return ZarrGroupHandler(
|
|
368
381
|
store=group,
|
|
369
382
|
cache=self.use_cache,
|
|
@@ -375,10 +388,11 @@ class ZarrGroupHandler:
|
|
|
375
388
|
def safe_derive_handler(
|
|
376
389
|
self,
|
|
377
390
|
path: str,
|
|
391
|
+
overwrite: bool = False,
|
|
378
392
|
) -> tuple[bool, "ZarrGroupHandler | NgioError"]:
|
|
379
393
|
"""Derive a new handler from the current handler."""
|
|
380
394
|
try:
|
|
381
|
-
return True, self.derive_handler(path)
|
|
395
|
+
return True, self.derive_handler(path, overwrite=overwrite)
|
|
382
396
|
except NgioError as e:
|
|
383
397
|
return False, e
|
|
384
398
|
|
|
@@ -393,7 +407,7 @@ class ZarrGroupHandler:
|
|
|
393
407
|
)
|
|
394
408
|
if n_skipped > 0:
|
|
395
409
|
raise NgioValueError(
|
|
396
|
-
f"Error copying group to {handler.
|
|
410
|
+
f"Error copying group to {handler.full_url}, "
|
|
397
411
|
f"#{n_skipped} files where skipped."
|
|
398
412
|
)
|
|
399
413
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ngio
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Next Generation file format IO
|
|
5
5
|
Project-URL: homepage, https://github.com/lorenzocerrone/ngio
|
|
6
6
|
Project-URL: repository, https://github.com/lorenzocerrone/ngio
|
|
@@ -23,7 +23,9 @@ Requires-Dist: filelock
|
|
|
23
23
|
Requires-Dist: numpy
|
|
24
24
|
Requires-Dist: ome-zarr-models
|
|
25
25
|
Requires-Dist: pandas>=1.2.0
|
|
26
|
+
Requires-Dist: polars
|
|
26
27
|
Requires-Dist: pooch
|
|
28
|
+
Requires-Dist: pyarrow
|
|
27
29
|
Requires-Dist: pydantic
|
|
28
30
|
Requires-Dist: requests
|
|
29
31
|
Requires-Dist: xarray
|
|
@@ -5,19 +5,19 @@ ngio/common/_axes_transforms.py,sha256=kWU0M5erNmgWBXdu5LNv-tLW3jqkT00MMYX7cz-ky
|
|
|
5
5
|
ngio/common/_common_types.py,sha256=OkAYNSNjZkixL1MI-HPBVuXamheFBr862uJ4PvTxmhk,129
|
|
6
6
|
ngio/common/_dimensions.py,sha256=UV2XulWaROb3Y2f4fv27ZkTIu-MoS53U26aDkrv-_lk,3900
|
|
7
7
|
ngio/common/_masking_roi.py,sha256=-o6meGP17iTXEbkO9aGh1VX2drkc2laIcRJvCy_pRRM,4919
|
|
8
|
-
ngio/common/_pyramid.py,sha256=
|
|
8
|
+
ngio/common/_pyramid.py,sha256=SJzPauuduuqcm9B7nFCJhMTzIg6Knjsnp4CY4lN61Is,7411
|
|
9
9
|
ngio/common/_roi.py,sha256=dq1iVT8-G_zWuxcYWJeHfviBSbPgsyKUcDL3Vg6jx6I,5122
|
|
10
10
|
ngio/common/_slicer.py,sha256=AKpwXRncOmF9nhjKYma0C_41WqAgSv860beKGx-aw-0,3075
|
|
11
11
|
ngio/common/_zoom.py,sha256=KsURa5VuixmpbAAY5-6obmuQV8vfiHKZqBxZDXvchpM,5473
|
|
12
12
|
ngio/hcs/__init__.py,sha256=5oAYT_454WGhms97kxo8gS4_rKHtFf_x-9uu8M_VeVM,356
|
|
13
|
-
ngio/hcs/plate.py,sha256=
|
|
13
|
+
ngio/hcs/plate.py,sha256=MK-HTuSyxt2dp1CuA9tvSwRc9VWEjDz4Pju-2dxXQf4,30102
|
|
14
14
|
ngio/images/__init__.py,sha256=DYbXAdBgPxyjBRdJrWvU0UnBRI0gUMmx9KaJ-Bucvz4,533
|
|
15
|
-
ngio/images/abstract_image.py,sha256=
|
|
15
|
+
ngio/images/abstract_image.py,sha256=8PNQPZjiDz-pcTFXSJAVw7nUr4yL_iRwqDEUTKkAnp0,10266
|
|
16
16
|
ngio/images/create.py,sha256=XYn30m_2OSZeHHASYHc3eK9u_gZIYy9wo6mGdRGaq5c,9473
|
|
17
|
-
ngio/images/image.py,sha256=
|
|
18
|
-
ngio/images/label.py,sha256=
|
|
17
|
+
ngio/images/image.py,sha256=mKLIR2DGQUWtQbf3my2fh0bEPkbbsabUoge_XJPhfWE,17824
|
|
18
|
+
ngio/images/label.py,sha256=qgbBHFPGYpUR2fHf1OiXZh4sn0FgCeeWwH1F4SrOM1c,10460
|
|
19
19
|
ngio/images/masked_image.py,sha256=IBo8x2jHyXBXn7ORo8fSiwBPjV_1JOTb_vatjKNxbJ0,8531
|
|
20
|
-
ngio/images/ome_zarr_container.py,sha256=
|
|
20
|
+
ngio/images/ome_zarr_container.py,sha256=5tgUd1iq2nQOmWsIZY-kwVR1d5UV4rKlVEXTslDBCno,28520
|
|
21
21
|
ngio/ome_zarr_meta/__init__.py,sha256=oZ8PEsWM7U0KwzpsnvVfX9k4UfuTz5sZ8B6B9eY5hyY,1193
|
|
22
22
|
ngio/ome_zarr_meta/_meta_handlers.py,sha256=BLvYt5PONYrWkEb2XgEiAXR_OX9rfeX_C0eEqen0jQA,25549
|
|
23
23
|
ngio/ome_zarr_meta/ngio_specs/__init__.py,sha256=05NQukZG0nNvjzf8AKWGu7PhjhQcImGSAOK3D3Bg-Js,1786
|
|
@@ -31,25 +31,27 @@ ngio/ome_zarr_meta/v04/__init__.py,sha256=dJRzzxyYc81kf-0Hip_bqvbdManaM8XTdQX2me
|
|
|
31
31
|
ngio/ome_zarr_meta/v04/_custom_models.py,sha256=5GxiDERvLuvq4QvApcA6EiKLS6hLFX1R0R_9rSaa85A,530
|
|
32
32
|
ngio/ome_zarr_meta/v04/_v04_spec_utils.py,sha256=05tEr2eEP_XVIfBMOAWLT7lzJV4KS5eYrpK8l94tn3w,15876
|
|
33
33
|
ngio/tables/__init__.py,sha256=gxvNvAgLePgrngOm06H5qU50Axc6boeIs5iCfrmqTi0,609
|
|
34
|
-
ngio/tables/_validators.py,sha256=
|
|
35
|
-
ngio/tables/tables_container.py,sha256=
|
|
36
|
-
ngio/tables/backends/__init__.py,sha256=
|
|
37
|
-
ngio/tables/backends/_abstract_backend.py,sha256
|
|
38
|
-
ngio/tables/backends/_anndata_utils.py,sha256=
|
|
39
|
-
ngio/tables/backends/_anndata_v1.py,sha256=
|
|
40
|
-
ngio/tables/backends/
|
|
41
|
-
ngio/tables/backends/
|
|
34
|
+
ngio/tables/_validators.py,sha256=7Eqln9j1tWmNakSCnryy2q39SbTuk6V31O2iMByTWWw,3363
|
|
35
|
+
ngio/tables/tables_container.py,sha256=Jt9FNjWU9EPbb4L9pKhLIuzDcr_gCkTEoRN5Wt-vOjw,9888
|
|
36
|
+
ngio/tables/backends/__init__.py,sha256=Y9MIFefwUaSmhhv5FDZFn7jBdYXDML2FovO-uK-vxgI,936
|
|
37
|
+
ngio/tables/backends/_abstract_backend.py,sha256=--4qeVHs4YRo5i5XsREmDm6BxMsQ5tIqc6XZ810GJno,8776
|
|
38
|
+
ngio/tables/backends/_anndata_utils.py,sha256=DBWIcR0btnH-DIvDvzlcnMXoYhhtXc9DstryiOP0Qsg,3122
|
|
39
|
+
ngio/tables/backends/_anndata_v1.py,sha256=5p_8pWUkYM4rEhm7g-b2yCXt2mmyd6lFisc1ubksAio,2469
|
|
40
|
+
ngio/tables/backends/_csv_v1.py,sha256=o5AGlBH3UQdXx6MP2DtMm7zmXkOwnBBzu5TKk-QgQdI,5847
|
|
41
|
+
ngio/tables/backends/_json_v1.py,sha256=7ALjB2thKTxPBeYOleqn2LNuAy6erp0Nzd-GZ9Xcd4Y,3079
|
|
42
|
+
ngio/tables/backends/_table_backends.py,sha256=NXdH4pxo9XWZ_YxC5RVaw4PTOg-do30c3vlIy8KG4vQ,5831
|
|
43
|
+
ngio/tables/backends/_utils.py,sha256=Q1Twe-knhg5b5LHKKSiwppT9lhCPE9-NWb6o1boD7ao,14557
|
|
42
44
|
ngio/tables/v1/__init__.py,sha256=XWi6f_KbjbX45Ku-7uymJRSTVWyFAPAAEp_TXDeZV4s,314
|
|
43
|
-
ngio/tables/v1/_feature_table.py,sha256=
|
|
44
|
-
ngio/tables/v1/_generic_table.py,sha256=
|
|
45
|
-
ngio/tables/v1/_roi_table.py,sha256=
|
|
45
|
+
ngio/tables/v1/_feature_table.py,sha256=2pZEENyZAmn_Awezu8VLGq90d-J7aXd6Ry8gNNR0wAQ,6104
|
|
46
|
+
ngio/tables/v1/_generic_table.py,sha256=O2fu8k_TjhWEZtJxlU3Uj7ZTZnc75vLlvjw5lweSnd8,5710
|
|
47
|
+
ngio/tables/v1/_roi_table.py,sha256=9kVLKzXz2gGrTmPC_sR3Zc6cX5VVROHYEjOJ-0Ol08g,11248
|
|
46
48
|
ngio/utils/__init__.py,sha256=r3nuLWgp6-cQlS4ODjYSBrfgdTLkCOVke9jKbn1NpkA,1129
|
|
47
49
|
ngio/utils/_datasets.py,sha256=EdYJHIifpRou4f43dIuiKsdxe4K6FaeS4f1_e_EYrcI,1727
|
|
48
50
|
ngio/utils/_errors.py,sha256=pKQ12LUjQLYE1nUawemA5h7HsgznjaSvV1n2PQU33N0,759
|
|
49
51
|
ngio/utils/_fractal_fsspec_store.py,sha256=7qoGLiLi8JQFh9Ej_z5WNwQQuWrujb0f6p9nj8ocsS8,548
|
|
50
52
|
ngio/utils/_logger.py,sha256=HIuqD_2ShfFGDswBddcouStbKfL0Vz_ah8cAIFGhbS8,888
|
|
51
|
-
ngio/utils/_zarr_utils.py,sha256=
|
|
52
|
-
ngio-0.2.
|
|
53
|
-
ngio-0.2.
|
|
54
|
-
ngio-0.2.
|
|
55
|
-
ngio-0.2.
|
|
53
|
+
ngio/utils/_zarr_utils.py,sha256=qOI-HL2HsfFLCj_yxsTR-aq4oHpSqS9KR13aEIvhGDY,13593
|
|
54
|
+
ngio-0.2.3.dist-info/METADATA,sha256=8q0VoG887uE9DmawKNHljCbGcXPsqjr4_Tp8nrHAK5A,5215
|
|
55
|
+
ngio-0.2.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
56
|
+
ngio-0.2.3.dist-info/licenses/LICENSE,sha256=UgN_a1QCeNh9rZWfz-wORQFxE3elQzLWPQaoK6N6fxQ,1502
|
|
57
|
+
ngio-0.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|