d1629e0cc961a0c80c1cce24ff652b5ee3906b1f
braney
  Thu Apr 17 15:54:59 2014 -0700
tweak autoscale on multiwigs to use the windowingFunction (min/max/mean)
diff --git src/hg/hgTracks/multiWig.c src/hg/hgTracks/multiWig.c
index b667c56..6339e1f 100644
--- src/hg/hgTracks/multiWig.c
+++ src/hg/hgTracks/multiWig.c
@@ -153,63 +153,79 @@
 	int red = fp[0]*FLOAT_FOR_BIGGEST_BYTE;
 	int green = fp[1]*FLOAT_FOR_BIGGEST_BYTE;
 	int blue = fp[2]*FLOAT_FOR_BIGGEST_BYTE;
 	*cp++ = MAKECOLOR_32(red, green, blue);
 	fp += 3;
 	}
     if (hvg->rc)
         reverseLineOfColors(lineBuf, width);
     hvGfxVerticalSmear(hvg, xOff, y + yOff, width, 1, lineBuf, TRUE);
     }
 freez(&lineBuf);
 }
 
 
 static void minMaxVals(struct slRef *refList, double *retMin, double *retMax,
-     enum wiggleAlwaysZeroEnum alwaysZero, double *yOffsets)
+     enum wiggleWindowingEnum windowingFunction,enum wiggleAlwaysZeroEnum alwaysZero, double *yOffsets)
 /* Figure out min/max of everything in list.  The refList contains pointers to
  * preDrawContainers */
 {
 /* Turns out to be *much* shorter to rewrite than to reuse preDrawAutoScale */
 double max = -BIGDOUBLE, min = BIGDOUBLE;
 struct slRef *ref;
 int numTrack = 0;
 for (ref = refList; ref != NULL; numTrack++,ref = ref->next)
     {
     struct preDrawContainer *pre = ref->val;
     if (pre == NULL)  // pre may be null if the bigWig file didn't load
 	continue;
 
     struct preDrawElement *p = pre->preDraw + pre->preDrawZero;
     int width = pre->width;
     int i;
     int offset = numTrack * pre->width;
     int prevOffset = (numTrack - 1) * pre->width;
     for (i=0; i<width; ++i, offset++)
 	{
+	double val;
+
+	switch(windowingFunction)
+	{
+	    case wiggleWindowingMean:
+		val = p->sumData / p->count;
+		break;
+
+	    case wiggleWindowingWhiskers:
+	    case wiggleWindowingMax:
+		val = p->max;
+		break;
+	    case wiggleWindowingMin:
+		val = p->min;
+		break;
+	}
 	if (p->count)
 	    {
-	    if (min > p->min) min = p->min;
-	    if (max < p->max) max = p->max;
+	    if (min > val) min = val;
+	    if (max < val) max = val;
 	    if (yOffsets)
-		yOffsets[offset] = p->max;
+		yOffsets[offset] = val;
 	    }
 	else if (yOffsets)
 	    {
 	    yOffsets[offset] = 0;
 	    }
-	if (prevOffset > 0)
+	if (yOffsets && (prevOffset > 0))
 	    yOffsets[offset] += yOffsets[prevOffset];
 	++p;
 	}
     }
 if (alwaysZero == wiggleAlwaysZeroOn)
     {
     if ( max < 0)
 	max = 0.0;
     else if ( min > 0)
 	min = 0.0;
     }
 *retMax = max;
 *retMin = min;
 }
 
@@ -280,31 +296,31 @@
 if (wigCart->autoScale)
     {
     /* Force load of all predraw arrays so can do calcs. Build up list, and then
      * figure out max/min.  No worries about multiple loading, the loaders protect
      * themselves. */
     struct slRef *refList = NULL;
     for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next)
         {
 	if (isSubtrackVisible(subtrack))
 	    {
 	    struct preDrawContainer *pre = subtrack->loadPreDraw(subtrack, seqStart, seqEnd, width);
 	    refAdd(&refList, pre);
 	    }
 	}
     double minVal, maxVal;
-    minMaxVals(refList, &minVal, &maxVal, wigCart->alwaysZero, wgo->yOffsets);
+    minMaxVals(refList, &minVal, &maxVal, wigCart->windowingFunction,  wigCart->alwaysZero, wgo->yOffsets);
     slFreeList(&refList);
 
     /* Cope with log transform if need be */
     if (wigCart->transformFunc == wiggleTransformFuncLog)
          {
 	 minVal = wiggleLogish(minVal);
 	 maxVal = wiggleLogish(maxVal);
 	 }
 
     /* Loop through again setting up the wigCarts of the children to have minY/maxY for
      * our limits and autoScale off. */
     for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next)
         {
 	struct wigCartOptions *wigCart = subtrack->extraUiData;
 	wigCart->minY = minVal;