spatialdata 0.2.5__tar.gz → 0.2.6__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.
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.github/workflows/test.yaml +2 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.mypy.ini +1 -1
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.pre-commit-config.yaml +6 -6
- {spatialdata-0.2.5 → spatialdata-0.2.6}/CHANGELOG.md +24 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/PKG-INFO +6 -7
- {spatialdata-0.2.5 → spatialdata-0.2.6}/_version.py +2 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/pyproject.toml +7 -7
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/_deepcopy.py +1 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/centroids.py +3 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/concatenate.py +2 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/data_extent.py +5 -6
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/_utils.py +2 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/aggregate.py +2 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/map.py +5 -6
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/rasterize.py +1 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/rasterize_bins.py +3 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/transform.py +9 -7
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/vectorize.py +4 -5
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/query/_utils.py +3 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/query/relational_query.py +3 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/query/spatial_query.py +14 -9
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/spatialdata.py +76 -9
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_docs.py +2 -1
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/_utils.py +24 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/format.py +2 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/io_points.py +2 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/io_raster.py +26 -23
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/io_shapes.py +2 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/io_zarr.py +3 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_types.py +4 -9
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_utils.py +40 -6
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/dataloader/datasets.py +3 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/datasets.py +4 -5
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/models/__init__.py +5 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/models/_utils.py +70 -12
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/models/models.py +43 -30
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/testing.py +4 -8
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/_utils.py +5 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/ngff/ngff_coordinate_system.py +7 -7
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/ngff/ngff_transformations.py +122 -120
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/operations.py +7 -6
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/transformations.py +17 -17
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/conftest.py +2 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/test_aggregations.py +1 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/test_rasterize.py +1 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/test_transform.py +5 -6
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/query/test_spatial_query.py +23 -8
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/dataloader/__init__.py +1 -1
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/test_format.py +4 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/test_metadata.py +32 -5
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/test_pyramids_performance.py +5 -6
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/test_readwrite.py +5 -4
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/models/test_models.py +24 -3
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/transformations/test_transformations.py +5 -5
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/utils/test_element_utils.py +1 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/utils/test_testing.py +1 -2
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.bumpversion.cfg +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.editorconfig +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.github/codecov.yml +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.github/workflows/build.yaml +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.github/workflows/release.yaml +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.gitignore +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.gitmodules +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/.readthedocs.yaml +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/Dockerfile +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/LICENSE +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/README.md +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/__main__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/_elements.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/_utils.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/operations/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_core/query/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_io/io_table.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/_logging.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/dataloader/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/ngff/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/src/spatialdata/transformations/ngff/_utils.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/test_map.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/test_rasterize_bins.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/test_spatialdata_operations.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/operations/test_vectorize.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/query/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/query/test_relational_query.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/test_centroids.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/test_data_extent.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/core/test_deepcopy.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/data/multipolygon.json +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/data/points.json +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/data/polygon.json +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/dataloader/test_datasets.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/datasets/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/datasets/test_datasets.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/test_multi_table.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/test_utils.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/io/test_versions.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/models/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/transformations/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/transformations/ngff/__init__.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/transformations/ngff/conftest.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/transformations/ngff/test_ngff_coordinate_system.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/transformations/ngff/test_ngff_transformations.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/transformations/test_transformations_utils.py +0 -0
- {spatialdata-0.2.5 → spatialdata-0.2.6}/tests/utils/__init__.py +0 -0
|
@@ -18,11 +18,11 @@ jobs:
|
|
|
18
18
|
strategy:
|
|
19
19
|
fail-fast: false
|
|
20
20
|
matrix:
|
|
21
|
-
python: ["3.
|
|
21
|
+
python: ["3.10", "3.12"]
|
|
22
22
|
os: [ubuntu-latest]
|
|
23
23
|
include:
|
|
24
24
|
- os: macos-latest
|
|
25
|
-
python: "3.
|
|
25
|
+
python: "3.10"
|
|
26
26
|
- os: macos-latest
|
|
27
27
|
python: "3.12"
|
|
28
28
|
pip-flags: "--pre"
|
|
@@ -2,14 +2,14 @@ fail_fast: false
|
|
|
2
2
|
default_language_version:
|
|
3
3
|
python: python3
|
|
4
4
|
default_stages:
|
|
5
|
-
- commit
|
|
6
|
-
- push
|
|
5
|
+
- pre-commit
|
|
6
|
+
- pre-push
|
|
7
7
|
minimum_pre_commit_version: 2.16.0
|
|
8
8
|
ci:
|
|
9
9
|
skip: []
|
|
10
10
|
repos:
|
|
11
11
|
- repo: https://github.com/psf/black
|
|
12
|
-
rev: 24.
|
|
12
|
+
rev: 24.10.0
|
|
13
13
|
hooks:
|
|
14
14
|
- id: black
|
|
15
15
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
|
@@ -17,17 +17,17 @@ repos:
|
|
|
17
17
|
hooks:
|
|
18
18
|
- id: prettier
|
|
19
19
|
- repo: https://github.com/asottile/blacken-docs
|
|
20
|
-
rev: 1.
|
|
20
|
+
rev: 1.19.1
|
|
21
21
|
hooks:
|
|
22
22
|
- id: blacken-docs
|
|
23
23
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
24
|
-
rev: v1.
|
|
24
|
+
rev: v1.13.0
|
|
25
25
|
hooks:
|
|
26
26
|
- id: mypy
|
|
27
27
|
additional_dependencies: [numpy, types-requests]
|
|
28
28
|
exclude: tests/|docs/
|
|
29
29
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
30
|
-
rev: v0.
|
|
30
|
+
rev: v0.7.3
|
|
31
31
|
hooks:
|
|
32
32
|
- id: ruff
|
|
33
33
|
args: [--fix, --exit-non-zero-on-fix]
|
|
@@ -8,13 +8,35 @@ and this project adheres to [Semantic Versioning][].
|
|
|
8
8
|
[keep a changelog]: https://keepachangelog.com/en/1.0.0/
|
|
9
9
|
[semantic versioning]: https://semver.org/spec/v2.0.0.html
|
|
10
10
|
|
|
11
|
-
## [0.2.
|
|
11
|
+
## [0.2.6] - 2024-11-26
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Added `set_channel_names` method to `SpatialData` to change the channel names of an
|
|
16
|
+
image element in `SpatialData` #786
|
|
17
|
+
- Added `write_channel_names` method to `SpatialData` to overwrite channel metadata on disk
|
|
18
|
+
without overwriting the image array itself. #786
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Argument `c_coords` is moved out of kwargs for the `ImageModel`s. #779
|
|
23
|
+
- `get_channels` is marked for deprecation in `SpatialData` v0.3.0. Function is replaced
|
|
24
|
+
by `get_channel_names` #786
|
|
25
|
+
- Updated dependency of `multiscale-spatial-image` #792
|
|
26
|
+
- Adjust to new version of `xarray` with `DataTree` # 752
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Updated deprecated default stages of `pre-commit` #771
|
|
31
|
+
- Preserve points `feature_key` during queries #794
|
|
32
|
+
|
|
33
|
+
## [0.2.5] - 2024-11-06
|
|
12
34
|
|
|
13
35
|
### Fixed
|
|
14
36
|
|
|
15
37
|
- Incompatibility issues due to newest release of `multiscale-spatial-image` #760
|
|
16
38
|
|
|
17
|
-
## [0.2.4] - 2024-06
|
|
39
|
+
## [0.2.4] - 2024-11-06
|
|
18
40
|
|
|
19
41
|
### Major
|
|
20
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: spatialdata
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: Spatial data format.
|
|
5
5
|
Project-URL: Documentation, https://spatialdata.scverse.org/en/latest
|
|
6
6
|
Project-URL: Source, https://github.com/scverse/spatialdata.git
|
|
@@ -36,15 +36,14 @@ License: BSD 3-Clause License
|
|
|
36
36
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
37
37
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
38
38
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
39
|
-
|
|
40
|
-
Requires-Python: >=3.9
|
|
39
|
+
Requires-Python: <3.13,>=3.10
|
|
41
40
|
Requires-Dist: anndata>=0.9.1
|
|
42
41
|
Requires-Dist: click
|
|
43
42
|
Requires-Dist: dask-image
|
|
44
43
|
Requires-Dist: dask>=2024.4.1
|
|
45
44
|
Requires-Dist: fsspec<=2023.6
|
|
46
45
|
Requires-Dist: geopandas>=0.14
|
|
47
|
-
Requires-Dist: multiscale-spatial-image
|
|
46
|
+
Requires-Dist: multiscale-spatial-image>=2.0.2
|
|
48
47
|
Requires-Dist: networkx
|
|
49
48
|
Requires-Dist: numba
|
|
50
49
|
Requires-Dist: numpy
|
|
@@ -59,16 +58,16 @@ Requires-Dist: setuptools
|
|
|
59
58
|
Requires-Dist: shapely>=2.0.1
|
|
60
59
|
Requires-Dist: spatial-image>=1.1.0
|
|
61
60
|
Requires-Dist: typing-extensions>=4.8.0
|
|
62
|
-
Requires-Dist: xarray-datatree
|
|
63
61
|
Requires-Dist: xarray-schema
|
|
64
62
|
Requires-Dist: xarray-spatial>=0.3.5
|
|
65
|
-
Requires-Dist: xarray
|
|
66
|
-
Requires-Dist: zarr
|
|
63
|
+
Requires-Dist: xarray>=2024.10.0
|
|
64
|
+
Requires-Dist: zarr<3
|
|
67
65
|
Provides-Extra: dev
|
|
68
66
|
Requires-Dist: bump2version; extra == 'dev'
|
|
69
67
|
Provides-Extra: docs
|
|
70
68
|
Requires-Dist: ipython>=8.6.0; extra == 'docs'
|
|
71
69
|
Requires-Dist: myst-nb; extra == 'docs'
|
|
70
|
+
Requires-Dist: sphinx-autobuild; extra == 'docs'
|
|
72
71
|
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
|
|
73
72
|
Requires-Dist: sphinx-book-theme>=1.0.0; extra == 'docs'
|
|
74
73
|
Requires-Dist: sphinx-copybutton; extra == 'docs'
|
|
@@ -15,7 +15,7 @@ maintainers = [
|
|
|
15
15
|
urls.Documentation = "https://spatialdata.scverse.org/en/latest"
|
|
16
16
|
urls.Source = "https://github.com/scverse/spatialdata.git"
|
|
17
17
|
urls.Home-page = "https://github.com/scverse/spatialdata.git"
|
|
18
|
-
requires-python = ">=3.
|
|
18
|
+
requires-python = ">=3.10, <3.13" # include 3.13 once multiscale-spatial-image conflicts are resolved
|
|
19
19
|
dynamic= [
|
|
20
20
|
"version" # allow version to be set by git tags
|
|
21
21
|
]
|
|
@@ -28,7 +28,7 @@ dependencies = [
|
|
|
28
28
|
"dask>=2024.4.1",
|
|
29
29
|
"fsspec<=2023.6",
|
|
30
30
|
"geopandas>=0.14",
|
|
31
|
-
"multiscale_spatial_image>=
|
|
31
|
+
"multiscale_spatial_image>=2.0.2",
|
|
32
32
|
"networkx",
|
|
33
33
|
"numba",
|
|
34
34
|
"numpy",
|
|
@@ -43,11 +43,10 @@ dependencies = [
|
|
|
43
43
|
"scikit-image",
|
|
44
44
|
"scipy",
|
|
45
45
|
"typing_extensions>=4.8.0",
|
|
46
|
-
"xarray
|
|
47
|
-
"xarray-datatree",
|
|
46
|
+
"xarray>=2024.10.0",
|
|
48
47
|
"xarray-schema",
|
|
49
48
|
"xarray-spatial>=0.3.5",
|
|
50
|
-
"zarr",
|
|
49
|
+
"zarr<3",
|
|
51
50
|
]
|
|
52
51
|
|
|
53
52
|
[project.optional-dependencies]
|
|
@@ -56,6 +55,7 @@ dev = [
|
|
|
56
55
|
]
|
|
57
56
|
docs = [
|
|
58
57
|
"sphinx>=4.5",
|
|
58
|
+
"sphinx-autobuild",
|
|
59
59
|
"sphinx-book-theme>=1.0.0",
|
|
60
60
|
"myst-nb",
|
|
61
61
|
"sphinxcontrib-bibtex>=1.0.0",
|
|
@@ -102,7 +102,7 @@ filterwarnings = [
|
|
|
102
102
|
|
|
103
103
|
[tool.black]
|
|
104
104
|
line-length = 120
|
|
105
|
-
target-version = ['
|
|
105
|
+
target-version = ['py310']
|
|
106
106
|
include = '\.pyi?$'
|
|
107
107
|
exclude = '''
|
|
108
108
|
(
|
|
@@ -147,7 +147,7 @@ exclude = [
|
|
|
147
147
|
"setup.py",
|
|
148
148
|
]
|
|
149
149
|
line-length = 120
|
|
150
|
-
target-version = "
|
|
150
|
+
target-version = "py310"
|
|
151
151
|
|
|
152
152
|
[tool.ruff.lint]
|
|
153
153
|
ignore = [
|
|
@@ -7,9 +7,8 @@ from anndata import AnnData
|
|
|
7
7
|
from dask.array.core import Array as DaskArray
|
|
8
8
|
from dask.array.core import from_array
|
|
9
9
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
10
|
-
from datatree import DataTree
|
|
11
10
|
from geopandas import GeoDataFrame
|
|
12
|
-
from xarray import DataArray
|
|
11
|
+
from xarray import DataArray, DataTree
|
|
13
12
|
|
|
14
13
|
from spatialdata._core.spatialdata import SpatialData
|
|
15
14
|
from spatialdata.models._utils import SpatialElement
|
|
@@ -7,10 +7,9 @@ import dask.array as da
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
import xarray as xr
|
|
9
9
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
10
|
-
from datatree import DataTree
|
|
11
10
|
from geopandas import GeoDataFrame
|
|
12
11
|
from shapely import MultiPolygon, Point, Polygon
|
|
13
|
-
from xarray import DataArray
|
|
12
|
+
from xarray import DataArray, DataTree
|
|
14
13
|
|
|
15
14
|
from spatialdata._core.operations.transform import transform
|
|
16
15
|
from spatialdata.models import get_axes_names
|
|
@@ -86,7 +85,7 @@ def _get_centroids_for_axis(xdata: xr.DataArray, axis: str) -> pd.DataFrame:
|
|
|
86
85
|
centroids[label_value] += count * i.values.item()
|
|
87
86
|
|
|
88
87
|
all_labels_values, all_labels_counts = da.unique(xdata.data, return_counts=True)
|
|
89
|
-
all_labels = dict(zip(all_labels_values.compute(), all_labels_counts.compute()))
|
|
88
|
+
all_labels = dict(zip(all_labels_values.compute(), all_labels_counts.compute(), strict=True))
|
|
90
89
|
for label_value in centroids:
|
|
91
90
|
centroids[label_value] /= all_labels[label_value]
|
|
92
91
|
centroids = dict(sorted(centroids.items(), key=lambda x: x[0]))
|
|
@@ -132,7 +131,7 @@ def _(e: GeoDataFrame, coordinate_system: str = "global") -> DaskDataFrame:
|
|
|
132
131
|
if isinstance(first_geometry, Point):
|
|
133
132
|
xy = e.geometry.get_coordinates().values
|
|
134
133
|
else:
|
|
135
|
-
assert isinstance(first_geometry,
|
|
134
|
+
assert isinstance(first_geometry, Polygon | MultiPolygon), (
|
|
136
135
|
f"Expected a GeoDataFrame either composed entirely of circles (Points with the `radius` column) or"
|
|
137
136
|
f" Polygons/MultiPolygons. Found {type(first_geometry)} instead."
|
|
138
137
|
)
|
|
@@ -51,7 +51,7 @@ def _concatenate_tables(
|
|
|
51
51
|
raise ValueError("`instance_key` must be specified if tables have different instance keys")
|
|
52
52
|
|
|
53
53
|
tables_l = []
|
|
54
|
-
for table_region_key, table_instance_key, table in zip(region_keys, instance_keys, tables):
|
|
54
|
+
for table_region_key, table_instance_key, table in zip(region_keys, instance_keys, tables, strict=True):
|
|
55
55
|
rename_dict = {}
|
|
56
56
|
if table_region_key != region_key:
|
|
57
57
|
rename_dict[table_region_key] = region_key
|
|
@@ -239,7 +239,7 @@ def _fix_ensure_unique_element_names(
|
|
|
239
239
|
tables[new_name] = table
|
|
240
240
|
tables_by_sdata.append(tables)
|
|
241
241
|
sdatas_fixed = []
|
|
242
|
-
for elements, tables in zip(elements_by_sdata, tables_by_sdata):
|
|
242
|
+
for elements, tables in zip(elements_by_sdata, tables_by_sdata, strict=True):
|
|
243
243
|
sdata = SpatialData.init_from_elements(elements, tables=tables)
|
|
244
244
|
sdatas_fixed.append(sdata)
|
|
245
245
|
return sdatas_fixed
|
|
@@ -8,10 +8,9 @@ from typing import Union
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import pandas as pd
|
|
10
10
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
11
|
-
from datatree import DataTree
|
|
12
11
|
from geopandas import GeoDataFrame
|
|
13
12
|
from shapely import MultiPolygon, Point, Polygon
|
|
14
|
-
from xarray import DataArray
|
|
13
|
+
from xarray import DataArray, DataTree
|
|
15
14
|
|
|
16
15
|
from spatialdata._core.operations.transform import transform
|
|
17
16
|
from spatialdata._core.spatialdata import SpatialData
|
|
@@ -71,7 +70,7 @@ def _get_extent_of_polygons_multipolygons(
|
|
|
71
70
|
-------
|
|
72
71
|
The bounding box description.
|
|
73
72
|
"""
|
|
74
|
-
assert isinstance(shapes.geometry.iloc[0],
|
|
73
|
+
assert isinstance(shapes.geometry.iloc[0], Polygon | MultiPolygon)
|
|
75
74
|
axes = get_axes_names(shapes)
|
|
76
75
|
bounds = shapes["geometry"].bounds
|
|
77
76
|
return {ax: (bounds[f"min{ax}"].min(), bounds[f"max{ax}"].max()) for ax in axes}
|
|
@@ -201,7 +200,7 @@ def _(
|
|
|
201
200
|
new_max_coordinates_dict: dict[str, list[float]] = defaultdict(list)
|
|
202
201
|
mask = [has_images, has_labels, has_points, has_shapes]
|
|
203
202
|
include_spatial_elements = ["images", "labels", "points", "shapes"]
|
|
204
|
-
include_spatial_elements = [i for (i, v) in zip(include_spatial_elements, mask) if v]
|
|
203
|
+
include_spatial_elements = [i for (i, v) in zip(include_spatial_elements, mask, strict=True) if v]
|
|
205
204
|
|
|
206
205
|
if elements is None: # to shut up ruff
|
|
207
206
|
elements = []
|
|
@@ -217,7 +216,7 @@ def _(
|
|
|
217
216
|
assert isinstance(transformations, dict)
|
|
218
217
|
coordinate_systems = list(transformations.keys())
|
|
219
218
|
if coordinate_system in coordinate_systems:
|
|
220
|
-
if isinstance(element_obj,
|
|
219
|
+
if isinstance(element_obj, DaskDataFrame | GeoDataFrame):
|
|
221
220
|
extent = get_extent(element_obj, coordinate_system=coordinate_system, exact=exact)
|
|
222
221
|
else:
|
|
223
222
|
extent = get_extent(element_obj, coordinate_system=coordinate_system)
|
|
@@ -254,7 +253,7 @@ def _get_extent_of_shapes(e: GeoDataFrame) -> BoundingBoxDescription:
|
|
|
254
253
|
first_geometry = e_temp["geometry"].iloc[0]
|
|
255
254
|
if isinstance(first_geometry, Point):
|
|
256
255
|
return _get_extent_of_circles(e)
|
|
257
|
-
assert isinstance(first_geometry,
|
|
256
|
+
assert isinstance(first_geometry, Polygon | MultiPolygon)
|
|
258
257
|
return _get_extent_of_polygons_multipolygons(e)
|
|
259
258
|
|
|
260
259
|
|
|
@@ -2,8 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from xarray import DataArray
|
|
5
|
+
from xarray import DataArray, DataTree
|
|
7
6
|
|
|
8
7
|
from spatialdata.models import SpatialElement
|
|
9
8
|
|
|
@@ -115,7 +114,7 @@ def transform_to_data_extent(
|
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
for _, element_name, element in sdata_raster.gen_spatial_elements():
|
|
118
|
-
if isinstance(element,
|
|
117
|
+
if isinstance(element, DataArray | DataTree):
|
|
119
118
|
rasterized = rasterize(
|
|
120
119
|
element,
|
|
121
120
|
axes=data_extent_axes,
|
|
@@ -10,11 +10,10 @@ import geopandas as gpd
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
import pandas as pd
|
|
12
12
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
13
|
-
from datatree import DataTree
|
|
14
13
|
from geopandas import GeoDataFrame
|
|
15
14
|
from scipy import sparse
|
|
16
15
|
from shapely import Point
|
|
17
|
-
from xarray import DataArray
|
|
16
|
+
from xarray import DataArray, DataTree
|
|
18
17
|
from xrspatial import zonal_stats
|
|
19
18
|
|
|
20
19
|
from spatialdata._core.operations._utils import _parse_element
|
|
@@ -246,7 +245,7 @@ def _create_sdata_from_table_and_shapes(
|
|
|
246
245
|
table = TableModel.parse(table, region=shapes_name, region_key=region_key, instance_key=instance_key)
|
|
247
246
|
|
|
248
247
|
# labels case, needs conversion from str to int
|
|
249
|
-
if isinstance(shapes,
|
|
248
|
+
if isinstance(shapes, DataArray | DataTree):
|
|
250
249
|
table.obs[instance_key] = table.obs[instance_key].astype(int)
|
|
251
250
|
|
|
252
251
|
if deepcopy:
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from collections.abc import Iterable, Mapping
|
|
3
|
+
from collections.abc import Callable, Iterable, Mapping
|
|
4
4
|
from types import MappingProxyType
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
7
|
import dask.array as da
|
|
8
8
|
from dask.array.overlap import coerce_depth
|
|
9
|
-
from
|
|
10
|
-
from xarray import DataArray
|
|
9
|
+
from xarray import DataArray, DataTree
|
|
11
10
|
|
|
12
|
-
from spatialdata.models._utils import get_axes_names,
|
|
11
|
+
from spatialdata.models._utils import get_axes_names, get_channel_names, get_raster_model_from_data_dims
|
|
13
12
|
from spatialdata.transformations import get_transformation
|
|
14
13
|
|
|
15
14
|
__all__ = ["map_raster"]
|
|
@@ -122,7 +121,7 @@ def map_raster(
|
|
|
122
121
|
|
|
123
122
|
if "c" in dims:
|
|
124
123
|
if c_coords is None:
|
|
125
|
-
c_coords = range(arr.shape[0]) if arr.shape[0] != len(
|
|
124
|
+
c_coords = range(arr.shape[0]) if arr.shape[0] != len(get_channel_names(data)) else get_channel_names(data)
|
|
126
125
|
else:
|
|
127
126
|
c_coords = None
|
|
128
127
|
if transformations is None:
|
|
@@ -5,10 +5,9 @@ import datashader as ds
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
from dask.array import Array as DaskArray
|
|
7
7
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
8
|
-
from datatree import DataTree
|
|
9
8
|
from geopandas import GeoDataFrame
|
|
10
9
|
from shapely import Point
|
|
11
|
-
from xarray import DataArray
|
|
10
|
+
from xarray import DataArray, DataTree
|
|
12
11
|
|
|
13
12
|
from spatialdata._core.operations._utils import _parse_element
|
|
14
13
|
from spatialdata._core.operations.transform import transform
|
|
@@ -73,7 +73,7 @@ def rasterize_bins(
|
|
|
73
73
|
"""
|
|
74
74
|
element = sdata[bins]
|
|
75
75
|
table = sdata.tables[table_name]
|
|
76
|
-
if not isinstance(element,
|
|
76
|
+
if not isinstance(element, GeoDataFrame | DaskDataFrame):
|
|
77
77
|
raise ValueError("The bins should be a GeoDataFrame or a DaskDataFrame.")
|
|
78
78
|
|
|
79
79
|
_, region_key, instance_key = get_table_keys(table)
|
|
@@ -94,7 +94,7 @@ def rasterize_bins(
|
|
|
94
94
|
keys = ([value_key] if isinstance(value_key, str) else value_key) if value_key is not None else table.var_names
|
|
95
95
|
|
|
96
96
|
if (value_key is None or any(key in table.var_names for key in keys)) and not isinstance(
|
|
97
|
-
table.X,
|
|
97
|
+
table.X, csc_matrix | np.ndarray
|
|
98
98
|
):
|
|
99
99
|
raise ValueError(
|
|
100
100
|
"To speed up bins rasterization, the X matrix in the table, when sparse, should be a csc_matrix matrix. "
|
|
@@ -162,7 +162,7 @@ def rasterize_bins(
|
|
|
162
162
|
sub_x = sub_df.geometry.x.values
|
|
163
163
|
sub_y = sub_df.geometry.y.values
|
|
164
164
|
else:
|
|
165
|
-
assert isinstance(sub_df.iloc[0].geometry,
|
|
165
|
+
assert isinstance(sub_df.iloc[0].geometry, Polygon | MultiPolygon)
|
|
166
166
|
sub_x = sub_df.centroid.x
|
|
167
167
|
sub_y = sub_df.centroid.y
|
|
168
168
|
else:
|
|
@@ -10,15 +10,14 @@ import dask_image.ndinterp
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
from dask.array.core import Array as DaskArray
|
|
12
12
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
13
|
-
from datatree import DataTree
|
|
14
13
|
from geopandas import GeoDataFrame
|
|
15
14
|
from shapely import Point
|
|
16
|
-
from xarray import DataArray
|
|
15
|
+
from xarray import DataArray, Dataset, DataTree
|
|
17
16
|
|
|
18
17
|
from spatialdata._core.spatialdata import SpatialData
|
|
19
18
|
from spatialdata._types import ArrayLike
|
|
20
19
|
from spatialdata.models import SpatialElement, get_axes_names, get_model
|
|
21
|
-
from spatialdata.models._utils import DEFAULT_COORDINATE_SYSTEM,
|
|
20
|
+
from spatialdata.models._utils import DEFAULT_COORDINATE_SYSTEM, get_channel_names
|
|
22
21
|
from spatialdata.transformations._utils import _get_scale, compute_coordinates, scale_radii
|
|
23
22
|
|
|
24
23
|
if TYPE_CHECKING:
|
|
@@ -161,13 +160,13 @@ def _set_transformation_for_transformed_elements(
|
|
|
161
160
|
assert to_coordinate_system is None
|
|
162
161
|
|
|
163
162
|
to_prepend: BaseTransformation | None
|
|
164
|
-
if isinstance(element,
|
|
163
|
+
if isinstance(element, DataArray | DataTree):
|
|
165
164
|
if maintain_positioning:
|
|
166
165
|
assert raster_translation is not None
|
|
167
166
|
to_prepend = Sequence([raster_translation, transformation.inverse()])
|
|
168
167
|
else:
|
|
169
168
|
to_prepend = raster_translation
|
|
170
|
-
elif isinstance(element,
|
|
169
|
+
elif isinstance(element, GeoDataFrame | DaskDataFrame):
|
|
171
170
|
assert raster_translation is None
|
|
172
171
|
to_prepend = transformation.inverse() if maintain_positioning else Identity()
|
|
173
172
|
else:
|
|
@@ -368,7 +367,7 @@ def _(
|
|
|
368
367
|
channel_names = None
|
|
369
368
|
elif schema in (Image2DModel, Image3DModel):
|
|
370
369
|
kwargs = {}
|
|
371
|
-
channel_names =
|
|
370
|
+
channel_names = get_channel_names(data)
|
|
372
371
|
else:
|
|
373
372
|
raise ValueError(f"DataTree with schema {schema} not supported")
|
|
374
373
|
|
|
@@ -393,8 +392,11 @@ def _(
|
|
|
393
392
|
raster_translation = raster_translation_single_scale
|
|
394
393
|
# we set a dummy empty dict for the transformation that will be replaced with the correct transformation for
|
|
395
394
|
# each scale later in this function, when calling set_transformation()
|
|
396
|
-
transformed_dict[k] =
|
|
395
|
+
transformed_dict[k] = Dataset(
|
|
396
|
+
{"image": DataArray(transformed_dask, dims=xdata.dims, name=xdata.name, attrs={TRANSFORM_KEY: {}})}
|
|
397
|
+
)
|
|
397
398
|
if channel_names is not None:
|
|
399
|
+
# This expression returns a dataset now.
|
|
398
400
|
transformed_dict[k] = transformed_dict[k].assign_coords(c=channel_names)
|
|
399
401
|
|
|
400
402
|
# mypy thinks that schema could be ShapesModel, PointsModel, ...
|
|
@@ -9,11 +9,10 @@ import pandas as pd
|
|
|
9
9
|
import shapely
|
|
10
10
|
import skimage.measure
|
|
11
11
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
12
|
-
from datatree import DataTree
|
|
13
12
|
from geopandas import GeoDataFrame
|
|
14
13
|
from shapely import MultiPolygon, Point, Polygon
|
|
15
14
|
from skimage.measure._regionprops import RegionProperties
|
|
16
|
-
from xarray import DataArray
|
|
15
|
+
from xarray import DataArray, DataTree
|
|
17
16
|
|
|
18
17
|
from spatialdata._core.centroids import get_centroids
|
|
19
18
|
from spatialdata._core.operations.aggregate import aggregate
|
|
@@ -106,7 +105,7 @@ def _(element: DataArray | DataTree, **kwargs: Any) -> GeoDataFrame:
|
|
|
106
105
|
@to_circles.register(GeoDataFrame)
|
|
107
106
|
def _(element: GeoDataFrame, **kwargs: Any) -> GeoDataFrame:
|
|
108
107
|
assert len(kwargs) == 0
|
|
109
|
-
if isinstance(element.geometry.iloc[0],
|
|
108
|
+
if isinstance(element.geometry.iloc[0], Polygon | MultiPolygon):
|
|
110
109
|
radius = np.sqrt(element.geometry.area / np.pi)
|
|
111
110
|
centroids = _get_centroids(element)
|
|
112
111
|
obs = pd.DataFrame({"radius": radius})
|
|
@@ -258,7 +257,7 @@ def _dissolve_on_overlaps(label: int, group: GeoDataFrame) -> GeoDataFrame:
|
|
|
258
257
|
|
|
259
258
|
@to_polygons.register(GeoDataFrame)
|
|
260
259
|
def _(gdf: GeoDataFrame, buffer_resolution: int = 16) -> GeoDataFrame:
|
|
261
|
-
if isinstance(gdf.geometry.iloc[0],
|
|
260
|
+
if isinstance(gdf.geometry.iloc[0], Polygon | MultiPolygon):
|
|
262
261
|
return gdf
|
|
263
262
|
if isinstance(gdf.geometry.iloc[0], Point):
|
|
264
263
|
ShapesModel.validate_shapes_not_mixed_types(gdf)
|
|
@@ -274,7 +273,7 @@ def _(gdf: GeoDataFrame, buffer_resolution: int = 16) -> GeoDataFrame:
|
|
|
274
273
|
# TODO replace with a function to copy the metadata (the parser could also do this): https://github.com/scverse/spatialdata/issues/258
|
|
275
274
|
buffered_df.attrs[ShapesModel.TRANSFORM_KEY] = gdf.attrs[ShapesModel.TRANSFORM_KEY]
|
|
276
275
|
return buffered_df
|
|
277
|
-
assert isinstance(gdf.geometry.iloc[0],
|
|
276
|
+
assert isinstance(gdf.geometry.iloc[0], Polygon | MultiPolygon)
|
|
278
277
|
return gdf
|
|
279
278
|
raise RuntimeError("Unsupported geometry type: " f"{type(gdf.geometry.iloc[0])}")
|
|
280
279
|
|
|
@@ -5,8 +5,7 @@ from typing import Any
|
|
|
5
5
|
import numba as nb
|
|
6
6
|
import numpy as np
|
|
7
7
|
from anndata import AnnData
|
|
8
|
-
from
|
|
9
|
-
from xarray import DataArray
|
|
8
|
+
from xarray import DataArray, Dataset, DataTree
|
|
10
9
|
|
|
11
10
|
from spatialdata._core._elements import Tables
|
|
12
11
|
from spatialdata._core.spatialdata import SpatialData
|
|
@@ -96,7 +95,7 @@ def get_bounding_box_corners(
|
|
|
96
95
|
return output.squeeze().drop_vars("box")
|
|
97
96
|
|
|
98
97
|
|
|
99
|
-
@nb.
|
|
98
|
+
@nb.jit(parallel=False, nopython=True)
|
|
100
99
|
def _create_slices_and_translation(
|
|
101
100
|
min_values: nb.types.Array,
|
|
102
101
|
max_values: nb.types.Array,
|
|
@@ -138,7 +137,7 @@ def _process_data_tree_query_result(query_result: DataTree) -> DataTree | None:
|
|
|
138
137
|
if len(scales_to_keep) == 0:
|
|
139
138
|
return None
|
|
140
139
|
|
|
141
|
-
d = {k: d[k] for k in scales_to_keep}
|
|
140
|
+
d = {k: Dataset({"image": d[k]}) for k in scales_to_keep}
|
|
142
141
|
result = DataTree.from_dict(d)
|
|
143
142
|
|
|
144
143
|
# Rechunk the data to avoid irregular chunks
|
|
@@ -13,9 +13,8 @@ import numpy as np
|
|
|
13
13
|
import pandas as pd
|
|
14
14
|
from anndata import AnnData
|
|
15
15
|
from dask.dataframe import DataFrame as DaskDataFrame
|
|
16
|
-
from datatree import DataTree
|
|
17
16
|
from geopandas import GeoDataFrame
|
|
18
|
-
from xarray import DataArray
|
|
17
|
+
from xarray import DataArray, DataTree
|
|
19
18
|
|
|
20
19
|
from spatialdata._core.spatialdata import SpatialData
|
|
21
20
|
from spatialdata._types import ArrayLike
|
|
@@ -653,7 +652,7 @@ def join_spatialelement_table(
|
|
|
653
652
|
if sdata is not None:
|
|
654
653
|
elements_dict = _create_sdata_elements_dict_for_join(sdata, spatial_element_names)
|
|
655
654
|
else:
|
|
656
|
-
derived_sdata = SpatialData.from_elements_dict(dict(zip(spatial_element_names, spatial_elements)))
|
|
655
|
+
derived_sdata = SpatialData.from_elements_dict(dict(zip(spatial_element_names, spatial_elements, strict=True)))
|
|
657
656
|
element_types = ["labels", "shapes", "points"]
|
|
658
657
|
elements_dict = defaultdict(lambda: defaultdict(dict))
|
|
659
658
|
for element_type in element_types:
|
|
@@ -919,7 +918,7 @@ def get_values(
|
|
|
919
918
|
x = matched_table[:, value_key_values].X
|
|
920
919
|
import scipy
|
|
921
920
|
|
|
922
|
-
if isinstance(x,
|
|
921
|
+
if isinstance(x, scipy.sparse.csr_matrix | scipy.sparse.csc_matrix | scipy.sparse.coo_matrix):
|
|
923
922
|
x = x.todense()
|
|
924
923
|
df = pd.DataFrame(x, columns=value_key_values)
|
|
925
924
|
if origin == "obsm":
|