8935bd46a374201b88bc38ed35994f2a306827d7 braney Thu Apr 24 17:38:41 2014 -0700 make stacked wiggles grok the smoothing parameter, Fix autoscale to usethe windowingFunction to drive the autoScale. diff --git src/hg/hgTracks/wigTrack.c src/hg/hgTracks/wigTrack.c index 05afa3c..8eb5eb6 100644 --- src/hg/hgTracks/wigTrack.c +++ src/hg/hgTracks/wigTrack.c @@ -645,109 +645,93 @@ } } if (preDraw[winBegin].count) { points += preDraw[winBegin].count; sum += preDraw[winBegin].plotValue * preDraw[winBegin].count; } if ((winMiddle >= 0) && points && preDraw[winMiddle].count) preDraw[winMiddle].smooth = sum / points; ++winEnd; ++winMiddle; } } } -double preDrawLimits(struct preDrawElement *preDraw, int preDrawZero, - int width, double *overallUpperLimit, double *overallLowerLimit) -/* scan preDraw array and determine graph limits */ -{ -int i; - -/* Just in case they haven't been initialized before */ -*overallUpperLimit = wigEncodeStartingUpperLimit; -*overallLowerLimit = wigEncodeStartingLowerLimit; -for (i = preDrawZero; i < preDrawZero+width; ++i) - { - /* count is non-zero meaning valid data exists here */ - if (preDraw[i].count) - { - if (preDraw[i].max > *overallUpperLimit) - *overallUpperLimit = preDraw[i].max; - if (preDraw[i].min < *overallLowerLimit) - *overallLowerLimit = preDraw[i].min; - } - } -return (overallUpperLimit - overallLowerLimit); -} - double preDrawAutoScale(struct preDrawElement *preDraw, int preDrawZero, int width, enum wiggleScaleOptEnum autoScale, - double *overallUpperLimit, double *overallLowerLimit, + enum wiggleWindowingEnum windowingFunction, double *graphUpperLimit, double *graphLowerLimit, - double *overallRange, double *epsilon, int lineHeight, + double *epsilon, int lineHeight, double maxY, double minY, enum wiggleAlwaysZeroEnum alwaysZero) /* if autoScaling, scan preDraw array and determine limits */ { double graphRange; +double overallUpperLimit, overallLowerLimit, overallRange; if (autoScale == wiggleScaleAuto) { int i, lastI = preDrawZero+width; /* reset limits for auto scale */ for (i = preDrawZero; i < lastI; ++i) { /* count is non-zero meaning valid data exists here */ if (preDraw[i].count) { - if (preDraw[i].smooth > *overallUpperLimit) - *overallUpperLimit = preDraw[i].smooth; - if (preDraw[i].smooth < *overallLowerLimit) - *overallLowerLimit = preDraw[i].smooth; + double val = preDraw[i].smooth; + if (windowingFunction == wiggleWindowingWhiskers) + val = preDraw[i].max; + if (val > overallUpperLimit) + overallUpperLimit = val; + val = preDraw[i].smooth; + if (windowingFunction == wiggleWindowingWhiskers) + val = preDraw[i].min; + if (val < overallLowerLimit) + overallLowerLimit = val; } } if (alwaysZero == wiggleAlwaysZeroOn) { - if ( *overallUpperLimit < 0) - *overallUpperLimit = 0.0; - else if ( *overallLowerLimit > 0) - *overallLowerLimit = 0.0; + if ( overallUpperLimit < 0) + overallUpperLimit = 0.0; + else if ( overallLowerLimit > 0) + overallLowerLimit = 0.0; } - *overallRange = *overallUpperLimit - *overallLowerLimit; - if (*overallRange == 0.0) + overallRange = overallUpperLimit - overallLowerLimit; + if (overallRange == 0.0) { - if (*overallUpperLimit > 0.0) + if (overallUpperLimit > 0.0) { - *graphUpperLimit = *overallUpperLimit; + *graphUpperLimit = overallUpperLimit; *graphLowerLimit = 0.0; } - else if (*overallUpperLimit < 0.0) + else if (overallUpperLimit < 0.0) { *graphUpperLimit = 0.0; - *graphLowerLimit = *overallUpperLimit; + *graphLowerLimit = overallUpperLimit; } else { *graphUpperLimit = 1.0; *graphLowerLimit = -1.0; } } else { - *graphUpperLimit = *overallUpperLimit; - *graphLowerLimit = *overallLowerLimit; + *graphUpperLimit = overallUpperLimit; + *graphLowerLimit = overallLowerLimit; } } else { *graphUpperLimit = maxY; *graphLowerLimit = minY; } graphRange = *graphUpperLimit - *graphLowerLimit; *epsilon = graphRange / lineHeight; return(graphRange); } static Color * makeColorArray(struct preDrawElement *preDraw, int width, int preDrawZero, struct wigCartOptions *wigCart, struct track *tg, struct hvGfx *hvg) /* allocate and fill in a coloring array based on another track */ @@ -1207,71 +1191,60 @@ } void wigDrawPredraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis, struct preDrawContainer *preContainer, int preDrawZero, int preDrawSize, double *retGraphUpperLimit, double *retGraphLowerLimit) /* Draw once we've figured out predraw (numerical values to graph) we draw it here. * This code is shared by wig, bigWig, and bedGraph drawers. */ { wigTrackSetGraphOutputDefault(tg, xOff, yOff, hvg); enum wiggleYLineMarkEnum yLineOnOff; double yLineMark; /* determined from data */ -double overallUpperLimit = wigEncodeStartingUpperLimit; -double overallLowerLimit = wigEncodeStartingLowerLimit; -double overallRange=0; /* determined from data */ double graphUpperLimit=0; /* scaling choice will set these */ double graphLowerLimit=0; /* scaling choice will set these */ double graphRange=0; /* scaling choice will set these */ double epsilon; /* range of data in one pixel */ struct wigCartOptions *wigCart = (struct wigCartOptions *) tg->extraUiData; yLineOnOff = wigCart->yLineOnOff; yLineMark = wigCart->yLineMark; /* width - width of drawing window in pixels * pixelsPerBase - pixels per base * basesPerPixel - calculated as 1.0/pixelsPerBase */ struct preDrawElement *preDraw = preContainer->preDraw; -double thisOverallUpperLimit; -double thisOverallLowerLimit; -double thisGraphUpperLimit; -double thisGraphLowerLimit; +if (preContainer->smoothingDone == FALSE) + { preDrawWindowFunction(preDraw, preDrawSize, wigCart->windowingFunction, wigCart->transformFunc); preDrawSmoothing(preDraw, preDrawSize, wigCart->smoothingWindow); -overallRange = preDrawLimits(preDraw, preDrawZero, width, - &thisOverallUpperLimit, &thisOverallLowerLimit); graphRange = preDrawAutoScale(preDraw, preDrawZero, width, - wigCart->autoScale, - &thisOverallUpperLimit, &thisOverallLowerLimit, - &thisGraphUpperLimit, &thisGraphLowerLimit, - &overallRange, &epsilon, tg->lineHeight, + wigCart->autoScale, wigCart->windowingFunction, + &preContainer->graphUpperLimit, &preContainer->graphLowerLimit, + &epsilon, tg->lineHeight, wigCart->maxY, wigCart->minY, wigCart->alwaysZero); + } -overallUpperLimit = thisOverallUpperLimit; -overallLowerLimit = thisOverallLowerLimit; -graphUpperLimit = thisGraphUpperLimit; -graphLowerLimit = thisGraphLowerLimit; - -overallRange = overallUpperLimit - overallLowerLimit; +graphUpperLimit = preContainer->graphUpperLimit; +graphLowerLimit = preContainer->graphLowerLimit; /* if we're autoscaling and the range is 0 this implies that all values * in the given range are the same. We create a bottom of the scale * by subtracting one from the only value. * This results in drawing a box that fills the range. */ if (graphUpperLimit == graphLowerLimit) { graphRange = 1.0; graphLowerLimit = graphUpperLimit - 1; } else { graphRange = graphUpperLimit - graphLowerLimit; }