Mutation cohort (TCGA)
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.13. Desktop beta builds are coming soon.
We turn a TCGA project's somatic mutation calls into one matrix, each column a distinct mutation and each row a tumor. JBrowse groups the rows by whichever clinical field you point it at, receptor status or stage, so the mutations a subtype shares line up.
Prerequisites
- A JBrowse 2 instance to add tracks to (see the web quickstart or the desktop quickstart) and the JBrowse CLI
Where the data comes from
TCGA-BRCA open-access somatic mutation calls from the GDC (TCGA 2012).
The build script fetches these files, so there is nothing to download by hand.
- primary-tumor Masked Somatic Mutation MAFs (mutation annotation format), queried and downloaded through the GDC API: api.gdc.cancer.gov/fileshttps://api.gdc.cancer.gov/files
- per-tumor clinical annotation, from harmonized case fields and each case's clinical XML: api.gdc.cancer.gov/caseshttps://api.gdc.cancer.gov/cases
The build script copies the hg38 reference and the MANE gene track from the hosted UCSC hg38 hub's config; that MANE track is the gene track the collapse-introns step below right-clicks.
The cohort VCF and the clinical table
The VCF is the GDC's per-tumor Masked Somatic Mutation calls merged into one multi-sample file, one column per tumor:
#CHROM POS ID REF ALT INFO FORMAT TCGA-A2-A0T2-01A TCGA-A8-A07C-01A
chr3 179234297 . A G GENE=PIK3CA;HGVSP=p.H1047R... GT:AD:DP 0/1:81,29:110 0/0Two conventions affect how to read the matrix:
0/0marks a site the caller did not call, since a MAF has no coverage record for one- every somatic call is written het, because a MAF gives no ploidy
Read counts are kept in AD/DP. INFO/CSQ re-encodes the VEP columns from
the MAF (Consequence, IMPACT, HGVSp_Short, SIFT, PolyPhen), so the track
can color cells by consequence impact without running an annotator.
The clinical TSV is one row per tumor barcode and one column per attribute:
name histology er pr her2 subtype stage
TCGA-3C-AAAU-01A lobular positive positive negative HR+/HER2- XIts columns come from three places:
histologyandstageare the GDC's harmonized case fieldser/pr/her2are read from each case's clinical XML, with in-situ hybridization taking precedence over immunohistochemistry for HER2subtypeis derived from those three; a tumor whose receptor calls do not resolve it staysunknown
The table lists more tumors than the mutation track draws.1
Load the cohort VCF into JBrowse
Add the assembly first. The hosted FASTA calls its contigs bare (1) while the
VCF uses chr1, so pass the alias file and both resolve.
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 cohort is a VariantTrack whose adapter reads the clinical TSV, shown in
the multi-sample matrix display:
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 1010,
"color": { "field": "impact" }
}
]
}jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 1010,
"color": { "field": "impact" }
}
]
}'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": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 1010,
"color": { "field": "impact" }
}
]
}The track config sets three things:
variantLayout: 'columns'uses one column per mutation, so a gene's mutations pack together however far apart they sit, with a connector band from each column to its positioncoloris a color scale, and itsfieldset toimpactcolors each cell by its VEP impact tier fromCSQ, the same as Color by... → Consequence impact in the track menusamplesTsvLocationmakes the clinical columns available to facet and color rows by
The display divides
height among the
rows, so each row is about a pixel tall and a band's mutation density shows as
its darkness.
Facet the rows by clinical annotation
In grammar-of-graphics terms,
facet splits the
display into stacked sections, one per value of a samples TSV column, sorted,
and facet.domain pins the sections you want first.
rowColor is a
color scale on each row's label bar, so it puts the matching color strip in the
gutter.
Group by... and Color by... → Samples in the track menu set the same two keys.
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 450,
"lineZoneHeight": 130,
"color": { "field": "impact" },
"facet": { "field": "histology", "domain": ["ductal", "lobular"] },
"rowColor": "histology"
}
]
}jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 450,
"lineZoneHeight": 130,
"color": { "field": "impact" },
"facet": { "field": "histology", "domain": ["ductal", "lobular"] },
"rowColor": "histology"
}
]
}'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": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 450,
"lineZoneHeight": 130,
"color": { "field": "impact" },
"facet": { "field": "histology", "domain": ["ductal", "lobular"] },
"rowColor": "histology"
}
]
}Open this track in JBrowse Web ↗
Open this track in JBrowse Desktop ↗ (JBrowse Desktop 5.0+)
We open the matrix over CDH1's exons (see Gene track):
- Right-click CDH1 in the gene track.
- Choose Collapse introns, then Replace current view.
Loss of E-cadherin, the protein CDH1 encodes, is the defining lesion of lobular breast cancer (Ciriello et al. 2015).
The GDC's open mutation calls cover the exome only, so every figure here is gene-scale.
Facet rows by receptor subtype
Setting facet and rowColor to subtype instead bands the rows by receptor
status (TCGA 2012), with the HR+/HER2-
band first in domain:
Goes in the tracks array of config.json. See Tracks.
{
"type": "VariantTrack",
"trackId": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 450,
"lineZoneHeight": 130,
"color": { "field": "impact" },
"facet": {
"field": "subtype",
"domain": ["HR+/HER2-", "HER2+", "triple-negative"]
},
"rowColor": "subtype"
}
]
}jbrowse add-track-json '{
"type": "VariantTrack",
"trackId": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 450,
"lineZoneHeight": 130,
"color": { "field": "impact" },
"facet": {
"field": "subtype",
"domain": ["HR+/HER2-", "HER2+", "triple-negative"]
},
"rowColor": "subtype"
}
]
}'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": "tcga_brca_mutations",
"name": "TCGA-BRCA somatic mutations (979 primary tumors)",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "VcfTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutations.vcf.gz",
"samplesTsvLocation": {
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_clinical.tsv"
}
},
"displays": [
{
"type": "LinearMultiSampleVariantDisplay",
"variantLayout": "columns",
"height": 450,
"lineZoneHeight": 130,
"color": { "field": "impact" },
"facet": {
"field": "subtype",
"domain": ["HR+/HER2-", "HER2+", "triple-negative"]
},
"rowColor": "subtype"
}
]
}Open this track in JBrowse Web ↗
Open this track in JBrowse Desktop ↗ (JBrowse Desktop 5.0+)
The bottom band is the tumors whose receptor calls do not resolve a subtype.
With its introns collapsed the same way, PIK3CA shows its calls piled on three columns: H1047R in the kinase domain, and E542K and E545K side by side in the helical domain. All three run through every band, densest in HR+/HER2-.
Add a track of mutation frequency per gene
The bands above differ in height, so their darkness does not compare as a rate.
mutation_recurrence.py
writes one interval per gene, valued as the percent of each group with a
mutation. It takes the same SAMPLES.tsv:COLUMN group spec as the copy-number
cohort's
cnv_recurrence.py:
curl -fO https://raw.githubusercontent.com/GMOD/jbrowse-components/main/scripts/mutation_recurrence.py
python3 mutation_recurrence.py tcga_brca_mutations.vcf.gz by_subtype.bedGraph \
--groups tcga_brca_clinical.tsv:subtype#chrom start end HR+/HER2- HER2+ triple-negative unknown
chr3 179199065 179234302 40.56 30.18 11.19 30.71
chr17 7670683 7676564 19.44 39.64 80.42 32.28BedGraphTabixAdapter takes every column past end as a separate signal, and a
MultiQuantitativeTrack draws one row
per group.
Goes in the tracks array of config.json. See Tracks.
{
"type": "MultiQuantitativeTrack",
"trackId": "tcga_brca_mutation_recurrence_by_subtype",
"name": "TCGA-BRCA mutation recurrence by receptor subtype",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "BedGraphTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutation_recurrence_by_subtype.bedGraph.gz"
},
"displayDefaults": {
"height": 260,
"scales": { "y": { "domainMin": 0, "domainMax": 100 } },
"showRowSeparators": true
}
}jbrowse add-track https://jbrowse.org/demos/tcga/tcga_brca_mutation_recurrence_by_subtype.bedGraph.gz \
--trackId tcga_brca_mutation_recurrence_by_subtype \
--name "TCGA-BRCA mutation recurrence by receptor subtype" \
--assemblyNames hg38 \
--trackType MultiQuantitativeTrack \
--category TCGA \
--displayDefaults '{"height":260,"scales":{"y":{"domainMin":0,"domainMax":100}},"showRowSeparators":true}'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": "tcga_brca_mutation_recurrence_by_subtype",
"name": "TCGA-BRCA mutation recurrence by receptor subtype",
"assemblyNames": ["hg38"],
"category": ["TCGA"],
"adapter": {
"type": "BedGraphTabixAdapter",
"uri": "https://jbrowse.org/demos/tcga/tcga_brca_mutation_recurrence_by_subtype.bedGraph.gz"
},
"displayDefaults": {
"height": 260,
"scales": { "y": { "domainMin": 0, "domainMax": 100 } },
"showRowSeparators": true
}
}Open the track above the matrix to read each band's rate over it.
--impact sets what counts as a hit, defaulting to the HIGH and MODERATE tiers
of the consequence impact that colors the matrix. The rate has no background
model, and gene length enters directly: TTN, a very long gene, ranks near the
top on passenger mutations alone.
On the matrix:
- Clustering → Cluster rows by genotype... gathers every mutated sample into one block (see Clustering rows).
- Filter by... → Minor allele frequency keeps the recurrent mutations (see filtering by allele frequency and missingness).
Use your own cohort
maf_to_vcf.py
takes any directory of MAFs (vcf2maf output,
cBioPortal study downloads, your own caller) whose rows have Chromosome,
Start_Position, the two allele columns, Tumor_Sample_Barcode, and CONTEXT.
A cohort that never passed through a MAF needs a multi-sample somatic VCF. For
grouping, any TSV whose first column matches the VCF's sample names works.
Reproduce it end to end
One script builds every file above for any project id,
build_tcga_cohort_mutations.sh:
- It downloads every open-access Masked Somatic Mutation MAF in the project, the GDC's aliquot-merged ensemble calls with germline sites masked out, which need no dbGaP application.
maf_to_vcf.pymerges them into one VCF, a column per tumor. A GDC file query also returns metastasis MAFs, so the merge keeps primary tumors (sample-type code01in each MAF's barcode), the tumors the copy-number cohort paints. It keeps one aliquot per tumor, names each column by sample barcode as the copy-number rows are named, and reads each deletion's anchor base from the MAF'sCONTEXTcolumn, so it needs no reference FASTA.tcga_clinical_tsv.pybuilds the clinical table.mutation_recurrence.pywrites, per gene and group, the share of tumors with at least one call in the--impacttiers. A tumor counts once however many calls it has in the gene.
It needs curl, python3, and bgzip + tabix from
htslib, which on Debian/Ubuntu is
apt install curl python3 tabix.
curl -fO https://raw.githubusercontent.com/GMOD/jbrowse-components/main/scripts/build_tcga_cohort_mutations.sh
bash build_tcga_cohort_mutations.sh TCGA-BRCA 20 # 20 tumors, to test the pipeline
bash build_tcga_cohort_mutations.sh TCGA-BRCA # the full cohort, ~10 minutes
npx --yes serve jbrowse2 # then open the printed URLThe script writes a jbrowse2/ opening on PIK3CA with the recurrence rows
over the matrix.
Swap in any other project id (TCGA-LUAD, TCGA-COAD, ...) for a different
cohort, with --no-receptors to tcga_clinical_tsv.py for a non-breast
project. A third argument names the clinical column the recurrence track splits
on; subtype is breast only, while histology and stage work for any
project.
See also
- Tutorial: CNV cohort (TCGA)
- Tutorial: A selected haplotype (Dog10K)
- User guide: Multi-sample variant display
- User guide: Clustering rows
- Config guide: Variant track
- Config guide: Using jexl callbacks
External links
Notes
-
A case with no mutation calls still has receptor status. JBrowse reports the unmatched tumors when the track loads. ↩
Feedback on this tutorial is welcome: contact us.