Skip to content

About

core cellAdmix algorithm implementation in C++ with R and python bindings

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

cellAdmix-core

cellAdmix-core is a C++ implementation of the core cellAdmix workflow for detecting and correcting transcript-level admixture in spatial transcriptomics data.

The package is designed around a high-performance C++ core with language bindings. The current public interfaces are the R package cellAdmixCore and an initial Python package, with integrations for Seurat and SpatialData-style workflows.

The implementation is optimized for large molecule-level datasets. Xenium bundles are handled as first-class inputs, with molecule tables streamed into an encoded on-disk store so large experiments do not need to be kept fully in R or Python memory. As a rough local benchmark, on Xenium 5K data (breast 5K; 96.6M kept molecules and 694K cells), a 10-thread batch run with auto-annotation, rank-30 fit, membrane scoring, a single-fit correction (--ensemble 1), and a minimal report completed in about 62 minutes with peak RSS about 42 GB; the default ensemble correction repeats the molecule-assignment and scoring stages once per ensemble member. (The breast tutorials run the same dataset with curated annotations and stricter cell QC, which keeps 82.1M molecules across 688K cells at rank 8.)

The quickest way to see the workflow end to end is the pancreas quickstart notebook: fit, audit the dataset's admixture, correct, and verify the cleanup in a few short steps.

Highlights

  • C++ core for neighborhood composition construction, NMF fitting, molecule assignment, spatial smoothing, admixture scoring, and correction.
  • R bindings with a high-level cellAdmix() constructor and R6 workflow.
  • Python bindings with a high-level CellAdmix class and optional SpatialData adapter.
  • Native Xenium bundle support, including transcript tables, cell metadata, boundaries, and morphology images when available.
  • Generic tabular input support for .csv, .csv.gz, .tsv, .tsv.gz, and Parquet molecule tables.
  • Seurat integration: use a Seurat object for cells, genes, annotations, and downstream storage while using the original Xenium bundle as the molecule-complete backing source.
  • Optional quick cell clustering and marker diagnostics when no annotation is available.
  • Corrected sparse gene-by-cell count collection and add-back to Seurat.
  • Admixture audit: exposure-gradient estimates of leaked molecules per cell-type pair, independent of the factorization, with post-correction verification of cleanup sensitivity and false removal (docs/benchmarks.md).
  • Ensemble correction by default: molecule-level voting across NMF restarts stabilizes seed-dependent corrections, with the vote threshold as a sensitivity/specificity dial.

NMF Methods

cellAdmix-core supports several factorization modes. ls_nmf is the default; in cleanup benchmarks (docs/benchmarks.md) the most effective variant follows the scoring method — invsqrt_kl for membrane-scored corrections on stained data, ls_nmf for bridge-scored ones.

nmf_variant Description
ls_nmf Default. Weighted least-squares NMF following the original cellAdmix formulation; produces the most reproducible cell-type-native factors across restarts.
invsqrt_kl Sparse KL-NMF with inverse-square-root gene-prevalence weighting; marker-driven loadings at the cost of lower restart stability. Best cleanup with membrane scoring.
kl Sparse KL-NMF without gene weighting.
sqrt_kl Sparse KL-NMF after square-root transformation of NCV counts.

Multirun fits report a per-factor restart stability diagnostic used for factor trust and rank selection; see docs/nmf_stability.md.

Installation

See docs/install.md for system dependencies and R/Python binding installation. The repository includes CMake presets, a vcpkg manifest, and GitHub Actions smoke builds for the C++ core plus R and Python bindings.

R Bindings

The R interface is documented in docs/r-bindings.md.

Minimal R workflow:

library(cellAdmixCore)

ds <- cellAdmix("data", output_dir = "out", annotation = cell_annotation)
fit <- ds$fit()
score <- fit$score_membrane()
rules <- score$rules()
correction <- score$correct(rules = rules)
corrected_counts <- correction$counts()

The R documentation page links to more detailed notes on inputs, scoring methods, batch processing, and example notebooks.

Python Bindings

The Python interface is documented in docs/python-bindings.md. It is a thin pybind11 layer over the same C++ analysis store and run artifacts used by the R package.

Minimal Python workflow:

import celladmix as ca

ds = ca.CellAdmix("data", output_dir="out", annotation=cell_annotation)
fit = ds.fit()
score = fit.score_membrane()
rules = score.rules()
correction = score.correct(rules=rules)
counts, genes, cells = correction.counts()

Batch processing from Python is available through scripts/celladmix_batch.py. The current Python batch entrypoint supports Xenium bundle inputs and mirrors the core R batch workflow:

python scripts/celladmix_batch.py --input data --output out \
  --annotation annotations/annotation.csv.gz \
  --annotation-col merged_annotation \
  --score auto --report --threads 10

See docs/python-batch.md for options and current Python-side limitations.

Examples

Rendered tutorials with embedded output are grouped by binding: the R tutorials are rendered markdown pages, the Python tutorials are Jupyter notebooks.

R Examples

Python Examples

Documentation

Status

This is an initial public release. The C++ core, R bindings, and Python bindings are usable, but interfaces may still evolve as the package matures.

About

core cellAdmix algorithm implementation in C++ with R and python bindings

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages