ff297774c7e9cb7056b780ea5554dc1ad2e22c10 braney Wed Aug 1 12:57:43 2018 -0700 add regular expression filtering on bigBeds. diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c index 0c81fe7..daf5482 100644 --- src/hg/hgTracks/bigBedTrack.c +++ src/hg/hgTracks/bigBedTrack.c @@ -117,30 +117,44 @@ { ret->comparisonType = COMPARE_LESS; ret->value1 = max; } else { ret->comparisonType = COMPARE_BETWEEN; ret->value1 = min; ret->value2 = max; } } } return ret; } +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); + +AllocVar(filter); +filter->fieldNum = bbExtraFieldIndex(bbi, field) + 3; +filter->comparisonType = COMPARE_REGEXP; +regcomp(&filter->regEx, value, REG_NOSUB); + +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; AllocVar(filter); filter->fieldNum = bbExtraFieldIndex(bbi, field) + 3; filter->comparisonType = COMPARE_HASH; filter->valueHash = newHash(5); for(; choices; choices = choices->next) hashStore(filter->valueHash, choices->name); return filter; @@ -148,55 +162,69 @@ struct bigBedFilter *bigBedBuildFilters(struct cart *cart, struct bbiFile *bbi, struct trackDb *tdb) /* Build all the numeric and filterBy filters for a bigBed */ { struct bigBedFilter *filters = NULL, *filter; struct slName *filterSettings = trackDbSettingsWildMatch(tdb, "*Filter"); for(; filterSettings; filterSettings = filterSettings->next) { char *fieldName = cloneString(filterSettings->name); fieldName[strlen(fieldName) - sizeof "Filter" + 1] = 0; if ((filter = bigBedMakeNumberFilter(cart, bbi, tdb, filterSettings->name, NULL, fieldName)) != NULL) slAddHead(&filters, filter); } +filterSettings = trackDbSettingsWildMatch(tdb, "*FilterText"); + +for(; filterSettings; filterSettings = filterSettings->next) + { + char *fieldName = cloneString(filterSettings->name); + fieldName[strlen(fieldName) - sizeof "FilterText" + 1] = 0; + if ((filter = bigBedMakeFilterText(cart, bbi, tdb, filterSettings->name, fieldName)) != NULL) + slAddHead(&filters, filter); + } + filterBy_t *filterBySet = filterBySetGet(tdb, cart,NULL); filterBy_t *filterBy = filterBySet; for (;filterBy != NULL; filterBy = filterBy->next) { if (filterBy->slChoices && differentString(filterBy->slChoices->name, "All")) { if ((filter = bigBedMakeFilterBy(cart, bbi, tdb, filterBy->column, filterBy->slChoices)) != NULL) slAddHead(&filters, filter); } } return filters; } boolean bigBedFilterInterval(char **bedRow, struct bigBedFilter *filters) /* Go through a row and filter based on filters. Return TRUE if all filters are passed. */ { struct bigBedFilter *filter; for(filter = filters; filter; filter = filter->next) { double val = atof(bedRow[filter->fieldNum]); switch(filter->comparisonType) { + case COMPARE_REGEXP: + if (regexec(&filter->regEx,bedRow[filter->fieldNum], 0, NULL,0 ) != 0) + return FALSE; + break; case COMPARE_HASH: if (!hashLookup(filter->valueHash, bedRow[filter->fieldNum])) return FALSE; break; case COMPARE_LESS: if (!(val <= filter->value1)) return FALSE; break; case COMPARE_MORE: if (!(val >= filter->value1)) return FALSE; break; case COMPARE_BETWEEN: if (!((val >= filter->value1) && (val <= filter->value2))) return FALSE;