src/hg/instinct/subjectView/subjectView.c 1.8
1.8 2009/11/19 20:18:52 jsanborn
fixed genoheatmap ref to url member
Index: src/hg/instinct/subjectView/subjectView.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/subjectView/subjectView.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -b -B -U 1000000 -r1.7 -r1.8
--- src/hg/instinct/subjectView/subjectView.c 24 Dec 2008 02:31:38 -0000 1.7
+++ src/hg/instinct/subjectView/subjectView.c 19 Nov 2009 20:18:52 -0000 1.8
@@ -1,361 +1,361 @@
/* subjectView - A CGI script to display the patient (subject) details page for all studies
*/
#include "common.h"
#include "linefile.h"
#include "hash.h"
#include "jksql.h"
#include "cheapcgi.h"
#include "htmshell.h"
#include "cart.h"
#include "hui.h"
#include "dbDb.h"
#include "hdb.h"
#include "web.h"
#include "microarray.h"
#include "ra.h"
#include "spDb.h"
#include "genePred.h"
#include "hgColors.h"
#include "hPrint.h"
#include "subjectView.h"
#include "hgHeatmapLib.h"
#include "featuresLib.h"
static char const rcsid[] = "$Id$";
/* ---- Global variables. ---- */
struct cart *cart; /* This holds cgi and other variables between clicks. */
struct hash *oldCart; /* Old cart hash. */
char *genome; /* Name of genome - mouse, human, etc. */
char *database; /* Name of genome database - hg15, mm3, or the like. */
#define UNCAT_STRING "Uncategorized"
void usage()
/* Explain usage and exit. */
{
errAbort(
"subjectView - A CGI script to display the subject details page.\n"
"usage:\n"
" subjectView cgi-vars in var=val format\n"
"options:\n"
" -dataset= Dataset to search for subject id"
" -subjectId= ID of subject\n"
);
}
/* --------------- Low level utility functions. ----------------- */
char *heatMapDbProfile = "localDb";
struct genoHeatmap *getGenoHeatmapMatching(char *dataset, char *raName)
/* Get graphs defined. Requried to be present in the database as well as
in the datasets.ra file */
{
if (!dataset)
return NULL;
struct sqlConnection *conn = hAllocConnProfile(heatMapDbProfile, database);
if (!conn)
return NULL;
char *name;
struct column *col, *colList = getColumns(NULL, raName, NULL);
if (colList == NULL)
errAbort("Couldn't find anything from %s", raName);
for (col = colList; col != NULL; col = col->next)
{
name = (char *)(hashFindVal(col->settings, "name"));
if (sameString(dataset, name))
break;
}
if (!col)
return NULL;
return getHeatmap(conn, database, name, col->settings);
}
char *getFirstSubjectId(struct sqlConnection *conn, struct column *col)
{
if (!col)
return NULL;
char query[128];
safef(query, sizeof(query), "select %s from %s limit 1",
col->keyField, col->table);
return sqlQuickString(conn, query);
}
boolean subjectExists(struct sqlConnection *conn, struct column *col, char *patientId)
{
if (!col)
return FALSE;
if (!col->keyField || !col->table || !patientId)
return FALSE;
char query[128];
safef(query, sizeof(query), "select %s from %s where %s = '%s'",
col->keyField, col->table, col->keyField, patientId);
return sqlExists(conn, query);
}
int sectionCmpPriority(const void *va, const void *vb)
/* Compare to sort sections based on priority. */
{
const struct section *a = *((struct section **)va);
const struct section *b = *((struct section **)vb);
float dif = a->priority - b->priority;
if (dif < 0)
return -1;
else if (dif > 0)
return 1;
else
return 0;
}
int sectionDataCmpPriority(const void *va, const void *vb)
/* Compare to sort sections based on priority. */
{
const struct sectionData *a = *((struct sectionData **)va);
const struct sectionData *b = *((struct sectionData **)vb);
float dif = a->priority - b->priority;
if (dif < 0)
return -1;
else if (dif > 0)
return 1;
else
return 0;
}
struct section *convertColumnToSections(struct sqlConnection *conn,
struct column *colList, char *patientId)
{
if (!colList)
return NULL;
struct slName *id = slNameNew(patientId);
struct column *col;
struct sectionData *sd;
struct hash *seHash = hashNew(10);
struct section *se, *sections = NULL;
for (col = colList; col; col = col->next)
{
char *name = col->group;
if (!name)
name = UNCAT_STRING;
struct hashEl *el = hashLookup(seHash, name);
if (!el)
{
AllocVar(se);
se->name = cloneString(name);
se->data = NULL;
se->priority = -1;
slAddHead(§ions, se);
hashAdd(seHash, name, se);
}
else
se = el->val;
if (col->priority > se->priority)
se->priority = col->priority;
AllocVar(sd);
sd->name = cloneString(col->longLabel);
sd->val = col->cellCodedVal(col, id, conn);
sd->priority = col->priority;
slAddHead(&se->data, sd);
}
/* sort everything accoring to priority */
slSort(§ions, sectionCmpPriority);
for (se = sections; se; se = se->next)
slSort(&se->data, sectionDataCmpPriority);
if (slCount(sections) == 1 && sameString(sections->name, UNCAT_STRING))
sections->name = cloneString("Subject Information");
return sections;
}
char *getPatientIdFromSampleId(struct sqlConnection *conn, char *id,
char *table, char *sampleField, char *patientField)
{
char query[128];
safef(query, sizeof(query), "select %s from %s where %s = '%s'",
patientField, table, sampleField, id);
return sqlQuickString(conn, query);
}
void printSubjectData(struct sqlConnection *conn, struct genoHeatmap *gh,
struct column *colList, char *patientId)
{
char *id = NULL;
if (!subjectExists(conn, colList, patientId) &&
(gh->patTable && gh->sampleField && gh->patField))
{/* No matching patient id, check if it matches a sample id and get patient id from it */
id = getPatientIdFromSampleId(conn, patientId, gh->patTable,
gh->sampleField, gh->patField);
if (subjectExists(conn, colList, id))
patientId = id;
}
if (!subjectExists(conn, colList, patientId))
{
printf("<H3>No data available for Subject <font color=red>%s</font></H3>", patientId);
fflush(stdout);
return;
}
struct sectionData *sd;
struct section *se, *sections = convertColumnToSections(conn, colList, patientId);
for (se = sections; se; se = se->next)
{
webNewSection("<B><font size=4>%s</font></B>", se->name);
printf("<table border='0' cellspacing='10'>");
for (sd = se->data; sd; sd = sd->next)
{
printf("<tr>");
printf("<td><B>%s</B></td>", sd->name);
if (sd->val)
printf("<td align='right'>%s</td>", sd->val);
else
printf("<td align='right'>N/A</td>");
printf("</tr>");
}
printf("</table>");
}
}
void hotLinks()
/* Put up the hot links bar. */
{
hPrintf("<LINK REL='STYLESHEET' HREF='../style/HGStyle.css' TYPE='text/css'>");
hPrintf("<!-- +++++++++++++++++++++ HOTLINKS BAR +++++++++++++++++++ -->");
hPrintf("<TR><TD COLSPAN=3 HEIGHT=40 >");
hPrintf("<table bgcolor='#000000' cellpadding='1' cellspacing='1' width='100%%' height='27'>");
hPrintf("<tr bgcolor='#2636D1'><td valign='middle'>");
hPrintf(" <table BORDER=0 CELLSPACING=0 CELLPADDING=0 bgcolor='#2636D1' height='24'><TR>");
hPrintf("<TD VALIGN='middle'><font color='#89A1DE'> ");
hPrintf(" <A HREF='../index.html?org=Human&db=hg18' class='topbar'>Home</A> ");
hPrintf("<A HREF='../cgi-bin/hgGateway?org=Human&db=hg18' class='topbar'>Genomes</A> ");
hPrintf("<A HREF='../cgi-bin/hgBlat?command=start&org=Human&db=hg18' class='topbar'>Blat</A> ");
hPrintf("<A HREF='../cgi-bin/hgTables?org=Human&db=hg18&hgta_doMainPage=1' class='topbar'>Tables</A> ");
hPrintf("<A HREF='../cgi-bin/hgNear?org=Human&db=hg18' class='topbar'>Gene Sorter</A> ");
hPrintf("<A HREF='../cgi-bin/hgPcr?org=Human&db=hg18' class='topbar'>PCR</A> ");
hPrintf("<A HREF='../cgi-bin/hgSession?org=Human&db=hg18&hgS_doMainPage=1' class='topbar'>Session</A> ");
hPrintf("<A HREF='../FAQ/' class='topbar'>FAQ</A> ");
hPrintf("<A HREF='../goldenPath/help/hgTracksHelp.html' class='topbar'>Help</A>");
hPrintf(" </font></TD>");
hPrintf("</TR></TABLE>");
hPrintf("</TD></TR></TABLE>");
hPrintf("</TD></TR>");
}
void webMain(struct sqlConnection *conn, struct genoHeatmap *gh, char *id)
/* Set up fancy web page with hotlinks bar and
* sections. */
{
struct column *colList = getColumns(conn, gh->raFile, gh->patDb);
if (!colList)
errAbort("Error: subject data not retrievable.");
printf("<FORM ACTION=\"/cgi-bin/subjectView\" NAME=\"mainForm\" METHOD=\"POST\">\n");
hotLinks();
printf("<BR><font size=\"5\"><B>Subject ID: %s</B></font><BR>", id);
-if (gh->url)
- printf(" <A HREF='%s'>%s</a>", gh->url, gh->longLabel);
+if (gh->local_url)
+ printf(" <A HREF='%s'>%s</a>", gh->local_url, gh->longLabel);
else
printf(" %s", gh->longLabel);
if (sameString(id, ""))
printf("<BR><BR> Enter Subject ID: ");
else
printf(" Search for another subject: ");
cgiMakeTextVar(subjViewSubjectId, "", 20);
cgiMakeHiddenVar(subjViewDataset, gh->name);
cgiMakeButton("submit", "Go!");
char *firstId = NULL;
if (sameString(id, "") && (firstId = getFirstSubjectId(conn, colList)) != NULL)
printf(" (e.g. %s)", firstId);
printf("<BR>");
if (!sameString(id, ""))
printSubjectData(conn, gh, colList, id);
puts("</FORM>");
}
void cartMain(struct cart *theCart)
/* We got the persistent/CGI variable cart. Now
* set up the globals and make a web page. */
{
struct sqlConnection *conn = NULL;
cart = theCart;
getDbAndGenome(cart, &database, &genome, oldCart);
char *id = cgiOptionalString(subjViewSubjectId);
if (!id)
id = "";
char *dataset = cgiOptionalString(subjViewDataset);
if (!dataset)
errAbort("Error: CGI variable %s required.", subjViewDataset);
struct genoHeatmap *gh = getGenoHeatmapMatching(dataset, "datasets.ra");
if (!gh)
errAbort("Error: Dataset '%s' does not exist in database %s.", dataset, database);
if (!gh->patDb)
errAbort("Error: Dataset '%s' does not have clinical database.", dataset);
char title[128];
safef(title, sizeof(title), "Subject %s -- %s", id, gh->longLabel);
cartHtmlStart(title);
database = cloneString(gh->patDb);
conn = hAllocConnProfile(heatMapDbProfile, database);
webMain(conn, gh, id);
hFreeConn(&conn);
cartHtmlEnd();
}
char *excludeVars[] = {"Submit", "submit", subjViewSubjectId, NULL};
int main(int argc, char *argv[])
/* Process command line. */
{
if (argc != 1)
usage();
cgiSpoof(&argc, argv);
htmlSetBgColor(0xFFF9D2);
oldCart = hashNew(12);
cartEmptyShell(cartMain, hUserCookie(), excludeVars, oldCart);
return 0;
}