migec 2.2.1 — the ctDNA ground truth was found, not built
The wheel is unchanged from 2.2.0. No command, flag, output file or number that migec itself
produces is different. Everything in this release is in the repository: a new documentation page,
the SLURM templates, the Nextflow downstream layer, two more notebooks, and the two scripts behind
them.
The ctDNA ground truth was found, not built
ROADMAP.md item 7 said a ctDNA ground truth had to be constructed, because the runs used by the
published UMI-aware caller benchmark carry no UMI. That is true of those two runs and not of the
archive. Screening SRA read structure instead turned up two studies that kept a real 12 nt inline
UMI — one that migec suggest recovers from base composition alone, with no knowledge of the
protocol:
| study | what it is |
|---|---|
PRJNA788522 |
72 runs, cell-free DNA reference material at certified 0 / 0.125 / 0.25 / 1% VAF, crossed with 5/20/80 ng input and 3.3/10/30x depth, three replicates |
PRJNA507366 |
28 runs, six polymerases on the same material, plus 0.031% and 0.0625% VAF |
Run over all 100 (scripts/ctdna_titration.py): at 0.125% VAF the input mass decides the
outcome, not the caller.
| input | depth | molecules at the site | variant molecules | P(at least 3 copies) |
|---|---|---|---|---|
| 5 ng | 3.3x | 2,699 | 3.4 | 0.65 |
| 5 ng | 10x | 4,530 | 5.7 | 0.89 |
| 20 ng | 3.3x | 7,162 | 9.0 | 0.99 |
| 20 ng | 10x | 11,961 | 15.0 | 1.00 |
At 5 ng a 0.125% variant is a coin flip and no caller fixes it — a third of replicates simply do
not contain three copies of it. The WT arms are 33 runs and 6.1 M molecules in which the truth is
zero, which is a false-positive floor measured on real chemistry rather than on a simulation.
The barcode error rate tracks polymerase fidelity
PRJNA507366 varies the polymerase while holding template and protocol fixed, which makes it an
independent check on refine's barcode-error estimate. It separates the high-fidelity enzymes from
the standard ones by 3 Phred, a factor of two — Accuprime, Platinum and Phusion at Q30.8–31.4
against Platinum HiFi at Q34.0 and Platinum SuperFi at Q34.8–35.1 — from the barcodes alone, with
no reference, no alignment and no knowledge of which enzyme it was reading.
Also in this release
docs/variants.rst— which variant caller, and the molecule count that decides whether any
of them can see it. Standard callers (Mutect2, LoFreq, FreeBayes, VarDict) compose with migec;
UMI-aware ones (UMI-VarCal, UMIErrorCorrect) replace a stage. Never set a family-size filter
afterassemble: every family has size 1 by construction, so--min-family-size 3discards the
entire library and reports zero variants without an error.integrations/slurm/— two sbatch templates and a sample sheet. Both run as ordinary bash
without SLURM, which is how they are tested and how a layout should be checked before a cohort is
queued.integrations/nextflow/— a runnable entry point (--mode consensus | ctdna | airr) and a
downstream layer (align, call variants, arda). The align module exits non-zero ifMI:Z:does
not reach the BAM, because that failure is otherwise silent.scripts/sra_fetch.py— fetch benchmark runs on demand instead of mirroring them. NCBI S3 is
33x faster than ENA here (6.7 MB/s on 8 connections against 200 kB/s), and some runs list their
original submitted file ahead of the.sra, sofasterq-dumpgets handed a gzipped FASTQ
unless you select on the file type.notebooks/—exome_capture.py,airr_repertoire.pyand a README. The PEP 723 headers
were under-declared: altair renders a polars frame through pyarrow and then pandas, so a clean
machine failed three imports deep with an error naming neither.
Corrected
"Sequencing deeper buys reads, not molecules" was wrong, and the data says so. The same 20 ng
library gives 6,310 / 10,299 / 16,809 molecules per amplicon at 3.3 / 10 / 30x — depth buys
molecules up to the input ceiling, past which it only raises reads per molecule.
Verified
bash setup.sh from a clean venv, ruff, 217 pytest, ctest and sphinx-build -W all clean; the
SLURM templates were run end to end. Nextflow was not run — it is not installed on the machine
this was written on — so those modules are reviewed against the nf-core module spec rather than
verified by a pipeline run.
Install: pip install migec or uv pip install migec. Wheels for CPython 3.10–3.13 on Linux
x86-64 and macOS arm64.