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;