Metadata-Version: 2.4
Name: sphot
Version: 0.1.0
Summary: Phenotype-associated spatial biomarker discovery in spatial transcriptomics with spHOT
Author: Hoeyoung Kim, Donghee Kim
License: MIT License
        
        Copyright (c) 2026 Hoeyoung Kim and Donghee Kim
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/DHKim327/spHOT
Project-URL: Repository, https://github.com/DHKim327/spHOT
Keywords: spatial transcriptomics,multiple instance learning,spatial biomarker,bioinformatics
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23
Requires-Dist: pandas>=1.5
Requires-Dist: scipy>=1.10
Requires-Dist: scikit-learn>=1.2
Requires-Dist: scanpy>=1.9
Requires-Dist: anndata>=0.9
Requires-Dist: torch>=2.0
Requires-Dist: novae>=1.0.0
Requires-Dist: networkx>=3.0
Requires-Dist: matplotlib>=3.6
Requires-Dist: seaborn>=0.12
Requires-Dist: termcolor>=2.0
Requires-Dist: pynvml>=11.0
Dynamic: license-file

# spHOT
### Phenotype-associated spatial biomarker discovery in spatial transcriptomics with spHOT
[![License: MIT](https://img.shields.io/badge/license-MIT-pink.svg)](https://github.com/DHKim327/spHOT/blob/main/LICENSE)
[![Python](https://img.shields.io/badge/python-3.10-pink.svg)](https://www.python.org/)


## 🧬 Description
**🔥spHOT🔥** is a framework for localizing phenotype-associated spatial biomarkers from multi-sample, multi-patient spatial transcriptomics datasets with sample-level case/control labels. spHOT integrates **spatial foundation model embeddings**, a **hierarchical domain tree**, and a dual-branch **teacher–student multiple instance learning architecture** to convert sample-level phenotype labels into spatially coherent cell-level biomarker scores.

<img src="https://raw.githubusercontent.com/DHKim327/spHOT/main/docs/spHOT_Figure1_V3.png" width="1000px" align="center" />


## ⚙️ Installation

**Option 1 — PyPI**
```bash
pip install sphot
```

**Option 2 — GitHub**
```bash
pip install git+https://github.com/DHKim327/spHOT.git
```

**Option 3 — conda yml**
```bash
git clone https://github.com/DHKim327/spHOT.git
cd spHOT
conda env create -f environment/env_spHOT.yml
conda activate env_spHOT
pip install -e .
```

## 📥 Inputs

**AnnData directory :**
<br>Path to `.h5ad` files, saved per sample :
```
adatas/
├── sample1/adata.h5ad
└── sample2/adata.h5ad
```
- `.obs` key should contain sample phenotype label

**Split information :**

The `splits.csv` file defines train/valid/test splits for each sample across multiple folds.

| SID         | 0     | 1     | 2     | 3     | 4     |
|--------------|-------|-------|-------|-------|-------|
| sample_1     | train | train | train | test  | valid |
| sample_2     | train | test  | valid | train | train |
| sample_3     | valid | train | train | train | test  |

- **SID :** Sample identifier (e.g., slide or tissue ID)  
- **0–4 :** Fold indices  
- Each cell indicates the dataset role of that sample for a specific fold.


## 📤 Outputs

After an spHOT run, the output directory structure will be organized as below :
```
results/
└── {task_name}/                          # Name of run
    ├── de/                               # Domain embedding module result
    │   └── adata.h5ad                    # Merged AnnData with Novae embeddings & initial domain info           
    ├── dt/                               # Domain tree module result
    |   ├── centroid_HC_results.pkl       # Hierarchical domain tree
    |   └── adata.h5ad                    # Merged AnnData with metadomains association info
    └── mil/                              # MIL module result
        ├── D{k}/                         # k-level MIL result
        │   ├── model_encoder_exp{exp}.pt     # Model and outputs for each fold
        │   ├── model_teacher_exp{exp}.pt             
        │   ├── model_student_exp{exp}.pt            
        │   ├── resource_{exp}.csv            # Resource performance log
        │   └── CELL_SCORE_test_{exp}.h5ad    # spHOT cell scores (test) for each fold
        ├── all_test_results.csv          # Sample classification performance of test samples
        ├── all_test_results.csv          # Sample classification performance of validation samples
        └── k_selection_results.csv       # Spatial scores and k-selection result of spHOT run
```

## 📘 Tutorials

We provide the code and resources required to reproduce all main figures in the manuscript within the `./tutorial` directory. Also, see the `./tutorial` directory for step-by-step spHOT usage.

### Figure-to-notebook map

| Figure | Dataset | Step | Notebook |
|---|---|---|---|
| **Fig. 2+@** | Simulation | Source data preparation | [`0.preproc_CosMx_Pouch_IBD.ipynb`](./tutorial/Fig2_Simulation/0.preproc_CosMx_Pouch_IBD.ipynb) |
| | | Simulation generation (V1) | [`1.simul_scCube_V1.ipynb`](./tutorial/Fig2_Simulation/1.simul_scCube_V1.ipynb) |
| | | Simulation generation (V2) | [`1.simul_scCube_V2.ipynb`](./tutorial/Fig2_Simulation/1.simul_scCube_V2.ipynb) |
| | | spHOT run (V1) | [`2.spHOT_simul_V1.ipynb`](./tutorial/Fig2_Simulation/2.spHOT_simul_V1.ipynb) |
| | | spHOT run (V2) | [`2.spHOT_simul_V2.ipynb`](./tutorial/Fig2_Simulation/2.spHOT_simul_V2.ipynb) |
| | | Evaluation (V1) | [`3.eval_simul_V1.ipynb`](./tutorial/Fig2_Simulation/3.eval_simul_V1.ipynb) |
| | | Evaluation (V2) | [`3.eval_simul_V2.ipynb`](./tutorial/Fig2_Simulation/3.eval_simul_V2.ipynb) |
| **Fig. 3–4** | Xenium IPF (GSE250346) | Preprocessing | [`0.preproc_Xenium_IPF.R`](./tutorial/Fig3_4_Xenium_IPF/0.preproc_Xenium_IPF.R) · [`0.preproc_Xenium_IPF.ipynb`](./tutorial/Fig3_4_Xenium_IPF/0.preproc_Xenium_IPF.ipynb) |
| | | spHOT run | [`1.spHOT_Xenium_IPF.ipynb`](./tutorial/Fig3_4_Xenium_IPF/1.spHOT_Xenium_IPF.ipynb) |
| | | Evaluation | [`2.eval_Xenium_IPF.ipynb`](./tutorial/Fig3_4_Xenium_IPF/2.eval_Xenium_IPF.ipynb) |
| | | Downstream analysis | [`3.downstream_Xenium_IPF.ipynb`](./tutorial/Fig3_4_Xenium_IPF/3.downstream_Xenium_IPF.ipynb) |
| **Fig. 5** | CosMx DKD | Preprocessing | [`0.preproc_CosMx_DKD.ipynb`](./tutorial/Fig5_CosMx_DKD/0.preproc_CosMx_DKD.ipynb) |
| | | spHOT run | [`1.spHOT_CosMx_DKD.ipynb`](./tutorial/Fig5_CosMx_DKD/1.spHOT_CosMx_DKD.ipynb) |
| | | Evaluation | [`2.eval_CosMx_DKD.ipynb`](./tutorial/Fig5_CosMx_DKD/2.eval_CosMx_DKD.ipynb) |
| | | Downstream analysis | [`3.downstream_CosMx_DKD.ipynb`](./tutorial/Fig5_CosMx_DKD/3.downstream_CosMx_DKD.ipynb) |
| **Fig. 6** | Xenium RPGN (GSE294965) | Preprocessing | [`0.preproc_Xenium_RPGN.ipynb`](./tutorial/Fig6_Xenium_RPGN/0.preproc_Xenium_RPGN.ipynb) |
| | | spHOT run | [`1.spHOT_Xenium_RPGN.ipynb`](./tutorial/Fig6_Xenium_RPGN/1.spHOT_Xenium_RPGN.ipynb) |
| | | Downstream analysis (1) | [`2.downstream_Xenium_RPGN_V1.ipynb`](./tutorial/Fig6_Xenium_RPGN/2.downstream_Xenium_RPGN_V1.ipynb) |
| | | Downstream analysis (2) | [`2.downstream_Xenium_RPGN_V2.ipynb`](./tutorial/Fig6_Xenium_RPGN/2.downstream_Xenium_RPGN_V2.ipynb) |
| **Fig. 7** | Xenium COPD (GSE313006) | Preprocessing & cell typing | [`0.preproc_Xenium_COPD.ipynb`](./tutorial/Fig7_Xenium_COPD/0.preproc_Xenium_COPD.ipynb) |
| | | Downstream analysis (1) | [`1.downstream_Xenium_COPD_V1.ipynb`](./tutorial/Fig7_Xenium_COPD/1.downstream_Xenium_COPD_V1.ipynb) |
| | | Downstream analysis (2) | [`1.downstream_Xenium_COPD_V2.ipynb`](./tutorial/Fig7_Xenium_COPD/1.downstream_Xenium_COPD_V2.ipynb) |
| **Fig. 2, 3, 5+@** | All datasets | Cross-dataset benchmarking & statistics | [`benchmark_stats_all_datasets.ipynb`](./tutorial/benchmark_stats_all_datasets.ipynb) |

> **Note :** Notebooks are numbered by execution order within each figure directory (`0.` → `3.`). Preprocessing notebooks start from public GEO accessions; the simulation dataset is downloaded from Zenodo as the version of record (see [Data availability](https://doi.org/10.5281/zenodo.21156231)).

## 😊 Acknowledgements
spHOT is built upon codes from [scMILD: Single-cell multiple instance learning for sample classification and associated subpopulation discovery](https://github.com/Khreat0205/scMILD). We thank the authors for publicly releasing their codes.


## 📚 References
Jeong, K., Choi, J. & Kim, K. scMILD: Single-cell multiple instance learning for sample classification and associated subpopulation discovery. iScience 29(2026).


<br><br>
