ngio 0.4.0a2__tar.gz → 0.4.0a4__tar.gz

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 (260) hide show
  1. {ngio-0.4.0a2 → ngio-0.4.0a4}/PKG-INFO +1 -1
  2. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/getting_started/3_tables.md +1 -1
  3. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/__init__.py +1 -2
  4. ngio-0.4.0a4/src/ngio/common/__init__.py +23 -0
  5. ngio-0.4.0a4/src/ngio/common/_dimensions.py +315 -0
  6. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/common/_pyramid.py +42 -23
  7. ngio-0.4.0a4/src/ngio/common/_roi.py +354 -0
  8. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/common/_zoom.py +32 -7
  9. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/experimental/iterators/_abstract_iterator.py +2 -2
  10. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/experimental/iterators/_feature.py +10 -15
  11. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/experimental/iterators/_image_processing.py +18 -28
  12. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/experimental/iterators/_rois_utils.py +6 -6
  13. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/experimental/iterators/_segmentation.py +38 -54
  14. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_abstract_image.py +136 -94
  15. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_create.py +16 -0
  16. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_create_synt_container.py +10 -0
  17. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_image.py +33 -9
  18. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_label.py +24 -3
  19. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_masked_image.py +60 -81
  20. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_ome_zarr_container.py +34 -1
  21. ngio-0.4.0a4/src/ngio/io_pipes/__init__.py +49 -0
  22. ngio-0.4.0a4/src/ngio/io_pipes/_io_pipes.py +286 -0
  23. ngio-0.4.0a4/src/ngio/io_pipes/_io_pipes_masked.py +481 -0
  24. ngio-0.4.0a4/src/ngio/io_pipes/_io_pipes_roi.py +143 -0
  25. ngio-0.4.0a4/src/ngio/io_pipes/_io_pipes_utils.py +299 -0
  26. ngio-0.4.0a4/src/ngio/io_pipes/_match_shape.py +376 -0
  27. ngio-0.4.0a4/src/ngio/io_pipes/_ops_axes.py +146 -0
  28. ngio-0.4.0a4/src/ngio/io_pipes/_ops_slices.py +218 -0
  29. ngio-0.4.0a4/src/ngio/io_pipes/_ops_transforms.py +104 -0
  30. ngio-0.4.0a4/src/ngio/io_pipes/_zoom_transform.py +175 -0
  31. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/__init__.py +6 -2
  32. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/ngio_specs/__init__.py +6 -4
  33. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/ngio_specs/_axes.py +182 -70
  34. ngio-0.4.0a4/src/ngio/ome_zarr_meta/ngio_specs/_dataset.py +98 -0
  35. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +30 -22
  36. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +17 -1
  37. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/v04/_v04_spec_utils.py +33 -30
  38. ngio-0.4.0a4/src/ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  39. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/resources/__init__.py +1 -0
  40. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/resources/resource_model.py +1 -0
  41. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/v1/_roi_table.py +11 -3
  42. {ngio-0.4.0a2/src/ngio/common → ngio-0.4.0a4/src/ngio}/transforms/__init__.py +1 -1
  43. ngio-0.4.0a4/src/ngio/transforms/_zoom.py +19 -0
  44. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/utils/_zarr_utils.py +5 -1
  45. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/common/test_dimensions.py +22 -7
  46. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/common/test_pyramid.py +11 -8
  47. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/common/test_roi.py +2 -7
  48. ngio-0.4.0a4/tests/unit/common/test_transforms.py +45 -0
  49. ngio-0.4.0a4/tests/unit/images/test_images.py +189 -0
  50. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/images/test_masked_images.py +54 -15
  51. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/images/test_omezarr_container.py +11 -10
  52. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/ome_zarr_meta/test_unit_ngio_specs.py +140 -133
  53. ngio-0.4.0a2/src/ngio/common/__init__.py +0 -72
  54. ngio-0.4.0a2/src/ngio/common/_array_io_pipes.py +0 -554
  55. ngio-0.4.0a2/src/ngio/common/_array_io_utils.py +0 -508
  56. ngio-0.4.0a2/src/ngio/common/_dimensions.py +0 -156
  57. ngio-0.4.0a2/src/ngio/common/_roi.py +0 -678
  58. ngio-0.4.0a2/src/ngio/common/transforms/_label.py +0 -12
  59. ngio-0.4.0a2/src/ngio/common/transforms/_zoom.py +0 -109
  60. ngio-0.4.0a2/src/ngio/ome_zarr_meta/ngio_specs/_dataset.py +0 -172
  61. ngio-0.4.0a2/src/ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  62. ngio-0.4.0a2/tests/unit/common/test_transforms.py +0 -59
  63. ngio-0.4.0a2/tests/unit/images/test_images.py +0 -25
  64. {ngio-0.4.0a2 → ngio-0.4.0a4}/.copier-answers.yml +0 -0
  65. {ngio-0.4.0a2 → ngio-0.4.0a4}/.gitattributes +0 -0
  66. {ngio-0.4.0a2 → ngio-0.4.0a4}/.github/ISSUE_TEMPLATE.md +0 -0
  67. {ngio-0.4.0a2 → ngio-0.4.0a4}/.github/TEST_FAIL_TEMPLATE.md +0 -0
  68. {ngio-0.4.0a2 → ngio-0.4.0a4}/.github/dependabot.yml +0 -0
  69. {ngio-0.4.0a2 → ngio-0.4.0a4}/.github/pull_request_template.md +0 -0
  70. {ngio-0.4.0a2 → ngio-0.4.0a4}/.github/workflows/build_docs.yml +0 -0
  71. {ngio-0.4.0a2 → ngio-0.4.0a4}/.github/workflows/ci.yml +0 -0
  72. {ngio-0.4.0a2 → ngio-0.4.0a4}/.gitignore +0 -0
  73. {ngio-0.4.0a2 → ngio-0.4.0a4}/.pre-commit-config.yaml +0 -0
  74. {ngio-0.4.0a2 → ngio-0.4.0a4}/CHANGELOG.md +0 -0
  75. {ngio-0.4.0a2 → ngio-0.4.0a4}/LICENSE +0 -0
  76. {ngio-0.4.0a2 → ngio-0.4.0a4}/README.md +0 -0
  77. {ngio-0.4.0a2 → ngio-0.4.0a4}/_typos.toml +0 -0
  78. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/hcs.md +0 -0
  79. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/images.md +0 -0
  80. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/ngio/common.md +0 -0
  81. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/ngio/hcs.md +0 -0
  82. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/ngio/images.md +0 -0
  83. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/ngio/ngio.md +0 -0
  84. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/ngio/tables.md +0 -0
  85. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/ngio/utils.md +0 -0
  86. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/ome_zarr_container.md +0 -0
  87. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/api/tables.md +0 -0
  88. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/changelog.md +0 -0
  89. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/code_of_conduct.md +0 -0
  90. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/contributing.md +0 -0
  91. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/getting_started/0_quickstart.md +0 -0
  92. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/getting_started/1_ome_zarr_containers.md +0 -0
  93. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/getting_started/2_images.md +0 -0
  94. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/getting_started/4_masked_images.md +0 -0
  95. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/getting_started/5_hcs.md +0 -0
  96. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/index.md +0 -0
  97. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/backend.md +0 -0
  98. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/overview.md +0 -0
  99. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/table_types/condition_table.md +0 -0
  100. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/table_types/custom_table.md +0 -0
  101. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/table_types/feature_table.md +0 -0
  102. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/table_types/generic_table.md +0 -0
  103. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/table_types/masking_roi_table.md +0 -0
  104. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/table_specs/table_types/roi_table.md +0 -0
  105. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/tutorials/create_ome_zarr.ipynb +0 -0
  106. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/tutorials/feature_extraction.ipynb +0 -0
  107. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/tutorials/hcs_exploration.ipynb +0 -0
  108. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/tutorials/image_processing.ipynb +0 -0
  109. {ngio-0.4.0a2 → ngio-0.4.0a4}/docs/tutorials/image_segmentation.ipynb +0 -0
  110. {ngio-0.4.0a2 → ngio-0.4.0a4}/mkdocs.yml +0 -0
  111. {ngio-0.4.0a2 → ngio-0.4.0a4}/pyproject.toml +0 -0
  112. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/common/_masking_roi.py +0 -0
  113. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/common/_synt_images_utils.py +0 -0
  114. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/experimental/__init__.py +0 -0
  115. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/experimental/iterators/__init__.py +0 -0
  116. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/hcs/__init__.py +0 -0
  117. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/hcs/_plate.py +0 -0
  118. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/__init__.py +0 -0
  119. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/images/_table_ops.py +0 -0
  120. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/_meta_handlers.py +0 -0
  121. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/ngio_specs/_channels.py +0 -0
  122. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +0 -0
  123. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/v04/__init__.py +0 -0
  124. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/ome_zarr_meta/v04/_custom_models.py +0 -0
  125. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
  126. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
  127. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/__init__.py +0 -0
  128. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/_abstract_table.py +0 -0
  129. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/_tables_container.py +0 -0
  130. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/__init__.py +0 -0
  131. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_abstract_backend.py +0 -0
  132. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_anndata.py +0 -0
  133. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_anndata_utils.py +0 -0
  134. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_csv.py +0 -0
  135. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_json.py +0 -0
  136. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_non_zarr_backends.py +0 -0
  137. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_parquet.py +0 -0
  138. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_table_backends.py +0 -0
  139. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/backends/_utils.py +0 -0
  140. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/v1/__init__.py +0 -0
  141. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/v1/_condition_table.py +0 -0
  142. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/v1/_feature_table.py +0 -0
  143. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/tables/v1/_generic_table.py +0 -0
  144. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/utils/__init__.py +0 -0
  145. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/utils/_datasets.py +0 -0
  146. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/utils/_errors.py +0 -0
  147. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/utils/_fractal_fsspec_store.py +0 -0
  148. {ngio-0.4.0a2 → ngio-0.4.0a4}/src/ngio/utils/_logger.py +0 -0
  149. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/conftest.py +0 -0
  150. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/.zattrs +0 -0
  151. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/.zgroup +0 -0
  152. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/0/.zarray +0 -0
  153. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/1/.zarray +0 -0
  154. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/labels/.zattrs +0 -0
  155. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/labels/.zgroup +0 -0
  156. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/.zattrs +0 -0
  157. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/.zgroup +0 -0
  158. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/0/.zarray +0 -0
  159. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/1/.zarray +0 -0
  160. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/.zattrs +0 -0
  161. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/.zgroup +0 -0
  162. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/0/.zarray +0 -0
  163. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/1/.zarray +0 -0
  164. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/labels/.zattrs +0 -0
  165. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/labels/.zgroup +0 -0
  166. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/labels/label/.zattrs +0 -0
  167. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/labels/label/.zgroup +0 -0
  168. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/labels/label/0/.zarray +0 -0
  169. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_cyx.zarr/labels/label/1/.zarray +0 -0
  170. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/.zattrs +0 -0
  171. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/.zgroup +0 -0
  172. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/0/.zarray +0 -0
  173. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/1/.zarray +0 -0
  174. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/labels/.zattrs +0 -0
  175. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/labels/.zgroup +0 -0
  176. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/labels/label/.zattrs +0 -0
  177. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/labels/label/.zgroup +0 -0
  178. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/labels/label/0/.zarray +0 -0
  179. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_czyx.zarr/labels/label/1/.zarray +0 -0
  180. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/.zattrs +0 -0
  181. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/.zgroup +0 -0
  182. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/0/.zarray +0 -0
  183. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/1/.zarray +0 -0
  184. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/labels/.zattrs +0 -0
  185. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/labels/.zgroup +0 -0
  186. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/.zattrs +0 -0
  187. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/.zgroup +0 -0
  188. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/0/.zarray +0 -0
  189. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/1/.zarray +0 -0
  190. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/.zattrs +0 -0
  191. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/.zgroup +0 -0
  192. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/0/.zarray +0 -0
  193. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/1/.zarray +0 -0
  194. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/labels/.zattrs +0 -0
  195. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/labels/.zgroup +0 -0
  196. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/.zattrs +0 -0
  197. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/.zgroup +0 -0
  198. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/0/.zarray +0 -0
  199. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/1/.zarray +0 -0
  200. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/.zattrs +0 -0
  201. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/.zgroup +0 -0
  202. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/0/.zarray +0 -0
  203. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/1/.zarray +0 -0
  204. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/labels/.zattrs +0 -0
  205. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/labels/.zgroup +0 -0
  206. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/labels/label/.zattrs +0 -0
  207. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/labels/label/.zgroup +0 -0
  208. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/labels/label/0/.zarray +0 -0
  209. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tyx.zarr/labels/label/1/.zarray +0 -0
  210. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/.zattrs +0 -0
  211. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/.zgroup +0 -0
  212. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/0/.zarray +0 -0
  213. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/1/.zarray +0 -0
  214. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/labels/.zattrs +0 -0
  215. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/labels/.zgroup +0 -0
  216. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/.zattrs +0 -0
  217. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/.zgroup +0 -0
  218. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/0/.zarray +0 -0
  219. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/1/.zarray +0 -0
  220. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/.zattrs +0 -0
  221. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/.zgroup +0 -0
  222. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/0/.zarray +0 -0
  223. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/1/.zarray +0 -0
  224. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/labels/.zattrs +0 -0
  225. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/labels/.zgroup +0 -0
  226. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/labels/label/.zattrs +0 -0
  227. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/labels/label/.zgroup +0 -0
  228. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/labels/label/0/.zarray +0 -0
  229. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_yx.zarr/labels/label/1/.zarray +0 -0
  230. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/.zattrs +0 -0
  231. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/.zgroup +0 -0
  232. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/0/.zarray +0 -0
  233. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/1/.zarray +0 -0
  234. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/labels/.zattrs +0 -0
  235. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/labels/.zgroup +0 -0
  236. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/labels/label/.zattrs +0 -0
  237. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/labels/label/.zgroup +0 -0
  238. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/labels/label/0/.zarray +0 -0
  239. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/images/test_image_zyx.zarr/labels/label/1/.zarray +0 -0
  240. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/meta/base_ome_zarr_image_meta.json +0 -0
  241. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/meta/base_ome_zarr_image_meta_wrong_axis_order.json +0 -0
  242. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/meta/base_ome_zarr_label_meta.json +0 -0
  243. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/meta/base_ome_zarr_well_meta.json +0 -0
  244. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/data/v04/meta/ome_zarr_well_path_normalization_meta.json +0 -0
  245. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/hcs/test_plate.py +0 -0
  246. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/hcs/test_well.py +0 -0
  247. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/images/test_create.py +0 -0
  248. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/images/test_table_ops.py +0 -0
  249. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/iterators/test_iterators.py +0 -0
  250. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/ome_zarr_meta/test_image_handler.py +0 -0
  251. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/ome_zarr_meta/test_unit_v04_utils.py +0 -0
  252. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/tables/test_backends.py +0 -0
  253. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/tables/test_backends_utils.py +0 -0
  254. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/tables/test_feature_table.py +0 -0
  255. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/tables/test_generic_table.py +0 -0
  256. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/tables/test_masking_roi_table_v1.py +0 -0
  257. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/tables/test_roi_table_v1.py +0 -0
  258. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/tables/test_table_group.py +0 -0
  259. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/utils/test_download_datasets.py +0 -0
  260. {ngio-0.4.0a2 → ngio-0.4.0a4}/tests/unit/utils/test_zarr_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngio
3
- Version: 0.4.0a2
3
+ Version: 0.4.0a4
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
@@ -38,7 +38,7 @@ Ngio supports three types of tables: `roi_table`, `feature_table`, and `masking_
38
38
  image_data = image_3.get_array(c=0)
39
39
  image_data = np.squeeze(image_data)
40
40
  roi = roi_table.get("FOV_1")
41
- roi = roi.to_roi_pixels(pixel_size=image_3.pixel_size, dimensions=image_3.dimensions)
41
+ roi = roi.to_roi_pixels(pixel_size=image_3.pixel_size)
42
42
  #label_3 = ome_zarr_container.get_label("nuclei", pixel_size=image_3.pixel_size)
43
43
  #label_data = label_3.get_array()
44
44
  #label_data = np.squeeze(label_data)
@@ -9,7 +9,7 @@ except PackageNotFoundError: # pragma: no cover
9
9
  __author__ = "Lorenzo Cerrone"
10
10
  __email__ = "lorenzo.cerrone@uzh.ch"
11
11
 
12
- from ngio.common import ArrayLike, Dimensions, Roi, RoiPixels
12
+ from ngio.common import Dimensions, Roi, RoiPixels
13
13
  from ngio.hcs import (
14
14
  OmeZarrPlate,
15
15
  OmeZarrWell,
@@ -39,7 +39,6 @@ from ngio.ome_zarr_meta.ngio_specs import (
39
39
  )
40
40
 
41
41
  __all__ = [
42
- "ArrayLike",
43
42
  "AxesSetup",
44
43
  "ChannelSelectionModel",
45
44
  "DefaultNgffVersion",
@@ -0,0 +1,23 @@
1
+ """Common classes and functions that are used across the package."""
2
+
3
+ from ngio.common._dimensions import Dimensions
4
+ from ngio.common._masking_roi import compute_masking_roi
5
+ from ngio.common._pyramid import consolidate_pyramid, init_empty_pyramid, on_disk_zoom
6
+ from ngio.common._roi import (
7
+ Roi,
8
+ RoiPixels,
9
+ )
10
+ from ngio.common._zoom import InterpolationOrder, dask_zoom, numpy_zoom
11
+
12
+ __all__ = [
13
+ "Dimensions",
14
+ "InterpolationOrder",
15
+ "Roi",
16
+ "RoiPixels",
17
+ "compute_masking_roi",
18
+ "consolidate_pyramid",
19
+ "dask_zoom",
20
+ "init_empty_pyramid",
21
+ "numpy_zoom",
22
+ "on_disk_zoom",
23
+ ]
@@ -0,0 +1,315 @@
1
+ """Dimension metadata.
2
+
3
+ This is not related to the NGFF metadata,
4
+ but it is based on the actual metadata of the image data.
5
+ """
6
+
7
+ import math
8
+ from typing import overload
9
+
10
+ from ngio.ome_zarr_meta import (
11
+ AxesHandler,
12
+ )
13
+ from ngio.ome_zarr_meta.ngio_specs._dataset import Dataset
14
+ from ngio.ome_zarr_meta.ngio_specs._pixel_size import PixelSize
15
+ from ngio.utils import NgioValueError
16
+
17
+
18
+ class Dimensions:
19
+ """Dimension metadata Handling Class.
20
+
21
+ This class is used to handle and manipulate dimension metadata.
22
+ It provides methods to access and validate dimension information,
23
+ such as shape, axes, and properties like is_2d, is_3d, is_time_series, etc.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ shape: tuple[int, ...],
29
+ dataset: Dataset,
30
+ ) -> None:
31
+ """Create a Dimension object from a Zarr array.
32
+
33
+ Args:
34
+ shape: The shape of the Zarr array.
35
+ dataset: The dataset object.
36
+ """
37
+ self._shape = shape
38
+ self._axes_handler = dataset.axes_handler
39
+ self._pixel_size = dataset.pixel_size
40
+
41
+ if len(self._shape) != len(self._axes_handler.axes):
42
+ raise NgioValueError(
43
+ "The number of dimensions must match the number of axes. "
44
+ f"Expected Axis {self._axes_handler.axes_names} but got shape "
45
+ f"{self._shape}."
46
+ )
47
+
48
+ def __str__(self) -> str:
49
+ """Return the string representation of the object."""
50
+ dims = ", ".join(
51
+ f"{ax.name}: {s}"
52
+ for ax, s in zip(self._axes_handler.axes, self._shape, strict=True)
53
+ )
54
+ return f"Dimensions({dims})"
55
+
56
+ def __repr__(self) -> str:
57
+ """Return the string representation of the object."""
58
+ return str(self)
59
+
60
+ @property
61
+ def axes_handler(self) -> AxesHandler:
62
+ """Return the axes handler object."""
63
+ return self._axes_handler
64
+
65
+ @property
66
+ def pixel_size(self) -> PixelSize:
67
+ """Return the pixel size object."""
68
+ return self._pixel_size
69
+
70
+ @property
71
+ def shape(self) -> tuple[int, ...]:
72
+ """Return the shape as a tuple."""
73
+ return tuple(self._shape)
74
+
75
+ @property
76
+ def axes(self) -> tuple[str, ...]:
77
+ """Return the axes as a tuple of strings."""
78
+ return self.axes_handler.axes_names
79
+
80
+ @property
81
+ def is_time_series(self) -> bool:
82
+ """Return whether the data is a time series."""
83
+ if self.get("t", default=1) == 1:
84
+ return False
85
+ return True
86
+
87
+ @property
88
+ def is_2d(self) -> bool:
89
+ """Return whether the data is 2D."""
90
+ if self.get("z", default=1) != 1:
91
+ return False
92
+ return True
93
+
94
+ @property
95
+ def is_2d_time_series(self) -> bool:
96
+ """Return whether the data is a 2D time series."""
97
+ return self.is_2d and self.is_time_series
98
+
99
+ @property
100
+ def is_3d(self) -> bool:
101
+ """Return whether the data is 3D."""
102
+ return not self.is_2d
103
+
104
+ @property
105
+ def is_3d_time_series(self) -> bool:
106
+ """Return whether the data is a 3D time series."""
107
+ return self.is_3d and self.is_time_series
108
+
109
+ @property
110
+ def is_multi_channels(self) -> bool:
111
+ """Return whether the data has multiple channels."""
112
+ if self.get("c", default=1) == 1:
113
+ return False
114
+ return True
115
+
116
+ @overload
117
+ def get(self, axis_name: str, default: None = None) -> int | None:
118
+ pass
119
+
120
+ @overload
121
+ def get(self, axis_name: str, default: int) -> int:
122
+ pass
123
+
124
+ def get(self, axis_name: str, default: int | None = None) -> int | None:
125
+ """Return the dimension of the given axis name.
126
+
127
+ Args:
128
+ axis_name: The name of the axis (either canonical or non-canonical).
129
+ default: The default value to return if the axis does not exist.
130
+ """
131
+ index = self.axes_handler.get_index(axis_name)
132
+ if index is None:
133
+ return default
134
+ return self._shape[index]
135
+
136
+ def get_index(self, axis_name: str) -> int | None:
137
+ """Return the index of the given axis name.
138
+
139
+ Args:
140
+ axis_name: The name of the axis (either canonical or non-canonical).
141
+ """
142
+ return self.axes_handler.get_index(axis_name)
143
+
144
+ def has_axis(self, axis_name: str) -> bool:
145
+ """Return whether the axis exists."""
146
+ index = self.axes_handler.get_index(axis_name)
147
+ if index is None:
148
+ return False
149
+ return True
150
+
151
+ def require_axes_match(self, other: "Dimensions") -> None:
152
+ """Check if two Dimensions objects have the same axes.
153
+
154
+ Besides the channel axis (which is a special case), all axes must be
155
+ present in both Dimensions objects.
156
+
157
+ Args:
158
+ other (Dimensions): The other dimensions object to compare against.
159
+
160
+ Raises:
161
+ NgioValueError: If the axes do not match.
162
+ """
163
+ require_axes_match(self, other)
164
+
165
+ def require_dimensions_match(
166
+ self, other: "Dimensions", allow_singleton: bool = False
167
+ ) -> None:
168
+ """Check if two Dimensions objects have the same axes and dimensions.
169
+
170
+ Besides the channel axis, all axes must have the same dimension in
171
+ both images.
172
+
173
+ Args:
174
+ other (Dimensions): The other dimensions object to compare against.
175
+ allow_singleton (bool): Whether to allow singleton dimensions to be
176
+ different. For example, if the input image has shape
177
+ (5, 100, 100) and the label has shape (1, 100, 100).
178
+
179
+ Raises:
180
+ NgioValueError: If the dimensions do not match.
181
+ """
182
+ require_dimensions_match(self, other, allow_singleton)
183
+
184
+ def require_can_be_rescaled(self, other: "Dimensions") -> None:
185
+ """Assert that two images can be rescaled.
186
+
187
+ For this to be true, the images must have the same axes, and
188
+ the pixel sizes must be compatible (i.e. one can be scaled to the other).
189
+
190
+ Args:
191
+ other (Dimensions): The other dimensions object to compare against.
192
+
193
+ """
194
+ require_rescalable(self, other)
195
+
196
+
197
+ def _are_compatible(shape1: int, shape2: int, scaling: float) -> bool:
198
+ """Check if shape2 is consistent with shape1 given pixel sizes.
199
+
200
+ Since we only deal with shape discrepancies due to rounding, we
201
+ shape1, needs to be larger than shape2.
202
+ """
203
+ if shape1 < shape2:
204
+ return _are_compatible(shape2, shape1, 1 / scaling)
205
+ expected_shape2 = shape1 * scaling
206
+ expected_shape2_floor = math.floor(expected_shape2)
207
+ expected_shape2_ceil = math.ceil(expected_shape2)
208
+ return shape2 in {expected_shape2_floor, expected_shape2_ceil}
209
+
210
+
211
+ def require_axes_match(dimensions1: Dimensions, dimensions2: Dimensions) -> None:
212
+ """Check if two Dimensions objects have the same axes.
213
+
214
+ Besides the channel axis (which is a special case), all axes must be
215
+ present in both Dimensions objects.
216
+
217
+ Args:
218
+ dimensions1 (Dimensions): The first dimensions object to compare against.
219
+ dimensions2 (Dimensions): The second dimensions object to compare against.
220
+
221
+ Raises:
222
+ NgioValueError: If the axes do not match.
223
+ """
224
+ for s_axis in dimensions1.axes_handler.axes:
225
+ if s_axis.axis_type == "channel":
226
+ continue
227
+ o_axis = dimensions2.axes_handler.get_axis(s_axis.name)
228
+ if o_axis is None:
229
+ raise NgioValueError(
230
+ f"Axes do not match. The axis {s_axis.name} "
231
+ f"is not present in either dimensions."
232
+ )
233
+ # Check for axes present in the other dimensions but not in this one
234
+ for o_axis in dimensions2.axes_handler.axes:
235
+ if o_axis.axis_type == "channel":
236
+ continue
237
+ s_axis = dimensions1.axes_handler.get_axis(o_axis.name)
238
+ if s_axis is None:
239
+ raise NgioValueError(
240
+ f"Axes do not match. The axis {o_axis.name} "
241
+ f"is not present in either dimensions."
242
+ )
243
+
244
+
245
+ def require_dimensions_match(
246
+ dimensions1: Dimensions, dimensions2: Dimensions, allow_singleton: bool = False
247
+ ) -> None:
248
+ """Check if two Dimensions objects have the same axes and dimensions.
249
+
250
+ Besides the channel axis, all axes must have the same dimension in
251
+ both images.
252
+
253
+ Args:
254
+ dimensions1 (Dimensions): The first dimensions object to compare against.
255
+ dimensions2 (Dimensions): The second dimensions object to compare against.
256
+ allow_singleton (bool): Whether to allow singleton dimensions to be
257
+ different. For example, if the input image has shape
258
+ (5, 100, 100) and the label has shape (1, 100, 100).
259
+
260
+ Raises:
261
+ NgioValueError: If the dimensions do not match.
262
+ """
263
+ require_axes_match(dimensions1, dimensions2)
264
+ for s_axis in dimensions1.axes_handler.axes:
265
+ if s_axis.axis_type == "channel":
266
+ continue
267
+ o_axis = dimensions2.axes_handler.get_axis(s_axis.name)
268
+ assert o_axis is not None # already checked in assert_axes_match
269
+
270
+ i_dim = dimensions1.get(s_axis.name, default=1)
271
+ o_dim = dimensions2.get(o_axis.name, default=1)
272
+
273
+ if i_dim != o_dim:
274
+ if allow_singleton and (i_dim == 1 or o_dim == 1):
275
+ continue
276
+ raise NgioValueError(
277
+ f"Dimensions do not match for axis "
278
+ f"{s_axis.name}. Got {i_dim} and {o_dim}."
279
+ )
280
+
281
+
282
+ def require_rescalable(dimensions1: Dimensions, dimensions2: Dimensions) -> None:
283
+ """Assert that two images can be rescaled.
284
+
285
+ For this to be true, the images must have the same axes, and
286
+ the pixel sizes must be compatible (i.e. one can be scaled to the other).
287
+
288
+ Args:
289
+ dimensions1 (Dimensions): The first dimensions object to compare against.
290
+ dimensions2 (Dimensions): The second dimensions object to compare against.
291
+
292
+ """
293
+ require_axes_match(dimensions1, dimensions2)
294
+ for ax1 in dimensions1.axes_handler.axes:
295
+ if ax1.axis_type == "channel":
296
+ continue
297
+ ax2 = dimensions2.axes_handler.get_axis(ax1.name)
298
+ assert ax2 is not None, "Axes do not match."
299
+ px1 = dimensions1.pixel_size.get(ax1.name, default=1.0)
300
+ px2 = dimensions2.pixel_size.get(ax2.name, default=1.0)
301
+ shape1 = dimensions1.get(ax1.name, default=1)
302
+ shape2 = dimensions2.get(ax2.name, default=1)
303
+ scale = px1 / px2
304
+ if not _are_compatible(
305
+ shape1=shape1,
306
+ shape2=shape2,
307
+ scaling=scale,
308
+ ):
309
+ raise NgioValueError(
310
+ f"Image1 with shape {dimensions1.shape}, "
311
+ f"and pixel size {dimensions1.pixel_size}, "
312
+ f"cannot be rescaled to "
313
+ f"Image2 with shape {dimensions2.shape}, "
314
+ f"and pixel size {dimensions2.pixel_size}. "
315
+ )
@@ -5,8 +5,14 @@ from typing import Literal
5
5
  import dask.array as da
6
6
  import numpy as np
7
7
  import zarr
8
+ from zarr.types import DIMENSION_SEPARATOR
8
9
 
9
- from ngio.common._zoom import _zoom_inputs_check, dask_zoom, numpy_zoom
10
+ from ngio.common._zoom import (
11
+ InterpolationOrder,
12
+ _zoom_inputs_check,
13
+ dask_zoom,
14
+ numpy_zoom,
15
+ )
10
16
  from ngio.utils import (
11
17
  AccessModeLiteral,
12
18
  NgioValueError,
@@ -18,7 +24,7 @@ from ngio.utils import (
18
24
  def _on_disk_numpy_zoom(
19
25
  source: zarr.Array,
20
26
  target: zarr.Array,
21
- order: Literal[0, 1, 2] = 1,
27
+ order: InterpolationOrder,
22
28
  ) -> None:
23
29
  target[...] = numpy_zoom(source[...], target_shape=target.shape, order=order)
24
30
 
@@ -26,7 +32,7 @@ def _on_disk_numpy_zoom(
26
32
  def _on_disk_dask_zoom(
27
33
  source: zarr.Array,
28
34
  target: zarr.Array,
29
- order: Literal[0, 1, 2] = 1,
35
+ order: InterpolationOrder,
30
36
  ) -> None:
31
37
  source_array = da.from_zarr(source)
32
38
  target_array = dask_zoom(source_array, target_shape=target.shape, order=order)
@@ -39,7 +45,7 @@ def _on_disk_dask_zoom(
39
45
  def _on_disk_coarsen(
40
46
  source: zarr.Array,
41
47
  target: zarr.Array,
42
- _order: Literal[0, 1] = 1,
48
+ order: InterpolationOrder = "linear",
43
49
  aggregation_function: Callable | None = None,
44
50
  ) -> None:
45
51
  """Apply a coarsening operation from a source zarr array to a target zarr array.
@@ -47,10 +53,10 @@ def _on_disk_coarsen(
47
53
  Args:
48
54
  source (zarr.Array): The source array to coarsen.
49
55
  target (zarr.Array): The target array to save the coarsened result to.
50
- _order (Literal[0, 1]): The order of interpolation is not really implemented
56
+ order (InterpolationOrder): The order of interpolation is not really implemented
51
57
  for coarsening, but it is kept for compatibility with the zoom function.
52
- _order=1 -> linear interpolation ~ np.mean
53
- _order=0 -> nearest interpolation ~ np.max
58
+ order="linear" -> linear interpolation ~ np.mean
59
+ order="nearest" -> nearest interpolation ~ np.max
54
60
  aggregation_function (np.ufunc): The aggregation function to use.
55
61
  """
56
62
  source_array = da.from_zarr(source)
@@ -64,13 +70,15 @@ def _on_disk_coarsen(
64
70
  )
65
71
 
66
72
  if aggregation_function is None:
67
- if _order == 1:
73
+ if order == "linear":
68
74
  aggregation_function = np.mean
69
- elif _order == 0:
75
+ elif order == "nearest":
70
76
  aggregation_function = np.max
77
+ elif order == "cubic":
78
+ raise NgioValueError("Cubic interpolation is not supported for coarsening.")
71
79
  else:
72
80
  raise NgioValueError(
73
- f"Aggregation function must be provided for order {_order}"
81
+ f"Aggregation function must be provided for order {order}"
74
82
  )
75
83
 
76
84
  coarsening_setup = {}
@@ -96,7 +104,7 @@ def _on_disk_coarsen(
96
104
  def on_disk_zoom(
97
105
  source: zarr.Array,
98
106
  target: zarr.Array,
99
- order: Literal[0, 1, 2] = 1,
107
+ order: InterpolationOrder = "linear",
100
108
  mode: Literal["dask", "numpy", "coarsen"] = "dask",
101
109
  ) -> None:
102
110
  """Apply a zoom operation from a source zarr array to a target zarr array.
@@ -104,7 +112,7 @@ def on_disk_zoom(
104
112
  Args:
105
113
  source (zarr.Array): The source array to zoom.
106
114
  target (zarr.Array): The target array to save the zoomed result to.
107
- order (Literal[0, 1, 2]): The order of interpolation. Defaults to 1.
115
+ order (InterpolationOrder): The order of interpolation. Defaults to "linear".
108
116
  mode (Literal["dask", "numpy", "coarsen"]): The mode to use. Defaults to "dask".
109
117
  """
110
118
  if not isinstance(source, zarr.Array):
@@ -155,7 +163,7 @@ def _find_closest_arrays(
155
163
  def consolidate_pyramid(
156
164
  source: zarr.Array,
157
165
  targets: list[zarr.Array],
158
- order: Literal[0, 1, 2] = 1,
166
+ order: InterpolationOrder = "linear",
159
167
  mode: Literal["dask", "numpy", "coarsen"] = "dask",
160
168
  ) -> None:
161
169
  """Consolidate the Zarr array."""
@@ -177,6 +185,15 @@ def consolidate_pyramid(
177
185
  processed.append(target_image)
178
186
 
179
187
 
188
+ def _maybe_int(value: float | int) -> float | int:
189
+ """Convert a float to an int if it is an integer."""
190
+ if isinstance(value, int):
191
+ return value
192
+ if value.is_integer():
193
+ return int(value)
194
+ return value
195
+
196
+
180
197
  def init_empty_pyramid(
181
198
  store: StoreOrGroup,
182
199
  paths: list[str],
@@ -185,6 +202,8 @@ def init_empty_pyramid(
185
202
  chunks: Sequence[int] | None = None,
186
203
  dtype: str = "uint16",
187
204
  mode: AccessModeLiteral = "a",
205
+ dimension_separator: DIMENSION_SEPARATOR = "/",
206
+ compressor="default",
188
207
  ) -> None:
189
208
  # Return the an Image object
190
209
  if chunks is not None and len(chunks) != len(ref_shape):
@@ -200,6 +219,10 @@ def init_empty_pyramid(
200
219
  "The shape and scaling factor must have the same number of dimensions."
201
220
  )
202
221
 
222
+ # Ensure scaling factors are int if possible
223
+ # To reduce the risk of floating point issues
224
+ scaling_factors = [_maybe_int(s) for s in scaling_factors]
225
+
203
226
  root_group = open_group_wrapper(store, mode=mode)
204
227
 
205
228
  for path in paths:
@@ -213,22 +236,18 @@ def init_empty_pyramid(
213
236
  shape=ref_shape,
214
237
  dtype=dtype,
215
238
  chunks=chunks,
216
- dimension_separator="/",
239
+ dimension_separator=dimension_separator,
217
240
  overwrite=True,
241
+ compressor=compressor,
218
242
  )
219
243
 
220
- # Todo redo this with when a proper build of pyramid is implemented
221
- _shape = []
222
- for s, sc in zip(ref_shape, scaling_factors, strict=True):
223
- if math.floor(s / sc) % 2 == 0:
224
- _shape.append(math.floor(s / sc))
225
- else:
226
- _shape.append(math.ceil(s / sc))
244
+ _shape = [
245
+ math.floor(s / sc) for s, sc in zip(ref_shape, scaling_factors, strict=True)
246
+ ]
227
247
  ref_shape = _shape
228
248
 
229
249
  if chunks is None:
230
250
  chunks = new_arr.chunks
231
- if chunks is None:
232
- raise NgioValueError("Something went wrong with the chunks")
251
+ assert chunks is not None
233
252
  chunks = [min(c, s) for c, s in zip(chunks, ref_shape, strict=True)]
234
253
  return None