3122e477cca8eacc6dc51bdf96544641877a904a
braney
  Tue Sep 24 15:03:24 2019 -0700
allow filtering on first three fields of bigBed.  Label filtered tracks
as filtered

diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c
index 851a909..e5e885c 100644
--- src/hg/hgTracks/bigBedTrack.c
+++ src/hg/hgTracks/bigBedTrack.c
@@ -15,36 +15,46 @@
 #include "hmmstats.h"
 #include "localmem.h"
 #include "wigCommon.h"
 #include "bbiFile.h"
 #include "obscure.h"
 #include "bigWig.h"
 #include "bigBed.h"
 #include "bigWarn.h"
 #include "errCatch.h"
 #include "trackHub.h"
 #include "net.h"
 #include "bigPsl.h"
 #include "bigBedFilter.h"
 #include "bigBedLabel.h"
 
+static unsigned getFieldNum(struct bbiFile *bbi, char *field)
+// get field number for field name in bigBed.  errAbort if field not found.
+{
+int fieldNum =  bbFieldIndex(bbi, field);
+if (fieldNum < 0)
+    errAbort("error building filter with field %s.  Field not found.", field);
+
+return fieldNum;
+}
+
 struct bigBedFilter *bigBedMakeNumberFilter(struct cart *cart, struct bbiFile *bbi, struct trackDb *tdb, char *filter, char *defaultLimits,  char *field)
 /* Make a filter on this column if the trackDb or cart wants us to. */
 {
 struct bigBedFilter *ret = NULL;
 char *setting = trackDbSettingClosestToHome(tdb, filter);
-int fieldNum =  bbExtraFieldIndex(bbi, field) + 3;
+int fieldNum =  getFieldNum(bbi, field);
 if (setting)
     {
     struct asObject *as = bigBedAsOrDefault(bbi);
     // All this isFloat conditional code is here because the cart
     // variables used for floats are different than those used for ints
     // in ../lib/hui.c so we have to use the correct getScore*() routine
     // to access them..    We're doomed.
     boolean isFloat = FALSE;
     struct asColumn *asCol = asColumnFind(as, field);
     if (asCol != NULL)
         isFloat = asTypesIsFloating(asCol->lowType->type);
     boolean invalid = FALSE;
     double minValueTdb = 0,maxValueTdb = NO_VALUE;
     double minLimit=NO_VALUE,maxLimit=NO_VALUE,min = minValueTdb,max = maxValueTdb;
     if (!isFloat)
@@ -133,56 +143,56 @@
 struct bigBedFilter *bigBedMakeFilterText(struct cart *cart, struct bbiFile *bbi, struct trackDb *tdb, char *filterName, char *field)
 /* Add a bigBed filter using a trackDb filterText statement. */
 {
 struct bigBedFilter *filter;
 char *setting = trackDbSettingClosestToHome(tdb, filterName);
 char *value = cartUsualStringClosestToHome(cart, tdb, FALSE, filterName, setting);
 
 if (isEmpty(value)) 
     return NULL;
 
 char filterType[4096];
 safef(filterType, sizeof filterType, "%s%s", field, FILTER_TYPE_NAME);
 char *typeValue = cartOrTdbString(cart, tdb, filterType, FILTERTEXT_WILDCARD);
 
 AllocVar(filter);
-filter->fieldNum =  bbExtraFieldIndex(bbi, field) + 3;
+filter->fieldNum =  getFieldNum(bbi, field);
 
 if (sameString(typeValue, FILTERTEXT_REGEXP) )
     {
     filter->comparisonType = COMPARE_REGEXP;
     regcomp(&filter->regEx, value, REG_NOSUB);
     }
 else
     {
     filter->comparisonType = COMPARE_WILDCARD;
     filter->wildCardString = cloneString(value);
     }
 
 return filter;
 }
 
 struct bigBedFilter *bigBedMakeFilterBy(struct cart *cart, struct bbiFile *bbi, struct trackDb *tdb, char *field, struct slName *choices)
 /* Add a bigBed filter using a trackDb filterBy statement. */
 {
 struct bigBedFilter *filter;
 char filterType[4096];
 safef(filterType, sizeof filterType, "%s%s", field, FILTER_TYPE_NAME);
 char *setting = cartOrTdbString(cart, tdb, filterType, FILTERBY_SINGLE);
 
 AllocVar(filter);
-filter->fieldNum =  bbExtraFieldIndex(bbi, field) + 3;
+filter->fieldNum =  getFieldNum(bbi, field);
 if (setting && (sameString(setting, FILTERBY_SINGLE_LIST) || sameString(setting, FILTERBY_MULTIPLE_LIST_OR)))
     filter->comparisonType = COMPARE_HASH_LIST_OR;
 else if (setting && sameString(setting, FILTERBY_MULTIPLE_LIST_AND))
     filter->comparisonType = COMPARE_HASH_LIST_AND;
 else
     filter->comparisonType = COMPARE_HASH;
 filter->valueHash = newHash(5);
 filter->numValuesInHash = slCount(choices);
 
 for(; choices; choices = choices->next)
     hashStore(filter->valueHash, choices->name);
 
 return filter;
 }
 
@@ -405,30 +415,32 @@
 if (scoreFilter)
     minScore = atoi(scoreFilter);
 
 struct bbiFile *bbi = fetchBbiForTrack(track);
 int seqTypeField =  0;
 if (sameString(track->tdb->type, "bigPsl"))
     {
     seqTypeField =  bbExtraFieldIndex(bbi, "seqType");
     }
 
 int mouseOverIdx = bbExtraFieldIndex(bbi, mouseOverField);
 
 track->bbiFile = NULL;
 
 struct bigBedFilter *filters = bigBedBuildFilters(cart, bbi, track->tdb) ;
+if (filters)
+    labelTrackAsFiltered(track);
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     struct linkedFeatures *lf = NULL;
     if (sameString(track->tdb->type, "bigPsl"))
 	{
 	char *seq, *cds;
 	struct psl *psl = pslFromBigPsl(chromName, bb, seqTypeField,  &seq, &cds); 
 	int sizeMul =  pslIsProtein(psl) ? 3 : 1;
 	boolean isXeno = 0;  // just affects grayIx
 	boolean nameGetsPos = FALSE; // we want the name to stay the name
 
 	lf = lfFromPslx(psl, sizeMul, isXeno, nameGetsPos, track);
 	lf->original = psl;
 	if ((seq != NULL) && (lf->orientation == -1))
 	    reverseComplement(seq, strlen(seq));