90386a2976637e3a37523bc7d04f6577d7c3f6b3
braney
  Thu Aug 3 14:10:42 2017 -0700
fold Joel's insert display changes into tree

diff --git src/hg/hgTracks/snakeTrack.c src/hg/hgTracks/snakeTrack.c
index 1a84742..8a7bdf5 100644
--- src/hg/hgTracks/snakeTrack.c
+++ src/hg/hgTracks/snakeTrack.c
@@ -18,30 +18,32 @@
 #include "errCatch.h"
 #include "twoBit.h"
 #include "bigWarn.h"
 #include <pthread.h>
 #include "trackHub.h"
 #include "limits.h"
 #include "snakeUi.h"
 #include "bits.h"
 #include "trix.h"
 
 #include "halBlockViz.h"
 #include "bigPsl.h"
 
 // this is the number of pixels used by the target self-align bar
 #define DUP_LINE_HEIGHT	4
+// this is the number of pixels used when displaying the insertion lengths
+#define INSERT_TEXT_HEIGHT 10
 
 struct snakeFeature
     {
     struct snakeFeature *next;
     int start, end;			/* Start/end in browser coordinates. */
     int qStart, qEnd;			/* query start/end */
     int level;				/* level in snake */
     int orientation;			/* strand... -1 is '-', 1 is '+' */
     boolean drawn;			/* did we draw this feature? */
     char *qSequence;			/* may have sequence, or NULL */
     char *tSequence;			/* may have sequence, or NULL */
     char *qName;			/* chrom name on other species */
     unsigned pixX1, pixX2;              /* pixel coordinates within window */
     };
 
@@ -658,31 +660,31 @@
 {
 if (tg->networkErrMsg != NULL)
     {
     // we had a parallel load failure
     tg->drawItems = bigDrawWarning;
     tg->totalHeight = bigWarnTotalHeight;
     return bigWarnTotalHeight(tg, vis);
     }
 
 if (vis == tvDense)
     return tg->lineHeight;
 
 if (vis == tvSquish)
     return tg->lineHeight/2;
 
-int height = DUP_LINE_HEIGHT; 
+int height = DUP_LINE_HEIGHT + INSERT_TEXT_HEIGHT; 
 struct slList *item = tg->items;
 
 item = tg->items;
 
 for (item=tg->items;item; item = item->next)
     {
     height += tg->itemHeight(tg, item);
     }
 if (height < DUP_LINE_HEIGHT + tg->lineHeight)
     height = DUP_LINE_HEIGHT + tg->lineHeight;
 return height;
 }
 
 static void snakeDraw(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width, 
@@ -1082,108 +1084,180 @@
 	y1 = offY + (lastLevel * 2 + 1) * lineHeight - 1;
 	y2 = offY + (sf->level * 2 ) * lineHeight - lineHeight/3;;
 	}
     s = sf->start; e = sf->end;
 
     sx = round((double)((int)s-winStart)*scale) + xOff;
     ex = round((double)((int)e-winStart)*scale) + xOff;
     color = (sf->orientation == -1) ? MG_RED : MG_BLUE;
 
     if (lastX != -1)
 	{
 	char buffer[1024];
 #define MG_ORANGE  0xff0082E6
 	int color = MG_GRAY;
 
-	if (lastQEnd != qs)
-	    color = MG_ORANGE;
+	if (lastQEnd != qs) {
+            long long queryInsertSize = llabs(lastQEnd - qs);
+            long long targetInsertSize;
+            if (sf->orientation == 1)
+                targetInsertSize = s - lastE;
+            else
+                targetInsertSize = lastS - e;
+            int blue = 0;
+            int red = 0;
+            int green = 0;
+            if (queryInsertSize > targetInsertSize) {
+                double frac = ((double) queryInsertSize - targetInsertSize) / targetInsertSize;
+                if (frac > 1.0)
+                    frac = 1.0;
+                red = 255 - 255 * frac;
+                blue = 255 * frac;
+            } else {
+                double frac = ((double) targetInsertSize - queryInsertSize) / targetInsertSize;
+                if (frac > 1.0)
+                    frac = 1.0;
+                red = 255 - 255 * frac;
+                green = 255 * frac;
+            }
+            color = hvGfxFindColorIx(hvg, red, green, blue);
+        }
+        double queryGapNFrac = 0.0;
+        double queryGapMaskedFrac = 0.0;
+        if (qs - lastQEnd != 0 && qs - lastQEnd < 1000000) {
+            // sketchy
+            char *fileName = trackDbSetting(tg->tdb, "bigDataUrl");
+            char *otherSpecies = trackDbSetting(tg->tdb, "otherSpecies");
+            int handle = halOpenLOD(fileName, NULL);
+            char *queryGapDna = halGetDna(handle, otherSpecies, sf->qName, lastQEnd, qs, NULL);
+            long long numNs = 0;
+            long long numMasked = 0;
+            char *i = queryGapDna;
+            while (*i != '\0') {
+                if (*i == 'N' || *i == 'n') {
+                    numNs++;
+                    numMasked++;
+                }
+                if (*i == 'a' || *i == 't' || *i == 'g' || *i == 'c') {
+                        numMasked++;
+                }
+                i++;
+            }
+            free(queryGapDna);
+            queryGapMaskedFrac = ((double) numMasked) / (qs - lastQEnd);
+            queryGapNFrac = ((double) numNs) / (qs - lastQEnd);
+        }
 
 	// draw the vertical orange bars if there is an insert in the other sequence
 	if ((winBaseCount < showSnpWidth) )
 	    {
 	    if ((sf->orientation == 1) && (qs != lastQEnd) && (lastE == s))
 		{
 		hvGfxLine(hvg, sx, y2 - lineHeight/2 , sx, y2 + lineHeight/2, MG_ORANGE);
-		safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+		safef(buffer, sizeof buffer, "%dbp (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100);
 		boundMapBox(hvg, s, e, sx, y2 - lineHeight/2, 1, lineHeight, tg->track,
 				    "foo", buffer, NULL, TRUE, NULL);
+		safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                hvGfxTextCentered(hvg, sx - 10, y2 + lineHeight/2, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer);
 		}
 	    else if ((sf->orientation == -1) && (qs != lastQEnd) && (lastS == e))
 		{
 		hvGfxLine(hvg, ex, y2 - lineHeight/2 , ex, y2 + lineHeight/2, MG_ORANGE);
-		safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+		safef(buffer, sizeof buffer, "%dbp (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100);
 		boundMapBox(hvg, s, e, ex, y2 - lineHeight/2, 1, lineHeight, tg->track,
 				    "foo", buffer, NULL, TRUE, NULL);
+		safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                hvGfxTextCentered(hvg, ex - 10, y2 + lineHeight/2, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer);
 		}
 	    }
 
 	// now draw the lines between blocks
 	if ((!((lastX == sx) && (y1 == y2))) &&
 	    (sf->drawn  || ((prevSf != NULL) && (prevSf->drawn))) &&
 	    (((lastE >= winStart) && (lastE <= winEnd)) || 
 	    ((s > winStart) && (s < winEnd))))
 	    {
 	    if (lastLevel == sf->level)
 		{
-		safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                if (sf->orientation == 1)
+                    safef(buffer, sizeof buffer, "%dbp (%dbp in ref) (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, s - lastE, queryGapNFrac*100, queryGapMaskedFrac*100);
+                else
+                    safef(buffer, sizeof buffer, "%dbp (%dbp in ref) (%.1lf%% N, %.1lf%% masked)", qs - lastQEnd, lastS - e, queryGapNFrac*100, queryGapMaskedFrac*100);
 		if (sf->orientation == -1)
 		    {
 		    if (lastX != ex)
 			{
 			hvGfxLine(hvg, ex, y1, lastX, y2, color);
 			boundMapBox(hvg, s, e, ex, y1, lastX-ex, 1, tg->track,
 				"", buffer, NULL, TRUE, NULL);
+                        if (lastQEnd != qs) {
+                            safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                            hvGfxTextCentered(hvg, ex, y2 + lineHeight/2, lastX-ex, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer);
+                        }
 			}
 		    }
 		else
 		    {
 		    if (lastX != sx)
 			{
 			hvGfxLine(hvg, lastX, y1, sx, y2, color);
 			boundMapBox(hvg, s, e, lastX, y1, sx-lastX, 1, tg->track,
 				"", buffer, NULL, TRUE, NULL);
+                        if (lastQEnd != qs) {
+                            safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                            hvGfxTextCentered(hvg, lastX, y2 + lineHeight/2, sx-lastX, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer);
+                        }
 			}
 		    }
 		}
 	    else if (lastLevel > sf->level)
 		{
 		hvGfxLine(hvg, lastX, y1, sx, y2, color);
 		hvGfxLine(hvg, sx, y2, sx, y2 - lineHeight - lineHeight/3, color);
 		char buffer[1024];
-		safef(buffer, sizeof buffer, "%d-%d %dbp gap",prevSf->qStart,prevSf->qEnd, qs - lastQEnd);
+		safef(buffer, sizeof buffer, "%d-%d %dbp gap (%.1lf%% N, %.1lf%% masked)",prevSf->qStart,prevSf->qEnd, qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100);
 		boundMapBox(hvg, s, e, sx, y2 - lineHeight - lineHeight/3, 2, lineHeight + lineHeight/3, tg->track,
 	                    "", buffer, NULL, TRUE, NULL);
+		safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                if (lastQEnd != qs)
+                    hvGfxTextCentered(hvg, sx - 10, y2 + lineHeight/2, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer);
 
 		}
 	    else
 		{
 		char buffer[1024];
-		safef(buffer, sizeof buffer, "%d-%d %dbp gap",prevSf->qStart,prevSf->qEnd, qs - lastQEnd);
+		safef(buffer, sizeof buffer, "%d-%d %dbp gap (%.1lf%% N, %.1lf%% masked)",prevSf->qStart,prevSf->qEnd, qs - lastQEnd, queryGapNFrac*100, queryGapMaskedFrac*100);
 		if (sf->orientation == -1)
 		    {
 		    hvGfxLine(hvg, lastX-1, y1, ex, y2, color);
 		    hvGfxLine(hvg, ex, y2, ex, y2 + lineHeight , color);
 		    boundMapBox(hvg, s, e, ex-1, y2, 2, lineHeight , tg->track,
 				"", buffer, NULL, TRUE, NULL);
+                    safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                    if (lastQEnd != qs)
+                        hvGfxTextCentered(hvg, ex - 10, y2 + lineHeight, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer);
 		    }
 		else
 		    {
 		    hvGfxLine(hvg, lastX-1, y1, sx, y2, color);
 		    hvGfxLine(hvg, sx, y2, sx, y2 + lineHeight , color);
 		    boundMapBox(hvg, s, e, sx-1, y2, 2, lineHeight , tg->track,
 				"", buffer, NULL, TRUE, NULL);
 
+                    safef(buffer, sizeof buffer, "%dbp", qs - lastQEnd);
+                    if (lastQEnd != qs)
+                        hvGfxTextCentered(hvg, sx - 10, y2 + lineHeight, 20, INSERT_TEXT_HEIGHT, MG_ORANGE, font, buffer);
 		    }
 		}
 	    }
 	}
     if (sf->orientation == -1)
 	lastX = sx;
     else
 	lastX = ex;
     lastS = s;
     lastE = e;
     lastLevel = sf->level;
     lastQEnd = qe;
     }
 }