src/hg/hgTracks/netTrack.c 1.24
1.24 2009/03/17 04:35:42 hiram
allow net tracks to color by gray scale, and fixing chain tracks Ui options
Index: src/hg/hgTracks/netTrack.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/hgTracks/netTrack.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -b -B -U 1000000 -r1.23 -r1.24
--- src/hg/hgTracks/netTrack.c 20 Feb 2008 00:42:27 -0000 1.23
+++ src/hg/hgTracks/netTrack.c 17 Mar 2009 04:35:42 -0000 1.24
@@ -1,266 +1,300 @@
/* netTrack - stuff to handle loading and display of
* netAlign type tracks in browser. Nets are derived
* from cross-species alignments usually. */
#include "common.h"
#include "hash.h"
#include "linefile.h"
#include "jksql.h"
#include "hdb.h"
#include "hgTracks.h"
#include "chainNet.h"
+#include "chainCart.h"
#include "chainNetDbLoad.h"
static char const rcsid[] = "$Id$";
+struct cartOptions
+ {
+ enum netColorEnum netColor; /* ChromColors, GrayScale */
+ int levelFilter ; /* filter chains by level 1 thru 6 */
+ };
+
struct netItem
/* A net track item. */
{
struct netItem *next;
int level;
char *className;
int yOffset;
};
static char *netClassNames[] = {
"Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", };
static struct netItem *makeNetItems()
/* Make the levels for net alignment track. */
{
struct netItem *ni, *niList = NULL;
int i;
int numClasses = ArraySize(netClassNames);
for (i=0; i<numClasses; ++i)
{
AllocVar(ni);
ni->level = i;
ni->className = netClassNames[i];
slAddHead(&niList, ni);
}
slReverse(&niList);
return niList;
}
static void netLoad(struct track *tg)
/* Load up net tracks. (Will query database during drawing for a change.) */
{
tg->items = makeNetItems();
}
static void netFree(struct track *tg)
/* Free up netGroup items. */
{
slFreeList(&tg->items);
}
static char *netName(struct track *tg, void *item)
/* Return name of net level track. */
{
struct netItem *ni = item;
return ni->className;
}
static struct track *rTg;
static struct hvGfx *rHvg;
static int rX; /* X offset of drawing area. */
static int rHeightPer; /* Height of boxes. */
static int rMidLineOff; /* Offset to draw connecting lines. */
static int rNextLine; /* Y offset to next line. */
static double rScale; /* Scale from bases to pixels. */
static boolean rIsFull; /* Full display? */
static char *netColorLastChrom;
static void netColorClearCashe()
{
netColorLastChrom = "UNKNOWN";
}
-static Color netColor(char *chrom)
+static Color netColor(struct track *tg, char *chrom, int level)
/* return appropriate color for a chromosome/scaffold */
{
+struct cartOptions *netCart;
+
+netCart = (struct cartOptions *) tg->extraUiData;
+
+if (netCart->netColor == netColorGrayScale)
+ switch(level)
+ {
+ case 1: return(shadesOfGray[9]); break;
+ case 2: return(shadesOfGray[7]); break;
+ case 3: return(shadesOfGray[6]); break;
+ case 4: return(shadesOfGray[5]); break;
+ case 5: return(shadesOfGray[4]); break;
+ case 6: return(shadesOfGray[3]); break;
+ default: return(shadesOfGray[2]); break;
+ }
+
static Color color;
if (!sameString(chrom, netColorLastChrom))
color = getSeqColor(chrom, rHvg);
if (0 == color)
color = 1; /* don't display in white */
netColorLastChrom = chrom;
return color;
}
static void rNetBox(struct hvGfx *hvg, struct cnFill *fill, int start, int end, int y, int level,
Color color, Color barbColor, int orientation)
/* Draw a scaled box. */
{
int x1,x2,w;
/* Do clipping before scaling because scaling may cause
* integer overflow. */
if (start < winStart) start = winStart;
if (end > winEnd) end = winEnd;
if (start >= end)
return;
x1 = round((double)(start-winStart)*rScale) + rX;
x2 = round((double)(end-winStart)*rScale) + rX;
w = x2-x1;
if (w < 1)
w = 1;
hvGfxBox(rHvg, x1, y, w, rHeightPer, color);
if (w > 3)
clippedBarbs(rHvg, x1, y+rMidLineOff, w, 2, 5, orientation, barbColor, TRUE);
if (w > 1)
{
if (rNextLine > 0) /* Put up click info in full mode. */
{
struct dyString *bubble = newDyString(256);
char depth[8];
snprintf(depth, sizeof(depth), "%d", level);
dyStringPrintf(bubble, "%s %c %dk ",
fill->qName, fill->qStrand, fill->qStart/1000);
mapBoxHc(hvg, start, end, x1, y, w, rHeightPer, rTg->mapName,
depth, bubble->string);
dyStringFree(&bubble);
}
}
}
static void rNetLine(struct hvGfx *hvg, struct cnFill *gap, int y, int level, Color color,
int orientation)
/* Write out line filling gap and associated info. */
{
int start = gap->tStart;
int end = start + gap->tSize;
int x1,x2,w;
/* Do clipping before scaling because scaling may cause
* integer overflow. */
if (start < winStart) start = winStart;
if (end > winEnd) end = winEnd;
if (start >= end)
return;
x1 = round((double)(start-winStart)*rScale) + rX;
x2 = round((double)(end-winStart)*rScale) + rX;
w = x2-x1;
if (w >= 1)
{
struct dyString *bubble = newDyString(256);
char depth[8];
int midY = y + rMidLineOff;
clippedBarbs(rHvg, x1, midY, w, 2, 5, orientation, color, FALSE);
hvGfxLine(rHvg, x1, midY, x2, midY, color);
if (rNextLine > 0) /* Put up click info in full mode. */
{
snprintf(depth, sizeof(depth), "%d", level);
dyStringPrintf(bubble, "size %d/%d Ns %d/%d newRep %d/%d",
gap->qSize, gap->tSize, gap->qN, gap->tN,
gap->qNewR, gap->tNewR);
mapBoxHc(hvg, start, end, x1, y, w, rHeightPer, rTg->mapName,
depth, bubble->string);
dyStringFree(&bubble);
}
}
}
-static void rNetDraw(struct hvGfx *hvg, struct cnFill *fillList, int level, int y)
+static void rNetDraw(struct track *tg, struct hvGfx *hvg, struct cnFill *fillList, int level, int y)
/* Recursively draw net. */
{
struct cnFill *fill;
struct cnFill *gap;
Color color, invColor;
int orientation;
for (fill = fillList; fill != NULL; fill = fill->next)
{
- color = netColor(fill->qName);
+ color = netColor(tg, fill->qName, level);
invColor = hvGfxContrastingColor(rHvg, color);
orientation = orientFromChar(fill->qStrand);
if (fill->children == NULL || fill->tSize * rScale < 2.5)
/* Draw single solid box if no gaps or no room to draw gaps. */
{
rNetBox(hvg, fill, fill->tStart, fill->tStart + fill->tSize, y, level,
color, invColor, orientation);
}
else
{
int fStart = fill->tStart;
for ( gap = fill->children; gap != NULL; gap = gap->next)
{
if (gap->tSize * rScale >= 1)
{
rNetBox(hvg, fill, fStart, gap->tStart, y, level,
color, invColor, orientation);
fStart = gap->tStart + gap->tSize;
rNetLine(hvg, gap, y, level+1, color, orientation);
}
}
rNetBox(hvg, fill, fStart, fill->tStart + fill->tSize, y, level,
color, invColor, orientation);
}
for (gap = fill->children; gap != NULL; gap = gap->next)
{
if (gap->children)
{
- rNetDraw(hvg, gap->children, level+2, y + rNextLine);
+ rNetDraw(tg, hvg, gap->children, level+2, y + rNextLine);
}
}
}
}
static void netDraw(struct track *tg, int seqStart, int seqEnd,
struct hvGfx *hvg, int xOff, int yOff, int width,
MgFont *font, Color color, enum trackVisibility vis)
/* Draw routine for netAlign type tracks. This will load
* the items as well as drawing them. */
{
/* Load Net. */
struct chainNet *net = chainNetLoadRange(database, tg->mapName, chromName,
seqStart, seqEnd, NULL);
if (net != NULL)
{
/* Copy parameters to statics for recursive routine. */
rTg = tg;
rHvg = hvg;
rX = xOff;
/* Clear cashe. */
netColorClearCashe();
/* Compute a few other positional things for recursive routine. */
rHeightPer = tg->heightPer;
rMidLineOff = rHeightPer/2;
rIsFull = (vis == tvFull);
if (rIsFull)
rNextLine = tg->lineHeight;
else
rNextLine = 0;
rScale = scaleForPixels(width);
/* Recursively do main bit of work. */
- rNetDraw(hvg, net->fillList, 1, yOff);
+ rNetDraw(tg, hvg, net->fillList, 1, yOff);
chainNetFree(&net);
}
if (vis == tvDense)
mapBoxToggleVis(hvg, xOff, yOff, width, tg->heightPer, tg);
}
void netMethods(struct track *tg)
/* Make track group for chain/net alignment. */
{
+struct cartOptions *netCart;
+
+AllocVar(netCart);
+
+netCart->netColor = netColorStringToEnum(
+ trackDbSettingClosestToHomeOrDefault(tg->tdb, NET_COLOR, CHROM_COLORS));
+/* allow cart to override trackDb */
+netCart->netColor = netColorStringToEnum(
+ cartUsualStringClosestToHome(cart, tg->tdb, FALSE, NET_COLOR,
+ netColorEnumToString(netCart->netColor)));
+
tg->loadItems = netLoad;
tg->freeItems = netFree;
tg->drawItems = netDraw;
tg->itemName = netName;
tg->mapItemName = netName;
tg->totalHeight = tgFixedTotalHeightNoOverflow;
tg->itemHeight = tgFixedItemHeight;
tg->itemStart = tgItemNoStart;
tg->itemEnd = tgItemNoEnd;
tg->mapsSelf = TRUE;
+tg->extraUiData = (void *) netCart;
}
-