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/wigTrack.c src/hg/hgTracks/wigTrack.c index 2f1a6b7..10144ee 100644 --- src/hg/hgTracks/wigTrack.c +++ src/hg/hgTracks/wigTrack.c @@ -538,50 +538,57 @@ static void wigFreeItems(struct track *tg) { #if defined(DEBUG) safef(dbgMsg, DBGMSGSZ, "I haven't seen wigFreeItems ever called ?"); wigDebugPrint("wigFreeItems"); #endif } struct preDrawContainer *initPreDrawContainer(int width) /* Initialize preDraw of given size */ { struct preDrawContainer *pre; AllocVar(pre); int size = pre->preDrawSize = width + 2*wiggleSmoothingMax; pre->preDrawZero = wiggleSmoothingMax; +pre->width = width; struct preDrawElement *preDraw = AllocArray(pre->preDraw, pre->preDrawSize); int i; for (i = 0; i < size; ++i) { preDraw[i].count = 0; preDraw[i].max = wigEncodeStartingUpperLimit; preDraw[i].min = wigEncodeStartingLowerLimit; } return pre; } +double wiggleLogish(double x) +/* Return log-like transform without singularity at 0. */ +{ +if (x >= 0) + return log(1+x); +else + return -log(1-x); +} + static double doTransform(double x, enum wiggleTransformFuncEnum transformFunc) /* Do log-type transformation if asked. */ { if (transformFunc == wiggleTransformFuncLog) { - if (x >= 0) - x = log(1+x); - else - x = -log(1-x); + x = wiggleLogish(x); } return x; } void preDrawWindowFunction(struct preDrawElement *preDraw, int preDrawSize, enum wiggleWindowingEnum windowingFunction, enum wiggleTransformFuncEnum transformFunc) /* apply windowing function to the values in preDraw array */ { int i; /* Determine the raw plotting value */ for (i = 0; i < preDrawSize; ++i) { @@ -679,70 +686,78 @@ return (overallUpperLimit - overallLowerLimit); } double preDrawAutoScale(struct preDrawElement *preDraw, int preDrawZero, int width, enum wiggleScaleOptEnum autoScale, double *overallUpperLimit, double *overallLowerLimit, double *graphUpperLimit, double *graphLowerLimit, double *overallRange, double *epsilon, int lineHeight, double maxY, double minY, enum wiggleAlwaysZeroEnum alwaysZero) /* if autoScaling, scan preDraw array and determine limits */ { double graphRange; if (autoScale == wiggleScaleAuto) { - int i; + int i, lastI = preDrawZero+width; /* reset limits for auto scale */ - for (i = preDrawZero; i < preDrawZero+width; ++i) + 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; } } if (alwaysZero == wiggleAlwaysZeroOn) { if ( *overallUpperLimit < 0) *overallUpperLimit = 0.0; else if ( *overallLowerLimit > 0) *overallLowerLimit = 0.0; } *overallRange = *overallUpperLimit - *overallLowerLimit; if (*overallRange == 0.0) { if (*overallUpperLimit > 0.0) { *graphUpperLimit = *overallUpperLimit; *graphLowerLimit = 0.0; - } else if (*overallUpperLimit < 0.0) { + } + else if (*overallUpperLimit < 0.0) + { *graphUpperLimit = 0.0; *graphLowerLimit = *overallUpperLimit; - } else { + } + else + { *graphUpperLimit = 1.0; *graphLowerLimit = -1.0; } - } else { + } + else + { *graphUpperLimit = *overallUpperLimit; *graphLowerLimit = *overallLowerLimit; } - } else { + } +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 */ { char *colorTrack = wigCart->colorTrack; int x1; Color *colorArray = NULL; /* Array of pixels to be drawn. */ @@ -1173,68 +1188,70 @@ graphLowerLimit = thisGraphLowerLimit; } else { if (overallUpperLimit < thisOverallUpperLimit) overallUpperLimit = thisOverallUpperLimit; if (overallLowerLimit > thisOverallLowerLimit) overallLowerLimit = thisOverallLowerLimit; if (graphUpperLimit < thisGraphUpperLimit) graphUpperLimit = thisGraphUpperLimit; if (graphLowerLimit > thisGraphLowerLimit) graphLowerLimit = thisGraphLowerLimit; } } - overallRange = overallUpperLimit - overallLowerLimit; graphRange = graphUpperLimit - graphLowerLimit; epsilon = graphRange / tg->lineHeight; struct preDrawElement *preDraw = preDrawList->preDraw; -colorArray = makeColorArray(preDraw, width, preDrawZero, - wigCart, tg, hvg); +colorArray = makeColorArray(preDraw, width, preDrawZero, wigCart, tg, hvg); /* now draw all the containers */ for(preContainer = preDrawList; preContainer; preContainer = preContainer->next) { struct preDrawElement *preDraw = preContainer->preDraw; graphPreDraw(preDraw, preDrawZero, width, tg, hvg, xOff, yOff, graphUpperLimit, graphLowerLimit, graphRange, epsilon, colorArray, vis, wigCart); } drawZeroLine(vis, wigCart->horizontalGrid, graphUpperLimit, graphLowerLimit, hvg, xOff, yOff, width, tg->lineHeight); drawArbitraryYLine(vis, wigCart->yLineOnOff, graphUpperLimit, graphLowerLimit, hvg, xOff, yOff, width, tg->lineHeight, wigCart->yLineMark, graphRange, wigCart->yLineOnOff); wigMapSelf(tg, hvg, seqStart, seqEnd, xOff, yOff, width); freez(&colorArray); if (retGraphUpperLimit != NULL) *retGraphUpperLimit = graphUpperLimit; if (retGraphLowerLimit != NULL) *retGraphLowerLimit = graphLowerLimit; } struct preDrawContainer *wigLoadPreDraw(struct track *tg, int seqStart, int seqEnd, int width) -/* Do bits that load the predraw buffer tg->preDraw and also preDrawSize and preDrawZero. */ +/* Do bits that load the predraw buffer tg->preDrawContainer. */ { +/* Just need to do this once... */ +if (tg->preDrawContainer) + return tg->preDrawContainer; + struct wigItem *wi; double pixelsPerBase = scaleForPixels(width); double basesPerPixel = 1.0; int itemCount = 0; char currentFile[PATH_LEN]; int wibFH = 0; /* file handle to binary file */ int i; /* an integer loop counter */ int x1 = 0; /* screen coordinates */ int x2 = 0; /* screen coordinates */ int usingDataSpan = 1; /* will become larger if possible */ if (tg->items == NULL) return NULL; currentFile[0] = '\0'; @@ -1620,19 +1637,20 @@ track->loadItems = wigLoadItems; track->freeItems = wigFreeItems; track->drawItems = wigDrawItems; track->itemName = wigNameCallback; track->mapItemName = wigNameCallback; track->totalHeight = wigTotalHeight; track->itemHeight = tgFixedItemHeight; track->itemStart = tgItemNoStart; track->itemEnd = tgItemNoEnd; /* the wigMaf parent will turn mapsSelf off */ track->mapsSelf = TRUE; track->extraUiData = (void *) wigCart; track->colorShades = shadesOfGray; track->drawLeftLabels = wigLeftLabels; +track->loadPreDraw = wigLoadPreDraw; /* the lfSubSample type makes the image map function correctly */ track->subType = lfSubSample; /*make subType be "sample" (=2)*/ } /* wigMethods() */