2da05417cd0dd231003e1082a7ee241504be7006
braney
  Wed Apr 8 11:31:41 2015 -0700
another file for little feet mode

diff --git src/hg/hgTracks/adjacencyTrack.c src/hg/hgTracks/adjacencyTrack.c
new file mode 100644
index 0000000..6f9dc7f
--- /dev/null
+++ src/hg/hgTracks/adjacencyTrack.c
@@ -0,0 +1,493 @@
+/* adjacencyTrack -- handlers for Variant Call Format data. */
+
+#include "common.h"
+#include "bigWarn.h"
+#include "dystring.h"
+#include "errCatch.h"
+#include "hacTree.h"
+#include "hdb.h"
+#include "hgColors.h"
+#include "hgTracks.h"
+#include "pgSnp.h"
+#include "trashDir.h"
+#include "adjacency.h"
+//#include "adjacencyUi.h"
+
+
+struct adjacencyInfo
+{
+struct adjacencyInfo *next;
+struct adjacency *list;
+boolean calced;
+int height;
+int ordering;
+};
+
+unsigned makeColor(unsigned score)
+{
+unsigned colorDelta;
+unsigned red, green, blue;
+
+if (score > 500)
+    {
+    colorDelta = (score - 500) * 255 / 500;
+    red = 255;
+    green = 127 - colorDelta/2;
+    blue = 127 - colorDelta/2;
+    }
+else
+    {
+    colorDelta = (score) * 255 / 500;
+    blue = 255;
+    green = colorDelta/2;
+    red = colorDelta/2;
+    }
+unsigned color =  MAKECOLOR_32(red, green, blue);
+
+return color;
+}
+
+int cmpOrdering(const void *va, const void *vb)
+{
+const struct adjacency *a = *((struct adjacency **)va);
+const struct adjacency *b = *((struct adjacency **)vb);
+
+int diff = a->ordering - b->ordering;
+
+return diff;
+}
+
+static void adjacencyLoadItems(struct track *tg)
+{
+struct adjacency *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+int rowOffset = 0;
+struct sqlConnection *conn;
+char *table = tg->table;
+struct customTrack *ct = tg->customPt;
+if (ct == NULL)
+    conn = hAllocConn(database);
+else
+    {
+    conn = hAllocConn(CUSTOM_TRASH);
+    table = ct->dbTableName;
+    }
+
+sr = hRangeQuery(conn, table, chromName, winStart, winEnd, NULL, &rowOffset);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = adjacencyLoad(row+rowOffset);
+    // only grab those that have a tick on screen
+    if ( sameString("SEGMENT", el->name) ||
+	((el->chromStart >= winStart) && (el->chromStart < winEnd)) ||
+	(sameString(chromName, el->name) &&
+	    ((el->chromEnd >= winStart) && (el->chromEnd < winEnd)))
+	)
+    slAddHead(&list, el);
+    }
+sqlFreeResult(&sr);
+
+slSort(&list, cmpOrdering);
+
+struct adjacencyInfo *adjInfoList = NULL;
+struct adjacencyInfo *adjInfo = NULL;
+struct adjacency *next;
+for(el = list; el; el = next)
+    {
+    next = el->next;
+    el->next = NULL;
+
+    if ((adjInfo == NULL) || (adjInfo->ordering != el->ordering))
+	{
+	AllocVar(adjInfo);
+	slAddHead(&adjInfoList, adjInfo);
+	adjInfo->ordering = el->ordering;
+	adjInfo->calced = FALSE;
+	adjInfo->list = NULL;
+	}
+
+    slAddHead(&adjInfo->list, el);
+    }
+slReverse(&adjInfoList);
+tg->items = adjInfoList;
+
+//printf("adfInfo Count %d\n", slCount(adjInfoList));
+}
+
+static void arcThrough( struct hvGfx *hvg, int x1, int y1,
+    int mx, int my, int x2, int y2, unsigned color)
+{
+hvGfxLine(hvg, x1, y1, mx, my, color);
+hvGfxLine(hvg, mx, my, x2, y2, color);
+}
+
+void adjacencyDrawAt(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 adjacency *adjacency = item;
+int heightPer = tg->heightPer;
+//int s = max(bed->chromStart, winStart), e = min(bed->chromEnd, winEnd);
+int s = adjacency->chromStart, e = adjacency->chromEnd;
+int x1 = round((s-winStart)*scale) + xOff;
+int x2 = round((e-winStart)*scale) + xOff;
+
+if (sameString("SEGMENT", adjacency->name))
+    {
+    hvGfxBox(hvg, x1, y + 3 , x2-x1, heightPer, color);
+    return;
+    }
+hvGfxBox(hvg, x1, y - heightPer, 1, heightPer, color);
+if (sameString(adjacency->chrom, adjacency->name))
+    {
+    hvGfxBox(hvg, x2, y - heightPer, 1, heightPer, color);
+    arcThrough(hvg, x1, y - heightPer, 
+	(x1 + x2) / 2, y - adjacency->level, 
+	x2, y - heightPer, color);
+    /*
+    arcThrough(hvg, x1, y - heightPer, 
+	(x1 + x2) / 2, y - (adjacency->level + 2) * heightPer, 
+	x2, y - heightPer, color);
+	*/
+    }
+else
+    {
+    char buffer[100];
+    safef(buffer, sizeof buffer, "%s", adjacency->name);
+    int textWidth = mgFontStringWidth(font, buffer);
+    int fontHeight = mgFontLineHeight(font);
+    hvGfxTextCentered(hvg, x1 - textWidth / 2, y - 2 * heightPer, textWidth , fontHeight, MG_BLACK, font, buffer);
+    }
+
+//y += 2 * heightPer;
+
+int xt1, xt2;
+if (adjacency->strand1[0] == '+')
+    xt1 = x1 + 5;
+else
+    xt1 = x1 - 5;
+hvGfxLine(hvg, x1, y, xt1, y, color);
+
+if (sameString(adjacency->chrom, adjacency->name))
+    {
+    if (adjacency->strand2[0] == '+')
+	xt2 = x2 + 5;
+    else
+	xt2 = x2 - 5;
+
+    hvGfxLine(hvg, x2, y, xt2, y, color);
+    }
+
+// now write out the other chrom if there is one
+}
+
+struct edge
+{
+struct edge *next;
+unsigned x;
+struct adjacency *adj;
+boolean in;
+};
+
+
+#ifdef NOTNOW
+static void makeEdge(struct edge **edgeList, struct adjacency *adj)
+{
+struct edge *edge;
+
+AllocVar(edge);
+slAddHead(edgeList, edge);
+edge->x = adj->chromStart;
+edge->adj = adj;
+edge->in = TRUE;
+
+AllocVar(edge);
+slAddHead(edgeList, edge);
+edge->adj = adj;
+edge->in = FALSE;
+if (sameString(adj->chrom, adj->name))
+    edge->x = adj->chromEnd;
+else
+    edge->x = adj->chromStart;
+}
+
+int cmpEdgeX(const void *va, const void *vb)
+{
+const struct edge *a = *((struct edge **)va);
+const struct edge *b = *((struct edge **)vb);
+
+int diff = a->x - b->x;
+
+if (diff == 0)
+    diff = b->in - a->in;
+if (diff == 0)
+    {
+    int bWidth = b->adj->chromEnd - b->adj->chromStart;
+    int aWidth = a->adj->chromEnd - a->adj->chromStart;
+    diff = bWidth - aWidth;
+    }
+
+return diff;
+}
+
+static struct adjacency *removeAdjacency(struct adjacency *list, 
+    struct adjacency *toRemove)
+{
+struct adjacency *prev = NULL;
+struct adjacency *adj;
+
+for(adj = list; adj != toRemove; prev = adj, adj = adj->next)
+    ;
+
+struct adjacency *ret;
+if (prev == NULL)
+    {
+    ret = list->next;
+    list->next = NULL;
+    return ret;
+    }
+
+prev->next = adj->next;
+adj->next = NULL;
+
+return list;
+}
+#endif
+
+void calcAdjacencyLevels(struct adjacencyInfo *adjInfo, int heightPer)
+{
+if (adjInfo->calced)
+    return;
+
+struct adjacency *adj = adjInfo->list;
+
+//struct adjacency *next;
+int maxLevel = 0;
+for(; adj; adj = adj->next)
+    {
+    adj->level = 5*log((double)adj->chromEnd - adj->chromStart);
+    if (adj->level > maxLevel)
+	maxLevel = adj->level;
+    }
+adjInfo->height =  2* (6 + maxLevel);
+adjInfo->calced = TRUE;
+
+#ifdef NOTNOW
+struct adjacency *adj = adjInfo->list;
+struct adjacency *segList = NULL;
+
+// build up list of edges to sort by
+struct edge *edgeList = NULL;
+struct adjacency *next;
+for(; adj; adj = next)
+    {
+    next = adj->next;
+    if (differentString(adj->name, "SEGMENT"))
+	makeEdge(&edgeList, adj);
+    else
+	slAddHead(&segList, adj);
+
+    adj->level = 0;
+    }
+slSort(&edgeList, cmpEdgeX);
+
+//printf("Edge Count %d\n",slCount(edgeList));
+//for(edge = edgeList ; edge; edge = edge->next)
+//    printf("edge x %d in %d |", edge->x, edge->in);
+
+struct edge *edge;
+int level = 0;
+int maxLevel = 0;
+struct adjacency *onDeck = NULL;
+for(edge = edgeList ; edge; edge = edge->next)
+    {
+    if (edge->in)
+	{
+	level++;
+	if (level > maxLevel)
+	    maxLevel = level;
+
+	// if the current level is as high as what's on deck, raise the roof!
+	if ((onDeck != NULL) && (level > onDeck->level))
+	    {
+	    struct adjacency *adj = onDeck;
+	    for(; adj; adj = adj->next)
+		adj->level++;
+	    }
+
+	// add this adjacency to the "on-deck" list
+	slAddHead(&onDeck, edge->adj);
+	}
+    else
+	{
+	level--;
+
+	// we have to remove this adjacency from onDeck
+	onDeck = removeAdjacency(onDeck, edge->adj);
+	}
+    }
+//printf("maxLevel %d level %d\n",maxLevel, level);
+
+// rebuild adjacency list
+//printf("Edge Count %d\n",slCount(edgeList));
+struct adjacency *newList = NULL;
+for(edge = edgeList ; edge; edge = edge->next)
+    {
+    if (edge->in)
+	slAddHead(&newList, edge->adj);
+    }
+newList = slCat(newList, segList);
+adjInfo->list = newList;
+
+//printf("Count %d\n",slCount(newList));
+//adj = newList;
+//for(; adj; adj = adj->next)
+//    {
+//    printf("adj %d %d level %d\n", adj->chromStart, adj->chromEnd, adj->level);
+//    }
+
+//adjInfo->height = maxLevel;
+adjInfo->height =  (6 + maxLevel)  * heightPer;
+adjInfo->calced = TRUE;
+#endif
+}
+
+int adjacencyHeight(struct track *tg, enum trackVisibility vis)
+/* calculate height of all the cycles being displayed */
+{
+int height = 0;
+
+struct adjacencyInfo *adjInfo = tg->items;
+for(; adjInfo; adjInfo = adjInfo->next)
+    {
+    calcAdjacencyLevels(adjInfo, tg->heightPer);
+    height +=   adjInfo->height;
+    //height +=  (4 + adjInfo->height)  * tg->heightPer;
+    //printf("height %d\n", height);
+    }
+return height;
+    
+#ifdef NOTNOW
+switch (tg->visibility  )
+    {
+    case tvDense:
+	return (4 + adjInfo->height)  * tg->heightPer;
+    case tvFull:
+	{
+	struct adjacency *adj = adjInfo->list;
+	int height = 0;
+	for(adj = adjInfo->list; adj; adj = adj->next)
+	    height += (adj->level + 2) * tg->heightPer;
+	return height;
+	}
+    default:
+	return 0;
+    }
+#endif
+}
+
+void adjacencyDraw(struct track *tg, int seqStart, int seqEnd,
+        struct hvGfx *hvg, int xOff, int yOff, int width,
+        MgFont *font, Color color, enum trackVisibility vis)
+/* Draw simple Bed items. */
+{
+//struct slList *item;
+int y = yOff;
+double scale = scaleForWindow(width, seqStart, seqEnd);
+int height = adjacencyHeight(tg, vis) +1;
+
+hvGfxSetClip(hvg, xOff, yOff, width, height);
+
+
+#ifdef NOTNOW
+switch (tg->visibility  )
+    {
+    case tvDense:
+	y = yOff + (adjInfo->height + 3) * tg->heightPer;
+	break;
+    case tvFull:
+	y = yOff + (adj->level + 2) * tg->heightPer;
+	break;
+    default:
+	y = yOff;
+	break;
+    }
+#endif
+
+struct adjacencyInfo *adjInfo = tg->items;
+for(; adjInfo; adjInfo = adjInfo->next)
+    {
+    struct adjacency *adj = adjInfo->list;
+    y += adjInfo->height;
+    for(adj = adjInfo->list; adj; adj = adj->next)
+	{
+    //printf("y %d\n", y);
+	unsigned color = makeColor(adj->score);
+	tg->drawItemAt(tg, adj, hvg, xOff, y, scale, font, color, vis);
+	} 
+    //y += adjInfo->height;
+    }
+}
+
+
+int adjacencyItemHeight(struct track *tg, void *item)
+{
+struct adjacencyInfo *adjInfo = item;
+switch (tg->visibility  )
+    {
+    case tvDense:
+	return 0;
+    case tvFull:
+	return adjInfo->height;
+	//return (2 + 2) * tg->heightPer;
+	//return (adj->level + 2) * tg->heightPer;
+    default:
+	return 0;
+
+    }
+}
+
+void adjacencyLeftLabels(struct track *tg, int seqStart, int seqEnd,
+	struct hvGfx *hvg, int xOff, int yOff, int width, int height,
+	boolean withCenterLabels, MgFont *font, Color color,
+	enum trackVisibility vis)
+{
+struct adjacencyInfo *adjInfo = tg->items;
+int y = yOff;
+for(; adjInfo; adjInfo = adjInfo->next)
+    {
+    y += adjInfo->height / 2;
+    //struct adjacency *adj = adjInfo->list;
+    hvGfxTextRight(hvg, xOff, y, width - 1,
+	tg->heightPer, color, font,adjInfo->list->cycle);
+    y += adjInfo->height / 2;
+    }
+}
+
+static void adjacencyMapItem(struct track *tg, struct hvGfx *hvg, void *item,
+				char *itemName, char *mapItemName, int start, int end,
+				int x, int y, int width, int height)
+/* Special mouseover text from item->label. (derived from genericMapItem) */
+{
+}
+
+void adjacencyMethods(struct track *track)
+{
+bedMethods(track);
+track->drawItems = adjacencyDraw;
+track->drawItemAt = adjacencyDrawAt;
+track->totalHeight = adjacencyHeight; 
+track->itemHeight = adjacencyItemHeight;
+track->drawLeftLabels = adjacencyLeftLabels;
+track->mapItem = adjacencyMapItem;
+
+// Disinherit next/prev flag and methods since we don't support next/prev:
+track->nextExonButtonable = FALSE;
+track->nextPrevExon = NULL;
+track->nextPrevItem = NULL;
+track->loadItems = adjacencyLoadItems;
+track->canPack = TRUE;
+}
+