58fdf423f2a7170310c1750b9b7739b6113dc990
braney
  Thu May 2 14:39:11 2013 -0700
tolerate missing a freeze field in an assembly hub, and add dense mode to snakes
diff --git src/hg/hgTracks/snakeTrack.c src/hg/hgTracks/snakeTrack.c
index 8c7ff2c..cb0eeb4 100644
--- src/hg/hgTracks/snakeTrack.c
+++ src/hg/hgTracks/snakeTrack.c
@@ -192,30 +192,33 @@
     next = temp->next;
     temp->next = NULL;
     slAddHead(&newList, temp);
     }
 }
 
 struct cartOptions
     {
     enum chainColorEnum chainColor; /*  ChromColors, ScoreColors, NoColors */
     int scoreFilter ; /* filter chains by score if > 0 */
     };
 
 static int snakeHeight(struct track *tg, enum trackVisibility vis)
 /* calculate height of all the snakes being displayed */
 {
+if (vis == tvDense)
+    return tg->lineHeight;
+
 int height = 0;
 struct slList *item = tg->items;
 
 item = tg->items;
 
 for (item=tg->items;item; item = item->next)
     {
     height += tg->itemHeight(tg, item);
     }
 return height;
 }
 
 // mySQL code to read in chains
 
 static void doQuery(struct sqlConnection *conn, char *fullName, 
@@ -420,60 +423,61 @@
     lf->score = 0;
     for (sf =  (struct snakeFeature *)lf->components; sf != NULL;  sf = sf->next)
 	{
 	lf->score += sf->end - sf->start;
 	}
     }
 
 slSort(&tg->items, linkedFeaturesCmpScore);
 
 y = yOff;
 for (item = tg->items; item != NULL; item = item->next)
     {
     if(tg->itemColor != NULL) 
 	color = tg->itemColor(tg, item, hvg);
     tg->drawItemAt(tg, item, hvg, xOff, y, scale, font, color, vis);
+    if (vis == tvFull)
     y += tg->itemHeight(tg, item);
     } 
 }
 
 static void packSnakeDrawAt(struct track *tg, void *item,
 	struct hvGfx *hvg, int xOff, int y, double scale, 
 	MgFont *font, Color color, enum trackVisibility vis)
 /* Draw a single simple bed item at position. */
 {
 struct linkedFeatures  *lf = (struct linkedFeatures *)item;
 calcPackSnake(tg, item);
 
 if (lf->components == NULL)
     return;
 
 boolean isHalSnake = FALSE;
 if (lf->original == (void *)1)
     isHalSnake = TRUE;
 
 struct snakeFeature  *sf = (struct snakeFeature *)lf->components, *prevSf = NULL;
 int s = tg->itemStart(tg, item);
 int sClp = (s < winStart) ? winStart : s;
 int x1 = round((sClp - winStart)*scale) + xOff;
 int textX = x1;
 int yOff = y;
-boolean withLabels = (withLeftLabels && (vis == tvPack) && !tg->drawName);
+//boolean withLabels = (withLeftLabels && (vis == tvFull) && !tg->drawName);
 unsigned   labelColor = MG_BLACK;
 
 // draw the labels (this code needs a clean up )
-if (withLabels)
+if (0)//withLabels)
     {
     char *name = tg->itemName(tg, item);
     int nameWidth = mgFontStringWidth(font, name);
     int dotWidth = tl.nWidth/2;
     boolean snapLeft = FALSE;
     boolean drawNameInverted = FALSE;
     textX -= nameWidth + dotWidth;
     snapLeft = (textX < insideX);
     /* Special tweak for expRatio in pack mode: force all labels
      * left to prevent only a subset from being placed right: */
     snapLeft |= (startsWith("expRatio", tg->tdb->type));
 #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
     if (theImgBox == NULL && snapLeft)
 #else///ifndef IMAGEv2_NO_LEFTLABEL_ON_FULL
     if (snapLeft)        /* Snap label to the left. */
@@ -515,30 +519,33 @@
 int lastS = -1;
 int offY = y;
 int lineHeight = tg->lineHeight ;
 int tStart, tEnd, qStart;
 int  qs, qe;
 int heightPer = tg->heightPer;
 int lastX = -1,lastY = y;
 int lastQEnd = 0;
 int lastLevel = -1;
 int e;
 qe = lastQEnd = 0;
 for (sf =  (struct snakeFeature *)lf->components; sf != NULL; lastQEnd = qe, prevSf = sf, sf = sf->next)
     {
     qs = sf->qStart;
     qe = sf->qEnd;
+    if (vis == tvDense)
+	y = offY;
+    else
     y = offY + (sf->level * 2) * lineHeight;
     s = sf->start; e = sf->end;
     tEnd = sf->end;
     int osx;
 
     int sx, ex;
     if (!positiveRangeIntersection(winStart, winEnd, s, e))
 	continue;
     osx = sx = round((double)((int)s-winStart)*scale) + xOff;
     ex = round((double)((int)e-winStart)*scale) + xOff;
 
     // color by strand
     static Color darkBlueColor = 0;
     static Color darkRedColor = 0;
     if (darkRedColor == 0)
@@ -551,38 +558,41 @@
     color = (sf->orientation == -1) ? darkRedColor : darkBlueColor;
 
     int w = ex - sx;
     if (w == 0) 
 	w = 1;
     assert(w > 0);
     char buffer[1024];
     safef(buffer, sizeof buffer, "%d %d",sf->qStart,sf->qEnd);
     if (sx < insideX)
 	{
 	int olap = insideX - sx;
 	sx = insideX;
 	w -= olap;
 	}
     char qAddress[4096];
+    if (vis == tvFull)
+	{
     safef(qAddress, sizeof qAddress, "qName=%s&qs=%d&qe=%d&qWidth=%d",tg->itemName(tg, item),  qs, qe,  winEnd - winStart);
     mapBoxHgcOrHgGene(hvg, s, e, sx+1, y, w-2, heightPer, tg->track,
 		buffer, buffer, NULL, TRUE, qAddress);
+	}
     hvGfxBox(hvg, sx, y, w, heightPer, color);
     int ow = w;
 
     // now draw the mismatches if we're at high enough resolution 
-    if (winBaseCount < 50000)
+    if ((winBaseCount < 50000) && (vis == tvFull))
     {
 	char *twoBitString = trackDbSetting(tg->tdb, "twoBit");
 	static struct twoBitFile *tbf = NULL;
 	static char *lastTwoBitString = NULL;
 	static struct dnaSeq *seq = NULL;
 	static char *lastQName = NULL;
 
 	// sequence for chain snakes is in 2bit files which we cache
 	if (!isHalSnake)
 	    {
 	    if (twoBitString == NULL)
 		twoBitString = "/gbdb/hg19/hg19.2bit";
 
 	    if ((lastTwoBitString == NULL) ||
 		differentString(lastTwoBitString, twoBitString))
@@ -638,30 +648,33 @@
 	    {
 	    spreadAlignString(hvg, osx, y, ow, heightPer, MG_WHITE, font, ourDna,
 		extraSeq->dna, seqLen, TRUE, FALSE);
 	    }
 
     }
     sf->drawn = TRUE;
     tEnd = e;
     tStart = s;
     qStart = sf->qStart;
     lastY = y;
     lastLevel = sf->level;
     //lastX = x;
     }
 
+if (vis == tvDense)
+    return;
+
 // now we're going to draw the lines between the blocks
 
 lastX = -1,lastY = y;
 lastQEnd = 0;
 lastLevel = 0;
 qe = lastQEnd = 0;
 prevSf = NULL;
 for (sf =  (struct snakeFeature *)lf->components; sf != NULL; lastQEnd = qe, prevSf = sf, sf = sf->next)
     {
     int y1, y2;
     int sx, ex;
     qs = sf->qStart;
     qe = sf->qEnd;
     if (lastLevel == sf->level)
 	{
@@ -780,32 +793,31 @@
     else
 	lastX = ex;
     lastS = s;
     lastE = e;
     lastLevel = sf->level;
     lastQEnd = qe;
     }
 }
 
 
 static void snakeDrawAt(struct track *tg, void *item,
 	struct hvGfx *hvg, int xOff, int y, double scale, 
 	MgFont *font, Color color, enum trackVisibility vis)
 /* Draw a single simple bed item at position. */
 {
-    
-    if (tg->visibility == tvFull)
+if ((tg->visibility == tvFull) || (tg->visibility == tvDense))
 	packSnakeDrawAt(tg, item, hvg, xOff, y, scale, 
 	    font, color, vis);
 }
 
 static void fixItems(struct linkedFeatures *lf)
 // put all chain blocks from a single query chromosome into one
 // linkedFeatures structure
 {
 struct linkedFeatures *firstLf, *next;
 struct snakeFeature  *sf,  *nextSf;
 
 firstLf = lf;
 for (;lf; lf = next)
     {
     next = lf->next;