scCS

scCS — Single-cell Commitment Scores with radial star embedding.

Generalizes the 2-state commitment score framework from:

Kriukov et al. (2025) “Single-cell transcriptome of myeloid cells in response to transplantation of human retinal neurons reveals reversibility of microglial activation”

to any number of cell fates (k-furcations), with: - User-supplied bifurcation cluster (e.g., leiden cluster ‘17’) - Radial star embedding: progenitor at origin, each fate on its own arm - Cells ordered along arms by differentiation metric (pseudotime,

CytoTRACE2, pathway score, or any custom per-cell score)

  • Population-level scores: unCS, nCS, commitment vector, entropy

  • Per-cell fate affinity scores with magnitude weighting

  • Bootstrap confidence intervals on CS values

  • Multi-condition analysis (PairScorer for 2, MultiScorer for 3+)

Three-scorer architecture

  • SingleScorer: single-condition analysis (1 experimental group)

  • PairScorer: pairwise comparison (exactly 2 conditions)

  • MultiScorer: multi-condition comparison (3+ conditions) with tiered statistical testing (omnibus + post-hoc)

Quick start — single condition

>>> import scCS
>>> scorer = scCS.SingleScorer(
...     adata,
...     root='17',
...     branches=['FateA', 'FateB', 'FateC'],
...     obs_key='leiden',
... )
>>> scorer.build_embedding(ordering_metric='pseudotime')
>>> scorer.refit_pseudotime()   # fix arm coverage
>>> scorer.fit()
>>> result = scorer.score(n_bootstrap=500)
>>> print(result.summary())
>>> scorer.plot_star(result)
>>> scorer.transfer_labels(adata, result)

Quick start — pairwise comparison (2 conditions)

>>> pscorer = scCS.PairScorer(
...     adata,
...     root='17',
...     branches=['homeostatic', 'activated'],
...     condition_obs_key='treatment',
...     obs_key='leiden',
... )
>>> pscorer.build_embedding(ordering_metric='pseudotime')
>>> pscorer.refit_pseudotime(scale_01=False)
>>> pscorer.fit()
>>> results = pscorer.score_all_conditions()
>>> delta = pscorer.compute_delta_CS('control', 'treated')
>>> stats = pscorer.compare_conditions(results)
>>> shift = pscorer.trajectory_shift(results)

Quick start — multi-condition (3+ conditions)

>>> mscorer = scCS.MultiScorer(
...     adata,
...     root='17',
...     branches=['homeostatic', 'activated'],
...     condition_obs_key='treatment',
...     obs_key='leiden',
... )
>>> mscorer.build_embedding(ordering_metric='pseudotime')
>>> mscorer.fit()
>>> results = mscorer.score_all_conditions()
>>> omnibus = mscorer.compare_omnibus(results)
>>> posthoc = mscorer.compare_posthoc(results, omnibus_results=omnibus)
>>> deltas = mscorer.compute_pairwise_deltas()

Submodules