spatial-aim 1.2.0__tar.gz → 1.3.0__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 (163) hide show
  1. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/PKG-INFO +31 -17
  2. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/README.md +26 -16
  3. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/environment.yml +7 -3
  4. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/pyproject.toml +4 -2
  5. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatial_aim.egg-info/PKG-INFO +31 -17
  6. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatial_aim.egg-info/SOURCES.txt +42 -13
  7. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatial_aim.egg-info/requires.txt +4 -0
  8. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatial_aim.egg-info/scm_file_list.json +42 -13
  9. spatial_aim-1.3.0/src/spatial_aim.egg-info/scm_version.json +8 -0
  10. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/__init__.py +4 -2
  11. spatial_aim-1.3.0/src/spatialaim/__main__.py +8 -0
  12. spatial_aim-1.3.0/src/spatialaim/adata_schema.py +132 -0
  13. spatial_aim-1.3.0/src/spatialaim/aggregation.py +88 -0
  14. spatial_aim-1.3.0/src/spatialaim/analysis/coherence.py +114 -0
  15. spatial_aim-1.3.0/src/spatialaim/analysis/compare_ks/__init__.py +19 -0
  16. spatial_aim-1.3.0/src/spatialaim/analysis/compare_ks/collect.py +84 -0
  17. spatial_aim-1.3.0/src/spatialaim/analysis/compare_ks/criteria.py +64 -0
  18. spatial_aim-1.3.0/src/spatialaim/analysis/compare_ks/run.py +65 -0
  19. spatial_aim-1.3.0/src/spatialaim/analysis/compare_ks/scoring.py +93 -0
  20. spatial_aim-1.3.0/src/spatialaim/analysis/compare_ks/selection.py +60 -0
  21. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/analysis/loading.py +26 -41
  22. spatial_aim-1.3.0/src/spatialaim/analysis/reconstruction.py +232 -0
  23. spatial_aim-1.3.0/src/spatialaim/analysis/run.py +37 -0
  24. spatial_aim-1.3.0/src/spatialaim/analysis/shape_consistency.py +92 -0
  25. spatial_aim-1.3.0/src/spatialaim/analysis/spatial_organization.py +122 -0
  26. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/cli.py +150 -131
  27. spatial_aim-1.3.0/src/spatialaim/clustering.py +170 -0
  28. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/config.py +10 -26
  29. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/README.md +3 -0
  30. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/_common.py +1 -1
  31. spatial_aim-1.3.0/src/spatialaim/data/curate_datasets/_segmentation.py +315 -0
  32. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_02_colorectal_cancer.py +89 -9
  33. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_03_mouse_liver.py +28 -5
  34. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_04_mouse_kidney.py +28 -5
  35. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_05_mouse_embryo.py +110 -31
  36. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_09_human_breast_cancer.py +64 -7
  37. spatial_aim-1.3.0/src/spatialaim/data/validate/__init__.py +29 -0
  38. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/validate/common.py +84 -72
  39. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/validate/runner.py +85 -98
  40. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/validate/validate_pair.py +8 -9
  41. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/validate/validate_sc.py +14 -12
  42. spatial_aim-1.3.0/src/spatialaim/data/validate/validate_segmentation.py +163 -0
  43. spatial_aim-1.3.0/src/spatialaim/data/validate/validate_st.py +98 -0
  44. spatial_aim-1.3.0/src/spatialaim/gui/__init__.py +21 -0
  45. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/gui/__main__.py +2 -1
  46. spatial_aim-1.3.0/src/spatialaim/gui/app.py +228 -0
  47. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/gui/compute.py +8 -2
  48. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/gui/data_access.py +36 -95
  49. spatial_aim-1.3.0/src/spatialaim/gui/loaders.py +96 -0
  50. spatial_aim-1.3.0/src/spatialaim/gui/render/__init__.py +14 -0
  51. spatial_aim-1.3.0/src/spatialaim/gui/render/cell_type.py +360 -0
  52. spatial_aim-1.3.0/src/spatialaim/gui/render/common.py +267 -0
  53. spatial_aim-1.3.0/src/spatialaim/gui/render/headline.py +387 -0
  54. spatial_aim-1.3.0/src/spatialaim/gui/render/ksweep.py +338 -0
  55. spatial_aim-1.3.0/src/spatialaim/gui/render/markers.py +457 -0
  56. spatial_aim-1.3.0/src/spatialaim/gui/render/report.py +386 -0
  57. spatial_aim-1.3.0/src/spatialaim/gui/render/scatter.py +482 -0
  58. spatial_aim-1.3.0/src/spatialaim/gui/render/shape.py +150 -0
  59. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/gui/scaffold.py +2 -1
  60. spatial_aim-1.3.0/src/spatialaim/gui/sidebar.py +568 -0
  61. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/gui/state_names.py +2 -1
  62. spatial_aim-1.3.0/src/spatialaim/gui/texts.py +110 -0
  63. spatial_aim-1.3.0/src/spatialaim/gui/validation.py +183 -0
  64. spatial_aim-1.3.0/src/spatialaim/gui/views/__init__.py +12 -0
  65. spatial_aim-1.3.0/src/spatialaim/gui/views/cards.py +180 -0
  66. spatial_aim-1.3.0/src/spatialaim/gui/views/cell_type_modal.py +351 -0
  67. spatial_aim-1.3.0/src/spatialaim/gui/views/choose_k.py +232 -0
  68. spatial_aim-1.3.0/src/spatialaim/gui/views/compare_tab.py +168 -0
  69. spatial_aim-1.3.0/src/spatialaim/gui/views/controls.py +46 -0
  70. spatial_aim-1.3.0/src/spatialaim/gui/views/mapper_tab.py +238 -0
  71. spatial_aim-1.3.0/src/spatialaim/gui/views/reference_tab.py +178 -0
  72. spatial_aim-1.3.0/src/spatialaim/gui/views/report.py +179 -0
  73. spatial_aim-1.3.0/src/spatialaim/gui/widgets/__init__.py +5 -0
  74. spatial_aim-1.3.0/src/spatialaim/gui/widgets/headline_plot.py +323 -0
  75. spatial_aim-1.3.0/src/spatialaim/gui/widgets/linked_plot.py +186 -0
  76. spatial_aim-1.3.0/src/spatialaim/gui/widgets/plotly_fit.py +63 -0
  77. spatial_aim-1.3.0/src/spatialaim/gui/widgets/slider.py +281 -0
  78. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/io.py +35 -68
  79. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/mapping/__init__.py +3 -2
  80. spatial_aim-1.3.0/src/spatialaim/mapping/base.py +58 -0
  81. spatial_aim-1.3.0/src/spatialaim/mapping/confidence.py +42 -0
  82. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/mapping/nearest_centroid.py +10 -11
  83. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/mapping/reference.py +29 -47
  84. spatial_aim-1.3.0/src/spatialaim/mapping/wann.py +169 -0
  85. spatial_aim-1.3.0/src/spatialaim/metrics/__init__.py +0 -0
  86. spatial_aim-1.3.0/src/spatialaim/metrics/cossim.py +16 -0
  87. spatial_aim-1.3.0/src/spatialaim/metrics/modularity.py +42 -0
  88. spatial_aim-1.3.0/src/spatialaim/metrics/shape_consistency.py +80 -0
  89. spatial_aim-1.3.0/src/spatialaim/metrics/topology.py +49 -0
  90. spatial_aim-1.3.0/src/spatialaim/reference_aligners/__init__.py +0 -0
  91. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/registry.py +2 -1
  92. spatial_aim-1.3.0/src/spatialaim/sweep.py +237 -0
  93. spatial_aim-1.3.0/src/spatialaim/tree.py +55 -0
  94. {spatial_aim-1.2.0/src/spatialaim/analysis → spatial_aim-1.3.0/src/spatialaim}/utils.py +5 -3
  95. spatial_aim-1.2.0/src/spatial_aim.egg-info/scm_version.json +0 -8
  96. spatial_aim-1.2.0/src/spatialaim/__main__.py +0 -6
  97. spatial_aim-1.2.0/src/spatialaim/adata_schema.py +0 -80
  98. spatial_aim-1.2.0/src/spatialaim/aggregation.py +0 -118
  99. spatial_aim-1.2.0/src/spatialaim/analysis/__init__.py +0 -13
  100. spatial_aim-1.2.0/src/spatialaim/analysis/analysis.py +0 -72
  101. spatial_aim-1.2.0/src/spatialaim/analysis/biology.py +0 -205
  102. spatial_aim-1.2.0/src/spatialaim/analysis/confidence.py +0 -49
  103. spatial_aim-1.2.0/src/spatialaim/analysis/ksweep.py +0 -184
  104. spatial_aim-1.2.0/src/spatialaim/analysis/onehot.py +0 -41
  105. spatial_aim-1.2.0/src/spatialaim/analysis/reconstruction.py +0 -131
  106. spatial_aim-1.2.0/src/spatialaim/analysis/topology.py +0 -142
  107. spatial_aim-1.2.0/src/spatialaim/clustering.py +0 -242
  108. spatial_aim-1.2.0/src/spatialaim/data/validate/__init__.py +0 -35
  109. spatial_aim-1.2.0/src/spatialaim/data/validate/validate_st.py +0 -74
  110. spatial_aim-1.2.0/src/spatialaim/gui/__init__.py +0 -8
  111. spatial_aim-1.2.0/src/spatialaim/gui/app.py +0 -2232
  112. spatial_aim-1.2.0/src/spatialaim/gui/render.py +0 -2444
  113. spatial_aim-1.2.0/src/spatialaim/gui/widgets.py +0 -810
  114. spatial_aim-1.2.0/src/spatialaim/mapping/base.py +0 -67
  115. spatial_aim-1.2.0/src/spatialaim/mapping/confidence.py +0 -51
  116. spatial_aim-1.2.0/src/spatialaim/mapping/wann.py +0 -208
  117. spatial_aim-1.2.0/src/spatialaim/metrics/__init__.py +0 -26
  118. spatial_aim-1.2.0/src/spatialaim/metrics/biology.py +0 -69
  119. spatial_aim-1.2.0/src/spatialaim/metrics/cossim.py +0 -127
  120. spatial_aim-1.2.0/src/spatialaim/metrics/kselection.py +0 -272
  121. spatial_aim-1.2.0/src/spatialaim/metrics/onehot.py +0 -54
  122. spatial_aim-1.2.0/src/spatialaim/metrics/reconstruction.py +0 -73
  123. spatial_aim-1.2.0/src/spatialaim/metrics/topology.py +0 -62
  124. spatial_aim-1.2.0/src/spatialaim/sweep.py +0 -261
  125. spatial_aim-1.2.0/src/spatialaim/tree.py +0 -86
  126. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/.github/workflows/ci.yml +0 -0
  127. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/.github/workflows/release.yml +0 -0
  128. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/.gitignore +0 -0
  129. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/.pre-commit-config.yaml +0 -0
  130. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/LICENSE +0 -0
  131. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/docs/aim_gui.gif +0 -0
  132. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/docs/figure_2_1.png +0 -0
  133. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/renovate.json +0 -0
  134. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/sample_dataset/ST/index.csv +0 -0
  135. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/sample_dataset/ST/sample_st.h5ad +0 -0
  136. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/sample_dataset/pairs.csv +0 -0
  137. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/sample_dataset/scRNA/index.csv +0 -0
  138. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/sample_dataset/scRNA/sample_sc.h5ad +0 -0
  139. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/setup.cfg +0 -0
  140. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatial_aim.egg-info/dependency_links.txt +0 -0
  141. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatial_aim.egg-info/entry_points.txt +0 -0
  142. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatial_aim.egg-info/top_level.txt +0 -0
  143. {spatial_aim-1.2.0/src/spatialaim/data → spatial_aim-1.3.0/src/spatialaim/analysis}/__init__.py +0 -0
  144. {spatial_aim-1.2.0/src/spatialaim/reference_aligners → spatial_aim-1.3.0/src/spatialaim/data}/__init__.py +0 -0
  145. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/__init__.py +0 -0
  146. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_01_mouse_ssp.py +0 -0
  147. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_06_mouse_retina.py +0 -0
  148. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_07_mouse_mpfc.py +0 -0
  149. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_08_mouse_visual_cortex.py +0 -0
  150. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/curate_10_human_mtg.py +0 -0
  151. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/dump_retina_counts.R +0 -0
  152. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/data/curate_datasets/environment_retina_qs.yml +0 -0
  153. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/environment_dot.yml +0 -0
  154. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/environment_tacco.yml +0 -0
  155. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/environment_tangram.yml +0 -0
  156. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/run_dot.R +0 -0
  157. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/run_dot.py +0 -0
  158. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/run_tacco.py +0 -0
  159. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/src/spatialaim/reference_aligners/run_tangram.py +0 -0
  160. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/tests/test_cli.py +0 -0
  161. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/tests/test_gui_imports.py +0 -0
  162. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/tests/test_registry.py +0 -0
  163. {spatial_aim-1.2.0 → spatial_aim-1.3.0}/tests/test_sweep_sample.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatial-aim
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: SpatialAIM — annotation-independent mapping of scRNA-seq references onto high-resolution spatial transcriptomics
5
5
  Author-email: Dominik Pysch <dominik.pysch@fau.de>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -702,6 +702,9 @@ Requires-Dist: squidpy>=1.4
702
702
  Requires-Dist: igraph>=0.11
703
703
  Requires-Dist: leidenalg>=0.10
704
704
  Requires-Dist: umap-learn>=0.5
705
+ Requires-Dist: tifffile>=2024.8
706
+ Requires-Dist: zarr>=2.16
707
+ Requires-Dist: scikit-image>=0.22
705
708
  Requires-Dist: streamlit>=1.40
706
709
  Requires-Dist: plotly>=5.20
707
710
  Requires-Dist: kaleido>=0.2
@@ -709,6 +712,7 @@ Provides-Extra: data
709
712
  Requires-Dist: matplotlib>=3.9; extra == "data"
710
713
  Requires-Dist: scikit-learn>=1.4; extra == "data"
711
714
  Requires-Dist: rdata>=1.1; extra == "data"
715
+ Requires-Dist: h5py>=3.10; extra == "data"
712
716
  Provides-Extra: dev
713
717
  Requires-Dist: pytest>=8; extra == "dev"
714
718
  Requires-Dist: black>=24; extra == "dev"
@@ -785,7 +789,8 @@ DATA/
785
789
  │ └── <scName>.h5ad
786
790
  ├── ST/
787
791
  │ ├── index.csv # one row per ST dataset
788
- │ └── <stName>.h5ad
792
+ │ ├── <stName>.h5ad
793
+ │ └── Segmentation/ # optional cell segmentation masks (index.csv column `Segmentation`)
789
794
  └── pairs.csv # links scRNA ↔ ST: PairID, scName, stName, …
790
795
  ```
791
796
 
@@ -822,7 +827,7 @@ Please install the corresponding conda environments on your computer.
822
827
  Check whether your data meets the main requirements.
823
828
 
824
829
  ```bash
825
- spatialaim validate --scdata path/to/sc.h5ad --stdata path/to/st.h5ad
830
+ spatialaim validate --scdata path/to/sc.h5ad --stdata path/to/st.h5ad [--segmentation path/to/mask.tif]
826
831
  ```
827
832
 
828
833
  or for every pair of a `pairs.csv` laid out as in [Batch Processing](#batch-processing):
@@ -840,6 +845,10 @@ Validations per dataset:
840
845
  - raw count matrices (no NaN values, np negative values, integer-looking, not library-size normalized or log1p'd)
841
846
  - unique uppercase gene names
842
847
  - `obsm["spatial"]` of shape `(n_spots, 2)`.
848
+ - Optional cell segmentation mask of an ST slice
849
+ - a 2D `.tif`/`.tiff` of dtype `uint32`: `0` = background, cells labelled `1..max` without gaps (labels without a cell in the h5ad are fine)
850
+ - the ST h5ad carries the integer `obs["segmentation_id"]` (each cell's mask label, `0` = no segmentation): non-negative, non-zero ids unique and present in the mask
851
+ - `uns["segmentation_pixel_size_um"]` (µm per pixel) is optional - a warning if missing
843
852
  - Per pair
844
853
  - the size of the shared-gene intersection
845
854
  - whether any ST spot is left all-zero by it.
@@ -856,6 +865,7 @@ spatialaim gui [--server_port 8501]
856
865
  Open the printed URL (default http://localhost:8501), set the inputs, pick one or multiple mapper(s), and click **Run**.
857
866
  As soon as both `.h5ad` paths are set, the GUI runs the same checks as [`spatialaim validate`](#validate-a-dataset-pair-spatialaim-validate) on that pair: a clean pair is confirmed with a tick in the sidebar, any error or warning is shown in a dialog you can close to continue anyway.
858
867
  The GUI writes each mapper's sweep to `<output_dir>/<mapper>/`. The results using each mapper are visualized in different tabs. When having run multiple mappers, also a "Compare" tab appears.
868
+ An optional **Segmentation path** (the ST slice's cell segmentation mask, see the sidebar's *Info*) is validated with the pair and passed to the runs; their mapper tabs then get a "Shape features" card (shape consistency and the cells' area / eccentricity / solidity per cell type), and the cell-type modal a "Shape features" view. Without it the GUI is unchanged.
859
869
 
860
870
  ### Run via CLI (`spatialaim run`)
861
871
 
@@ -882,6 +892,7 @@ Give such runs their own `--output_dir`: a run root is named after the mapper al
882
892
  spatialaim run --scdata path/to/sc.h5ad \
883
893
  --stdata path/to/st.h5ad \
884
894
  --output_dir path/to/out_dir \
895
+ [--segmentation path/to/mask.tif] \
885
896
  [--mapping nearest_centroid|wann|tangram|tacco|dot] \
886
897
  [--linkage_method average|ward] \
887
898
  [--start_from_annotation <obs_column>] \
@@ -890,7 +901,9 @@ spatialaim run --scdata path/to/sc.h5ad \
890
901
  [--logging verbose]
891
902
  ```
892
903
 
893
- **Batch mode (all pairs in `pairs.csv`):**
904
+ `--segmentation` is the ST slice's optional cell segmentation mask; with it the analysis also scores **shape consistency** (column `shape` of `k_comparison.csv`), without it that score is NaN.
905
+
906
+ **Batch mode (all pairs in `pairs.csv`):** each slice's mask is taken from the `Segmentation` column of `ST/index.csv` (file in `ST/Segmentation/`), if set.
894
907
 
895
908
  ```bash
896
909
  spatialaim run --pairs_csv path/to/pairs.csv \
@@ -909,19 +922,20 @@ Each pair is written to `<out_dir>/<PairID>_<scName>__<stName>/`.
909
922
 
910
923
  **Output layout** (per pair):
911
924
 
912
- - `<mapping>/config.yaml` — the run configuration.
913
- - `start_clustering.h5ad` — per-cell start cluster (`start_cluster` id + `start_cluster_name`); computed once, reused for every `K`.
914
- - `k_<kkk>/` — one folder per `K`:
915
- - `spot_to_state_mapping_soft.h5ad` — the spot→state matrix `P` (spots × `K`);
916
- carries `obs["mapping_confidence"]` when the mapper defines one.
917
- - `spot_to_state_mapping.csv` — `P` as CSV (for eyeballing).
918
- - `start_cluster_to_state.csv` — the start-cluster→state tree cut.
919
- - `analysis/data/` — machine-readable metrics for that `K` (no figures; the GUI renders them).
920
- - `k_comparison.csv` — one row per `K`: the measured metrics, plus each criterion's combined
921
- score (harmonic mean of its two curves), the overall score across criteria, and a
922
- `pareto` flag.
923
- - `k_selection.json` — the proposal: the Pareto-optimal `K`, and the best `K` per criterion
924
- and overall, each with its score. Same computation the GUI's "Choose K" card shows.
925
+ ```
926
+ <out_dir>/
927
+ ├── reference_scaffold.h5ad # cached reference preparation, shared by all mappers
928
+ └── <mapping>/ # one folder per mapper, e.g. nearest_centroid/
929
+ ├── config.yaml # the run's settings
930
+ ├── start_clustering.h5ad # each reference cell's start cluster
931
+ ├── cell_shape_features.csv # only with a segmentation mask: area, eccentricity, solidity per cell
932
+ ├── k_<kkk>/ # one folder per K
933
+ │ ├── spot_to_state_mapping_soft.h5ad # the mapping P (spots × K), plus confidence if the mapper has one
934
+ │ ├── start_cluster_to_state.csv # which state each start cluster belongs to
935
+ │ └── analysis/data/ # the metrics for this K (the GUI plots them)
936
+ ├── k_comparison.csv # one row per K: all metrics and the K-selection scores
937
+ └── k_selection.json # the suggested K, overall and per criterion
938
+ ```
925
939
 
926
940
  **Sample-dataset example:**
927
941
 
@@ -64,7 +64,8 @@ DATA/
64
64
  │ └── <scName>.h5ad
65
65
  ├── ST/
66
66
  │ ├── index.csv # one row per ST dataset
67
- │ └── <stName>.h5ad
67
+ │ ├── <stName>.h5ad
68
+ │ └── Segmentation/ # optional cell segmentation masks (index.csv column `Segmentation`)
68
69
  └── pairs.csv # links scRNA ↔ ST: PairID, scName, stName, …
69
70
  ```
70
71
 
@@ -101,7 +102,7 @@ Please install the corresponding conda environments on your computer.
101
102
  Check whether your data meets the main requirements.
102
103
 
103
104
  ```bash
104
- spatialaim validate --scdata path/to/sc.h5ad --stdata path/to/st.h5ad
105
+ spatialaim validate --scdata path/to/sc.h5ad --stdata path/to/st.h5ad [--segmentation path/to/mask.tif]
105
106
  ```
106
107
 
107
108
  or for every pair of a `pairs.csv` laid out as in [Batch Processing](#batch-processing):
@@ -119,6 +120,10 @@ Validations per dataset:
119
120
  - raw count matrices (no NaN values, np negative values, integer-looking, not library-size normalized or log1p'd)
120
121
  - unique uppercase gene names
121
122
  - `obsm["spatial"]` of shape `(n_spots, 2)`.
123
+ - Optional cell segmentation mask of an ST slice
124
+ - a 2D `.tif`/`.tiff` of dtype `uint32`: `0` = background, cells labelled `1..max` without gaps (labels without a cell in the h5ad are fine)
125
+ - the ST h5ad carries the integer `obs["segmentation_id"]` (each cell's mask label, `0` = no segmentation): non-negative, non-zero ids unique and present in the mask
126
+ - `uns["segmentation_pixel_size_um"]` (µm per pixel) is optional - a warning if missing
122
127
  - Per pair
123
128
  - the size of the shared-gene intersection
124
129
  - whether any ST spot is left all-zero by it.
@@ -135,6 +140,7 @@ spatialaim gui [--server_port 8501]
135
140
  Open the printed URL (default http://localhost:8501), set the inputs, pick one or multiple mapper(s), and click **Run**.
136
141
  As soon as both `.h5ad` paths are set, the GUI runs the same checks as [`spatialaim validate`](#validate-a-dataset-pair-spatialaim-validate) on that pair: a clean pair is confirmed with a tick in the sidebar, any error or warning is shown in a dialog you can close to continue anyway.
137
142
  The GUI writes each mapper's sweep to `<output_dir>/<mapper>/`. The results using each mapper are visualized in different tabs. When having run multiple mappers, also a "Compare" tab appears.
143
+ An optional **Segmentation path** (the ST slice's cell segmentation mask, see the sidebar's *Info*) is validated with the pair and passed to the runs; their mapper tabs then get a "Shape features" card (shape consistency and the cells' area / eccentricity / solidity per cell type), and the cell-type modal a "Shape features" view. Without it the GUI is unchanged.
138
144
 
139
145
  ### Run via CLI (`spatialaim run`)
140
146
 
@@ -161,6 +167,7 @@ Give such runs their own `--output_dir`: a run root is named after the mapper al
161
167
  spatialaim run --scdata path/to/sc.h5ad \
162
168
  --stdata path/to/st.h5ad \
163
169
  --output_dir path/to/out_dir \
170
+ [--segmentation path/to/mask.tif] \
164
171
  [--mapping nearest_centroid|wann|tangram|tacco|dot] \
165
172
  [--linkage_method average|ward] \
166
173
  [--start_from_annotation <obs_column>] \
@@ -169,7 +176,9 @@ spatialaim run --scdata path/to/sc.h5ad \
169
176
  [--logging verbose]
170
177
  ```
171
178
 
172
- **Batch mode (all pairs in `pairs.csv`):**
179
+ `--segmentation` is the ST slice's optional cell segmentation mask; with it the analysis also scores **shape consistency** (column `shape` of `k_comparison.csv`), without it that score is NaN.
180
+
181
+ **Batch mode (all pairs in `pairs.csv`):** each slice's mask is taken from the `Segmentation` column of `ST/index.csv` (file in `ST/Segmentation/`), if set.
173
182
 
174
183
  ```bash
175
184
  spatialaim run --pairs_csv path/to/pairs.csv \
@@ -188,19 +197,20 @@ Each pair is written to `<out_dir>/<PairID>_<scName>__<stName>/`.
188
197
 
189
198
  **Output layout** (per pair):
190
199
 
191
- - `<mapping>/config.yaml` — the run configuration.
192
- - `start_clustering.h5ad` — per-cell start cluster (`start_cluster` id + `start_cluster_name`); computed once, reused for every `K`.
193
- - `k_<kkk>/` — one folder per `K`:
194
- - `spot_to_state_mapping_soft.h5ad` — the spot→state matrix `P` (spots × `K`);
195
- carries `obs["mapping_confidence"]` when the mapper defines one.
196
- - `spot_to_state_mapping.csv` — `P` as CSV (for eyeballing).
197
- - `start_cluster_to_state.csv` — the start-cluster→state tree cut.
198
- - `analysis/data/` — machine-readable metrics for that `K` (no figures; the GUI renders them).
199
- - `k_comparison.csv` — one row per `K`: the measured metrics, plus each criterion's combined
200
- score (harmonic mean of its two curves), the overall score across criteria, and a
201
- `pareto` flag.
202
- - `k_selection.json` — the proposal: the Pareto-optimal `K`, and the best `K` per criterion
203
- and overall, each with its score. Same computation the GUI's "Choose K" card shows.
200
+ ```
201
+ <out_dir>/
202
+ ├── reference_scaffold.h5ad # cached reference preparation, shared by all mappers
203
+ └── <mapping>/ # one folder per mapper, e.g. nearest_centroid/
204
+ ├── config.yaml # the run's settings
205
+ ├── start_clustering.h5ad # each reference cell's start cluster
206
+ ├── cell_shape_features.csv # only with a segmentation mask: area, eccentricity, solidity per cell
207
+ ├── k_<kkk>/ # one folder per K
208
+ │ ├── spot_to_state_mapping_soft.h5ad # the mapping P (spots × K), plus confidence if the mapper has one
209
+ │ ├── start_cluster_to_state.csv # which state each start cluster belongs to
210
+ │ └── analysis/data/ # the metrics for this K (the GUI plots them)
211
+ ├── k_comparison.csv # one row per K: all metrics and the K-selection scores
212
+ └── k_selection.json # the suggested K, overall and per criterion
213
+ ```
204
214
 
205
215
  **Sample-dataset example:**
206
216
 
@@ -15,15 +15,19 @@ dependencies:
15
15
  - scipy==1.18.0
16
16
  - pyyaml==6.0.3
17
17
  - anndata==0.12.7
18
- - scanpy==1.11.5 # Leiden over-clustering, UMAP, analysis.biology
18
+ - scanpy==1.11.5 # Leiden over-clustering, UMAP, analysis.coherence
19
+ - tifffile # cell segmentation masks
20
+ - zarr # reading large masks in bands
21
+ - scikit-image # shape-consistency metric (regionprops); rasterising masks at curation
19
22
  # --- data preparation only ---
20
23
  - matplotlib==3.9.2
21
24
  - rdata # read R .Rds sources (curate_datasets/curate_05_mouse_embryo)
25
+ - h5py # read HDF5 sources (curate_datasets 01, 02, 09)
22
26
  - pip:
23
27
  # --- core (pip-only) ---
24
- - igraph # modularity (metrics.biology)
28
+ - igraph # modularity (metrics.modularity)
25
29
  - leidenalg # Leiden over-clustering
26
- - squidpy # spatial metrics (analysis.topology)
30
+ - squidpy # spatial metrics (analysis.spatial_organization)
27
31
  # --- GUI only ---
28
32
  - streamlit
29
33
  - plotly
@@ -44,6 +44,9 @@ dependencies = [
44
44
  "igraph>=0.11",
45
45
  "leidenalg>=0.10",
46
46
  "umap-learn>=0.5",
47
+ "tifffile>=2024.8", # cell segmentation masks
48
+ "zarr>=2.16", # reading large masks in bands
49
+ "scikit-image>=0.22", # shape-consistency metric (regionprops), rasterising masks
47
50
  # GUI
48
51
  "streamlit>=1.40",
49
52
  "plotly>=5.20",
@@ -51,7 +54,7 @@ dependencies = [
51
54
  ]
52
55
 
53
56
  [project.optional-dependencies]
54
- data = ["matplotlib>=3.9", "scikit-learn>=1.4", "rdata>=1.1"]
57
+ data = ["matplotlib>=3.9", "scikit-learn>=1.4", "rdata>=1.1", "h5py>=3.10"]
55
58
  dev = [
56
59
  "pytest>=8",
57
60
  "black>=24",
@@ -78,7 +81,6 @@ where = ["src"]
78
81
  # curate_06_mouse_retina reads an R .qs object, so it ships an R script and the
79
82
  # env spec for the small R environment that runs it.
80
83
  "spatialaim.data.curate_datasets" = ["*.yml", "*.R"]
81
-
82
84
  [tool.setuptools_scm]
83
85
  # Version is derived from git tags (e.g. v0.1.0). Falls back to 0.0.0.dev* in a
84
86
  # source tree without tags.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatial-aim
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: SpatialAIM — annotation-independent mapping of scRNA-seq references onto high-resolution spatial transcriptomics
5
5
  Author-email: Dominik Pysch <dominik.pysch@fau.de>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -702,6 +702,9 @@ Requires-Dist: squidpy>=1.4
702
702
  Requires-Dist: igraph>=0.11
703
703
  Requires-Dist: leidenalg>=0.10
704
704
  Requires-Dist: umap-learn>=0.5
705
+ Requires-Dist: tifffile>=2024.8
706
+ Requires-Dist: zarr>=2.16
707
+ Requires-Dist: scikit-image>=0.22
705
708
  Requires-Dist: streamlit>=1.40
706
709
  Requires-Dist: plotly>=5.20
707
710
  Requires-Dist: kaleido>=0.2
@@ -709,6 +712,7 @@ Provides-Extra: data
709
712
  Requires-Dist: matplotlib>=3.9; extra == "data"
710
713
  Requires-Dist: scikit-learn>=1.4; extra == "data"
711
714
  Requires-Dist: rdata>=1.1; extra == "data"
715
+ Requires-Dist: h5py>=3.10; extra == "data"
712
716
  Provides-Extra: dev
713
717
  Requires-Dist: pytest>=8; extra == "dev"
714
718
  Requires-Dist: black>=24; extra == "dev"
@@ -785,7 +789,8 @@ DATA/
785
789
  │ └── <scName>.h5ad
786
790
  ├── ST/
787
791
  │ ├── index.csv # one row per ST dataset
788
- │ └── <stName>.h5ad
792
+ │ ├── <stName>.h5ad
793
+ │ └── Segmentation/ # optional cell segmentation masks (index.csv column `Segmentation`)
789
794
  └── pairs.csv # links scRNA ↔ ST: PairID, scName, stName, …
790
795
  ```
791
796
 
@@ -822,7 +827,7 @@ Please install the corresponding conda environments on your computer.
822
827
  Check whether your data meets the main requirements.
823
828
 
824
829
  ```bash
825
- spatialaim validate --scdata path/to/sc.h5ad --stdata path/to/st.h5ad
830
+ spatialaim validate --scdata path/to/sc.h5ad --stdata path/to/st.h5ad [--segmentation path/to/mask.tif]
826
831
  ```
827
832
 
828
833
  or for every pair of a `pairs.csv` laid out as in [Batch Processing](#batch-processing):
@@ -840,6 +845,10 @@ Validations per dataset:
840
845
  - raw count matrices (no NaN values, np negative values, integer-looking, not library-size normalized or log1p'd)
841
846
  - unique uppercase gene names
842
847
  - `obsm["spatial"]` of shape `(n_spots, 2)`.
848
+ - Optional cell segmentation mask of an ST slice
849
+ - a 2D `.tif`/`.tiff` of dtype `uint32`: `0` = background, cells labelled `1..max` without gaps (labels without a cell in the h5ad are fine)
850
+ - the ST h5ad carries the integer `obs["segmentation_id"]` (each cell's mask label, `0` = no segmentation): non-negative, non-zero ids unique and present in the mask
851
+ - `uns["segmentation_pixel_size_um"]` (µm per pixel) is optional - a warning if missing
843
852
  - Per pair
844
853
  - the size of the shared-gene intersection
845
854
  - whether any ST spot is left all-zero by it.
@@ -856,6 +865,7 @@ spatialaim gui [--server_port 8501]
856
865
  Open the printed URL (default http://localhost:8501), set the inputs, pick one or multiple mapper(s), and click **Run**.
857
866
  As soon as both `.h5ad` paths are set, the GUI runs the same checks as [`spatialaim validate`](#validate-a-dataset-pair-spatialaim-validate) on that pair: a clean pair is confirmed with a tick in the sidebar, any error or warning is shown in a dialog you can close to continue anyway.
858
867
  The GUI writes each mapper's sweep to `<output_dir>/<mapper>/`. The results using each mapper are visualized in different tabs. When having run multiple mappers, also a "Compare" tab appears.
868
+ An optional **Segmentation path** (the ST slice's cell segmentation mask, see the sidebar's *Info*) is validated with the pair and passed to the runs; their mapper tabs then get a "Shape features" card (shape consistency and the cells' area / eccentricity / solidity per cell type), and the cell-type modal a "Shape features" view. Without it the GUI is unchanged.
859
869
 
860
870
  ### Run via CLI (`spatialaim run`)
861
871
 
@@ -882,6 +892,7 @@ Give such runs their own `--output_dir`: a run root is named after the mapper al
882
892
  spatialaim run --scdata path/to/sc.h5ad \
883
893
  --stdata path/to/st.h5ad \
884
894
  --output_dir path/to/out_dir \
895
+ [--segmentation path/to/mask.tif] \
885
896
  [--mapping nearest_centroid|wann|tangram|tacco|dot] \
886
897
  [--linkage_method average|ward] \
887
898
  [--start_from_annotation <obs_column>] \
@@ -890,7 +901,9 @@ spatialaim run --scdata path/to/sc.h5ad \
890
901
  [--logging verbose]
891
902
  ```
892
903
 
893
- **Batch mode (all pairs in `pairs.csv`):**
904
+ `--segmentation` is the ST slice's optional cell segmentation mask; with it the analysis also scores **shape consistency** (column `shape` of `k_comparison.csv`), without it that score is NaN.
905
+
906
+ **Batch mode (all pairs in `pairs.csv`):** each slice's mask is taken from the `Segmentation` column of `ST/index.csv` (file in `ST/Segmentation/`), if set.
894
907
 
895
908
  ```bash
896
909
  spatialaim run --pairs_csv path/to/pairs.csv \
@@ -909,19 +922,20 @@ Each pair is written to `<out_dir>/<PairID>_<scName>__<stName>/`.
909
922
 
910
923
  **Output layout** (per pair):
911
924
 
912
- - `<mapping>/config.yaml` — the run configuration.
913
- - `start_clustering.h5ad` — per-cell start cluster (`start_cluster` id + `start_cluster_name`); computed once, reused for every `K`.
914
- - `k_<kkk>/` — one folder per `K`:
915
- - `spot_to_state_mapping_soft.h5ad` — the spot→state matrix `P` (spots × `K`);
916
- carries `obs["mapping_confidence"]` when the mapper defines one.
917
- - `spot_to_state_mapping.csv` — `P` as CSV (for eyeballing).
918
- - `start_cluster_to_state.csv` — the start-cluster→state tree cut.
919
- - `analysis/data/` — machine-readable metrics for that `K` (no figures; the GUI renders them).
920
- - `k_comparison.csv` — one row per `K`: the measured metrics, plus each criterion's combined
921
- score (harmonic mean of its two curves), the overall score across criteria, and a
922
- `pareto` flag.
923
- - `k_selection.json` — the proposal: the Pareto-optimal `K`, and the best `K` per criterion
924
- and overall, each with its score. Same computation the GUI's "Choose K" card shows.
925
+ ```
926
+ <out_dir>/
927
+ ├── reference_scaffold.h5ad # cached reference preparation, shared by all mappers
928
+ └── <mapping>/ # one folder per mapper, e.g. nearest_centroid/
929
+ ├── config.yaml # the run's settings
930
+ ├── start_clustering.h5ad # each reference cell's start cluster
931
+ ├── cell_shape_features.csv # only with a segmentation mask: area, eccentricity, solidity per cell
932
+ ├── k_<kkk>/ # one folder per K
933
+ │ ├── spot_to_state_mapping_soft.h5ad # the mapping P (spots × K), plus confidence if the mapper has one
934
+ │ ├── start_cluster_to_state.csv # which state each start cluster belongs to
935
+ │ └── analysis/data/ # the metrics for this K (the GUI plots them)
936
+ ├── k_comparison.csv # one row per K: all metrics and the K-selection scores
937
+ └── k_selection.json # the suggested K, overall and per criterion
938
+ ```
925
939
 
926
940
  **Sample-dataset example:**
927
941
 
@@ -32,20 +32,25 @@ src/spatialaim/config.py
32
32
  src/spatialaim/io.py
33
33
  src/spatialaim/sweep.py
34
34
  src/spatialaim/tree.py
35
+ src/spatialaim/utils.py
35
36
  src/spatialaim/analysis/__init__.py
36
- src/spatialaim/analysis/analysis.py
37
- src/spatialaim/analysis/biology.py
38
- src/spatialaim/analysis/confidence.py
39
- src/spatialaim/analysis/ksweep.py
37
+ src/spatialaim/analysis/coherence.py
40
38
  src/spatialaim/analysis/loading.py
41
- src/spatialaim/analysis/onehot.py
42
39
  src/spatialaim/analysis/reconstruction.py
43
- src/spatialaim/analysis/topology.py
44
- src/spatialaim/analysis/utils.py
40
+ src/spatialaim/analysis/run.py
41
+ src/spatialaim/analysis/shape_consistency.py
42
+ src/spatialaim/analysis/spatial_organization.py
43
+ src/spatialaim/analysis/compare_ks/__init__.py
44
+ src/spatialaim/analysis/compare_ks/collect.py
45
+ src/spatialaim/analysis/compare_ks/criteria.py
46
+ src/spatialaim/analysis/compare_ks/run.py
47
+ src/spatialaim/analysis/compare_ks/scoring.py
48
+ src/spatialaim/analysis/compare_ks/selection.py
45
49
  src/spatialaim/data/__init__.py
46
50
  src/spatialaim/data/curate_datasets/README.md
47
51
  src/spatialaim/data/curate_datasets/__init__.py
48
52
  src/spatialaim/data/curate_datasets/_common.py
53
+ src/spatialaim/data/curate_datasets/_segmentation.py
49
54
  src/spatialaim/data/curate_datasets/curate_01_mouse_ssp.py
50
55
  src/spatialaim/data/curate_datasets/curate_02_colorectal_cancer.py
51
56
  src/spatialaim/data/curate_datasets/curate_03_mouse_liver.py
@@ -63,16 +68,42 @@ src/spatialaim/data/validate/common.py
63
68
  src/spatialaim/data/validate/runner.py
64
69
  src/spatialaim/data/validate/validate_pair.py
65
70
  src/spatialaim/data/validate/validate_sc.py
71
+ src/spatialaim/data/validate/validate_segmentation.py
66
72
  src/spatialaim/data/validate/validate_st.py
67
73
  src/spatialaim/gui/__init__.py
68
74
  src/spatialaim/gui/__main__.py
69
75
  src/spatialaim/gui/app.py
70
76
  src/spatialaim/gui/compute.py
71
77
  src/spatialaim/gui/data_access.py
72
- src/spatialaim/gui/render.py
78
+ src/spatialaim/gui/loaders.py
73
79
  src/spatialaim/gui/scaffold.py
80
+ src/spatialaim/gui/sidebar.py
74
81
  src/spatialaim/gui/state_names.py
75
- src/spatialaim/gui/widgets.py
82
+ src/spatialaim/gui/texts.py
83
+ src/spatialaim/gui/validation.py
84
+ src/spatialaim/gui/render/__init__.py
85
+ src/spatialaim/gui/render/cell_type.py
86
+ src/spatialaim/gui/render/common.py
87
+ src/spatialaim/gui/render/headline.py
88
+ src/spatialaim/gui/render/ksweep.py
89
+ src/spatialaim/gui/render/markers.py
90
+ src/spatialaim/gui/render/report.py
91
+ src/spatialaim/gui/render/scatter.py
92
+ src/spatialaim/gui/render/shape.py
93
+ src/spatialaim/gui/views/__init__.py
94
+ src/spatialaim/gui/views/cards.py
95
+ src/spatialaim/gui/views/cell_type_modal.py
96
+ src/spatialaim/gui/views/choose_k.py
97
+ src/spatialaim/gui/views/compare_tab.py
98
+ src/spatialaim/gui/views/controls.py
99
+ src/spatialaim/gui/views/mapper_tab.py
100
+ src/spatialaim/gui/views/reference_tab.py
101
+ src/spatialaim/gui/views/report.py
102
+ src/spatialaim/gui/widgets/__init__.py
103
+ src/spatialaim/gui/widgets/headline_plot.py
104
+ src/spatialaim/gui/widgets/linked_plot.py
105
+ src/spatialaim/gui/widgets/plotly_fit.py
106
+ src/spatialaim/gui/widgets/slider.py
76
107
  src/spatialaim/mapping/__init__.py
77
108
  src/spatialaim/mapping/base.py
78
109
  src/spatialaim/mapping/confidence.py
@@ -80,11 +111,9 @@ src/spatialaim/mapping/nearest_centroid.py
80
111
  src/spatialaim/mapping/reference.py
81
112
  src/spatialaim/mapping/wann.py
82
113
  src/spatialaim/metrics/__init__.py
83
- src/spatialaim/metrics/biology.py
84
114
  src/spatialaim/metrics/cossim.py
85
- src/spatialaim/metrics/kselection.py
86
- src/spatialaim/metrics/onehot.py
87
- src/spatialaim/metrics/reconstruction.py
115
+ src/spatialaim/metrics/modularity.py
116
+ src/spatialaim/metrics/shape_consistency.py
88
117
  src/spatialaim/metrics/topology.py
89
118
  src/spatialaim/reference_aligners/__init__.py
90
119
  src/spatialaim/reference_aligners/environment_dot.yml
@@ -8,6 +8,9 @@ squidpy>=1.4
8
8
  igraph>=0.11
9
9
  leidenalg>=0.10
10
10
  umap-learn>=0.5
11
+ tifffile>=2024.8
12
+ zarr>=2.16
13
+ scikit-image>=0.22
11
14
  streamlit>=1.40
12
15
  plotly>=5.20
13
16
  kaleido>=0.2
@@ -16,6 +19,7 @@ kaleido>=0.2
16
19
  matplotlib>=3.9
17
20
  scikit-learn>=1.4
18
21
  rdata>=1.1
22
+ h5py>=3.10
19
23
 
20
24
  [dev]
21
25
  pytest>=8
@@ -21,15 +21,18 @@
21
21
  "src/spatialaim/adata_schema.py",
22
22
  "src/spatialaim/aggregation.py",
23
23
  "src/spatialaim/analysis/__init__.py",
24
- "src/spatialaim/analysis/analysis.py",
25
- "src/spatialaim/analysis/biology.py",
26
- "src/spatialaim/analysis/confidence.py",
27
- "src/spatialaim/analysis/ksweep.py",
24
+ "src/spatialaim/analysis/coherence.py",
25
+ "src/spatialaim/analysis/compare_ks/__init__.py",
26
+ "src/spatialaim/analysis/compare_ks/collect.py",
27
+ "src/spatialaim/analysis/compare_ks/criteria.py",
28
+ "src/spatialaim/analysis/compare_ks/run.py",
29
+ "src/spatialaim/analysis/compare_ks/scoring.py",
30
+ "src/spatialaim/analysis/compare_ks/selection.py",
28
31
  "src/spatialaim/analysis/loading.py",
29
- "src/spatialaim/analysis/onehot.py",
30
32
  "src/spatialaim/analysis/reconstruction.py",
31
- "src/spatialaim/analysis/topology.py",
32
- "src/spatialaim/analysis/utils.py",
33
+ "src/spatialaim/analysis/run.py",
34
+ "src/spatialaim/analysis/shape_consistency.py",
35
+ "src/spatialaim/analysis/spatial_organization.py",
33
36
  "src/spatialaim/cli.py",
34
37
  "src/spatialaim/clustering.py",
35
38
  "src/spatialaim/config.py",
@@ -37,6 +40,7 @@
37
40
  "src/spatialaim/data/curate_datasets/README.md",
38
41
  "src/spatialaim/data/curate_datasets/__init__.py",
39
42
  "src/spatialaim/data/curate_datasets/_common.py",
43
+ "src/spatialaim/data/curate_datasets/_segmentation.py",
40
44
  "src/spatialaim/data/curate_datasets/curate_01_mouse_ssp.py",
41
45
  "src/spatialaim/data/curate_datasets/curate_02_colorectal_cancer.py",
42
46
  "src/spatialaim/data/curate_datasets/curate_03_mouse_liver.py",
@@ -54,16 +58,42 @@
54
58
  "src/spatialaim/data/validate/runner.py",
55
59
  "src/spatialaim/data/validate/validate_pair.py",
56
60
  "src/spatialaim/data/validate/validate_sc.py",
61
+ "src/spatialaim/data/validate/validate_segmentation.py",
57
62
  "src/spatialaim/data/validate/validate_st.py",
58
63
  "src/spatialaim/gui/__init__.py",
59
64
  "src/spatialaim/gui/__main__.py",
60
65
  "src/spatialaim/gui/app.py",
61
66
  "src/spatialaim/gui/compute.py",
62
67
  "src/spatialaim/gui/data_access.py",
63
- "src/spatialaim/gui/render.py",
68
+ "src/spatialaim/gui/loaders.py",
69
+ "src/spatialaim/gui/render/__init__.py",
70
+ "src/spatialaim/gui/render/cell_type.py",
71
+ "src/spatialaim/gui/render/common.py",
72
+ "src/spatialaim/gui/render/headline.py",
73
+ "src/spatialaim/gui/render/ksweep.py",
74
+ "src/spatialaim/gui/render/markers.py",
75
+ "src/spatialaim/gui/render/report.py",
76
+ "src/spatialaim/gui/render/scatter.py",
77
+ "src/spatialaim/gui/render/shape.py",
64
78
  "src/spatialaim/gui/scaffold.py",
79
+ "src/spatialaim/gui/sidebar.py",
65
80
  "src/spatialaim/gui/state_names.py",
66
- "src/spatialaim/gui/widgets.py",
81
+ "src/spatialaim/gui/texts.py",
82
+ "src/spatialaim/gui/validation.py",
83
+ "src/spatialaim/gui/views/__init__.py",
84
+ "src/spatialaim/gui/views/cards.py",
85
+ "src/spatialaim/gui/views/cell_type_modal.py",
86
+ "src/spatialaim/gui/views/choose_k.py",
87
+ "src/spatialaim/gui/views/compare_tab.py",
88
+ "src/spatialaim/gui/views/controls.py",
89
+ "src/spatialaim/gui/views/mapper_tab.py",
90
+ "src/spatialaim/gui/views/reference_tab.py",
91
+ "src/spatialaim/gui/views/report.py",
92
+ "src/spatialaim/gui/widgets/__init__.py",
93
+ "src/spatialaim/gui/widgets/headline_plot.py",
94
+ "src/spatialaim/gui/widgets/linked_plot.py",
95
+ "src/spatialaim/gui/widgets/plotly_fit.py",
96
+ "src/spatialaim/gui/widgets/slider.py",
67
97
  "src/spatialaim/io.py",
68
98
  "src/spatialaim/mapping/__init__.py",
69
99
  "src/spatialaim/mapping/base.py",
@@ -72,11 +102,9 @@
72
102
  "src/spatialaim/mapping/reference.py",
73
103
  "src/spatialaim/mapping/wann.py",
74
104
  "src/spatialaim/metrics/__init__.py",
75
- "src/spatialaim/metrics/biology.py",
76
105
  "src/spatialaim/metrics/cossim.py",
77
- "src/spatialaim/metrics/kselection.py",
78
- "src/spatialaim/metrics/onehot.py",
79
- "src/spatialaim/metrics/reconstruction.py",
106
+ "src/spatialaim/metrics/modularity.py",
107
+ "src/spatialaim/metrics/shape_consistency.py",
80
108
  "src/spatialaim/metrics/topology.py",
81
109
  "src/spatialaim/reference_aligners/__init__.py",
82
110
  "src/spatialaim/reference_aligners/environment_dot.yml",
@@ -89,6 +117,7 @@
89
117
  "src/spatialaim/reference_aligners/run_tangram.py",
90
118
  "src/spatialaim/sweep.py",
91
119
  "src/spatialaim/tree.py",
120
+ "src/spatialaim/utils.py",
92
121
  "tests/test_cli.py",
93
122
  "tests/test_gui_imports.py",
94
123
  "tests/test_registry.py",
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.3.0",
3
+ "distance": 0,
4
+ "node": "g3ff1552b03833c77cdbaada6b0efd4e446c91b6a",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-14"
8
+ }
@@ -1,5 +1,7 @@
1
- """SpatialAIM (Annotation Independent Mapping): over-cluster an scRNA reference, agglomerate
2
- the subclusters into K states, and map ST spots onto those states across a K sweep.
1
+ """
2
+ SpatialAIM (Annotation Independent Mapping): split an scRNA reference into start
3
+ clusters, agglomerate them into K states, and map ST spots onto those states across a
4
+ K sweep.
3
5
  Public surface: ``SpatialAIMConfig``, ``MAPPING_CHOICES``, ``run``, ``SpotStateMapper``.
4
6
 
5
7
  These names are exposed lazily (PEP 562) so that importing ``spatialaim``, or a
@@ -0,0 +1,8 @@
1
+ """
2
+ Enable ``python -m spatialaim ...`` as an alias for the ``spatialaim`` console script.
3
+ """
4
+
5
+ from spatialaim.cli import main
6
+
7
+ if __name__ == "__main__":
8
+ raise SystemExit(main())