c9d17a52b6b5663c7175b01f801d23198b675f7e
max
  Fri Sep 25 12:03:55 2026 -0700
Revert all bigBed-filters for VCF changes, as Chris did that earlier already.

This reverts commit 2521d696f5073ce8cee3f59f423f161fdb77d550.

diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c
index fb164dd7e1d..6dedc243815 100644
--- src/hg/hgTracks/vcfTrack.c
+++ src/hg/hgTracks/vcfTrack.c
@@ -2,31 +2,30 @@
 
 /* Copyright (C) 2014 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 
 #include "common.h"
 #include "bigWarn.h"
 #include "dystring.h"
 #include "rainbow.h"
 #include "errCatch.h"
 #include "fa.h"
 #include "genePredReader.h"
 #include "hacTree.h"
 #include "hdb.h"
 #include "hgColors.h"
 #include "hgTracks.h"
-#include "bigBedFilter.h"
 #include "iupac.h"
 #include "net.h"
 #include "pgSnp.h"
 #include "phyloTree.h"
 #include "trackHub.h"
 #include "trashDir.h"
 #include "variantProjector.h"
 #include "vcf.h"
 #include "vcfUi.h"
 #include "knetUdc.h"
 #include "udc.h"
 #include "memgfx.h"
 #include "chromAlias.h"
 #include "hgConfig.h"
 #include "wigCommon.h"
@@ -228,217 +227,53 @@
     nextRecord = rec->next;
     boolean allRef = TRUE;
     for (sample = sampleOrder; sample != NULL; sample = sample->next)
         {
         gt = vcfRecordFindGenotype(rec, sample->name);
         if (gt && !(gt->hapIxA == 0 && gt->hapIxB == 0) )
             allRef = FALSE;
         }
     if (!allRef)
         slAddHead(&retList, rec);
     }
 slReverse(&retList);
 vcff->records = retList;
 }
 
-struct vcfInfoFilter
-/* One generic trackDb filter (filter.*, filterText.*, filterValues.*, as for bigBed) on a VCF
- * INFO field or on the fixed ID or QUAL column. */
-    {
-    struct vcfInfoFilter *next;
-    char *field;                    /* INFO key, or ID or QUAL */
-    const struct vcfInfoDef *def;   /* Header definition of the INFO key, NULL for ID and QUAL */
-    struct bigBedFilter *filter;    /* The comparison, made by the bigBed filter code */
-    };
-
-static void addVcfInfoFilter(struct vcfInfoFilter **pList, struct vcfFile *vcff, char *field,
-                             struct bigBedFilter *filter)
-/* If filter is not NULL, add it to *pList as a filter on the INFO field (or ID/QUAL column) field. */
-{
-if (filter == NULL)
-    return;
-struct vcfInfoFilter *vf;
-AllocVar(vf);
-vf->field = field;
-vf->def = vcfInfoDefForKey(vcff, field);
-vf->filter = filter;
-slAddHead(pList, vf);
-}
-
-static void checkVcfFilterField(struct vcfFile *vcff, struct trackDb *tdb, char *field)
-/* errAbort if a trackDb filter is on a field that is neither a declared INFO key nor ID/QUAL,
- * like the bigBed filters do for a field that is not in the autoSql. */
-{
-if (vcfInfoDefForKey(vcff, field) == NULL && differentString(field, "ID")
-&& differentString(field, "QUAL"))
-    errAbort("track %s: trackDb filter on field '%s', but the VCF header has no INFO "
-             "definition for it.", tdb->track, field);
-}
-
-static struct vcfInfoFilter *vcfBuildInfoFilters(struct vcfFile *vcff, struct trackDb *tdb)
-/* Build the generic trackDb filters of a VCF track, using the bigBed filter code, where the
- * field names are INFO keys. The field number of the bigBed filter is not used. */
-{
-struct vcfInfoFilter *list = NULL;
-struct trackDbFilter *tdbFilter;
-for (tdbFilter = tdbGetTrackNumFilters(tdb);  tdbFilter != NULL;  tdbFilter = tdbFilter->next)
-    {
-    checkVcfFilterField(vcff, tdb, tdbFilter->fieldName);
-    addVcfInfoFilter(&list, vcff, tdbFilter->fieldName,
-                     bigBedMakeNumberFilterOnField(cart, tdb, tdbFilter->name, NULL,
-                                                   tdbFilter->fieldName, 0, FALSE));
-    }
-for (tdbFilter = tdbGetTrackTextFilters(tdb);  tdbFilter != NULL;  tdbFilter = tdbFilter->next)
-    {
-    checkVcfFilterField(vcff, tdb, tdbFilter->fieldName);
-    addVcfInfoFilter(&list, vcff, tdbFilter->fieldName,
-                     bigBedMakeFilterTextOnField(cart, tdb, tdbFilter->name,
-                                                 tdbFilter->fieldName, 0, FALSE));
-    }
-filterBy_t *filterBy;
-for (filterBy = filterBySetGet(tdb, cart, NULL);  filterBy != NULL;  filterBy = filterBy->next)
-    {
-    checkVcfFilterField(vcff, tdb, filterBy->column);
-    if (filterBy->slChoices && differentString(filterBy->slChoices->name, "All"))
-        addVcfInfoFilter(&list, vcff, filterBy->column,
-                         bigBedMakeFilterByOnField(cart, tdb, filterBy->column, 0,
-                                                   filterBy->slChoices, FALSE));
-    }
-return list;
-}
-
-static char *vcfDatumToString(union vcfDatum datum, enum vcfInfoType type, char *buf, int bufSize)
-/* Return the string form of one INFO value, for the bigBed filter comparison. */
-{
-switch (type)
-    {
-    case vcfInfoInteger:
-        safef(buf, bufSize, "%d", datum.datInt);
-        return buf;
-    case vcfInfoFloat:
-        // 15 significant digits: the value parsed from the VCF text comes back unchanged
-        safef(buf, bufSize, "%.15g", datum.datFloat);
-        return buf;
-    case vcfInfoCharacter:
-        safef(buf, bufSize, "%c", datum.datChar);
-        return buf;
-    default:
-        return datum.datString;
-    }
-}
-
-static boolean vcfInfoFilterPass(struct vcfRecord *rec, struct vcfInfoFilter *vf)
-/* Return TRUE if rec passes one generic trackDb filter.
- * - A field with several values (e.g. Number=A) passes if any of its values passes. For
- *   filterType multipleListOr/multipleListAnd the values are compared as a list, like a
- *   comma-separated bigBed field.
- * - A missing value ('.' or key absent) fails a numeric filter (as in bcftools view -i). For text
- *   and value filters it is compared as the empty string, so the wildcard '*' still shows it.
- * - A Flag field has the value 1 if the key is present and 0 if it is absent. */
-{
-struct bigBedFilter *filter = vf->filter;
-boolean isNumeric = (filter->comparisonType == COMPARE_LESS
-                     || filter->comparisonType == COMPARE_MORE
-                     || filter->comparisonType == COMPARE_BETWEEN);
-boolean isList = (filter->comparisonType == COMPARE_HASH_LIST_AND
-                  || filter->comparisonType == COMPARE_HASH_LIST_OR);
-if (vf->def == NULL)
-    {
-    // the fixed columns ID or QUAL
-    char *val = sameString(vf->field, "ID") ? rec->name : rec->qual;
-    if (sameString(val, "."))
-        return isNumeric ? FALSE : bigBedFilterOneValue(filter, "");
-    return bigBedFilterOneValue(filter, val);
-    }
-const struct vcfInfoElement *el = vcfRecordFindInfo(rec, vf->field);
-if (vf->def->type == vcfInfoFlag)
-    {
-    char *val = "0";
-    if (el != NULL)
-        {
-        val = "1";
-        // older VCFs can have a value on a flag, e.g. VCF 3.2's DB=0 or DB=1
-        if (el->count > 0 && isNotEmpty(el->values[0].datString))
-            val = el->values[0].datString;
-        }
-    return bigBedFilterOneValue(filter, val);
-    }
-struct dyString *listVal = isList ? dyStringNew(0) : NULL;
-boolean gotValue = FALSE;
-int i;
-for (i = 0;  el != NULL && i < el->count;  i++)
-    {
-    if (el->missingData[i])
-        continue;
-    char buf[64];
-    char *val = vcfDatumToString(el->values[i], vf->def->type, buf, sizeof buf);
-    gotValue = TRUE;
-    if (isList)
-        {
-        if (dyStringLen(listVal) > 0)
-            dyStringAppendC(listVal, ',');
-        dyStringAppend(listVal, val);
-        }
-    else if (bigBedFilterOneValue(filter, val))
-        return TRUE;
-    }
-if (isList)
-    {
-    boolean pass = bigBedFilterOneValue(filter, dyStringContents(listVal));
-    dyStringFree(&listVal);
-    return pass;
-    }
-if (!gotValue && !isNumeric)
-    return bigBedFilterOneValue(filter, "");
-return FALSE;
-}
-
-static boolean vcfInfoFiltersFail(struct vcfRecord *rec, struct vcfInfoFilter *filters)
-/* Return TRUE if rec fails any of the generic trackDb filters. */
-{
-struct vcfInfoFilter *vf;
-for (vf = filters;  vf != NULL;  vf = vf->next)
-    if (!vcfInfoFilterPass(rec, vf))
-        return TRUE;
-return FALSE;
-}
-
 static void filterRecords(struct vcfFile *vcff, struct track *tg)
 /* If a filter is specified in the cart, remove any records that don't pass filter. Adapt longLabel if something was filtered. */
 {
 struct trackDb *tdb = tg->tdb;
 double minQual = VCF_DEFAULT_MIN_QUAL;
 struct slName *filterValues = NULL;
 double minFreq = VCF_DEFAULT_MIN_ALLELE_FREQ;
 int minAc = VCF_DEFAULT_MIN_AC;
 boolean gotQualFilter = getMinQual(tdb, &minQual);
 boolean gotFilterFilter = getFilterValues(tdb, &filterValues);
 boolean gotMinFreqFilter = getMinFreq(tdb, &minFreq);
 boolean gotMinAcFilter = getMinAc(tdb, &minAc);
-struct vcfInfoFilter *infoFilters = vcfBuildInfoFilters(vcff, tdb);
 int filtOut = 0;
-if (gotQualFilter || gotFilterFilter || gotMinFreqFilter || gotMinAcFilter || infoFilters != NULL)
+if (gotQualFilter || gotFilterFilter || gotMinFreqFilter || gotMinAcFilter)
     {
     struct vcfRecord *rec, *nextRec, *newList = NULL;
     for (rec = vcff->records;  rec != NULL;  rec = nextRec)
         {
         nextRec = rec->next;
         if (! ((gotQualFilter && minQualFail(rec, minQual)) ||
                (gotFilterFilter && filterColumnFail(rec, filterValues)) ||
                (gotMinFreqFilter && minFreqFail(rec, minFreq)) ||
-               (gotMinAcFilter && minAcFail(rec, minAc)) ||
-               (infoFilters != NULL && vcfInfoFiltersFail(rec, infoFilters)) ))
+               (gotMinAcFilter && minAcFail(rec, minAc)) ))
             slAddHead(&newList, rec);
         else 
             filtOut++;
         }
     slReverse(&newList);
     vcff->records = newList;
     }
 
 labelTrackAsFilteredNumber(tg, filtOut);
 }
 
 struct pgSnpVcfStartEnd
 /* This extends struct pgSnp by tacking on an original VCF chromStart and End at the end,
  * for use by indelTweakMapItem below.  This can be cast to pgs. */
 {