You re-run a model from a 2018 paper in ADMIXTOOLS 2. The weights land close, the p-value does not, and the forum thread you consult contains one person shouting "broken" and another shouting "user error". Usually it is neither: the two implementations make different default choices at three specific points, each documented, each reproducible. This is the map of those points — what actually differs, what does not, and the settings that make the new software speak the old one's dialect when a comparison demands it.
What does not differ#
The method. ADMIXTOOLS 2 was validated against the classic programs as part of its publication — same estimators, same f-statistic identities, same block jackknife, agreeing results on shared inputs under matched settings. The rewrite's contributions are speed (precomputed f2-statistics turn thousand-model screens from cluster jobs into laptop sessions), an R interface replacing parameter files, and diagnostics the originals never printed — per-statistic SNP counts, weight covariances, the nested-model tables. Nobody chooses between them for correctness; you choose for workflow, and translate settings when numbers must line up.
Difference one: what "allsnps" means#
Both offer an allsnps mode; they do not mean the same thing by it. Classic qpAdm with
allsnps: YES computes each f4-statistic on all sites available for that statistic's four
populations. ADMIXTOOLS 2 matches that only when given the genotype prefix directly with
allsnps = TRUE — its precomputed-f2 route restricts everything to sites shared across all
populations in the extraction, a stricter set no classic mode uses. On complete data the routes
converge; on real ancient panels (the missingness table)
they diverge hard. A published classic run compared against an f2-cache rerun differs by
construction, before anyone errs.
Difference two: fudge_twice#
Both implementations stabilise the covariance inversion with a small ridge
("fudge"); a subtle implementation detail means the
original effectively applies the adjustment in a way the rewrite reproduces only with
fudge_twice = TRUE. The weights barely notice; the p-value — the number everyone
compares — can. It is off by default, so an ADMIXTOOLS 2 rerun of a classic table with everything
else matched can still show p drift traceable to this one flag.
Difference three: the input pipeline itself#
Classic runs consumed EIGENSTRAT files fresh each run; ADMIXTOOLS 2 workflows usually flow
through extract_f2 directories with their own maxmiss filtering — so the site set entering
the mathematics differs between a naive old run and a naive new run even before semantics.
Add the encoding of your own merged sample and any panel-version gap (a 2018 paper's AADR
predates today's — labels move between releases)
and most "discrepancies" dissolve into inventory, not mystery.
The reproduction recipe#
To match a classic result in ADMIXTOOLS 2, in order: same AADR release and population labels;
genotype-prefix input, allsnps = TRUE; fudge_twice = TRUE; default jackknife (5 cM), no
bootstrap, unconstrained; then expect agreement to rounding on weights and closely on p. Residual
daylight after all that is almost always the site set — print the per-statistic SNP counts and
compare against the paper's, if it reported any (many did not, which is its own lesson —
reporting standards exist for this exact reason).
The inverse discipline also matters: when not reproducing, do not cargo-cult classic settings. The rewrite's defaults are fine choices for fresh work; what they are not is interchangeable mid-project. Pick the regime, write it in the methods block, hold it — the rule every parameter on this list shares. And if what you actually want is the model without the archaeology of settings, the analysis service runs one declared regime across every order for exactly this reason: numbers that compare because nothing under them moved.
Terms used here are defined in the glossary.
References#
- Maier, R. et al. (2023). On the limits of fitting complex models of population history to f-statistics. eLife, 12, e85492. (ADMIXTOOLS 2 and its validation against classic.)
- Patterson, N. et al. (2012). Ancient admixture in human history. Genetics, 192(3), 1065–1093. (Classic ADMIXTOOLS.)
- Haak, W. et al. (2015). Massive migration from the steppe was a source for Indo-European languages in Europe. Nature, 522, 207–211. (The original qpAdm supplement.)
- ADMIXTOOLS 2 documentation: qpadm(), extract_f2() and the classic-comparison notes.



