Skip to content

Commit

Permalink
Add VRS data to GraphQL API
Browse files Browse the repository at this point in the history
  • Loading branch information
phildarnowsky-broad committed Jun 24, 2024
1 parent 747900b commit 83cb92c
Show file tree
Hide file tree
Showing 9 changed files with 802 additions and 35 deletions.
22 changes: 22 additions & 0 deletions dataset-metadata/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export type DatasetMetadata = {
structuralVariantDatasetId: DatasetId
copyNumberVariantDatasetId: DatasetId
hasJointFrequencyData: boolean
hasVRSData: boolean
}

const metadata: Record<DatasetId, DatasetMetadata> = {
Expand Down Expand Up @@ -124,6 +125,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r2_1: {
isSubset: false,
Expand Down Expand Up @@ -173,6 +175,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r2_1_controls: {
isSubset: true,
Expand Down Expand Up @@ -222,6 +225,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r2_1_non_cancer: {
isSubset: true,
Expand Down Expand Up @@ -271,6 +275,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r2_1_non_neuro: {
isSubset: true,
Expand Down Expand Up @@ -320,6 +325,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r2_1_non_topmed: {
isSubset: true,
Expand Down Expand Up @@ -369,6 +375,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r3: {
isSubset: false,
Expand Down Expand Up @@ -418,6 +425,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r3_controls_and_biobanks: {
isSubset: true,
Expand Down Expand Up @@ -467,6 +475,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r3_non_cancer: {
isSubset: true,
Expand Down Expand Up @@ -516,6 +525,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r3_non_neuro: {
isSubset: true,
Expand Down Expand Up @@ -565,6 +575,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r3_non_topmed: {
isSubset: true,
Expand Down Expand Up @@ -614,6 +625,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_r3_non_v2: {
isSubset: true,
Expand Down Expand Up @@ -663,6 +675,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_sv_r2_1: {
isSubset: false,
Expand Down Expand Up @@ -712,6 +725,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_sv_r2_1_controls: {
isSubset: true,
Expand Down Expand Up @@ -761,6 +775,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_sv_r2_1_non_neuro: {
isSubset: true,
Expand Down Expand Up @@ -810,6 +825,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: false,
hasVRSData: false,
},
gnomad_sv_r4: {
isSubset: false,
Expand Down Expand Up @@ -859,6 +875,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: true,
hasVRSData: false,
},
gnomad_cnv_r4: {
isSubset: false,
Expand Down Expand Up @@ -908,6 +925,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: true,
hasJointFrequencyData: true,
hasVRSData: false,
},
gnomad_r4: {
isSubset: false,
Expand Down Expand Up @@ -957,6 +975,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
copyNumberVariantDatasetId: 'gnomad_cnv_r4',
hasCopyNumberVariantCoverage: false,
hasJointFrequencyData: true,
hasVRSData: true,
},
gnomad_r4_non_ukb: {
isSubset: true,
Expand Down Expand Up @@ -1006,6 +1025,7 @@ const metadata: Record<DatasetId, DatasetMetadata> = {
hasCopyNumberVariantCoverage: false,
hasRelatedVariants: true,
hasJointFrequencyData: false,
hasVRSData: true,
},
}

Expand Down Expand Up @@ -1156,3 +1176,5 @@ export const getTopLevelDataset = (datasetId: DatasetId) => {

return 'default'
}

export const hasVRSData = (datasetId: DatasetId) => getMetadata(datasetId, 'hasVRSData')
175 changes: 175 additions & 0 deletions graphql-api/src/graphql/resolvers/va.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { describe, expect, test } from '@jest/globals'

import {
resolveVACohortAlleleFrequencies,
resolveVAAllele,
Allele as VAAllele,
CohortAlleleFrequency,
} from './va'

const alleleEsDocument = {
vrs: {
ref: {
allele_id: 'ga4gh:SQ.IAmTheRefStateID',
start: 123,
end: 234,
state: 'G',
},
alt: {
allele_id: 'ga4gh:SQ.IAmTheAltStateID',
start: 124,
end: 235,
state: 'A',
},
},
}

const expectedAllele: VAAllele = {
_id: 'ga4gh:SQ.IAmTheAltStateID',
type: 'Allele',
location: {
_id: 'ga4gh:VSL.OogSNIt-1Z7HF4tbdm45IDLYc7-oSE2Y',
type: 'SequenceLocation',
sequence_id: '2mN7PzLXx-QQq2GVIODPRSkWmlwybsv0',
interval: {
type: 'SequenceInterval',
start: { type: 'Number', value: 124 },
end: { type: 'Number', value: 235 },
},
},
state: {
type: 'LiteralSequenceExpression',
sequence: 'A',
},
}

describe('resolveVAAllele', () => {
test('parses a single allele correctly', async () => {
const resolved = await resolveVAAllele(alleleEsDocument, null, null)
expect(resolved).toEqual(expectedAllele)
})
})

describe('resolveVACohortAlleleFrequency', () => {
const exomeEsDocument = {
ac: 5,
an: 100,
hemizygote_count: 2,
homozygote_count: 3,
faf95: { popmax: 0.123, popmax_population: 'afr' },
ancestry_groups: [],
}

const variantESDocument = {
...alleleEsDocument,
variant_id: '1-123-G-A',
exome: exomeEsDocument,
joint: { fafmax: { faf95_max: 0.234, faf95_max_gen_anc: 'amr' } },
}

test('parses a single CohortAlleleFrequency correctly', async () => {
const resolved = await resolveVACohortAlleleFrequencies(variantESDocument, null, null)
const expected: CohortAlleleFrequency[] = [
{
id: 'gnomad4:1-123-G-A',
label: 'Overall Cohort Allele Frequency for 1-123-G-A',
type: 'CohortAlleleFrequency',
focusAllele: expectedAllele,
derivedFrom: {
id: 'gnomad4.1.0',
type: 'DataSet',
label: 'gnomAD v4.1.0',
version: '4.1.0',
},
focusAlleleCount: 5,
locusAlleleCount: 100,
alleleFrequency: 0.05,
cohort: { id: 'ALL', label: 'Overall', characteristics: null },
ancillaryResults: {
grpMaxFAF95: { frequency: 0.123, confidenceInterval: 0.95, groupId: 'afr' },
jointGrpMaxFAF95: { frequency: 0.234, confidenceInterval: 0.95, groupId: 'amr' },
homozygotes: 3,
hemizygotes: 2,
},
subcohortFrequency: [],
},
]

expect(resolved).toEqual(expected)
})

test('has the correct subcohortAlleleFrequency when there are multiple CAFs', async () => {
// Shuffled order of IDs is intentional here to better test sorting
const subcohortIds = [
'eur_XY',
'XY',
'ami_XX',
'amr',
'XX',
'ami',
'ami_XY',
'amr_XX',
'eur',
'amr_XY',
'eur_XX',
]
const subcohortDocuments = subcohortIds.map((subcohortId) => ({
...exomeEsDocument,
id: subcohortId,
}))

const fullDocument = {
...variantESDocument,
exome: { ...exomeEsDocument, ancestry_groups: subcohortDocuments },
}

const resolved = await resolveVACohortAlleleFrequencies(fullDocument, null, null)
expect(resolved && resolved.length === subcohortIds.length + 1).toEqual(true)

const subcohortMap: Record<string, string[]> = resolved!.reduce(
(acc, cohort) => ({
...acc,
[cohort.id]: cohort.subcohortFrequency.map((subcohort) => subcohort.id),
}),
{}
)

expect(subcohortMap['gnomad4:1-123-G-A']!.sort()).toEqual(
subcohortIds.map((cohortId) => `gnomad4:1-123-G-A.${cohortId}`).sort()
)

expect(subcohortMap['gnomad4:1-123-G-A.XX'].sort()).toEqual([
'gnomad4:1-123-G-A.ami_XX',
'gnomad4:1-123-G-A.amr_XX',
'gnomad4:1-123-G-A.eur_XX',
])

expect(subcohortMap['gnomad4:1-123-G-A.XY'].sort()).toEqual([
'gnomad4:1-123-G-A.ami_XY',
'gnomad4:1-123-G-A.amr_XY',
'gnomad4:1-123-G-A.eur_XY',
])

expect(subcohortMap['gnomad4:1-123-G-A.ami'].sort()).toEqual([
'gnomad4:1-123-G-A.ami_XX',
'gnomad4:1-123-G-A.ami_XY',
])

expect(subcohortMap['gnomad4:1-123-G-A.amr'].sort()).toEqual([
'gnomad4:1-123-G-A.amr_XX',
'gnomad4:1-123-G-A.amr_XY',
])

expect(subcohortMap['gnomad4:1-123-G-A.eur'].sort()).toEqual([
'gnomad4:1-123-G-A.eur_XX',
'gnomad4:1-123-G-A.eur_XY',
])

expect(subcohortMap['gnomad4:1-123-G-A.ami_XX']).toEqual([])
expect(subcohortMap['gnomad4:1-123-G-A.ami_XY']).toEqual([])
expect(subcohortMap['gnomad4:1-123-G-A.amr_XX']).toEqual([])
expect(subcohortMap['gnomad4:1-123-G-A.amr_XY']).toEqual([])
expect(subcohortMap['gnomad4:1-123-G-A.eur_XX']).toEqual([])
expect(subcohortMap['gnomad4:1-123-G-A.eur_XY']).toEqual([])
})
})
Loading

0 comments on commit 83cb92c

Please sign in to comment.