629bb6f183fd2102cec5fdb484aa8d3270fb4f6d
braney
  Thu Oct 3 11:25:05 2013 -0700
add chromosome color mode to snakes that uses a hash of the chrom to geta color ffrom a fixed palette.   Also make pack mode a little more dense

diff --git src/hg/hgTracks/snakeTrack.c src/hg/hgTracks/snakeTrack.c
index 7ad3cee..22ab830 100644
--- src/hg/hgTracks/snakeTrack.c
+++ src/hg/hgTracks/snakeTrack.c
@@ -425,31 +425,35 @@
 {
 if ((item == NULL) || (tg->visibility == tvSquish) || (tg->visibility == tvDense)) 
     return 0;
 
 struct linkedFeatures  *lf = (struct linkedFeatures *)item;
 if (lf->components == NULL)
     return 0;
 
 if (tg->visibility == tvFull) 
     calcFullSnake(tg, item);
 else if (tg->visibility == tvPack) 
     calcPackSnake(tg, item);
 
 struct snakeInfo *si = (struct snakeInfo *)lf->codons;
 int lineHeight = tg->lineHeight ;
-return (si->maxLevel + 1) * (2 * lineHeight);
+int multiplier = 1;
+
+if (tg->visibility == tvFull)
+    multiplier = 2;
+return (si->maxLevel + 1) * (multiplier * lineHeight);
 }
 
 static int linkedFeaturesCmpScore(const void *va, const void *vb)
 /* Help sort linkedFeatures by score */
 {
 const struct linkedFeatures *a = *((struct linkedFeatures **)va);
 const struct linkedFeatures *b = *((struct linkedFeatures **)vb);
 if (a->score > b->score)
     return -1;
 else if (a->score < b->score)
     return 1;
 return 0;
 }
 
 static int snakeHeight(struct track *tg, enum trackVisibility vis)
@@ -513,40 +517,48 @@
     }
 
 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);
     } 
 }
 
 //  this is a 16 color palette with every other color being a lighter version of
 //  the color before it
-//static int snakePalette[] =
-//{
-//0x1f77b4, 0xaec7e8, 0xff7f0e, 0xffbb78, 0x2ca02c, 0x98df8a, 0xd62728, 0xff9896, 0x9467bd, 0xc5b0d5, 0x8c564b, 0xc49c94, 0xe377c2, 0xf7b6d2, 0x7f7f7f, 0xc7c7c7, 0xbcbd22, 0xdbdb8d, 0x17becf, 0x9edae5
-//};
+static int snakePalette2[] =
+{
+0x1f77b4, 0xaec7e8, 0xff7f0e, 0xffbb78, 0x2ca02c, 0x98df8a, 0xd62728, 0xff9896, 0x9467bd, 0xc5b0d5, 0x8c564b, 0xc49c94, 0xe377c2, 0xf7b6d2, 0x7f7f7f, 0xc7c7c7, 0xbcbd22, 0xdbdb8d, 0x17becf, 0x9edae5
+};
 
 static int snakePalette[] =
 {
 0x1f77b4, 0xff7f0e, 0x2ca02c, 0xd62728, 0x9467bd, 0x8c564b, 0xe377c2, 0x7f7f7f, 0xbcbd22, 0x17becf
 };
 
+static Color hashColor(char *name)
+{
+bits32 hashVal = hashString(name);
+unsigned int colorInt = snakePalette2[hashVal % (sizeof(snakePalette2)/sizeof(Color))];
+
+return MAKECOLOR_32(((colorInt >> 16) & 0xff),((colorInt >> 8) & 0xff),((colorInt >> 0) & 0xff));
+}
+
 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. */
 {
 unsigned showSnpWidth = cartOrTdbInt(cart, tg->tdb, 
     SNAKE_SHOW_SNP_WIDTH, SNAKE_DEFAULT_SHOW_SNP_WIDTH);
 struct linkedFeatures  *lf = (struct linkedFeatures *)item;
 
 
 if (tg->visibility == tvFull) 
     calcFullSnake(tg, item);
 else if (tg->visibility == tvPack)
     calcPackSnake(tg, item);
 
@@ -649,70 +661,76 @@
 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
+    else if ((vis == tvPack) || (vis == tvSquish))
+	y = offY + (sf->level * 1) * lineHeight;
+    else if (vis == tvFull)
 	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)
 	{
 	//the light blue: rgb(149, 204, 252)
 	//the light red: rgb(232, 156, 156)
 	darkRedColor = hvGfxFindColorIx(hvg, 232,156,156);
 	darkBlueColor = hvGfxFindColorIx(hvg, 149,204,252);
 	}
     
     char *colorBy = cartOrTdbString(cart, tg->tdb, 
 	SNAKE_COLOR_BY, SNAKE_DEFAULT_COLOR_BY);
 
     extern Color getChromColor(char *name, struct hvGfx *hvg);
     if (sameString(colorBy, SNAKE_COLOR_BY_STRAND_VALUE))
 	color = (sf->orientation == -1) ? darkRedColor : darkBlueColor;
     else if (sameString(colorBy, SNAKE_COLOR_BY_CHROM_VALUE))
-	color = getChromColor(lf->name, hvg);
+	color = hashColor(sf->qName);
     else
 	color =  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 (vis == tvFull)
+	safef(buffer, sizeof buffer, "%d-%d",sf->qStart,sf->qEnd);
+    else
+	safef(buffer, sizeof buffer, "%s:%d-%d",sf->qName,sf->qStart,sf->qEnd);
     if (sx < insideX)
 	{
 	int olap = insideX - sx;
 	sx = insideX;
 	w -= olap;
 	}
     char qAddress[4096];
     if ((vis == tvFull) || (vis == tvPack) )
 	{
 	safef(qAddress, sizeof qAddress, "qName=%s&qs=%d&qe=%d&qWidth=%d",sf->qName,  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);
 
@@ -975,58 +993,57 @@
     for(;targetDupeBlocks; targetDupeBlocks = targetDupeBlocks->next)
 	{
 	printf("<br>id: %d qChrom %s\n", targetDupeBlocks->id, targetDupeBlocks->qChrom);
 	struct hal_target_range_t *range = targetDupeBlocks->tRange;
 	for(; range; range = range->next)
 	    {
 	    printf("<br>   %ld : %ld\n", range->tStart, range->size);
 	    }
 	}
 #endif
 
     while (cur)
     {
 	struct hashEl* hel;
 
-	//safef(buffer, sizeof buffer, "%s.%c", cur->qChrom,cur->strand);
 	if (tg->visibility == tvFull)
 	    safef(buffer, sizeof buffer, "%s", cur->qChrom);
 	else
 	    {
 	    // make sure the block is on the screen 
 	    if (!positiveRangeIntersection(winStart, winEnd, cur->tStart,  cur->tStart + cur->size))
 		{
 		cur = cur->next;
 		continue;
 		}
 	    safef(buffer, sizeof buffer, "allInOne");
 	    }
 
 	if ((hel = hashLookup(qChromHash, buffer)) == NULL)
 	    {
 	    AllocVar(lf);
 	    lf->isHalSnake = TRUE;
 	    slAddHead(&lfList, lf);
 	    lf->start = 0;
 	    lf->end = 1000000000;
 	    lf->grayIx = maxShade;
 	    lf->name = cloneString(buffer);
 	    lf->extra = cloneString(buffer);
 	    lf->orientation = (cur->strand == '+') ? 1 : -1;
 	    hashAdd(qChromHash, lf->name, lf);
 
-	    // now figure out where the blue bars go
+	    // now figure out where the duplication bars go
 	    struct hal_target_dupe_list_t* targetDupeBlocks = head->targetDupeBlocks;
 
 	    if ((tg->visibility == tvPack) || (tg->visibility == tvFull))
 		for(;targetDupeBlocks; targetDupeBlocks = targetDupeBlocks->next)
 		    {
 		    if ((tg->visibility == tvPack) ||
 			((tg->visibility == tvFull) &&
 			 (sameString(targetDupeBlocks->qChrom, cur->qChrom))))
 			{
 			struct hal_target_dupe_list_t* dupeList;
 			AllocVar(dupeList);
 			*dupeList = *targetDupeBlocks;
 			slAddHead(&lf->dupeList, dupeList);
 			// TODO: should clone the target_range structures
 			// rather than copying them