Comparing one genome's two haplotypes (T2T-HG002)
2 videos in this tutorial
TL;DR: T2T-HG002 v1.2 ships both haplotypes as contigs of one FASTA, named
chr1_MATERNAL and chr1_PATERNAL, so JBrowse loads it as a single assembly
and maternal against paternal is a self-alignment. The Q100 project publishes
the chain between them, so there is nothing to align.
Prerequisites
- a JBrowse instance to load the config into (the web quickstart, or the desktop quickstart). Every file here is a URL, so Desktop needs nothing hosted. The JBrowse CLI is needed only for the CLI tab under each config below
Where the data comes from
T2T-HG002 v1.2, the Q100 project's diploid assembly and its own maternal-to-paternal chain (Hansen et al. 2026), plus JHU Liftoff v0.6 gene models built on v1.1.
- the diploid assembly, both haplotypes in one FASTA (e.g.
chr1_MATERNAL,chr1_PATERNAL): https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/hg002v1.2.fasta.gz - the Q100 project's maternal-to-paternal chain: https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/changes/hg002v1.2_to_other_haplotype.chain.gz
- the JHU Liftoff v0.6 gene models, maternal haplotype (the paternal file sits
beside it,
PATin place ofMAT): https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/annotation/JHULiftoff/v0.6/hg002v1.1.MAT.loff.v0.6.gff.gz
Loading the assembly and the alignment
The Q100 project serves both the assembly and the alignment between the haplotypes, and JBrowse reads each from its published URL, so there is nothing to download.
We'll start by loading the assembly, one entry under assemblies. A name and
the FASTA URL are everything it carries, since JBrowse picks the adapter from
the file extension and reads the .fai and .gzi sitting beside it. The tabs
below are the three ways to apply it.
{
"name": "hg002v1.2",
"displayName": "T2T-HG002 v1.2 (diploid)",
"uri": "https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/hg002v1.2.fasta.gz"
}
jbrowse add-assembly https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/hg002v1.2.fasta.gz \
--name hg002v1.2 \
--displayName "T2T-HG002 v1.2 (diploid)"
In JBrowse Desktop, Open new genome on the start screen (or File → Open genome... in a session), then Open from a URL and paste, one per line:
https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/hg002v1.2.fasta.gz
https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/hg002v1.2.fasta.gz.fai
https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/hg002v1.2.fasta.gz.gzi
JBrowse reads the format off the file name. Then fill in:
- Genome name:
hg002v1.2 - Assembly display name (under More options):
T2T-HG002 v1.2 (diploid)
Next comes the alignment, a synteny track over the Q100 project's own chain. Both of its endpoints are the same assembly, since the two haplotypes are contigs of one:
{
"type": "SyntenyTrack",
"trackId": "hg002v1.2_mat_vs_pat",
"name": "Maternal vs paternal (Q100 chain)",
"assemblyNames": ["hg002v1.2", "hg002v1.2"],
"adapter": {
"type": "ChainAdapter",
"uri": "https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/changes/hg002v1.2_to_other_haplotype.chain.gz",
"queryAssembly": "hg002v1.2",
"targetAssembly": "hg002v1.2"
}
}
jbrowse add-track-json '{
"type": "SyntenyTrack",
"trackId": "hg002v1.2_mat_vs_pat",
"name": "Maternal vs paternal (Q100 chain)",
"assemblyNames": ["hg002v1.2", "hg002v1.2"],
"adapter": {
"type": "ChainAdapter",
"uri": "https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/changes/hg002v1.2_to_other_haplotype.chain.gz",
"queryAssembly": "hg002v1.2",
"targetAssembly": "hg002v1.2"
}
}'
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": "hg002v1.2_mat_vs_pat",
"name": "Maternal vs paternal (Q100 chain)",
"assemblyNames": ["hg002v1.2", "hg002v1.2"],
"adapter": {
"type": "ChainAdapter",
"uri": "https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/changes/hg002v1.2_to_other_haplotype.chain.gz",
"queryAssembly": "hg002v1.2",
"targetAssembly": "hg002v1.2"
}
}
The whole genome first
With those two in place, a dotplot shows whether anything moved between chromosomes.
Open Add → Dotplot view. Both axis dropdowns already read
T2T-HG002 v1.2 (diploid), the only assembly here, and an axis set to it
carries both haplotypes, so every maternal and paternal contig lands on both
axes, interleaved.
Switch to Manual and tick Plot only certain chromosomes, which puts a
box beside each assembly. Each takes a comma-separated list of contig names,
where * matches any characters, so *_MATERNAL on the X axis and *_PATERNAL
on the Y axis give one haplotype per axis. An empty box takes the whole
assembly.
Press Launch, then click the palette icon in the view's header and pick Strand, which draws the collinear blocks red and the inverted ones blue.
HG002 is male, so chrX_MATERNAL and chrY_PATERNAL have nothing on the other
haplotype to chain to, and their column and row stay empty.
The 8p23.1 inversion
Chromosome 8 carries an inversion polymorphism at 8p23.1 that HG002 is heterozygous for (Bosch et al. 2009), so the two haplotypes of one person differ there at a scale a whole-chromosome view can show. Open Add → Linear synteny view. The form opens on Quick start, which offers the two rows the Q100 chain implies and the chain between them, so Launch is the only click it needs. Then:
- go to
chr8_MATERNAL:5,250,000-14,250,000in the top panel's search box, and the same range onchr8_PATERNALbelow - pick Strand from the palette icon
- turn the chain track on in each panel's own track selector, where it draws as blocks on that panel's own ruler
Genes read the inversion a second way. The JHU Liftoff GFFs are published beside the assembly, one per haplotype, on contig names that already match:
- they annotate v1.1, the newest gene set the project publishes, and on chromosome 8 the lanes still land where the v1.2 ribbons do
- the gene symbol is in
gene_nameand there is noName, so the label points there - load one file per haplotype; the other panel takes the same config with
PATin the name and the URL, under its owntrackId
{
"type": "FeatureTrack",
"trackId": "hg002_genes_mat",
"name": "Genes (JHU Liftoff v0.6, HG002 v1.1 MAT)",
"assemblyNames": ["hg002v1.2"],
"adapter": {
"type": "Gff3TabixAdapter",
"uri": "https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/annotation/JHULiftoff/v0.6/hg002v1.1.MAT.loff.v0.6.gff.gz"
},
"displayDefaults": {
"geneGlyphMode": "longestCoding",
"labels": { "name": "jexl:feature.gene_name || feature.name || feature.id" }
}
}
jbrowse add-track https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/annotation/JHULiftoff/v0.6/hg002v1.1.MAT.loff.v0.6.gff.gz \
--trackId hg002_genes_mat \
--name "Genes (JHU Liftoff v0.6, HG002 v1.1 MAT)" \
--assemblyNames hg002v1.2 \
--displayDefaults '{"geneGlyphMode":"longestCoding","labels":{"name":"jexl:feature.gene_name || feature.name || feature.id"}}'
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": "FeatureTrack",
"trackId": "hg002_genes_mat",
"name": "Genes (JHU Liftoff v0.6, HG002 v1.1 MAT)",
"assemblyNames": ["hg002v1.2"],
"adapter": {
"type": "Gff3TabixAdapter",
"uri": "https://s3-us-west-2.amazonaws.com/human-pangenomics/T2T/HG002/assemblies/annotation/JHULiftoff/v0.6/hg002v1.1.MAT.loff.v0.6.gff.gz"
},
"displayDefaults": {
"geneGlyphMode": "longestCoding",
"labels": { "name": "jexl:feature.gene_name || feature.name || feature.id" }
}
}
Then, on each gene lane:
geneGlyphModekeeps the longest coding transcript, so the lane is one row deep- Color by... → Strand paints forward red and reverse blue, matching the ribbons
- labels arrive at this zoom on a second track over the same GFF, cut to a few genes with Filter by...
Framing both panels on the same sequence
Zoomed in, the same coordinate stops being the same sequence: an indel anywhere upstream offsets one haplotype against the other, and the offset accumulates. The follow button in the view's header walks the top panel's visible window through the alignment's CIGAR and sends the panel below it there, again every time you pan. Right-click on a chain block offers Move other panel to the matching region, which does the same walk once.
Location markers, in the header's settings menu, reads the alignment inside a ribbon. It draws lines through the ribbon at regularly spaced positions, each joining a point on the top row to the point it maps to on the bottom.
See also
- Synteny visualization (a polyploid against itself)
- Methylation (long-read)
- Synteny visualization (pairwise minimap2)
- Linear synteny view
- Dotplot view
References
- The Q100 / T2T-HG002 assembly releases, including v1.2 and the chains between the haplotypes. https://github.com/marbl/HG002
- Hansen, N. F. et al. A complete diploid human genome benchmark for personalized genomics. Cell (2026). https://doi.org/10.1016/j.cell.2026.06.016
- Bosch, N. et al. Nucleotide, cytogenetic and expression impact of the human chromosome 8p23.1 inversion polymorphism. PLOS ONE 4, e8269 (2009). https://doi.org/10.1371/journal.pone.0008269
Feedback on this tutorial is welcome: contact us.