src/hg/hgc/expClick.c 1.25
1.25 2010/05/11 01:43:28 kent
Refactoring to split the trackDb.tableName field into separate track and table fields. Similarly track.mapName field goes to the same track and table fields.
Index: src/hg/hgc/expClick.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/hgc/expClick.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -b -B -U 1000000 -r1.24 -r1.25
--- src/hg/hgc/expClick.c 22 Jan 2010 22:52:04 -0000 1.24
+++ src/hg/hgc/expClick.c 11 May 2010 01:43:28 -0000 1.25
@@ -1,488 +1,488 @@
/* Handle details pages for expression ratio tracks. */
#include "common.h"
#include "hash.h"
#include "linefile.h"
#include "hgc.h"
#include "hui.h"
#include "expRecord.h"
#include "obscure.h"
#include "cheapcgi.h"
#include "genePred.h"
#include "affyAllExonProbe.h"
#include "microarray.h"
static char const rcsid[] = "$Id$";
/* global flag to indicate if the track is a cancer genomics track */
boolean isCancerGenomicsTrack = FALSE;
static struct rgbColor getColorForExprBed(float val, float max,
enum expColorType colorScheme)
/* Return the correct color for a given score */
{
float absVal = fabs(val);
struct rgbColor color;
int colorIndex = 0;
/* if log score is -10000 data is missing */
if(val == -10000)
{
color.g = color.r = color.b = 128;
return(color);
}
if(absVal > max)
absVal = max;
if (max == 0)
errAbort("ERROR: hgc::getColorForExprBed() maxDeviation can't be zero\n");
colorIndex = (int)(absVal * 255/max);
color.r = color.g = color.b = 0;
if (colorScheme == redBlue)
if (val > 0)
color.r = colorIndex;
else
color.b = colorIndex;
else if (colorScheme == yellowBlue)
if (val > 0)
{
color.r = colorIndex;
color.g = colorIndex;
}
else
color.b = colorIndex;
else if (colorScheme == redBlueOnWhite)
if (val > 0)
{
color.r = 255;
color.g = 255 - colorIndex;
color.b = 255 - colorIndex;
}
else
{
color.r = 255 - colorIndex;
color.g = 255 - colorIndex;
color.b = 255;
}
else if (colorScheme == redBlueOnYellow)
if (val > 0)
{
color.r = 255;
color.g = 255 - colorIndex;
}
else
{
color.r = 255 - colorIndex;
color.g = 255 - colorIndex;
color.b = colorIndex;
}
else
if (val > 0)
color.r = colorIndex;
else
color.g = colorIndex;
return color;
}
static void msBedPrintTableHeader(struct bed *bedList,
struct hash *erHash, char *itemName,
char **headerNames, int headerCount, char *scoresHeader)
/* print out a bed with multiple scores header for a table.
headerNames contain titles of columns up to the scores columns. scoresHeader
is a single string that will span as many columns as there are beds.*/
{
struct bed *bed;
int featureCount = slCount(bedList);
int i=0;
printf("<tr>");
for(i=0;i<headerCount; i++)
printf("<th align=center>%s</th>\n",headerNames[i]);
printf("<th align=center colspan=%d valign=top>%s</th>\n",featureCount, scoresHeader);
printf("</tr>\n<tr>");
for(i=0;i<headerCount; i++)
printf("<td> </td>\n");
for(bed = bedList; bed != NULL; bed = bed->next)
{
printf("<td valign=top align=center>\n");
printTableHeaderName(bed->name, itemName, NULL);
printf("</td>");
}
printf("</tr>\n");
}
static void msBedDefaultPrintHeader(struct bed *bedList, struct hash *erHash,
char *itemName)
/* print out a header with names for each bed with itemName highlighted */
{
char *headerNames[] = {"Experiment"};
char *scoresHeader = "Item Name";
msBedPrintTableHeader(bedList, erHash, itemName, headerNames, ArraySize(headerNames), scoresHeader);
}
static void printExprssnColorKey(float minVal, float maxVal, float stepSize, int base,
struct rgbColor(*getColor)(float val, float maxVal, enum expColorType colorScheme), enum expColorType colorScheme)
/* print out a little table which provides a color->score key */
{
float currentVal = -1 * maxVal;
int numColumns;
assert(stepSize != 0);
numColumns = maxVal/stepSize *2+1;
printf("<TABLE BGCOLOR=\"#000000\" BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"1\"><TR><TD>");
printf("<TABLE BGCOLOR=\"#fffee8\" BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"1\"><TR>");
printf("<th colspan=%d>False Color Key, all values log base %d</th></tr><tr>\n",numColumns, base);
/* have to add the stepSize/2 to account for the ability to
absolutely represent some numbers as floating points */
for(currentVal = minVal; currentVal <= maxVal + (stepSize/2); currentVal += stepSize)
{
printf("<th><b>%.1f </b></th>", currentVal);
}
printf("</tr><tr>\n");
for(currentVal = minVal; currentVal <= maxVal + (stepSize/2); currentVal += stepSize)
{
struct rgbColor rgb = getColor(currentVal, maxVal, colorScheme);
printf("<td bgcolor=\"#%.2X%.2X%.2X\"> </td>\n", rgb.r, rgb.g, rgb.b);
}
printf("</tr></table>\n");
printf("</td></tr></table>\n");
}
static void msBedExpressionPrintRow(struct bed *bedList, struct hash *erHash,
int expIndex, char *expName, float maxScore,
enum expColorType colorScheme)
/* print the name of the experiment and color the
background of individual cells using the score to
create false two color display */
{
char buff[32];
struct bed *bed = bedList;
struct expRecord *er = NULL;
int square = 10;
snprintf(buff, sizeof(buff), "%d", expIndex);
er = hashMustFindVal(erHash, buff);
printf("<tr>\n");
if(strstr(er->name, expName))
printf("<td align=left bgcolor=\"D9E4F8\"> %s</td>\n",er->name);
else
{
if (isCancerGenomicsTrack)
{
printf("<td align=left><A HREF=\"../cgi-bin/subjectView?sv_dataset=%s&sv_subjectId=%s\" TARGET=_blank>%s</A></td>\n",
cartString(cart, "g"), er->name, er->name);
}
else
{
printf("<td align=left> %s</td>\n", er->name);
}
}
for(bed = bedList;bed != NULL; bed = bed->next)
{
/* use the background colors to creat patterns */
struct rgbColor rgb = getColorForExprBed(bed->expScores[expIndex], maxScore, colorScheme);
printf("<td height=%d width=%d bgcolor=\"#%.2X%.2X%.2X\"> </td>\n", square, square, rgb.r, rgb.g, rgb.b);
}
printf("</tr>\n");
}
static void msBedPrintTable(struct bed *bedList, struct hash *erHash,
char *itemName, char *expName, float minScore, float maxScore,
float stepSize, int base,
void(*printHeader)(struct bed *bedList, struct hash *erHash, char *item),
void(*printRow)(struct bed *bedList,struct hash *erHash, int expIndex, char *expName, float maxScore, enum expColorType colorScheme),
void(*printKey)(float minVal, float maxVal, float size, int base, struct rgbColor(*getColor)(float val, float max, enum expColorType colorScheme), enum expColorType colorScheme),
struct rgbColor(*getColor)(float val, float max, enum expColorType colorScheme),
enum expColorType colorScheme)
/* prints out a table from the data present in the bedList */
{
int i,featureCount=0;
if(bedList == NULL)
errAbort("hgc::msBedPrintTable() - bedList is NULL");
featureCount = slCount(bedList);
/* time to write out some html, first the table and header */
if(printKey != NULL)
printKey(minScore, maxScore, stepSize, base, getColor, colorScheme);
printf("<p>\n");
printf("<basefont size=-1>\n");
printf("<table bgcolor=\"#000000\" border=\"0\" cellspacing=\"0\" cellpadding=\"1\"><tr><td>");
printf("<table bgcolor=\"#fffee8\" border=\"0\" cellspacing=\"0\" cellpadding=\"1\">");
printHeader(bedList, erHash, itemName);
for(i=0; i<bedList->expCount; i++)
{
printRow(bedList, erHash, i, expName, maxScore, colorScheme);
}
printf("</table>");
printf("</td></tr></table>");
printf("</basefont>");
}
static struct bed *loadMsBed(struct trackDb *tdb, char *table, char *chrom, uint start, uint end)
/* load every thing from a bed 15 table in the given range */
{
struct sqlConnection *conn = hAllocConnTrack(database, tdb);
struct sqlResult *sr;
char **row;
int rowOffset;
struct bed *bedList = NULL, *bed;
sr = hRangeQuery(conn, table, chrom, start, end, NULL, &rowOffset);
while ((row = sqlNextRow(sr)) != NULL)
{
bed = bedLoadN(row+rowOffset, 15);
slAddHead(&bedList, bed);
}
sqlFreeResult(&sr);
hFreeConn(&conn);
slReverse(&bedList);
return bedList;
}
static struct bed * loadMsBedAll(char *table)
/* load every thing from a bed 15 table */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr;
char **row;
struct bed *bedList = NULL, *bed;
char query[512];
sprintf(query, "select * from %s", table);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
bed = bedLoadN(row, 15);
slAddHead(&bedList, bed);
}
sqlFreeResult(&sr);
hFreeConn(&conn);
slReverse(&bedList);
return bedList;
}
static struct expRecord * loadExpRecord(char *table, char *database)
/* load everything from an expRecord table in the
specified database, usually hgFixed instead of hg7, hg8, etc. */
{
struct sqlConnection *conn = sqlConnect(database);
char query[256];
struct expRecord *erList = NULL;
snprintf(query, sizeof(query), "select * from %s", table);
erList = expRecordLoadByQuery(conn, query);
sqlDisconnect(&conn);
return erList;
}
void getMsBedExpDetails(struct trackDb *tdb, char *expName, boolean all)
/* Create tab-delimited output to download */
{
char *expTable = cartString(cart, "i");
char *bedTable = cartString(cart, "o");
struct expRecord *er, *erList=NULL;
struct bed *b, *bedList=NULL;
int i;
/* Get all of the expression record details */
erList = loadExpRecord(expTable, "hgFixed");
/* Get either all of the data, or only that data in the range */
if (all)
bedList = loadMsBedAll(bedTable);
else
bedList = loadMsBed(tdb, bedTable, seqName, winStart, winEnd);
/* Print out a header row */
printf("<HTML><BODY><PRE>\n");
printf("Name\tChr\tChrStart\tChrEnd\tTallChrStart\tTallChrEnd");
for (er = erList; er != NULL; er = er->next)
if (sameString(bedTable, "cghNci60"))
printf("\t%s(%s)",er->name, er->extras[1]);
else
printf("\t%s",er->name);
printf("\n");
/* Print out a row for each of the record in the bedList */
for (b = bedList; b != NULL; b = b->next)
{
printf("%s\t%s\t%d\t%d\t%d\t%d",b->name, b->chrom, b->chromStart, b->chromEnd, b->thickStart, b->thickEnd);
for (i = 0; i < b->expCount; i++)
if (i == b->expIds[i])
printf("\t%f",b->expScores[i]);
else
printf("\t");
printf("\n");
}
printf("</PRE>");
}
struct expRecord *basicExpRecord(char *expName, int id, int extrasIndex)
/* This returns a stripped-down new expRecord, probably the result of an average. */
{
int i;
struct expRecord *er = NULL;
AllocVar(er);
er->id = id;
er->name = cloneString(expName);
er->description = cloneString(expName);
er->url = cloneString("n/a");
er->ref = cloneString("n/a");
er->credit = cloneString("n/a");
er->numExtras = extrasIndex+1;
AllocArray(er->extras, er->numExtras);
for (i = 0; i < er->numExtras; i++)
er->extras[i] = cloneString(expName);
return er;
}
void bedListExpRecordAverage(struct bed **pBedList, struct expRecord **pERList, int extrasIndex)
/* This is a mildy complicated function to make the details page have the */
/* same data as the track when the UI option "Tissue averages" is selected. */
/* This is done by hacking the bed and expRecord lists in place and keeping */
/* the original code for the most part. */
{
struct bed *bed = NULL;
struct expRecord *er, *newERList = NULL;
struct slName *extras = NULL, *oneSlName;
int M, N, i, columns;
int *mapping;
if (!pBedList || !pERList || !*pBedList || !*pERList)
return;
er = *pERList;
if ((extrasIndex < 0) || (extrasIndex >= er->numExtras))
return;
/* Build up a unique list of words from the specific "extras" column. */
for (er = *pERList; er != NULL; er = er->next)
slNameStore(&extras, er->extras[extrasIndex]);
slReverse(&extras);
M = slCount(extras);
N = slCount(*pERList);
columns = N + 1;
/* M rows, reserve first column for counts. */
mapping = needMem(sizeof(int) * M * columns);
/* Create the mapping array: */
/* each row corresponds to one of the groupings. The first column is the number of */
/* things in the original list in the group (k things), and the next k elements on */
/* that row are indeces. */
for (er = *pERList, i = 0; er != NULL && i < N; er = er->next, i++)
{
int ix = slNameFindIx(extras, er->extras[extrasIndex]) * columns;
mapping[ix + ++mapping[ix]] = er->id;
}
/* Make a new expRecord list. */
for (oneSlName = extras, i = 0; oneSlName != NULL && i < M; oneSlName = oneSlName->next, i++)
{
struct expRecord *newER = basicExpRecord(oneSlName->name, i, extrasIndex);
slAddHead(&newERList, newER);
}
slReverse(&newERList);
expRecordFreeList(pERList);
*pERList = newERList;
/* Go through each bed and change it. */
for (bed = *pBedList; bed != NULL; bed = bed->next)
{
float *newExpScores = needMem(sizeof(float) * M);
int *newExpIds = needMem(sizeof(int) * M);
/* Calculate averages. */
for (i = 0; i < M; i++)
{
int ix = i * columns;
int size = mapping[ix];
int j;
double sum = 0;
for (j = 1; j < size + 1; j++)
sum += (double)bed->expScores[mapping[ix + j]];
newExpScores[i] = (float)(sum/size);
newExpIds[i] = i;
}
bed->expCount = M;
freeMem(bed->expIds);
bed->expIds = newExpIds;
freeMem(bed->expScores);
bed->expScores = newExpScores;
}
/* Free stuff. */
slNameFreeList(&extras);
freez(&mapping);
}
void erHashElFree(struct hashEl *el)
/* Frees up expRecord hash head. */
{
struct expRecord *er = el->val;
expRecordFree(&er);
}
void doExpRatio(struct trackDb *tdb, char *item, struct customTrack *ct)
/* Generic expression ratio deatils using microarrayGroups.ra file */
/* and not the expRecord tables. */
{
char *expScale = trackDbRequiredSetting(tdb, "expScale");
char *expStep = trackDbRequiredSetting(tdb, "expStep");
double maxScore = atof(expScale);
double stepSize = atof(expStep);
struct bed *bedList;
char *itemName = cgiUsualString("i2","none");
char *expName = (item == NULL) ? itemName : item;
char *tdbSetting = trackDbSettingOrDefault(tdb, "expColor", "redGreen");
char *colorVal = NULL;
enum expColorType colorScheme;
char colorVarName[256];
-safef(colorVarName, sizeof(colorVarName), "%s.color", tdb->tableName);
+safef(colorVarName, sizeof(colorVarName), "%s.color", tdb->track);
colorVal = cartUsualString(cart, colorVarName, tdbSetting);
colorScheme = getExpColorType(colorVal);
if (sameWord(tdb->grp, "cancerGenomics"))
{
/* set global flag */
isCancerGenomicsTrack = TRUE;
}
if (!ct)
{
genericHeader(tdb, itemName);
- bedList = loadMsBed(tdb, tdb->tableName, seqName, winStart, winEnd);
+ bedList = loadMsBed(tdb, tdb->table, seqName, winStart, winEnd);
}
else if (ct->dbTrack)
{
genericHeader(tdb, itemName);
printCustomUrl(tdb, itemName, TRUE);
bedList = ctLoadMultScoresBedDb(ct, seqName, winStart, winEnd);
}
else
bedList = bedFilterListInRange(ct->bedList, NULL, seqName, winStart, winEnd);
if (bedList == NULL)
printf("<b>No Expression Data in this Range.</b>\n");
else if (expName && sameString(expName, "zoomInMore"))
printf("<b>Too much data to display in detail in this range.</b>\n");
else
{
struct microarrayGroups *groupings = NULL;
struct maGrouping *combineGroup;
struct hash *erHash = newHash(6);
int i;
if (!ct)
{
groupings = maGetTrackGroupings(database, tdb);
- combineGroup = maCombineGroupingFromCart(groupings, cart, tdb->tableName);
+ combineGroup = maCombineGroupingFromCart(groupings, cart, tdb->track);
}
else
combineGroup = maGetGroupingFromCt(ct);
maBedClumpGivenGrouping(bedList, combineGroup);
for (i = 0; i < combineGroup->numGroups; i++)
{
/* make stupid exprecord hash.perhaps eventually this won't be needed */
char id[16];
struct expRecord *er = basicExpRecord(combineGroup->names[i], i, 2);
safef(id, sizeof(id), "%d", i);
hashAdd(erHash, id, er);
}
puts("<h2></h2><p>\n");
msBedPrintTable(bedList, erHash, itemName, expName, -1*maxScore, maxScore,
stepSize, 2, msBedDefaultPrintHeader, msBedExpressionPrintRow,
printExprssnColorKey, getColorForExprBed, colorScheme);
hashTraverseEls(erHash, erHashElFree);
hashFree(&erHash);
microarrayGroupsFree(&groupings);
}
puts("<h2></h2><p>\n");
bedFreeList(&bedList);
}