2b1890d71cd3481a8244ee2ef2999f03c9b6e160 angie Mon Oct 7 15:14:52 2013 -0700 Fix for the latest bug uncovered by the tenacious users of MLQ #11775:a deletion that spans the UTR/CDS boundary was something I hadn't tested against yet. refs #11775 diff --git src/hg/lib/gpFx.c src/hg/lib/gpFx.c index 17cc5f1..b47b704 100644 --- src/hg/lib/gpFx.c +++ src/hg/lib/gpFx.c @@ -102,52 +102,61 @@ int exonOffset = 0, cdsOffset = 0; uint varStart = variant->chromStart, varEnd = variant->chromEnd; // If the variant begins upstream, handle that before looping on exons: if (varStart < pred->txStart && varEnd > pred->txStart) { txc.startInCdna = 0; if (varStart < pred->cdsEnd && varEnd > pred->cdsStart) txc.startInCds = 0; } int ii; for (ii = 0; ii < pred->exonCount; ii++) { uint exonStart = pred->exonStarts[ii], exonEnd = pred->exonEnds[ii]; uint exonCdsStart = max(pred->cdsStart, exonStart); uint exonCdsEnd = min(pred->cdsEnd, exonEnd); + uint exonCdsSize = 0; + if (exonCdsEnd > exonCdsStart) + exonCdsSize = exonCdsEnd - exonCdsStart; if (varStart >= exonStart && varStart < exonEnd) { txc.startInExon = TRUE; txc.startExonIx = ii; txc.startInCdna = exonOffset + varStart - exonStart; if (varStart >= pred->cdsStart && varStart < pred->cdsEnd) txc.startInCds = cdsOffset + varStart - exonCdsStart; + else if (varStart < pred->cdsStart && varEnd > pred->cdsStart) + // Variant spans the left UTR/CDS boundary; set cdsStart to 0: + txc.startInCds = 0; // If this is an insertion at the beginning of an exon, varEnd is at the end // of the preceding intron and its endInC* have not been set, so copy them over: if (varEnd == varStart) { txc.endInCdna = txc.startInCdna; txc.endInCds = txc.startInCds; } } if (varEnd > exonStart && varEnd <= exonEnd) { txc.endInExon = TRUE; txc.endExonIx = ii; txc.endInCdna = exonOffset + varEnd - exonStart; if (varEnd > pred->cdsStart && varEnd <= pred->cdsEnd) txc.endInCds = cdsOffset + varEnd - exonCdsStart; + else if (varEnd > pred->cdsEnd && varStart < pred->cdsEnd) + // Variant spans the right CDS/UTR boundary; set cdsEnd to cdsSize: + txc.endInCds = cdsOffset + exonCdsSize; // If this is an insertion at the end of an exon, varStart is at the beginning // of the following intron and its startInC* have not been set, so copy them over: if (varStart == varEnd) { txc.startInCdna = txc.endInCdna; txc.startInCds = txc.endInCds; } } if (ii < pred->exonCount - 1) { uint nextExonStart = pred->exonStarts[ii+1]; // 'exonIx' is actually an intronIx in this case: if (varStart >= exonEnd && varStart < nextExonStart) { txc.startExonIx = ii; @@ -165,40 +174,39 @@ txc.startInCds = 0; } } } if (varEnd > exonEnd && varEnd <= nextExonStart) { txc.endExonIx = ii; if (varStart < exonEnd) { // Variant ends in an intron, but it also overlaps the previous exon; // note the end in cDNA (and CDS if applicable): txc.endInCdna = exonOffset + exonEnd - exonStart; if (varEnd > pred->cdsStart && varStart < pred->cdsEnd) { if (exonStart < pred->cdsEnd) - txc.endInCds = cdsOffset + exonCdsEnd - exonCdsStart; + txc.endInCds = cdsOffset + exonCdsSize; else txc.endInCds = cdsOffset; } } } } exonOffset += exonEnd - exonStart; - if (exonStart < pred->cdsEnd && exonEnd > pred->cdsStart) - cdsOffset += exonCdsEnd - exonCdsStart; + cdsOffset += exonCdsSize; } txc.cdnaSize = exonOffset; txc.cdsSize = cdsOffset; // Does variant end downstream? if (varEnd > pred->txEnd) { txc.endInCdna = txc.cdnaSize; if (varStart < pred->cdsEnd && varEnd > pred->cdsStart) txc.endInCds = txc.cdsSize; } if (pred->strand[0] == '-') txc = txCoordsReverse(&txc); if ((txc.startInCdna == -1) != (txc.endInCdna == -1) || (txc.startInCds >= 0 && txc.endInCds < 0)) errAbort("getTxCoords: inconsistent start/ends for variant %s:%d-%d in %s at %s:%d-%d: "