3904cbc6353d7d6d09d7615bfddf7449456588f5
kent
  Tue Apr 19 16:54:41 2011 -0700
Making autoscale work as you'd hope for multiWigs - where all the wigs have a common scale.
diff --git src/hg/hgTracks/multiWig.c src/hg/hgTracks/multiWig.c
index ed979f3..022c51a 100644
--- src/hg/hgTracks/multiWig.c
+++ src/hg/hgTracks/multiWig.c
@@ -1,53 +1,118 @@
 /* A container for multiple wiggles with a couple of options for combining them. */
 
 #include "common.h"
 #include "hash.h"
 #include "linefile.h"
 #include "jksql.h"
 #include "dystring.h"
 #include "hdb.h"
 #include "hgTracks.h"
 #include "container.h"
 #include "wiggle.h"
 #include "wigCommon.h"
 #include "hui.h"
 
+static void minMaxVals(struct slRef *refList, double *retMin, double *retMax)
+/* 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;
+for (ref = refList; ref != NULL; ref = ref->next)
+    {
+    struct preDrawContainer *pre;
+    for (pre = ref->val; pre != NULL; pre = pre->next)
+	{
+	struct preDrawElement *p = pre->preDraw + pre->preDrawZero;
+	int width = pre->width;
+	int i;
+	for (i=0; i<width; ++i)
+	    {
+	    if (p->count)
+		{
+		if (min > p->min) min = p->min;
+		if (max < p->max) max = p->max;
+		}
+	    ++p;
+	    }
+	}
+    }
+*retMax = max;
+*retMin = min;
+}
 
 static void multiWigDraw(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width, 
         MgFont *font, Color color, enum trackVisibility vis)
 /* Draw items in multiWig container. */
 {
 struct track *subtrack;
 char *aggregate = wigFetchAggregateValWithCart(cart, tg->tdb);
 boolean overlay = wigIsOverlayTypeAggregate(aggregate);
 boolean errMsgShown = FALSE;
 int y = yOff;
 boolean errMsgFound = FALSE;
 // determine if any subtracks had errors
 for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next)
     {
     if (isSubtrackVisible(subtrack) && subtrack->networkErrMsg)
 	errMsgFound = TRUE;
     }
 if (errMsgFound)
     {
     Color yellow = hvGfxFindRgb(hvg, &undefinedYellowColor);
     hvGfxBox(hvg, xOff, yOff, width, tg->height, yellow);
     }
 
+/* Cope with autoScale - we do it here rather than in the child tracks, so that
+ * all children can be on same scale. */
+struct wigCartOptions *wigCart = tg->extraUiData;
+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)
+        {
+	struct preDrawContainer *pre = subtrack->loadPreDraw(subtrack, seqStart, seqEnd, width);
+	refAdd(&refList, pre);
+	}
+    double minVal, maxVal;
+    minMaxVals(refList, &minVal, &maxVal);
+    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;
+	wigCart->maxY = maxVal;
+	wigCart->autoScale = wiggleScaleManual;
+	}
+    }
+
 for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next)
     {
     if (isSubtrackVisible(subtrack))
 	{
         if (!subtrack->networkErrMsg || !errMsgShown)
 	    {
 	    if (subtrack->networkErrMsg)
 	       errMsgShown = TRUE;
 	    int height = subtrack->totalHeight(subtrack, vis);
 	    hvGfxSetClip(hvg, xOff, y, width, height);
 	    if (sameString(WIG_AGGREGATE_TRANSPARENT, aggregate))
 		hvGfxSetWriteMode(hvg, MG_WRITE_MODE_MULTIPLY);
 	    if (overlay)
 		subtrack->lineHeight = tg->lineHeight;
 	    subtrack->drawItems(subtrack, seqStart, seqEnd, hvg, xOff, y, width, font, color, vis);