src/hg/instinct/hgGeneset/hgGenesets.c 1.13
1.13 2010/01/31 02:45:46 jsanborn
added sorting
Index: src/hg/instinct/hgGeneset/hgGenesets.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/hgGeneset/hgGenesets.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -b -B -U 4 -r1.12 -r1.13
--- src/hg/instinct/hgGeneset/hgGenesets.c 31 Jan 2010 01:17:07 -0000 1.12
+++ src/hg/instinct/hgGeneset/hgGenesets.c 31 Jan 2010 02:45:46 -0000 1.13
@@ -18,8 +18,9 @@
#include "hgStatsLib.h"
#include "featuresLib.h"
#include "json.h"
#include "hgStats.h"
+#include "heatmapUtility.h"
#include "hgGenesets.h"
static char const rcsid[] = "$Id$";
/* ---- Global variables. ---- */
@@ -864,51 +865,67 @@
return rdList;
}
-void clusterRawData(struct rawData *rdList, struct mapSettings *settings,
- char *metricStr, char *methodStr)
+void updateSampleOrder(struct mapSettings *settings, struct slName *slList)
{
-char metric = getClusterMetric(metricStr);
-char method = getClusterMethod(methodStr);
-
-if (method == '-' || metric == '-')
- errAbort("Invalid clustering method or metric string.\n");
-
-struct slName *sl, *geneOrder = NULL, *sampleOrder = NULL;
-clusterData(rdList, settings, method, metric, &geneOrder, &sampleOrder);
+if (!slList)
+ return;
-if (sampleOrder)
- {
- hashFree(&settings->x_index);
- settings->x_index = hashNew(0);
+struct slName *sl;
+hashFree(&settings->x_index);
+settings->x_index = hashNew(0);
- struct hashEl *el;
- int numSamples = 0;
- for (sl = sampleOrder; sl; sl = sl->next)
+struct hashEl *el;
+int numSamples = 0;
+for (sl = slList; sl; sl = sl->next)
{
if ((el = hashLookup(settings->x_index, sl->name)) != NULL)
continue;
hashAddInt(settings->x_index, sl->name, numSamples);
numSamples += 1;
}
- }
-if (geneOrder)
- {
- hashFree(&settings->y_index);
- settings->y_index = hashNew(0);
+char *list = strFromSlNameList(slList);
+cartSetString(cart, hghSampleIds, list);
+}
- struct hashEl *el;
- int numFeatures = 0;
- for (sl = geneOrder; sl; sl = sl->next)
+void updateFeatureOrder(struct mapSettings *settings, struct slName *slList)
+{
+if (!slList)
+ return;
+
+struct slName *sl;
+hashFree(&settings->y_index);
+settings->y_index = hashNew(0);
+
+struct hashEl *el;
+int numFeatures = 0;
+for (sl = slList; sl; sl = sl->next)
{
if ((el = hashLookup(settings->y_index, sl->name)) != NULL)
continue;
hashAddInt(settings->y_index, sl->name, numFeatures);
numFeatures += 1;
}
- }
+char *list = strFromSlNameList(slList);
+cartSetString(cart, hghFeatureIds, list);
+}
+
+void clusterRawData(struct rawData *rdList, struct mapSettings *settings,
+ char *metricStr, char *methodStr)
+{
+char metric = getClusterMetric(metricStr);
+char method = getClusterMethod(methodStr);
+
+if (method == '-' || metric == '-')
+ errAbort("Invalid clustering method or metric string.\n");
+
+struct slName *geneOrder = NULL, *sampleOrder = NULL;
+clusterData(rdList, settings, method, metric, &geneOrder, &sampleOrder);
+
+updateSampleOrder(settings, sampleOrder);
+updateFeatureOrder(settings, geneOrder);
}
void jsonSettings(struct json *js, struct mapSettings *settings)
@@ -962,8 +977,9 @@
continue;
int start = ceil(((double) i) * settings->hm_x_scale) + settings->hm_x;
int stop = ceil(((double) i + 1) * settings->hm_x_scale) + settings->hm_x;
+ jsonAddInt(new, "id", atoi(el->name));
jsonAddString(new, "name", name);
jsonAddInt(new, "start", start);
jsonAddInt(new, "stop", stop);
@@ -985,16 +1001,92 @@
continue;
int start = round(((double) i) * settings->hm_y_scale) + settings->hm_y;
int stop = round(((double) i + 1) * settings->hm_y_scale) + settings->hm_y;
+ jsonAddInt(new, "id", atoi(el->name));
jsonAddString(new, "name", name);
jsonAddInt(new, "start", start);
jsonAddInt(new, "stop", stop);
new = NULL;
}
}
+struct slData {
+ struct slData *next;
+ char *name;
+ double val;
+};
+
+int slDataCmp(const void *va, const void *vb)
+/* Compare function to sort array of ints. */
+{
+const struct slData *a = *((struct slData **)va);
+const struct slData *b = *((struct slData **)vb);
+double diff = a->val - b->val;
+if (diff < 0)
+ return -1;
+else if (diff > 0)
+ return 1;
+else
+ return 0;
+}
+
+
+void sortByFeature(struct sqlConnection *conn, struct datasets *da,
+ int feature_id, char *direction, struct samples *samples,
+ struct mapSettings *settings)
+{
+struct samples *sa;
+struct dyString *dy = dyStringNew(100);
+dyStringPrintf(dy, "select sample_id from %s where sample_id in (",
+ da->data_table);
+for (sa = samples; sa; sa = sa->next)
+ {
+ dyStringPrintf(dy, "%d", sa->sample_id);
+ if (sa->next)
+ dyStringPrintf(dy, ",");
+ }
+dyStringPrintf(dy, ") and feature_id = %d order by val", feature_id);
+char *query = dyStringCannibalize(&dy);
+
+struct slName *slList = sqlQuickList(conn, query);
+if (!direction || sameString(direction, "DESC"))
+ slReverse(&slList);
+
+updateSampleOrder(settings, slList);
+}
+
+void sortBySample(struct sqlConnection *conn, struct datasets *da,
+ int sample_id, char *direction, struct analysisFeatures *afList,
+ struct mapSettings *settings)
+{
+struct analysisFeatures *af;
+struct dyString *dy = dyStringNew(100);
+dyStringPrintf(dy, "select feature_id from %s where feature_id in (",
+ da->data_table);
+for (af = afList; af; af = af->next)
+ {
+ dyStringPrintf(dy, "%d", af->id);
+ if (af->next)
+ dyStringPrintf(dy, ",");
+ }
+dyStringPrintf(dy, ") and sample_id = %d order by val", sample_id);
+char *query = dyStringCannibalize(&dy);
+
+struct slName *slList = sqlQuickList(conn, query);
+if (!direction || sameString(direction, "DESC"))
+ slReverse(&slList);
+
+updateFeatureOrder(settings, slList);
+}
+
+void cartUpdateSettings(struct mapSettings *settings)
+{
+cartSetInt(cart, hghWidth, settings->width);
+cartSetInt(cart, hghHeight, settings->height);
+}
+
void drawHeatmap()
{
struct sqlConnection *conn = hAllocConnProfile(localDb, db);
@@ -1005,11 +1097,17 @@
int dataset_id = cartUsualInt(cart, hghDatasetId, -1);
int getFirst = cartUsualInt(cart, hghGetFirst, -1);
+/* Clustering */
char *metric = cartOptionalString(cart, hghClusterMetric);
char *method = cartOptionalString(cart, hghClusterMethod);
+/* Sorting by sample/gene */
+int sortFeatureId = cartUsualInt(cart, hghSortFeatureId, -1);
+int sortSampleId = cartUsualInt(cart, hghSortSampleId, -1);
+char *sortDir = cartOptionalString(cart, hghSortDir);
+
struct datasets *da = getDatasetById(conn, dataset_id);
if (!da)
errAbort("No dataset matching id = %d\n", dataset_id);
@@ -1019,9 +1117,12 @@
//errAbort("%s is required\n", hghSampleIds);
}
if (!featureIds && getFirst > 0)
+ {
featureIds = getNumAnalysisFeatureIdsInDataset(conn, da, getFirst);
+ cartSetString(cart, hghFeatureIds, featureIds);
+ }
if (!featureIds)
errAbort("%s is required\n", hghFeatureIds);
@@ -1046,8 +1146,14 @@
errAbort("No data matching input parameters.");
if (metric && method)
clusterRawData(rdList, settings, metric, method);
+else if (sortFeatureId > 0)
+ sortByFeature(conn, da, sortFeatureId, sortDir, samples, settings);
+else if (sortSampleId > 0)
+ sortBySample(conn, da, sortSampleId, sortDir, afList, settings);
+
+cartUpdateSettings(settings);
char *filename = heatmapGif(conn, rdList, settings);
struct json *js = newJson();
@@ -1051,14 +1157,15 @@
char *filename = heatmapGif(conn, rdList, settings);
struct json *js = newJson();
jsonAddString(js, "image", filename);
-
jsonSettings(js, settings);
if (js)
hPrintf("%s\n", js->print(js));
-}
+cartRemovePrefix(cart, hghSortPrefix);
+cartRemovePrefix(cart, hghClusterPrefix);
+}
struct searchResults {
struct searchResults *next;
int id;
@@ -1190,8 +1296,66 @@
cartRemovePrefix(cart, hghInfoPrefix);
}
+struct slInt *slIntListFromComma(char *list)
+{ /* very dumb/lazy way of doing this */
+
+struct slName *sl, *slList = slNameListFromComma(list);
+struct slInt *si, *siList = NULL;
+
+for (sl = slList; sl; sl = sl->next)
+ {
+ si = slIntNew(atoi(sl->name));
+ slAddHead(&siList, si);
+ }
+slReverse(&siList);
+
+return siList;
+}
+
+void requestState()
+{
+int datasetId = cartUsualInt(cart, hghDatasetId, -1);
+int width = cartUsualInt(cart, hghWidth, -1);
+int height = cartUsualInt(cart, hghHeight, -1);
+
+char *samples = cartOptionalString(cart, hghSampleIds);
+char *features = cartOptionalString(cart, hghFeatureIds);
+
+struct json *js = newJson();
+
+if (datasetId >= 0)
+ jsonAddInt(js, hghDatasetId, datasetId);
+if (width >= 0)
+ jsonAddInt(js, hghWidth, width);
+if (height >= 0)
+ jsonAddInt(js, hghHeight, height);
+
+if (samples)
+ {
+ struct slInt *siList = slIntListFromComma(samples);
+ jsonAddSlInt(js, hghSampleIds, siList);
+ }
+
+if (features)
+ {
+ struct slInt *siList = slIntListFromComma(features);
+ jsonAddSlInt(js, hghFeatureIds, siList);
+ }
+
+if (js)
+ hPrintf("%s\n", js->print(js));
+}
+
+void resetState()
+{
+cartRemovePrefix(cart, hghPrefix);
+struct json *js = newJson();
+if (js)
+ hPrintf("%s\n", js->print(js));
+}
+
void dispatchRoutines()
/* Look at command variables in cart and figure out which
* page to draw. */
{
@@ -1209,10 +1373,12 @@
else if (sameString(mode, "getCohorts"))
getCohorts();
else if (sameString(mode, "getSamples"))
getSamples();
+else if (sameString(mode, "requestState"))
+ requestState();
else if (sameString(mode, "resetState"))
- cartRemovePrefix(cart, hghPrefix);
+ resetState();
else
errAbort("Incorrect mode = %s", mode);
//cartRemovePrefix(cart, hghPrefix);