/// <summary> /// get the shorted intron offset from the nearest exon /// </summary> private void GetIntronOffset(CdnaCoordinateMap prevExon, CdnaCoordinateMap exon, int?position, PositionOffset po) { int?upDist = position - prevExon.GenomicEnd; int?downDist = exon.GenomicStart - position; int tempCdnaBegin, tempCdnaEnd; if (upDist < downDist || upDist == downDist && !_transcript.Gene.OnReverseStrand) { // distance to upstream exon is the shortest (or equal and in the positive orientation) TranscriptUtilities.GetCodingDnaEndpoints(_transcript.CdnaMaps, prevExon.GenomicStart, prevExon.GenomicEnd, out tempCdnaBegin, out tempCdnaEnd); if (_transcript.Gene.OnReverseStrand) { po.Position = tempCdnaBegin; po.Offset = -upDist; } else { po.Position = tempCdnaEnd; po.Offset = upDist; } } else { // distance to downstream exon is the shortest TranscriptUtilities.GetCodingDnaEndpoints(_transcript.CdnaMaps, exon.GenomicStart, exon.GenomicEnd, out tempCdnaBegin, out tempCdnaEnd); if (_transcript.Gene.OnReverseStrand) { po.Position = tempCdnaEnd; po.Offset = downDist; } else { po.Position = tempCdnaBegin; po.Offset = -downDist; } } }
/// <summary> /// gets the variant position (with intron offset) in the transcript [TranscriptVariationAllele.pm:1805 _get_cDNA_position] /// </summary> private void GetCdnaPosition(PositionOffset po) { int?position = po.Position; // start and stop coordinate relative to transcript. Take into account which // strand we're working on position = _transcript.Gene.OnReverseStrand ? _transcript.End - position + 1 : _transcript.Start + position - 1; // loop over the exons and get the coordinates of the variation in exon+intron notation var exons = _transcript.CdnaMaps; for (int exonIndex = 0; exonIndex < exons.Length; exonIndex++) { var exon = exons[exonIndex]; // skip if the start point is beyond this exon if (position > exon.GenomicEnd) { continue; } // EXONIC: if the start coordinate is within this exon if (position >= exon.GenomicStart) { // get the cDNA start coordinate of the exon and add the number of nucleotides // from the exon boundary to the variation. If the transcript is in the opposite // direction, count from the end instead int tempCdnaEnd, tempCdnaBegin; TranscriptUtilities.GetCodingDnaEndpoints(_transcript.CdnaMaps, exon.GenomicStart, exon.GenomicEnd, out tempCdnaBegin, out tempCdnaEnd); po.Position = tempCdnaBegin + (_transcript.Gene.OnReverseStrand ? exon.GenomicEnd - position : position - exon.GenomicStart); break; } // INTRONIC: the start coordinate is between this exon and the previous one, determine which one is closest and get coordinates relative to that one // sanity check: make sure we have at least passed one exon if (exonIndex < 1) { po.Position = null; return; } var prevExon = exons[exonIndex - 1]; GetIntronOffset(prevExon, exon, position, po); break; } // start by correcting for the stop codon int startCodon = _transcript.Translation == null ? -1 : _transcript.Translation.CodingRegion.CdnaStart; int stopCodon = _transcript.Translation == null ? -1 : _transcript.Translation.CodingRegion.CdnaEnd; string cdnaCoord = po.Position.ToString(); po.HasStopCodonNotation = false; bool hasNoPosition = false; if (stopCodon != -1) { if (po.Position > stopCodon) { cdnaCoord = '*' + (po.Position - stopCodon).ToString(); po.HasStopCodonNotation = true; } else if (po.Offset != null && po.Position == stopCodon) { cdnaCoord = "*"; po.HasStopCodonNotation = true; hasNoPosition = true; } } if (!po.HasStopCodonNotation && startCodon != -1) { cdnaCoord = (po.Position + (po.Position >= startCodon ? 1 : 0) - startCodon).ToString(); } // re-assemble the cDNA position [ return exon num & offset & direction for intron eg. 142+363] if (hasNoPosition) { po.Value = "*" + po.Offset; } else { po.Value = cdnaCoord + (po.Offset == null ? "" : ((int)po.Offset).ToString("+0;-0;+0")); } }