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