Skip to content

Commit

Permalink
feat: refurbishing SV details page (#236) (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
holtgrewe authored Nov 30, 2023
1 parent d3df9d7 commit 0d8dd34
Show file tree
Hide file tree
Showing 50 changed files with 2,052 additions and 902 deletions.
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{ts,vue}]
line_length=100
indent_style = space
indent_size = 2

[*.py]
line_length=120
known_first_party=varfish
Expand Down
1 change: 1 addition & 0 deletions backend/.editorconfig
Binary file modified backend/app/assets/favicon.ico
Binary file not shown.
134 changes: 134 additions & 0 deletions backend/app/assets/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ format:
.PHONY: lint
lint:
npm run lint
npm run type-check
npm run format:check

.PHONY: test
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/api/annonars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,26 @@ export class AnnonarsClient {
})
return result
}

/**
* Fetch overlapping ClinVar strucvars via annonars REST API.
*/
async fetchClinvarStrucvars(
genomeRelease: string,
chromosome: string,
start: number,
end: number,
pageSize: number = 1000,
minOverlap: number = 0.1
): Promise<any> {
const url =
`${this.apiBaseUrl}clinvar-sv/query?genomeRelease=${genomeRelease}&` +
`chromosome=${chromosome}&start=${start}&stop=${end}&pageSize=${pageSize}&` +
`minOverlap=${minOverlap}`

const response = await fetch(url, {
method: 'GET'
})
return await response.json()
}
}
1 change: 1 addition & 0 deletions frontend/src/components/GeneDetails/ClinvarCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const props = withDefaults(defineProps<Props>(), {
:clinvar="geneClinvar"
:transcripts="transcripts"
:genome-release="genomeRelease"
:gene-symbol="geneInfo?.hgnc?.symbol"
/>
</v-col>
</v-row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ export interface Props {
transcripts: any
/** The genome release. */
genomeRelease: 'grch37' | 'grch38'
/** Gene symbol */
geneSymbol: string
}
const props = withDefaults(defineProps<Props>(), {
clinvar: null,
transcripts: null,
genomeRelease: 'grch37'
genomeRelease: 'grch37',
geneSymbol: '???'
})
const clinvarSignificanceMapping: { [key: string]: number } = {
Expand Down Expand Up @@ -361,9 +364,14 @@ const vegaLayer = [
:data-values="vegaData"
:encoding="vegaEncoding"
:layer="vegaLayer"
:width="1200"
:height="300"
renderer="canvas"
/>
<div>
The plot above shows the sequence variants in the ClinVar database that are that are located
in the gene <span class="font-italic"> {{ geneSymbol }} </span>.
</div>
</v-sheet>
</div>
</template>
2 changes: 2 additions & 0 deletions frontend/src/components/GeneDetails/ConditionsCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ const hpoTermsToShow = computed<HpoTerm[]>(() => {
label="numeric terms"
class="ml-3 d-inline-flex flex-grow-0"
density="compact"
inset
/>
<v-switch
v-model="showTermLinks"
Expand All @@ -231,6 +232,7 @@ const hpoTermsToShow = computed<HpoTerm[]>(() => {
label="show links"
class="ml-3 d-inline-flex flex-grow-0"
density="compact"
inset
/>
<v-btn
:href="`https://hpo.jax.org/app/browse/gene/${geneInfo?.hgnc?.entrezId}`"
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/components/GeneDetails/PathogenicityCard.c.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/** Enumeration with dosage. */
export enum Dosage {
CLINGEN_DOSAGE_SCORE_UNKNOWN = 'CLINGEN_DOSAGE_SCORE_UNKNOWN',
CLINGEN_DOSAGE_SCORE_SUFFICIENT_EVIDENCE_AVAILABLE = 'CLINGEN_DOSAGE_SCORE_SUFFICIENT_EVIDENCE_AVAILABLE',
CLINGEN_DOSAGE_SCORE_SOME_EVIDENCE_AVAILABLE = 'CLINGEN_DOSAGE_SCORE_SOME_EVIDENCE_AVAILABLE',
CLINGEN_DOSAGE_SCORE_LITTLE_EVIDENCE = 'CLINGEN_DOSAGE_SCORE_LITTLE_EVIDENCE',
CLINGEN_DOSAGE_SCORE_NO_EVIDENCE_AVAILABLE = 'CLINGEN_DOSAGE_SCORE_NO_EVIDENCE_AVAILABLE',
CLINGEN_DOSAGE_SCORE_RECESSIVE = 'CLINGEN_DOSAGE_SCORE_RECESSIVE',
CLINGEN_DOSAGE_SCORE_UNLIKELY = 'CLINGEN_DOSAGE_SCORE_UNLIKELY'
}

/** Scores for ClinGen dosage scores. */
export const CLINGEN_DOSAGE_SCORES: { [key: string]: number } = {
CLINGEN_DOSAGE_SCORE_UNKNOWN: 0,
Expand All @@ -9,6 +20,17 @@ export const CLINGEN_DOSAGE_SCORES: { [key: string]: number } = {
CLINGEN_DOSAGE_SCORE_UNLIKELY: 40
}

/** Colors for ClinGen dosage scores. */
export const CLINGEN_DOSAGE_COLOR: { [key: string]: string } = {
CLINGEN_DOSAGE_SCORE_UNKNOWN: 'transparent',
CLINGEN_DOSAGE_SCORE_SUFFICIENT_EVIDENCE_AVAILABLE: 'red-darken-3',
CLINGEN_DOSAGE_SCORE_SOME_EVIDENCE_AVAILABLE: 'orange-darken-2',
CLINGEN_DOSAGE_SCORE_LITTLE_EVIDENCE: 'orange-darken-2',
CLINGEN_DOSAGE_SCORE_NO_EVIDENCE_AVAILABLE: 'green-lighten-2',
CLINGEN_DOSAGE_SCORE_RECESSIVE: 'orange-darken-2',
CLINGEN_DOSAGE_SCORE_UNLIKELY: 'green-lighten-2'
}

/** Labels for ClinGen dosage scores. */
export const CLINGEN_DOSAGE_LABELS: { [key: string]: string } = {
CLINGEN_DOSAGE_SCORE_UNKNOWN: 'unknown',
Expand Down
File renamed without changes.
30 changes: 16 additions & 14 deletions frontend/src/components/GenomeBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
import igv from 'igv'
import { onMounted, ref, watch } from 'vue'
import { publicTracks } from '@/lib/genomeBrowserTracks'
import { publicTracks } from './GenomeBrowser.c'
/** Alias for Genome Browser type. */
type GenomeBrowser = any
export interface Props {
// Genome build, e.g., "hg19" or "b37"
genome: string
// Genome build
genomeRelease: 'grch37' | 'grch38'
// Locus to go to, e.g., "chr1:1,900,000-2,000,000"
locus: string
locus?: string
}
// Define the props.
const props = defineProps<Props>()
const props = withDefaults(defineProps<Props>(), { locus: '' })
/** The <div> to show the browser in. */
const genomeBrowserDivRef = ref(null)
Expand All @@ -29,9 +29,9 @@ const igvBrowser = ref(null)
* @returns The translated genome build name. (hg19/hg38)
*/
const translateGenome = (value: any) => {
if (value === 'GRCh37') {
if (value === 'grch37') {
return 'hg19'
} else if (value === 'GRCh38') {
} else if (value === 'grch38') {
return 'hg38'
} else {
return value
Expand All @@ -51,10 +51,10 @@ const addTracks = (browser: any) => {
// Watch changes to the genome (requires full reload).
watch(
() => props.genome,
() => props.genomeRelease,
() => {
;(igvBrowser.value! as GenomeBrowser)
.loadGenome(translateGenome(props.genome))
.loadGenome(translateGenome(props.genomeRelease))
.then((browser: GenomeBrowser) => {
browser.search(props.locus)
})
Expand All @@ -78,7 +78,7 @@ watch(
onMounted(() => {
igv
.createBrowser(genomeBrowserDivRef.value, {
genome: translateGenome(props.genome),
genome: translateGenome(props.genomeRelease),
locus: props.locus
})
.then((browser: GenomeBrowser) => {
Expand All @@ -92,9 +92,11 @@ onMounted(() => {
</script>

<template>
<v-card>
<v-card-title>Genome Browser</v-card-title>
<v-divider />
<div ref="genomeBrowserDivRef" style="margin: 5px" />
<v-card class="mt-3">
<v-card-title class="pb-0"> Genome Browser </v-card-title>
<v-card-text>
<div ref="genomeBrowserDivRef" style="margin: 5px" />
</v-card-text>
</v-card>
</template>
@/lib/GenomeBrowser.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ const ACMG_CRITERIA_CNV_DEFS: Map<
description: `Reported proband (from literature, public databases, or internal lab data) has either:
• A complete deletion of or a LOF variant within gene encompassed by the observed
copy-number loss OR
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
the reported phenotype is highly specific and relatively unique to the gene or
genomic region,`,
conflictingEvidence: [AcmgCriteriaCNVLoss.Loss4B, AcmgCriteriaCNVLoss.Loss4C],
Expand All @@ -568,7 +568,7 @@ const ACMG_CRITERIA_CNV_DEFS: Map<
description: `Reported proband (from literature, public databases, or internal lab data) has either:
• A complete deletion of or a LOF variant within gene encompassed by the observed
copy-number loss OR
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
the reported phenotype is consistent with the gene/genomic region, is highly
specific, but not necessarily unique to the gene/genomic region.`,
conflictingEvidence: [AcmgCriteriaCNVLoss.Loss4A, AcmgCriteriaCNVLoss.Loss4C],
Expand All @@ -584,7 +584,7 @@ const ACMG_CRITERIA_CNV_DEFS: Map<
description: `Reported proband (from literature, public databases, or internal lab data) has either:
• A complete deletion of or a LOF variant within gene encompassed by the observed
copy-number loss OR
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
the reported phenotype is consistent with the gene/genomic region, but not highly
specific and/or with high genetic heterogeneity.`,
conflictingEvidence: [AcmgCriteriaCNVLoss.Loss4A, AcmgCriteriaCNVLoss.Loss4B],
Expand All @@ -600,7 +600,7 @@ const ACMG_CRITERIA_CNV_DEFS: Map<
description: `Reported proband (from literature, public databases, or internal lab data) has either:
• A complete deletion of or a LOF variant within gene encompassed by the observed
copy-number loss OR
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
• An overlapping copy-number loss similar in genomic content to the observed copynumber loss AND
the reported phenotype is NOT consistent with what is expected for the gene/
genomic region or not consistent in general.`,
conflictingEvidence: [],
Expand Down Expand Up @@ -740,7 +740,7 @@ const ACMG_CRITERIA_CNV_DEFS: Map<
minScore: 0,
maxScore: 0.45,
label: '5A',
hint: `Observed copy-number loss is de novo. Use de novo scoring categories from section 4
hint: `Observed copy-number loss is de novo. Use de novo scoring categories from section 4
(4A-4D) to determine score`,
description: `Use appropriate category from de novo scoring section in section 4.`,
conflictingEvidence: [
Expand Down
Loading

0 comments on commit 0d8dd34

Please sign in to comment.