From af2a1436c79fe274384a78274480b58b5da52e33 Mon Sep 17 00:00:00 2001 From: Phil Darnowsky Date: Mon, 12 Aug 2024 14:10:56 -0400 Subject: [PATCH 1/6] Remove unused VA noncodingTranscriptError quality measure --- graphql-api/src/graphql/types/va.graphql | 1 - 1 file changed, 1 deletion(-) diff --git a/graphql-api/src/graphql/types/va.graphql b/graphql-api/src/graphql/types/va.graphql index 03017146d..cb4c95b45 100644 --- a/graphql-api/src/graphql/types/va.graphql +++ b/graphql-api/src/graphql/types/va.graphql @@ -96,7 +96,6 @@ type VAQualityMeasures { lowComplexityRegion: Boolean lowConfidenceLossOfFunctionError: Boolean lossOfFunctionWarning: Boolean - noncodingTranscriptError: Boolean heterozygousSkewedAlleleCount: Int } From 56c2a6ea76e6f5527f9e5f2a8df2ed38dc338b76 Mon Sep 17 00:00:00 2001 From: Phil Darnowsky Date: Tue, 13 Aug 2024 13:05:41 -0400 Subject: [PATCH 2/6] Add mean depth VA quality measure --- graphql-api/src/graphql/resolvers/va.spec.ts | 21 +++++++++++++++ graphql-api/src/graphql/resolvers/va.ts | 28 ++++++++++++++++++++ graphql-api/src/graphql/types/va.graphql | 2 ++ 3 files changed, 51 insertions(+) diff --git a/graphql-api/src/graphql/resolvers/va.spec.ts b/graphql-api/src/graphql/resolvers/va.spec.ts index 1df264fa4..1be80870f 100644 --- a/graphql-api/src/graphql/resolvers/va.spec.ts +++ b/graphql-api/src/graphql/resolvers/va.spec.ts @@ -76,6 +76,7 @@ describe('resolveVACohortAlleleFrequency', () => { exome: exomeEsDocument, genome: genomeEsDocument, joint: { fafmax: { faf95_max: 0.234, faf95_max_gen_anc: 'amr' } }, + coverage: { exome: { mean: 0.345 }, genome: { mean: 0.456 } }, } test('parses a single CohortAlleleFrequency exome correctly', async () => { @@ -103,6 +104,16 @@ describe('resolveVACohortAlleleFrequency', () => { hemizygotes: 2, }, subcohortFrequency: [], + qualityMeasures: { + meanDepth: 0.345, + fractionCoverage20x: null, + monoallelic: null, + qcFilters: null, + lowComplexityRegion: null, + lowConfidenceLossOfFunctionError: null, + lossOfFunctionWarning: null, + heterozygousSkewedAlleleCount: null, + }, }, ] @@ -134,6 +145,16 @@ describe('resolveVACohortAlleleFrequency', () => { hemizygotes: 4, }, subcohortFrequency: [], + qualityMeasures: { + meanDepth: 0.456, + fractionCoverage20x: null, + monoallelic: null, + qcFilters: null, + lowComplexityRegion: null, + lowConfidenceLossOfFunctionError: null, + lossOfFunctionWarning: null, + heterozygousSkewedAlleleCount: null, + }, }, ] diff --git a/graphql-api/src/graphql/resolvers/va.ts b/graphql-api/src/graphql/resolvers/va.ts index 790c3d33e..c637e8621 100644 --- a/graphql-api/src/graphql/resolvers/va.ts +++ b/graphql-api/src/graphql/resolvers/va.ts @@ -93,6 +93,17 @@ type AncillaryResults = { hemizygotes: number | null } +type QualityMeasures = { + meanDepth: number | null + fractionCoverage20x: number | null + qcFilters: string[] | null + monoallelic: boolean | null + lowComplexityRegion: boolean | null + lowConfidenceLossOfFunctionError: boolean | null + lossOfFunctionWarning: boolean | null + heterozygousSkewedAlleleCount: number | null +} + export type CohortAlleleFrequency = { id: string type: string @@ -104,6 +115,7 @@ export type CohortAlleleFrequency = { alleleFrequency: number cohort: Cohort ancillaryResults: AncillaryResults | null + qualityMeasures: QualityMeasures | null subcohortFrequency: CohortAlleleFrequency[] } @@ -187,6 +199,7 @@ type Subset = { homozygote_count: number grpMax?: GrpMaxFAF95 jointGrpMax?: GrpMaxFAF95 + meanDepth: number } const GNOMAD_V4_DERIVATION = { @@ -268,6 +281,18 @@ const resolveVACohortAlleleFrequency = ( hemizygotes: subset.hemizygote_count !== undefined ? subset.hemizygote_count : null, } + // const coverage = obj.coverage.exome && obj.coverage.exome + const qualityMeasures = { + meanDepth: subset.meanDepth, + fractionCoverage20x: null, // TK + qcFilters: null, // TK + monoallelic: null, // TK + lowComplexityRegion: null, // TK + lowConfidenceLossOfFunctionError: null, // TK + lossOfFunctionWarning: null, // TK + heterozygousSkewedAlleleCount: null, // TK + } + return { id, label, @@ -279,6 +304,7 @@ const resolveVACohortAlleleFrequency = ( alleleFrequency: subset.ac / subset.an, cohort, ancillaryResults, + qualityMeasures, } } @@ -382,6 +408,7 @@ const resolveVACohortAlleleFrequencies = async ( if (!frequencies) { return null } + const coverage = obj.coverage[frequencyField] const fullSet: Subset = { ac: frequencies.ac, @@ -401,6 +428,7 @@ const resolveVACohortAlleleFrequencies = async ( confidenceInterval: 0.95, } : undefined, + meanDepth: coverage && coverage.mean ? coverage.mean : null, } const subsets = [fullSet, ...(frequencies.ancestry_groups as Subset[])] const cohortsWithoutSubcohorts = subsets.map((subset) => diff --git a/graphql-api/src/graphql/types/va.graphql b/graphql-api/src/graphql/types/va.graphql index cb4c95b45..9c1656746 100644 --- a/graphql-api/src/graphql/types/va.graphql +++ b/graphql-api/src/graphql/types/va.graphql @@ -117,6 +117,8 @@ type VACohortAlleleFrequencyData { cohort: VACohort! "Ancillary results that may be associated with the CohortAlleleFrequency, providing additional context or information." ancillaryResults: VAAncillaryResults + "Metrics of quality of, or confidence in, the CohortAlleleFrequency." + qualityMeasures: VAQualityMeasures """ A list of CohortAlleleFrequency objects describing subcohorts of the cohort currently being described. This creates a recursive relationship and subcohorts can be further subdivided into more subcohorts. From eca5109f2576e17402316f29dc77c54f6dd2d445 Mon Sep 17 00:00:00 2001 From: Phil Darnowsky Date: Tue, 13 Aug 2024 13:13:52 -0400 Subject: [PATCH 3/6] Add fraction with 20X coverage VA quality measure --- graphql-api/src/graphql/resolvers/va.spec.ts | 8 +++--- graphql-api/src/graphql/resolvers/va.ts | 29 ++++++++++---------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/graphql-api/src/graphql/resolvers/va.spec.ts b/graphql-api/src/graphql/resolvers/va.spec.ts index 1be80870f..a5b22a2f9 100644 --- a/graphql-api/src/graphql/resolvers/va.spec.ts +++ b/graphql-api/src/graphql/resolvers/va.spec.ts @@ -76,7 +76,7 @@ describe('resolveVACohortAlleleFrequency', () => { exome: exomeEsDocument, genome: genomeEsDocument, joint: { fafmax: { faf95_max: 0.234, faf95_max_gen_anc: 'amr' } }, - coverage: { exome: { mean: 0.345 }, genome: { mean: 0.456 } }, + coverage: { exome: { mean: 0.345, over_20: 0.456 }, genome: { mean: 0.111, over_20: 0.222 } }, } test('parses a single CohortAlleleFrequency exome correctly', async () => { @@ -106,7 +106,7 @@ describe('resolveVACohortAlleleFrequency', () => { subcohortFrequency: [], qualityMeasures: { meanDepth: 0.345, - fractionCoverage20x: null, + fractionCoverage20x: 0.456, monoallelic: null, qcFilters: null, lowComplexityRegion: null, @@ -146,8 +146,8 @@ describe('resolveVACohortAlleleFrequency', () => { }, subcohortFrequency: [], qualityMeasures: { - meanDepth: 0.456, - fractionCoverage20x: null, + meanDepth: 0.111, + fractionCoverage20x: 0.222, monoallelic: null, qcFilters: null, lowComplexityRegion: null, diff --git a/graphql-api/src/graphql/resolvers/va.ts b/graphql-api/src/graphql/resolvers/va.ts index c637e8621..d90773537 100644 --- a/graphql-api/src/graphql/resolvers/va.ts +++ b/graphql-api/src/graphql/resolvers/va.ts @@ -199,7 +199,7 @@ type Subset = { homozygote_count: number grpMax?: GrpMaxFAF95 jointGrpMax?: GrpMaxFAF95 - meanDepth: number + qualityMeasures: QualityMeasures } const GNOMAD_V4_DERIVATION = { @@ -281,18 +281,6 @@ const resolveVACohortAlleleFrequency = ( hemizygotes: subset.hemizygote_count !== undefined ? subset.hemizygote_count : null, } - // const coverage = obj.coverage.exome && obj.coverage.exome - const qualityMeasures = { - meanDepth: subset.meanDepth, - fractionCoverage20x: null, // TK - qcFilters: null, // TK - monoallelic: null, // TK - lowComplexityRegion: null, // TK - lowConfidenceLossOfFunctionError: null, // TK - lossOfFunctionWarning: null, // TK - heterozygousSkewedAlleleCount: null, // TK - } - return { id, label, @@ -304,7 +292,7 @@ const resolveVACohortAlleleFrequency = ( alleleFrequency: subset.ac / subset.an, cohort, ancillaryResults, - qualityMeasures, + qualityMeasures: subset.qualityMeasures, } } @@ -410,6 +398,17 @@ const resolveVACohortAlleleFrequencies = async ( } const coverage = obj.coverage[frequencyField] + const qualityMeasures = { + meanDepth: coverage && coverage.mean ? coverage.mean : null, + fractionCoverage20x: coverage && coverage.over_20 ? coverage.over_20 : null, + monoallelic: null, + qcFilters: null, + lowComplexityRegion: null, + lowConfidenceLossOfFunctionError: null, + lossOfFunctionWarning: null, + heterozygousSkewedAlleleCount: null, + } + const fullSet: Subset = { ac: frequencies.ac, an: frequencies.an, @@ -428,7 +427,7 @@ const resolveVACohortAlleleFrequencies = async ( confidenceInterval: 0.95, } : undefined, - meanDepth: coverage && coverage.mean ? coverage.mean : null, + qualityMeasures, } const subsets = [fullSet, ...(frequencies.ancestry_groups as Subset[])] const cohortsWithoutSubcohorts = subsets.map((subset) => From 7357962afa2453fcaba70243cb6757c62ee6915c Mon Sep 17 00:00:00 2001 From: Phil Darnowsky Date: Tue, 13 Aug 2024 15:48:52 -0400 Subject: [PATCH 4/6] Add QC filters to VA --- graphql-api/src/graphql/resolvers/va.spec.ts | 3 ++- graphql-api/src/graphql/resolvers/va.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/graphql-api/src/graphql/resolvers/va.spec.ts b/graphql-api/src/graphql/resolvers/va.spec.ts index a5b22a2f9..70df4182f 100644 --- a/graphql-api/src/graphql/resolvers/va.spec.ts +++ b/graphql-api/src/graphql/resolvers/va.spec.ts @@ -59,6 +59,7 @@ describe('resolveVACohortAlleleFrequency', () => { homozygote_count: 3, faf95: { popmax: 0.123, popmax_population: 'afr' }, ancestry_groups: [], + filters: ['AC0'], } const genomeEsDocument = { @@ -107,8 +108,8 @@ describe('resolveVACohortAlleleFrequency', () => { qualityMeasures: { meanDepth: 0.345, fractionCoverage20x: 0.456, + qcFilters: ['AC0'], monoallelic: null, - qcFilters: null, lowComplexityRegion: null, lowConfidenceLossOfFunctionError: null, lossOfFunctionWarning: null, diff --git a/graphql-api/src/graphql/resolvers/va.ts b/graphql-api/src/graphql/resolvers/va.ts index d90773537..279a59a44 100644 --- a/graphql-api/src/graphql/resolvers/va.ts +++ b/graphql-api/src/graphql/resolvers/va.ts @@ -401,8 +401,8 @@ const resolveVACohortAlleleFrequencies = async ( const qualityMeasures = { meanDepth: coverage && coverage.mean ? coverage.mean : null, fractionCoverage20x: coverage && coverage.over_20 ? coverage.over_20 : null, + qcFilters: frequencies.filters, monoallelic: null, - qcFilters: null, lowComplexityRegion: null, lowConfidenceLossOfFunctionError: null, lossOfFunctionWarning: null, From 7f3098829727bf1e3986783499cc9721070eb69e Mon Sep 17 00:00:00 2001 From: Phil Darnowsky Date: Tue, 13 Aug 2024 15:43:42 -0400 Subject: [PATCH 5/6] Add variant QA flags to VA --- graphql-api/src/graphql/resolvers/va.spec.ts | 22 ++++++++++++-------- graphql-api/src/graphql/resolvers/va.ts | 8 +++---- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/graphql-api/src/graphql/resolvers/va.spec.ts b/graphql-api/src/graphql/resolvers/va.spec.ts index 70df4182f..874c4275f 100644 --- a/graphql-api/src/graphql/resolvers/va.spec.ts +++ b/graphql-api/src/graphql/resolvers/va.spec.ts @@ -60,6 +60,7 @@ describe('resolveVACohortAlleleFrequency', () => { faf95: { popmax: 0.123, popmax_population: 'afr' }, ancestry_groups: [], filters: ['AC0'], + flags: ['monoallelic'], } const genomeEsDocument = { @@ -68,7 +69,9 @@ describe('resolveVACohortAlleleFrequency', () => { hemizygote_count: 4, homozygote_count: 5, faf95: { popmax: 0.234, popmax_population: 'eas' }, + filters: ['AC0'], ancestry_groups: [], + flags: ['monoallelic'], } const variantESDocument = { @@ -78,6 +81,7 @@ describe('resolveVACohortAlleleFrequency', () => { genome: genomeEsDocument, joint: { fafmax: { faf95_max: 0.234, faf95_max_gen_anc: 'amr' } }, coverage: { exome: { mean: 0.345, over_20: 0.456 }, genome: { mean: 0.111, over_20: 0.222 } }, + flags: ['lcr', 'lc_lof', 'lof_flag'], } test('parses a single CohortAlleleFrequency exome correctly', async () => { @@ -109,10 +113,10 @@ describe('resolveVACohortAlleleFrequency', () => { meanDepth: 0.345, fractionCoverage20x: 0.456, qcFilters: ['AC0'], - monoallelic: null, - lowComplexityRegion: null, - lowConfidenceLossOfFunctionError: null, - lossOfFunctionWarning: null, + monoallelic: true, + lowComplexityRegion: true, + lowConfidenceLossOfFunctionError: true, + lossOfFunctionWarning: true, heterozygousSkewedAlleleCount: null, }, }, @@ -149,11 +153,11 @@ describe('resolveVACohortAlleleFrequency', () => { qualityMeasures: { meanDepth: 0.111, fractionCoverage20x: 0.222, - monoallelic: null, - qcFilters: null, - lowComplexityRegion: null, - lowConfidenceLossOfFunctionError: null, - lossOfFunctionWarning: null, + monoallelic: true, + qcFilters: ['AC0'], + lowComplexityRegion: true, + lowConfidenceLossOfFunctionError: true, + lossOfFunctionWarning: true, heterozygousSkewedAlleleCount: null, }, }, diff --git a/graphql-api/src/graphql/resolvers/va.ts b/graphql-api/src/graphql/resolvers/va.ts index 279a59a44..309a066e2 100644 --- a/graphql-api/src/graphql/resolvers/va.ts +++ b/graphql-api/src/graphql/resolvers/va.ts @@ -402,10 +402,10 @@ const resolveVACohortAlleleFrequencies = async ( meanDepth: coverage && coverage.mean ? coverage.mean : null, fractionCoverage20x: coverage && coverage.over_20 ? coverage.over_20 : null, qcFilters: frequencies.filters, - monoallelic: null, - lowComplexityRegion: null, - lowConfidenceLossOfFunctionError: null, - lossOfFunctionWarning: null, + monoallelic: frequencies.flags.includes('monoallelic'), + lowComplexityRegion: obj.flags.includes('lcr'), + lowConfidenceLossOfFunctionError: obj.flags.includes('lc_lof'), + lossOfFunctionWarning: obj.flags.includes('lof_flag'), heterozygousSkewedAlleleCount: null, } From aaf676d021c4d2dd965284262193df940f77c1a0 Mon Sep 17 00:00:00 2001 From: Phil Darnowsky Date: Wed, 14 Aug 2024 16:34:37 -0400 Subject: [PATCH 6/6] Add heterozygous skewed allele count to VA --- graphql-api/src/graphql/resolvers/va.spec.ts | 19 ++++++++++++++++-- graphql-api/src/graphql/resolvers/va.ts | 21 +++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/graphql-api/src/graphql/resolvers/va.spec.ts b/graphql-api/src/graphql/resolvers/va.spec.ts index 874c4275f..b0eb11bcb 100644 --- a/graphql-api/src/graphql/resolvers/va.spec.ts +++ b/graphql-api/src/graphql/resolvers/va.spec.ts @@ -61,6 +61,11 @@ describe('resolveVACohortAlleleFrequency', () => { ancestry_groups: [], filters: ['AC0'], flags: ['monoallelic'], + quality_metrics: { + allele_balance: { + alt: { bin_freq: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] }, + }, + }, } const genomeEsDocument = { @@ -72,6 +77,16 @@ describe('resolveVACohortAlleleFrequency', () => { filters: ['AC0'], ancestry_groups: [], flags: ['monoallelic'], + quality_metrics: { + allele_balance: { + alt: { + bin_freq: [ + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, + ], + }, + }, + }, } const variantESDocument = { @@ -117,7 +132,7 @@ describe('resolveVACohortAlleleFrequency', () => { lowComplexityRegion: true, lowConfidenceLossOfFunctionError: true, lossOfFunctionWarning: true, - heterozygousSkewedAlleleCount: null, + heterozygousSkewedAlleleCount: 37, }, }, ] @@ -158,7 +173,7 @@ describe('resolveVACohortAlleleFrequency', () => { lowComplexityRegion: true, lowConfidenceLossOfFunctionError: true, lossOfFunctionWarning: true, - heterozygousSkewedAlleleCount: null, + heterozygousSkewedAlleleCount: 237, }, }, ] diff --git a/graphql-api/src/graphql/resolvers/va.ts b/graphql-api/src/graphql/resolvers/va.ts index 309a066e2..0e8401d97 100644 --- a/graphql-api/src/graphql/resolvers/va.ts +++ b/graphql-api/src/graphql/resolvers/va.ts @@ -381,6 +381,25 @@ const addSubcohorts = ( return Object.values(subcohortMap) } +type ESFrequencies = { + quality_metrics: { + allele_balance: { + alt?: { + bin_freq: number[] + } + } + } +} + +const calculateHeterozygousSkewedAlleleCount = (frequencies: ESFrequencies): number | null => { + const { alt } = frequencies.quality_metrics.allele_balance + if (!alt) { + return null + } + + return alt.bin_freq[18] + alt.bin_freq[19] +} + const resolveVACohortAlleleFrequencies = async ( obj: any, args: any, @@ -406,7 +425,7 @@ const resolveVACohortAlleleFrequencies = async ( lowComplexityRegion: obj.flags.includes('lcr'), lowConfidenceLossOfFunctionError: obj.flags.includes('lc_lof'), lossOfFunctionWarning: obj.flags.includes('lof_flag'), - heterozygousSkewedAlleleCount: null, + heterozygousSkewedAlleleCount: calculateHeterozygousSkewedAlleleCount(frequencies), } const fullSet: Subset = {