Skip to content

Genotype population priors: Genotype.sample(...) - #6

Merged
MuteJester merged 6 commits into
masterfrom
genotype-population-priors
Jun 17, 2026
Merged

Genotype population priors: Genotype.sample(...)#6
MuteJester merged 6 commits into
masterfrom
genotype-population-priors

Conversation

@MuteJester

Copy link
Copy Markdown
Owner

Summary

Follow-on #1 to the merged genotype foundation. Adds Genotype.sample(cfg, …) — draw a fully-specified diploid genotype from population priors instead of specifying every gene by hand.

  • Model: independent per-gene, per-chromosome Hardy-Weinberg draw — each gene on each chromosome is independently deleted (haplotype_deletion_prob) or assigned an allele from that gene's frequencies; homozygous/heterozygous/hemizygous/deleted emerge at the expected rates. Deterministic (seed).
  • Honest scope: NOT a population haplotype model (no LD, co-deletion blocks, ancestry, donor haplotype structure); catalogue alleles only (no novel); deletion only (no duplication). Documented as such.
  • Frequencies: uniform-within-gene default (deliberately not the cartridge's recombination allele_usage); opt-in allele_frequencies="usage_as_prior"; segment-aware {segment:{gene:{allele:weight}}} (+ flat {gene:…} when unambiguous); zero weight excludes an allele; full name/weight validation.
  • Deletion: float or per-gene/per-segment dict, validated to [0,1].
  • Always runnable: segments_to_sample must cover required segments (no half-specified genotypes); ensure_viable=True (default) re-draws deterministically up to max_resamples until a complete haplotype exists, else a clear ValueError; ensure_viable=False opt-out.
  • Docs: new "Sampling from population priors" guide section (with honesty note); removed from Limitations. All 11 doc examples execute against the live API.

Test plan

  • CI: full Rust + Python matrix green
  • 55 genotype tests (determinism, HW-rate bias, zero-weight exclusion, deletion shapes, viability, truth-call end-to-end). Full local Python suite: 2369 passed. mkdocs --strict clean. No engine/Rust changes.

…ht viability, conditioned-HW docs

- Fully validate allele_frequencies (nested + flat): unknown segment/gene/allele,
  non-Mapping / None / empty gene values, and usage_as_prior genes absent from the
  catalogue now raise instead of being silently ignored. (High)
- Zero-weight chromosomes are never expressed: Genotype._is_viable requires a
  positive-weight complete haplotype, and the engine's SampleGenotypePass excludes
  zero-weight chromosomes from the viable set (no silent fall-back to a 0-weight
  chromosome). (High)
- Docs: state that default ensure_viable=True yields HW *conditioned on viability*,
  not unconditional HW; tests pin conditioned vs unconditioned.
- segments_to_sample rejects duplicates and is canonicalized to V/D/J order
  (order-invariant results).
- Resample sub-seeds derived from a base RNG (no collision with seed+1).
- Mapping checks at every layer -> clean ValueErrors (no leaked TypeError/AttributeError).
- Perf: compute the cartridge content hash once and reuse across draws (no manifest
  recompute per resample).
@MuteJester
MuteJester merged commit 0420f3b into master Jun 17, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant