a6a236e1f1855cb202d1824435bdf797cf07ad47 braney Mon Nov 2 16:24:47 2020 -0800 add support for bigLolly custom tracks and specifying lolly trackDb fields that specify a field using the name of the field OR the field number diff --git src/hg/hgTracks/lollyTrack.c src/hg/hgTracks/lollyTrack.c index 232f2f1..ea045a3 100644 --- src/hg/hgTracks/lollyTrack.c +++ src/hg/hgTracks/lollyTrack.c @@ -1,29 +1,30 @@ /* lollyTrack -- load and draw lollys */ /* 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 "lolly.h" #include "limits.h" #include "float.h" #include "bigBedFilter.h" +#include "asParse.h" #define LOLLY_DIAMETER 2 * (lollyCart->radius + 2) struct lolly { struct lolly *next; char *name; /* the mouseover name */ double val; /* value in the data file */ unsigned start; /* genomic start address */ unsigned end; /* genomic end address */ unsigned radius; /* radius of the top of the lolly */ unsigned height; /* height of the lolly */ Color color; /* color of the lolly */ char *mouseOver; }; @@ -181,60 +182,73 @@ if ( tg->visibility == tvDense) return tl.fontHeight; // return the height we calculated at load time return tg->lollyCart->height; } int cmpHeight(const void *va, const void *vb) // sort the lollies by height { const struct lolly *a = *((struct lolly **)va); const struct lolly *b = *((struct lolly **)vb); return a->height - b->height; } +static int getField(struct trackDb *tdb, char *name, struct asObject *as, int defaultValue) +/* Get the as field (if any) that a trackDb variable references. This can either be + * a field name, or a number. */ +{ +int ret = defaultValue; +char *setting = trackDbSetting(tdb, name); +if (setting != NULL) + { + if (isNumericString(setting)) + ret = atoi(setting); + else + { + struct asColumn *columns = as->columnList; + ret = asColumnMustFindIx(columns, setting) + 1; + } + } +return ret; +} + void lollyLoadItems(struct track *tg) // load lollies from the data file { struct lollyCartOptions *lollyCart = tg->lollyCart; if (tg->visibility == tvSquish) { //lollyCart->radius = 2; lollyCart->height = lollyCart->origHeight / 2; } else if (tg->visibility == tvPack) { //lollyCart->radius = 4; lollyCart->height = lollyCart->origHeight / 1.5; } struct lm *lm = lmInit(0); struct bbiFile *bbi = fetchBbiForTrack(tg); +struct asObject *as = bigBedAsOrDefault(bbi); struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, chromName, winStart, winEnd, 0, lm); char *bedRow[bbi->fieldCount]; char startBuf[16], endBuf[16]; struct lolly *popList = NULL, *pop; -unsigned lollyField = 5; // we use the score field by default -char *setting = trackDbSetting(tg->tdb, "lollyField"); -if (setting != NULL) - lollyField = atoi(setting); - -int lollySizeField = -1 ; -setting = trackDbSetting(tg->tdb, "lollySizeField"); -if (setting != NULL) - lollySizeField = atoi(setting); +unsigned lollyField = getField(tg->tdb, "lollyField", as, 5); // we use the score field by default +int lollySizeField = getField(tg->tdb, "lollySizeField", as, -1); // no size field by default double minVal = DBL_MAX, maxVal = -DBL_MAX; //double sumData = 0.0, sumSquares = 0.0; unsigned count = 0; int trackHeight = tg->lollyCart->height; struct bigBedFilter *filters = bigBedBuildFilters(cart, bbi, tg->tdb); char *mouseOverField = cartOrTdbString(cart, tg->tdb, "mouseOverField", NULL); int mouseOverIdx = bbExtraFieldIndex(bbi, mouseOverField) ; char *mouseOverPattern = NULL; char **fieldNames = NULL; if (!mouseOverIdx) { mouseOverPattern = cartOrTdbString(cart, tg->tdb, "mouseOver", NULL);