Pangenome (HPRC) part 2: haplotypes against each other
The tutorials target the JBrowse v5 beta, and the v4.3.0 release
on the download page lacks some of what they show. To install the
beta of JBrowse Web, run npm install -g @jbrowse/cli@next, then
jbrowse create jbrowse2 --branch v5.0.0-beta.13. Desktop beta builds are coming soon.
We draw human haplotypes from the Human Pangenome Reference Consortium's release 2 side by side, one lane per haplotype drawn in that haplotype's assembly coordinates, and use the pangenome graph to show where neighbouring lanes match. With that view we:
- at CFH, find haplotypes missing two genes
- at GSTT1, find haplotypes with a gene GRCh38's chromosome lacks
- at FLNA / EMD, find haplotypes with two genes in the opposite order
The graph view is a beta plugin, and the HPRC page launches it on the JBrowse 5 development build until JBrowse 5 ships. We welcome your feedback.
A lane shows only what the graph aligned, and some haplotypes get no lane at all. Read what the lanes leave out before reading an absent or empty lane as a deletion.
Prerequisites
- the GraphGenomeView plugin, for the
GraphTrackbelow. In your own JBrowse, install it from the plugin store; the HPRC page's launches and the hosted config already load it - for
Whole-genome synteny from a GFA's walks:
python3and the JBrowse CLI formake-pif
Where the data comes from
The build script takes these files from HPRC release 2 by URL, so there is nothing to download by hand.
- the release's minigraph-cactus graph as a GFA: s3-us-west-2.amazonaws.com/…/hprc-v2.1-mc-grch38.gfa.gzhttps://s3-us-west-2.amazonaws.com/human-pangenomics/pangenomes/freeze/release2/minigraph-cactus/v2.1/hprc-v2.1-mc-grch38/hprc-v2.1-mc-grch38.gfa.gz
- the assemblies: raw.githubusercontent.com/…/assemblies_release2_v1.0.index.csvhttps://raw.githubusercontent.com/human-pangenomics/hprc_intermediate_assembly/main/data_tables/assemblies_release2_v1.0.index.csv
- the CAT gene annotation index, one GFF3 per haplotype: raw.githubusercontent.com/…/cat_genes_hprc_r2_v1.3.index.csvhttps://raw.githubusercontent.com/human-pangenomics/hprc_intermediate_assembly/main/data_tables/annotation/cat/cat_genes_hprc_r2_v1.3.index.csv
Read by URL (no download needed)
- our tabix index files of the graph's haplotype walks and bubbles, with the exact build recorded beside them: jbrowse.org/…/README.txthttps://jbrowse.org/demos/hprc/README.txt
Configuring the haplotype lanes track
One track draws the lanes, reading each haplotype's walk from tabix-indexed files we built from the release's graph. The HPRC page's Haplotypes launch adds it, and the config below is the one to adapt for your own graph:
- A lane is one haplotype's walk, its route through the graph.
assemblyNameslists an assembly per haplotype. The track finds each walk through the assembly'ssample#haplotypealias (HG00097.1is aliasedHG00097#1), which one assembly entry declares.assemblyNameToPanSNnames the walk of an assembly with no such alias, here GRCh38's.- The walk files for a graph of your own come from Hosting your own graph.
Goes in the tracks array of config.json. See Tracks.
{
"type": "GraphTrack",
"trackId": "hprc_v2_1_walk_lanes",
"name": "HPRC v2.1 haplotypes vs GRCh38, read from the walk files",
"assemblyNames": ["hg38", "HG00097.1", "HG00099.1"],
"adapter": {
"type": "WalkTabixSyntenyAdapter",
"walksUri": "https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38-f2.GRCh38",
"assemblyNames": ["hg38"],
"assemblyNameToPanSN": { "hg38": "GRCh38#0" }
},
"displays": [
{ "type": "MultiWaySyntenyDisplay", "height": 600 },
{ "type": "LinearGraphDisplay" }
]
}jbrowse add-track-json '{
"type": "GraphTrack",
"trackId": "hprc_v2_1_walk_lanes",
"name": "HPRC v2.1 haplotypes vs GRCh38, read from the walk files",
"assemblyNames": ["hg38", "HG00097.1", "HG00099.1"],
"adapter": {
"type": "WalkTabixSyntenyAdapter",
"walksUri": "https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38-f2.GRCh38",
"assemblyNames": ["hg38"],
"assemblyNameToPanSN": { "hg38": "GRCh38#0" }
},
"displays": [
{ "type": "MultiWaySyntenyDisplay", "height": 600 },
{ "type": "LinearGraphDisplay" }
]
}'In JBrowse Desktop, or in any running JBrowse Web session, open a view on this track’s assembly, then File → Open track..., choose Add track from pasted JSON, and paste:
{
"type": "GraphTrack",
"trackId": "hprc_v2_1_walk_lanes",
"name": "HPRC v2.1 haplotypes vs GRCh38, read from the walk files",
"assemblyNames": ["hg38", "HG00097.1", "HG00099.1"],
"adapter": {
"type": "WalkTabixSyntenyAdapter",
"walksUri": "https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38-f2.GRCh38",
"assemblyNames": ["hg38"],
"assemblyNameToPanSN": { "hg38": "GRCh38#0" }
},
"displays": [
{ "type": "MultiWaySyntenyDisplay", "height": 600 },
{ "type": "LinearGraphDisplay" }
]
}CFH: haplotypes missing two genes
Open the HPRC page and click the CFH / CFHR example, the complement factor H gene cluster, then Haplotypes. A lane missing CFHR3 and CFHR1 (Hughes et al. 2006), such as HG00253's second haplotype, breaks across both genes.
GSTT1: a gene GRCh38's chromosome lacks
GRCh38's chromosome 22 has the common GSTT1 deletion, so the gene sits on an
alternate contig and no chr22 track draws it. From any Haplotypes launch,
we'll move to chr22:23,950,001-24,060,000, choose HG00128.2, HG01960.1,
HG00146.2, HG01109.1, HG00099.1, HG00232.1, HG00133.1, HG00126.2,
HG00146.1 and HG00097.1 under Lanes → Choose lanes..., and then:
- Lanes → Order lanes by structure stacks each lane beside the one whose deletions and insertions against GRCh38 are most alike, so the haplotypes with GSTT1 sit as one block.
- The band between two lanes aligns the two haplotypes to each other, read off the nodes both walks share. It fans open where the lower lane has sequence the upper one lacks, and runs unbroken between two haplotypes that both have it.
FLNA / EMD: two genes in the opposite order
An inversion keeps the same sequence and reverses it, so no lane changes length.
FLNA and EMD sit between two inverted repeats on Xq28, and the block between
them is inverted on many X chromosomes (Small et al. 1997). From any
Haplotypes launch, we'll move to chrX:154,320,001-154,410,000.
Lanes → Choose lanes... takes HG00097.1, HG00099.1, HG00099.2 and
HG01978.1. Then:
-
The band between two lanes crosses itself where the lower lane runs the block in the other direction.
-
HPRC release 2 bubbles in the track selector adds the graph's bubbles, the places where haplotype paths split and rejoin.
gfatools bubbleflags one asinversionwhen its paths disagree about orientation. -
Filter by... → Edit filters... on that track keeps the flagged ones with this filter:
jexl:feature.inversion
What the lanes leave out
The three loci above are ones the lanes draw well. The cases below mislead, each measured on HPRC release 2.1 in October 2026; part 1 lists the limits of the graph and the VCF behind them.
- A haplotype the graph does not align has no lane. Part 1 lists where, and how many the page counts.
- A lane can be empty and correct. Where a haplotype's deletion is longer than the window, the graph has no walk for it there and the launch opens no row. Around SMN1 / SMN2 four of eight lanes are 190 to 250 kb deletions that draw nothing in a 60 kb window.
- A lane can stop partway. A haplotype aligned for part of a window draws that part and ends. The gap after it is where the graph's alignment stops, not where the sequence does.
- One lane stands for many haplotypes. The page picks one haplotype per structural form, and a form groups haplotypes by their structural variants of 50 bp or more. Two haplotypes in one form can still differ in everything smaller.
- Near-identical gene copies share one path, so a lane at RHD / RHCE or CYP2D6 cannot show how many copies a haplotype has.
Whole-genome synteny from a GFA's walks
A GFA that records each haplotype's walk converts to PAF against the reference walk, one record per stretch of shared nodes, for a whole-genome synteny view.
Convert the walks you want:
curl -fO https://raw.githubusercontent.com/cmdcolin/gfa-to-pairwise-paf/v1.0.0/gfa_to_pairwise_paf.py
# --contig-lengths: each assembly's .fai, since walks omit contig lengths
gzip -dc graph.gfa.gz | python3 gfa_to_pairwise_paf.py --reference GRCh38#0 \
--queries HG01109#1,HG00099#1 --contig-lengths contigs.fai > graph.pafIndex the PAF for JBrowse:
jbrowse make-pif graph.paf --csi --out graph.pif.gzReproduce it end to end
The HPRC build runs that conversion on the release graph. It:
- downloads the 63 GB release graph
- converts eight haplotypes' walks against GRCh38's and indexes the PAF
- fetches each haplotype's contig lengths and CAT genes
- writes a
config.jsonwith one assembly per haplotype
curl -fO https://raw.githubusercontent.com/GMOD/jbrowse-components/main/scripts/build_hprc_multiway_synteny.sh
bash build_hprc_multiway_synteny.shIts output is hosted and opens at the CFH deletion, one lane per haplotype under GRCh38.
See also
- Tutorial: Pangenome (HPRC) part 1: the graph's alleles and the haplotypes that have them
- Tutorial: Pangenome (HPRC) part 3: repeat lengths across haplotypes
- Tutorial: Pangenome (hosting your own graph)
- Tutorial: Comparing one genome's two haplotypes (T2T-HG002)
- Tutorial: Synteny visualization (all-vs-all minimap2)
- Config guide: Grouping and lane order
External links
- Li H. gfatools, whose
bubblesubcommand flags the inversion. - gfa-to-tabix, which files each haplotype's walk under the reference so a window is one range request.
Citations
- HPRC release 2, the release whose graph, assemblies and CAT annotations this page reads.
- Hughes AE et al. A common CFH haplotype, with deletion of CFHR1 and CFHR3, is associated with lower risk of age-related macular degeneration. Nature Genetics, 2006.
- Small K, Iber J, Warren ST. Emerin deletion reveals a common X-chromosome inversion mediated by inverted repeats. Nature Genetics, 1997.
Feedback on this tutorial is welcome: contact us.