spatialdata 0.2.2__tar.gz → 0.2.3__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 (111) hide show
  1. spatialdata-0.2.3/.github/ISSUE_TEMPLATE/bug_report.md +53 -0
  2. spatialdata-0.2.3/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  3. {spatialdata-0.2.2 → spatialdata-0.2.3}/.pre-commit-config.yaml +2 -2
  4. {spatialdata-0.2.2 → spatialdata-0.2.3}/CHANGELOG.md +13 -4
  5. {spatialdata-0.2.2 → spatialdata-0.2.3}/PKG-INFO +1 -1
  6. {spatialdata-0.2.2 → spatialdata-0.2.3}/_version.py +2 -2
  7. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/rasterize.py +1 -1
  8. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/rasterize_bins.py +4 -2
  9. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/transform.py +2 -2
  10. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/query/relational_query.py +16 -1
  11. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/query/spatial_query.py +20 -1
  12. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/spatialdata.py +3 -1
  13. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/io_zarr.py +2 -2
  14. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_types.py +2 -1
  15. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/datasets.py +14 -2
  16. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/models/models.py +31 -9
  17. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/conftest.py +2 -1
  18. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/test_aggregations.py +2 -1
  19. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/test_map.py +2 -1
  20. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/test_rasterize_bins.py +1 -0
  21. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/test_spatialdata_operations.py +2 -2
  22. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/test_transform.py +2 -1
  23. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/test_vectorize.py +1 -0
  24. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/query/test_relational_query.py +1 -0
  25. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/query/test_spatial_query.py +37 -2
  26. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/test_centroids.py +1 -0
  27. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/test_data_extent.py +1 -0
  28. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/test_deepcopy.py +1 -0
  29. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/dataloader/test_datasets.py +1 -0
  30. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/io/test_format.py +1 -0
  31. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/io/test_metadata.py +1 -0
  32. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/io/test_utils.py +1 -0
  33. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/models/test_models.py +23 -2
  34. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/transformations/ngff/test_ngff_coordinate_system.py +1 -0
  35. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/transformations/test_transformations.py +2 -1
  36. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/utils/test_element_utils.py +2 -1
  37. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/utils/test_testing.py +2 -1
  38. {spatialdata-0.2.2 → spatialdata-0.2.3}/.bumpversion.cfg +0 -0
  39. {spatialdata-0.2.2 → spatialdata-0.2.3}/.editorconfig +0 -0
  40. {spatialdata-0.2.2 → spatialdata-0.2.3}/.github/codecov.yml +0 -0
  41. {spatialdata-0.2.2 → spatialdata-0.2.3}/.github/workflows/build.yaml +0 -0
  42. {spatialdata-0.2.2 → spatialdata-0.2.3}/.github/workflows/release.yaml +0 -0
  43. {spatialdata-0.2.2 → spatialdata-0.2.3}/.github/workflows/test.yaml +0 -0
  44. {spatialdata-0.2.2 → spatialdata-0.2.3}/.gitignore +0 -0
  45. {spatialdata-0.2.2 → spatialdata-0.2.3}/.gitmodules +0 -0
  46. {spatialdata-0.2.2 → spatialdata-0.2.3}/.mypy.ini +0 -0
  47. {spatialdata-0.2.2 → spatialdata-0.2.3}/.readthedocs.yaml +0 -0
  48. {spatialdata-0.2.2 → spatialdata-0.2.3}/Dockerfile +0 -0
  49. {spatialdata-0.2.2 → spatialdata-0.2.3}/LICENSE +0 -0
  50. {spatialdata-0.2.2 → spatialdata-0.2.3}/README.md +0 -0
  51. {spatialdata-0.2.2 → spatialdata-0.2.3}/pyproject.toml +0 -0
  52. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/__init__.py +0 -0
  53. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/__main__.py +0 -0
  54. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/__init__.py +0 -0
  55. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/_deepcopy.py +0 -0
  56. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/_elements.py +0 -0
  57. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/_utils.py +0 -0
  58. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/centroids.py +0 -0
  59. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/concatenate.py +0 -0
  60. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/data_extent.py +0 -0
  61. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/__init__.py +0 -0
  62. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/_utils.py +0 -0
  63. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/aggregate.py +0 -0
  64. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/map.py +0 -0
  65. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/operations/vectorize.py +0 -0
  66. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/query/__init__.py +0 -0
  67. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_core/query/_utils.py +0 -0
  68. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/__init__.py +0 -0
  69. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/_utils.py +0 -0
  70. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/format.py +0 -0
  71. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/io_points.py +0 -0
  72. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/io_raster.py +0 -0
  73. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/io_shapes.py +0 -0
  74. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_io/io_table.py +0 -0
  75. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_logging.py +0 -0
  76. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/_utils.py +0 -0
  77. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/dataloader/__init__.py +0 -0
  78. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/dataloader/datasets.py +0 -0
  79. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/models/__init__.py +0 -0
  80. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/models/_utils.py +0 -0
  81. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/testing.py +0 -0
  82. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/__init__.py +0 -0
  83. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/_utils.py +0 -0
  84. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/ngff/__init__.py +0 -0
  85. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/ngff/_utils.py +0 -0
  86. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/ngff/ngff_coordinate_system.py +0 -0
  87. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/ngff/ngff_transformations.py +0 -0
  88. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/operations.py +0 -0
  89. {spatialdata-0.2.2 → spatialdata-0.2.3}/src/spatialdata/transformations/transformations.py +0 -0
  90. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/__init__.py +0 -0
  91. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/__init__.py +0 -0
  92. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/__init__.py +0 -0
  93. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/operations/test_rasterize.py +2 -2
  94. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/core/query/__init__.py +0 -0
  95. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/data/multipolygon.json +0 -0
  96. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/data/points.json +0 -0
  97. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/data/polygon.json +0 -0
  98. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/dataloader/__init__.py +0 -0
  99. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/datasets/__init__.py +0 -0
  100. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/datasets/test_datasets.py +0 -0
  101. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/io/__init__.py +0 -0
  102. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/io/test_multi_table.py +1 -1
  103. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/io/test_readwrite.py +1 -1
  104. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/io/test_versions.py +0 -0
  105. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/models/__init__.py +0 -0
  106. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/transformations/__init__.py +0 -0
  107. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/transformations/ngff/__init__.py +0 -0
  108. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/transformations/ngff/conftest.py +0 -0
  109. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/transformations/ngff/test_ngff_transformations.py +1 -1
  110. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/transformations/test_transformations_utils.py +0 -0
  111. {spatialdata-0.2.2 → spatialdata-0.2.3}/tests/utils/__init__.py +0 -0
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ""
5
+ labels: ""
6
+ assignees: ""
7
+ ---
8
+
9
+ **Recommendation: attach a minimal working example**
10
+ Generally, the easier it is for us to reproduce the issue, the faster we can work on it. It is not required, but if you can, please:
11
+
12
+ 1. Reproduce using the [`blobs` dataset](https://spatialdata.scverse.org/en/latest/generated/spatialdata.datasets.blobs.html)
13
+
14
+ ```python
15
+ from spatialdata.datasets import blobs
16
+
17
+ sdata = blobs()
18
+ ```
19
+
20
+ You can also use [`blobs_annotating_element`](https://spatialdata.scverse.org/en/latest/generated/spatialdata.datasets.blobs_annotating_element.html) for more control:
21
+
22
+ ```
23
+ from spatialdata.datasets import blobs_annotating_element
24
+ sdata = blobs_annotating_element('blobs_labels')
25
+ ```
26
+
27
+ 2. If the above is not possible, reproduce using a public dataset and explain how we can download the data.
28
+ 3. If the data is private, consider sharing an anonymized version/subset via a [Zulip private message](https://scverse.zulipchat.com/#user/480560), or provide screenshots/GIFs showing the behavior.
29
+
30
+ **Describe the bug**
31
+ A clear and concise description of what the bug is; please report only one bug per issue.
32
+
33
+ **To Reproduce**
34
+ Steps to reproduce the behavior:
35
+
36
+ 1. Go to '...'
37
+ 2. Click on '....'
38
+ 3. Scroll down to '....'
39
+ 4. See error
40
+
41
+ **Expected behavior**
42
+ A clear and concise description of what you expected to happen.
43
+
44
+ **Screenshots**
45
+ If applicable, add screenshots to help explain your problem.
46
+
47
+ **Desktop (optional):**
48
+
49
+ - OS: [e.g. macOS, Windows, Linux]
50
+ - Version [e.g. 22]
51
+
52
+ **Additional context**
53
+ Add any other context about the problem here.
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ""
5
+ labels: ""
6
+ assignees: ""
7
+ ---
8
+
9
+ **Is your feature request related to a problem? Please describe.**
10
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11
+
12
+ **Describe the solution you'd like**
13
+ A clear and concise description of what you want to happen.
14
+
15
+ **Describe alternatives you've considered**
16
+ A clear and concise description of any alternative solutions or features you've considered.
17
+
18
+ **Additional context**
19
+ Add any other context or screenshots about the feature request here.
@@ -21,13 +21,13 @@ repos:
21
21
  hooks:
22
22
  - id: blacken-docs
23
23
  - repo: https://github.com/pre-commit/mirrors-mypy
24
- rev: v1.11.1
24
+ rev: v1.11.2
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.5.6
30
+ rev: v0.6.3
31
31
  hooks:
32
32
  - id: ruff
33
33
  args: [--fix, --exit-non-zero-on-fix]
@@ -8,20 +8,29 @@ 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.x.x] - 2024-xx-xx
11
+ ## [0.2.3] - 2024-09-25
12
+
13
+ ### Minor
14
+
15
+ - Added `clip: bool = False` parameter to `polygon_query()` #670
16
+ - Add `sort` parameter to `PointsModel.parse()` #672
17
+
18
+ ### Fixed
19
+
20
+ - Fix interpolation artifact multiscale computation for labels #697
12
21
 
13
22
  ## [0.2.2] - 2024-08-07
14
23
 
15
- # Major
24
+ ### Major
16
25
 
17
26
  - New disk format for shapes using `GeoParquet` (the change is backward compatible) #542
18
27
 
19
- # Minor
28
+ ### Minor
20
29
 
21
30
  - Add `return_background` as argument to `get_centroids` and `get_element_instances` #621
22
31
  - Ability to save data using older disk formats #542
23
32
 
24
- # Fixed
33
+ ### Fixed
25
34
 
26
35
  - Circles validation now checks for inf or nan radii #653
27
36
  - Bug with table name in torch dataset #654 @LLehner
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: spatialdata
3
- Version: 0.2.2
3
+ Version: 0.2.3
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
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.2.2'
16
- __version_tuple__ = version_tuple = (0, 2, 2)
15
+ __version__ = version = '0.2.3'
16
+ __version_tuple__ = version_tuple = (0, 2, 3)
@@ -336,7 +336,7 @@ def rasterize(
336
336
  element_name = data if isinstance(data, str) else None
337
337
  kwargs = {"sdata": sdata, "element_name": element_name} if element_name is not None else {"element": data}
338
338
  values = get_values(value_key, table_name=table_name, **kwargs).iloc[:, 0] # type: ignore[arg-type, union-attr]
339
- max_index = np.max(values.index)
339
+ max_index: int = np.max(values.index)
340
340
  assigner = np.zeros(max_index + 1, dtype=values.dtype)
341
341
  assigner[values.index] = values
342
342
  # call-arg is ignored because model is never TableModel (the error is that the transformation param is not
@@ -14,6 +14,7 @@ from skimage.transform import estimate_transform
14
14
  from xarray import DataArray
15
15
 
16
16
  from spatialdata._core.query.relational_query import get_values
17
+ from spatialdata._types import ArrayLike
17
18
  from spatialdata.models import Image2DModel, get_table_keys
18
19
  from spatialdata.transformations import Affine, Sequence, get_transformation
19
20
 
@@ -113,8 +114,9 @@ def rasterize_bins(
113
114
  if value_key is None:
114
115
  shape = (n_rows, n_cols)
115
116
 
116
- def channel_rasterization(block_id: tuple[int, int, int] | None) -> np.ndarray: # type: ignore[type-arg]
117
- image = np.zeros((1, *shape), dtype=dtype)
117
+ def channel_rasterization(block_id: tuple[int, int, int] | None) -> ArrayLike:
118
+
119
+ image: ArrayLike = np.zeros((1, *shape), dtype=dtype)
118
120
 
119
121
  if block_id is None:
120
122
  return image
@@ -49,11 +49,11 @@ def _transform_raster(
49
49
  v: ArrayLike = np.hstack(c_channel + [binary, np.ones(len(binary)).reshape((-1, 1))])
50
50
  matrix = transformation.to_affine_matrix(input_axes=axes, output_axes=axes)
51
51
  inverse_matrix = transformation.inverse().to_affine_matrix(input_axes=axes, output_axes=axes)
52
- new_v = (matrix @ v.T).T
52
+ new_v: ArrayLike = (matrix @ v.T).T
53
53
  c_shape: tuple[int, ...]
54
54
  c_shape = (data.shape[0],) if "c" in axes else ()
55
55
  new_spatial_shape = tuple(
56
- int(np.max(new_v[:, i]) - np.min(new_v[:, i])) for i in range(len(c_shape), n_spatial_dims + len(c_shape))
56
+ int(np.max(new_v[:, i]) - np.min(new_v[:, i])) for i in range(len(c_shape), n_spatial_dims + len(c_shape)) # type: ignore[operator]
57
57
  )
58
58
  output_shape = c_shape + new_spatial_shape
59
59
  translation_vector = np.min(new_v[:, :-1], axis=0)
@@ -220,8 +220,8 @@ def _filter_table_by_elements(
220
220
  merged = pd.merge(table_df, pd.DataFrame(index=instances), left_on=instance_key, right_index=True, how="right")
221
221
  matched_positions = merged["position"].to_numpy()
222
222
  table = table[matched_positions, :]
223
- _inplace_fix_subset_categorical_obs(subset_adata=table, original_adata=original_table)
224
223
  table = table.copy()
224
+ _inplace_fix_subset_categorical_obs(subset_adata=table, original_adata=original_table)
225
225
  table.uns[TableModel.ATTRS_KEY][TableModel.REGION_KEY] = table.obs[region_key].unique().tolist()
226
226
  return table
227
227
 
@@ -623,6 +623,11 @@ def join_spatialelement_table(
623
623
  If the provided join type is not supported.
624
624
  ValueError
625
625
  If an incorrect value is given for `match_rows`.
626
+
627
+ See Also
628
+ --------
629
+ match_element_to_table : Function to match elements to a table.
630
+ join_spatialelement_table : Function to join spatial elements with a table.
626
631
  """
627
632
  if spatial_element_names is None:
628
633
  raise ValueError("`spatial_element_names` must be provided.")
@@ -698,6 +703,11 @@ def match_table_to_element(sdata: SpatialData, element_name: str, table_name: st
698
703
  Returns
699
704
  -------
700
705
  Table with the rows matching the instances of the element
706
+
707
+ See Also
708
+ --------
709
+ match_element_to_table : Function to match a spatial element to a table.
710
+ join_spatialelement_table : General function, to join spatial elements with a table with more control.
701
711
  """
702
712
  if table_name is None:
703
713
  warnings.warn(
@@ -731,6 +741,11 @@ def match_element_to_table(
731
741
  Returns
732
742
  -------
733
743
  A tuple containing the joined elements as a dictionary and the joined table as an AnnData object.
744
+
745
+ See Also
746
+ --------
747
+ match_table_to_element : Function to match a table to a spatial element.
748
+ join_spatialelement_table : General function, to join spatial elements with a table with more control.
734
749
  """
735
750
  element_dict, table = join_spatialelement_table(
736
751
  sdata=sdata, spatial_element_names=element_name, table_name=table_name, how="right", match_rows="right"
@@ -13,7 +13,7 @@ import numpy as np
13
13
  from dask.dataframe import DataFrame as DaskDataFrame
14
14
  from datatree import DataTree
15
15
  from geopandas import GeoDataFrame
16
- from shapely.geometry import MultiPolygon, Polygon
16
+ from shapely.geometry import MultiPolygon, Point, Polygon
17
17
  from xarray import DataArray
18
18
 
19
19
  from spatialdata import to_polygons
@@ -758,6 +758,7 @@ def polygon_query(
758
758
  polygon: Polygon | MultiPolygon,
759
759
  target_coordinate_system: str,
760
760
  filter_table: bool = True,
761
+ clip: bool = False,
761
762
  shapes: bool = True,
762
763
  points: bool = True,
763
764
  images: bool = True,
@@ -777,6 +778,12 @@ def polygon_query(
777
778
  filter_table
778
779
  Specifies whether to filter the tables to only include tables that annotate elements in the retrieved
779
780
  SpatialData object of the query.
781
+ clip
782
+ If `True`, the shapes are clipped to the polygon. This behavior is implemented only when querying
783
+ polygons/multipolygons or circles, and it is ignored for other types of elements (images, labels, points).
784
+ Importantly, when clipping is enabled, the circles will be converted to polygons before the clipping. This may
785
+ affect downstream operations that rely on the circle radius or on performance, so it is recommended to disable
786
+ clipping when querying circles or when querying a `SpatialData` object that contains circles.
780
787
  shapes [Deprecated]
781
788
  This argument is now ignored and will be removed. Please filter the SpatialData object before calling this
782
789
  function.
@@ -810,6 +817,7 @@ def _(
810
817
  polygon: Polygon | MultiPolygon,
811
818
  target_coordinate_system: str,
812
819
  filter_table: bool = True,
820
+ clip: bool = False,
813
821
  shapes: bool = True,
814
822
  points: bool = True,
815
823
  images: bool = True,
@@ -825,6 +833,7 @@ def _(
825
833
  polygon_query,
826
834
  polygon=polygon,
827
835
  target_coordinate_system=target_coordinate_system,
836
+ clip=clip,
828
837
  )
829
838
  new_elements[element_type] = queried_elements
830
839
 
@@ -891,6 +900,7 @@ def _(
891
900
  element: GeoDataFrame,
892
901
  polygon: Polygon | MultiPolygon,
893
902
  target_coordinate_system: str,
903
+ clip: bool = False,
894
904
  **kwargs: Any,
895
905
  ) -> GeoDataFrame | None:
896
906
  from spatialdata.transformations import get_transformation, set_transformation
@@ -912,9 +922,18 @@ def _(
912
922
  queried_shapes = element[indices]
913
923
  queried_shapes.index = buffered[indices][OLD_INDEX]
914
924
  queried_shapes.index.name = None
925
+
926
+ if clip:
927
+ if isinstance(element.geometry.iloc[0], Point):
928
+ queried_shapes = buffered[indices]
929
+ queried_shapes.index = buffered[indices][OLD_INDEX]
930
+ queried_shapes.index.name = None
931
+ queried_shapes = queried_shapes.clip(polygon_gdf, keep_geom_type=True)
932
+
915
933
  del buffered[OLD_INDEX]
916
934
  if OLD_INDEX in queried_shapes.columns:
917
935
  del queried_shapes[OLD_INDEX]
936
+
918
937
  transformation = get_transformation(buffered, target_coordinate_system)
919
938
  queried_shapes = ShapesModel.parse(queried_shapes)
920
939
  set_transformation(queried_shapes, transformation, target_coordinate_system)
@@ -628,7 +628,7 @@ class SpatialData:
628
628
  found_element_name: list[str] = []
629
629
  for element_type in ["images", "labels", "points", "shapes", "tables"]:
630
630
  for element_name, element_value in getattr(self, element_type).items():
631
- if id(element_value) == id(element):
631
+ if element_value is element:
632
632
  found.append(element_value)
633
633
  found_element_type.append(element_type)
634
634
  found_element_name.append(element_name)
@@ -2225,6 +2225,7 @@ class QueryManager:
2225
2225
  polygon: Polygon | MultiPolygon,
2226
2226
  target_coordinate_system: str,
2227
2227
  filter_table: bool = True,
2228
+ clip: bool = False,
2228
2229
  ) -> SpatialData:
2229
2230
  """
2230
2231
  Perform a polygon query on the SpatialData object.
@@ -2239,6 +2240,7 @@ class QueryManager:
2239
2240
  polygon=polygon,
2240
2241
  target_coordinate_system=target_coordinate_system,
2241
2242
  filter_table=filter_table,
2243
+ clip=clip,
2242
2244
  )
2243
2245
 
2244
2246
  def __call__(self, request: BaseSpatialRequest, **kwargs) -> SpatialData: # type: ignore[no-untyped-def]
@@ -128,8 +128,8 @@ def read_zarr(store: Union[str, Path, zarr.Group], selection: Optional[tuple[str
128
128
 
129
129
  if "table" in selector and "table" in f:
130
130
  warnings.warn(
131
- f"Table group found in zarr store at location {f_store_path}. Please update the zarr store"
132
- f"to use tables instead.",
131
+ f"Table group found in zarr store at location {f_store_path}. Please update the zarr store to use tables "
132
+ f"instead.",
133
133
  DeprecationWarning,
134
134
  stacklevel=2,
135
135
  )
@@ -6,7 +6,7 @@ import numpy as np
6
6
  from datatree import DataTree
7
7
  from xarray import DataArray
8
8
 
9
- __all__ = ["ArrayLike", "DTypeLike", "Raster_T"]
9
+ __all__ = ["ArrayLike", "ColorLike", "DTypeLike", "Raster_T"]
10
10
 
11
11
  try:
12
12
  from numpy.typing import DTypeLike, NDArray
@@ -17,3 +17,4 @@ except (ImportError, TypeError):
17
17
  DTypeLike = np.dtype # type: ignore[misc]
18
18
 
19
19
  Raster_T = Union[DataArray, DataTree]
20
+ ColorLike = Union[tuple[float, ...], str]
@@ -63,8 +63,7 @@ def blobs(
63
63
 
64
64
  Returns
65
65
  -------
66
- SpatialData
67
- SpatialData object with blobs dataset.
66
+ SpatialData object with blobs dataset.
68
67
  """
69
68
  return BlobsDataset(
70
69
  length=length,
@@ -355,6 +354,19 @@ BlobsTypes = Literal[
355
354
 
356
355
 
357
356
  def blobs_annotating_element(name: BlobsTypes) -> SpatialData:
357
+ """
358
+ Return the blobs dataset with the desired element annotated by the table.
359
+
360
+ Parameters
361
+ ----------
362
+ name
363
+ Name of the element to annotate. One of "blobs_labels", "blobs_multiscale_labels", "blobs_circles",
364
+ "blobs_polygons", "blobs_multipolygons".
365
+
366
+ Returns
367
+ -------
368
+ SpatialData object with the desired element annotated by the table.
369
+ """
358
370
  sdata = blobs(length=50)
359
371
  if name in ["blobs_labels", "blobs_multiscale_labels"]:
360
372
  instance_id = get_element_instances(sdata[name]).tolist()
@@ -255,6 +255,17 @@ class Labels2DModel(RasterSchema):
255
255
  **kwargs,
256
256
  )
257
257
 
258
+ @classmethod
259
+ def parse( # noqa: D102
260
+ self,
261
+ *args: Any,
262
+ **kwargs: Any,
263
+ ) -> DataArray | DataTree:
264
+ if kwargs.get("scale_factors") is not None and kwargs.get("method") is None:
265
+ # Override default scaling method to preserve labels
266
+ kwargs["method"] = Methods.DASK_IMAGE_NEAREST
267
+ return super().parse(*args, **kwargs)
268
+
258
269
 
259
270
  class Labels3DModel(RasterSchema):
260
271
  dims = DimsSchema((Z, Y, X))
@@ -270,6 +281,13 @@ class Labels3DModel(RasterSchema):
270
281
  **kwargs,
271
282
  )
272
283
 
284
+ @classmethod
285
+ def parse(self, *args: Any, **kwargs: Any) -> DataArray | DataTree: # noqa: D102
286
+ if kwargs.get("scale_factors") is not None and kwargs.get("method") is None:
287
+ # Override default scaling method to preserve labels
288
+ kwargs["method"] = Methods.DASK_IMAGE_NEAREST
289
+ return super().parse(*args, **kwargs)
290
+
273
291
 
274
292
  class Image2DModel(RasterSchema):
275
293
  dims = DimsSchema((C, Y, X))
@@ -656,14 +674,18 @@ class PointsModel:
656
674
  )
657
675
  ndim = len(coordinates)
658
676
  axes = [X, Y, Z][:ndim]
659
- index_monotonically_increasing = data.index.is_monotonic_increasing
660
- if not isinstance(index_monotonically_increasing, bool):
661
- index_monotonically_increasing = index_monotonically_increasing.compute()
662
- if not index_monotonically_increasing:
677
+ if "sort" not in kwargs:
678
+ index_monotonically_increasing = data.index.is_monotonic_increasing
679
+ if not isinstance(index_monotonically_increasing, bool):
680
+ index_monotonically_increasing = index_monotonically_increasing.compute()
681
+ sort = index_monotonically_increasing
682
+ else:
683
+ sort = kwargs["sort"]
684
+ if not sort:
663
685
  warnings.warn(
664
686
  "The index of the dataframe is not monotonic increasing. It is recommended to sort the data to "
665
- "adjust the order of the index before calling .parse() to avoid possible problems due to unknown "
666
- "divisions",
687
+ "adjust the order of the index before calling .parse() (or call `parse(sort=True)`) to avoid possible "
688
+ "problems due to unknown divisions.",
667
689
  UserWarning,
668
690
  stacklevel=2,
669
691
  )
@@ -671,16 +693,16 @@ class PointsModel:
671
693
  table: DaskDataFrame = dd.from_pandas( # type: ignore[attr-defined]
672
694
  pd.DataFrame(data[[coordinates[ax] for ax in axes]].to_numpy(), columns=axes, index=data.index),
673
695
  # we need to pass sort=True also when the index is sorted to ensure that the divisions are computed
674
- sort=index_monotonically_increasing,
696
+ sort=sort,
675
697
  **kwargs,
676
698
  )
677
699
  # we cannot compute the divisions whne the index is not monotonically increasing and npartitions > 1
678
- if not table.known_divisions and (index_monotonically_increasing or table.npartitions == 1):
700
+ if not table.known_divisions and (sort or table.npartitions == 1):
679
701
  table.divisions = table.compute_current_divisions()
680
702
  if feature_key is not None:
681
703
  feature_categ = dd.from_pandas(
682
704
  data[feature_key].astype(str).astype("category"),
683
- sort=index_monotonically_increasing,
705
+ sort=sort,
684
706
  **kwargs,
685
707
  ) # type: ignore[attr-defined]
686
708
  table[feature_key] = feature_categ
@@ -21,6 +21,8 @@ from scipy import ndimage as ndi
21
21
  from shapely import linearrings, polygons
22
22
  from shapely.geometry import MultiPolygon, Point, Polygon
23
23
  from skimage import data
24
+ from xarray import DataArray
25
+
24
26
  from spatialdata._core._deepcopy import deepcopy
25
27
  from spatialdata._core.spatialdata import SpatialData
26
28
  from spatialdata._types import ArrayLike
@@ -34,7 +36,6 @@ from spatialdata.models import (
34
36
  ShapesModel,
35
37
  TableModel,
36
38
  )
37
- from xarray import DataArray
38
39
 
39
40
  SEED = 0
40
41
  RNG = default_rng(seed=SEED)
@@ -8,6 +8,7 @@ from anndata import AnnData
8
8
  from anndata.tests.helpers import assert_equal
9
9
  from geopandas import GeoDataFrame
10
10
  from numpy.random import default_rng
11
+
11
12
  from spatialdata import aggregate, to_polygons
12
13
  from spatialdata._core._deepcopy import deepcopy as _deepcopy
13
14
  from spatialdata._core.spatialdata import SpatialData
@@ -366,7 +367,7 @@ def test_aggregate_requiring_alignment(sdata_blobs: SpatialData, values, by) ->
366
367
  raise pytest.skip("Aggregation mixing raster and vector data is not currently supported.")
367
368
  values = sdata_blobs[values]
368
369
  by = sdata_blobs[by]
369
- if id(values) == id(by):
370
+ if values is by:
370
371
  # warning: this will give problems when aggregation labels by labels (not supported yet), because of this: https://github.com/scverse/spatialdata/issues/269
371
372
  by = _deepcopy(by)
372
373
  assert by.attrs["transform"] is not values.attrs["transform"]
@@ -2,9 +2,10 @@ import re
2
2
 
3
3
  import numpy as np
4
4
  import pytest
5
+ from xarray import DataArray
6
+
5
7
  from spatialdata._core.operations.map import map_raster
6
8
  from spatialdata.transformations import Translation, get_transformation, set_transformation
7
- from xarray import DataArray
8
9
 
9
10
 
10
11
  def _multiply(arr, parameter=10):
@@ -8,6 +8,7 @@ from numpy.random import default_rng
8
8
  from pandas import DataFrame
9
9
  from scipy.sparse import csr_matrix
10
10
  from shapely.geometry import Polygon
11
+
11
12
  from spatialdata._core.data_extent import are_extents_equal, get_extent
12
13
  from spatialdata._core.operations.rasterize_bins import rasterize_bins
13
14
  from spatialdata._core.spatialdata import SpatialData
@@ -5,6 +5,7 @@ import math
5
5
  import numpy as np
6
6
  import pytest
7
7
  from anndata import AnnData
8
+
8
9
  from spatialdata._core.concatenate import _concatenate_tables, concatenate
9
10
  from spatialdata._core.data_extent import are_extents_equal, get_extent
10
11
  from spatialdata._core.operations._utils import transform_to_data_extent
@@ -21,7 +22,6 @@ from spatialdata.transformations.transformations import (
21
22
  Sequence,
22
23
  Translation,
23
24
  )
24
-
25
25
  from tests.conftest import _get_table
26
26
 
27
27
 
@@ -296,7 +296,7 @@ def test_locate_spatial_element(full_sdata: SpatialData) -> None:
296
296
 
297
297
 
298
298
  def test_get_item(points: SpatialData) -> None:
299
- assert id(points["points_0"]) == id(points.points["points_0"])
299
+ assert points["points_0"] is points.points["points_0"]
300
300
 
301
301
  # removed this test after this change: https://github.com/scverse/spatialdata/pull/145#discussion_r1133122720
302
302
  # to be uncommented/removed/modified after this is closed: https://github.com/scverse/spatialdata/issues/186
@@ -6,6 +6,8 @@ import numpy as np
6
6
  import pytest
7
7
  from datatree import DataTree
8
8
  from geopandas.testing import geom_almost_equals
9
+ from xarray import DataArray
10
+
9
11
  from spatialdata import transform
10
12
  from spatialdata._core.data_extent import are_extents_equal, get_extent
11
13
  from spatialdata._core.spatialdata import SpatialData
@@ -28,7 +30,6 @@ from spatialdata.transformations.transformations import (
28
30
  Sequence,
29
31
  Translation,
30
32
  )
31
- from xarray import DataArray
32
33
 
33
34
 
34
35
  class TestElementsTransform:
@@ -4,6 +4,7 @@ import numpy as np
4
4
  import pytest
5
5
  from geopandas import GeoDataFrame
6
6
  from shapely import MultiPoint, Point
7
+
7
8
  from spatialdata._core.operations.vectorize import to_circles, to_polygons
8
9
  from spatialdata.datasets import blobs
9
10
  from spatialdata.models.models import ShapesModel
@@ -2,6 +2,7 @@ import numpy as np
2
2
  import pandas as pd
3
3
  import pytest
4
4
  from anndata import AnnData
5
+
5
6
  from spatialdata import get_values, match_table_to_element
6
7
  from spatialdata._core.query.relational_query import (
7
8
  _locate_value,
@@ -11,6 +11,9 @@ from dask.dataframe import DataFrame as DaskDataFrame
11
11
  from datatree import DataTree
12
12
  from geopandas import GeoDataFrame
13
13
  from shapely import MultiPolygon, Point, Polygon
14
+ from xarray import DataArray
15
+
16
+ from spatialdata._core.data_extent import get_extent
14
17
  from spatialdata._core.query.spatial_query import (
15
18
  BaseSpatialRequest,
16
19
  BoundingBoxRequest,
@@ -29,8 +32,6 @@ from spatialdata.models import (
29
32
  )
30
33
  from spatialdata.testing import assert_spatial_data_objects_are_identical
31
34
  from spatialdata.transformations import Identity, MapAxis, set_transformation
32
- from xarray import DataArray
33
-
34
35
  from tests.conftest import _make_points, _make_squares
35
36
 
36
37
 
@@ -686,3 +687,37 @@ def test_spatial_query_different_axes(full_sdata, name: str):
686
687
  return
687
688
 
688
689
  raise RuntimeError(f"Unexpected type {type(original)}")
690
+
691
+
692
+ def test_query_with_clipping(sdata_blobs):
693
+ circles = sdata_blobs["blobs_circles"]
694
+ circles.index = [10, 100, 1]
695
+ polygons = sdata_blobs["blobs_polygons"]
696
+ polygons.index = [10, 100, 1]
697
+
698
+ # define square to use as query geometry
699
+ minx = 120
700
+ maxx = 170
701
+ miny = 150
702
+ maxy = 210
703
+ x_coords = [minx, maxx, maxx, minx, minx]
704
+ y_coords = [miny, miny, maxy, maxy, miny]
705
+ polygon = Polygon(zip(x_coords, y_coords))
706
+
707
+ queried_circles = polygon_query(circles, polygon=polygon, target_coordinate_system="global", clip=True)
708
+ queried_polygons = polygon_query(polygons, polygon=polygon, target_coordinate_system="global", clip=True)
709
+
710
+ assert queried_circles.index.tolist() == [100]
711
+ assert queried_polygons.index.tolist() == [100]
712
+
713
+ extent_circles = get_extent(queried_circles)
714
+ extent_polygons = get_extent(queried_polygons)
715
+
716
+ def query_polyon_contains_queried_data(extent: dict[str, tuple[float, float]]) -> None:
717
+ assert extent["x"][0] >= minx
718
+ assert extent["x"][1] <= maxx
719
+ assert extent["y"][0] >= miny
720
+ assert extent["y"][1] <= maxy
721
+
722
+ query_polyon_contains_queried_data(extent_circles)
723
+ query_polyon_contains_queried_data(extent_polygons)
@@ -5,6 +5,7 @@ import pandas as pd
5
5
  import pytest
6
6
  from anndata import AnnData
7
7
  from numpy.random import default_rng
8
+
8
9
  from spatialdata._core.centroids import get_centroids
9
10
  from spatialdata._core.query.relational_query import get_element_instances
10
11
  from spatialdata.models import Labels2DModel, Labels3DModel, PointsModel, TableModel, get_axes_names
@@ -6,6 +6,7 @@ import pytest
6
6
  from geopandas import GeoDataFrame
7
7
  from numpy.random import default_rng
8
8
  from shapely.geometry import MultiPolygon, Point, Polygon
9
+
9
10
  from spatialdata import SpatialData, get_extent, transform
10
11
  from spatialdata._core._deepcopy import deepcopy as _deepcopy
11
12
  from spatialdata.datasets import blobs
@@ -1,4 +1,5 @@
1
1
  from pandas.testing import assert_frame_equal
2
+
2
3
  from spatialdata._core._deepcopy import deepcopy as _deepcopy
3
4
  from spatialdata.testing import assert_spatial_data_objects_are_identical
4
5
 
@@ -1,5 +1,6 @@
1
1
  import numpy as np
2
2
  import pytest
3
+
3
4
  from spatialdata.dataloader import ImageTilesDataset
4
5
  from spatialdata.datasets import blobs_annotating_element
5
6
 
@@ -2,6 +2,7 @@ from typing import Any, Optional
2
2
 
3
3
  import pytest
4
4
  from shapely import GeometryType
5
+
5
6
  from spatialdata._io.format import CurrentPointsFormat, CurrentShapesFormat, ShapesFormatV01
6
7
  from spatialdata.models import PointsModel, ShapesModel
7
8
 
@@ -3,6 +3,7 @@ import os
3
3
  import tempfile
4
4
 
5
5
  import pytest
6
+
6
7
  from spatialdata import SpatialData, read_zarr
7
8
  from spatialdata._io._utils import _is_element_self_contained
8
9
  from spatialdata._logging import logger
@@ -2,6 +2,7 @@ import os
2
2
  import tempfile
3
3
 
4
4
  import dask.dataframe as dd
5
+
5
6
  from spatialdata import read_zarr
6
7
  from spatialdata._io._utils import get_dask_backing_files
7
8
 
@@ -22,6 +22,8 @@ from numpy.random import default_rng
22
22
  from shapely.geometry import MultiPolygon, Point, Polygon
23
23
  from shapely.io import to_ragged_array
24
24
  from spatial_image import to_spatial_image
25
+ from xarray import DataArray
26
+
25
27
  from spatialdata._core.spatialdata import SpatialData
26
28
  from spatialdata._types import ArrayLike
27
29
  from spatialdata.models._utils import (
@@ -51,8 +53,6 @@ from spatialdata.transformations.operations import (
51
53
  set_transformation,
52
54
  )
53
55
  from spatialdata.transformations.transformations import Identity, Scale
54
- from xarray import DataArray
55
-
56
56
  from tests.conftest import (
57
57
  MULTIPOLYGON_PATH,
58
58
  POINT_PATH,
@@ -195,6 +195,27 @@ class TestModels:
195
195
  with pytest.raises(ValueError):
196
196
  model.parse(image, **kwargs)
197
197
 
198
+ @pytest.mark.parametrize("model", [Labels2DModel, Labels3DModel])
199
+ def test_labels_model_with_multiscales(self, model):
200
+ # Passing "scale_factors" should generate multiscales with a "method" appropriate for labels
201
+ dims = np.array(model.dims.dims).tolist()
202
+ n_dims = len(dims)
203
+
204
+ # A labels image with one label value 4, that partially covers 2×2 blocks.
205
+ # Downsampling with interpolation would produce values 1, 2, 3, 4.
206
+ image: ArrayLike = np.array([[0, 0, 0, 0], [0, 4, 4, 4], [4, 4, 4, 4], [0, 4, 4, 4]], dtype=np.uint16)
207
+ if n_dims == 3:
208
+ image = np.stack([image] * image.shape[0])
209
+ actual = model.parse(image, scale_factors=(2,))
210
+ assert isinstance(actual, DataTree)
211
+ assert actual.children.keys() == {"scale0", "scale1"}
212
+ assert actual.scale0.image.dtype == image.dtype
213
+ assert actual.scale1.image.dtype == image.dtype
214
+ assert set(np.unique(image)) == set(np.unique(actual.scale0.image)), "Scale0 should be preserved"
215
+ assert set(np.unique(image)) >= set(
216
+ np.unique(actual.scale1.image)
217
+ ), "Subsequent scales should not have interpolation artifacts"
218
+
198
219
  @pytest.mark.parametrize("model", [ShapesModel])
199
220
  @pytest.mark.parametrize("path", [POLYGON_PATH, MULTIPOLYGON_PATH, POINT_PATH])
200
221
  def test_shapes_model(self, model: ShapesModel, path: Path) -> None:
@@ -2,6 +2,7 @@ import copy
2
2
  import json
3
3
 
4
4
  import pytest
5
+
5
6
  from spatialdata.transformations.ngff.ngff_coordinate_system import (
6
7
  NgffAxis,
7
8
  NgffCoordinateSystem,
@@ -4,6 +4,8 @@ from copy import deepcopy
4
4
  import numpy as np
5
5
  import pytest
6
6
  import xarray.testing
7
+ from xarray import DataArray
8
+
7
9
  from spatialdata import transform
8
10
  from spatialdata.datasets import blobs
9
11
  from spatialdata.models import Image2DModel, PointsModel
@@ -32,7 +34,6 @@ from spatialdata.transformations.transformations import (
32
34
  _decompose_transformation,
33
35
  _get_affine_for_element,
34
36
  )
35
- from xarray import DataArray
36
37
 
37
38
 
38
39
  def test_identity():
@@ -4,10 +4,11 @@ import dask_image.ndinterp
4
4
  import pytest
5
5
  import xarray
6
6
  from datatree import DataTree
7
+ from xarray import DataArray
8
+
7
9
  from spatialdata._utils import unpad_raster
8
10
  from spatialdata.models import get_model
9
11
  from spatialdata.transformations import Affine
10
- from xarray import DataArray
11
12
 
12
13
 
13
14
  def _pad_raster(data: DataArray, axes: tuple[str, ...]) -> DataArray:
@@ -3,6 +3,8 @@ import copy
3
3
  import numpy as np
4
4
  import pytest
5
5
  from datatree import DataTree
6
+ from xarray import DataArray
7
+
6
8
  from spatialdata import SpatialData, deepcopy
7
9
  from spatialdata.models import (
8
10
  Image2DModel,
@@ -16,7 +18,6 @@ from spatialdata.models import (
16
18
  )
17
19
  from spatialdata.testing import assert_elements_are_identical, assert_spatial_data_objects_are_identical
18
20
  from spatialdata.transformations import Scale, set_transformation
19
- from xarray import DataArray
20
21
 
21
22
  scale = Scale([1.0], axes=("x",))
22
23
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -11,6 +11,8 @@ from geopandas import GeoDataFrame
11
11
  from multiscale_spatial_image import MultiscaleSpatialImage
12
12
  from shapely import MultiPolygon, box
13
13
  from spatial_image import SpatialImage
14
+ from xarray import DataArray
15
+
14
16
  from spatialdata import SpatialData, get_extent
15
17
  from spatialdata._core.operations.rasterize import rasterize
16
18
  from spatialdata._core.query.relational_query import get_element_instances
@@ -18,8 +20,6 @@ from spatialdata._io._utils import _iter_multiscale
18
20
  from spatialdata.models import PointsModel, ShapesModel, TableModel, get_axes_names
19
21
  from spatialdata.models._utils import get_spatial_axes
20
22
  from spatialdata.transformations import MapAxis
21
- from xarray import DataArray
22
-
23
23
  from tests.conftest import _get_images, _get_labels
24
24
 
25
25
 
@@ -4,9 +4,9 @@ import pandas as pd
4
4
  import pytest
5
5
  from anndata import AnnData
6
6
  from anndata.tests.helpers import assert_equal
7
+
7
8
  from spatialdata import SpatialData, concatenate
8
9
  from spatialdata.models import TableModel
9
-
10
10
  from tests.conftest import _get_shapes, _get_table
11
11
 
12
12
  # notes on paths: https://github.com/orgs/scverse/projects/17/views/1?pane=issue&itemId=44066734
@@ -8,6 +8,7 @@ import numpy as np
8
8
  import pytest
9
9
  from anndata import AnnData
10
10
  from numpy.random import default_rng
11
+
11
12
  from spatialdata import SpatialData, deepcopy, read_zarr
12
13
  from spatialdata._io._utils import _are_directories_identical, get_dask_backing_files
13
14
  from spatialdata.datasets import blobs
@@ -19,7 +20,6 @@ from spatialdata.transformations.operations import (
19
20
  set_transformation,
20
21
  )
21
22
  from spatialdata.transformations.transformations import Identity, Scale
22
-
23
23
  from tests.conftest import _get_images, _get_labels, _get_points, _get_shapes
24
24
 
25
25
  RNG = default_rng(0)
@@ -4,6 +4,7 @@ import json
4
4
 
5
5
  import numpy as np
6
6
  import pytest
7
+
7
8
  from spatialdata._types import ArrayLike
8
9
  from spatialdata.models import C, X, Y, Z
9
10
  from spatialdata.transformations.ngff._utils import get_default_coordinate_system
@@ -19,7 +20,6 @@ from spatialdata.transformations.ngff.ngff_transformations import (
19
20
  NgffSequence,
20
21
  NgffTranslation,
21
22
  )
22
-
23
23
  from tests.transformations.ngff.conftest import (
24
24
  c_cs,
25
25
  cyx_cs,