Metadata-Version: 2.4
Name: sparank
Version: 0.1.6
Summary: Transferable spatial omics deconvolution
Author-email: Yoshua <3200376951@qq.com>
License: MIT
Project-URL: Homepage, https://github.com/XiHuYan/SpaRank
Project-URL: Documentation, https://sparank.readthedocs.io
Project-URL: Repository, https://github.com/XiHuYan/SpaRank
Project-URL: Issues, https://github.com/XiHuYan/SpaRank/issues
Keywords: spatial transcriptomics,deconvolution,single-cell,transformer,multimodal
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.25.2
Requires-Dist: pandas>=2.3.3
Requires-Dist: scipy>=1.11.3
Requires-Dist: scanpy>=1.9.5
Requires-Dist: anndata>=0.9.2
Requires-Dist: numba>=0.60.0
Requires-Dist: muon>=0.1.5
Requires-Dist: tqdm
Provides-Extra: docs
Requires-Dist: sphinx>=7.0; extra == "docs"
Requires-Dist: sphinx-rtd-theme; extra == "docs"
Requires-Dist: myst-parser; extra == "docs"
Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
Requires-Dist: sphinx-copybutton; extra == "docs"
Requires-Dist: nbsphinx; extra == "docs"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# SpaRank

**Transferable spatial omics deconvolution.**

SpaRank turns expression profiles into rank-ordered token sequences and runs them through a Transformer encoder to predict cell-type composition at each spatial spot. Trained once on a multi-context single-cell reference, a single model deploys directly to spatial sections spanning contexts without per-slice retraining. The same pipeline handles unimodal (RNA), multimodal (RNA + ADT, …), and context-conditioned setups.

<p align="center">
  <a href="https://pypi.org/project/sparank/"><img src="https://img.shields.io/pypi/v/sparank.svg" alt="PyPI"></a>
  <a href="https://sparank.readthedocs.io"><img src="https://img.shields.io/readthedocs/sparank" alt="Docs"></a>
  <a href="https://github.com/XiHuYan/sparank/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
</p>

## Installation

Requires Python >= 3.10

### Install torch
```bash
# Install PyTorch matching your CUDA driver.
# Example
pip install torch==2.9.1+cu128 --index-url https://download.pytorch.org/whl/cu128
```

### From PyPI
```bash
pip install sparank
```

### From source

```bash
git clone https://github.com/XiHuYan/SpaRank.git
cd SpaRank
pip install -e .
```

## Quick start

### Unimodal RNA

```python
from sparank import SpaRank, ExpConfig, ModalityConfig, SimulationConfig

cfg = ExpConfig(
    modalities=[ModalityConfig(name="rna", top_k=500)],
    simulation=SimulationConfig(       # controls pseudo-spot generation for training
        total_samples=100_000,
        cells_mean=10,                 # expected cells per spot — match your section resolution
        cells_std=5,
        cell_sample_method="gaussian",
        batch_key="Tissue",            # group cells by Tissue; simulate pseudo-spots within each, then pool (can differ from context_key)
    ),
    celltype_key="cell_type",
    batch_key="batch",                # group cells by batch; detect marker genes within each group
    context_key="Tissue",             # label cells by Tissue; embed the label into the prediction head
    epochs=20,
)

sr = SpaRank(cfg, save_dir="./output")
sr.register_modality("rna", adata_sc_rna)
sr.prepare()                           
# or pass markers directly:
# sr.prepare(marker_features={"rna": prior_gene_list})
sr.fit()
sr.save()

# Deploy to a spatial section — no retraining needed
df = sr.predict({"rna": adata_sp_rna})
```

### Multimodal RNA + ADT

```python
cfg = ExpConfig(
    modalities=[
        ModalityConfig(name="rna", top_k=500),
        ModalityConfig(name="adt", top_k=200),
    ],
    simulation=SimulationConfig(       # controls pseudo-spot generation for training
        total_samples=100_000,
        cells_mean=10,                 # expected cells per spot — match your section resolution
        cells_std=5,
        cell_sample_method="gaussian",
        batch_key="Tissue",            # group cells by Tissue; simulate pseudo-spots within each, then pool (can differ from context_key)
    ),
    celltype_key="cell_type",
    batch_key="batch",           
    context_key="Tissue",          
    fusion_type="sigmoid_gate",    # "concat" | "gate" | "joint_gate" | "sigmoid_gate" | "attention"
    epochs=20,
)

sr = SpaRank(cfg, save_dir="./output")
sr.register_modality("rna", adata_sc_rna)
sr.register_modality("adt", adata_sc_adt)
sr.prepare()
sr.fit()

# Predict proportions
proportions_df = sr.predict(
    {"rna": adata_sp_rna, "adt": adata_sp_adt},
)
```


