src/hg/instinct/bioInt2/bioIntUI.c 1.5

1.5 2009/03/31 01:06:15 jsanborn
added description field
Index: src/hg/instinct/bioInt2/bioIntUI.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/bioInt2/bioIntUI.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -b -B -U 1000000 -r1.4 -r1.5
--- src/hg/instinct/bioInt2/bioIntUI.c	29 Mar 2009 03:31:05 -0000	1.4
+++ src/hg/instinct/bioInt2/bioIntUI.c	31 Mar 2009 01:06:15 -0000	1.5
@@ -1,492 +1,519 @@
 /* bioIntUI */
 #include "common.h"
 #include "bed.h"
 #include "cart.h"
 #include "linefile.h"
 #include "customTrack.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 "microarray.h"
 #include "ra.h"
 #include "hgStatsLib.h"
 #include "featuresLib.h" 
 #include "json.h"
 #include "bioIntDb.h"
 #include "bioIntDriver.h"
 #include "bioIntUI.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 = "bioInt";
 char *localDb = "localDb";
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "bioIntUI\n"
   "usage:\n"
   "   bioIntUI\n"
   );
 }
 
 /****** BEGIN HELPER FUNCTIONS *******/
 
 struct analyses *getAnalysesById(struct sqlConnection *conn, int analysis_id)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select * from %s where id = %d;", 
       AN_TABLE, analysis_id);
 
 return analysesLoadByQuery(conn, query);
 }
 
 struct analyses *getAnalysesByCohortId(struct sqlConnection *conn, int cohort_id)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select * from %s where cohort_id = %d;", 
       AN_TABLE, cohort_id);
 
 return analysesLoadByQuery(conn, query);
 }
 
 struct analysisFeatures *getAnalysisFeaturesByName(struct sqlConnection *conn, 
 						   char *name)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select * from %s where feature_name = \"%s\"", 
       AF_TABLE, name);
 
 return analysisFeaturesLoadByQuery(conn, query);
 }
 
 struct analysisFeatures *getAnalysisFeaturesById(struct sqlConnection *conn, 
 						 int id)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select * from %s where id = %d", 
       AF_TABLE, id);
 
 return analysisFeaturesLoadByQuery(conn, query);
 }
 
 
 struct features *getFeaturesByName(struct sqlConnection *conn, 
 				   char *name)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select * from %s where name = \"%s\"", 
       FE_TABLE, name);
 
 return featuresLoadByQuery(conn, query);
 }
 
 struct features *getFeaturesById(struct sqlConnection *conn, 
 				 int id)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select * from %s where id = %d", 
       FE_TABLE, id);
 
 return featuresLoadByQuery(conn, query);
 }
 
 struct datasets *getDatasetsByCohortId(struct sqlConnection *conn, int cohort_id)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select %s.* from %s join %s on %s.id = %s.dataset_id "
       "where %s.cohort_id = %d",
       DA_TABLE, DA_TABLE, DC_TABLE, DA_TABLE, DC_TABLE, DC_TABLE, cohort_id);
 
 return datasetsLoadByQuery(conn, query);
 }
 
 struct cohortCorr *getCohortCorrByCohortId(struct sqlConnection *conn, int cohort_id)
 {
 char query[256];
 safef(query, sizeof(query), 
       "select * from %s where cohort_id = %d",
       CC_TABLE, cohort_id);
 
 return cohortCorrLoadByQuery(conn, query);
 }
 
+char *getFieldFromKgXref(struct sqlConnection *conn, char *geneSymbol, 
+			 char *field)
+{
+char query[256];
+safef(query, sizeof(query), 
+      "select %s from %s where geneSymbol = \"%s\" ",
+      field, KX_TABLE, geneSymbol);
+
+return sqlQuickString(conn, query);
+}
 
 /****** END HELPER FUNCTIONS *******/
 
 
 /* get a list of the current analyses */
 void getAnalyses()
 {
 char query[256];
 safef(query, sizeof(query),
       "select * from analyses;");
 
 struct sqlConnection *conn = hAllocConnProfile(localDb, db);
 struct analyses *an, *anList = analysesLoadByQuery(conn, query);
 
 struct json *js = newJson();
 struct json *analysis, *analyses = jsonAddContainerList(js, "analyses");
 analysis = analyses;
 for (an = anList; an; an = an->next)
     {
     jsonAddInt(analysis, "id", an->id);
     jsonAddInt(analysis, "cohort_id", an->cohort_id);
     jsonAddInt(analysis, "module_id", an->module_id);
     jsonAddString(analysis, "result_table", an->result_table);
     jsonAddString(analysis, "input_tables", an->input_tables);
     
     if (an->next)
 	analysis = jsonAddContainerToList(&analyses);    
     }
 
 if (js)
     hPrintf("%s\n", js->print(js));
 
 hFreeConn(&conn);
 }
 
 void getFeatureData()
 {
 int cohort_id = cartUsualInt(cart, bioIntCohortId, -1);
 if (cohort_id == -1)
     cohort_id = 1;  // hard code for first analysis during testing!
 
 int feature_id = cartUsualInt(cart, bioIntFeatureId, -1);
 char *feature_name = cartOptionalString(cart, bioIntFeatureName);
 if (!feature_name && feature_id == -1)
     errAbort("%s or %s must be set for mode=getFeatureData\n", bioIntFeature, bioIntFeatureId);
 
 struct sqlConnection *conn = hAllocConnProfile(localDb, db);
 
 struct analysisFeatures *af = NULL;
 if (feature_id == -1)
     af = getAnalysisFeaturesByName(conn, feature_name);
 else
     af = getAnalysisFeaturesById(conn, feature_id);
 
 if (!af)
     {
     hFreeConn(&conn);
     errAbort("Could not find analysisFeature in db");
     }
 
 struct analyses *an, *anList = getAnalysesByCohortId(conn, cohort_id);
 if (!anList)
     {
     hFreeConn(&conn);
     errAbort("No analyses with cohort_id = %d.\n", cohort_id);
     }
 
 char query[512];
 for (an = anList; an; an = an->next)
     {
     safef(query, sizeof(query), 
 	  "select DISTINCT %s.name, %s.val from %s join %s on %s.sample_id = %s.id "
 	  "where %s.feature_id = %d;",
 	  SA_TABLE, an->result_table, an->result_table, SA_TABLE, an->result_table, SA_TABLE,
 	  an->result_table, af->id);
     if (sqlExists(conn, query))
 	break;
     }
 
 struct json *js = newJson();
+
+char *desc = getFieldFromKgXref(conn, af->feature_name, "description"); 
+if (!desc)
+    desc = cloneString(af->feature_name);
+
+/* String 'isoform xxx' from description... almost all entries have them */
+char *ptr = rStringIn("isoform", desc);
+if (ptr)
+    *ptr = '\0';
+jsonAddString(js, "description", desc);
+
+char *kgId = getFieldFromKgXref(conn, af->feature_name, "kgId");
+if (kgId)
+    jsonAddString(js, "hgg_gene", kgId);
+
+struct json *data = jsonAddContainer(js, "data");
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = NULL;
 while ((row = sqlNextRow(sr)) != NULL)
     { 
     char *name = row[0];
     double val = atof(row[1]);
-    jsonAddDouble(js, name, val);
+    jsonAddDouble(data, name, val);
     }
+sqlFreeResult(&sr);
 
 if (js)
     hPrintf("%s\n", js->print(js));
 
 hFreeConn(&conn);
 }
 
 void getClinicalFeatures()
 {
 int cohort_id = cartUsualInt(cart, bioIntCohortId, -1);
 if (cohort_id == -1)
     cohort_id = 1;  // hard code for first analysis during testing!
 
 struct sqlConnection *conn = hAllocConnProfile(localDb, db);
 
 struct datasets *da, *daList = getDatasetsByCohortId(conn, cohort_id);
 if (!daList)
     {
     hFreeConn(&conn);
     errAbort("No datasets matching cohort_id = %d", cohort_id);
     }
 
 struct dyString *dy = dyStringNew(100);
 dyStringPrintf(dy, 
 	       "select DISTINCT %s.* from %s join %s on %s.id = %s.feature_id "
 	       "join %s on %s.sample_id = %s.id where %s.dataset_id in (", 
 	       FE_TABLE, FE_TABLE, CD_TABLE, FE_TABLE, CD_TABLE, 
 	       SA_TABLE, CD_TABLE, SA_TABLE, SA_TABLE);
 for (da = daList; da; da = da->next)
     {
     dyStringPrintf(dy, "%d", da->id);
     if (da->next)
 	dyStringPrintf(dy, ",");
     }
 dyStringPrintf(dy, ")");
 
 char *query = dyStringCannibalize(&dy);
 struct features *fe, *feList = featuresLoadByQuery(conn, query);
 
 struct json *js = newJson();
 struct json *feature, *features = jsonAddContainerList(js, "features");
 feature = features;
 for (fe = feList; fe; fe = fe->next)
     {
     jsonAddInt(feature, "id", fe->id);
     jsonAddString(feature, "name", fe->name);
     jsonAddString(feature, "shortLabel", fe->shortLabel);
     jsonAddString(feature, "longLabel", fe->longLabel);
 
     if (fe->next)
 	feature = jsonAddContainerToList(&features);
     }
 
 if (js)
     hPrintf("%s\n", js->print(js));
 
 hFreeConn(&conn);
 }
 
 void getClinicalData()
 {
 int cohort_id = cartUsualInt(cart, bioIntCohortId, -1);
 if (cohort_id == -1)
     cohort_id = 1;  // hard code for first analysis during testing!
 
 int feature_id = cartUsualInt(cart, bioIntFeatureId, -1);
 char *feature_name = cartOptionalString(cart, bioIntFeatureName);
 if (!feature_name && feature_id == -1)
     errAbort("%s or %s must be set for mode=getClinicalData\n", bioIntFeature, bioIntFeatureId);
 
 struct sqlConnection *conn = hAllocConnProfile(localDb, db);
 
 struct features *fe = NULL;
 if (feature_id == -1)
     fe = getFeaturesByName(conn, feature_name);
 else
     fe = getFeaturesById(conn, feature_id);
 
 if (!fe)
     {
     hFreeConn(&conn);
     errAbort("Could not find clinical feature in db");
     }
 
 struct datasets *da, *daList = getDatasetsByCohortId(conn, cohort_id);
 if (!daList)
     {
     hFreeConn(&conn);
     errAbort("No datasets matching cohort_id = %d", cohort_id);
     }
 
 struct dyString *dy = dyStringNew(100);
 dyStringPrintf(dy, 
 	       "select DISTINCT %s.name, %s.val from %s join %s on %s.sample_id = %s.id ", 
 	       SA_TABLE, CD_TABLE, CD_TABLE, SA_TABLE, CD_TABLE, SA_TABLE);
 dyStringPrintf(dy, 
 	       "where %s.feature_id = %d and %s.dataset_id in (", 
 	       CD_TABLE, fe->id, SA_TABLE);
 
 for (da = daList; da; da = da->next)
     {
     dyStringPrintf(dy, "%d", da->id);
     if (da->next)
 	dyStringPrintf(dy, ",");
     }
 dyStringPrintf(dy, ")");
 
 char *query = dyStringCannibalize(&dy);
 struct json *js = newJson();
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = NULL;
 while ((row = sqlNextRow(sr)) != NULL)
     { 
     char *name = row[0];
     double val = atof(row[1]);
     jsonAddDouble(js, name, val);
     }
 
 if (js)
     hPrintf("%s\n", js->print(js));
 
 hFreeConn(&conn);
 }
 
 void getMostCorrelated()
 {
 int takeTop = cartUsualInt(cart, bioIntTakeTop, 5);
 
 int cohort_id = cartUsualInt(cart, bioIntCohortId, -1);
 if (cohort_id == -1)
     cohort_id = 1;  // hard code for first analysis during testing!
 
 int feature_id = cartUsualInt(cart, bioIntFeatureId, -1);
 char *feature_name = cartOptionalString(cart, bioIntFeatureName);
 if (!feature_name && feature_id == -1)
     errAbort("%s or %s must be set for mode=getFeatureData\n", bioIntFeature, bioIntFeatureId);
 
 struct sqlConnection *conn = hAllocConnProfile(localDb, db);
 
 struct analysisFeatures *af = NULL;
 if (feature_id == -1)
     af = getAnalysisFeaturesByName(conn, feature_name);
 else
     af = getAnalysisFeaturesById(conn, feature_id);
 
 if (!af)
     {
     hFreeConn(&conn);
     errAbort("Could not find analysisFeature in db");
     }
 
 struct cohortCorr *cc = getCohortCorrByCohortId(conn, cohort_id);
 if (!cc)
     {
     hFreeConn(&conn);
     errAbort("No cohort correlation table with cohort_id = %d.\n", cohort_id);
     }
 
 struct dyString *dy = dyStringNew(100);
 dyStringPrintf(dy, "select a1.feature_name, a2.feature_name, %s.val from %s "
 	       "join %s as a1 on %s.feature_id1 = a1.id ", 
 	       cc->result_table, cc->result_table, AF_TABLE, cc->result_table);
 dyStringPrintf(dy, "join %s as a2 on %s.feature_id2 = a2.id ", 
 	       AF_TABLE, cc->result_table);
 dyStringPrintf(dy, "where feature_id1 = %d or feature_id2 = %d order by %s.val DESC", 
 	       af->id, af->id, cc->result_table);
 char *query = dyStringCannibalize(&dy);
 
 struct slPair *sp, *spList = NULL;
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = NULL;
 while ((row = sqlNextRow(sr)) != NULL)
     {
     char *name = NULL;
     char *name1 = row[0];
     char *name2 = row[1];
     double val = atof(row[2]);
 
     if (sameString(name1, af->feature_name))
 	name = name2;
     else if (sameString(name2, af->feature_name))
 	name = name1;
     else  // doesn't match either, should *never* get here
 	continue;
 
     AllocVar(sp);
     sp->name = cloneString(name);
     sp->val = slDoubleNew(val);
     slAddHead(&spList, sp);
     }
 slReverse(&spList);
 
 int count;
 struct json *js = newJson();
 struct json *corrs = jsonAddContainer(js, "Top Correlated");
 for (sp = spList, count = 0; sp && (count < takeTop); sp = sp->next, count++)
     {
     struct slDouble *sd = sp->val;
     if (sd->val < 0.0)
 	continue;
 
     jsonAddDouble(corrs, sp->name, sd->val);    
     }
 
 slReverse(&spList);
 corrs = jsonAddContainer(js, "Top Anti-Correlated");
 for (sp = spList, count = 0; sp && (count < takeTop); sp = sp->next, count++)
     {
     struct slDouble *sd = sp->val;
     if (sd->val > 0.0)
 	continue;
     jsonAddDouble(corrs, sp->name, sd->val);    
     }
 
 if (js)
     hPrintf("%s", js->print(js));
 
 hFreeConn(&conn);
 }
 
 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, bioIntMode);
 if (!mode)
     errAbort("%s is required.", bioIntMode);
 
 if (sameString(mode, "getAnalyses"))
     getAnalyses();
 else if (sameString(mode, "getFeatureData"))
     getFeatureData();
 else if (sameString(mode, "getClinicalData"))
     getClinicalData();
 else if (sameString(mode, "getClinicalFeatures"))
     getClinicalFeatures();
 else if (sameString(mode, "getMostCorrelated"))
     getMostCorrelated();
 else
     errAbort("Incorrect mode = %s", mode);
 
 cartRemovePrefix(cart, bioIntPrefix);
 
 }
 
 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;
 }