src/hg/instinct/bioInt2/bioIntUI.c 1.6
1.6 2009/03/31 04:08:23 jsanborn
added search
Index: src/hg/instinct/bioInt2/bioIntUI.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/bioInt2/bioIntUI.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -b -B -U 4 -r1.5 -r1.6
--- src/hg/instinct/bioInt2/bioIntUI.c 31 Mar 2009 01:06:15 -0000 1.5
+++ src/hg/instinct/bioInt2/bioIntUI.c 31 Mar 2009 04:08:23 -0000 1.6
@@ -139,8 +139,31 @@
return sqlQuickString(conn, query);
}
+void setAnalysisFeatureDesc(struct sqlConnection *conn, struct json *js,
+ struct analysisFeatures *af)
+{
+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);
+}
+
+void setAnalysisFeatureLink(struct sqlConnection *conn, struct json *js,
+ struct analysisFeatures *af)
+{
+char *kgId = getFieldFromKgXref(conn, af->feature_name, "kgId");
+if (kgId)
+ jsonAddString(js, "hgg_gene", kgId);
+}
+
/****** END HELPER FUNCTIONS *******/
/* get a list of the current analyses */
@@ -173,31 +196,97 @@
hFreeConn(&conn);
}
-void getFeatureData()
+struct slPair *searchForFeatures(struct sqlConnection *conn, int cohort_id,
+ struct datasets *daList, char *feature_name)
{
-int cohort_id = cartUsualInt(cart, bioIntCohortId, -1);
-if (cohort_id == -1)
- cohort_id = 1; // hard code for first analysis during testing!
+int maxResponse = 5;
+/* Check analysis features */
+char query[256];
+safef(query, sizeof(query),
+ "select feature_name from %s where feature_name like \"%%%s%%\" ",
+ AF_TABLE, feature_name);
-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);
+int count = 0;
+struct slPair *sp, *spList = NULL;
+struct sqlResult *sr = sqlGetResult(conn, query);
+char **row = NULL;
+while ((row = sqlNextRow(sr)) != NULL)
+ {
+ char *name = row[0];
+ AllocVar(sp);
+ sp->name = cloneString(name);
+ sp->val = cloneString("gene/geneset");
+ slAddHead(&spList, sp);
+ if (count > maxResponse)
+ break;
+ count++;
+ }
+sqlFreeResult(&sr);
-struct sqlConnection *conn = hAllocConnProfile(localDb, db);
+/* Check clinical features */
+struct datasets *da;
+struct dyString *dy = dyStringNew(100);
+dyStringPrintf(dy,
+ "select DISTINCT %s.name from %s join %s on %s.sample_id = %s.id ",
+ FE_TABLE, CD_TABLE, SA_TABLE, CD_TABLE, SA_TABLE);
+dyStringPrintf(dy,
+ "join %s on %s.id = %s.feature_id ",
+ FE_TABLE, FE_TABLE, CD_TABLE);
+dyStringPrintf(dy,
+ "where %s.name like \"%%%s%%\" and %s.dataset_id in (",
+ FE_TABLE, feature_name, SA_TABLE);
+for (da = daList; da; da = da->next)
+ {
+ dyStringPrintf(dy, "%d", da->id);
+ if (da->next)
+ dyStringPrintf(dy, ",");
+ }
+dyStringPrintf(dy, ")");
+char *cquery = dyStringCannibalize(&dy);
-struct analysisFeatures *af = NULL;
-if (feature_id == -1)
- af = getAnalysisFeaturesByName(conn, feature_name);
-else
- af = getAnalysisFeaturesById(conn, feature_id);
+count = 0;
+sr = sqlGetResult(conn, cquery);
+while ((row = sqlNextRow(sr)) != NULL)
+ {
+ char *name = row[0];
+ AllocVar(sp);
+ sp->name = cloneString(name);
+ sp->val = cloneString("clinical");
+ slAddHead(&spList, sp);
+ if (count < maxResponse)
+ break;
+ count++;
+ }
+sqlFreeResult(&sr);
+return spList;
+}
+
+void sendNoMatch(struct json *js)
+{
+return;
+}
+
+void sendAmbiguities(struct json *js, struct slPair *spList)
+{
+struct slPair *sp;
+for (sp = spList; sp; sp = sp->next)
+ {
+ char *source = sp->val;
+ jsonAddString(js, sp->name, source);
+ }
+}
+
+void sendAnalysisFeatureData(struct sqlConnection *conn, struct json *js,
+ int cohort_id, char *feature_name)
+{
+struct analysisFeatures *af = getAnalysisFeaturesByName(conn, feature_name);
if (!af)
{
hFreeConn(&conn);
- errAbort("Could not find analysisFeature in db");
+ errAbort("Could not find analysisFeature named in %s in db", feature_name);
}
struct analyses *an, *anList = getAnalysesByCohortId(conn, cohort_id);
if (!anList)
@@ -217,23 +306,10 @@
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);
+setAnalysisFeatureDesc(conn, js, af);
+setAnalysisFeatureLink(conn, js, af); // e.g. 'hgg_gene' = kgId
struct json *data = jsonAddContainer(js, "data");
struct sqlResult *sr = sqlGetResult(conn, query);
char **row = NULL;
@@ -243,8 +319,96 @@
double val = atof(row[1]);
jsonAddDouble(data, name, val);
}
sqlFreeResult(&sr);
+}
+
+void sendClinicalData(struct sqlConnection *conn, struct json *js,
+ int cohort_id, char *feature_name, struct datasets *daList)
+{
+struct features *fe = getFeaturesByName(conn, feature_name);
+
+if (!fe)
+ {
+ hFreeConn(&conn);
+ errAbort("Could not find clinical feature in db");
+ }
+
+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);
+
+struct datasets *da;
+for (da = daList; da; da = da->next)
+ {
+ dyStringPrintf(dy, "%d", da->id);
+ if (da->next)
+ dyStringPrintf(dy, ",");
+ }
+dyStringPrintf(dy, ")");
+
+char *query = dyStringCannibalize(&dy);
+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);
+ }
+}
+
+void sendUniqueMatch(struct sqlConnection *conn, struct json *js,
+ int cohort_id, char *feature_name, char *source,
+ struct datasets *daList)
+{
+if (sameString(source, "gene/geneset"))
+ sendAnalysisFeatureData(conn, js, cohort_id, feature_name);
+else if (sameString(source, "clinical"))
+ sendClinicalData(conn, js, cohort_id, feature_name, daList);
+}
+
+void getFeatureData()
+{
+int cohort_id = cartUsualInt(cart, bioIntCohortId, -1);
+if (cohort_id == -1)
+ cohort_id = 1; // hard code for first analysis during testing!
+
+/* feature source = gene,geneset,clinical... */
+char *source = cartOptionalString(cart, bioIntSourceName);
+
+char *feature_name = cartOptionalString(cart, bioIntFeatureName);
+if (!feature_name)
+ errAbort("%s or %s must be set for mode=getFeatureData\n", bioIntFeature, bioIntFeatureId);
+
+struct sqlConnection *conn = hAllocConnProfile(localDb, db);
+
+struct datasets *daList = getDatasetsByCohortId(conn, cohort_id);
+if (!daList)
+ errAbort("No datasets matching cohort_id = %d", cohort_id);
+
+struct json *js = newJson();
+if (source)
+ sendUniqueMatch(conn, js, cohort_id, feature_name, source, daList);
+else
+ {
+ struct slPair *spList = searchForFeatures(conn, cohort_id, daList, feature_name);
+
+ int numMatched = slCount(spList);
+ if (numMatched == 0)
+ sendNoMatch(js);
+ else if (numMatched == 1)
+ {
+ source = spList->val;
+ sendUniqueMatch(conn, js, cohort_id, spList->name, source, daList);
+ }
+ else
+ sendAmbiguities(js, spList);
+ }
if (js)
hPrintf("%s\n", js->print(js));
@@ -378,9 +542,9 @@
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);
+ errAbort("%s or %s must be set for mode=getMostCorrelated\n", bioIntFeature, bioIntFeatureId);
struct sqlConnection *conn = hAllocConnProfile(localDb, db);
struct analysisFeatures *af = NULL;