Skip to main content

Participant-level differential analysis for longitudinal single-cell experiments: DiD, paired comparisons, module scoring, pseudobulk, and power analysis.

Project description

sctrial

Participant-Level Differential Analysis for Longitudinal Single-Cell Experiments

Test Status Release Version Python Versions License: MIT Documentation


Overview

sctrial is a Python package for performing rigorous statistical inference on single-cell RNA-seq data from clinical trials and longitudinal studies. Built on top of AnnData and Scanpy, it provides specialized tools for:

  • Difference-in-Differences (DiD) analysis with participant fixed effects
  • Paired within-arm pre→post contrasts
  • Between-arm comparisons at fixed timepoints
  • Cell-type abundance change testing
  • Gene set enrichment analysis (GSEA) on DiD rankings
  • Power analysis and sample size calculations
  • Effect size estimation with confidence intervals

sctrial overview — from scRNA-seq input through trial-aware analysis to statistical outputs

Key Features

Feature Description
Trial-Aware Design Define participant, visit, arm, and cell type columns once
Robust Statistics Wild cluster bootstrap, participant-level aggregation
Multiple Comparisons Built-in FDR correction across features and cell types
Power Analysis Two-arm DiD and single-arm paired power/sample size calculations
Single-Arm Support arm_col=None for studies without a control arm
Publication-Ready Plots Forest plots, interaction plots, GSEA heatmaps
Scalable Efficient processing of large single-cell datasets

Installation

pip install sctrial

For development:

git clone https://github.com/TheOmarLab/sctrial.git
cd sctrial
pip install -e ".[dev]"

Quick Start

pip install "sctrial[plots]"   # includes dataset loaders and visualization
import sctrial as st

# 1. Load a real immunotherapy trial dataset (auto-downloads on first use)
adata = st.load_sade_feldman()
adata = st.harmonize_response(adata)  # majority-vote response labels

# 2. Define trial design
design = st.TrialDesign(
    participant_col="participant_id",
    visit_col="visit",
    arm_col="response_harmonized",
    arm_treated="Responder",
    arm_control="Non-responder",
    celltype_col="cell_type",
)

# 3. Score gene sets (dataset ships pre-normalized with log1p_tpm layer)
gene_sets = {
    "Cytotoxicity": ["GZMA", "GZMB", "PRF1", "GNLY", "NKG7"],
    "Exhaustion":   ["PDCD1", "CTLA4", "HAVCR2", "LAG3", "TIGIT"],
}
adata = st.score_gene_sets(adata, gene_sets, layer="log1p_tpm", method="zmean", prefix="ms_")

# 4. Run Difference-in-Differences on CD8 T cells
features = [c for c in adata.obs.columns if c.startswith("ms_")]
results = st.did_table(adata, features, design, visits=("Pre", "Post"), celltype="CD8 T cell")
print(results[["feature", "beta_DiD", "se_DiD", "p_DiD", "FDR_DiD"]])

Or use the one-liner convenience wrapper for a quick multi-cell-type scan:

results = st.quick_did(
    adata,
    module_scores=gene_sets,
    visits=("Pre", "Post"),
    arm_col="response_harmonized",
    arm_treated="Responder",
    arm_control="Non-responder",
    celltype_col="cell_type",
)

Supported Study Designs & Datasets

sctrial ships with five real clinical trial datasets, accessible via built-in loaders (st.load_*()). Each demonstrates a different study design:

Design Description Dataset Source Tutorial
Two-arm paired DiD Pre/post × treatment/control interaction Sade-Feldman et al., Cell 2018 — melanoma immunotherapy GSE120575 Immunotherapy
Single-arm pre/post Paired within-arm contrasts over time ImmPort GSE171964 — PBMC vaccine response GSE171964 Vaccine
Single-arm pre/post Paired within-arm, multi-timepoint van Galen et al., Cell 2019 — AML chemotherapy GSE116256
Single-arm multi-timepoint Longitudinal tracking across 4 visits GSE290722 — CAR-T cell therapy (ZUMA-1) GSE290722
Cross-sectional between-arm Between-group comparison at one timepoint Stephenson et al., Nature Medicine 2021 — COVID-19 severity E-MTAB-10026 COVID-19

Additional tutorial: Scalability Benchmark — performance testing on the Sade-Feldman dataset.

Documentation

Full documentation: https://sctrial.readthedocs.io

Citation

If you use sctrial in your research, please cite:

Vasanthakumari P, Valencia I, Aghmiouni MR, Magana B, Omar MN. sctrial: Participant-Level Differential Analysis for Longitudinal Single-Cell Experiments. bioRxiv (2026).

@article{vasanthakumari2026sctrial,
  title = {sctrial: Participant-Level Differential Analysis for Longitudinal Single-Cell Experiments},
  author = {Vasanthakumari, Priyanka and Valencia, Itzel and Aghmiouni, Maryam R. and Magana, Bryan and Omar, Mohamed N.},
  journal = {bioRxiv},
  year = {2026},
  url = {https://github.com/TheOmarLab/sctrial}
}

License

MIT License - see LICENSE for details.

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

sctrial-0.3.0.tar.gz (185.0 kB view details)

Uploaded Source

Built Distribution

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

sctrial-0.3.0-py3-none-any.whl (170.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sctrial-0.3.0.tar.gz
  • Upload date:
  • Size: 185.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for sctrial-0.3.0.tar.gz
Algorithm Hash digest
SHA256 2fd430a0cc536e760187bd42b720290c5f2aeb9990376f5e6b5144db7f6be557
MD5 1ce428ef29a203a4c586ee3fb1569db8
BLAKE2b-256 cbfc13ee5b40300e930ecf6ad445c1d7cf5f470cdb76df6fdde8a758e63271f6

See more details on using hashes here.

File details

Details for the file sctrial-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: sctrial-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 170.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for sctrial-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8f589fd7a4b4a07336ffd9f00b530372bf73cd6bd35ff2371344c7fac9414ef2
MD5 eb3f1d0b3ad5db1a5111e682c7ca3aca
BLAKE2b-256 40b6d401d1560271f976ac97fb94669a49c796da8d6c43e4fb2cbbc3f0153332

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