Structural variants from Hi-C
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.
Two chromosomes joined by a translocation touch along the join, so Hi-C reads linking them run far above background. The Philadelphia chromosome, the BCR-ABL1 fusion in the K562 leukemia line, is the example, against GM12878's normal karyotype. JBrowse fetches a Hi-C matrix for every pair of regions on screen. We:
- load each line's
.hicfile as a Hi-C track, and the contact domains as a BEDPE feature track - open a chr9 window and a chr22 window in one linear genome view, so JBrowse draws the contacts between the two
- rank the chr9-chr22 contact bins with juicer_tools to find the junction, and pick the control and normalization the ranking needs
Prerequisites
- a JBrowse to paste the tracks into (Web or Desktop)
java, whichjuicer_toolsneeds for the scan script; the script downloadsjuicer_toolsitselfcurl, for the same scan script
The data
Deep in situ Hi-C for GM12878 and K562 from ENCODE, plus ENCODE's domain and loop calls over the GM12878 matrix.
Nothing to download: the track configs and the scan script below read these
files by URL. Your own .hic file loads by swapping uri in the track config
under Adding the Hi-C and contact-domain tracks.
Read by URL (no download needed)
| What it is | File |
|---|---|
| GM12878 in situ Hi-C (ENCSR410MDC) | ENCFF053VBX.hic |
| K562 in situ Hi-C (ENCSR545YBD) | ENCFF080DPJ.hic |
| GM12878 contact domains (Arrowhead) | ENCFF301CUL.bedpe.gz |
| GM12878 loops (HiCCUPS) | ENCFF712NKX.bedpe.gz |
Reading a Hi-C contact map: the triangle, domains and loops
Hi-C counts how often two stretches of the genome touch in the nucleus. JBrowse draws the result as a triangle: the diagonal runs along the top edge, and depth below it is genomic separation. Two features of that picture have names, and ENCODE publishes both as annotation files derived from the matrix:
- Contact domains (also called topologically associating domains, TADs) are the square blocks sitting on the diagonal. Inside one, everything contacts everything; across a boundary, contact drops sharply. ENCODE calls them with Arrowhead and ships a BEDPE.
- Loops are individual bright dots off the diagonal: two specific points contacting each other far more than their separation predicts, usually a pair of convergent CTCF sites. ENCODE calls them with HiCCUPS, also a BEDPE.
Over a wide window the triangle can render as red speckle. If a Hi-C track looks
like noise, change data.resolution
first, where a negative value steps to coarser bins
(adjusting resolution).
Loading the GRCh38 assembly
ENCODE aligned both Hi-C libraries to GRCh38, so we load that assembly before adding any track.
Goes in the assemblies array of config.json. See Assemblies.
{
"name": "hg38",
"uri": "https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz",
"refNameAliases": {
"uri": "https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt"
},
"cytobands": "https://jbrowse.org/genomes/GRCh38/cytoBand.txt"
}jbrowse add-assembly https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz \
--name hg38 \
--refNameAliases https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt \
--config '{"cytobands":"https://jbrowse.org/genomes/GRCh38/cytoBand.txt"}'hg38 is one of the genomes JBrowse Desktop hosts, with gene tracks already set up: on the start screen click Show all available genomes and pick it. To load the files of this config instead:
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://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz
https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz.fai
https://jbrowse.org/genomes/GRCh38/fasta/hg38.prefix.fa.gz.gziJBrowse reads the format off the file name. Then fill in:
- Genome name:
hg38 - refName aliases (under More options):
https://s3.amazonaws.com/jbrowse.org/genomes/GRCh38/hg38_aliases.txt - cytobands (under More options):
https://jbrowse.org/genomes/GRCh38/cytoBand.txt
The figures also show NCBI's MANE transcripts as the gene track:
Goes in the tracks array of config.json. See Tracks.
{
"trackId": "mane_hg38",
"name": "MANE 1.0",
"uri": "https://hgdownload.soe.ucsc.edu/gbdb/hg38/mane/mane.1.0.bb",
"assemblyNames": ["hg38"]
}jbrowse add-track https://hgdownload.soe.ucsc.edu/gbdb/hg38/mane/mane.1.0.bb \
--trackId mane_hg38 \
--name "MANE 1.0" \
--assemblyNames hg38In JBrowse Desktop, or in any running JBrowse Web session, open a view on this track’s assembly, then File → Open track... and, in Add a track from file or URL, enter:
- Main file:
https://hgdownload.soe.ucsc.edu/gbdb/hg38/mane/mane.1.0.bb
Click Next. JBrowse reads the adapter and track type off the file name. Then fill in:
- Track name:
MANE 1.0 - Assembly:
hg38
Click Add.
Adding the Hi-C and contact-domain tracks
The .hic files are tens of GB, and JBrowse requests only the bins on screen.
Goes in the tracks array of config.json. See Tracks.
{
"trackId": "hic_k562_insitu",
"name": "K562 in situ Hi-C (ENCODE ENCSR545YBD)",
"uri": "https://encode-public.s3.amazonaws.com/2021/10/28/4d332729-3463-4782-b33c-76e4fa8ff72a/ENCFF080DPJ.hic",
"assemblyNames": ["hg38"],
"displayDefaults": {
"data": { "normalization": "NONE" }
}
}jbrowse add-track https://encode-public.s3.amazonaws.com/2021/10/28/4d332729-3463-4782-b33c-76e4fa8ff72a/ENCFF080DPJ.hic \
--trackId hic_k562_insitu \
--name "K562 in situ Hi-C (ENCODE ENCSR545YBD)" \
--assemblyNames hg38 \
--displayDefaults '{"data":{"normalization":"NONE"}}'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:
{
"trackId": "hic_k562_insitu",
"name": "K562 in situ Hi-C (ENCODE ENCSR545YBD)",
"uri": "https://encode-public.s3.amazonaws.com/2021/10/28/4d332729-3463-4782-b33c-76e4fa8ff72a/ENCFF080DPJ.hic",
"assemblyNames": ["hg38"],
"displayDefaults": {
"data": { "normalization": "NONE" }
}
}Goes in the tracks array of config.json. See Tracks.
{
"trackId": "hic_gm12878_insitu",
"name": "GM12878 in situ Hi-C, deep (ENCODE ENCSR410MDC)",
"uri": "https://encode-public.s3.amazonaws.com/2021/10/28/6f0cc163-86c7-4a68-baac-65af90f5a90d/ENCFF053VBX.hic",
"assemblyNames": ["hg38"],
"displayDefaults": {
"data": { "normalization": "NONE" }
}
}jbrowse add-track https://encode-public.s3.amazonaws.com/2021/10/28/6f0cc163-86c7-4a68-baac-65af90f5a90d/ENCFF053VBX.hic \
--trackId hic_gm12878_insitu \
--name "GM12878 in situ Hi-C, deep (ENCODE ENCSR410MDC)" \
--assemblyNames hg38 \
--displayDefaults '{"data":{"normalization":"NONE"}}'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:
{
"trackId": "hic_gm12878_insitu",
"name": "GM12878 in situ Hi-C, deep (ENCODE ENCSR410MDC)",
"uri": "https://encode-public.s3.amazonaws.com/2021/10/28/6f0cc163-86c7-4a68-baac-65af90f5a90d/ENCFF053VBX.hic",
"assemblyNames": ["hg38"],
"displayDefaults": {
"data": { "normalization": "NONE" }
}
}Use ENCODE's direct S3 URLs. hic-straw's range reader cannot follow the
cross-origin redirect the portal's @@download links return, and the .hic
comes back as a 403. The S3 URL for any ENCODE file is in its metadata under
cloud_metadata.url.
The domain BEDPE needs one extra slot, "type": "FeatureTrack":
Goes in the tracks array of config.json. See Tracks.
{
"type": "FeatureTrack",
"trackId": "hic_gm12878_domains",
"name": "GM12878 contact domains (Arrowhead)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "BedpeAdapter",
"uri": "https://encode-public.s3.amazonaws.com/2021/10/28/467750ae-7aab-47b0-a304-dc5f8dff89f7/ENCFF301CUL.bedpe.gz"
}
}jbrowse add-track https://encode-public.s3.amazonaws.com/2021/10/28/467750ae-7aab-47b0-a304-dc5f8dff89f7/ENCFF301CUL.bedpe.gz \
--trackId hic_gm12878_domains \
--name "GM12878 contact domains (Arrowhead)" \
--assemblyNames hg38 \
--trackType FeatureTrackIn 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": "hic_gm12878_domains",
"name": "GM12878 contact domains (Arrowhead)",
"assemblyNames": ["hg38"],
"adapter": {
"type": "BedpeAdapter",
"uri": "https://encode-public.s3.amazonaws.com/2021/10/28/467750ae-7aab-47b0-a304-dc5f8dff89f7/ENCFF301CUL.bedpe.gz"
}
}Arrowhead writes each domain with both BEDPE ends set to the same interval, so
as a FeatureTrack the file gives one box per domain, nested domains stacking
into rows. Loops, whose mates differ, are the paired-arc case in the
Hi-C track config guide;
the whole GM12878 loops track is hic_gm12878_loops in
https://jbrowse.org/code/jb2/main/test_data/config_demo.json.
To color or filter either track by a column, set
columnNames
explicitly.1
Opening chr9 and chr22 in one view to look for the translocation
Type both locations into the location box, separated by a space:
chr9:129,730,000-131,730,000 chr22:22,285,000-24,285,000.
Two regions on separate chromosomes touch at background rate, so the wedge between them stays faint unless the two are fused. K562 carries the Philadelphia chromosome, t(9;22)(q34;q11) (Rowley 1973), joining BCR on chr22 to ABL1 on chr9.
The domain boundaries inside each window line up between the two lines, so chr9 and chr22 each fold normally in K562.
Ranking chr9-chr22 contact bins with juicer_tools
The wedge shows that chr9 and chr22 touch, and ranking the contact bins finds
where. Run one dump per .hic file and sort the results, starting with the raw
contact counts between the two chromosomes:
# NONE: raw counts, since balancing divides out an amplified fusion
# BP 250000: 250 kb base-pair bins
# -Xmx4g: a whole chromosome pair needs more than the default heap
java -Xmx4g -jar juicer_tools.jar dump observed NONE \
case.hic chr9 chr22 BP 250000 case.txtAn empty output file means the .hic stores nothing at that resolution, or has
no vector for the normalization you asked for (a file may store those only at
coarser bins). The file has three columns: bin1 start, bin2 start and contact
count. Rank the bins by count:
# awk in place of head, which would kill sort with SIGPIPE under pipefail
sort -k3,3 -rn case.txt | awk 'NR <= 10'scan_hic_translocation.sh
dumps the case and the control, ranks the case bins and prints the control count
beside each:
curl -fO https://raw.githubusercontent.com/GMOD/jbrowse-components/main/scripts/scan_hic_translocation.sh
bash scan_hic_translocation.shOverride CASE, CTRL, CHR1, CHR2, RES and NORM to scan any two .hic
files that hold inter-chromosomal blocks. Reading the output:
- The top row pairs ABL1 intron 1 with the 5' end of BCR.
RES=10000resolves the junction itself, ABL1 intron 1 against the BCR major breakpoint cluster region. The K562 fusions tutorial places the DNA break of the same fusion in that intron.- A second chr9-chr22 bin further down also sits well clear of the control, so treat the ranking as a list of candidates to open.
Purpose-built callers scan the whole genome: EagleC, hic_breakfinder and HiNT. Each writes BEDPE, which loads here as a paired-arc track next to the matrix it was called from.
Choosing the control and normalization for the translocation scan
The ranking rests on the choice of control and of normalization, and both carry over to a scan of your own files:
- Control depth. The scan compares the case against a control, ENCODE's deep
GM12878 in situ file
ENCSR410MDCby default. The script leaves the much shallower GM12878 "supernatant" fraction,ENCSR730CER, commented out, because a wedge empty for want of reads looks the same as one empty for want of a translocation. With the deep file, GM12878 has more contact than K562 across the whole chr9-chr22 block except the junction bin, where the order inverts. - Normalization. Matrix balancing divides out per-bin coverage differences,
and an amplified fusion is such a difference. Re-run the scan with
NORM=INTER_SCALEand ABL1×BCR drops off the top of the table. Balanced matrices suit domains and loops and raw counts suit rearrangements, so both Hi-C tracks here setdata.normalizationtoNONE. - The control's own ranking. The scan prints a ranked list for the control below the one for the case. A bin hot in both GM12878 and K562, such as the top of the control list, is a reproducible mapping artifact.
See also
- Tutorial: ChromHMM chromatin states
- Tutorial: Complex rearrangements and derivative alleles
- Tutorial: Gene fusion calls and the DNA behind them
- User guide: Hi-C track
- User guide: SV visualization
- Config guide: Hi-C track
External links
Notes
-
Juicer writes a version banner after the header line, so column names read from the header come out
undefinedpast the tenth column, and a jexl expression on one of them matches nothing and reports no error. HiCCUPS writes 24 columns and Arrowhead 16, and both leavenameandscoreat.and put what they rank by further along:observedfor HiCCUPS, a second column calledscorefor Arrowhead. Values past the tenth column arrive as strings, so compare with>and<, which coerce. ↩
Feedback on this tutorial is welcome: contact us.