Skip to main content

Topological analysis of single-cell data: per-cluster persistent homology and periodicity-based topogene discovery.

Project description

sctopo

Topological analysis of single-cell data. sctopo extracts statistically significant 1-dimensional homological features (loops) in single-cell embeddings, scores genes by how strongly their expression is locked to each loop, and visualizes both geometry and gene-expression structure in three complementary 3-D views per cycle.

License: BSD-3-Clause Python: 3.9+


What it does

Given a single-cell embedding (typically PCA or Concord) and Leiden cluster labels, sctopo runs the following pipeline per cluster:

  1. Per-cluster persistent homology. Compute Vietoris–Rips persistent homology on the cluster's embedding (Ripser).

  2. Significance filtering. Keep only H1 classes whose persistence exceeds the (1 − α) quantile of a column-permutation null distribution, and whose birth radius is below a quantile of nearest-neighbor distances.

  3. Critical-edge cycle recovery. For each surviving class, extract a representative cycle via shortest-path on the 1-skeleton.

  4. Circular coordinates. Assign a continuous angle θ ∈ [0, 2π) to every topocell (cells in a neighborhood of the cycle) using DREiMac.

  5. Topogene discovery. Rank genes by the amplitude of their circular correlation with θ:

    $$r_{\text{circ}}(g) = \sqrt{\,\operatorname{corr}(x_g, \cos\theta)^2 + \operatorname{corr}(x_g, \sin\theta)^2\,}$$

    This is the first Fourier-mode amplitude along the cycle. A permutation test gives per-gene p-values and a family-wise significance threshold.

  6. Visualization. Three 3-D views per loop (cluster PCA / global UMAP / topogene PCA), plus per-loop matplotlib panels for PDF export.


Installation

git clone https://github.com/binglunshao/sctopo.git
cd sctopo
pip install -e .

Development install:

pip install -e ".[dev]"

Core dependencies: numpy, scipy, scikit-learn, networkx, pandas, matplotlib, plotly, anndata, scanpy, ripser, persim, dreimac, torch (legacy gradient scoring only). torch is only required if you call sctopo.genes.topo_scores_rep_sampling; the default periodicity scoring is pure NumPy.


Quick start

import anndata as ad
import sctopo.cells as tpc
import sctopo.genes as tpg
import sctopo.viz as tpv

# Load and subset to one cluster
adata = ad.read_h5ad("brain_dev_concord.h5ad")
adata_cluster = adata[adata.obs["leiden"] == "2"].copy()

# 1. Per-cluster PH with significance filtering
X = adata_cluster.obsm["X_pca"]
topological_loops = tpc.critical_edge_method_significant(
    X,
    n_subsamples=50,
    alpha=0.05,
    birth_dist_nn_quantile=0.75,
    verbose=True,
)
tpv.quick_loop_summary(topological_loops)

# 2. Circular coords + topogenes for each loop
results = []
for i in range(len(topological_loops)):
    cc = tpg.get_circular_coords(topological_loops, loop_index=i)
    res = tpg.compute_topogenes(
        adata_cluster, topological_loops, cc,
        loop_index=i, n_genes=100,
    )
    results.append({"cc": cc, **res})
    print(f"Loop {i+1}: top genes = {res['topogenes'][:5]}")

# 3. Per-gene permutation significance
sig = tpg.topogenes_significance(
    adata_cluster, topological_loops, results[0]["cc"],
    loop_index=0, n_perms=100,
)
print(f"Family-wise α=0.05 threshold: {sig['max_threshold_0p05']:.3f}")

# 4. Visualize
import scanpy as sc
topocell_ixs = topological_loops[0]["topocell_ixs"]
adata_cc = adata_cluster[topocell_ixs, results[0]["topogenes"]].copy()
sc.tl.pca(adata_cc, n_comps=3)

fig = tpv.plot_topocells_subplots(
    adata_cluster, adata_cc, topological_loops,
    loop_index=0, color_col="phase",
)
fig.show()

A complete walk-through is in notebooks/example_pipeline.ipynb.


Topogene scoring: two methods

sctopo ships two topogene-scoring algorithms. The periodicity method is the default and recommended choice; the gradient method is preserved for reproducibility with earlier analyses.

Periodicity (default) Gradient (legacy)
Function topo_scores_periodicity topo_scores_rep_sampling
Definition √(corr(x, cos θ)² + corr(x, sin θ)²) ‖∇₍x₎ Σ subsample-cycle-perimeter‖₂
Determinism Deterministic Monte-Carlo over n_reps
Interpretation First Fourier amplitude along cycle Sensitivity of cycle length to expression
Dependencies NumPy + SciPy PyTorch
Per-gene p-value Yes (cheap permutation) Yes (more expensive)

Both methods accept the same arguments and return the same shape of output, so you can swap via compute_topogenes(..., method="periodicity"|"rep_sampling").


Package layout

sctopo/
├── pp/              preprocessing utilities
│   ├── pca.py             gap-based PCA cutoff (sparse-aware)
│   └── outliers.py        Isolation Forest on PCA coords
├── cells/           per-cluster PH, significance, loop extraction
│   ├── graph.py        VR 1-skeleton construction
│   ├── significance.py permutation null
│   ├── loops.py        critical_edge_method[_significant]
│   └── cycle_assign.py project all cells onto a cycle
├── genes/           circular coords + topogene scoring
│   ├── circular_coords.py   DREiMac wrapper, circular variance
│   ├── periodicity.py       default scoring (Fourier amplitude)
│   ├── rep_sampling.py      legacy gradient scoring
│   └── topogenes.py         compute_topogenes, topogenes_significance
└── viz/             plotly + matplotlib visualizations
    ├── cloud.py             3-D topocell views
    ├── diagrams.py          persistence diagrams
    └── summary.py           text summaries

Citing

If you use sctopo in published work, please cite:

@software{sctopo2026,
  author  = {Shao, Binglun},
  title   = {sctopo: topological analysis of single-cell data},
  year    = {2026},
  url     = {https://github.com/binglunshao/sctopo},
  version = {0.1.0},
}

A paper describing the method is in preparation; please also cite the underlying tools ripser (Tralie et al. 2018) and dreimac (Perea et al.).


Acknowledgements

sctopo builds on ideas from an earlier prototype totopos, developed in collaboration with Emanuel Flores Bautista. Per-cluster persistent homology, periodicity-based topogene scoring, permutation-null significance testing, and the unified visualization API are new in this package.


License

BSD 3-Clause License. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sctopo-0.1.0.tar.gz (43.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sctopo-0.1.0-py3-none-any.whl (43.0 kB view details)

Uploaded Python 3

File details

Details for the file sctopo-0.1.0.tar.gz.

File metadata

  • Download URL: sctopo-0.1.0.tar.gz
  • Upload date:
  • Size: 43.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for sctopo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bde4fb8095437e0d85a8d424fbc789aaa0aa399b21570babd22025c48091c6d0
MD5 89a786b9575a63a9f1890a8dc7b43276
BLAKE2b-256 2defa581c0568d230ffa30e1559f20d9e06ff74cb6d4c50f23382db10a667cfa

See more details on using hashes here.

File details

Details for the file sctopo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sctopo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 43.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for sctopo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 63b95f5b019922c98928ac5d8c6d96b253ecc00ff84f50433fec9f095be23ec4
MD5 5d73d3a9cfa54825f76e3560f11c503f
BLAKE2b-256 a6d786128cccaa7a9726c6557b22bb597acb9b7ea5c642081c87dd4c45ef28f6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page