Stratify hypermutated samples with the SigProfiler GMM cutoff
Source:R/stratify.R
ms_stratify_hypermutants.RdApplies the frozen SigProfilerExtractor hypermutant rule (`vignettes/articles/devlog-2026-09-30-GMM-stratify-memo.qmd`): a k = 2 Gaussian mixture on the raw per-sample mutation totals (no log transform), an iterative majority-cluster prune until the cluster means differ by less than 4 standard deviations, then `cutoff = trunc(mean + 2 sd)` of the retained bulk, floored at `manual_cutoff` (default 100 x channels, matching the upstream call site). A sample is hypermutated iff its total is strictly greater than the cutoff.
Arguments
- catalog
an [MsCatalog] (totals are the catalog column sums) or a named numeric vector of per-sample mutation totals.
- manual_cutoff
single whole number: the floor applied to the derived cutoff. Defaults to `100 * nrow(counts)` for an [MsCatalog] (the upstream call-site convention; 9600 for SBS96) and to 0 for a totals vector.
- seed
single non-negative whole number seeding the GMM initialization stream (canonical MsRng layout; same input and seed give identical results).
Details
msuiter's pipeline policy diverges deliberately from upstream's rescaling: the flagged samples are **excluded from de novo extraction** and refitted afterwards (M2; ARCHITECTURE section 5). This function returns the decision record; the extraction pipeline consumes it.
Examples
labels <- paste0("CH", 1:3)
counts <- matrix(1:12, 3, 4, dimnames = list(labels, paste0("S", 1:4)))
counts[1, 4] <- 9500 # a hypermutated sample
cat1 <- ms_catalog(counts, list(name = "SYN3", labels = labels),
colnames(counts), provenance = list(genome = "GRCh38"))
ms_stratify_hypermutants(cat1, seed = 1)
#> <MsStratification> GMM cutoff 300: 1/4 hypermutated; excluded from de novo, refit pending (M2)