0658fac8d5f0ec35d5212eec876c3a2d87bd25ac
braney
  Mon Feb 6 15:46:27 2017 -0800
add the ability to set default labels and the label separator for bigBed
labels

diff --git src/hg/hgTracks/bedTrack.c src/hg/hgTracks/bedTrack.c
index a1a536a..74ceb60 100644
--- src/hg/hgTracks/bedTrack.c
+++ src/hg/hgTracks/bedTrack.c
@@ -1,94 +1,104 @@
 /* bedTrack - handle most aspects of a bed-format track (or bigBed). */
 
 /* Copyright (C) 2013 The Regents of the University of California 
  * See README in this or parent directory for licensing information. */
 
 #include "common.h"
 #include "jksql.h"
 #include "bed.h"
 #include "hdb.h"
 #include "bedCart.h"
 #include "bbiFile.h"
 #include "bigBed.h"
 #include "hgTracks.h"
 #include "cds.h"
 #include "bedTabix.h"
+#include "obscure.h"
 
 #define SEQ_DELIM '~'
 
 struct bed *bedLoadPairedTagAlign(char **row)
 /* Load first six fields of bed.
  * Add ~seq1~seq2 to end of name
  * Then remove the sequence to extra field when we convert to linkedFeature.
  * Assumes seq1 and seq2 are in row[6] and row[7], as they would be with a
  * pairedTagAlign type (hg/lib/encode/pairedTagAlign.as). It would be good to be
  * able to check these columns exist but we dont have the sqlResult here. */
 {
 char buf[1024];
 struct bed *ret = bedLoad6(row);
 safef(buf, sizeof(buf), "%s%c%s%c%s", ret->name, SEQ_DELIM, row[6], SEQ_DELIM, row[7]);
 freez(&(ret->name));
 ret->name = cloneString(buf);
 return ret;
 }
 
 static void calculateLabelFields(struct track *track)
 /* Figure out which fields are available to label a bigBed track. */
 {
-char *labelFields = trackDbSettingClosestToHome(track->tdb, "labelFields");
+struct bbiFile *bbi = fetchBbiForTrack(track);
+struct asObject *as = bigBedAsOrDefault(bbi);
+struct slPair *labelList = buildFieldList(track->tdb, "labelFields",  as);
 
-if (labelFields == NULL)
+if (labelList == NULL)
     {
-    // if there is a name, use it by default, otherwise no label by default 
+    // There is no labelFields entry in the trackDb.
+    // If there is a name, use it by default, otherwise no label by default 
     if (track->bedSize > 3)
         slAddHead(&track->labelColumns, slIntNew(3));
     }
 else
     {
-    char cartVar[1024];
     // what has the user said to use as a label
+    char cartVar[1024];
     safef(cartVar, sizeof cartVar, "%s.label", track->tdb->track);
     struct hashEl *labelEl = cartFindPrefix(cart, cartVar);
-    struct hash *labelHash = newHash(5);
-    struct slName *thisLabel, *labelIds = slNameListFromComma(labelFields);
+    struct hash *onHash = newHash(4);
 
     // fill hash with fields that should be used for labels
     if (labelEl == NULL) 
-        hashAdd(labelHash, labelIds->name, "1");
+        {
+        // there are no cart variables, so look for defaults
+        struct slPair *defaultLabelList = buildFieldList(track->tdb, "defaultLabelFields",  as);
+        if (defaultLabelList != NULL)
+            {
+            for(; defaultLabelList; defaultLabelList = defaultLabelList->next)
+                hashStore(onHash, defaultLabelList->name);
+            }
+        else
+            // no default list, use first entry in labelFields as default
+            hashStore(onHash, labelList->name);
+        }
     else
         {
+        // use cart variables to fill in onHash
         for(; labelEl; labelEl = labelEl->next)
-            hashAdd(labelHash, &labelEl->name[strlen(cartVar) + 1], labelEl->val);
+            {
+            if (sameString((char *)labelEl->val, "1"))
+                hashStore(onHash, &labelEl->name[strlen(cartVar) + 1]);
+            }
         }
 
-    struct asObject *as = asForDb(track->tdb, database);
-
-    for(thisLabel = labelIds; thisLabel; thisLabel = thisLabel->next)
+    struct slPair *thisLabel = labelList;
+    for(; thisLabel; thisLabel = thisLabel->next)
         {
-        char *trimLabel = trimSpaces(thisLabel->name);
-        char *str = hashFindVal(labelHash, trimLabel);
         
-        if ((str != NULL) && sameString(str, "1"))
+        if (hashLookup(onHash, thisLabel->name))
             {
-            unsigned colNum = asColumnFindIx(as->columnList, trimLabel);
-            if (colNum == -1)
-                errAbort("cannot find field named '%s' in as file '%s'", 
-                    trimLabel, as->name);
-
             // put this column number in the list of columns to use to make label
-            slAddHead(&track->labelColumns, slIntNew(colNum));
+            slAddHead(&track->labelColumns, slIntNew(ptToInt(thisLabel->val)));
             }
         }
     slReverse(&track->labelColumns);
     }
 }
 
 void loadSimpleBed(struct track *tg)
 /* Load the items in one track - just move beds in
  * window... */
 {
 struct bed *(*loader)(char **row);
 struct bed *bed, *list = NULL;
 char **row;
 int rowOffset;
 char *words[3];