v0.2.2 — Local ancestry and IBD inference directly from pangenome-derived alignments.
impopk is a small suite of Rust CLI tools that compute windowed pairwise
sequence identity from haplotype-resolved assembly alignments and feed that
signal to Hidden Markov Models for IBD detection, local ancestry inference,
and kinship estimation. It does not require phased VCFs, variant
calling, or a population-specific SNP panel.
Given a pangenome alignment (PAF) and a haplotype-resolved assembly archive
(AGC), impopk offers four inference modes:
| Mode | Binary | Input | Output |
|---|---|---|---|
| IBS | ibs |
PAF + AGC + region + subset list | Windowed pairwise identity TSV |
| IBD | ibd |
IBS TSV + sample pairs | Detected IBD segments per pair |
| Local ancestry | ancestry |
IBS TSV + population map + query list | Painted ancestry tracts per query |
| Kinship (scalar θ) | scripts/kinship_from_ibd.py |
IBD segments TSV + chromosome length | θ̂ = Σ L_IBD / 4·L per diploid pair |
| Kinship (Δ states) | jacquard |
IBS TSV + 4 haplotype IDs | Nine Jacquard Δ coefficients for that pair |
The ibs binary is a wrapper over impg similarity that filters, deduplicates,
and canonicalizes its output into a stable TSV format. Everything downstream
(ibd, ancestry, jacquard) reads that TSV.
The only hard requirement to run the HMMs on precomputed inputs (see
data/examples/) is a working Rust toolchain.
To run the full pipeline starting from a pangenome you also need:
# Dependencies
cargo install impg # Rust crate
# AGC must be built from source (C++); see its repo for instructions.
# impopk
git clone https://github.com/MarsicoFL/IMPOPk.git
cd IMPOPk
cargo build --releaseBinaries are placed in target/release/:
target/release/ibs # windowed pairwise identity (wraps impg)
target/release/ibd # 2-state IBD HMM
target/release/ibd-validate # compare ibd output against a gold-standard IBD TSV
target/release/ancestry # N-state local ancestry / founder painting HMM
target/release/jacquard # 9 Jacquard Δ coefficients for a diploid pair
ibd-validate is a developer utility: given a detected-IBD TSV and a
ground-truth TSV (same columns), it reports recall, precision, and
boundary accuracy. Useful when tuning parameters against simulated data.
Three forms of the name appear and are intentional:
impopₖ is the stylised display form, impopk is the prose and
code form, and IMPOPk is the GitHub repository slug. They all refer
to the same project.
| Build system | Cargo workspace (5 crates, cargo build --release) |
| Stripped release size | ibs 1.1 MB · ibd 1.3 MB · ancestry 2.8 MB · jacquard 0.9 MB |
| MSRV | Rust 1.74 (enforced by CI on every PR) |
| Test suite | 5500+ tests via cargo test --workspace; end-to-end bash test/run_mini_tests.sh |
| Dependencies (lib) | clap, anyhow, rayon, serde (workspace only), thiserror (common) |
| External tools (full pipeline) | impg ≥ 0.3, AGC ≥ 3.2 |
| Container | Dockerfile multi-stage build bundling AGC + impg + impopk |
| Distribution today | source only — build from git clone |
| Distribution planned | GitHub Releases with prebuilt static binaries per OS |
The data/examples/ folder ships precomputed pairwise-identity TSVs for
each inference mode, so you can run the HMMs without first setting up a
pangenome alignment. Each subfolder contains a ready-to-run shell recipe:
cd data/examples/ibd && bash run.sh # 2-state IBD HMM
cd data/examples/ancestry && bash run.sh # N-state ancestry HMM
cd data/examples/pedigree && bash run.sh # founder painting (4-state)
cd data/examples/ibs && bash run.sh # IBS window enrichmentSee data/examples/README.md for a walkthrough.
If you already have a pangenome alignment (PAF) and assemblies (AGC), the full pipeline looks like this:
ibs \
-a data/alignments/hprc_chr12.paf.gz \
--sequence-files data/assemblies/HPRC_r2.agc \
-r CHM13 \
--region chr12:1-133324548 \
--size 10000 \
--subset-sequence-list data/panel_subset.txt \
--threads 8 \
--output ibs_chr12.tsvibd \
--similarity-file ibs_chr12.tsv \
--region chr12:1-133324548 \
--region-length 133324548 \
--size 10000 \
--min-len-bp 2000000 \
--population Generic \
--threads 8 \
--output ibd_chr12.tsvancestry \
--similarity-file ibs_chr12.tsv \
--window-size 10000 \
--populations populations.tsv \
--query-samples queries.txt \
--emission-model max \
--estimate-params \
--threads 8 \
--output ancestry_chr12.tsvPangenome-derived per-window depth can be passed to ancestry as a confidence
weight. Windows where part of the reference panel does not align (centromeres,
reference-absent structural haplotypes) are shrunk toward a uniform emission
so the HMM relies on flanking interpolation instead of noisy local identity.
The weights file is a tab-separated table with one row per ancestry window.
Each row's (chrom, start, end) must match an ancestry window exactly (the
same window grid used to build the similarity TSV). Unlisted windows default
to weight 1.0.
chrom start end weight
chr12 0 10000 1.0000
chr12 10000 20000 1.0000
...
chr12 36400000 36410000 0.0940
chr12 36410000 36420000 0.0940
To derive weights from impg depth --combined-output, re-tile its depth
intervals at the ancestry window size and emit one weight row per window
(weight = mean_depth_in_window / max_depth). Once the file is built:
ancestry \
--similarity-file ibs_chr12.tsv \
--window-size 10000 \
--populations populations.tsv \
--query-samples queries.txt \
--window-weights weights_chr12.tsv \
--weight-mode interp \
--output ancestry_chr12.tsv--weight-mode interp (default) blends the per-window log-emission with the
uniform prior: log_e'(t, k) = w · log_e(t, k) + (1 − w) · log(1/K).
--weight-mode mult shrinks log-emissions multiplicatively (after the
forward-backward normalization the effect is similar to interp at the same
w, with slightly less aggressive pull toward the prior).
If more than 10% of windows in the similarity file have no matching row in
the weights file, ancestry emits a warning that suggests a window-grid
mismatch (typically caused by re-tiling at a different size or by including
intervals that span more than one ancestry window). Omitting
--window-weights is a strict no-op — exercised in CI by
data/examples/ancestry/run_weights.sh.
The kinship formula
θ̂ = Σα,β LIBD(Aα, Bβ) / 4·L
is implemented as a thin post-processor over the ibd output:
python3 scripts/kinship_from_ibd.py \
--ibd ibd_chr12.tsv \
--chrom-length 133324548 \
--output kinship_chr12.tsvOutput columns: individual_a, individual_b, total_ibd_bp, theta_hat.
jacquard reads the windowed identity TSV (not IBD segments) and takes the
four haplotypes of the pair as arguments:
jacquard \
--ibs ibs_chr12.tsv \
--hap-a1 HG00097#1 --hap-a2 HG00097#2 \
--hap-b1 HG00099#1 --hap-b2 HG00099#2The nine condensed-identity deltas are printed to stdout. Use this when you need the full identity-state decomposition rather than the scalar θ.
Tab-separated, one row per pair-window:
chrom start end group.a group.b estimated.identity [group.a.length] [group.b.length]
chromcan be either a bare chromosome (chr12) or a PanSN path (CHM13#0#chr12) — downstream tools accept both.group.a,group.bare haplotype identifiers. Either short form (HG00097#1) or full PanSN contig (HG00097#1#CM087323.1:1-248000) is accepted. The downstream HMMs strip everything after the second#to reduce to a haplotype identity.- The trailing coverage-length columns are optional (present when
ibsis run with--coverage-featuredownstream).
Tab-separated, two columns, no header:
EUR HG00097#1
EUR HG00097#2
AFR HG01884#1
...
The first column is the state label used by the HMM; the second is the
haplotype ID. For founder painting (pedigree mode) each founder is its
own state — see data/examples/pedigree/input/populations.tsv.
One haplotype ID per line.
One haplotype ID (or sample ID) per line. Accepted: HG00097,
HG00097#1, or full PanSN contigs.
chrom start end group.a group.b n_windows mean_identity mean_posterior
min_posterior max_posterior lod_score
chrom start end sample ancestry n_windows mean_similarity mean_posterior
discriminability lod_score
discriminability: gap between the top two state probabilities (high = clear call, low = ambiguous).lod_score: log-odds of the top state versus the next-best alternative.
End-to-end tutorials covering each mode are in docs/tutorials.html.
A short end-to-end sanity script exercises all five binaries on the
bundled mini fixtures and runs cargo test --workspace + cargo clippy:
bash test/run_mini_tests.shExpect 21/21 passed. Use this after any local modification to catch
regressions.
MIT. See LICENSE.