677b513b231891e30d32024de7ded7766ef72058
braney
  Wed May 24 14:09:42 2017 -0700
add mathWig track type which is an arithmetic combination of bigWi.

diff --git src/hg/hgTables/bigWig.c src/hg/hgTables/bigWig.c
index 69281631..baa455c 100644
--- src/hg/hgTables/bigWig.c
+++ src/hg/hgTables/bigWig.c
@@ -11,39 +11,40 @@
 #include "jksql.h"
 #include "cheapcgi.h"
 #include "cart.h"
 #include "web.h"
 #include "bed.h"
 #include "hdb.h"
 #include "trackDb.h"
 #include "customTrack.h"
 #include "wiggle.h"
 #include "hmmstats.h"
 #include "correlate.h"
 #include "bbiFile.h"
 #include "bigWig.h"
 #include "hubConnect.h"
 #include "hgTables.h"
+#include "mathWig.h"
 
 boolean isBigWigTable(char *table)
 /* Return TRUE if table corresponds to a bigWig file. */
 {
 struct trackDb *tdb = hashFindVal(fullTableToTdbHash, table);
 if (tdb)
     return tdbIsBigWig(tdb);
 else
-    return trackIsType(database, table, curTrack, "bigWig", ctLookupName);
+    return trackIsType(database, table, curTrack, "bigWig", ctLookupName) || trackIsType(database, table, curTrack, "mathWig", ctLookupName);
 }
 
 static char *settingFromCtOrHub(char *table, struct sqlConnection *conn, char *settingName, boolean mustBeInHub)
 /* If table is a custom track or hub track, return a setting;
  * otherwise return NULL.  Do a freeMem on returned string when done. */
 {
 char *settingVal = NULL;
 if (isCustomTrack(table))
     {
     struct customTrack *ct = ctLookupName(table);
     if (ct != NULL)
         settingVal = cloneString(trackDbSetting(ct->tdb, settingName));
     }
 else
     {
@@ -168,30 +169,58 @@
 
 return ivList;
 }
 
 void getWigFilter(char *database, char *table, enum wigCompare *retCmp, double *retLl, double *retUl)
 /* Get wiggle filter variables from cart and convert them into numbers. */
 {
 char *dataConstraint;
 enum wigCompare cmp = wigNoOp_e;
 checkWigDataFilter(database, curTable, &dataConstraint, retLl, retUl);
 if (dataConstraint != NULL)
     cmp = wigCompareFromString(dataConstraint);
 *retCmp = cmp;
 }
 
+static void valuesToVector(double *values, struct dataVector *dv, int start)
+/* Move an array of doubles into a dataVector. */
+{
+int ii;
+
+for(ii=0; ii < dv->maxCount; ii++)
+    {
+    dv->value[ii] = values[ii];
+    dv->position[ii] = start + ii;
+    }
+dv->count = dv->maxCount;
+}
+
+int mathWigOutRegion(struct trackDb *track, char *table, struct sqlConnection *conn,
+			     struct region *region, int maxOut,
+			     enum wigOutputType wigOutType)
+/* Write out mathWig for region, doing intersecting and filtering as need be. */
+{
+int resultCount = 0;
+struct dataVector *dv = dataVectorNew(region->chrom, region->end - region->start);
+char *equation = cloneString(trackDbSetting(track, "mathDataUrl"));
+double *values = mathWigGetValues(equation, region->chrom, region->start, region->end);
+valuesToVector(values, dv, region->start);
+resultCount = wigPrintDataVectorOut(dv, wigOutType, maxOut, NULL);
+dataVectorFree(&dv);
+return resultCount;
+}
+
 int bigWigOutRegion(char *table, struct sqlConnection *conn,
 			     struct region *region, int maxOut,
 			     enum wigOutputType wigOutType)
 /* Write out bigWig for region, doing intersecting and filtering as need be. */
 {
 boolean isMerged = anySubtrackMerge(table, database);
 int resultCount = 0;
 char *wigFileName = bigWigFileName(table, conn);
 if (wigFileName)
     {
     struct bbiFile *bwf = bigWigFileOpen(wigFileName);
     if (bwf)
 	{
 	/* Easy case, just dump out data. */
 	if (!anyFilter() && !anyIntersection() && !isMerged && wigOutType == wigOutData)