Skip to content

Support per-source recombination rates in matching - #1208

Merged
jeromekelleher merged 3 commits into
tskit-dev:mainfrom
jeromekelleher:add-recomb-map
Oct 28, 2026
Merged

jeromekelleher merged 3 commits into
tskit-dev:mainfrom
jeromekelleher:add-recomb-map

Conversation

@jeromekelleher

Copy link
Copy Markdown
Member

The matching HMM used a constant recombination probability for every pair of adjacent sites, with no way to account for distance between sites or a varying genetic map. Port recombination_rate from tsinfer 0.5.1, without mismatch_ratio, as a per-source match parameter.

  • [match.sources.] accepts recombination_rate, either a constant rate per bp or the path to a HapMap genetic map. Genetic distances between adjacent inference sites are converted to probabilities with Haldane's map function. It cannot be combined with recombination.
  • likelihood_threshold is passed through to the matcher, and the existing recombination and mismatch keys are documented.
  • The mismatch probability is set directly; it is not derived from the recombination rate.
  • HMM parameters are computed once per source in match() and passed to Matcher, so map files are not re-read for each group.

This is an interrim API; the full API will be reviewed later on when all the functionality is complete.

Closes #1199

The matching HMM used a constant recombination probability for every
pair of adjacent sites, with no way to account for distance between
sites or a varying genetic map. Port recombination_rate from tsinfer
0.5.1, without mismatch_ratio, as a per-source match parameter.

- [match.sources.<name>] accepts recombination_rate, either a constant
  rate per bp or the path to a HapMap genetic map. Genetic distances
  between adjacent inference sites are converted to probabilities with
  Haldane's map function. It cannot be combined with recombination.
- likelihood_threshold is passed through to the matcher, and the
  existing recombination and mismatch keys are documented.
- The mismatch probability is set directly; it is not derived from the
  recombination rate.
- HMM parameters are computed once per source in match() and passed to
  Matcher, so map files are not re-read for each group.
@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.73418% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 92.66%. Comparing base (8f3d62d) to head (fccf797).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1208      +/-   ##
==========================================
+ Coverage   92.59%   92.66%   +0.07%     
==========================================
  Files          16       16              
  Lines        4845     4910      +65     
  Branches      766      783      +17     
==========================================
+ Hits         4486     4550      +64     
  Misses        254      254              
- Partials      105      106       +1     
Flag Coverage Δ
C 82.61% <ø> (ø)
c-python 72.72% <ø> (ø)
python-tests 93.64% <98.73%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Python API 93.74% <98.73%> (+0.10%) ⬆️
Python C interface 89.82% <ø> (ø)
C library 91.15% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Jerome Kelleher added 2 commits October 28, 2026 13:17
Add dedicated tests for read_genetic_map and recombination_probabilities
covering nominal values, corner cases (map flanks, single-row maps, zero
rate regions, empty site arrays, int32 extremes, saturation at 0.5) and
randomised comparisons against msprime.RateMap as an oracle.

Writing these showed that malformed input was silently accepted, so
read_genetic_map now raises ValueError for an empty map, positions that
are not strictly increasing, or a decreasing map column, and a negative
constant recombination rate is rejected. Previously these gave an
IndexError, wrong interpolated positions, or negative probabilities.
test_constant_rate_matches_rate_map failed on macOS CI. The msprime
oracle computes distances by differencing cumulative masses of up to ~1,
losing ~1e-16 in absolute terms, which is a large relative error for
small distances. Use atol=1e-15 as in the other oracle comparisons.
@jeromekelleher
jeromekelleher merged commit 605b4fb into tskit-dev:main Oct 28, 2026
13 checks passed
@jeromekelleher
jeromekelleher deleted the add-recomb-map branch October 28, 2026 14:19
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.

Add support for recombination maps and new mismatch approach

1 participant