[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7EBGC8PJGC03AEZGCNBNX08":3,"skill-same:01M7EBGC8PJGC03AEZGCNBNX08":62},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":14,"repositoryHtmlUrl":33,"repositoryHomepageUrl":33,"ownerHtmlUrl":34,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":35,"install":36,"resources":49},"01M7EBGC8PJGC03AEZGCNBNX08","bio-analytical-validation",null,"Treats a ctDNA assay as a molecule-counting experiment at the Poisson edge and builds its analytical-validation case the measurement-science way. Covers the genome-equivalent currency (~330 haploid copies\u002Fng), the lambda = input_GE x VAF sampling ceiling (lambda>=3 for ~95% detection), the error-suppression ladder (raw NGS ~1e-3 -> single-strand UMI ~1e-4\u002F1e-5 -> duplex \u003C1e-7), the CLSI EP17 LoB\u002FLoD\u002FLoD95\u002FLoQ framework, the per-locus-vs-panel-integrated LoD distinction that lets bespoke MRD reach ppm, contrived\u002FSEQC2 reference standards, and honest LoD reporting conditioned on input mass + consensus depth + replicate detection rate. Use when stating or trusting a sensitivity claim, designing a dilution-series validation, deciding how many genome equivalents are needed at a target VAF, choosing a single-locus vs panel-integrated LoD, or auditing a \"detects 0.1% VAF\" claim.","Mr-Nobody-Anonymous\u002FAll-skills","Mr-Nobody-Anonymous","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F184253119?v=4","01M7AEXFJHKTYQW5R0ZCQQTWFV","anonymous","01M7C00M3GQR4QKP9GZA42GFAK",0,"MIT","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-analytical-validation\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: bio-analytical-validation\ndescription: Treats a ctDNA assay as a molecule-counting experiment at the Poisson edge and builds its analytical-validation case the measurement-science way. Covers the genome-equivalent currency (~330 haploid copies\u002Fng), the lambda = input_GE x VAF sampling ceiling (lambda>=3 for ~95% detection), the error-suppression ladder (raw NGS ~1e-3 -> single-strand UMI ~1e-4\u002F1e-5 -> duplex \u003C1e-7), the CLSI EP17 LoB\u002FLoD\u002FLoD95\u002FLoQ framework, the per-locus-vs-panel-integrated LoD distinction that lets bespoke MRD reach ppm, contrived\u002FSEQC2 reference standards, and honest LoD reporting conditioned on input mass + consensus depth + replicate detection rate. Use when stating or trusting a sensitivity claim, designing a dilution-series validation, deciding how many genome equivalents are needed at a target VAF, choosing a single-locus vs panel-integrated LoD, or auditing a \"detects 0.1% VAF\" claim.\ntool_type: python\nprimary_tool: scipy\nsource: \"https:\u002F\u002Fgithub.com\u002FGPTomics\u002FbioSkills\"\nsource_repository: \"GPTomics\u002FbioSkills\"\nsource_path: \"liquid-biopsy\u002Fanalytical-validation\u002FSKILL.md\"\nlicense: \"MIT\"\nimported_at: \"2026-09-20\"\n---\n\n## Version Compatibility\n\nReference examples tested with: numpy 1.26+, scipy 1.12+, statsmodels 0.14+\n\nBefore using code patterns, verify installed versions match. If versions differ:\n- Python: `pip show \u003Cpackage>` then `help(module.function)` to check signatures\n\nIf code throws ImportError, AttributeError, or TypeError, introspect the installed\npackage and adapt the example to match the actual API rather than retrying.\n\n# Analytical Validation and Detection Limits\n\n**\"What is the real limit of detection of my ctDNA assay, and can I trust the number I am about to report?\"** -> Quantify the Poisson sampling ceiling, the error-suppression floor, and the LoB\u002FLoD\u002FLoQ that together define a defensible sensitivity claim.\n- Python: `scipy.stats.poisson` for detection-probability math, `scipy.stats.norm` for CLSI LoB\u002FLoD, `statsmodels` Probit\u002FLogit for a dilution-series LoD95 fit.\n\n## The Single Most Important Modern Insight -- LoD Is Set by Genome Equivalents Sampled and Error Suppression, NOT by Sequencing Depth or the Caller\n\nA ctDNA assay is a molecule-counting experiment at the Poisson edge. The mutant signal is a fixed, tiny number of physical template molecules in the tube, and the limit of detection is governed by two ceilings: how many genome equivalents were sampled (Poisson), and how low the background error floor was driven (error suppression). 1 ng of human DNA is ~330 haploid genome equivalents; the expected mutant-molecule count is lambda = input_GE x VAF. A 0.1% variant on 1,000 GE (~3.0 ng) has lambda = 1, so e^-1 ~= 37% of the time the mutant template was never in the tube and a perfect sequencer detects nothing. Past the point where every input molecule has been read once (sampling saturation, visible as a deduplication plateau in UMI families), additional read depth re-sequences the same physical molecules and adds zero information. Reporting an LoD as a bare VAF -- with no input mass, no unique-molecule (consensus) depth, no replicate detection rate -- is reporting an undefined quantity.\n\nThe second ceiling is the per-base background error rate, which sets the VAF floor independently: a 0.1% variant cannot be distinguished from noise if the assay manufactures that base at 0.1%. Error suppression is a ladder (raw NGS ~1e-3 -> single-strand UMI consensus ~1e-4\u002F1e-5 -> duplex \u003C1e-7), and single-strand consensus does NOT remove template-resident damage (C->T deamination, G->T 8-oxoG) because every PCR copy of that strand inherits the lesion -- only duplex strand-concordance catches it. The achieved LoD is the *worse* of the two ceilings: error dominates above ~0.1% VAF for tumor-naive single-locus calling, sampling dominates below it. The escape hatch is integration -- a bespoke panel summing mutant molecules across 16-50 loci against summed background reaches single-ppm even though each locus alone is ~1e-3 to 1e-4 (per-locus vs panel-integrated LoD).\n\n## Methods Landscape\n\n| Concept | Definition | Source |\n|---------|------------|--------|\n| LoB (Limit of Blank) | Highest signal expected from an analyte-free blank (95th pct): LoB = mean_blank + 1.645*SD_blank; the false-positive anchor on true negatives | CLSI EP17-A2 |\n| LoD (Limit of Detection) | Lowest level reliably distinguishable from LoB: LoD = LoB + 1.645*SD_low; a sample at LoD is detected ~95% of the time | CLSI EP17-A2 |\n| LoD95 | The concentration\u002FVAF where detection probability = 95%; a point on a probit\u002Flogistic detection curve, not a separate definition | CLSI EP17-A2; Newman 2016 |\n| LoQ (Limit of Quantitation) | Lowest level measurable with stated precision (e.g. CV\u003C=20%); LoQ >= LoD always, so a \"VAF\" near the floor is detectable but not trustworthy | CLSI EP17-A2 |\n| Per-locus LoD | Single-variant LoD; sampling- and error-limited (~0.05-0.1% VAF typical) | Newman 2014\u002F2016 |\n| Panel-integrated LoD | Evidence summed across N tracked variants via a >=k-of-N positivity rule (binomial over per-locus Poisson detection), reaching single-ppm at 16-50 loci; ~sqrt(N) variance-averaging is only a loose lower bound | Reinert 2019 |\n| Reference standards | Contrived defined-VAF cell-line admixtures fragmented to ~160 bp into normal cfDNA; SEQC2 Sample A \u002F HCC1395 truth sets | Fang 2021 (SEQC2) |\n\n## Decision Tree by Scenario\n\n| Scenario | Recommended | Why |\n|----------|-------------|-----|\n| \"How many GE for 95% detection at VAF X?\" | Solve lambda = input_GE x VAF >= 3, so input_GE >= 3\u002FVAF | 1 - e^-3 = 0.95; ~30,000 GE (~91 ng at 330 GE\u002Fng) for a single 1e-4 variant -- often more than one tube provides |\n| \"Why is more depth not helping?\" | Report unique (consensus) molecular coverage, not raw depth; check the dedup plateau | Past sampling saturation, depth re-reads the same molecules; the ceiling is GE in the tube |\n| Single hotspot vs bespoke panel for low VAF | Single locus: error\u002Fsampling-limited ~0.1%; need ppm -> integrate across 16-50 clonal loci | Per-locus Poisson\u002Ferror floor is escaped only by summing independent detections (panel-integrated LoD) |\n| Reporting an LoD | Condition on input mass (GE) + consensus depth + replicate detection rate (e.g. \"LoD95 0.1% VAF at 30 ng \u002F 2x duplex \u002F 95% of 20 replicates\") | A bare VAF omits the input mass, the unique depth, and per-locus vs integrated -- it is undefined |\n| Estimating LoD95 from a dilution series | Probit (or logistic) regression of detection (0\u002F1) on VAF; read off the 95% point with a CI | CLSI EP17-A2 detection-curve method; binary detection is a clean GLM target |\n| Distinguishing detection from quantitation | Set LoD for yes\u002Fno calls; set LoQ (CV\u003C=20%) separately for any reported VAF\u002FTF | MRD calls are binary and can sit far below LoQ; a near-floor VAF number is not quantitative |\n| Validating against truth | Contrived SEQC2 Sample A \u002F HCC1395 admixtures, fragmented to cfDNA-like ~160 bp | Real low-VAF patient material is scarce\u002Funverifiable; commutability with plasma is the caveat |\n\n## Genome-Equivalent and Poisson Detection Calculator\n\n**Goal:** Convert an input mass and target VAF into an expected mutant-molecule count and a detection probability, so a sensitivity claim is anchored to molecules rather than to a VAF alone.\n\n**Approach:** Convert ng to haploid genome equivalents (~330\u002Fng), set lambda = input_GE x VAF, and read the detection probability as a Poisson tail P(X >= k) = 1 - cdf(k-1, lambda); invert for the minimum GE that puts lambda at the >=3 sampling-detection threshold.\n\n```python\nimport numpy as np\nfrom scipy.stats import poisson\n\nGE_PER_NG = 330  # haploid ~3.3 pg -> strict 1 ng \u002F 3.3 pg = 303; 330 is the common diploid-6.6 pg\u002Frounding convention\n\ndef genome_equivalents(input_ng):\n    return input_ng * GE_PER_NG\n\ndef detection_probability(input_ng, vaf, min_mutant_molecules=1):\n    '''P(at least min_mutant_molecules present) under Poisson(lambda = GE * VAF).'''\n    lam = genome_equivalents(input_ng) * vaf\n    return float(poisson.sf(min_mutant_molecules - 1, lam))\n\ndef ge_for_sampling_detection(vaf, target_lambda=3.0):\n    '''GE needed so lambda >= 3 -> ~95% chance the mutant molecule is present at all.'''\n    return target_lambda \u002F vaf\n\n# A 0.1% variant on 3.0 ng (~990 GE) has lambda ~= 1 -> ~63% detected, ~37% missed by sampling alone.\ndetection_probability(3.0, 0.001)          # ~0.63\nge_for_sampling_detection(1e-4)            # 30000 GE (~91 ng) for a single 0.01% variant\n```\n\n## LoB and LoD95 from a Dilution Series (CLSI EP17 style)\n\n**Goal:** Estimate the VAF at which the assay detects 95% of the time, from a contrived dilution series, and anchor it to the blank-derived false-positive floor.\n\n**Approach:** Compute LoB from blank replicates (mean + 1.645*SD, one-sided 95th pct), then fit a probit GLM of binary detection on log10(VAF) (CLSI EP17 fits on log concentration) across the dilution series and invert it for the 95% detection point. The series must bracket the 0.95 crossing — all-detected upper levels cause near-complete separation and an unstable slope.\n\n```python\nimport numpy as np\nimport statsmodels.api as sm\nfrom scipy.stats import norm\n\ndef limit_of_blank(blank_signals):\n    '''LoB = mean + 1.645*SD; one-sided 95th percentile of analyte-free blanks.'''\n    blank_signals = np.asarray(blank_signals, dtype=float)\n    return blank_signals.mean() + 1.645 * blank_signals.std(ddof=1)\n\ndef lod95_probit(vaf_levels, detected):\n    '''Probit fit of detection (0\u002F1) on log10(VAF); returns the VAF where P(detect) = 0.95.'''\n    log_vaf = np.log10(np.asarray(vaf_levels, dtype=float))\n    y = np.asarray(detected, dtype=float)\n    X = sm.add_constant(log_vaf)\n    fit = sm.GLM(y, X, family=sm.families.Binomial(link=sm.families.links.Probit())).fit()\n    intercept, slope = fit.params\n    return 10 ** ((norm.ppf(0.95) - intercept) \u002F slope)\n```\n\n## Per-Locus to Panel-Integrated LoD\n\n**Goal:** Combine independent per-locus detection probabilities into the panel-level detection probability that a bespoke MRD assay actually achieves, and find the integrated LoD.\n\n**Approach:** Treat each tracked locus as an independent Poisson sampler at the same tumor VAF; a panel positive call requires at least k loci detected, so the panel detection probability is the binomial-tail over the per-locus probabilities -- this is why summing 16-50 loci reaches ppm.\n\n```python\nimport numpy as np\nfrom scipy.stats import poisson, binom\n\ndef panel_detection_probability(input_ng, vaf, n_loci, min_loci_positive=2):\n    '''P(>= min_loci_positive of n_loci detected); >=2-of-N is the Signatera-style positivity rule.'''\n    per_locus = float(poisson.sf(0, input_ng * 330 * vaf))\n    return float(binom.sf(min_loci_positive - 1, n_loci, per_locus))\n\ndef panel_integrated_lod95(input_ng, n_loci, min_loci_positive=2, grid=None):\n    '''Lowest VAF on a log grid where the >=k-of-N panel call hits 95%.'''\n    grid = np.logspace(-6, -2, 400) if grid is None else np.asarray(grid)\n    probs = [panel_detection_probability(input_ng, v, n_loci, min_loci_positive) for v in grid]\n    hits = grid[np.asarray(probs) >= 0.95]\n    return float(hits.min()) if hits.size else float('nan')\n```\n\n## Quantitative Thresholds\n\n| Threshold | Source | Rationale |\n|-----------|--------|-----------|\n| ~330 haploid genome equivalents per ng cfDNA | Standard (haploid ~3.3 pg) | Converts input mass to the molecule count that actually sets sensitivity; strict 1 ng \u002F 3.3 pg = 303, with 330 the common diploid-6.6 pg\u002Frounding convention |\n| lambda = input_GE x VAF; lambda >= 3 for ~95% sampling-detection | Poisson, 1 - e^-3 = 0.95 | Below lambda~3 the mutant template is often simply absent from the tube regardless of sequencing |\n| Raw NGS error floor ~1e-3 | Schmitt 2012 context; field consensus | Sets the per-base VAF floor before any consensus; a global VAF cutoff above this is noise-limited |\n| Single-strand UMI consensus ~1e-4 to 1e-5 | Newman 2014\u002F2016 (CAPP-Seq\u002FiDES) | Majority-vote within a UMI family erases PCR\u002Fsequencing error not shared across the family |\n| Duplex sequencing \u003C1e-7 (theory \u003C1\u002F1e9 nt) | Schmitt 2012 *PNAS* 109:14508 | Requires the variant on BOTH original strands; independent strand errors cannot agree |\n| iDES adds ~3-15x over baseline; ctDNA to ~4e-5 | Newman 2016 *Nat Biotechnol* 34:547 | Position\u002Ftrinucleotide background model subtracts stereotyped artifacts per locus |\n| ichorCNA tumor-fraction floor ~3% | Adalsteinsson 2017 *Nat Commun* 8:1324 | Copy-number-based TF estimation; sWGS\u002FULP-WGS cannot resolve TF below ~3% -- an LoD, not a VAF |\n| Bespoke panel reaches single-ppm by integrating 16-50 loci | Reinert 2019 *JAMA Oncol* 5:1124 | Per-locus ~1e-4 floor escaped by summing independent detections; >=2-of-N positivity rule |\n| LoQ >= LoD (e.g. CV\u003C=20% for quantitation) | CLSI EP17-A2 | Detection (binary) is easier than quantitation (continuous); near-floor VAFs are not trustworthy numbers |\n\n## Common Errors\n\n| Error \u002F symptom | Cause | Solution |\n|-----------------|-------|----------|\n| \"Assay detects 0.1% VAF\" with no input mass | VAF reported as a standalone sensitivity spec | Condition the LoD on input GE + consensus depth + replicate detection rate; 0.1% on 100 GE is noise |\n| Buying more sequencing depth to improve sensitivity | Conflating read depth with molecule count | Past the dedup plateau the assay is sampling-saturated; add plasma volume \u002F conversion efficiency, not depth |\n| Per-locus LoD quoted as the panel LoD (or vice versa) | Ignoring integration across tracked loci | State which is reported; a 50-variant panel's integrated LoD is orders of magnitude below any single locus |\n| VAF used as the sensitivity unit | Omitting the molecule count behind the fraction | Pair every VAF with input GE; lambda = GE x VAF is the quantity that determines detection |\n| Single-strand UMI assumed to remove damage artifacts | Template-resident C->T\u002FG->T inherited by every copy | Use duplex strand-concordance for sub-1e-5 claims; single-strand votes unanimously for the lesion |\n| Reporting a near-floor VAF as a measured value | Confusing LoD (detect) with LoQ (quantify) | Quantitative VAF\u002FTF only at\u002Fabove LoQ (CV\u003C=20%); below it report detected\u002Fnot-detected |\n| Global VAF cutoff across all loci | Background error is position\u002Fcontext-dependent | Use a per-locus background model (iDES-style); a flat threshold loses sensitivity and specificity |\n\n## References\n\n- Diehl F, Schmidt K, Choti MA, et al. 2008. Circulating mutant DNA to assess tumor dynamics. *Nat Med* 14:985-990. -- ctDNA half-life ~114 min; molecule-counting framing of tumor dynamics.\n- Schmitt MW, Kennedy SR, Salk JJ, et al. 2012. Detection of ultra-rare mutations by next-generation sequencing. *PNAS* 109:14508-14513. -- Duplex sequencing; theoretical error floor \u003C1 per 1e9 nt.\n- Newman AM, Bratman SV, To J, et al. 2014. An ultrasensitive method for quantitating circulating tumor DNA with broad patient coverage. *Nat Med* 20:548-554. -- CAPP-Seq; UMI-consensus error suppression.\n- Newman AM, Lovejoy AF, Klass DM, et al. 2016. Integrated digital error suppression for improved detection of circulating tumor DNA. *Nat Biotechnol* 34:547-555. -- iDES; ~3-15x gain; ctDNA to ~4e-5.\n- Razavi P, Li BT, Brown DN, et al. 2019. High-intensity sequencing reveals the sources of plasma circulating cell-free DNA variants. *Nat Med* 25:1928-1937. -- CHIP as the dominant non-tumor signal in the LoB blank.\n- Adalsteinsson VA, Ha G, Freeman SS, et al. 2017. Scalable whole-exome sequencing of cell-free DNA reveals high concordance with metastatic tumors. *Nat Commun* 8:1324. -- ichorCNA; copy-number tumor-fraction floor ~3%.\n- Reinert T, Henriksen TV, Christensen E, et al. 2019. Analysis of plasma cell-free DNA by ultradeep sequencing in patients with stages I to III colorectal cancer. *JAMA Oncol* 5:1124-1131. -- Signatera; 16-variant integration; >=2-of-N positivity.\n- Fang LT, Zhu B, Zhao Y, et al.; SEQC2 Consortium. 2021. Establishing community reference samples, data and call sets for benchmarking cancer mutation detection using whole-genome sequencing. *Nat Biotechnol* 39:1151-1160. -- SEQC2 Sample A \u002F HCC1395 contrived reference standards.\n- CLSI EP17-A2. 2012. Evaluation of Detection Capability for Clinical Laboratory Measurement Procedures; Approved Guideline -- Second Edition. Clinical and Laboratory Standards Institute. -- Governing LoB\u002FLoD\u002FLoQ definitions.\n\n## Related Skills\n\n- ctdna-mutation-detection - applies these limits to low-VAF somatic calls\n- longitudinal-monitoring - per-timepoint LoD and left-censoring of undetectable samples\n- tumor-fraction-estimation - the ~3% CNA-based detection floor as an LoD\n- experimental-design\u002Fmultiple-testing - repeated-surveillance specificity and FDR\n- clinical-biostatistics\u002Fpower-and-sample-size - validation-study design\n","## Version Compatibility\n\nReference examples tested with: numpy 1.26+, scipy 1.12+, statsmodels 0.14+\n\nBefore using code patterns, verify installed versions match. If versions differ:\n- Python: `pip show \u003Cpackage>` then `help(module.function)` to check signatures\n\nIf code throws ImportError, AttributeError, or TypeError, introspect the installed\npackage and adapt the example to match the actual API rather than retrying.\n\n# Analytical Validation and Detection Limits\n\n**\"What is the real limit of detection of my ctDNA assay, and can I trust the number I am about to report?\"** -> Quantify the Poisson sampling ceiling, the error-suppression floor, and the LoB\u002FLoD\u002FLoQ that together define a defensible sensitivity claim.\n- Python: `scipy.stats.poisson` for detection-probability math, `scipy.stats.norm` for CLSI LoB\u002FLoD, `statsmodels` Probit\u002FLogit for a dilution-series LoD95 fit.\n\n## The Single Most Important Modern Insight -- LoD Is Set by Genome Equivalents Sampled and Error Suppression, NOT by Sequencing Depth or the Caller\n\nA ctDNA assay is a molecule-counting experiment at the Poisson edge. The mutant signal is a fixed, tiny number of physical template molecules in the tube, and the limit of detection is governed by two ceilings: how many genome equivalents were sampled (Poisson), and how low the background error floor was driven (error suppression). 1 ng of human DNA is ~330 haploid genome equivalents; the expected mutant-molecule count is lambda = input_GE x VAF. A 0.1% variant on 1,000 GE (~3.0 ng) has lambda = 1, so e^-1 ~= 37% of the time the mutant template was never in the tube and a perfect sequencer detects nothing. Past the point where every input molecule has been read once (sampling saturation, visible as a deduplication plateau in UMI families), additional read depth re-sequences the same physical molecules and adds zero information. Reporting an LoD as a bare VAF -- with no input mass, no unique-molecule (consensus) depth, no replicate detection rate -- is reporting an undefined quantity.\n\nThe second ceiling is the per-base background error rate, which sets the VAF floor independently: a 0.1% variant cannot be distinguished from noise if the assay manufactures that base at 0.1%. Error suppression is a ladder (raw NGS ~1e-3 -> single-strand UMI consensus ~1e-4\u002F1e-5 -> duplex \u003C1e-7), and single-strand consensus does NOT remove template-resident damage (C->T deamination, G->T 8-oxoG) because every PCR copy of that strand inherits the lesion -- only duplex strand-concordance catches it. The achieved LoD is the *worse* of the two ceilings: error dominates above ~0.1% VAF for tumor-naive single-locus calling, sampling dominates below it. The escape hatch is integration -- a bespoke panel summing mutant molecules across 16-50 loci against summed background reaches single-ppm even though each locus alone is ~1e-3 to 1e-4 (per-locus vs panel-integrated LoD).\n\n## Methods Landscape\n\n| Concept | Definition | Source |\n|---------|------------|--------|\n| LoB (Limit of Blank) | Highest signal expected from an analyte-free blank (95th pct): LoB = mean_blank + 1.645*SD_blank; the false-positive anchor on true negatives | CLSI EP17-A2 |\n| LoD (Limit of Detection) | Lowest level reliably distinguishable from LoB: LoD = LoB + 1.645*SD_low; a sample at LoD is detected ~95% of the time | CLSI EP17-A2 |\n| LoD95 | The concentration\u002FVAF where detection probability = 95%; a point on a probit\u002Flogistic detection curve, not a separate definition | CLSI EP17-A2; Newman 2016 |\n| LoQ (Limit of Quantitation) | Lowest level measurable with stated precision (e.g. CV\u003C=20%); LoQ >= LoD always, so a \"VAF\" near the floor is detectable but not trustworthy | CLSI EP17-A2 |\n| Per-locus LoD | Single-variant LoD; sampling- and error-limited (~0.05-0.1% VAF typical) | Newman 2014\u002F2016 |\n| Panel-integrated LoD | Evidence summed across N tracked variants via a >=k-of-N positivity rule (binomial over per-locus Poisson detection), reaching single-ppm at 16-50 loci; ~sqrt(N) variance-averaging is only a loose lower bound | Reinert 2019 |\n| Reference standards | Contrived defined-VAF cell-line admixtures fragmented to ~160 bp into normal cfDNA; SEQC2 Sample A \u002F HCC1395 truth sets | Fang 2021 (SEQC2) |\n\n## Decision Tree by Scenario\n\n| Scenario | Recommended | Why |\n|----------|-------------|-----|\n| \"How many GE for 95% detection at VAF X?\" | Solve lambda = input_GE x VAF >= 3, so input_GE >= 3\u002FVAF | 1 - e^-3 = 0.95; ~30,000 GE (~91 ng at 330 GE\u002Fng) for a single 1e-4 variant -- often more than one tube provides |\n| \"Why is more depth not helping?\" | Report unique (consensus) molecular coverage, not raw depth; check the dedup plateau | Past sampling saturation, depth re-reads the same molecules; the ceiling is GE in the tube |\n| Single hotspot vs bespoke panel for low VAF | Single locus: error\u002Fsampling-limited ~0.1%; need ppm -> integrate across 16-50 clonal loci | Per-locus Poisson\u002Ferror floor is escaped only by summing independent detections (panel-integrated LoD) |\n| Reporting an LoD | Condition on input mass (GE) + consensus depth + replicate detection rate (e.g. \"LoD95 0.1% VAF at 30 ng \u002F 2x duplex \u002F 95% of 20 replicates\") | A bare VAF omits the input mass, the unique depth, and per-locus vs integrated -- it is undefined |\n| Estimating LoD95 from a dilution series | Probit (or logistic) regression of detection (0\u002F1) on VAF; read off the 95% point with a CI | CLSI EP17-A2 detection-curve method; binary detection is a clean GLM target |\n| Distinguishing detection from quantitation | Set LoD for yes\u002Fno calls; set LoQ (CV\u003C=20%) separately for any reported VAF\u002FTF | MRD calls are binary and can sit far below LoQ; a near-floor VAF number is not quantitative |\n| Validating against truth | Contrived SEQC2 Sample A \u002F HCC1395 admixtures, fragmented to cfDNA-like ~160 bp | Real low-VAF patient material is scarce\u002Funverifiable; commutability with plasma is the caveat |\n\n## Genome-Equivalent and Poisson Detection Calculator\n\n**Goal:** Convert an input mass and target VAF into an expected mutant-molecule count and a detection probability, so a sensitivity claim is anchored to molecules rather than to a VAF alone.\n\n**Approach:** Convert ng to haploid genome equivalents (~330\u002Fng), set lambda = input_GE x VAF, and read the detection probability as a Poisson tail P(X >= k) = 1 - cdf(k-1, lambda); invert for the minimum GE that puts lambda at the >=3 sampling-detection threshold.\n\n```python\nimport numpy as np\nfrom scipy.stats import poisson\n\nGE_PER_NG = 330  # haploid ~3.3 pg -> strict 1 ng \u002F 3.3 pg = 303; 330 is the common diploid-6.6 pg\u002Frounding convention\n\ndef genome_equivalents(input_ng):\n    return input_ng * GE_PER_NG\n\ndef detection_probability(input_ng, vaf, min_mutant_molecules=1):\n    '''P(at least min_mutant_molecules present) under Poisson(lambda = GE * VAF).'''\n    lam = genome_equivalents(input_ng) * vaf\n    return float(poisson.sf(min_mutant_molecules - 1, lam))\n\ndef ge_for_sampling_detection(vaf, target_lambda=3.0):\n    '''GE needed so lambda >= 3 -> ~95% chance the mutant molecule is present at all.'''\n    return target_lambda \u002F vaf\n\n# A 0.1% variant on 3.0 ng (~990 GE) has lambda ~= 1 -> ~63% detected, ~37% missed by sampling alone.\ndetection_probability(3.0, 0.001)          # ~0.63\nge_for_sampling_detection(1e-4)            # 30000 GE (~91 ng) for a single 0.01% variant\n```\n\n## LoB and LoD95 from a Dilution Series (CLSI EP17 style)\n\n**Goal:** Estimate the VAF at which the assay detects 95% of the time, from a contrived dilution series, and anchor it to the blank-derived false-positive floor.\n\n**Approach:** Compute LoB from blank replicates (mean + 1.645*SD, one-sided 95th pct), then fit a probit GLM of binary detection on log10(VAF) (CLSI EP17 fits on log concentration) across the dilution series and invert it for the 95% detection point. The series must bracket the 0.95 crossing — all-detected upper levels cause near-complete separation and an unstable slope.\n\n```python\nimport numpy as np\nimport statsmodels.api as sm\nfrom scipy.stats import norm\n\ndef limit_of_blank(blank_signals):\n    '''LoB = mean + 1.645*SD; one-sided 95th percentile of analyte-free blanks.'''\n    blank_signals = np.asarray(blank_signals, dtype=float)\n    return blank_signals.mean() + 1.645 * blank_signals.std(ddof=1)\n\ndef lod95_probit(vaf_levels, detected):\n    '''Probit fit of detection (0\u002F1) on log10(VAF); returns the VAF where P(detect) = 0.95.'''\n    log_vaf = np.log10(np.asarray(vaf_levels, dtype=float))\n    y = np.asarray(detected, dtype=float)\n    X = sm.add_constant(log_vaf)\n    fit = sm.GLM(y, X, family=sm.families.Binomial(link=sm.families.links.Probit())).fit()\n    intercept, slope = fit.params\n    return 10 ** ((norm.ppf(0.95) - intercept) \u002F slope)\n```\n\n## Per-Locus to Panel-Integrated LoD\n\n**Goal:** Combine independent per-locus detection probabilities into the panel-level detection probability that a bespoke MRD assay actually achieves, and find the integrated LoD.\n\n**Approach:** Treat each tracked locus as an independent Poisson sampler at the same tumor VAF; a panel positive call requires at least k loci detected, so the panel detection probability is the binomial-tail over the per-locus probabilities -- this is why summing 16-50 loci reaches ppm.\n\n```python\nimport numpy as np\nfrom scipy.stats import poisson, binom\n\ndef panel_detection_probability(input_ng, vaf, n_loci, min_loci_positive=2):\n    '''P(>= min_loci_positive of n_loci detected); >=2-of-N is the Signatera-style positivity rule.'''\n    per_locus = float(poisson.sf(0, input_ng * 330 * vaf))\n    return float(binom.sf(min_loci_positive - 1, n_loci, per_locus))\n\ndef panel_integrated_lod95(input_ng, n_loci, min_loci_positive=2, grid=None):\n    '''Lowest VAF on a log grid where the >=k-of-N panel call hits 95%.'''\n    grid = np.logspace(-6, -2, 400) if grid is None else np.asarray(grid)\n    probs = [panel_detection_probability(input_ng, v, n_loci, min_loci_positive) for v in grid]\n    hits = grid[np.asarray(probs) >= 0.95]\n    return float(hits.min()) if hits.size else float('nan')\n```\n\n## Quantitative Thresholds\n\n| Threshold | Source | Rationale |\n|-----------|--------|-----------|\n| ~330 haploid genome equivalents per ng cfDNA | Standard (haploid ~3.3 pg) | Converts input mass to the molecule count that actually sets sensitivity; strict 1 ng \u002F 3.3 pg = 303, with 330 the common diploid-6.6 pg\u002Frounding convention |\n| lambda = input_GE x VAF; lambda >= 3 for ~95% sampling-detection | Poisson, 1 - e^-3 = 0.95 | Below lambda~3 the mutant template is often simply absent from the tube regardless of sequencing |\n| Raw NGS error floor ~1e-3 | Schmitt 2012 context; field consensus | Sets the per-base VAF floor before any consensus; a global VAF cutoff above this is noise-limited |\n| Single-strand UMI consensus ~1e-4 to 1e-5 | Newman 2014\u002F2016 (CAPP-Seq\u002FiDES) | Majority-vote within a UMI family erases PCR\u002Fsequencing error not shared across the family |\n| Duplex sequencing \u003C1e-7 (theory \u003C1\u002F1e9 nt) | Schmitt 2012 *PNAS* 109:14508 | Requires the variant on BOTH original strands; independent strand errors cannot agree |\n| iDES adds ~3-15x over baseline; ctDNA to ~4e-5 | Newman 2016 *Nat Biotechnol* 34:547 | Position\u002Ftrinucleotide background model subtracts stereotyped artifacts per locus |\n| ichorCNA tumor-fraction floor ~3% | Adalsteinsson 2017 *Nat Commun* 8:1324 | Copy-number-based TF estimation; sWGS\u002FULP-WGS cannot resolve TF below ~3% -- an LoD, not a VAF |\n| Bespoke panel reaches single-ppm by integrating 16-50 loci | Reinert 2019 *JAMA Oncol* 5:1124 | Per-locus ~1e-4 floor escaped by summing independent detections; >=2-of-N positivity rule |\n| LoQ >= LoD (e.g. CV\u003C=20% for quantitation) | CLSI EP17-A2 | Detection (binary) is easier than quantitation (continuous); near-floor VAFs are not trustworthy numbers |\n\n## Common Errors\n\n| Error \u002F symptom | Cause | Solution |\n|-----------------|-------|----------|\n| \"Assay detects 0.1% VAF\" with no input mass | VAF reported as a standalone sensitivity spec | Condition the LoD on input GE + consensus depth + replicate detection rate; 0.1% on 100 GE is noise |\n| Buying more sequencing depth to improve sensitivity | Conflating read depth with molecule count | Past the dedup plateau the assay is sampling-saturated; add plasma volume \u002F conversion efficiency, not depth |\n| Per-locus LoD quoted as the panel LoD (or vice versa) | Ignoring integration across tracked loci | State which is reported; a 50-variant panel's integrated LoD is orders of magnitude below any single locus |\n| VAF used as the sensitivity unit | Omitting the molecule count behind the fraction | Pair every VAF with input GE; lambda = GE x VAF is the quantity that determines detection |\n| Single-strand UMI assumed to remove damage artifacts | Template-resident C->T\u002FG->T inherited by every copy | Use duplex strand-concordance for sub-1e-5 claims; single-strand votes unanimously for the lesion |\n| Reporting a near-floor VAF as a measured value | Confusing LoD (detect) with LoQ (quantify) | Quantitative VAF\u002FTF only at\u002Fabove LoQ (CV\u003C=20%); below it report detected\u002Fnot-detected |\n| Global VAF cutoff across all loci | Background error is position\u002Fcontext-dependent | Use a per-locus background model (iDES-style); a flat threshold loses sensitivity and specificity |\n\n## References\n\n- Diehl F, Schmidt K, Choti MA, et al. 2008. Circulating mutant DNA to assess tumor dynamics. *Nat Med* 14:985-990. -- ctDNA half-life ~114 min; molecule-counting framing of tumor dynamics.\n- Schmitt MW, Kennedy SR, Salk JJ, et al. 2012. Detection of ultra-rare mutations by next-generation sequencing. *PNAS* 109:14508-14513. -- Duplex sequencing; theoretical error floor \u003C1 per 1e9 nt.\n- Newman AM, Bratman SV, To J, et al. 2014. An ultrasensitive method for quantitating circulating tumor DNA with broad patient coverage. *Nat Med* 20:548-554. -- CAPP-Seq; UMI-consensus error suppression.\n- Newman AM, Lovejoy AF, Klass DM, et al. 2016. Integrated digital error suppression for improved detection of circulating tumor DNA. *Nat Biotechnol* 34:547-555. -- iDES; ~3-15x gain; ctDNA to ~4e-5.\n- Razavi P, Li BT, Brown DN, et al. 2019. High-intensity sequencing reveals the sources of plasma circulating cell-free DNA variants. *Nat Med* 25:1928-1937. -- CHIP as the dominant non-tumor signal in the LoB blank.\n- Adalsteinsson VA, Ha G, Freeman SS, et al. 2017. Scalable whole-exome sequencing of cell-free DNA reveals high concordance with metastatic tumors. *Nat Commun* 8:1324. -- ichorCNA; copy-number tumor-fraction floor ~3%.\n- Reinert T, Henriksen TV, Christensen E, et al. 2019. Analysis of plasma cell-free DNA by ultradeep sequencing in patients with stages I to III colorectal cancer. *JAMA Oncol* 5:1124-1131. -- Signatera; 16-variant integration; >=2-of-N positivity.\n- Fang LT, Zhu B, Zhao Y, et al.; SEQC2 Consortium. 2021. Establishing community reference samples, data and call sets for benchmarking cancer mutation detection using whole-genome sequencing. *Nat Biotechnol* 39:1151-1160. -- SEQC2 Sample A \u002F HCC1395 contrived reference standards.\n- CLSI EP17-A2. 2012. Evaluation of Detection Capability for Clinical Laboratory Measurement Procedures; Approved Guideline -- Second Edition. Clinical and Laboratory Standards Institute. -- Governing LoB\u002FLoD\u002FLoQ definitions.\n\n## Related Skills\n\n- ctdna-mutation-detection - applies these limits to low-VAF somatic calls\n- longitudinal-monitoring - per-timepoint LoD and left-censoring of undetectable samples\n- tumor-fraction-estimation - the ~3% CNA-based detection floor as an LoD\n- experimental-design\u002Fmultiple-testing - repeated-surveillance specificity and FDR\n- clinical-biostatistics\u002Fpower-and-sample-size - validation-study design\n",{"name":5,"source":24,"license":15,"tool_type":25,"description":7,"imported_at":26,"source_path":27,"primary_tool":28,"source_repository":29},"https:\u002F\u002Fgithub.com\u002FGPTomics\u002FbioSkills","python","2026-09-20","liquid-biopsy\u002Fanalytical-validation\u002FSKILL.md","scipy","GPTomics\u002FbioSkills","main","2d1750717747097b602acf30bd09a7cbd4b4c6ea","awesome_skills\u002Fbiology\u002Fbio-analytical-validation","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous","2026-11-09 11:45:36",{"source":8,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-analytical-validation",{"tool":42,"command":43},"bunx","bunx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-analytical-validation",{"tool":45,"command":46},"pnpm","pnpm dlx skills add Mr-Nobody-Anonymous\u002FAll-skills --skill bio-analytical-validation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-analytical-validation\u002FSKILL.md",true,[50,56],{"path":51,"resourceType":52,"resourceTypeDesc":53,"sizeBytes":54,"sourceHtmlUrl":55},"examples\u002Fdetection_limits.py","SCRIPT","脚本",4075,"https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-analytical-validation\u002Fexamples\u002Fdetection_limits.py",{"path":57,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":61},"usage-guide.md","REFERENCE","参考文档",3796,"https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fbiology\u002Fbio-analytical-validation\u002Fusage-guide.md",[63,71,78,85,92,99],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":70},"01M7EXRQF9GFM7D9BG6N5HAT34","oath","Auditing regulatory compliance (SOC2\u002FPCI-DSS\u002FHIPAA\u002FISO 27001): maps requirements, checks controls, designs audit trails, implements Policy as Code. Use when compliance auditing is needed.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Foath\u002FSKILL.md",[],[],"2026-11-15 14:25:24",{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M7EXRH7TYTNZJT0BQXEWAMW7","nexus","Orchestrating multi-specialist task chains and scope-adaptive product delivery: classifies intent, selects and executes the minimum viable chain, aggregates results, and verifies acceptance criteria. For multi-domain tasks, build-first delivery, and product lifecycle execution.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnexus\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M7EXRCDPFWVEEEFR2ZQGJCYY","nest","Designing LLM-optimized folder structures: audits and restructures directories for context efficiency, progressive disclosure, and prompt cache performance. Not for general repo structure (Grove).","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnest\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":19},"01M7EXR7JEER60TH0HD0AH4EE9","native","Implementing production iOS\u002FAndroid\u002FmacOS native features (SwiftUI, Compose) and iterating a screen against a reference design. Not for cross-platform RN\u002FFlutter (Port) or web (Artisan).","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fnative\u002FSKILL.md",[],[],{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":98,"publishedAt":19},"01M7EXR133J7DD5961R80QTRZY","muse","Defining and managing design tokens, applying token systems to existing codebases, building design system foundations. Use for spacing, color, typography, dark mode, cross-platform output.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fmuse\u002FSKILL.md",[],[],{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":19},"01M7EXQWWX7ECQN0J50B41YN5N","morph","Converting document formats (Markdown\u002FWord\u002FExcel\u002FPDF\u002FHTML) and generating reusable conversion scripts. Use for distributable specs, accessibility-compliant PDFs, or Pandoc\u002FLibreOffice pipelines.","https:\u002F\u002Fgithub.com\u002FMr-Nobody-Anonymous\u002FAll-skills\u002Fblob\u002Fmain\u002Fawesome_skills\u002Fdevsecops\u002Fmorph\u002FSKILL.md",[],[]]