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: "