Pangenome (HPRC): who carries each allele
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.9. Desktop beta builds are coming soon.
A pangenome graph stores each allele once, credited to the first assembly that contributed it, so the graph alone cannot say who else carries it. The Human Pangenome Reference Consortium's release 2 publishes that answer beside its graph as a callset, one genotype per haplotype for all 464, and we open both from the consortium's page on genomes.jbrowse.org at the MHC class II locus. We:
- cluster the callset's haplotypes by the alleles they share
- find who carries the HLA-DRB5 allele in the callset and the graph at once
- read carriage at the graph's own granularity
- check both against the multiple alignment they come from, and settle a 1q21.1 inversion the graph cannot
Browsing the graph traces that allele to the one haplotype the graph credits it to.
Prerequisites
- the GraphGenomeView plugin, which the HPRC page's graph launches load; both callsets are a URL any JBrowse reads with no plugin
Where the data comes from
The data is HPRC release 2. JBrowse reads its callsets and its multiple alignment directly from S3, and reads the bubble projections from our host.
- the decomposed variant callset, 464 haplotypes, read straight off S3: https://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.wave.vcf.gz
- the undecomposed, snarl-level carriage file, 462 haplotypes: https://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.pgbi.vcf.gz
- the multiple alignment the graph and the callset are both derived from: https://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.full.maf.gz
- the release's all-vs-GRCh38 alignment, sliced for the inversion figure: https://s3-us-west-2.amazonaws.com/human-pangenomics/pangenomes/freeze/release2/impg/pafs/hprc465vsgrch38.aln.paf.gz
- the CAT gene annotation index, one GFF3 per haplotype, which that figure's haplotype rows carry: https://raw.githubusercontent.com/human-pangenomics/hprc_intermediate_assembly/main/data_tables/annotation/cat/cat_genes_hprc_r2_v1.3.index.csv
- our bubble projections, with the exact build recorded beside them: https://jbrowse.org/demos/hprc/README.txt
The variant callset
Open the HPRC page and
press variants on the HLA / MHC row. JBrowse opens on the MHC class II
window, chr6:32,510,001-32,600,000, with the release's decomposed callset as a
matrix of haplotypes. Indexed alongside the 2.3 GB VCF, the track is this
config:
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "hprc2_wave_grch38",
"name": "HPRC2 pangenome",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://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.wave.vcf.gz"
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"renderingMode": "phased"
}
]
}jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "hprc2_wave_grch38",
"name": "HPRC2 pangenome",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://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.wave.vcf.gz"
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"renderingMode": "phased"
}
]
}'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": "VariantTrack",
"trackId": "hprc2_wave_grch38",
"name": "HPRC2 pangenome",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://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.wave.vcf.gz"
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"renderingMode": "phased"
}
]
}renderingMode: "phased" splits each sample into its two haplotypes, one row
each. The launch filters the fully decomposed VCF to the structural tier; open
the track menu's Edit filters to read it:
jexl:feature.INFO.LV[0]==0 && alleleLength(feature)>=50alleleLength is the longest allele the record describes, over end - start
since an insertion consumes no reference; LV==0 keeps the top-level sites of
vg's snarl tree, so a nested child does not paint twice.
Open the track menu again and take Clustering → Cluster rows by genotype..., then Run clustering: the rows reorder by genotype similarity with a dendrogram beside them, and haplotypes that share alleles gather into blocks.
The graph beside the callset
minigraph collapses variation under about 50 bp, so the callset filtered to 50 bp and up holds the same tier as the graph. The graph records an allele and its length, the callset who carries it.
Press graph on the same HLA / MHC row for the graph track under the genes, the bubbles and the allele inventory. Turn on HPRC2 pangenome callset (464 haplotypes) from the track selector and filter it as before, admitting the HLA-DRB5 deletion by position since vcfwave nests it one level down:
jexl:(feature.INFO.LV[0]==0 || feature.start==32517421) && alleleLength(feature)>=50Cluster it, hide the bubbles and the allele inventory, pick Layout → Force-directed layout, and right-click the charcoal allele beside HLA-DRB5 for Highlight in hg38.
Carriage at the graph's own granularity
vcfwave splits a snarl's alleles into smaller records, so a callset record need
not line up with a bubble. Release 2 also publishes the undecomposed form, one
record per snarl, as the pgbi.vcf.gz beside each build: read it to find
who carries a given bubble, since its rows are the graph's own alleles. Add it
to the same session:
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "hprc2_pgbi_grch38",
"name": "HPRC2 pangenome carriage (snarl-level, 462 haplotypes)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://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.pgbi.vcf.gz"
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"renderingMode": "phased"
}
]
}jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "hprc2_pgbi_grch38",
"name": "HPRC2 pangenome carriage (snarl-level, 462 haplotypes)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://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.pgbi.vcf.gz"
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"renderingMode": "phased"
}
]
}'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": "VariantTrack",
"trackId": "hprc2_pgbi_grch38",
"name": "HPRC2 pangenome carriage (snarl-level, 462 haplotypes)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://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.pgbi.vcf.gz"
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"renderingMode": "phased"
}
]
}Apply the same LV==0 filter from Edit filters, and
the lane cuts to the tier the graph's bubbles hold, matched to a bubble by
interval.
The alignment underneath both
The graph and the callset both derive from the multiple alignment, and release
2.1 publishes it too: hprc-v2.1-mc-grch38.full.maf.gz, 53 GB, beside a .tai
index written by taffy
that makes a locus one ranged read:
Goes in the tracks array of config.json. See Tracks.
{
"type": "MafTrack",
"trackId": "hprc_v2_0_mc_grch38",
"name": "HPRC release 2 pangenome alignment (464 haplotypes)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "BgzipMafAdapter",
"uri": "https://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.full.maf.gz"
}
}jbrowse add-track-json '{
"type": "MafTrack",
"trackId": "hprc_v2_0_mc_grch38",
"name": "HPRC release 2 pangenome alignment (464 haplotypes)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "BgzipMafAdapter",
"uri": "https://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.full.maf.gz"
}
}'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": "MafTrack",
"trackId": "hprc_v2_0_mc_grch38",
"name": "HPRC release 2 pangenome alignment (464 haplotypes)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "BgzipMafAdapter",
"uri": "https://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.full.maf.gz"
}
}The uri shorthand resolves the sibling .tai. Release 2.0 publishes the same
alignment as a 5.9 GB TAF, read by BgzipTaffyAdapter with the same shorthand:
a quarter of the bytes per locus, but an earlier build with more underalignment
and unpatched centromeres.
Type the C4 window, chr6:31,980,000-32,050,000, and show three lanes over the
graph track: the genes, the filtered callset and this alignment. A row that
drops out belongs to a haplotype that does not carry that segment.
Order the rows with Clustering → Cluster rows by genotype... on the callset and Clustering → Cluster rows by identity... on the alignment (computed over the window in view, since HPRC's file ships no guide tree); Reset row order puts back the file's own order.
The figure keeps thirty-two haplotype rows so each has the height for its name beside it; the track as configured above draws every haplotype.
Inversions
An inversion is the same reference sequence, walked backwards. gfatools bubble
flags it as an inversion boolean when a bubble's paths disagree about
orientation. Show the bubbles lane again, open Edit filters, and enter:
jexl:feature.inversionType chr1:144,260,000-144,610,000, the 1q21.1 locus. The lane's one flagged
bubble cannot distinguish a polymorphic inversion from an inverted paralog in a
segmental duplication, and the graph draws its breakpoints as two deletion arcs
since its edges carry no orientation. The alignments settle it: the figure below
comes from
build_hprc_inversion_synteny.sh
under Reproduce it end to end, which classifies
every haplotype at the bubble from HPRC's all-vs-GRCh38 PAF and slices out a
carrier and a non-carrier, each with its CAT annotation. The hg38 row between
them agrees with the non-carrier.
Reproduce it end to end
Hosting your own graph builds the
bubbles lane in one command that runs on any rGFA; pointed at
hprc-v2.1-mc-grch38.sv.gfa.gz, it writes the files we host, and
README.txt beside them records
their provenance.
We do not rebuild carriage here, since HPRC publishes it as a file. Rebuilding it takes a 464-assembly download and a mapping run, one call per sample:
# --call asks, at every bubble, which path this assembly takes through the graph
minigraph -cxasm --call -t"$(nproc)" graph.gfa assembly.fa > sample.call.bedbuild_minigraph_paths.sh
wraps that call in the per-sample loop and the join, and
the same page walks
through the script.
A separate script builds the inversion figure from release 2's published all-vs-GRCh38 PAF:
curl -fO https://raw.githubusercontent.com/GMOD/jbrowse-components/main/scripts/build_hprc_inversion_synteny.sh
bash build_hprc_inversion_synteny.sh # writes ./hprc_inversion_synteny_build/build_hprc_inversion_synteny.sh
keeps the haplotypes whose alignments reverse the block while the flanks stay
forward, then slices out one haplotype of each kind: the alignment, the contig
length and the CAT genes.
See also
- Pangenome (HPRC): browsing the graph
- Pangenome (HPRC): haplotypes against each other
- Pangenome (HPRC): mitochondrial lineages
- Pangenome (hosting your own graph)
- Graph genome view
- Multi-sample variant display
- User guide: MAF track
References
- HPRC release 2, the release this page opens: the Minigraph-Cactus graph, the multiple alignment and the two callsets deconstructed from it.
- Li H.
The rGFA format and
gfatools, whose
bubblesubcommand calls the bubbles this page reads. - taffy, which writes the
.taiindex that makes the alignment addressable by locus.
Feedback on this tutorial is welcome: contact us.