Skip to content

v0.2.0 — genomic selection

Choose a tag to compare

@musharna musharna released this 30 Jul 00:33
6065542

Genomic selection, gated on measured founder linkage disequilibrium.

Added

selection_method="genomic" on run_program and compare_programs — RRBLUP fitted to marker genotypes each cycle, selection on the estimated breeding value. found_population gains n_snp_per_chr for the SNP chip, which is a founding decision because the markers must exist before anything can be predicted from them.

Setting the two arms of compare_programs to different methods makes "is genotyping worth it on these founders?" a single paired call — a contrast that needs pairing more than most, since the gap between methods is routinely smaller than the sd 0.247 of seed-to-seed noise.

The trap this release exists to surface

Markers predict a trait only through linkage disequilibrium with the causal loci. Measured on AlphaSimR 2.1.0:

generator adjacent |r| distant pairs ratio out-of-sample accuracy
quickHaplo 0.0444 0.0462 0.96 0.097
runMacs 0.1979 0.0495 4.00 0.351

quickHaplo samples haplotypes with no coalescent history, so adjacent markers are indistinguishable from unlinked ones and there is nothing to learn from. It is also the default generator and the only reproducible one — so on this engine, reproducibility and genomic realism cannot currently be had at the same time. Every genotyped founding now returns a measured linkage_disequilibrium block, with a no_linkage_disequilibrium warning when the markers are uninformative.

Why the guard measures LD rather than accuracy

At 20 replicates, a population with an LD ratio of 1.00 reached prediction accuracy 0.208 by cycle three, beating a genuinely linked population at the same selection intensity. Out-of-sample accuracy in a closed population conflates linkage with plain relatedness — as descendants of a few parents fill it, markers predict by tracking pedigree. An accuracy threshold would pass exactly the case it claimed to catch.

Accuracy is reported per cycle, measured out-of-sample on progeny the model never saw. Scoring it in-sample read 0.448 where the truth was 0.097.

Verification

57 tests against real AlphaSimR on Python 3.11/3.12/3.13, and 20 mutation checks all confirmed red (docs/MUTATION-CHECKS.md).

Full changelog: https://github.com/musharna/breedsim-mcp/blob/master/CHANGELOG.md