diff --git a/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.spec.tsx b/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.spec.tsx index 871d5353a..9d60f7f98 100644 --- a/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.spec.tsx +++ b/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.spec.tsx @@ -290,5 +290,46 @@ describe('ClinvarAllVariantsPlot', () => { expect(() => plotLayoutMatches(expectedPlotLayout, plotBody)).not.toThrowError() expect(tree).toMatchSnapshot() }) + + test('clamps end to end of the downstream UTR when the end in the HGVSP is "?"', () => { + const variant = { ...baseVariant, hgvsp: 'p.Tyr30SerfsTer?' } + const tree = render( + + ).asFragment() + const plotBody = extractPlotFragment(tree) + + const plotLayouts: Record = { + '+': [ + ['overlay', 310, 822 - 310], + ['cds', 310, 322], + ['utr', 322, 423], + ['cds', 423, 522], + ['utr', 522, 623], + ['cds', 623, 722], + ['utr', 723, 822], + ['stop_marker', 822], + ], + '-': [ + ['overlay', 123, 635 - 123], + ['utr', 123, 222], + ['cds', 223, 322], + ['utr', 322, 423], + ['cds', 423, 522], + ['utr', 522, 623], + ['cds', 623, 635], + ['stop_marker', 123], + ], + } + const expectedPlotLayout = plotLayouts[strand] + + expect(() => plotLayoutMatches(expectedPlotLayout, plotBody)).not.toThrowError() + expect(tree).toMatchSnapshot() + }) }) }) diff --git a/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.tsx b/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.tsx index b5c69a1ca..5625d2ce0 100644 --- a/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.tsx +++ b/browser/src/ClinvarVariantsTrack/ClinvarAllVariantsPlot.tsx @@ -46,32 +46,29 @@ const getGlobalFrameshiftCoordinates = ( const codingAndDownstreamExons = exons.slice( exons.findIndex((exon: Exon) => exon.feature_type === 'CDS') ) - const codingRegionStart = - transcript.strand === '+' ? codingAndDownstreamExons[0].start : codingAndDownstreamExons[0].stop - // Termination site position may be "?" if the new reading frame does not encounter a stop codon // In this case, place the termination site at the end of the transcript const lastExon = codingAndDownstreamExons[codingAndDownstreamExons.length - 1] const transcriptEnd = transcript.strand === '+' ? lastExon.stop : lastExon.start + // Codon numbers are 1 indexed + const startOffsetFromCDS = position * 3 - 2 + + const { remainingIntervals, globalCoordinate: startCoordinate } = advanceOverIntervals( + codingAndDownstreamExons, + startOffsetFromCDS, + transcript.strand + ) if (terminationSitePosition === '?') { - return [codingRegionStart, transcriptEnd] + return [startCoordinate || transcriptEnd, transcriptEnd] } // Offset in bases from the start of the transcript's CDS region to the termination site - // Codon numbers are 1 indexed - const startOffsetFromCDS = position * 3 - 2 // The extra "+2" at the end is because we start at the first nucleotide of // the first codon, and end with the last nucleotide (rather than the first) // of some downstream codon. const lengthInNucleotides = (Number(terminationSitePosition) - 1) * 3 + 2 - // Both ends should always fall within an exon - const { remainingIntervals, globalCoordinate: startCoordinate } = advanceOverIntervals( - codingAndDownstreamExons, - startOffsetFromCDS, - transcript.strand - ) const { globalCoordinate: endCoordinate } = advanceOverIntervals( remainingIntervals, lengthInNucleotides, diff --git a/browser/src/ClinvarVariantsTrack/__snapshots__/ClinvarAllVariantsPlot.spec.tsx.snap b/browser/src/ClinvarVariantsTrack/__snapshots__/ClinvarAllVariantsPlot.spec.tsx.snap index f2f43d880..a8829bc16 100644 --- a/browser/src/ClinvarVariantsTrack/__snapshots__/ClinvarAllVariantsPlot.spec.tsx.snap +++ b/browser/src/ClinvarVariantsTrack/__snapshots__/ClinvarAllVariantsPlot.spec.tsx.snap @@ -1,5 +1,201 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`ClinvarAllVariantsPlot rendering a frameshift on strand + clamps end to end of the downstream UTR when the end in the HGVSP is "?" 1`] = ` + + + + + + + + Frameshift + + + + + + Other pLoF + + + + + + Missense / Inframe indel + + + + + + Splice region + + + + + + Synonymous / non-coding + + + + + + + + + + + + + + + + + + +`; + exports[`ClinvarAllVariantsPlot rendering a frameshift on strand + renders clamped to the end of the downstream UTR when the variant overruns the downstream UTR 1`] = ` `; +exports[`ClinvarAllVariantsPlot rendering a frameshift on strand - clamps end to end of the downstream UTR when the end in the HGVSP is "?" 1`] = ` + + + + + + + + Frameshift + + + + + + Other pLoF + + + + + + Missense / Inframe indel + + + + + + Splice region + + + + + + Synonymous / non-coding + + + + + + + + + + + + + + + + + + +`; + exports[`ClinvarAllVariantsPlot rendering a frameshift on strand - renders clamped to the end of the downstream UTR when the variant overruns the downstream UTR 1`] = `