Pangenomes beyond human, mouse and cattle
The machinery on the HPRC pangenome page is not human-specific. Two more graphs are hosted the same way, on references JBrowse already serves: a mouse strain graph over GRCm39 and the bovine super-pangenome over ARS-UCD1.2. Opening them needs no new adapters and no new track types. What differs between the three is what each graph is able to say.
The three graphs, and what separates them
All three are SV-resolution minigraph rGFA, so the tracks, the adapters and the coarse tier are identical, and each is served as the same five files:
| file | what it holds |
|---|---|
<prefix>.segs.bed.gz | one row per graph node, with its rank |
<prefix>.links.bed.gz | one row per edge per endpoint |
<prefix>.bubbles.bed.gz | gfatools bubble output |
<prefix>.alleles.bed.gz | one row per allele, with a CIGAR for its size |
<prefix>.tier10000.* | one node per bubble, so a chromosome is drawable |
What separates them is carriage: whether the graph can say which samples carry a given allele:
- HPRC can. Minigraph-Cactus records per-haplotype walks, so carriage is a query against the graph and a callset beside it.
- Cattle can, indirectly. The published graphs are plain GFA with one path
per assembly, so
vg deconstructturns those paths into a VCF. - Mouse cannot.
minigraphwrites no path lines at all, so the information is not in the file to recover.
Only a graph that records haplotypes can say who carries an allele.
Mouse: a deletion that appears as an insertion
The mouse graph is GRCm39 plus eighteen inbred and wild-derived strain
assemblies from the Mouse Genomes Project, as rehosted in UCSC GenArk. Each
chromosome is one minigraph call over the reference followed by the strains,
reference first, which is what makes it rank 0:
minigraph -cxggs -t "$THREADS" $(tr '\n' ' ' < "chrom/$c/order.txt")
Start at Nnt. C57BL/6J carries a well-known multi-exon deletion there that
abolishes the protein and is why B6J mice are glucose intolerant, and GRCm39
is C57BL/6J, so the backbone of this graph is the strain with the deletion.
The deletion shows up with the opposite sign from every description of it: as
sequence the other strains carry and the reference lacks.
The allele lane is what makes that readable. An insertion consumes almost no reference, so on a plain feature track a large one and a small one draw at the same minimum width; reading the file as alignments lets each allele be drawn at its real size from its CIGAR.
Cattle: where the graph and the callset say different things
The bovine super-pangenome is twelve assemblies on ARS-UCD1.2, and the panel is unusually wide for a livestock pangenome: taurine and indicine breeds plus yak, bison and gaur.
The BoLA class II region is where its two routes diverge. The graph shows
that a lot of sequence is present in some assemblies and absent from the
reference, but it can only attribute it by convention: these graphs record no
construction rank, so firstSeenIn in the allele file means "first in a fixed
list", not "carries it".
The callset can say. One vg deconstruct call per chromosome over the same
graph gives a genotype per assembly:
vg convert -g "$TMPDIR/$k.renamed.gfa" -p > "$TMPDIR/$k.vg"
vg deconstruct -p "chr$k" -a -t "$THREADS" "$TMPDIR/$k.vg" > "vcf/chr$k.vcf.tmp"
Read the genotype rows across: most assemblies carry a different allele here, which is cattle MHC behaving much like human MHC. None of it is visible in the graph lanes around it.
A whole chromosome, off the coarse tier
The level-of-detail tier is one node per bubble instead of one per segment, which is what makes a whole chromosome drawable, and it is not a human-only trick. Over a full cattle chromosome the fine segments track refuses with "Too many features"; the tier draws.
A graph view pointed at a tier raises maxRegionBp explicitly, because the view
refuses a cut wider than 5 Mb, which is a proxy for node count and a good one
only at segment granularity.
These panels are a dozen or two assemblies rather than ninety haplotypes, so their cuts are chains with a few loops and the anchored layout often reads better. Check the node and edge counts in the graph pane's header before reaching for the force layout; it earns its place where the bubbles lane says a window is genuinely tangled.
Finding the loci
Nnt and BoLA are both loci someone had already written about, and that does
not generalise: a panel nobody has published on has no literature to read, which
is most panels. The graph can answer the question itself. The coarse tier
records how many segments each bubble holds, so ranking it says where the graph
varies most, and intersecting the result with the reference annotation names
what it found.
On these two datasets that recovers the beta-defensin cluster, the vomeronasal
receptor and Speer families, the immunoglobulin heavy chain locus and BoLA, with
nobody curating a list. The densest window it returns for mouse is a single
bubble sitting inside one intron of Dock2:
It is also the counterexample to the note above. Every other panel on this page is a chain and is drawn anchored; this cut is loops hanging off a backbone, which is the shape the force-directed layout exists for, and it was found by ranking a file rather than by knowing anything about mouse. Clicking the superbubble's label opens it, and the graph derives the bubbles inside it from its own layering, so the descent continues level by level: a bubble inside a bubble follows it down.
Ranking the graph rather than the literature is what makes the method repeatable
for a panel nobody has written about yet. The ranking lives in
generatePangenomeLoci.ts
in the genomes.jbrowse.org repo, which publishes the derived catalogues at
genomes.jbrowse.org/pangenomes so a
locus can be opened without building anything.
Building one for your own panel
Both graphs are reproducible from committed scripts:
build_mouse_pangenome.shdownloads the assemblies, extracts one sequence per chromosome renamed to PanSN, runsminigraphper chromosome, concatenates, and projects the five files. It is a long run, most of a day of alignment.build_bovine_pangenome.shdownloads the published archive, recovers rGFA tags from its path lines withgfa_paths_to_rgfa.py, projects the same five files, and deconstructs the callset. About half an hour after the download.
Both write a README.txt beside the data recording the source, what was
modified, the tool versions and the audits that ran. The audits are the part
worth copying: each build refuses unless the reference path reproduces the
reference's own chromosome lengths, and refuses on a duplicate segment id after
renumbering. Either failure would otherwise produce a graph whose coordinates
are quietly wrong, and every check downstream would pass on it.
If your own graph has path lines, use
build_pggb_tabix.sh
rather than build_rgfa_tabix.sh: it walks the paths, so it can write the
carriage tag that rGFA has nowhere to put, and the graph view will show which
samples cross each node.
Feedback on this tutorial is welcome: contact us.