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);