Skip to content

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 vcf data source for parsing the compressed callset in the browser.
  • A self-input lookup to match BND records using their MATE_ID and ID.
  • link marks for intra- and interchromosomal SV arcs.
  • regexFold to generate endpoint paws from paired breakpoint columns.
  • A shared locus x-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:

  1. Keep passing DEL, DUP, and BND records on canonical chromosomes.
  2. Assign source-order numbers and derive a lookup key. A self-input lookup matches each BND's MATE_ID to the corresponding record's ID.
  3. Keep one record from each BND pair. Use its mate's CHROM and POS for the second endpoint; deletions and duplications use their own INFO.END.
  4. Derive the common endpoint and strand fields used by the link and breakpoint layers. regexFold then 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.