ngio 0.4.8__py3-none-any.whl → 0.5.0__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.
Files changed (56) hide show
  1. ngio/__init__.py +5 -2
  2. ngio/common/__init__.py +11 -6
  3. ngio/common/_masking_roi.py +34 -54
  4. ngio/common/_pyramid.py +322 -75
  5. ngio/common/_roi.py +258 -330
  6. ngio/experimental/iterators/_feature.py +3 -3
  7. ngio/experimental/iterators/_rois_utils.py +10 -11
  8. ngio/hcs/_plate.py +192 -136
  9. ngio/images/_abstract_image.py +539 -35
  10. ngio/images/_create_synt_container.py +45 -47
  11. ngio/images/_create_utils.py +406 -0
  12. ngio/images/_image.py +524 -248
  13. ngio/images/_label.py +257 -180
  14. ngio/images/_masked_image.py +2 -2
  15. ngio/images/_ome_zarr_container.py +658 -255
  16. ngio/io_pipes/_io_pipes.py +9 -9
  17. ngio/io_pipes/_io_pipes_masked.py +7 -7
  18. ngio/io_pipes/_io_pipes_roi.py +6 -6
  19. ngio/io_pipes/_io_pipes_types.py +3 -3
  20. ngio/io_pipes/_match_shape.py +6 -8
  21. ngio/io_pipes/_ops_slices_utils.py +8 -5
  22. ngio/ome_zarr_meta/__init__.py +29 -18
  23. ngio/ome_zarr_meta/_meta_handlers.py +402 -689
  24. ngio/ome_zarr_meta/ngio_specs/__init__.py +4 -0
  25. ngio/ome_zarr_meta/ngio_specs/_axes.py +152 -51
  26. ngio/ome_zarr_meta/ngio_specs/_dataset.py +13 -22
  27. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +129 -91
  28. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +69 -69
  29. ngio/ome_zarr_meta/v04/__init__.py +5 -1
  30. ngio/ome_zarr_meta/v04/{_v04_spec_utils.py → _v04_spec.py} +55 -86
  31. ngio/ome_zarr_meta/v05/__init__.py +27 -0
  32. ngio/ome_zarr_meta/v05/_custom_models.py +18 -0
  33. ngio/ome_zarr_meta/v05/_v05_spec.py +495 -0
  34. ngio/resources/__init__.py +1 -1
  35. ngio/resources/resource_model.py +1 -1
  36. ngio/tables/_tables_container.py +82 -24
  37. ngio/tables/backends/_abstract_backend.py +7 -0
  38. ngio/tables/backends/_anndata.py +60 -7
  39. ngio/tables/backends/_anndata_utils.py +2 -4
  40. ngio/tables/backends/_csv.py +3 -19
  41. ngio/tables/backends/_json.py +10 -13
  42. ngio/tables/backends/_parquet.py +3 -31
  43. ngio/tables/backends/_py_arrow_backends.py +222 -0
  44. ngio/tables/backends/_utils.py +1 -1
  45. ngio/tables/v1/_roi_table.py +41 -24
  46. ngio/utils/__init__.py +8 -12
  47. ngio/utils/_cache.py +48 -0
  48. ngio/utils/_zarr_utils.py +354 -236
  49. {ngio-0.4.8.dist-info → ngio-0.5.0.dist-info}/METADATA +12 -5
  50. ngio-0.5.0.dist-info/RECORD +88 -0
  51. ngio/images/_create.py +0 -276
  52. ngio/tables/backends/_non_zarr_backends.py +0 -196
  53. ngio/utils/_logger.py +0 -50
  54. ngio-0.4.8.dist-info/RECORD +0 -85
  55. {ngio-0.4.8.dist-info → ngio-0.5.0.dist-info}/WHEEL +0 -0
  56. {ngio-0.4.8.dist-info → ngio-0.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngio
3
- Version: 0.4.8
3
+ Version: 0.5.0
4
4
  Summary: Next Generation file format IO
5
5
  Project-URL: homepage, https://github.com/BioVisionCenter/ngio
6
6
  Project-URL: repository, https://github.com/BioVisionCenter/ngio
@@ -13,10 +13,11 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
16
17
  Classifier: Typing :: Typed
17
- Requires-Python: <3.14,>=3.11
18
+ Requires-Python: <3.15,>=3.11
18
19
  Requires-Dist: aiohttp
19
- Requires-Dist: anndata<0.11.4,>=0.8.0
20
+ Requires-Dist: anndata
20
21
  Requires-Dist: dask[array]<2025.11.0
21
22
  Requires-Dist: dask[distributed]<2025.11.0
22
23
  Requires-Dist: filelock
@@ -29,9 +30,8 @@ Requires-Dist: pooch
29
30
  Requires-Dist: pyarrow
30
31
  Requires-Dist: pydantic
31
32
  Requires-Dist: requests
32
- Requires-Dist: zarr<3
33
+ Requires-Dist: zarr>3
33
34
  Provides-Extra: dev
34
- Requires-Dist: devtools; extra == 'dev'
35
35
  Requires-Dist: matplotlib; extra == 'dev'
36
36
  Requires-Dist: mypy; extra == 'dev'
37
37
  Requires-Dist: napari; extra == 'dev'
@@ -43,6 +43,7 @@ Requires-Dist: pyqt5; extra == 'dev'
43
43
  Requires-Dist: rich; extra == 'dev'
44
44
  Requires-Dist: ruff; extra == 'dev'
45
45
  Requires-Dist: scikit-image; extra == 'dev'
46
+ Requires-Dist: zarrs; extra == 'dev'
46
47
  Provides-Extra: docs
47
48
  Requires-Dist: griffe-typingdoc; extra == 'docs'
48
49
  Requires-Dist: markdown-exec[ansi]; extra == 'docs'
@@ -57,11 +58,17 @@ Requires-Dist: mkdocs-jupyter; extra == 'docs'
57
58
  Requires-Dist: mkdocs-material; extra == 'docs'
58
59
  Requires-Dist: mkdocstrings[python]; extra == 'docs'
59
60
  Requires-Dist: rich; extra == 'docs'
61
+ Requires-Dist: ruff; extra == 'docs'
60
62
  Requires-Dist: scikit-image; extra == 'docs'
61
63
  Requires-Dist: tabulate; extra == 'docs'
62
64
  Provides-Extra: test
65
+ Requires-Dist: boto; extra == 'test'
66
+ Requires-Dist: devtools; extra == 'test'
67
+ Requires-Dist: moto[server]; extra == 'test'
63
68
  Requires-Dist: pytest; extra == 'test'
64
69
  Requires-Dist: pytest-cov; extra == 'test'
70
+ Requires-Dist: pytest-httpserver; extra == 'test'
71
+ Requires-Dist: s3fs; extra == 'test'
65
72
  Requires-Dist: scikit-image; extra == 'test'
66
73
  Description-Content-Type: text/markdown
67
74
 
@@ -0,0 +1,88 @@
1
+ ngio/__init__.py,sha256=kyInohhWrBs4qkbMYFIQeAiy1CDpvbSOtXB4buFocbw,1535
2
+ ngio/common/__init__.py,sha256=F3zAHQIhwig1xUA-SpmFVRtMeOrEj926-nHWhj-wS6c,684
3
+ ngio/common/_dimensions.py,sha256=w8PYgyWxA8hgJETjFbw5CXf7WrasCL5FbzgfL1in86M,11361
4
+ ngio/common/_masking_roi.py,sha256=-2IzQvaIpdgAxS8LY3DRb-Eax5efX6H0OhV7lNVdL1E,5202
5
+ ngio/common/_pyramid.py,sha256=7kbvCY4J0hLl_iV5oT267j_h3UTkbqIdltqHcrwicvw,17571
6
+ ngio/common/_roi.py,sha256=IM0rYaekNvEDSMctYbAEZkeG9iPaJ1qjtnJ9kOVV8as,11416
7
+ ngio/common/_synt_images_utils.py,sha256=B6uYOW1NyrM06YMR-csca3_YnAAkPRTbvnbLdy9tk9E,3188
8
+ ngio/common/_zoom.py,sha256=U01c-vqXjzZkrpd9Yvs24frVfTls_xPJeeaFCGmUwYI,6727
9
+ ngio/experimental/__init__.py,sha256=3pmBtHi-i8bKjTsvrOJM56ZyRX3Pv_dceCdt88-8COQ,147
10
+ ngio/experimental/iterators/__init__.py,sha256=TECOMGb5PEEZ0yXxt8pqIGvLKG41g_L1fTJU-zGPeV8,488
11
+ ngio/experimental/iterators/_abstract_iterator.py,sha256=7aAoMI-6vYGCMKxO3M10WpuBMTdqX4zr0K-TutAOp88,13195
12
+ ngio/experimental/iterators/_feature.py,sha256=OnqeSP-UMWku7AIBcutsDsAWqnFqPrjCJiMvMGM96fk,6714
13
+ ngio/experimental/iterators/_image_processing.py,sha256=cM7sL7xgdcjSOKAu-6367Aov89o6wgiJ_wqCGkU2Bsw,5091
14
+ ngio/experimental/iterators/_mappers.py,sha256=VVVsjems57wJUnWeufUFcgqa23k7VPeFL4Nc04HVw4o,1399
15
+ ngio/experimental/iterators/_rois_utils.py,sha256=5foGjt3qrACNrO29LlvSUbJ4yfI0z6MhU2oVCzEU214,4363
16
+ ngio/experimental/iterators/_segmentation.py,sha256=xzotGvTn04HPeMeXZ_URnQqWco6d2lH6Ng6vkCUh9NM,9153
17
+ ngio/hcs/__init__.py,sha256=G8j9vD-liLeB_UeGtKYIgshWvJnUA6ks9GwjvWBLdHs,357
18
+ ngio/hcs/_plate.py,sha256=-dFlUuB4DbzR-A5OONafiIGaTpasd9uybRybNgGDFPQ,46118
19
+ ngio/images/__init__.py,sha256=9Whvt7GTiCgT_vXaEEqGnDaY1-UsRk3dhLTv091F_g4,1211
20
+ ngio/images/_abstract_image.py,sha256=YUBLCqLOWD_9BlwhoVqNc6ISdmmqP1DUbZKn_sk8DJU,36022
21
+ ngio/images/_create_synt_container.py,sha256=4hZa0wKfI5RL30vsPE841SCVhWNb9Kj8kJiaTsD-0BA,5399
22
+ ngio/images/_create_utils.py,sha256=CxRO-b0_vyL27jMg6koXlt9vFNU1lmqKIWOU5ypAtvg,13811
23
+ ngio/images/_image.py,sha256=Ei2_bqsLg7q1rhjDIKusXqSdqhar8Ojsd6mYZ9ar6GI,45558
24
+ ngio/images/_label.py,sha256=iC9XPyM5SOWcI3Z3PZ0M1RUUCCUbBQ98zdrchva00Jw,16002
25
+ ngio/images/_masked_image.py,sha256=25BFnEHTqWdq5ImLs6dbo_X-ryGLIL7vJ2mmbx4Npv8,18834
26
+ ngio/images/_ome_zarr_container.py,sha256=ddcDRGhmJoyg47NHFaoNLZuWfXpLfNkZtP-hzLWWBIQ,56100
27
+ ngio/images/_table_ops.py,sha256=jFv_AMqoB4JBpoWsMtZppZVW7dAOC_u-JpfNm8b33kY,15292
28
+ ngio/io_pipes/__init__.py,sha256=arW_7GWzZs82kPNKdm_6B1sIDFV0lWwp-ZaORr9Q1FQ,2412
29
+ ngio/io_pipes/_io_pipes.py,sha256=l85mmjj1l0uYU3qzsSHg9l8cMIEevInm_MTD-8MlXgw,10603
30
+ ngio/io_pipes/_io_pipes_masked.py,sha256=uvfNIuW8prWux3fZ-a25l44zDfZW4qBaXZEm0TkhloA,16916
31
+ ngio/io_pipes/_io_pipes_roi.py,sha256=HJHlItx2nsFYcE4OjvVR-W0lFMMK8CcyYK23dKUrP8w,4472
32
+ ngio/io_pipes/_io_pipes_types.py,sha256=PcRdnjBJIsXcDT1_dbH2LZiH6d3z6D7y48cmybyZCXk,1358
33
+ ngio/io_pipes/_match_shape.py,sha256=sCAhJHzlqZwnz1MmwFCUQkH_6rohMSNwPCAmCuDElEA,13002
34
+ ngio/io_pipes/_ops_axes.py,sha256=Geg4ZXxB0njWWopX9YeiwRJJ9Ef2GKfG0NIUafOmi2c,10043
35
+ ngio/io_pipes/_ops_slices.py,sha256=hHMIOQ_niUSK9uFl8P2-10dP_K4GX3Do6vivN4fGRE0,14520
36
+ ngio/io_pipes/_ops_slices_utils.py,sha256=mps_I0eTI4gdBVM9MCKsd8rCyefdo9bIK9fEmqwr23E,6633
37
+ ngio/io_pipes/_ops_transforms.py,sha256=uITs6v6sZ7DQ_Hpw3JdX8MuPOzir-bihvGzY84Qn4wY,2934
38
+ ngio/io_pipes/_zoom_transform.py,sha256=WBY1tO6_Qhf8FaDujfTdipuuqFf7PSi204wx5VKKs88,6884
39
+ ngio/ome_zarr_meta/__init__.py,sha256=7VDrX-ev5Gg2zQfGsrlj-YPTeIGzbplxbptxw1u-vU0,1491
40
+ ngio/ome_zarr_meta/_meta_handlers.py,sha256=u6a-z-q4Gu0TSahpD5qCmpIOLwnJqNjfoAnOyzzCyrg,14794
41
+ ngio/ome_zarr_meta/ngio_specs/__init__.py,sha256=FukhukN9ksW-SDUiAtmiwpQ7c9qWAyq0cnTnSqZLsVc,1800
42
+ ngio/ome_zarr_meta/ngio_specs/_axes.py,sha256=yfFylcr_xGda5HuXWRV25V4gRUbNJdfJwyn9mqXEB6I,20313
43
+ ngio/ome_zarr_meta/ngio_specs/_channels.py,sha256=TDxIy-yVc2YaWPIFJRYnYwZbA8O5Ee_OiWppHYrEdpU,16647
44
+ ngio/ome_zarr_meta/ngio_specs/_dataset.py,sha256=5YdAplk90koX3vjoIJimms-CJYxt095rJ9YagZSQg88,2872
45
+ ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py,sha256=kktIwHWZ8u2f6xMUB4zXiUfNF6i-We86_agLjJ7XVOU,18363
46
+ ngio/ome_zarr_meta/ngio_specs/_ngio_image.py,sha256=LJE_bA8e5KIEm_7pr15Etda-KhKCAqjWCUFHoCnwTag,15654
47
+ ngio/ome_zarr_meta/ngio_specs/_pixel_size.py,sha256=4VF1djY9T5tp6GCJXppFrUJwALI1XgIm0imoM5rNvdE,3876
48
+ ngio/ome_zarr_meta/v04/__init__.py,sha256=tRt3zGelL948EoLfy_gW-LKvJcBbSkbT9kwIgU0hQV8,721
49
+ ngio/ome_zarr_meta/v04/_custom_models.py,sha256=5GxiDERvLuvq4QvApcA6EiKLS6hLFX1R0R_9rSaa85A,530
50
+ ngio/ome_zarr_meta/v04/_v04_spec.py,sha256=S9a9Z3wYLI-WHnOZsg3RKPAcovssqGIr-x8GVAjV0IU,14321
51
+ ngio/ome_zarr_meta/v05/__init__.py,sha256=B6VIUkrm5W4lcrvy4R7c7NZ6dEx-0a1AhqhZ7snCnCo,721
52
+ ngio/ome_zarr_meta/v05/_custom_models.py,sha256=ZN3bE9nwx4y3tElhsYafI4S2zp_WzdkQKcyuuBiaXXo,530
53
+ ngio/ome_zarr_meta/v05/_v05_spec.py,sha256=pCIoSsYmJjmrZ3jbgkdio7e6qKV2_ggd4WQe4zBSt8M,15225
54
+ ngio/resources/__init__.py,sha256=pOo2YqxDlzTSWo6qyYQzXZbIKWSUoEl3iqX41Iw-oQI,1661
55
+ ngio/resources/resource_model.py,sha256=mmx8gbfDHBg_gVNvtZZydAZDATdmcaM8DsOfnRVrXXA,858
56
+ ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png,sha256=g3QmxQdmeciAtBe5cTCRfR6yw3keG9cBYfjizMo6EGo,11890
57
+ ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png,sha256=Yw0k5pn2EHDMWTwyb7N51NX7WVk6-MlwfP9WZrhY-Ic,19446
58
+ ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg,sha256=82lejQAIokj5w9g-qqhysDTWpHtNvJTkdURG_BjqIxQ,37743
59
+ ngio/tables/__init__.py,sha256=_BV3sclNMLITu_J8_3DkkUrCB6Kro0HzeWLDCD1ivKM,877
60
+ ngio/tables/_abstract_table.py,sha256=rwGa47TzbFmosucBWVfFq6JEXtgGvOdUVtU9DIelV88,8204
61
+ ngio/tables/_tables_container.py,sha256=4frJpcfuW-J8N13enzFuH6wQIVwRVRKN7FOLWx_VxRc,14035
62
+ ngio/tables/backends/__init__.py,sha256=MwSRXNF1rWQBFOTDA_vT3oGoNZpviVgytsL5Txnu08I,1619
63
+ ngio/tables/backends/_abstract_backend.py,sha256=M1ogsBpWBiQMV65YweZhA845PAtkzG2BsZCPN_7Xp8U,7613
64
+ ngio/tables/backends/_anndata.py,sha256=T67N-SPNO4eqe7-VGAUfgtwaSy_o2DqCvZgE2yRH5jE,4582
65
+ ngio/tables/backends/_anndata_utils.py,sha256=PoHiLkGeDhBgPsEMJi9QH-NejHmfrfILcwj1CYubyCM,3095
66
+ ngio/tables/backends/_csv.py,sha256=iZJNLHOXYysV_2iq6Lmekq0XXYsVE7OYrKz2HP2TU9w,479
67
+ ngio/tables/backends/_json.py,sha256=A4iaKOIc5Q_XKDOm321QNqAN4DAOuA-dEinnfTlk1Fk,3091
68
+ ngio/tables/backends/_parquet.py,sha256=Fi3VZlTH5UTykk0eqr43_e_Qt_GQcEN-3pHK07XFBwk,503
69
+ ngio/tables/backends/_py_arrow_backends.py,sha256=lxxI5TN4lFYwpsjD1g1xAxEt4lZ9Mu7YW3-m3nIuo2g,8587
70
+ ngio/tables/backends/_table_backends.py,sha256=ksP2NAosXZkNMZf-IMrLx7bjQgp_eKfvPYK4vMdT1A8,7250
71
+ ngio/tables/backends/_utils.py,sha256=t4dLXSPxx2AnJvVtj0GIwrLoO11h4Ges6U7hj4md0hY,19730
72
+ ngio/tables/v1/__init__.py,sha256=Wr1_9RZFpaN8FYMTnxT9Yjkw4AS7y9FMWailmB_uj5g,617
73
+ ngio/tables/v1/_condition_table.py,sha256=T0Uq5BKkmMoEspt_Rx0U99Ow6S9GAMZDHqvUO5obCAM,1780
74
+ ngio/tables/v1/_feature_table.py,sha256=n9uMHwoBh-_dlOhUXCFbmAjXFVXncNCR3SjE2qzXI68,3821
75
+ ngio/tables/v1/_generic_table.py,sha256=1ktJHeuv7U1g5Z8PFUuTkCjOzcYMQd8xegKHKUedJB8,1240
76
+ ngio/tables/v1/_roi_table.py,sha256=DuKJlDmtQtLOfL0g4CSdncfm4hBsKWG6F6fkMUpt4Nk,17821
77
+ ngio/transforms/__init__.py,sha256=JA0-Ui7skbXkm9ofN-AEhU1FTLutkMkwTdVD-310frQ,113
78
+ ngio/transforms/_zoom.py,sha256=otyE-vxFnywUJ8U4mHjat-bNG_7_jv62ckTpqDMxyVQ,550
79
+ ngio/utils/__init__.py,sha256=d2OHQGMFPpf8-_ipuqquxtqCNGJpX5yXt34A65nScUU,1037
80
+ ngio/utils/_cache.py,sha256=Ey9fgc_BTdMyqg6c80C0CuGDhOafln8-3e_1MQ0MFzw,1283
81
+ ngio/utils/_datasets.py,sha256=YOV367skFA8nbKAqbyK0EsUU7E9UId_u5ButuLesrzk,5896
82
+ ngio/utils/_errors.py,sha256=pKQ12LUjQLYE1nUawemA5h7HsgznjaSvV1n2PQU33N0,759
83
+ ngio/utils/_fractal_fsspec_store.py,sha256=RdcCFOgHexRKX9zZvJV5RI-5OPc7VOPS6q_IeRxm24I,1548
84
+ ngio/utils/_zarr_utils.py,sha256=n9EvUIZFNIBIHBoadefSz_7r9q8GLu7x7FF2G6Dgb94,18095
85
+ ngio-0.5.0.dist-info/METADATA,sha256=tecky39dej2Kd41NqWTJaAloeiXQAgGDtoyXJNJdWgU,6424
86
+ ngio-0.5.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
87
+ ngio-0.5.0.dist-info/licenses/LICENSE,sha256=UgN_a1QCeNh9rZWfz-wORQFxE3elQzLWPQaoK6N6fxQ,1502
88
+ ngio-0.5.0.dist-info/RECORD,,
ngio/images/_create.py DELETED
@@ -1,276 +0,0 @@
1
- """Utility functions for working with OME-Zarr images."""
2
-
3
- from collections.abc import Sequence
4
- from typing import TypeVar
5
-
6
- from zarr.types import DIMENSION_SEPARATOR
7
-
8
- from ngio.common._pyramid import init_empty_pyramid
9
- from ngio.ome_zarr_meta import (
10
- NgioImageMeta,
11
- NgioLabelMeta,
12
- PixelSize,
13
- get_image_meta_handler,
14
- get_label_meta_handler,
15
- )
16
- from ngio.ome_zarr_meta.ngio_specs import (
17
- DefaultNgffVersion,
18
- DefaultSpaceUnit,
19
- DefaultTimeUnit,
20
- NgffVersions,
21
- SpaceUnits,
22
- TimeUnits,
23
- canonical_axes_order,
24
- canonical_label_axes_order,
25
- )
26
- from ngio.utils import NgioValueError, StoreOrGroup, ZarrGroupHandler
27
-
28
- _image_or_label_meta = TypeVar("_image_or_label_meta", NgioImageMeta, NgioLabelMeta)
29
-
30
-
31
- def _init_generic_meta(
32
- meta_type: type[_image_or_label_meta],
33
- pixelsize: float,
34
- axes_names: Sequence[str],
35
- z_spacing: float = 1.0,
36
- time_spacing: float = 1.0,
37
- levels: int | list[str] = 5,
38
- yx_scaling_factor: float | tuple[float, float] = 2.0,
39
- z_scaling_factor: float = 1.0,
40
- space_unit: SpaceUnits | str | None = DefaultSpaceUnit,
41
- time_unit: TimeUnits | str | None = DefaultTimeUnit,
42
- name: str | None = None,
43
- version: NgffVersions = DefaultNgffVersion,
44
- ) -> tuple[_image_or_label_meta, list[float]]:
45
- """Initialize the metadata for an image or label."""
46
- scaling_factors = []
47
- for ax in axes_names:
48
- if ax == "z":
49
- scaling_factors.append(z_scaling_factor)
50
- elif ax in ["x"]:
51
- if isinstance(yx_scaling_factor, tuple):
52
- scaling_factors.append(yx_scaling_factor[1])
53
- else:
54
- scaling_factors.append(yx_scaling_factor)
55
- elif ax in ["y"]:
56
- if isinstance(yx_scaling_factor, tuple):
57
- scaling_factors.append(yx_scaling_factor[0])
58
- else:
59
- scaling_factors.append(yx_scaling_factor)
60
- else:
61
- scaling_factors.append(1.0)
62
-
63
- pixel_sizes = PixelSize(
64
- x=pixelsize,
65
- y=pixelsize,
66
- z=z_spacing,
67
- t=time_spacing,
68
- space_unit=space_unit,
69
- time_unit=time_unit,
70
- )
71
-
72
- meta = meta_type.default_init(
73
- name=name,
74
- levels=levels,
75
- axes_names=axes_names,
76
- pixel_size=pixel_sizes,
77
- scaling_factors=scaling_factors,
78
- version=version,
79
- )
80
- return meta, scaling_factors
81
-
82
-
83
- def create_empty_label_container(
84
- store: StoreOrGroup,
85
- shape: Sequence[int],
86
- pixelsize: float,
87
- z_spacing: float = 1.0,
88
- time_spacing: float = 1.0,
89
- levels: int | list[str] = 5,
90
- yx_scaling_factor: float | tuple[float, float] = 2.0,
91
- z_scaling_factor: float = 1.0,
92
- space_unit: SpaceUnits | str | None = DefaultSpaceUnit,
93
- time_unit: TimeUnits | str | None = DefaultTimeUnit,
94
- axes_names: Sequence[str] | None = None,
95
- name: str | None = None,
96
- chunks: Sequence[int] | None = None,
97
- dtype: str = "uint32",
98
- dimension_separator: DIMENSION_SEPARATOR = "/",
99
- compressor="default",
100
- overwrite: bool = False,
101
- version: NgffVersions = DefaultNgffVersion,
102
- ) -> ZarrGroupHandler:
103
- """Create an empty label with the given shape and metadata.
104
-
105
- Args:
106
- store (StoreOrGroup): The Zarr store or group to create the image in.
107
- shape (Sequence[int]): The shape of the image.
108
- pixelsize (float): The pixel size in x and y dimensions.
109
- z_spacing (float, optional): The spacing between z slices. Defaults to 1.0.
110
- time_spacing (float, optional): The spacing between time points.
111
- Defaults to 1.0.
112
- levels (int | list[str], optional): The number of levels in the pyramid or a
113
- list of level names. Defaults to 5.
114
- yx_scaling_factor (float, optional): The down-scaling factor in x and y
115
- dimensions. Defaults to 2.0.
116
- z_scaling_factor (float, optional): The down-scaling factor in z dimension.
117
- Defaults to 1.0.
118
- space_unit (SpaceUnits, optional): The unit of space. Defaults to
119
- DefaultSpaceUnit.
120
- time_unit (TimeUnits, optional): The unit of time. Defaults to
121
- DefaultTimeUnit.
122
- axes_names (Sequence[str] | None, optional): The names of the axes.
123
- If None the canonical names are used. Defaults to None.
124
- name (str | None, optional): The name of the image. Defaults to None.
125
- chunks (Sequence[int] | None, optional): The chunk shape. If None the shape
126
- is used. Defaults to None.
127
- dimension_separator (DIMENSION_SEPARATOR): The separator to use for
128
- dimensions. Defaults to "/".
129
- compressor: The compressor to use. Defaults to "default".
130
- dtype (str, optional): The data type of the image. Defaults to "uint16".
131
- overwrite (bool, optional): Whether to overwrite an existing image.
132
- Defaults to True.
133
- version (str, optional): The version of the OME-Zarr specification.
134
- Defaults to DefaultVersion.
135
-
136
- """
137
- if axes_names is None:
138
- axes_names = canonical_label_axes_order()[-len(shape) :]
139
-
140
- if len(axes_names) != len(shape):
141
- raise NgioValueError(
142
- f"Number of axes names {axes_names} does not match the number of "
143
- f"dimensions {shape}."
144
- )
145
-
146
- meta, scaling_factors = _init_generic_meta(
147
- meta_type=NgioLabelMeta,
148
- pixelsize=pixelsize,
149
- z_spacing=z_spacing,
150
- time_spacing=time_spacing,
151
- levels=levels,
152
- yx_scaling_factor=yx_scaling_factor,
153
- z_scaling_factor=z_scaling_factor,
154
- space_unit=space_unit,
155
- time_unit=time_unit,
156
- axes_names=axes_names,
157
- name=name,
158
- version=version,
159
- )
160
-
161
- mode = "w" if overwrite else "w-"
162
- group_handler = ZarrGroupHandler(store=store, mode=mode, cache=False)
163
- image_handler = get_label_meta_handler(version=version, group_handler=group_handler)
164
- image_handler.write_meta(meta)
165
-
166
- init_empty_pyramid(
167
- store=store,
168
- paths=meta.paths,
169
- scaling_factors=scaling_factors,
170
- ref_shape=shape,
171
- chunks=chunks,
172
- dtype=dtype,
173
- mode="a",
174
- dimension_separator=dimension_separator,
175
- compressor=compressor,
176
- )
177
- group_handler._mode = "r+"
178
- return group_handler
179
-
180
-
181
- def create_empty_image_container(
182
- store: StoreOrGroup,
183
- shape: Sequence[int],
184
- pixelsize: float,
185
- z_spacing: float = 1.0,
186
- time_spacing: float = 1.0,
187
- levels: int | list[str] = 5,
188
- yx_scaling_factor: float | tuple[float, float] = 2,
189
- z_scaling_factor: float = 1.0,
190
- space_unit: SpaceUnits | str | None = DefaultSpaceUnit,
191
- time_unit: TimeUnits | str | None = DefaultTimeUnit,
192
- axes_names: Sequence[str] | None = None,
193
- name: str | None = None,
194
- chunks: Sequence[int] | None = None,
195
- dtype: str = "uint16",
196
- dimension_separator: DIMENSION_SEPARATOR = "/",
197
- compressor="default",
198
- overwrite: bool = False,
199
- version: NgffVersions = DefaultNgffVersion,
200
- ) -> ZarrGroupHandler:
201
- """Create an empty OME-Zarr image with the given shape and metadata.
202
-
203
- Args:
204
- store (StoreOrGroup): The Zarr store or group to create the image in.
205
- shape (Sequence[int]): The shape of the image.
206
- pixelsize (float): The pixel size in x and y dimensions.
207
- z_spacing (float, optional): The spacing between z slices. Defaults to 1.0.
208
- time_spacing (float, optional): The spacing between time points.
209
- Defaults to 1.0.
210
- levels (int | list[str], optional): The number of levels in the pyramid or a
211
- list of level names. Defaults to 5.
212
- yx_scaling_factor (float, optional): The down-scaling factor in x and y
213
- dimensions. Defaults to 2.0.
214
- z_scaling_factor (float, optional): The down-scaling factor in z dimension.
215
- Defaults to 1.0.
216
- space_unit (SpaceUnits, optional): The unit of space. Defaults to
217
- DefaultSpaceUnit.
218
- time_unit (TimeUnits, optional): The unit of time. Defaults to
219
- DefaultTimeUnit.
220
- axes_names (Sequence[str] | None, optional): The names of the axes.
221
- If None the canonical names are used. Defaults to None.
222
- name (str | None, optional): The name of the image. Defaults to None.
223
- chunks (Sequence[int] | None, optional): The chunk shape. If None the shape
224
- is used. Defaults to None.
225
- dtype (str, optional): The data type of the image. Defaults to "uint16".
226
- dimension_separator (DIMENSION_SEPARATOR): The separator to use for
227
- dimensions. Defaults to "/".
228
- compressor: The compressor to use. Defaults to "default".
229
- overwrite (bool, optional): Whether to overwrite an existing image.
230
- Defaults to True.
231
- version (str, optional): The version of the OME-Zarr specification.
232
- Defaults to DefaultVersion.
233
-
234
- """
235
- if axes_names is None:
236
- axes_names = canonical_axes_order()[-len(shape) :]
237
-
238
- if len(axes_names) != len(shape):
239
- raise NgioValueError(
240
- f"Number of axes names {axes_names} does not match the number of "
241
- f"dimensions {shape}."
242
- )
243
-
244
- meta, scaling_factors = _init_generic_meta(
245
- meta_type=NgioImageMeta,
246
- pixelsize=pixelsize,
247
- z_spacing=z_spacing,
248
- time_spacing=time_spacing,
249
- levels=levels,
250
- yx_scaling_factor=yx_scaling_factor,
251
- z_scaling_factor=z_scaling_factor,
252
- space_unit=space_unit,
253
- time_unit=time_unit,
254
- axes_names=axes_names,
255
- name=name,
256
- version=version,
257
- )
258
- mode = "w" if overwrite else "w-"
259
- group_handler = ZarrGroupHandler(store=store, mode=mode, cache=False)
260
- image_handler = get_image_meta_handler(version=version, group_handler=group_handler)
261
- image_handler.write_meta(meta)
262
-
263
- init_empty_pyramid(
264
- store=store,
265
- paths=meta.paths,
266
- scaling_factors=scaling_factors,
267
- ref_shape=shape,
268
- chunks=chunks,
269
- dtype=dtype,
270
- mode="a",
271
- dimension_separator=dimension_separator,
272
- compressor=compressor,
273
- )
274
-
275
- group_handler._mode = "r+"
276
- return group_handler
@@ -1,196 +0,0 @@
1
- import io
2
- from collections.abc import Callable
3
- from typing import Any
4
-
5
- from pandas import DataFrame
6
- from polars import DataFrame as PolarsDataFrame
7
- from polars import LazyFrame
8
- from zarr.storage import DirectoryStore, FSStore
9
-
10
- from ngio.tables.backends._abstract_backend import AbstractTableBackend
11
- from ngio.tables.backends._utils import normalize_pandas_df, normalize_polars_lf
12
- from ngio.utils import NgioFileNotFoundError, NgioValueError
13
-
14
-
15
- class NonZarrBaseBackend(AbstractTableBackend):
16
- """A class to load and write small tables in CSV format."""
17
-
18
- def __init__(
19
- self,
20
- df_reader: Callable[[Any], DataFrame],
21
- lf_reader: Callable[[Any], LazyFrame],
22
- df_writer: Callable[[str, DataFrame], None],
23
- lf_writer: Callable[[str, PolarsDataFrame], None],
24
- table_name: str,
25
- ):
26
- self.df_reader = df_reader
27
- self.lf_reader = lf_reader
28
- self.df_writer = df_writer
29
- self.lf_writer = lf_writer
30
- self.table_name = table_name
31
-
32
- @staticmethod
33
- def implements_anndata() -> bool:
34
- """Whether the handler implements the anndata protocol."""
35
- return False
36
-
37
- @staticmethod
38
- def implements_pandas() -> bool:
39
- """Whether the handler implements the dataframe protocol."""
40
- return True
41
-
42
- @staticmethod
43
- def implements_polars() -> bool:
44
- """Whether the handler implements the polars protocol."""
45
- return True
46
-
47
- @staticmethod
48
- def backend_name() -> str:
49
- """Return the name of the backend."""
50
- raise NotImplementedError(
51
- "The backend_name method must be implemented in the subclass."
52
- )
53
-
54
- def _load_from_directory_store(self, reader):
55
- """Load the table from a directory store."""
56
- url = self._group_handler.full_url
57
- if url is None:
58
- ext = self.table_name.split(".")[-1]
59
- raise NgioValueError(
60
- f"Ngio does not support reading a {ext} table from a "
61
- f"store of type {type(self._group_handler)}. "
62
- "Please make sure to use a compatible "
63
- "store like a zarr.DirectoryStore."
64
- )
65
- table_path = f"{url}/{self.table_name}"
66
- dataframe = reader(table_path)
67
- return dataframe
68
-
69
- def _load_from_fs_store_df(self, reader):
70
- """Load the table from an FS store."""
71
- path = self._group_handler.group.path
72
- table_path = f"{path}/{self.table_name}"
73
- bytes_table = self._group_handler.store.get(table_path)
74
- if bytes_table is None:
75
- raise NgioFileNotFoundError(f"No table found at {table_path}. ")
76
- dataframe = reader(io.BytesIO(bytes_table))
77
- return dataframe
78
-
79
- def _load_from_fs_store_lf(self, reader):
80
- """Load the table from an FS store."""
81
- full_url = self._group_handler.full_url
82
- parquet_path = f"{full_url}/{self.table_name}"
83
- store_fs = self._group_handler.store.fs # type: ignore (in this context, store_fs is a fs.FSStore)
84
- with store_fs.open(parquet_path, "rb") as f:
85
- dataframe = reader(f)
86
- return dataframe
87
-
88
- def load_as_pandas_df(self) -> DataFrame:
89
- """Load the table as a pandas DataFrame."""
90
- store = self._group_handler.store
91
- if isinstance(store, DirectoryStore):
92
- dataframe = self._load_from_directory_store(reader=self.df_reader)
93
- elif isinstance(store, FSStore):
94
- dataframe = self._load_from_fs_store_df(reader=self.df_reader)
95
- else:
96
- ext = self.table_name.split(".")[-1]
97
- raise NgioValueError(
98
- f"Ngio does not support reading a {ext} table from a "
99
- f"store of type {type(store)}. "
100
- "Please make sure to use a compatible "
101
- "store like a zarr.DirectoryStore or "
102
- "zarr.FSStore."
103
- )
104
-
105
- dataframe = normalize_pandas_df(
106
- dataframe,
107
- index_key=self.index_key,
108
- index_type=self.index_type,
109
- reset_index=False,
110
- )
111
- return dataframe
112
-
113
- def load(self) -> DataFrame:
114
- """Load the table as a pandas DataFrame."""
115
- return self.load_as_pandas_df()
116
-
117
- def load_as_polars_lf(self) -> LazyFrame:
118
- """Load the table as a polars LazyFrame."""
119
- store = self._group_handler.store
120
- if isinstance(store, DirectoryStore):
121
- lazy_frame = self._load_from_directory_store(reader=self.lf_reader)
122
- elif isinstance(store, FSStore):
123
- lazy_frame = self._load_from_fs_store_lf(reader=self.lf_reader)
124
- else:
125
- ext = self.table_name.split(".")[-1]
126
- raise NgioValueError(
127
- f"Ngio does not support reading a {ext} from a "
128
- f"store of type {type(store)}. "
129
- "Please make sure to use a compatible "
130
- "store like a zarr.DirectoryStore or "
131
- "zarr.FSStore."
132
- )
133
- if not isinstance(lazy_frame, LazyFrame):
134
- raise NgioValueError(
135
- "Table is not a lazy frame. Please report this issue as an ngio bug."
136
- f" {type(lazy_frame)}"
137
- )
138
-
139
- lazy_frame = normalize_polars_lf(
140
- lazy_frame,
141
- index_key=self.index_key,
142
- index_type=self.index_type,
143
- )
144
- return lazy_frame
145
-
146
- def _get_store_url(self) -> str:
147
- """Get the store URL."""
148
- store = self._group_handler.store
149
- if isinstance(store, DirectoryStore):
150
- full_url = self._group_handler.full_url
151
- else:
152
- ext = self.table_name.split(".")[-1]
153
- raise NgioValueError(
154
- f"Ngio does not support writing a {ext} file to a "
155
- f"store of type {type(store)}. "
156
- "Please make sure to use a compatible "
157
- "store like a zarr.DirectoryStore or "
158
- "zarr.FSStore."
159
- )
160
- if full_url is None:
161
- ext = self.table_name.split(".")[-1]
162
- raise NgioValueError(
163
- f"Ngio does not support writing a {ext} file to a "
164
- f"store of type {type(store)}. "
165
- "Please make sure to use a compatible "
166
- "store like a zarr.DirectoryStore or "
167
- "zarr.FSStore."
168
- )
169
- return full_url
170
-
171
- def write_from_pandas(self, table: DataFrame) -> None:
172
- """Write the table from a pandas DataFrame."""
173
- table = normalize_pandas_df(
174
- table,
175
- index_key=self.index_key,
176
- index_type=self.index_type,
177
- reset_index=True,
178
- )
179
- full_url = self._get_store_url()
180
- table_path = f"{full_url}/{self.table_name}"
181
- self.df_writer(table_path, table)
182
-
183
- def write_from_polars(self, table: PolarsDataFrame | LazyFrame) -> None:
184
- """Write the table from a polars DataFrame or LazyFrame."""
185
- table = normalize_polars_lf(
186
- table,
187
- index_key=self.index_key,
188
- index_type=self.index_type,
189
- )
190
-
191
- if isinstance(table, LazyFrame):
192
- table = table.collect()
193
-
194
- full_url = self._get_store_url()
195
- table_path = f"{full_url}/{self.table_name}"
196
- self.lf_writer(table_path, table)
ngio/utils/_logger.py DELETED
@@ -1,50 +0,0 @@
1
- import logging
2
- import time
3
- from functools import cache
4
-
5
- from ngio.utils._errors import NgioValueError
6
-
7
- # Configure the logger
8
- ngio_logger = logging.getLogger("NgioLogger")
9
- ngio_logger.setLevel(logging.ERROR)
10
-
11
- # Set up a console handler with a custom format
12
- console_handler = logging.StreamHandler()
13
- formatter = logging.Formatter(
14
- "%(asctime)s - %(levelname)s - %(name)s - "
15
- "[%(module)s.%(funcName)s:%(lineno)d]: %(message)s"
16
- )
17
- console_handler.setFormatter(formatter)
18
-
19
- # Add the handler to the logger
20
- ngio_logger.addHandler(console_handler)
21
-
22
-
23
- def set_logger_level(level: str) -> None:
24
- """Set the logger level.
25
-
26
- Args:
27
- level: The level to set the logger to.
28
- Must be one of "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL".
29
- """
30
- if level not in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
31
- raise NgioValueError(f"Invalid log level: {level}")
32
-
33
- ngio_logger.setLevel(level)
34
-
35
-
36
- @cache
37
- def _warn(message: str, ttl_hash: int) -> None:
38
- """Log a warning message with a time-to-live (TTL) hash."""
39
- ngio_logger.warning(message, stacklevel=3)
40
-
41
-
42
- def ngio_warn(message: str, cooldown: int = 2) -> None:
43
- """Log a warning message.
44
-
45
- Args:
46
- message: The warning message to log.
47
- cooldown: The cooldown period in seconds to avoid repeated logging.
48
- """
49
- ttl_hash = time.time() // cooldown
50
- _warn(message, ttl_hash)