Skip to main content

Rust implementation of the SCENIC single-cell GRN pipeline (GRN + cisTarget + AUCell)

Project description

scenic-rs

CI PyPI Python

A memory-efficient Rust implementation of the pySCENIC single-cell gene regulatory network (GRN) pipeline. Not associated with the lab, just built this as a quick project!

Benefits

  • Implements the same algorithms as pySCENIC (GRNBoost2, GENIE3, AUCell, CTX trimming)
  • Can use modern numpy/pandas in your environment
  • Memory usage is constant with increased parallelism, allowing for faster execution without OOM

Requirements

Runtime (using scenic-rs)

  • Python ≥ 3.9
  • numpy, pandas
  • scanpy (optional) — only if you use it to load your data (Cell Ranger / .h5ad); scenic-rs itself just takes a numpy matrix + gene/TF names
  • For the ctx step only: the cisTarget ranking databases (*.genes_vs_motifs.rankings.feather) and the motif2TF annotations (.tbl), from resources.aertslab.org/cistarget

From source (optional — only for development; pip install uses prebuilt wheels)

  • A recent stable Rust toolchain (cargo/rustc) — ≥ 1.70 (tested on 1.86); install via rustup.rs.
  • maturin ≥ 1.0 (pip install maturin), then maturin develop --release

Benchmarks / validation only (optional)

  • A separate pySCENIC environment to compare against: python3.10 -m venv ~/venvs/pyscenic_clean && ~/venvs/pyscenic_clean/bin/pip install "numpy<1.24" "pandas<2" pyscenic
  • matplotlib + scipy for the plotting and validation scripts

Install

pip install scenic-rs   # prebuilt wheels: Linux / macOS / Windows, Python >=3.9

scenic-rs depends only on (unpinned) numpy and pandas, so it drops into an existing environment — including a scanpy env — without forcing a downgrade.

conda — a ready-made environment that includes scanpy:

conda env create -f environment.yml   # then: conda activate scenic-rs

Docker / Nextflow / Singularity — a version-pinned image is published per release for reproducible pipelines:

docker pull ghcr.io/nglaszik/scenic-rs:latest      # or a pinned tag, e.g. :0.1.1
// In a Nextflow process, just point at the image:
process scenic {
    container 'ghcr.io/nglaszik/scenic-rs:0.1.1'
    // ... your script that `import scenic_rs`
}

Usage

scenic-rs takes a cells × genes float32 matrix plus the gene names and a TF list — load these however you like (e.g. with scanpy). Raw counts; do your own cell/gene QC first. From Cell Ranger output:

import numpy as np, scanpy as sc

adata = sc.read_10x_mtx("sample/outs/filtered_feature_bc_matrix")   # or sc.read_10x_h5(".../filtered_feature_bc_matrix.h5")
adata.var_names_make_unique()
sc.pp.filter_genes(adata, min_cells=3)                              # basic QC (filter cells/genes as you see fit)
X = np.asarray(adata.X.todense() if hasattr(adata.X, "todense") else adata.X, dtype="float32")
gene_names = adata.var_names.tolist()

# ...or from an existing AnnData .h5ad:
# adata = sc.read_h5ad("counts.h5ad")
# X = np.asarray(adata.layers["counts"].todense(), dtype="float32"); gene_names = adata.var_names.tolist()

# TFs = a TF list (e.g. allTFs_hg38.txt from aertslab) intersected with the genes present
tf_names = [g for g in open("allTFs_hg38.txt").read().split() if g in set(gene_names)]

Then run the pipeline:

from scenic_rs import grnboost2, genie3, aucell, RankingDb, ctx

# 1. GRN: TF -> target importances  (pandas DataFrame [TF, target, importance])
adj = grnboost2(X, gene_names, tf_names)        # default — fast, OOB early stopping
# adj = genie3(X, gene_names, tf_names)         # alternative — random forest, slower, ~same result (use one)

# 2. ctx: prune co-expression modules to motif-supported regulons
dbs = [RankingDb("hg38_...genes_vs_motifs.rankings.feather", "hg38")]
regulons = ctx(adj, X, gene_names, dbs, "motifs-...hgnc-...tbl")   # -> [Regulon(...)]

# 3. AUCell: per-cell regulon activity
auc = aucell(X, gene_names, {r.name: r.genes for r in regulons})

adj matches pySCENIC's adjacencies format and ctx matches its regulon output, so any step can also be swapped in individually alongside pySCENIC.

Validation & benchmarks (vs real pySCENIC)

  • Running each step (grnboost2/genie3/aucell/ctx) in both scenic-rs and pySCENIC 0.12.1 / ctxcore 0.2.0
  • Uses the same inputs (pbmc3k 2700 cells × 758 genes, 300 TFs), (hg38 cisTarget DB 5876 motifs × 27015 genes + motif2tf annotations)
  • Equal cores — rayon threads = pySCENIC's Dask-worker count
  • Backend startup counted on both sides

Correctness — scenic-rs reproduces pySCENIC's numbers

step concordance vs pySCENIC
GRN / GRNBoost2 Spearman 0.74, top-1000 edge Jaccard 0.56 — at the stochastic ceiling
GRN / GENIE3 Spearman 0.99, per-target median 0.99
ctx / cisTarget per-(module,motif) NES Spearman 1.00 (max diff 1.4e-13)
AUCell Spearman 0.98, max abs diff 0.06

GRNBoost2 is stochastic — running the algorithm twice (different seed) only agrees ~0.73 per target.

output concordance GRN per-target concordance

Memory & speed

  • Peak memory (PSS) is constant in scenic-rs as cores increase, but grows ~linearly in pySCENIC (per-worker copies). Ratios = pySCENIC / scenic-rs:
step memory: 16c → 96c speed (equal cores)
GRN / GRNBoost2 13× → 26× less 2.8× faster @96c
GRN / GENIE3 30× → 123× less equivalent
ctx / cisTarget 14× → 26× less ~10× faster
AUCell 18× → 51× less ~170× faster

At 96 cores pySCENIC peaks at ~11.7 GB (GRNBoost2), ~20.5 GB (GENIE3) and ~17 GB (ctx); scenic-rs stays at ~0.45 GB, ~0.17 GB and ~0.66 GB respectively.

Speedup on GRNBoost2 is likely due to Dask setup, relatively negligible on larger datasets.

peak memory vs cores wall-clock vs cores

Reproduce

Needs a pySCENIC env, e.g. python3.10 -m venv ~/venvs/pyscenic_clean && ~/venvs/pyscenic_clean/bin/pip install "numpy<1.24" "pandas<2" pyscenic:

# correctness + cached adjacencies (GRN + AUCell)
python bench/benchmark_pyscenic.py --workers 16 --genie3
# memory/time scaling sweep across cores (GRNBoost2, GENIE3, AUCell)
python bench/mem_benchmark.py --sweep 16,48,96 --genie3
# ctx scaling sweep (real hg38 DB)
python bench/benchmark_ctx.py --sweep 16,48,96
# ctx per-step parity checks (math, DB, modules, regulons, NES concordance)
PYTHONPATH=python ~/venvs/pyscenic_clean/bin/python bench/validate_ctx_regulons.py
# render figures
python bench/plot_benchmark.py        # concordance.png, grn_per_target.png
python bench/plot_mem_benchmark.py    # mem_scaling.png, time_scaling.png (all steps)

License & attribution

GPL-3.0-or-later. scenic-rs is a Rust reimplementation of, and a derivative work of, the GPL-3.0 projects pySCENIC and ctxcore (aertslab, VIB-KU Leuven) — their GRN/cisTarget/AUCell workflow and the recovery/NES/module/pruning logic. It is an independent project, not affiliated with or endorsed by aertslab. See NOTICE for details.

If you use scenic-rs, please cite the original SCENIC work:

  • Aibar et al. (2017) SCENIC: single-cell regulatory network inference and clustering. Nature Methods.
  • Van de Sande et al. (2020) A scalable SCENIC workflow for single-cell gene regulatory network analysis. Nature Protocols.
  • Moerman et al. (2019) GRNBoost2 and Arboreto… Bioinformatics.

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

scenic_rs-0.3.0.tar.gz (3.0 MB view details)

Uploaded Source

Built Distributions

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

scenic_rs-0.3.0-cp39-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.9+Windows x86-64

scenic_rs-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

scenic_rs-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

scenic_rs-0.3.0-cp39-abi3-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file scenic_rs-0.3.0.tar.gz.

File metadata

  • Download URL: scenic_rs-0.3.0.tar.gz
  • Upload date:
  • Size: 3.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scenic_rs-0.3.0.tar.gz
Algorithm Hash digest
SHA256 8e7bdb95629f04cd846a6accff4bfc1d680cd23bacea1f1f884106ee5ed5b05a
MD5 3997b8aff001fc6dc5db977a58e9a609
BLAKE2b-256 5e6cf79ec79e1586765cd1bb9299ff870b8f93ac03098c7ac22af3c576e2b844

See more details on using hashes here.

File details

Details for the file scenic_rs-0.3.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: scenic_rs-0.3.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scenic_rs-0.3.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5c0657c7fdf94247222d6bc52005f96b8444b3ae1a4c95237c2a1317fb5a2b59
MD5 33af0d5c165a3feeecf12557b6457aac
BLAKE2b-256 be476595bf4b14c975f2fba14a71959d7d9e2afcb536800c121dad4ebab1143e

See more details on using hashes here.

File details

Details for the file scenic_rs-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for scenic_rs-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 94829ed9766d55f6b44debe968d6ed2ecea71c3bf67bc67172c8f25887200286
MD5 46e3b3ca930b68e5f47694127a5f62f6
BLAKE2b-256 0cd709e2ed1985240428e2d20b39cec566af78573c9cb23696f4fdf4f605c91c

See more details on using hashes here.

File details

Details for the file scenic_rs-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for scenic_rs-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 afb103ad24be58cf2bcf13ca15bc5093dd73154a628c54d58efd22d7e7b16553
MD5 b9eeec67cb13187a706f8c93f0adde39
BLAKE2b-256 b90bb25e4e5c5a7152554f97d4c28787c17ae13f2ef73390e2b09d05967185ac

See more details on using hashes here.

File details

Details for the file scenic_rs-0.3.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for scenic_rs-0.3.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a9f33700d69a9ab637c652baf564ccfc8a361448a41a0a91f7ad808b9185b397
MD5 f2a4970f396e992f224ef01f8f462692
BLAKE2b-256 eb538c22cee6031d573bfcb17f2d9f7c16c674be782149fe789288b3440f28c3

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