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 PyPI Documentation


Overview

sctrial is a Python package for participant-level differential analysis of longitudinal single-cell RNA-seq data from clinical trials and translational studies. Built on AnnData and the scverse ecosystem, it provides:

  • 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://www.omar-lab.com/sctrial/

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.3.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.3-py3-none-any.whl (170.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sctrial-0.3.3.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.3.tar.gz
Algorithm Hash digest
SHA256 ecbb92d4d537b1c0f5c04e1f30b180f7bd08ecbd6a6c9e7a47d41b1ba198575c
MD5 b6ad7c905bb35303c90cb84eddd0b134
BLAKE2b-256 2d1f436d5b624f725c6062e2e8a16bf035e9abe416e67abfa0eeacf0ecc46c26

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sctrial-0.3.3-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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 575b1a9a8537d057e03283d0c2eb1b192816931f1956bf9e71156ecdfccabeaa
MD5 7af2315da20ef1331f3691746ed0c101
BLAKE2b-256 30dbd5867e35cdab7d801b07f790085d3dbae8a7665bf65cc71a0e944b22c579

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