Real-data downsampling sanity harness for exposure confidence intervals
Source:R/calibrate-real.R
ms_calibration_sanity.Rd`ms_calibration_sanity()` runs the M3b real-data sanity protocol (design memo vignettes/articles/devlog-2026-10-04-M3b-design-memo.qmd section 4) on a CALLER-SUPPLIED real catalog: the frozen production face fits the full catalog (the point estimate is the declared **pseudo-truth**), every dilution level \(N \in\) `dilution_sizes` down-samples each live sample through \(\mathrm{Multinomial}(N,\ \mathrm{counts}_j / \mathrm{total}_j)\) `n_dilutions` times, each diluted catalog is refit with the production face + CI, and \(S(N)\) – the coverage of the pseudo-truth entries with pseudo-truth share >= 0.05 – forms the downsampling curve.
Usage
ms_calibration_sanity(
catalog_real,
sigs_real,
n_boot = 200,
bca = FALSE,
dilution_sizes = c(100, 1000, 10000),
n_dilutions = 100,
synthetic = NULL,
tolerance = .MS_SANITY_TOLERANCE,
seed = 1,
nb_size = 8,
n_threads = NULL
)Arguments
- catalog_real
An [MsCatalog] holding the real counts (channels x samples). Samples with zero total are dead and excluded from the dilution draws (their pseudo-truth is zero anyway).
- sigs_real
The dictionary to fit against: a numeric matrix (channels x signatures) or an [MsSignature], resolved exactly as in [ms_fit()] (channel alignment by label, display normalization).
- n_boot
Single positive whole number: bootstrap replicates of every diluted fit (the memo protocol uses 1000; the default here is the reduced 200 for interactive budgets).
- bca
Single logical (default `FALSE`): read the BCa face of the diluted CIs instead of the percentile face (fallback cells are bit-identical to percentile either way).
- dilution_sizes
Increasing vector of positive whole numbers: the dilution (downsampled mutation total per sample) axis; the memo protocol is
c(100, 1000, 10000). Every level must be a strict downsample of every live sample (level <= the smallest live total).- n_dilutions
Single positive whole number in \([1, 4096]\): dilution replicates per level (the memo protocol uses 100).
- synthetic
NULL (default) or a data.frame with columns `n` and `coverage`: the synthetic MAIN-arm calibration curve to compare against (a subset of [ms_calibration_grid()] output over the same N axis, run at the frozen protocol). With NULL the acceptance falls back to the floor band \([0.90, 1.00]\) alone (recorded in the result).
- tolerance
Single number in \([0, 1]\): the |S(N) - synthetic| band half-width (frozen 0.05, PI ruling) and the step-inversion noise slack.
- seed
Single non-negative whole number: the base seed. The dilution draws consume base R's RNG seeded exactly once (draws run in fixed level x replicate x sample order; the caller's RNG state is restored on exit), and the bootstrap of dilution (level i, replicate d) uses the derived PCG64 seed `seed + (i-1)*n_dilutions + (d-1)` – the whole result is a pure function of the inputs.
- nb_size, n_threads
As in [ms_fit()] / [ms_fit_bootstrap()].
Value
A list of class `ms_calibration_sanity` with elements: `pass`; `s_curve` (data.frame `n`, `s`, `se`, `tallies`, `deviation`, `within` – `deviation` is |S(N) - synthetic(N)| (NA without a synthetic curve) and `within` the per-level acceptance: the +/-`tolerance` band around the synthetic value OR the floor band [0.90, 1.00], whichever wider, floor alone without a synthetic curve); `synthetic_used`; `n_inversions`, `inverted_at`, `systematic_inversion`; `tolerance`; `floor_band`; `share_floor`; `dilution_sizes`; `n_dilutions`; `n_boot`; `bca`; `seed`; `nb_size`; `method`; `kept` (data.frame `signature`, `sample`, `truth`, `truth_share` – the pseudo-truth entries S(N) is measured on); `n_live_samples`; `dead_samples`. All violations raise `msuiter_error_*` conditions.
Details
**This is a sanity/stability instrument, never calibration evidence**
(memo section 4, non-claim discipline): the pseudo-truth is an estimator
and real data violate the fitted model. Data acquisition and governance
(PCAWG WGS primary / TCGA GDC open WXS secondary, WES and panel axes
deferred to M4 by PI ruling) live in
inst/sanity/README.md; this function never downloads data.
**The pseudo-truth.** The full catalog is fit once with the production face (`"likelihood_bidirectional"`, zero_threshold 0.01, rescale), the same face the synthetic grid declares on. Kept entries are the (signature, sample) cells whose pseudo-truth share is >= 0.05; S(N) pools over kept entries x dilution replicates.
**Acceptance.** `pass = all(within) && !systematic_inversion`, where `within` is per level: |S(N) - synthetic(N)| <= `tolerance`, OR S(N) inside the wider floor band [0.90, 1.00] (the memo's "the wider one" union); without a synthetic curve, the floor band alone. A level-to-level drop steeper than `tolerance` is an inversion; the inversion is systematic when a strict majority of steps invert.