Synteny from a Cactus alignment (T2T apes)
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.20. Desktop beta builds for Linux and
macOS are on the releases page;
the Windows build waits on code signing.
We stack ape genomes under a human locus in the order of their family tree and compare each genome with the one above it, so a change of orientation shows up between the two lineages that differ. A stack built from chains against human alone joins every lane to human; comparing neighbours needs a chain between each pair of apes. The Cactus alignment of the telomere-to-telomere ape genomes has one, since its authors publish a chain for every pair of genomes in it. We:
- convert the chains between neighbouring genomes to PAF with PanSN names, and index them as one PIF file
- load the file as one multi-way synteny track over the apes, each lane drawing the RefSeq genes of that ape's hub on genomes.jbrowse.org
- open the track in a linear genome view at ERBB2, with the ribbons colored by strand
Prerequisites
- chain2paf, built with
cargo install --path .from its checkout - The JBrowse CLI, for
jbrowse make-pif - htslib (
bgzip,tabix), whichjbrowse make-pifcalls python3, for the build script- A running JBrowse instance (the web quickstart or the desktop quickstart)
# Debian/Ubuntu
sudo apt install tabix
# or conda, which has every tool above
conda install -c bioconda -c conda-forge htslib
# any platform
npm install -g @jbrowse/cli@nextThe data
The Cactus alignment of hg38 and the T2T ape assemblies (Yoo et al. 2025), built with Progressive Cactus (Armstrong et al. 2020).
You don't need these files to follow the page: the track configs below read the hosted results. The build script fetches them to rebuild those results, and the chain steps below take your own chains.
| What it is | File |
|---|---|
Chains between every pair of genomes in the 8-way alignment, one <genome>_vs_<genome>.chain.gz per pair | chains/ |
Read by URL (no download needed)
| What it is | File |
|---|---|
| The pairs the track uses, as one indexed alignment | apes.pif.gz |
Chains between neighbours, from one alignment
Each lane reads two chains from the file. The chain between hg38 and that ape places the lane under the human window, and the chain between that ape and the one above it draws the ribbons between them. The pairs cover every ape in the stack:
- hg38 against each ape
- chimpanzee against bonobo, bonobo against gorilla, gorilla against the Sumatran orangutan, the Sumatran against the Bornean orangutan, and the Bornean orangutan against the siamang
The steps below start from pairwise chains. A Cactus alignment of your own is a
HAL file, from which Cactus's cactus-hal2chains writes the same chains
(Cactus documentation).
chain2paf reads a chain uncompressed:
gzip -dc genomeA_vs_genomeB.chain.gz > pair.chainchain2paf writes the chain's query (genomeB) as each PAF row's first
sequence and its target (genomeA) as the second. JBrowse reads a PanSN prefix
on each name (genome#haplotype#contig) as the genome the sequence belongs to,
so every pair can go into one file:
# the prefix is the assembly name JBrowse knows each genome by
chain2paf -i pair.chain \
| awk -F'\t' -v q=genomeB -v t=genomeA 'BEGIN { OFS = "\t" } { $1 = q "#0#" $1; $6 = t "#0#" $6; print }' \
>> apes.pafmake-pif sorts and indexes the concatenated pairs, writing each row twice so a
query from either genome is one tabix lookup:
jbrowse make-pif apes.paf --out apes.pif.gzmake-pif warns that the file states only some of its pairs. The missing ones
are the pairs no two neighbouring lanes need, such as chimpanzee against the
siamang.
One track over the apes
A MultiGenomeIndexedPAFAdapter reads the file and finds each genome by its
PanSN prefix. rows.sort stacks the lanes in tree order, so each lane's
neighbour above it is the genome its ribbons were aligned to. The assemblies and
gene tracks come from each genome's hub unchanged, as in the hosted config.
Goes in the tracks array of config.json. See Tracks.
{
"type": "SyntenyTrack",
"trackId": "t2t_apes_cactus",
"name": "T2T apes (Cactus alignment)",
"assemblyNames": [
"hg38",
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
],
"adapter": {
"type": "MultiGenomeIndexedPAFAdapter",
"uri": "https://jbrowse.org/demos/t2t_apes_cactus/apes.pif.gz",
"assemblyNames": [
"hg38",
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
]
},
"displays": [
{
"type": "MultiWaySyntenyDisplay",
"displayId": "t2t_apes_cactus-MultiWaySyntenyDisplay",
"rows": {
"sort": [
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
]
}
}
]
}jbrowse add-track-json '{
"type": "SyntenyTrack",
"trackId": "t2t_apes_cactus",
"name": "T2T apes (Cactus alignment)",
"assemblyNames": [
"hg38",
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
],
"adapter": {
"type": "MultiGenomeIndexedPAFAdapter",
"uri": "https://jbrowse.org/demos/t2t_apes_cactus/apes.pif.gz",
"assemblyNames": [
"hg38",
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
]
},
"displays": [
{
"type": "MultiWaySyntenyDisplay",
"displayId": "t2t_apes_cactus-MultiWaySyntenyDisplay",
"rows": {
"sort": [
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
]
}
}
]
}'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": "SyntenyTrack",
"trackId": "t2t_apes_cactus",
"name": "T2T apes (Cactus alignment)",
"assemblyNames": [
"hg38",
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
],
"adapter": {
"type": "MultiGenomeIndexedPAFAdapter",
"uri": "https://jbrowse.org/demos/t2t_apes_cactus/apes.pif.gz",
"assemblyNames": [
"hg38",
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
]
},
"displays": [
{
"type": "MultiWaySyntenyDisplay",
"displayId": "t2t_apes_cactus-MultiWaySyntenyDisplay",
"rows": {
"sort": [
"GCF_028858775.2",
"GCF_029289425.2",
"GCF_029281585.2",
"GCF_028885655.2",
"GCF_028885625.2",
"GCF_028878055.3"
]
}
}
]
}That shows it in the linear view. For the synteny view, open Add → Linear synteny view, pick the track under Quick start, and click Launch.
Orientation at ERBB2 down the tree
We'll open the track on hg38 around ERBB2 on 17q12. It draws a lane per ape
under human, each in the coordinates of that ape's assembly, and each lane
header names the chromosome and the span the lane shows, with [rev] where the
lane runs against human. The ribbons color by strand (Color by → Strand,
under Ribbons in the track menu), blue where a lane runs against the one
above it:
Goes at the top level of config.json, replacing any defaultSession there. See Default session.
{
"defaultSession": {
"name": "ERBB2 across seven apes",
"views": [
{
"type": "LinearGenomeView",
"assembly": "hg38",
"loc": "chr17:39,400,000-40,200,000",
"tracks": [
"hg38-ncbiRefSeq",
{
"trackId": "t2t_apes_cactus",
"type": "MultiWaySyntenyDisplay",
"height": 600
}
]
}
]
}
}jbrowse set-default-session --session - << 'EOF'
{
"name": "ERBB2 across seven apes",
"views": [
{
"type": "LinearGenomeView",
"assembly": "hg38",
"loc": "chr17:39,400,000-40,200,000",
"tracks": [
"hg38-ncbiRefSeq",
{
"trackId": "t2t_apes_cactus",
"type": "MultiWaySyntenyDisplay",
"height": 600
}
]
}
]
}
EOFThe ribbons turn blue between human and chimpanzee, and again between gorilla and the Sumatran orangutan: chimpanzee, bonobo and gorilla have ERBB2 in one orientation, and human, both orangutans and the siamang in the other.
Reproduce it end to end
The script works in four steps:
- Fetch each genome's hub config from genomes.jbrowse.org, which gives its lane the assembly and the NCBI RefSeq gene track.
- Download the chains: hg38 against each ape, and each ape against the next one down the tree.
- Convert each chain to PAF with PanSN names and index them all as one file.
- Write the config, with the lanes stacked in tree order.
curl -fO https://raw.githubusercontent.com/GMOD/jbrowse-components/main/scripts/build_t2t_apes_cactus_multiway.sh
bash build_t2t_apes_cactus_multiway.sh # writes ./t2t_apes_cactus_build/config.jsonSee also
- Tutorial: Synteny from liftOver chains (hg38 and eight vertebrates)
- Tutorial: Synteny from gene symbols (primates and E. coli)
- Tutorial: Pangenome (Minigraph-Cactus)
- Tutorial: Synteny visualization (all-vs-all minimap2)
External links
- Cactus T2T ape alignments: https://cglgenomics.ucsc.edu/february-2024-t2t-apes
- The T2T primates project: https://github.com/marbl/Primates
- chain2paf: https://github.com/AndreaGuarracino/chain2paf
Citations
- Yoo et al. (2025). Complete sequencing of ape genomes
- Armstrong et al. (2020). Progressive Cactus is a multiple-genome aligner for the thousand-genome era
Feedback on this tutorial is welcome: contact us.