ngio 0.4.1__tar.gz → 0.4.2__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.
- {ngio-0.4.1 → ngio-0.4.2}/CHANGELOG.md +11 -0
- {ngio-0.4.1 → ngio-0.4.2}/PKG-INFO +1 -1
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/common/_roi.py +51 -18
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_io_pipes_roi.py +4 -10
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_ops_slices.py +23 -58
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_ops_slices_utils.py +4 -4
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +12 -39
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/common/test_roi.py +2 -2
- {ngio-0.4.1 → ngio-0.4.2}/.copier-answers.yml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.gitattributes +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.github/ISSUE_TEMPLATE.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.github/TEST_FAIL_TEMPLATE.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.github/dependabot.yml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.github/pull_request_template.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.github/workflows/build_docs.yml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.github/workflows/ci.yml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.gitignore +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/.pre-commit-config.yaml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/LICENSE +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/README.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/_typos.toml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/hcs.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/images.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/iterators.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/common.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/hcs.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/images.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/io_pipes.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/iterators.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/ngio.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/tables.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/transforms.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ngio/utils.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/ome_zarr_container.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/api/tables.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/changelog.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/code_of_conduct.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/contributing.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/getting_started/0_quickstart.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/getting_started/1_ome_zarr_containers.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/getting_started/2_images.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/getting_started/3_tables.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/getting_started/4_masked_images.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/getting_started/5_hcs.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/getting_started/6_iterators.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/index.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/backend.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/overview.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/table_types/condition_table.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/table_types/custom_table.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/table_types/feature_table.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/table_types/generic_table.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/table_types/masking_roi_table.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/table_specs/table_types/roi_table.md +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/tutorials/create_ome_zarr.ipynb +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/tutorials/feature_extraction.ipynb +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/tutorials/hcs_exploration.ipynb +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/tutorials/image_processing.ipynb +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/docs/tutorials/image_segmentation.ipynb +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/mkdocs.yml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/pyproject.toml +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/common/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/common/_dimensions.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/common/_masking_roi.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/common/_pyramid.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/common/_synt_images_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/common/_zoom.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/iterators/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/iterators/_abstract_iterator.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/iterators/_feature.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/iterators/_image_processing.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/iterators/_mappers.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/iterators/_rois_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/experimental/iterators/_segmentation.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/hcs/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/hcs/_plate.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_abstract_image.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_create.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_create_synt_container.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_image.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_label.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_masked_image.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_ome_zarr_container.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/images/_table_ops.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_io_pipes.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_io_pipes_masked.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_io_pipes_types.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_match_shape.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_ops_axes.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_ops_transforms.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/io_pipes/_zoom_transform.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/_meta_handlers.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/ngio_specs/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/ngio_specs/_axes.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/ngio_specs/_channels.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/ngio_specs/_dataset.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/v04/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/v04/_custom_models.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/ome_zarr_meta/v04/_v04_spec_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/resources/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/resources/resource_model.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/_abstract_table.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/_tables_container.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_abstract_backend.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_anndata.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_anndata_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_csv.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_json.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_non_zarr_backends.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_parquet.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_table_backends.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/backends/_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/v1/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/v1/_condition_table.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/v1/_feature_table.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/v1/_generic_table.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/tables/v1/_roi_table.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/transforms/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/transforms/_zoom.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/utils/__init__.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/utils/_datasets.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/utils/_errors.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/utils/_fractal_fsspec_store.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/utils/_logger.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/src/ngio/utils/_zarr_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/conftest.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_c1yx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_cyx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_czyx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tcyx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tczyx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tyx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_tzyx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_yx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/labels/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/labels/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/labels/label/.zattrs +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/labels/label/.zgroup +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/labels/label/0/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/images/test_image_zyx.zarr/labels/label/1/.zarray +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/meta/base_ome_zarr_image_meta.json +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/meta/base_ome_zarr_image_meta_wrong_axis_order.json +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/meta/base_ome_zarr_label_meta.json +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/meta/base_ome_zarr_well_meta.json +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/data/v04/meta/ome_zarr_well_path_normalization_meta.json +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/common/test_dimensions.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/common/test_pyramid.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/common/test_transforms.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/hcs/test_plate.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/hcs/test_well.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/images/test_create.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/images/test_images.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/images/test_masked_images.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/images/test_omezarr_container.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/images/test_table_ops.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/io_pipes/test_axes_ops.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/io_pipes/test_slicing_ops.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/iterators/test_iterators.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/ome_zarr_meta/test_image_handler.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/ome_zarr_meta/test_unit_ngio_specs.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/ome_zarr_meta/test_unit_v04_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/tables/test_backends.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/tables/test_backends_utils.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/tables/test_feature_table.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/tables/test_generic_table.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/tables/test_masking_roi_table_v1.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/tables/test_roi_table_v1.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/tables/test_table_group.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/utils/test_download_datasets.py +0 -0
- {ngio-0.4.1 → ngio-0.4.2}/tests/unit/utils/test_zarr_utils.py +0 -0
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v0.4.2]
|
|
4
|
+
|
|
5
|
+
### API Changes
|
|
6
|
+
|
|
7
|
+
- Make roi.to_slicing_dict(pixel_size) always require pixel_size argument for consistency with other roi methods.
|
|
8
|
+
- Make PixelSize object a Pydantic model to allow for serialization.
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
- Improve robustness when rounding Rois to pixel coordinates.
|
|
13
|
+
|
|
3
14
|
## [v0.4.1]
|
|
4
15
|
|
|
5
16
|
### Bug Fixes
|
|
@@ -14,9 +14,22 @@ from ngio.ome_zarr_meta.ngio_specs import DefaultSpaceUnit, PixelSize, SpaceUnit
|
|
|
14
14
|
from ngio.utils import NgioValueError
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def
|
|
17
|
+
def _world_to_raster(value: float, pixel_size: float, eps: float = 1e-6) -> float:
|
|
18
18
|
raster_value = value / pixel_size
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
# If the value is very close to an integer, round it
|
|
21
|
+
# This ensures that we don't have floating point precision issues
|
|
22
|
+
# When loading ROIs that were originally defined in pixel coordinates
|
|
23
|
+
_rounded = round(raster_value)
|
|
24
|
+
if abs(_rounded - raster_value) < eps:
|
|
25
|
+
return _rounded
|
|
26
|
+
return raster_value
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _to_raster(value: float, length: float, pixel_size: float) -> tuple[float, float]:
|
|
30
|
+
"""Convert to raster coordinates."""
|
|
31
|
+
raster_value = _world_to_raster(value, pixel_size)
|
|
32
|
+
raster_length = _world_to_raster(length, pixel_size)
|
|
20
33
|
return raster_value, raster_length
|
|
21
34
|
|
|
22
35
|
|
|
@@ -29,7 +42,7 @@ def _to_slice(start: float | None, length: float | None) -> slice:
|
|
|
29
42
|
return slice(start, end)
|
|
30
43
|
|
|
31
44
|
|
|
32
|
-
def
|
|
45
|
+
def _raster_to_world(value: int | float, pixel_size: float) -> float:
|
|
33
46
|
"""Convert to world coordinates."""
|
|
34
47
|
return value * pixel_size
|
|
35
48
|
|
|
@@ -60,16 +73,28 @@ class GenericRoi(BaseModel):
|
|
|
60
73
|
|
|
61
74
|
def _nice_str(self) -> str:
|
|
62
75
|
if self.t is not None:
|
|
63
|
-
|
|
76
|
+
t_start = self.t
|
|
77
|
+
else:
|
|
78
|
+
t_start = None
|
|
79
|
+
if self.t_length is not None and t_start is not None:
|
|
80
|
+
t_end = t_start + self.t_length
|
|
64
81
|
else:
|
|
65
|
-
|
|
82
|
+
t_end = None
|
|
83
|
+
|
|
84
|
+
t_str = f"t={t_start}->{t_end}"
|
|
85
|
+
|
|
66
86
|
if self.z is not None:
|
|
67
|
-
|
|
87
|
+
z_start = self.z
|
|
88
|
+
else:
|
|
89
|
+
z_start = None
|
|
90
|
+
if self.z_length is not None and z_start is not None:
|
|
91
|
+
z_end = z_start + self.z_length
|
|
68
92
|
else:
|
|
69
|
-
|
|
93
|
+
z_end = None
|
|
94
|
+
z_str = f"z={z_start}->{z_end}"
|
|
70
95
|
|
|
71
|
-
y_str = f"y={self.y}->{self.y_length}"
|
|
72
|
-
x_str = f"x={self.x}->{self.x_length}"
|
|
96
|
+
y_str = f"y={self.y}->{self.y + self.y_length}"
|
|
97
|
+
x_str = f"x={self.x}->{self.x + self.x_length}"
|
|
73
98
|
|
|
74
99
|
if self.label is not None:
|
|
75
100
|
label_str = f", label={self.label}"
|
|
@@ -90,6 +115,9 @@ class GenericRoi(BaseModel):
|
|
|
90
115
|
def __str__(self) -> str:
|
|
91
116
|
return self._nice_str()
|
|
92
117
|
|
|
118
|
+
def to_slicing_dict(self, pixel_size: PixelSize) -> dict[str, slice]:
|
|
119
|
+
raise NotImplementedError
|
|
120
|
+
|
|
93
121
|
|
|
94
122
|
def _1d_intersection(
|
|
95
123
|
a: T | None, a_length: T | None, b: T | None, b_length: T | None
|
|
@@ -251,6 +279,11 @@ class Roi(GenericRoi):
|
|
|
251
279
|
"""
|
|
252
280
|
return zoom_roi(self, zoom_factor)
|
|
253
281
|
|
|
282
|
+
def to_slicing_dict(self, pixel_size: PixelSize) -> dict[str, slice]:
|
|
283
|
+
"""Convert to a slicing dictionary."""
|
|
284
|
+
roi_pixels = self.to_roi_pixels(pixel_size)
|
|
285
|
+
return roi_pixels.to_slicing_dict(pixel_size)
|
|
286
|
+
|
|
254
287
|
|
|
255
288
|
class RoiPixels(GenericRoi):
|
|
256
289
|
"""Region of interest (ROI) in pixel coordinates."""
|
|
@@ -261,30 +294,30 @@ class RoiPixels(GenericRoi):
|
|
|
261
294
|
|
|
262
295
|
def to_roi(self, pixel_size: PixelSize) -> "Roi":
|
|
263
296
|
"""Convert to raster coordinates."""
|
|
264
|
-
x =
|
|
265
|
-
x_length =
|
|
266
|
-
y =
|
|
267
|
-
y_length =
|
|
297
|
+
x = _raster_to_world(self.x, pixel_size.x)
|
|
298
|
+
x_length = _raster_to_world(self.x_length, pixel_size.x)
|
|
299
|
+
y = _raster_to_world(self.y, pixel_size.y)
|
|
300
|
+
y_length = _raster_to_world(self.y_length, pixel_size.y)
|
|
268
301
|
|
|
269
302
|
if self.z is None:
|
|
270
303
|
z = None
|
|
271
304
|
else:
|
|
272
|
-
z =
|
|
305
|
+
z = _raster_to_world(self.z, pixel_size.z)
|
|
273
306
|
|
|
274
307
|
if self.z_length is None:
|
|
275
308
|
z_length = None
|
|
276
309
|
else:
|
|
277
|
-
z_length =
|
|
310
|
+
z_length = _raster_to_world(self.z_length, pixel_size.z)
|
|
278
311
|
|
|
279
312
|
if self.t is None:
|
|
280
313
|
t = None
|
|
281
314
|
else:
|
|
282
|
-
t =
|
|
315
|
+
t = _raster_to_world(self.t, pixel_size.t)
|
|
283
316
|
|
|
284
317
|
if self.t_length is None:
|
|
285
318
|
t_length = None
|
|
286
319
|
else:
|
|
287
|
-
t_length =
|
|
320
|
+
t_length = _raster_to_world(self.t_length, pixel_size.t)
|
|
288
321
|
|
|
289
322
|
extra_dict = self.model_extra if self.model_extra else {}
|
|
290
323
|
return Roi(
|
|
@@ -302,7 +335,7 @@ class RoiPixels(GenericRoi):
|
|
|
302
335
|
**extra_dict,
|
|
303
336
|
)
|
|
304
337
|
|
|
305
|
-
def to_slicing_dict(self) -> dict[str, slice]:
|
|
338
|
+
def to_slicing_dict(self, pixel_size: PixelSize) -> dict[str, slice]:
|
|
306
339
|
"""Convert to a slicing dictionary."""
|
|
307
340
|
x_slice = _to_slice(self.x, self.x_length)
|
|
308
341
|
y_slice = _to_slice(self.y, self.y_length)
|
|
@@ -13,24 +13,18 @@ from ngio.io_pipes._io_pipes import (
|
|
|
13
13
|
from ngio.io_pipes._ops_slices import SlicingInputType
|
|
14
14
|
from ngio.io_pipes._ops_transforms import TransformProtocol
|
|
15
15
|
from ngio.ome_zarr_meta.ngio_specs._pixel_size import PixelSize
|
|
16
|
-
from ngio.utils import NgioValueError
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
def roi_to_slicing_dict(
|
|
20
19
|
*,
|
|
21
20
|
roi: Roi | RoiPixels,
|
|
22
|
-
pixel_size: PixelSize
|
|
21
|
+
pixel_size: PixelSize,
|
|
23
22
|
slicing_dict: dict[str, SlicingInputType] | None = None,
|
|
24
23
|
) -> dict[str, SlicingInputType]:
|
|
25
24
|
"""Convert a ROI to a slicing dictionary."""
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"pixel_size must be provided when converting a Roi to slice_kwargs."
|
|
30
|
-
)
|
|
31
|
-
roi = roi.to_roi_pixels(pixel_size=pixel_size)
|
|
32
|
-
|
|
33
|
-
roi_slicing_dict: dict[str, SlicingInputType] = roi.to_slicing_dict() # type: ignore
|
|
25
|
+
roi_slicing_dict: dict[str, SlicingInputType] = roi.to_slicing_dict(
|
|
26
|
+
pixel_size=pixel_size
|
|
27
|
+
) # type: ignore
|
|
34
28
|
if slicing_dict is None:
|
|
35
29
|
return roi_slicing_dict
|
|
36
30
|
|
|
@@ -14,7 +14,7 @@ from ngio.ome_zarr_meta.ngio_specs import Axis
|
|
|
14
14
|
from ngio.utils import NgioValueError
|
|
15
15
|
|
|
16
16
|
SlicingInputType: TypeAlias = slice | Sequence[int] | int | None
|
|
17
|
-
SlicingType: TypeAlias = slice |
|
|
17
|
+
SlicingType: TypeAlias = slice | list[int] | int
|
|
18
18
|
|
|
19
19
|
##############################################################
|
|
20
20
|
#
|
|
@@ -60,7 +60,7 @@ def _slicing_tuple_boundary_check(
|
|
|
60
60
|
elif isinstance(sl, int):
|
|
61
61
|
_int_boundary_check(sl, shape=sh)
|
|
62
62
|
out_slicing_tuple.append(sl)
|
|
63
|
-
elif isinstance(sl,
|
|
63
|
+
elif isinstance(sl, list):
|
|
64
64
|
[_int_boundary_check(i, shape=sh) for i in sl]
|
|
65
65
|
out_slicing_tuple.append(sl)
|
|
66
66
|
else:
|
|
@@ -115,32 +115,31 @@ class SlicingOps(BaseModel):
|
|
|
115
115
|
return slicing_tuple[ax_index]
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
def
|
|
118
|
+
def _check_list_in_slicing_tuple(
|
|
119
119
|
slicing_tuple: tuple[SlicingType, ...],
|
|
120
|
-
) -> tuple[None, None] | tuple[int,
|
|
121
|
-
"""Check if there are any
|
|
120
|
+
) -> tuple[None, None] | tuple[int, list[int]]:
|
|
121
|
+
"""Check if there are any lists in the slicing tuple.
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
Dask regions when setting data do not support non-contiguous
|
|
124
|
+
selections natively.
|
|
125
|
+
Ngio support a single list in the slicing tuple to allow non-contiguous
|
|
125
126
|
selection (main use case: selecting multiple channels).
|
|
126
127
|
"""
|
|
127
|
-
# Find if the is any
|
|
128
|
+
# Find if the is any list in the slicing tuple
|
|
128
129
|
# If there is one we need to handle it differently
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if not tuple_in_slice:
|
|
133
|
-
# No tuple in the slicing tuple
|
|
130
|
+
list_in_slice = [(i, s) for i, s in enumerate(slicing_tuple) if isinstance(s, list)]
|
|
131
|
+
if not list_in_slice:
|
|
132
|
+
# No list in the slicing tuple
|
|
134
133
|
return None, None
|
|
135
134
|
|
|
136
|
-
if len(
|
|
135
|
+
if len(list_in_slice) > 1:
|
|
137
136
|
raise NotImplementedError(
|
|
138
137
|
"Slicing with multiple non-contiguous tuples/lists "
|
|
139
138
|
"is not supported yet in Ngio. Use directly the "
|
|
140
139
|
"zarr.Array api to get the correct array slice."
|
|
141
140
|
)
|
|
142
141
|
# Complex case, we have exactly one tuple in the slicing tuple
|
|
143
|
-
ax, first_tuple =
|
|
142
|
+
ax, first_tuple = list_in_slice[0]
|
|
144
143
|
if len(first_tuple) > 100:
|
|
145
144
|
warn(
|
|
146
145
|
"Performance warning: "
|
|
@@ -164,38 +163,14 @@ def get_slice_as_numpy(zarr_array: zarr.Array, slicing_ops: SlicingOps) -> np.nd
|
|
|
164
163
|
slicing_tuple = slicing_ops.normalized_slicing_tuple
|
|
165
164
|
# Find if the is any tuple in the slicing tuple
|
|
166
165
|
# If there is one we need to handle it differently
|
|
167
|
-
|
|
168
|
-
if ax is None:
|
|
169
|
-
# Simple case, no tuple in the slicing tuple
|
|
170
|
-
return zarr_array[slicing_tuple]
|
|
171
|
-
|
|
172
|
-
assert first_tuple is not None
|
|
173
|
-
slices = [
|
|
174
|
-
zarr_array[(*slicing_tuple[:ax], idx, *slicing_tuple[ax + 1 :])]
|
|
175
|
-
for idx in first_tuple
|
|
176
|
-
]
|
|
177
|
-
out_array = np.stack(slices, axis=ax)
|
|
178
|
-
return out_array
|
|
166
|
+
return zarr_array[slicing_tuple]
|
|
179
167
|
|
|
180
168
|
|
|
181
169
|
def get_slice_as_dask(zarr_array: zarr.Array, slicing_ops: SlicingOps) -> da.Array:
|
|
182
170
|
"""Get a slice of a zarr array as a dask array."""
|
|
183
171
|
da_array = da.from_zarr(zarr_array)
|
|
184
172
|
slicing_tuple = slicing_ops.normalized_slicing_tuple
|
|
185
|
-
|
|
186
|
-
# If there is one we need to handle it differently
|
|
187
|
-
ax, first_tuple = _check_tuple_in_slicing_tuple(slicing_tuple)
|
|
188
|
-
if ax is None:
|
|
189
|
-
# Base case, no tuple in the slicing tuple
|
|
190
|
-
return da_array[slicing_tuple]
|
|
191
|
-
|
|
192
|
-
assert first_tuple is not None
|
|
193
|
-
slices = [
|
|
194
|
-
da_array[(*slicing_tuple[:ax], idx, *slicing_tuple[ax + 1 :])]
|
|
195
|
-
for idx in first_tuple
|
|
196
|
-
]
|
|
197
|
-
out_array = da.stack(slices, axis=ax)
|
|
198
|
-
return out_array
|
|
173
|
+
return da_array[slicing_tuple]
|
|
199
174
|
|
|
200
175
|
|
|
201
176
|
def set_slice_as_numpy(
|
|
@@ -204,17 +179,7 @@ def set_slice_as_numpy(
|
|
|
204
179
|
slicing_ops: SlicingOps,
|
|
205
180
|
) -> None:
|
|
206
181
|
slice_tuple = slicing_ops.normalized_slicing_tuple
|
|
207
|
-
|
|
208
|
-
if ax is None:
|
|
209
|
-
# Base case, no tuple in the slicing tuple
|
|
210
|
-
zarr_array[slice_tuple] = patch
|
|
211
|
-
return
|
|
212
|
-
|
|
213
|
-
# Complex case, we have exactly one tuple in the slicing tuple
|
|
214
|
-
assert first_tuple is not None
|
|
215
|
-
for i, idx in enumerate(first_tuple):
|
|
216
|
-
_sub_slice = (*slice_tuple[:ax], idx, *slice_tuple[ax + 1 :])
|
|
217
|
-
zarr_array[_sub_slice] = np.take(patch, indices=i, axis=ax)
|
|
182
|
+
zarr_array[slice_tuple] = patch
|
|
218
183
|
|
|
219
184
|
|
|
220
185
|
def handle_int_set_as_dask(
|
|
@@ -237,7 +202,7 @@ def set_slice_as_dask(
|
|
|
237
202
|
zarr_array: zarr.Array, patch: da.Array, slicing_ops: SlicingOps
|
|
238
203
|
) -> None:
|
|
239
204
|
slice_tuple = slicing_ops.normalized_slicing_tuple
|
|
240
|
-
ax, first_tuple =
|
|
205
|
+
ax, first_tuple = _check_list_in_slicing_tuple(slice_tuple)
|
|
241
206
|
patch, slice_tuple = handle_int_set_as_dask(patch, slice_tuple)
|
|
242
207
|
if ax is None:
|
|
243
208
|
# Base case, no tuple in the slicing tuple
|
|
@@ -261,13 +226,13 @@ def set_slice_as_dask(
|
|
|
261
226
|
##############################################################
|
|
262
227
|
|
|
263
228
|
|
|
264
|
-
def _try_to_slice(value: Sequence[int]) -> slice |
|
|
229
|
+
def _try_to_slice(value: Sequence[int]) -> slice | list[int]:
|
|
265
230
|
"""Try to convert a list of integers into a slice if they are contiguous.
|
|
266
231
|
|
|
267
232
|
- If the input is empty, return an empty tuple.
|
|
268
233
|
- If the input is sorted, and contains contiguous integers,
|
|
269
234
|
return a slice from the minimum to the maximum integer.
|
|
270
|
-
- Otherwise, return the input as a
|
|
235
|
+
- Otherwise, return the input as a list of integers.
|
|
271
236
|
|
|
272
237
|
This is useful for optimizing array slicing operations
|
|
273
238
|
by allowing the use of slices when possible, which can be more efficient.
|
|
@@ -293,7 +258,7 @@ def _try_to_slice(value: Sequence[int]) -> slice | tuple[int, ...]:
|
|
|
293
258
|
if sorted(value) == list(range(min_input, max_input + 1)):
|
|
294
259
|
return slice(min_input, max_input + 1)
|
|
295
260
|
|
|
296
|
-
return
|
|
261
|
+
return list(value)
|
|
297
262
|
|
|
298
263
|
|
|
299
264
|
def _remove_channel_slicing(
|
|
@@ -393,7 +358,7 @@ def _normalize_slicing_tuple(
|
|
|
393
358
|
The output types are:
|
|
394
359
|
- slice
|
|
395
360
|
- int
|
|
396
|
-
-
|
|
361
|
+
- list of int (for non-contiguous selection)
|
|
397
362
|
"""
|
|
398
363
|
axis_name = axis.name
|
|
399
364
|
if axis_name not in slicing_dict:
|
|
@@ -408,7 +373,7 @@ def _normalize_slicing_tuple(
|
|
|
408
373
|
elif isinstance(value, Sequence):
|
|
409
374
|
# If a contiguous sequence of integers is provided,
|
|
410
375
|
# convert it to a slice for simplicity.
|
|
411
|
-
# Alternatively, it will be converted to a
|
|
376
|
+
# Alternatively, it will be converted to a list of ints
|
|
412
377
|
return _try_to_slice(value)
|
|
413
378
|
|
|
414
379
|
raise NgioValueError(
|
|
@@ -22,7 +22,7 @@ def _pairs_stream(iterable: Iterable[T]) -> Iterator[tuple[T, T]]:
|
|
|
22
22
|
seen.append(a)
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
SlicingType: TypeAlias = slice |
|
|
25
|
+
SlicingType: TypeAlias = slice | list[int] | int
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def check_elem_intersection(s1: SlicingType, s2: SlicingType) -> bool:
|
|
@@ -30,7 +30,7 @@ def check_elem_intersection(s1: SlicingType, s2: SlicingType) -> bool:
|
|
|
30
30
|
|
|
31
31
|
If they are a slice, check if they overlap.
|
|
32
32
|
If they are integers, check if they are equal.
|
|
33
|
-
If they are
|
|
33
|
+
If they are lists, check if they have any common elements.
|
|
34
34
|
"""
|
|
35
35
|
if not isinstance(s1, type(s2)):
|
|
36
36
|
raise NgioValueError(
|
|
@@ -56,7 +56,7 @@ def check_elem_intersection(s1: SlicingType, s2: SlicingType) -> bool:
|
|
|
56
56
|
elif isinstance(s1, int) and isinstance(s2, int):
|
|
57
57
|
# Handle integer indices
|
|
58
58
|
return s1 == s2
|
|
59
|
-
elif isinstance(s1,
|
|
59
|
+
elif isinstance(s1, list) and isinstance(s2, list):
|
|
60
60
|
if set(s1) & set(s2):
|
|
61
61
|
return True
|
|
62
62
|
return False
|
|
@@ -130,7 +130,7 @@ def _chunk_indices_for_axis(sel: SlicingType, size: int, csize: int) -> list[int
|
|
|
130
130
|
raise IndexError(f"index {sel} out of bounds for axis of size {size}")
|
|
131
131
|
return [sel // csize]
|
|
132
132
|
|
|
133
|
-
if isinstance(sel,
|
|
133
|
+
if isinstance(sel, list):
|
|
134
134
|
if not sel:
|
|
135
135
|
return []
|
|
136
136
|
chunks_hit = {}
|
|
@@ -5,6 +5,7 @@ from functools import total_ordering
|
|
|
5
5
|
from typing import overload
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
|
+
from pydantic import BaseModel
|
|
8
9
|
|
|
9
10
|
from ngio.ome_zarr_meta.ngio_specs import (
|
|
10
11
|
DefaultSpaceUnit,
|
|
@@ -22,34 +23,16 @@ from ngio.ome_zarr_meta.ngio_specs import (
|
|
|
22
23
|
#################################################################################################
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def _validate_type(value: float, name: str) -> float:
|
|
26
|
-
"""Check the type of the value."""
|
|
27
|
-
if not isinstance(value, int | float):
|
|
28
|
-
raise TypeError(f"{name} must be a number.")
|
|
29
|
-
return float(value)
|
|
30
|
-
|
|
31
|
-
|
|
32
26
|
@total_ordering
|
|
33
|
-
class PixelSize:
|
|
27
|
+
class PixelSize(BaseModel):
|
|
34
28
|
"""PixelSize class to store the pixel size in 3D space."""
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
space_unit: SpaceUnits | str | None = DefaultSpaceUnit,
|
|
43
|
-
time_unit: TimeUnits | str | None = DefaultTimeUnit,
|
|
44
|
-
):
|
|
45
|
-
"""Initialize the pixel size."""
|
|
46
|
-
self.x = _validate_type(x, "x")
|
|
47
|
-
self.y = _validate_type(y, "y")
|
|
48
|
-
self.z = _validate_type(z, "z")
|
|
49
|
-
self.t = _validate_type(t, "t")
|
|
50
|
-
|
|
51
|
-
self._space_unit = space_unit
|
|
52
|
-
self._time_unit = time_unit
|
|
30
|
+
x: float
|
|
31
|
+
y: float
|
|
32
|
+
z: float
|
|
33
|
+
t: float = 1
|
|
34
|
+
space_unit: SpaceUnits | str | None = DefaultSpaceUnit
|
|
35
|
+
time_unit: TimeUnits | str | None = DefaultTimeUnit
|
|
53
36
|
|
|
54
37
|
def __repr__(self) -> str:
|
|
55
38
|
"""Return a string representation of the pixel size."""
|
|
@@ -76,10 +59,10 @@ class PixelSize:
|
|
|
76
59
|
if not isinstance(other, PixelSize):
|
|
77
60
|
raise TypeError("Can only compare PixelSize with PixelSize.")
|
|
78
61
|
ref = PixelSize(
|
|
79
|
-
0,
|
|
80
|
-
0,
|
|
81
|
-
0,
|
|
82
|
-
0,
|
|
62
|
+
x=0,
|
|
63
|
+
y=0,
|
|
64
|
+
z=0,
|
|
65
|
+
t=0,
|
|
83
66
|
space_unit=self.space_unit,
|
|
84
67
|
time_unit=self.time_unit, # type: ignore
|
|
85
68
|
)
|
|
@@ -104,16 +87,6 @@ class PixelSize:
|
|
|
104
87
|
)
|
|
105
88
|
return px_size
|
|
106
89
|
|
|
107
|
-
@property
|
|
108
|
-
def space_unit(self) -> SpaceUnits | str | None:
|
|
109
|
-
"""Return the space unit."""
|
|
110
|
-
return self._space_unit
|
|
111
|
-
|
|
112
|
-
@property
|
|
113
|
-
def time_unit(self) -> TimeUnits | str | None:
|
|
114
|
-
"""Return the time unit."""
|
|
115
|
-
return self._time_unit
|
|
116
|
-
|
|
117
90
|
@property
|
|
118
91
|
def tzyx(self) -> tuple[float, float, float, float]:
|
|
119
92
|
"""Return the voxel size in t, z, y, x order."""
|
|
@@ -26,7 +26,7 @@ def test_basic_rois_ops():
|
|
|
26
26
|
assert roi.__str__()
|
|
27
27
|
assert roi.__repr__()
|
|
28
28
|
|
|
29
|
-
assert raster_roi.to_slicing_dict() == {
|
|
29
|
+
assert raster_roi.to_slicing_dict(pixel_size=pixel_size) == {
|
|
30
30
|
"x": slice(0, 1),
|
|
31
31
|
"y": slice(0, 1),
|
|
32
32
|
"z": slice(0, 1),
|
|
@@ -49,7 +49,7 @@ def test_basic_rois_ops():
|
|
|
49
49
|
with pytest.raises(ValueError):
|
|
50
50
|
roi.zoom(-1.0)
|
|
51
51
|
|
|
52
|
-
assert roi_zoomed.
|
|
52
|
+
assert roi_zoomed.to_slicing_dict(pixel_size) == {
|
|
53
53
|
"x": slice(0, 2),
|
|
54
54
|
"y": slice(0, 2),
|
|
55
55
|
"z": slice(0, 1),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|