Structural variants (Cancer GIAB) part 2: copy number
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.15. Desktop beta builds are coming soon.
HG008-T, the tumor of the C-GIAB matched pair, is hypodiploid: 35 chromosomes down from 46, with widespread arm-level loss (Wagner et al. 2026). C-GIAB publishes copy-number calls on it from four groups. Starting from the assembly, reads and benchmark that part 1 loads, we:
- load four copy-number callsets as tracks: DRAGEN's segments, NYGC's segments and log2 ratio, Wakhan's copy number per haplotype, and the benchmark's absolute copy number
- build binned depth from the reads with HiFiCNV and B-allele frequency with bcftools, and load both beside the callsets
- load tumor and matched-normal coverage as overlapping scatter tracks
- check copy number at four driver genes, CDKN2A, TP53, SMAD4 and KRAS, against depth and B-allele frequency
Prerequisites
The walkthroughs also run on the hosted C-GIAB demo. Building your own instance needs:
- The JBrowse instance, assembly, CRAMs and benchmark tracks that part 1 builds
- The command-line tools below, with the versions tested in parentheses:
- megadepth (v1.2.0 or later), for the coverage tracks
- HiFiCNV (v1.0 or later), for the binned depth track
- bcftools (v1.21 or later), for the B-allele frequency track
- tabix (v1.21 or later), to index the heterozygous sites
bedGraphToBigWigfrom the UCSC utilities
# Debian/Ubuntu
sudo apt install bcftools tabix
# or conda, which has every tool above
conda install -c bioconda -c conda-forge bcftools htslib \
ucsc-bedgraphtobigwig megadepth hificnv
# or Linux x86_64 binaries for the tools apt lacks
wget -P ~/.local/bin \
https://hgdownload.soe.ucsc.edu/admin/exe/linux.x86_64/bedGraphToBigWig
chmod +x ~/.local/bin/bedGraphToBigWigThe data
The copy-number call sets are on the C-GIAB FTP, and the tracks over them read the files by URL. The depth, B-allele frequency and coverage tracks read local files that the commands below write from the CRAMs of part 1, so run the build script first, or follow the same commands on your own reads.
| What it is | File |
|---|---|
| The V0.5 draft benchmark SV and CNV calls | NIST_HG008-T_somatic-stvar-CNV_DraftBenchmark_V0.5-20260318/ |
| DRAGEN's somatic SV and CNV calls (Illumina) | standard/ |
| NYGC's somatic SVs, annotated CNV segments and BIC-seq2 log2 ratio (Illumina) | GRCh38-GIABv3/ |
| Wakhan's haplotype-specific copy number and LOH segments (HiFi phased with Hi-C) | bed_output/ |
| The earlier Wakhan run's Clair3 tumor small-variant calls | merge_output_tumor.vcf.gz |
| The normal's germline calls | HG008-N-P.GRCh38.deepvariant.phased.vcf.gz |
Installing megadepth and HiFiCNV
Two prerequisites install from release binaries:
wget https://github.com/ChristopherWilks/megadepth/releases/download/1.2.0/megadepth
chmod +x megadepth && sudo mv megadepth /usr/local/bin/
# --strip-components=1: drop the top-level folder of the release tarball
# --wildcards '*/hificnv': extract the binary alone
curl -L https://github.com/PacificBiosciences/HiFiCNV/releases/download/v1.0.1/hificnv-v1.0.1-x86_64-unknown-linux-gnu.tar.gz \
| tar xz --strip-components=1 -C /usr/local/bin --wildcards '*/hificnv'Coverage bigWigs from the CRAMs
megadepth writes each CRAM's per-base coverage as a bigWig, which the driver-gene tracks below read:
megadepth HG008-T.cram --bigwigCopy number from the published callsets
C-GIAB publishes copy-number calls on this pair from four groups:
| Callset | Called from | Each segment has |
|---|---|---|
| NIST V0.5 draft benchmark | assembly comparison plus read support | absolute total and per-haplotype copy number |
| Wakhan | PacBio HiFi, phased with Hi-C | copy number per parental haplotype, with loss-of-heterozygosity (LOH) intervals in a second file |
| NYGC somatic pipeline, BIC-seq2 | Illumina WGS | log2 tumor-versus-normal copy ratio, and the genes the segment covers |
| DRAGEN | Illumina WGS | integer copy number, minor-haplotype copy number and minor allele frequency |
Read the other callsets against the benchmark CNV BED that part 1 adds, whose copy numbers are absolute, so CN 2 marks a diploid region.
Loading DRAGEN copy-number segments
DRAGEN's CNV calls load as an indexed VCF, one record per segment. Record IDs
read DRAGEN:CNLOH:chr9:22631070-22939213 (copy-neutral loss of
heterozygosity), so the label takes the class from the second field:
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "hg008t_dragen_cnv",
"name": "HG008-T DRAGEN somatic CNV (Illumina)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/DRAGEN-v4.2.4_ILMN-WGS_20240312/standard/dragen_4.2.4_HG008-mosaic_tumor.cnv.vcf.gz"
},
"displayDefaults": {
"labels": { "name": "jexl:split(feature.name,':')[1]" }
}
}jbrowse add-track https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/DRAGEN-v4.2.4_ILMN-WGS_20240312/standard/dragen_4.2.4_HG008-mosaic_tumor.cnv.vcf.gz \
--trackId hg008t_dragen_cnv \
--name "HG008-T DRAGEN somatic CNV (Illumina)" \
--assemblyNames GRCh38_GIABv3 \
--displayDefaults "{\"labels\":{\"name\":\"jexl:split(feature.name,':')[1]\"}}"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": "hg008t_dragen_cnv",
"name": "HG008-T DRAGEN somatic CNV (Illumina)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/DRAGEN-v4.2.4_ILMN-WGS_20240312/standard/dragen_4.2.4_HG008-mosaic_tumor.cnv.vcf.gz"
},
"displayDefaults": {
"labels": { "name": "jexl:split(feature.name,':')[1]" }
}
}NYGC copy-number segments and log2 copy ratio
C-GIAB publishes the NYGC CNV output in two forms.
HG008-T--HG008-N.cnv.annotated.v7.final.bed loads as is, because the adapter
reads column names from its # header line.
Goes in the tracks array of config.json. See Tracks.
{
"type": "FeatureTrack",
"trackId": "hg008t_nygc_cnv",
"name": "HG008-T NYGC CNV calls, annotated (BIC-seq2)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BedAdapter",
"uri": "https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/NYGC-somatic-pipeline_20240412/GRCh38-GIABv3/HG008-T--HG008-N.cnv.annotated.v7.final.bed"
},
"displayDefaults": {
"displayMode": "compact",
"color": {
"field": "type",
"domain": ["DEL", "DUP"],
"range": ["#2166ac", "#b2182b"],
"labels": ["Loss (DEL)", "Gain (DUP)"],
"title": "Call"
},
"labels": { "name": "jexl:feature.type+' '+feature.cytoband" }
}
}jbrowse add-track https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/NYGC-somatic-pipeline_20240412/GRCh38-GIABv3/HG008-T--HG008-N.cnv.annotated.v7.final.bed \
--trackId hg008t_nygc_cnv \
--name "HG008-T NYGC CNV calls, annotated (BIC-seq2)" \
--assemblyNames GRCh38_GIABv3 \
--displayDefaults "{\"displayMode\":\"compact\",\"color\":{\"field\":\"type\",\"domain\":[\"DEL\",\"DUP\"],\"range\":[\"#2166ac\",\"#b2182b\"],\"labels\":[\"Loss (DEL)\",\"Gain (DUP)\"],\"title\":\"Call\"},\"labels\":{\"name\":\"jexl:feature.type+' '+feature.cytoband\"}}"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": "hg008t_nygc_cnv",
"name": "HG008-T NYGC CNV calls, annotated (BIC-seq2)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BedAdapter",
"uri": "https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/NYGC-somatic-pipeline_20240412/GRCh38-GIABv3/HG008-T--HG008-N.cnv.annotated.v7.final.bed"
},
"displayDefaults": {
"displayMode": "compact",
"color": {
"field": "type",
"domain": ["DEL", "DUP"],
"range": ["#2166ac", "#b2182b"],
"labels": ["Loss (DEL)", "Gain (DUP)"],
"title": "Call"
},
"labels": { "name": "jexl:feature.type+' '+feature.cytoband" }
}
}HG008-T--HG008-N.bicseq2.txt is the same segmentation with one log2 ratio per
segment, which one awk command converts to a bedGraph:
# column 9 is log2.copyRatio; $2-1 converts the 1-based start to 0-based
awk 'NR>1 {printf "%s\t%d\t%d\t%.4f\n", $1, $2-1, $3, $9}' \
HG008-T--HG008-N.bicseq2.txt > HG008-T_bicseq2_log2ratio.bedgraphWe'll plot it as bars from zero on a fixed axis, so a step means the same thing from one window to the next. A homozygous deletion has no reads and so no finite ratio, and a balanced region sits above zero because BIC-seq2 normalizes on total read counts and HG008-T is hypodiploid.
Goes in the tracks array of config.json. See Tracks.
{
"type": "QuantitativeTrack",
"trackId": "hg008t_bicseq2",
"name": "HG008-T copy ratio, segmented (NYGC BIC-seq2, log2 T/N)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BedGraphAdapter",
"uri": "HG008-T_bicseq2_log2ratio.bedgraph"
},
"displayDefaults": {
"mark": "bar",
"scales": {
"y": {
"domainMin": -2,
"domainMax": 2,
"grid": true,
"title": "log2 tumor/normal"
}
}
}
}jbrowse add-track HG008-T_bicseq2_log2ratio.bedgraph \
--trackId hg008t_bicseq2 \
--name "HG008-T copy ratio, segmented (NYGC BIC-seq2, log2 T/N)" \
--assemblyNames GRCh38_GIABv3 \
--displayDefaults '{"mark":"bar","scales":{"y":{"domainMin":-2,"domainMax":2,"grid":true,"title":"log2 tumor/normal"}}}' \
--load copyIn 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": "QuantitativeTrack",
"trackId": "hg008t_bicseq2",
"name": "HG008-T copy ratio, segmented (NYGC BIC-seq2, log2 T/N)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BedGraphAdapter",
"uri": "HG008-T_bicseq2_log2ratio.bedgraph"
},
"displayDefaults": {
"mark": "bar",
"scales": {
"y": {
"domainMin": -2,
"domainMax": 2,
"grid": true,
"title": "log2 tumor/normal"
}
}
}
}HG008-T_bicseq2_log2ratio.bedgraph is relative to a config.json. Replace it with its URL or its path on this computer.
Loading Wakhan copy number per haplotype
Wakhan's HG008_HiFi_HiC_copynumbers_segments.bed is long format, one row per
haplotype, with no # on its column-name line:
chr start end copynumber_state coverage haplotype
chr1 0 23750000 2 106.025 1
chr1 23750001 119650000 0.72 58.025 1The haplotype column assigns each segment to a row, so we use
LinearMultiRowFeatureDisplay and
set rows to
haplotype. The adapter names its columns with
columnNames:
Goes in the tracks array of config.json. See Tracks.
{
"type": "FeatureTrack",
"trackId": "hg008t_wakhan_hifi_hic",
"name": "HG008-T Wakhan copy number per haplotype (HiFi + Hi-C)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BedAdapter",
"uri": "https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/NIH_HiFi-HiC_Wakhan-CNA_20240424/bed_output/HG008_HiFi_HiC_copynumbers_segments.bed",
"columnNames": [
"chrom",
"start",
"end",
"copynumber_state",
"coverage",
"haplotype"
]
},
"displays": [
{
"type": "LinearMultiRowFeatureDisplay",
"rows": "haplotype",
"color": {
"field": "copynumber_state",
"scale": "threshold",
"domain": [0.5, 1.5],
"range": ["#2166ac", "#bdbdbd", "#f4a582"],
"labels": ["Haplotype lost (0)", "One copy", "Two or more copies"],
"title": "Copy number per haplotype"
}
}
]
}jbrowse add-track-json '{
"type": "FeatureTrack",
"trackId": "hg008t_wakhan_hifi_hic",
"name": "HG008-T Wakhan copy number per haplotype (HiFi + Hi-C)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BedAdapter",
"uri": "https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/NIH_HiFi-HiC_Wakhan-CNA_20240424/bed_output/HG008_HiFi_HiC_copynumbers_segments.bed",
"columnNames": [
"chrom",
"start",
"end",
"copynumber_state",
"coverage",
"haplotype"
]
},
"displays": [
{
"type": "LinearMultiRowFeatureDisplay",
"rows": "haplotype",
"color": {
"field": "copynumber_state",
"scale": "threshold",
"domain": [0.5, 1.5],
"range": ["#2166ac", "#bdbdbd", "#f4a582"],
"labels": ["Haplotype lost (0)", "One copy", "Two or more copies"],
"title": "Copy number per haplotype"
}
}
]
}'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": "hg008t_wakhan_hifi_hic",
"name": "HG008-T Wakhan copy number per haplotype (HiFi + Hi-C)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BedAdapter",
"uri": "https://ftp-trace.ncbi.nlm.nih.gov/ReferenceSamples/giab/data_somatic/HG008/Liss_lab/analysis/NIH_HiFi-HiC_Wakhan-CNA_20240424/bed_output/HG008_HiFi_HiC_copynumbers_segments.bed",
"columnNames": [
"chrom",
"start",
"end",
"copynumber_state",
"coverage",
"haplotype"
]
},
"displays": [
{
"type": "LinearMultiRowFeatureDisplay",
"rows": "haplotype",
"color": {
"field": "copynumber_state",
"scale": "threshold",
"domain": [0.5, 1.5],
"range": ["#2166ac", "#bdbdbd", "#f4a582"],
"labels": ["Haplotype lost (0)", "One copy", "Two or more copies"],
"title": "Copy number per haplotype"
}
}
]
}A copynumber_state of 0 marks a haplotype lost across an arm (LOH), and 1
is the normal single copy. Advanced → Edit plot... in the track menu shows
rows and color as text and applies edits to the open track.
Building depth-per-bin and B-allele frequency tracks
HiFiCNV writes a binned depth track from the tumor reads:
# the depth output is <prefix>.<sample>.depth.bw, named for the --bam sample,
# so this run writes hificnv.<sample>.depth.bw
# the hosted demo renames it HG008-T.hificnv.depth.bw, the uri below
# --maf: the Clair3 tumor small-variant VCF from the C-GIAB Wakhan run;
# HiFiCNV reads AD from it for the allele-frequency output
# --bam: the reads, for depth
hificnv --bam HG008-T.cram --ref GRCh38.fa --maf tumor_smallvariants.vcf.gz \
--output-prefix hificnvWe'll load the depth as points, the Scatter plot type:
Goes in the tracks array of config.json. See Tracks.
{
"type": "QuantitativeTrack",
"trackId": "hg008_depth",
"name": "HG008-T HiFiCNV depth",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BigWigAdapter",
"uri": "HG008-T.hificnv.depth.bw"
},
"displayDefaults": { "mark": "point", "size": 1 }
}jbrowse add-track HG008-T.hificnv.depth.bw \
--trackId hg008_depth \
--name "HG008-T HiFiCNV depth" \
--assemblyNames GRCh38_GIABv3 \
--displayDefaults '{"mark":"point","size":1}' \
--load copyIn 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": "QuantitativeTrack",
"trackId": "hg008_depth",
"name": "HG008-T HiFiCNV depth",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BigWigAdapter",
"uri": "HG008-T.hificnv.depth.bw"
},
"displayDefaults": { "mark": "point", "size": 1 }
}HG008-T.hificnv.depth.bw is relative to a config.json. Replace it with its URL or its path on this computer.
To compare the depth with the callsets, draw it with Plot type → XY plot and
a fixed axis from Y axis... → Range, so a halving reads as a level. Open
chr9:21,850,000-23,050,000, around CDKN2A, with the depth above the four CNV
callsets:
B-allele frequency (BAF) is the fraction of tumor reads with the alternate allele, drawn unfolded. A balanced region is one band at 0.5, and a region with LOH (one parental copy gone) splits into two bands at 0 and 1. Build it by piling up the tumor reads at the sites the normal calls heterozygous and taking the alt fraction:
# het sites come from the normal, because LOH sites are homozygous in the tumor
bcftools view -g het -Oz -o hets.vcf.gz normal.deepvariant.vcf.gz
tabix -p vcf hets.vcf.gz
cut -f1,2 GRCh38.fa.fai > GRCh38.chrom.sizes
# -q 1 drops multi-mapped reads, -Q 0 leaves HiFi base qualities alone
bcftools mpileup -f GRCh38.fa -T hets.vcf.gz -a AD -q 1 -Q 0 tumor.bam |
bcftools query -f '%CHROM\t%POS\t[%AD]\n' |
# unfolded alt fraction at sites with depth 10 or more
awk -F'[\t,]' '{d=$3+$4; if (d>=10) printf "%s\t%d\t%d\t%.4f\n",$1,$2-1,$2,$4/d}' |
LC_COLLATE=C sort -k1,1 -k2,2n > baf.bedgraph
bedGraphToBigWig baf.bedgraph GRCh38.chrom.sizes HG008-T_baf.bcftools.bwPlot it with Scatter over a fixed 0 to 1 range.
Drawing individual BAF points when zoomed out
Zoomed out, the default bigWig summary paints an LOH arm as a solid block of
full height. A small
resolutionMultiplier
makes the adapter fetch raw per-site values at the zoom levels of these figures:
Goes in the tracks array of config.json. See Tracks.
{
"type": "QuantitativeTrack",
"trackId": "HG008-T_baf",
"name": "HG008-T B-allele frequency (BAF)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BigWigAdapter",
"uri": "HG008-T_baf.bcftools.bw",
"resolutionMultiplier": 0.001
},
"displayDefaults": {
"mark": "point",
"size": 1,
"scales": { "y": { "domainMin": 0, "domainMax": 1 } }
}
}jbrowse add-track-json '{
"type": "QuantitativeTrack",
"trackId": "HG008-T_baf",
"name": "HG008-T B-allele frequency (BAF)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BigWigAdapter",
"uri": "HG008-T_baf.bcftools.bw",
"resolutionMultiplier": 0.001
},
"displayDefaults": {
"mark": "point",
"size": 1,
"scales": { "y": { "domainMin": 0, "domainMax": 1 } }
}
}'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": "QuantitativeTrack",
"trackId": "HG008-T_baf",
"name": "HG008-T B-allele frequency (BAF)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "BigWigAdapter",
"uri": "HG008-T_baf.bcftools.bw",
"resolutionMultiplier": 0.001
},
"displayDefaults": {
"mark": "point",
"size": 1,
"scales": { "y": { "domainMin": 0, "domainMax": 1 } }
}
}HG008-T_baf.bcftools.bw is relative to a config.json. Replace it with its URL or its path on this computer.
Checking copy number at four pancreatic cancer driver genes
In pancreatic ductal adenocarcinoma the recurrently altered genes are KRAS, CDKN2A, TP53 and SMAD4 (Waddell et al. 2015, Bailey et al. 2016). Each copy-number figure below draws the gene's MANE Select (standard reference) transcript under the tracks.
For a first check, load the tumor and normal coverage from
goleft indexcov as one
multi-wiggle track, one bigWig per sample. indexcov scales each sample by its
median depth, so the two compare directly. It writes a per-sample table, so the
track below reads the demo's bigWig copies; swap each uri for your sample's
bigWig:
Goes in the tracks array of config.json. See Tracks.
{
"type": "MultiQuantitativeTrack",
"trackId": "hg008_cnv_indexcov",
"name": "HG008 normal vs tumor coverage (indexcov)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "MultiWiggleAdapter",
"subadapters": [
{
"name": "HG008-N (normal)",
"type": "BigWigAdapter",
"bigWigLocation": {
"uri": "https://jbrowse.org/demos/cgiab/HG008-N_indexcov.bw"
}
},
{
"name": "HG008-T (tumor)",
"type": "BigWigAdapter",
"bigWigLocation": {
"uri": "https://jbrowse.org/demos/cgiab/HG008-T_indexcov.bw"
}
}
]
}
}jbrowse add-track-json '{
"type": "MultiQuantitativeTrack",
"trackId": "hg008_cnv_indexcov",
"name": "HG008 normal vs tumor coverage (indexcov)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "MultiWiggleAdapter",
"subadapters": [
{
"name": "HG008-N (normal)",
"type": "BigWigAdapter",
"bigWigLocation": {
"uri": "https://jbrowse.org/demos/cgiab/HG008-N_indexcov.bw"
}
},
{
"name": "HG008-T (tumor)",
"type": "BigWigAdapter",
"bigWigLocation": {
"uri": "https://jbrowse.org/demos/cgiab/HG008-T_indexcov.bw"
}
}
]
}
}'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": "MultiQuantitativeTrack",
"trackId": "hg008_cnv_indexcov",
"name": "HG008 normal vs tumor coverage (indexcov)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "MultiWiggleAdapter",
"subadapters": [
{
"name": "HG008-N (normal)",
"type": "BigWigAdapter",
"bigWigLocation": {
"uri": "https://jbrowse.org/demos/cgiab/HG008-N_indexcov.bw"
}
},
{
"name": "HG008-T (tumor)",
"type": "BigWigAdapter",
"bigWigLocation": {
"uri": "https://jbrowse.org/demos/cgiab/HG008-T_indexcov.bw"
}
}
]
}
}Plot type → Overlapping → Scatter in its track menu draws the two samples as points in one band, with a key naming each sample's color. Y axis... → Range with 0 and 3 stops indexcov's centromere spikes from flattening every plateau.
Zoom to a region and open the benchmark CNV BED. Coverage shows where the copy number steps and BAF the allelic balance across each step.
CDKN2A: homozygous deletion
Navigate to CDKN2A on chr9. The benchmark calls a focal ~20 kb homozygous
deletion over the gene (SV_75, CN 0, no copies left), inside a larger
single-copy-loss arm (CNA_14, 0+1 copies on the two haplotypes) where depth is
already halved
(Wagner et al. 2026).
Load the tumor and matched normal per-base coverage as one
multi-quantitative track, one row per
sample, with an explicit score range. The two bigWigs are the megadepth
outputs for each sample's CRAM; swap in yours:
Goes in the tracks array of config.json. See Tracks.
{
"type": "MultiQuantitativeTrack",
"trackId": "hg008_tn_perbase",
"name": "HG008 tumor vs matched normal coverage (per-base)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "MultiWiggleAdapter",
"subadapters": [
{
"name": "HG008-T (tumor)",
"type": "BigWigAdapter",
"color": "#e41a1c",
"bigWigLocation": { "uri": "HG008-T.cram.all.bw" }
},
{
"name": "HG008-N (normal)",
"type": "BigWigAdapter",
"color": "#377eb8",
"bigWigLocation": { "uri": "HG008-N.cram.all.bw" }
}
]
},
"displayDefaults": {
"mark": "bar",
"extent": "none",
"scales": { "y": { "domainMin": 0, "domainMax": 80, "grid": false } },
"height": 280
}
}jbrowse add-track-json '{
"type": "MultiQuantitativeTrack",
"trackId": "hg008_tn_perbase",
"name": "HG008 tumor vs matched normal coverage (per-base)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "MultiWiggleAdapter",
"subadapters": [
{
"name": "HG008-T (tumor)",
"type": "BigWigAdapter",
"color": "#e41a1c",
"bigWigLocation": { "uri": "HG008-T.cram.all.bw" }
},
{
"name": "HG008-N (normal)",
"type": "BigWigAdapter",
"color": "#377eb8",
"bigWigLocation": { "uri": "HG008-N.cram.all.bw" }
}
]
},
"displayDefaults": {
"mark": "bar",
"extent": "none",
"scales": { "y": { "domainMin": 0, "domainMax": 80, "grid": false } },
"height": 280
}
}'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": "MultiQuantitativeTrack",
"trackId": "hg008_tn_perbase",
"name": "HG008 tumor vs matched normal coverage (per-base)",
"assemblyNames": ["GRCh38_GIABv3"],
"adapter": {
"type": "MultiWiggleAdapter",
"subadapters": [
{
"name": "HG008-T (tumor)",
"type": "BigWigAdapter",
"color": "#e41a1c",
"bigWigLocation": { "uri": "HG008-T.cram.all.bw" }
},
{
"name": "HG008-N (normal)",
"type": "BigWigAdapter",
"color": "#377eb8",
"bigWigLocation": { "uri": "HG008-N.cram.all.bw" }
}
]
},
"displayDefaults": {
"mark": "bar",
"extent": "none",
"scales": { "y": { "domainMin": 0, "domainMax": 80, "grid": false } },
"height": 280
}
}HG008-T.cram.all.bw, HG008-N.cram.all.bw are relative to a config.json. Replace each with its URL or its path on this computer.
Thin lines across the gap in the read pileup are reads with the deletion.
The benchmark's total_copy_number is absolute, so CN 2 is diploid; 9p has
already lost a copy, so CN 1 is the local background here. Widen the view
several hundred kilobases right to read CN 2 against it.
Chromosome 17: two kinds of loss of heterozygosity
Chromosome 17 has two LOH states, split partway along the q-arm. Open it whole with the depth track above the BAF:
- The p-arm (covering TP53) and the start of the q-arm are a single-copy
loss with LOH (
CNA_20, CN 1, 1+0). - The rest of the q-arm is copy-neutral LOH (
CNA_21, CN 2, 2+0): one haplotype lost, the other duplicated.
Together, depth and BAF separate these states:
| depth | BAF | Interpretation |
|---|---|---|
| flat (CN 2) | one band at 0.5 | balanced diploid |
| flat (CN 2) | split to 0, 1 | copy-neutral LOH |
| halved | split to 0, 1 | single-copy loss with LOH |
| raised | 1/3 and 2/3 | allelic gain |
The benchmark BED's hap1_copy_number and hap2_copy_number columns give the
1+0 and 2+0 splits. Click a CNV feature to see both.
KRAS gain and SMAD4 loss
Navigate to KRAS on chr12. It sits in a gain (SV_101, CN 3, 2+1): a 2 Mb
tandem duplication that includes the G12V-mutated copy
(Wagner et al. 2026).
SMAD4 on 18q is a single-copy loss with LOH (CNA_48, CN 1, 0+1), like
TP53. The balanced p-arm and the matched normal are the two controls. Leave
the copy-ratio track's color unset (one color above the origin of 0, another
below) with a symmetric axis, so a step down and a step up fill equally.
Reproduce it end to end
build_sv_visualization_cgiab.sh
writes the coverage, depth and B-allele frequency files above as part of the run
that part 1
describes.
See also
- Tutorial: CNV cohort (TCGA)
- Tutorial: CNV across a population (1000 Genomes)
- User guide: Quantitative track
Citations
- Bailey et al. (2016). Genomic analyses identify molecular subtypes of pancreatic cancer
- Diesh et al. (2023). JBrowse 2: A Modular Genome Browser with Views of Synteny and Structural Variation
- McDaniel et al. (2025). Development and Extensive Sequencing of a Broadly-Consented Genome in a Bottle Matched Tumor-Normal Pair
- Waddell et al. (2015). Whole genomes redefine the mutational landscape of pancreatic cancer
- Wagner et al. (2026). A complete human pancreatic cancer genome
Feedback on this tutorial is welcome: contact us.