2fd02c5e1ce1bb989549b2e0069270ca8907efad braney Thu Apr 10 15:03:42 2025 -0700 add bigLolly to quickLift support diff --git src/hg/hgTracks/lollyTrack.c src/hg/hgTracks/lollyTrack.c index 0f929fb0ead..8542c2fc4ed 100644 --- src/hg/hgTracks/lollyTrack.c +++ src/hg/hgTracks/lollyTrack.c @@ -1,30 +1,31 @@ /* lollyTrack -- load and draw lollys */ /* Copyright (C) 2019 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ 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" +#include "quickLift.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; }; @@ -316,31 +317,37 @@ { 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); +struct bigBedInterval *bb, *bbList; +char *quickLiftFile = cloneString(trackDbSetting(tg->tdb, "quickLiftUrl")); +struct hash *chainHash = NULL; +if (quickLiftFile) + bbList = quickLiftGetIntervals(quickLiftFile, bbi, chromName, winStart, winEnd, &chainHash); +else + bbList = bigBedIntervalQuery(bbi, chromName, winStart, winEnd, 0, lm); char *bedRow[bbi->fieldCount]; char startBuf[16], endBuf[16]; struct lolly *popList = NULL, *pop; 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) ; @@ -365,39 +372,58 @@ { bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); // throw away items that don't pass the filters if (!bigBedFilterInterval(bbi, bedRow, filters)) { filtered++; continue; } // clip out lollies that aren't in our display range double val = atof(bedRow[lollyField - 1]); if (!((lollyCart->autoScale == wiggleScaleAuto) || ((val >= lollyCart->minY) && (val <= lollyCart->maxY) ))) continue; + if (quickLiftFile) + { + struct bed *bed; + if ((bed = quickLiftIntervalsToBed(bbi, chainHash, bb)) != NULL) + { + // don't draw lollies off the screen + if (bed->chromStart < winStart) + continue; + + AllocVar(pop); + slAddHead(&popList, pop); + pop->val = val; + pop->start = bed->chromStart; + pop->end = bed->chromEnd; + } + } + else + { // don't draw lollies off the screen if (atoi(bedRow[1]) < winStart) continue; AllocVar(pop); slAddHead(&popList, pop); pop->val = val; pop->start = atoi(bedRow[1]); pop->end = atoi(bedRow[2]); + } pop->name = cloneString(bedRow[3]); pop->radius = -1; if (lollySizeField > 0) { double radius = atoi(bedRow[lollySizeField - 1]) * trackHeight / 100.0; pop->radius = radius; } pop->color = 0; pop->mouseOver = pop->name; extern char* restField(struct bigBedInterval *bb, int fieldIdx) ; if (mouseOverIdx > 0) pop->mouseOver = restField(bb, mouseOverIdx); else if (mouseOverPattern) pop->mouseOver = replaceFieldInPattern(mouseOverPattern, bbi->fieldCount, fieldNames, bedRow);