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(&sections, 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(&sections, 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'>&nbsp;");
 hPrintf("&nbsp;<A HREF='../index.html?org=Human&db=hg18' class='topbar'>Home</A> &nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../cgi-bin/hgGateway?org=Human&db=hg18' class='topbar'>Genomes</A> &nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../cgi-bin/hgBlat?command=start&org=Human&db=hg18' class='topbar'>Blat</A> &nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../cgi-bin/hgTables?org=Human&db=hg18&hgta_doMainPage=1' class='topbar'>Tables</A> &nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../cgi-bin/hgNear?org=Human&db=hg18' class='topbar'>Gene Sorter</A> &nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../cgi-bin/hgPcr?org=Human&db=hg18' class='topbar'>PCR</A> &nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../cgi-bin/hgSession?org=Human&db=hg18&hgS_doMainPage=1' class='topbar'>Session</A>&nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../FAQ/' class='topbar'>FAQ</A> &nbsp;&nbsp;&nbsp;");
 hPrintf("<A HREF='../goldenPath/help/hgTracksHelp.html' class='topbar'>Help</A>");
 hPrintf("&nbsp;</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("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF='%s'>%s</a>", gh->url, gh->longLabel);
+if (gh->local_url)
+    printf("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF='%s'>%s</a>", gh->local_url, gh->longLabel);
 else
     printf("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s", gh->longLabel);
 
 if (sameString(id, ""))
     printf("<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enter Subject ID:&nbsp;");
 else
     printf("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Search for another subject:&nbsp;");
 
 cgiMakeTextVar(subjViewSubjectId, "", 20);
 cgiMakeHiddenVar(subjViewDataset, gh->name);
 cgiMakeButton("submit", "Go!");
 char *firstId = NULL;
 if (sameString(id, "") && (firstId = getFirstSubjectId(conn, colList)) != NULL)
     printf("&nbsp;&nbsp;&nbsp;&nbsp;(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;
 }