HCC1954 Structural Variants and Copy Number¶
This example combines somatic structural variants (SVs) and copy-number (CN) segments from the highly rearranged HCC1954/HCC1954BL breast-cancer cell-line pair. It uses PacBio HiFi results from the CASTLE tumour-normal dataset: the Severus somatic calls consumed by Wakhan and the corresponding haplotype-specific CN solution.
{
"description": [
"HCC1954 Structural Variants and Copy Number",
"Shows paired Severus somatic SV arcs and Wakhan ploidy-relative copy-number segments for the highly rearranged HCC1954 breast-cancer cell line.",
"Keskus et al., Severus: accurate detection and characterization of somatic structural variation in tumor genomes using long reads; Ahmad et al., Wakhan: reconstruction of chromosome-scale copy number profiles of tumor genomes with long-read sequencing; Akdemir et al. (2020), https://doi.org/10.1038/s41588-019-0564-y"
],
"assembly": "hg38",
"scales": {
"x": {
"domain": [
{ "chrom": "chr21", "pos": 4708647 },
{ "chrom": "chr22", "pos": 43863053 }
]
}
},
"resolve": { "scale": { "x": "shared" }, "axis": { "x": "shared" } },
"spacing": 1,
"vconcat": [
{
"name": "sv-link-layers",
"data": {
"url": "https://data.genomespy.app/sample-data/HCC1954/severus_somatic.vcf.gz",
"format": { "type": "vcf" }
},
"transform": [
{
"type": "filter",
"expr": "datum.FILTER == 'PASS' && test(/^chr([1-9]|1[0-9]|2[0-2]|X|Y)$/, datum.CHROM) && test(/^(DEL|DUP|BND)$/, datum.INFO.SVTYPE[0])"
},
{
"type": "window",
"ops": ["row_number"],
"as": ["_source_order"],
"description": "Record VCF order so one record from each BND mate pair can be retained."
},
{
"type": "formula",
"expr": "datum.INFO.SVTYPE[0] == 'BND' ? datum.INFO.MATE_ID[0] : datum.ID[0]",
"as": "_lookup_mate_id",
"description": "Use MATE_ID for BND records and the record's own ID for DEL and DUP lookup."
},
{
"type": "lookup",
"from": { "source": "input" },
"fields": "_lookup_mate_id",
"key": "ID[0]",
"values": ["CHROM", "POS", "_source_order"],
"as": ["mateChrom", "matePos", "mateOrder"],
"description": "Attach the matching BND record's coordinates and source order."
},
{
"type": "filter",
"expr": "datum.INFO.SVTYPE[0] != 'BND' || datum._source_order < datum.mateOrder",
"description": "Keep one representative from each BND pair and retain every DEL and DUP."
},
{
"type": "formula",
"expr": "datum.CHROM",
"as": "chrom1"
},
{
"type": "formula",
"expr": "datum.POS",
"as": "breakpoint1"
},
{
"type": "formula",
"expr": "datum.INFO.SVTYPE[0] == 'BND' ? datum.mateChrom : datum.CHROM",
"as": "chrom2",
"description": "Use the mate chromosome for BND and the source chromosome for interval variants."
},
{
"type": "formula",
"expr": "datum.INFO.SVTYPE[0] == 'BND' ? datum.matePos : datum.INFO.END[0]",
"as": "breakpoint2",
"description": "Use the mate position for BND and INFO.END for interval variants."
},
{
"type": "formula",
"expr": "datum.INFO.STRANDS[0][0]",
"as": "strand1"
},
{
"type": "formula",
"expr": "datum.INFO.STRANDS[0][1]",
"as": "strand2"
}
],
"encoding": {
"color": {
"field": "INFO.SVTYPE[0]",
"type": "nominal",
"scale": {
"domain": ["DEL", "DUP", "BND"],
"range": ["#2563eb", "#dc2626", "#808080"]
},
"legend": { "title": "Severus SV type", "orient": "top" }
}
},
"layer": [
{
"transform": [
{
"type": "regexFold",
"description": "Fold both link endpoints into rows for breakpoint markers.",
"columnRegex": [
"^chrom(1|2)$",
"^breakpoint(1|2)$",
"^strand(1|2)$"
],
"asValue": ["chrom", "pos", "strand"],
"asKey": "endpoint"
}
],
"mark": {
"type": "point",
"size": 100,
"tooltip": null,
"y": 0,
"dy": 0.5,
"opacity": 0.5
},
"encoding": {
"x": {
"chrom": "chrom",
"pos": "pos",
"type": "locus",
"band": 0
},
"shape": {
"field": "strand",
"type": "nominal",
"scale": {
"domain": ["-", "+"],
"range": ["tick-right", "tick-left"]
},
"legend": null
}
}
},
{
"title": {
"text": "Severus somatic structural variants loaded directly from VCF",
"orient": "none"
},
"params": [
{
"name": "svHover",
"select": { "type": "point", "on": "mouseover" },
"persist": false
}
],
"mark": {
"type": "link",
"arcFadingDistance": { "expr": "[height - 20, height + 20]" },
"segments": 200
},
"encoding": {
"x": {
"chrom": "chrom1",
"pos": "breakpoint1",
"type": "locus",
"band": 0
},
"x2": { "chrom": "chrom2", "pos": "breakpoint2", "band": 0 },
"size": {
"field": "SAMPLES.wakhan_haplotagged.VAF[0]",
"type": "quantitative",
"scale": { "range": [0.1, 2.5], "type": "pow" },
"legend": {
"title": "Variant allele frequency",
"orient": "top"
},
"condition": [{ "param": "svHover", "empty": false, "value": 3 }]
},
"opacity": {
"condition": [{ "param": "svHover", "empty": false, "value": 1 }],
"value": 0.5
},
"tooltip": [
{
"expr": "datum.INFO.SVTYPE[0] == 'BND' ? replace(datum.ID[0], /_[12]$/, '') : datum.ID[0]",
"title": "SV ID"
},
{
"field": "INFO.SVTYPE[0]",
"title": "SV type"
},
{
"expr": "isValid(datum.INFO.DETAILED_TYPE) ? datum.INFO.DETAILED_TYPE[0] : null",
"title": "Detailed type"
},
{
"field": "SAMPLES.wakhan_haplotagged.VAF[0]",
"title": "Variant allele frequency",
"format": ".3f"
},
{
"field": "SAMPLES.wakhan_haplotagged.hVAF",
"title": "Haplotype VAF",
"format": ".3f"
},
{
"field": "SAMPLES.wakhan_haplotagged.GT[0]",
"title": "Genotype"
},
{
"expr": "datum.SAMPLES.wakhan_haplotagged.DV[0] + ' variant, ' + datum.SAMPLES.wakhan_haplotagged.DR[0] + ' reference'",
"title": "Read support"
},
{
"expr": "isValid(datum.INFO.HP) ? datum.INFO.HP[0] : null",
"title": "Haplotype"
},
{
"expr": "isValid(datum.INFO.PHASESETID) ? datum.INFO.PHASESETID[0] : null",
"title": "Phase set"
},
{ "field": "INFO.MAPQ[0]", "title": "Mapping quality" }
]
}
}
]
},
{
"name": "copy-numbers",
"title": {
"text": "Wakhan total copy number relative to ploidy (4.57)",
"orient": "none"
},
"height": 32,
"data": {
"url": "https://data.genomespy.app/sample-data/HCC1954/copy-numbers.tsv"
},
"mark": { "type": "rect" },
"encoding": {
"x": { "chrom": "chrom", "pos": "start", "type": "locus" },
"x2": { "chrom": "chrom", "pos": "end" },
"color": {
"field": "relative_copy_ratio",
"type": "quantitative",
"scale": {
"domain": [0, 1, 3, 8],
"range": ["#1060f8", "#f6f6f6", "#ff4000", "#801800"]
},
"legend": { "title": "Total CN / ploidy", "values": [0, 1, 3, 8] }
}
}
}
]
}
The source data are publicly released CASTLE supplementary data on Zenodo.
The selected Wakhan source record,
17780982, and the compact Severus
callset, 18989691, are licensed CC
BY 4.0. The example uses Wakhan's 4.57_0.99_0.9 rank-1 solution (DNA purity
1.00, cell purity 0.99, ploidy 4.57, confidence 0.90).
Source attribution: Keskus et al., Severus detects somatic structural variation and complex rearrangements in cancer genomes using long-read sequencing, Nature Biotechnology 44, 247-257 (2026); Ahmad et al., Wakhan: reconstruction of chromosome-scale copy number profiles of tumor genomes with long-read sequencing; and Akdemir et al., Disruption of chromatin folding domains by somatic genomic rearrangements in human cancer.
What to notice¶
The upper track shows paired Severus breakends, deletions, and duplications. Arc stroke width encodes variant allele frequency. Hovering an arc emphasizes it by increasing its stroke width and opacity. The lower track shows Wakhan copy-number segments colored by their total copy number divided by the selected ploidy estimate: pale grey represents copy number near the genome-wide ploidy, while blue and red indicate lower and higher relative copy number.
The initial view covers a dense chromosome 21-22 region with a chromothripsis-like pattern of structural variants. Pan and zoom to inspect other rearranged regions, including chromosome 8q and chromosome 5-8 events. The tooltips expose detailed SV annotations, phased haplotype information, and supporting-read counts directly from the VCF.
GenomeSpy features¶
This example combines:
- An eager
vcfdata source for parsing the compressed callset in the browser. - A self-input
lookupto match BND records using theirMATE_IDandID. linkmarks for intra- and interchromosomal SV arcs.regexFoldto generate endpoint paws from paired breakpoint columns.- A shared
locusx-scale to keep SV and CN positions aligned across vertically concatenated tracks. - Conditional encodings and a point selection to emphasize the hovered arc.
Data wrangling¶
The upper track reads the compressed Severus VCF directly. There is no separate SV-to-TSV preprocessing step: the GenomeSpy dataflow parses the VCF and prepares the link records in the browser:
- Keep passing
DEL,DUP, andBNDrecords on canonical chromosomes. - Assign source-order numbers and derive a lookup key. A self-input lookup
matches each BND's
MATE_IDto the corresponding record'sID. - Keep one record from each BND pair. Use its mate's
CHROMandPOSfor the second endpoint; deletions and duplications use their ownINFO.END. - Derive the common endpoint and strand fields used by the link and breakpoint
layers.
regexFoldthen turns the two endpoints into breakpoint-marker rows.
Insertions and single-ended breakends are omitted because they do not form
two-ended arcs. VCF INFO, sample, and genotype fields remain available for
encodings and tooltips throughout the dataflow.
The CN track does use preprocessing: Wakhan's source segments were converted into
the TSV loaded by the example. Their one-based inclusive boundaries became
GenomeSpy's zero-based half-open intervals by subtracting one from start and
retaining end. The two haplotype segmentations were synchronized, then their
integer copy numbers were summed and divided by the selected ploidy (4.57) for
the color encoding. This ratio is a visual normalization of reconstructed
absolute CN, not a measured tumour-versus-normal log ratio.