Repository navigation
StateTrace 0.2.0
pip install statetrace-sc==0.2.0 (import name statetrace).
StateTrace 0.2.0 expands reference validation and transport diagnostics
with calibrated out-of-reference detection, mapper-independent reference
reproducibility diagnostics, study-aware novelty calibration, and
complementary cell- and donor-level distribution-shift tests.
Highlights
-
Improved reference validation. Reproducibility can now be evaluated
in a frozen expression space, independently of mapper-specific latent
coordinates. Study-aware holdout calibration accounts for variation
across represented studies, with fallback for insufficient evidence. -
Calibrated novelty detection. kNN distance replaces centroid
distance as the default OOD statistic following a prespecified
simulation-based comparison. Support-deficit and combined
kNN-support diagnostics are available for sensitivity analysis. -
Complementary shift evidence. E-distance permutation testing and
optional scXMatch cross-match testing assess cell-level and
donor-profile distribution differences without changing state
classifications. -
Reference-aware caution thresholds. Recovery and uncertainty
warnings now use held-out reference evidence rather than fixed
thresholds where sufficient calibration data are available. -
Reproducibility and compatibility. Frozen-reference format 4 adds
cell-level expression coordinates and donor profiles. Format 3
references remain loadable. Configuration provenance and fallback
decisions are recorded.
Benchmark status
Benchmark G1 was evaluated using StateTrace commit 07def17
(StateTrace-benchmarking 00_gates/_m/G1.md, 2026-10-16).
The benchmark passed insufficient-state recall (1.000) and
cross-backend status agreement (0.843). Withheld-state detection
did not meet its registered criterion (AUROC 0.652 versus the
registered comparison value of 0.722).
The withheld-state detection failure remains accepted as a
documented limitation, not a successful benchmark outcome.
Release defaults were selected using simulator-based criteria rather
than optimized against G1. Inspection of G1 identified an additional
mixed-neighborhood failure mode, motivating support-based diagnostics.
Those diagnostics did not satisfy the registered replacement rule and
are retained as post hoc sensitivity tools rather than new defaults.
The G1 results describe the evaluated commit and do not independently
validate additions made after that evaluation.
Added
- Out-of-reference scores that see a population the reference lacks when it sits between
reference states rather than away from them (TransportConfig.ood_score):"support", the
local-support deficit standardised against the held-out support of the assigned state
(novelty.support_novelty), and"knn_support", the larger of the standardised kNN
distance and the support deficit. Benchmark G1 (StateTrace-benchmarking) withheld CD4 T
cells from a PBMC reference that keeps Tregs and CD8: every mapper absorbed them into
Treg or CD8 with kNN and centroid distances no larger than those states' own held-out
cells (AUROC at chance), while their mixed neighbourhoods were visible; the frozen
expression space showed the same (CD4 cells sit closer to the Treg centroid than held-out
Tregs do), so no distance score, in any space, sees such a state. The score the benchmark
predeclares is chosen on the simulator by a rule fixed before it runs, asknnwas.
distance_calibrationgainssupport_mean_holdout,support_sd_holdout,
supportz_q95/q99_holdoutandknn_support_q95/q99_holdout;cellsgains
support_novelty,knn_support_noveltyandood_novelty(the standardised score behind
the out-of-reference call, so a benchmark ranks what the rule used). Frozen references
without the new calibration columns fall back to the centroid z rule for the new scores,
androute.reference["ood_fallback"]says so. simulate_transport(novel_chimera=...): a withheld state that takes a reference state's
latent centroid exactly and, on a few seeded genes, a third state's expression level; the
case of a population that shares its neighbour's programs but differs in marker genes.- Two-sample engines (
statetrace.twosample,TwoSampleConfig): the E-distance permutation
test (native; Euclidean, as in pertpy) and Rosenbaum's cross-match test through scXMatch
(Moeller et al., Bioinformatics 2026, doi:10.1093/bioinformatics/btag706; optional, conda
only).TransportConfig(two_sample=...)runs them for every reference state at cell level
(frozen cell-level space) and on donor profiles (held-out reference donors against query
donors), over all assigned and in-reference cells;route.two_sample,two_sample.csvand a
report section. Reported evidence only:statusandSTATE_COLUMNSare unchanged. - Frozen cell-level space in
ExpressionSpace(cell_sample_per_state,cell_components,
cell_seed;build_cell_space,project_cells) and the held-out reference donor profiles
(null_profiles);query_profilesexposes the standardised donor profiles behind
score_query. simulate_transport(spread_states=...): a change in spread with the mean kept (truth
spread, columnspread_factor).LODOConfig(calibration_unit="study"): the novelty null of a leave-one-group-out run
(held-out distances, their quantiles, the population thresholds) is built with one study
held out at a time, each held-out donor's latent offset removed as for a query donor, so a
query from a new study is judged against between-study differences an offset does not
remove. States without enough study-held-out evidence keep the group null;
distance_calibration["calibration_unit"]androute.reference["novelty_calibration_unit"]
record the choice. Reproducibility still comes from the group holdout. Default"auto"
(see Changed).LODOConfig(reproducibility_space="expression"): thereproducibilitycategory is judged
by the grouped holdout repeated with the kNN on every reference cell in the frozen
cell-level expression space (expression.cell_coordinates), built from counts alone, so
the same reference cells get the same call whichever mapper's latent they sit in. The
latent call is kept asreproducibility_latent; the expression holdout adds
reproducibility_expressionand*_expressionmetrics. Transport reports
ref_reproducibility_latentandref_reproducibility_expressionbeside the deciding
ref_reproducibility, androute.reference["reproducibility_space"]. Default"auto"
(see Changed).- Elongated states and a withheld state between two states in the simulator:
simulate_reference/simulate_transport(state_anisotropy=, anisotropic_dims=)stretch
each state's noise along its own random directions (drawn from a separate generator, so
every existing seed is unchanged), andsimulate_transport(novel_between={novel: (a, b, t)})places a withheld state a fractiontof the way fromatob. With elongated
absorbing states the centroid score loses an absorbed population that the kNN distance
still finds (tests/test_transport.py: AUROC 0.66-0.88 centroid against 0.89-0.98 kNN over
three seeds att=0.35, stretch 3); the round-state grid behind the predeclared
ood_scorenever showed this. TransportConfig(caution_calibration="holdout"): the recovery and uncertainty caution
triggers compare the query's donors with held-out reference donors, both measured from
StateTrace's own evidence in the mapper's latent (novelty.group_evidence_table), instead
of fixed cut-offs (recovery below 0.8, uncertain fraction above 0.2): caution when the query
is worse with one-sidedp < caution_alpha(Fisher exact for recovery, Mann-Whitney for
per-donor uncertain fractions) and by more thancaution_margin. States seen in too few
held-out donors keep the cut-offs (caution_basis). New state columnscaution_basis,
ref_groups_observed,cmp_recovery_rate,ref_recovery_rate,recovery_p,
cmp_uncertain_fraction,ref_uncertain_fraction,uncertain_pand, in every mode,
caution_reasons(also in the report);route.reference["caution_calibration"]. Default
"holdout"(see Changed).
Changed
- Distribution name on PyPI is
statetrace-sc: PyPI refusesstatetraceas too similar to
the unrelatedstate-traceproject (separators are ignored in the comparison). The import
name, the repository and the documentation keepstatetrace;pip install statetrace-sc. - Defaults that change results on the same data (benchmark gate G1 failed on 0.1.0: the
status differed across mappers and the centroid novelty score lost withheld populations;
every fix was chosen on the simulator, never on the G1 data):LODOConfig.reproducibility_spacedefaults to"auto": the frozen cell-level expression
space when the reference has it, else the latent. The reproducibility call no longer
depends on which mapper's latent the reference sits in.LODOConfig.calibration_unitdefaults to"auto": the study-held-out null when the
reference has at least two studies, else the donor-held-out null.TransportConfig.caution_calibrationdefaults to"holdout": caution when the query's
donors do measurably worse than held-out reference donors, not when a noisy rate crosses
a fixed cut-off.ValidationResult.configrecords the resolved values.reproducibility_space="latent",
calibration_unit="group",caution_calibration="fixed"andood_score="centroid"
reproduce 0.1.0.TransportConfig.ood_scoredefaults to"knn"(was"centroid"), set from the
withheld-state curve on elongated states (StateTrace-benchmarking S1.3b,
withheld_geometry_curve.csv; 240 runs, 5 seeds, StateTrace93e7261) by a rule fixed
on 2026-10-12, before any result of that curve. Over the G1 mappers (scANVI,
scPoli, Symphony): (1) primary = mean AUROC on elongated states with the withheld state
between two (stretch 3, t = 0.2, 0.35, 0.5); (2) on round states at the default
placement (the G0 geometry), mean AUROC no more than 0.02 below centroid and no mapper
more than 0.05 below; (3) false rate of the score's q95 rule no more than 0.02 above
centroid's; (4) amongknnandjointmeeting (2) and (3), the higher primary wins if it
beats centroid by at least 0.02,jointwhen the two are within 0.01; elsecentroid.
Result (mean AUROC; centroid / knn / joint): elongated, between 0.680 / 0.859 / 0.812;
round 0.949 / 0.949 / 0.955, per mapper knn within 0.006 of centroid; q95 false rate
0.048 / 0.042 / 0.047; q95 power on elongated 0.16 / 0.49 / 0.42. Both candidates were
eligible and knn led joint by 0.047, soknn. Without held-out calibration the centroid
z rule still applies (route.reference["ood_fallback"]).
validate_transportraises when a query group (donor) is also a reference group, unless
TransportConfig(allow_group_overlap=True)(the explicit cell-level control); it warns when
the reference is not frozen and records the check inroute.reference["independence"].- Frozen format 4:
expression/addsnull_profiles.npyand the cell-level space. Format 3
bundles still load; their two-sample rows readunsupporteduntil re-frozen. - Positioning: StateTrace orchestrates shift evidence and is not a distribution-shift test
(README, concepts, transport guide, roadmaps). - matplotlib is no longer a core dependency: the new
plotextra carries it for
statetrace.plotting, which says so when it is missing. scvi-tools stays in thescviextra.
Fixed
- Python 3.11:
isinstance(backend, MappingBackend)raised on an unfittedKNNBackend,
because 3.11 checks protocol members withhasattr, which runs theclasses_property.
The backend protocols now look members up statically on 3.11, as 3.12 does. - Expression space: when LAPACK's divide-and-conquer SVD (gesdd) does not converge, the PCA
retries with the QR-iteration driver (gesvd). Which matrices fail depends on the CPU's BLAS
kernels: a 210k-cell PBMC reference failed on one node type and not on another. Reference.fitno longer turns that numerical failure into the "expression space not built"
warning (LinAlgErroris aValueError); it used to fall back to the mapping latent and so
change the shift and reproducibility diagnostics with only a warning.
Known limitations
Absorbed novel populations. StateTrace may fail to identify a withheld population when
mapping places its cells within the distance distribution of existing reference states.
In benchmark G1, withheld CD4 T cells were absorbed into retained Treg and CD8 states. The
evaluated distance-based diagnostics did not reliably distinguish these cells from held-out
reference cells. The registered withheld-state detection criterion was not met
(AUROC 0.652 versus 0.722).
Mixed-neighborhood support provided additional information about this failure mode. However,
the support-deficit and combined kNN-support scores did not satisfy their prespecified
replacement criteria. They are retained as sensitivity diagnostics; kNN distance
remains the default OOD score.
Reference completeness. A low out-of-reference fraction does not establish that all
biological populations are represented. Novelty estimates should be interpreted alongside
neighborhood support, reference recovery, and uncertainty diagnostics.
Statistical interpretation. Cell-level two-sample tests identify differences in sampled
cell distributions but do not by themselves establish donor-level replication.
Donor-profile evidence is reported separately. Neither test changes StateTrace status calls.
Calibration and transportability. Holdout calibration describes variation represented
in the reference. Performance may degrade for new studies, populations, or technical
conditions not adequately represented by those holdouts. Insufficient calibration evidence
triggers documented fallback behavior.
Planned
- Stage 6 (0.5.0) StateTrace-Spatial: segmentation-stability diagnostics, controlled boundary-error
benchmark design and optional CellART adapter; roadmap only, schedule unassigned, not a
submission requirement. - scANVI
AnnDataBackendwith per-fold latent refitting (statetrace[scvi]). - Downstream-validity helpers (type I error and replication summaries for gated vs ungated analyses).
- Plotting.
- Within-donor localisation of a shifted subpopulation (per-cell displacement against held-out
reference cells); the state-level cell tests above are done.