src/hg/instinct/hgBamBam/hgBamBam.c 1.8
1.8 2010/06/01 06:29:06 jsanborn
updated
Index: src/hg/instinct/hgBamBam/hgBamBam.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/hgBamBam/hgBamBam.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -b -B -U 1000000 -r1.7 -r1.8
--- src/hg/instinct/hgBamBam/hgBamBam.c 1 Jun 2010 04:00:48 -0000 1.7
+++ src/hg/instinct/hgBamBam/hgBamBam.c 1 Jun 2010 06:29:06 -0000 1.8
@@ -1,476 +1,477 @@
/* hgBamBam */
#include "common.h"
#include "bed.h"
#include "cart.h"
#include "linefile.h"
#include "genoLay.h"
#include "hash.h"
#include "hCommon.h"
#include "hdb.h"
#include "hPrint.h"
#include "htmshell.h"
#include "hui.h"
#include "trackLayout.h"
#include "web.h"
#include "json.h"
#include "hgBamBam.h"
static char const rcsid[] = "$Id$";
/* ---- Global variables. ---- */
struct cart *cart; /* This holds cgi and other variables between clicks. */
struct hash *oldVars; /* Old cart hash. */
char *db = "pdata";
char *localDb = "localDb";
void usage()
/* Explain usage and exit. */
{
errAbort(
"hgBamBam\n"
"usage:\n"
" hgBamBam\n"
);
}
/****** BEGIN HELPER FUNCTIONS *******/
struct bed *getBed(struct sqlConnection *conn, char *tableName, char *pos, int nField)
{
/* get the data from the database */
char **row = NULL;
char query[512];
query[0] = '\0';
if (!pos)
safef(query, sizeof(query), "select * from %s", tableName);
else
{
char *chrom = NULL;
int start = 0;
int stop = 0;
if (!hgParseChromRange(NULL, pos, &chrom, &start, &stop))
return NULL;
safef(query, sizeof(query),
"select * from %s where chrom = '%s' and chromStart<%d and chromEnd>%d",
tableName, chrom, stop, start);
}
struct sqlResult *sr = sqlGetResult(conn, query);
struct bed *tuple = NULL;
struct bed *tupleList = NULL;
/* all copy number tracks are bed 4 */
while ((row = sqlNextRow(sr)) != NULL)
{
tuple = bedLoadN(row+1, nField);
slAddHead(&tupleList, tuple);
}
slReverse(&tupleList);
sqlFreeResult(&sr);
return tupleList;
}
struct breaks *getBreaks(struct sqlConnection *conn, char *tableName, char *pos, boolean intra)
{
/* get the data from the database */
char **row = NULL;
char query[512];
query[0] = '\0';
if (!pos)
{
if (intra)
safef(query, sizeof(query), "select * from %s where chrom = chrom2", tableName);
else
safef(query, sizeof(query), "select * from %s where chrom != chrom2", tableName);
}
else
{
char *chrom = NULL;
int start = 0;
int stop = 0;
if (!hgParseChromRange(NULL, pos, &chrom, &start, &stop))
return NULL;
if (intra)
safef(query, sizeof(query),
"select * from %s where chrom = chrom2 and chrom = '%s' and (chromStart<%d and chromEnd>%d) or (chromStart2<%d and chromEnd2>%d) or (chromStart<%d and chromEnd2>%d) or (chromStart2<%d and chromEnd>%d)",
tableName, chrom, stop, start, stop, start, stop, start, stop, start);
else
safef(query, sizeof(query),
"select * from %s where chrom != chrom2 and ((chrom = '%s' and chromStart<%d and chromEnd>%d) or (chrom2 = '%s' and chromStart2<%d and chromEnd2>%d))",
tableName, chrom, stop, start, chrom, stop, start);
}
struct sqlResult *sr = sqlGetResult(conn, query);
struct breaks *br, *brList = NULL;
/* all copy number tracks are bed 4 */
while ((row = sqlNextRow(sr)) != NULL)
{
AllocVar(br);
br->chrom = cloneString(row[0]);
br->chromStart = atoi(row[1]);
br->chromEnd = atoi(row[2]);
strcpy(br->strand, row[3]);
br->chrom2 = cloneString(row[4]);
br->chromStart2 = atoi(row[5]);
br->chromEnd2 = atoi(row[6]);
strcpy(br->strand2, row[7]);
br->support = atoi(row[8]);
br->qual = atof(row[9]);
slAddHead(&brList, br);
}
slReverse(&brList);
sqlFreeResult(&sr);
return brList;
}
/****** END HELPER FUNCTIONS *******/
float drawCopy(struct sqlConnection *conn, struct json *js,
char *pos, int width, int height, char *sampleName, char *suffix,
char *title, float maxVal, float medVal, Color col)
{
char tableName[256];
safef(tableName, sizeof(tableName), "%s_%s", sampleName, suffix);
struct bed *bed = getBed(conn, tableName, pos, 4);
struct settings *settings = initSettings(conn, pos, title, width, height, 0.0, maxVal);
char *filename = copyNumberGif(conn, bed, settings, suffix, 0.0, col);
if (!filename)
return 0.0;
char jsName[256];
safef(jsName, sizeof(jsName), "image_%s", suffix);
jsonAddString(js, jsName, filename);
bedFree(&bed);
return settings->maxVal;
}
void drawInterBreaks(struct sqlConnection *conn, struct json *js,
char *pos, int width, char *name, char *suffix)
{
char tableName[256];
safef(tableName, sizeof(tableName), "%s_%s", name, suffix);
int height = DEFAULT_LABEL_HEIGHT;
struct breaks *breaks = getBreaks(conn, tableName, pos, FALSE); // FALSE = inter
struct settings *settings = initSettings(conn, pos, "Inter-Chromosomal Breaks", width, height, 0, 0);
char *filename = interBreaksGif(conn, breaks, settings);
if (!filename)
return;
char jsName[256];
safef(jsName, sizeof(jsName), "inter_%s", suffix);
jsonAddString(js, jsName, filename);
jsonAddInt(js, "interBreaksHeight", settings->height);
}
void drawIntraBreaks(struct sqlConnection *conn, struct json *js,
char *pos, int width, char *name, char *suffix)
{
char tableName[256];
safef(tableName, sizeof(tableName), "%s_%s", name, suffix);
int height = DEFAULT_LABEL_HEIGHT;
struct breaks *breaks = getBreaks(conn, tableName, pos, TRUE); // TRUE = intra
struct settings *settings = initSettings(conn, pos, "Intra-Chromosomal Breaks", width, height, 0, 0);
char *filename = intraBreaksGif(conn, breaks, settings);
if (!filename)
return;
char jsName[256];
safef(jsName, sizeof(jsName), "intra_%s", suffix);
jsonAddString(js, jsName, filename);
jsonAddInt(js, "intraBreaksHeight", settings->height);
}
void drawIdeo(struct sqlConnection *conn, struct json *js,
char *pos, int width)
{
int height = DEFAULT_LABEL_HEIGHT + CYTO_HEIGHT;
struct settings *settings = initSettings(conn, pos, NULL, width, height, 0, 0);
char *filename = genomeLabelsGif(conn, settings);
if (!filename)
return;
jsonAddString(js, "ideogram", filename);
}
void drawGenes(struct sqlConnection *conn, struct json *js,
char *pos, int width)
{
int height = DEFAULT_LABEL_HEIGHT + TITLE_HEIGHT;
struct settings *settings = initSettings(conn, pos, "RefSeq Genes", width, height, 0, 0);
char *filename = annotationGif(settings, "refGene");
if (!filename)
return;
jsonAddString(js, "genes", filename);
jsonAddInt(js, "genesHeight", settings->height);
}
void drawSNPs(struct sqlConnection *conn, struct json *js,
char *pos, int width, char *name, char *suffix)
{
int height = DEFAULT_LABEL_HEIGHT;
struct settings *settings = initSettings(conn, pos,
"Single Nucleotide Variants", width, height, 0, 0);
char tableName[256];
safef(tableName, sizeof(tableName), "%s_%s", name, suffix);
char *filename = snpsGif(settings, tableName);
if (!filename)
return;
char jsName[256];
safef(jsName, sizeof(jsName), "image_%s", suffix);
jsonAddString(js, jsName, filename);
jsonAddInt(js, "snpsHeight", settings->height);
}
void drawScale(struct sqlConnection *conn, struct json *js,
char *pos, int width)
{
int height = DEFAULT_LABEL_HEIGHT;
struct settings *settings = initSettings(conn, pos, NULL, width, height, 0, 0);
char *filename = genomeScaleGif(settings);
if (!filename)
return;
jsonAddString(js, "scale", filename);
}
char *getPosition(struct genoLayChrom *glList)
{
char *pos = cartUsualString(cart, bbPos, NULL);
if (!pos)
return NULL;
if (sameString(pos, ""))
return NULL;
char *chrom;
int start = -1, stop = -1;
struct genoLayChrom *gl;
for (gl = glList; gl; gl = gl->next)
{
if (!sameString(gl->fullName, pos))
continue;
break;
}
if (gl) // only single chrom (e.g. "chr7") given as input.
chrom = cloneString(gl->fullName);
else
{
if (!hgParseChromRange(NULL, pos, &chrom, &start, &stop))
return NULL;
for (gl = glList; gl; gl = gl->next)
{
if (!sameString(gl->fullName, chrom))
continue;
break;
}
if (!gl)
return NULL;
}
if (start <= 0 && stop <= 0)
{
start = 1;
stop = gl->size - 1;
}
if (start <= 0)
start = 1;
else if (start > gl->size - 1)
start = gl->size - 1;
if (stop <= 0)
stop = 1;
else if (stop > gl->size - 1)
stop = gl->size - 1;
char newPos[256];
safef(newPos, sizeof(newPos), "%s:%d-%d", chrom, start, stop);
return cloneString(newPos);
}
void draw()
{
struct sqlConnection *conn = hAllocConnProfile(localDb, db);
struct genoLayChrom *glList = genoLayDbChroms(conn, FALSE);
char *pos = getPosition(glList);
int width = cartUsualInt(cart, bbWidth, DEFAULT_PLOT_WIDTH);
int height = cartUsualInt(cart, bbHeight, DEFAULT_PLOT_HEIGHT);
char *name = cartUsualString(cart, bbSampleName, NULL);
if (!name)
return;
struct json *js = newJson();
float maxVal = FLOAT_NULL;
drawCopy(conn, js, pos, width, height, name,
"cnv", "Overall Copy Number", FLOAT_NULL, 0.0, MG_BLACK);
/* set max val according to majority copy number */
maxVal = drawCopy(conn, js, pos, width, height, name,
"major", "Majority Copy Number", maxVal, 0.0, MG_RED);
drawCopy(conn, js, pos, width, height, name,
"minor", "Minority Copy Number", maxVal, 0.0, MG_BLUE);
drawSNPs(conn, js, pos, width, name, "snps");
drawInterBreaks(conn, js, pos, width, name, "breaks");
drawIntraBreaks(conn, js, pos, width, name, "breaks");
drawIdeo(conn, js, pos, width);
drawGenes(conn, js, pos, width);
drawScale(conn, js, pos, width);
if (pos)
jsonAddString(js, "pos", pos);
else
jsonAddString(js, "pos", "");
struct settings *settings = initSettings(conn, pos, "settings", width, height, 0, 0);
if (settings)
{
struct json *new, *list = jsonAddContainerList(js, "chroms");
new = list;
struct chromLay *cl;
for (cl = settings->layoutList; cl; cl = cl->next)
{
jsonAddString(new, "name", cl->chrom);
jsonAddDouble(new, "baseStart", cl->baseStart);
jsonAddDouble(new, "baseEnd", cl->baseEnd);
jsonAddDouble(new, "baseWidth", cl->baseWidth);
jsonAddInt(new, "pxStart", cl->pxStart);
jsonAddInt(new, "pxStop", cl->pxStart + cl->pxWidth);
jsonAddInt(new, "pxWidth", cl->pxWidth);
if (cl->next)
new = jsonAddContainerToList(&list);
}
}
if (js)
hPrintf("%s\n", js->print(js));
hFreeConn(&conn);
}
void share()
{
char *emailTo = cartUsualString(cart, bbEmailTo, NULL);
char *emailFrom = cartUsualString(cart, bbEmailFrom, NULL);
+char *emailSubject = cartUsualString(cart, bbEmailSubject, "UCSC BamBam Browser link");
char *link = cartUsualString(cart, bbLink, NULL);
struct json *js = newJson();
if (!emailTo || !emailFrom || !link)
- jsonAddString(js, "response", "All fields must be filled.");
+ jsonAddString(js, "response", "Email fields must be filled.");
else
{
char cmd[1024];
safef(cmd, sizeof(cmd),
"echo 'User %s wanted you to check out:\n\n%s\n\nCourtesy of the UCSC BamBam Browser.'"
- "| mail -s \"UCSC BamBam Browser link\" -c %s %s",
- emailFrom, link, emailFrom, emailTo);
+ "| mail -s \"%s\" -c %s %s",
+ emailFrom, link, emailSubject, emailFrom, emailTo);
int result = system(cmd);
if (result == -1)
jsonAddString(js, "response", "Error sending email.");
else
{
char response[256];
- safef(response, sizeof(response), "Email sent to %s", emailTo);
+ safef(response, sizeof(response), "Email sent");
jsonAddString(js, "response", response);
}
}
if (js)
hPrintf("%s\n", js->print(js));
}
void dispatchRoutines()
/* Look at command variables in cart and figure out which
* page to draw. */
{
/* retrieve cart variables, handle various modes */
char *mode = cartOptionalString(cart, bbMode);
if (!mode)
errAbort("%s is required.", bbMode);
if (sameString(mode, "draw"))
draw();
else if (sameString(mode, "share"))
share();
else
errAbort("Incorrect mode = %s", mode);
cartRemovePrefix(cart, bbPrefix);
}
void hghDoUsualHttp()
/* Wrap html page dispatcher with code that writes out
* HTTP header and write cart back to database. */
{
cartWriteCookie(cart, hUserCookie());
printf("Content-Type:application/x-javascript\r\n\r\n");
/* Dispatch other pages, that actually want to write HTML. */
cartWarnCatcher(dispatchRoutines, cart, jsonEarlyWarningHandler);
cartCheckout(&cart);
}
char *excludeVars[] = {"Submit", "submit", NULL};
int main(int argc, char *argv[])
/* Process command line. */
{
htmlPushEarlyHandlers();
cgiSpoof(&argc, argv);
htmlSetStyle(htmlStyleUndecoratedLink);
oldVars = hashNew(12);
cart = cartForSession(hUserCookie(), excludeVars, oldVars);
hghDoUsualHttp();
return 0;
}