a715f8ee926e405d684ba6891aef9ef7c6b28475 braney Fri Feb 1 16:41:47 2019 -0800 circle primitive and a basic version of lollipops diff --git src/hg/hgTracks/lollipop.c src/hg/hgTracks/lollipop.c index 03feba8..ba2895d 100644 --- src/hg/hgTracks/lollipop.c +++ src/hg/hgTracks/lollipop.c @@ -1,34 +1,160 @@ -/* lollipopTrack -- draw lollipopion between two genomic regions */ +/* lollipopTrack -- draw lollipop */ -/* Copyright (C) 2018 The Regents of the University of California +/* Copyright (C) 2019 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "obscure.h" #include "hgTracks.h" #include "bedCart.h" #include "bigWarn.h" #include "lollipop.h" +#include "limits.h" -void lollipopDrawItems(struct track *tg, int seqStart, int seqEnd, +static int trackHeight; + +struct lollipop +{ +struct lollipop *next; +double val; +unsigned start; +unsigned radius; +unsigned height; +Color color; +}; + +static void lollipopDrawItems(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw a list of lollipop structures. */ { +double scale = scaleForWindow(width, seqStart, seqEnd); +struct lollipop *popList = tg->items, *pop; + +if (popList == NULL) + return; + +for (pop = popList; pop; pop = pop->next) + { + int sx = ((pop->start - seqStart) + .5) * scale; // x coord of center (lower region) + hvGfxLine(hvg, sx, yOff + trackHeight, sx , yOff+(trackHeight - pop->height), pop->color); + hvGfxCircle(hvg, sx, yOff + trackHeight - pop->radius - pop->height, pop->radius, pop->color, TRUE); + } +} + +void lollipopLeftLabels(struct track *tg, int seqStart, int seqEnd, + struct hvGfx *hvg, int xOff, int yOff, int width, int height, + boolean withCenterLabels, MgFont *font, Color color, + enum trackVisibility vis) +{ +} + + +static int lollipopHeight(struct track *tg, enum trackVisibility vis) +/* calculate height of all the lollipops being displayed */ +{ +if ( tg->visibility == tvDense) + return tl.fontHeight; +trackHeight = 5 * tl.fontHeight; +return 5 * tl.fontHeight; +} + +static void lollipopMapItem(struct track *tg, struct hvGfx *hvg, void *item, char *itemName, char *mapItemName, int start, int end, + int x, int y, int width, int height) +{ +} + + +double calcVarianceFromSums(double sum, double sumSquares, bits64 n) +/* Calculate variance. */ +{ +double var = sumSquares - sum*sum/n; +if (n > 1) + var /= n-1; +return var; +} + +double calcStdFromSums(double sum, double sumSquares, bits64 n) +/* Calculate standard deviation. */ +{ +return sqrt(calcVarianceFromSums(sum, sumSquares, n)); +} + +int cmpHeight(const void *va, const void *vb) +{ +const struct lollipop *a = *((struct lollipop **)va); +const struct lollipop *b = *((struct lollipop **)vb); +return a->height - b->height; } void lollipopLoadItems(struct track *tg) - /* Load interact items in interact format */ { -//loadAndFilterItems(tg); +struct lm *lm = lmInit(0); +struct bbiFile *bbi = fetchBbiForTrack(tg); +struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, chromName, winStart, winEnd, 0, lm); +char *bedRow[5]; +char startBuf[16], endBuf[16]; +struct lollipop *popList = NULL, *pop; +unsigned lollipopField = atoi(trackDbSetting(tg->tdb, "lollipopField")); +double sumData = 0.0, sumSquares = 0.0; +//double minVal = DBL_MAX, maxVal = -DBL_MAX; +unsigned count = 0; + +for (bb = bbList; bb != NULL; bb = bb->next) + { + AllocVar(pop); + slAddHead(&popList, pop); + bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); + double val = atof(bedRow[lollipopField]); + pop->val = val; + pop->start = atoi(bedRow[1]); + count++; + sumData += val; + sumSquares += val * val; + } + +double average = sumData/count; +double stdDev = calcStdFromSums(sumData, sumSquares, count); + +for(pop = popList; pop; pop = pop->next) + { + if (pop->val > average + stdDev / 5) + { + pop->color = MG_RED; + pop->radius = 8; + pop->height = 3 * tl.fontHeight; + } + else if (pop->val < average - stdDev / 5) + { + pop->color = MG_GREEN; + pop->radius = 3; + pop->height = 1 * tl.fontHeight; + } + else + { + pop->color = MG_GRAY; + pop->radius = 5; + pop->height = 2 * tl.fontHeight; + } + + } +slSort(&popList, cmpHeight); +tg->items = popList; } -void lollipopMethods(struct track *tg) +void lollipopMethods(struct track *track, struct trackDb *tdb, + int wordCount, char *words[]) /* Interact track type methods */ { -tg->bedSize = 12; -linkedFeaturesMethods(tg); // for most vis and mode settings -tg->loadItems = lollipopLoadItems; -//tg->itemRightPixels = lollipopRightPixels; -tg->drawItems = lollipopDrawItems; +char *ourWords[2]; +ourWords[0] = "bigBed"; +ourWords[1] = "4"; +bigBedMethods(track, tdb,2,ourWords); +if (tdb->visibility == tvDense) + return; +track->loadItems = lollipopLoadItems; +track->drawItems = lollipopDrawItems; +track->totalHeight = lollipopHeight; +track->drawLeftLabels = lollipopLeftLabels; +track->mapItem = lollipopMapItem; }