de6d2d4e5d0106a57d1ada79e9e36005676c260e
chmalee
  Fri Sep 25 12:39:18 2026 -0700
Add trackDb defined filters, coloring, and mouseovers for vcf tracks, using INFO fields or sub INFO fields, like vep.Consequence, refs #37617, #37618

diff --git src/hg/inc/vcfUi.h src/hg/inc/vcfUi.h
index f19e1554fd6..52b1dd5c2b9 100644
--- src/hg/inc/vcfUi.h
+++ src/hg/inc/vcfUi.h
@@ -1,26 +1,27 @@
 /* vcfUi - Variant Call Format user interface controls that are shared
  * between more than one CGI. */
 
 /* Copyright (C) 2011 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 #ifndef VCFUI_H
 #define VCFUI_H
 
 #include "cart.h"
 #include "trackDb.h"
 #include "vcf.h"
+#include "bigBedFilter.h"
 
 #define VCF_HAP_HEIGHT_VAR "hapClusterHeight"
 #define VCF_DEFAULT_HAP_HEIGHT 128
 
 #define VCF_HAP_ENABLED_VAR "hapClusterEnabled"
 #define VCF_HAP_METHOD_VAR "hapClusterMethod"
 #define VCF_HAP_METHOD_CENTER_WEIGHTED "centerWeighted"
 #define VCF_HAP_METHOD_FILE_ORDER "fileOrder"
 #define VCF_HAP_METHOD_TREE_FILE "treeFile"
 #define VCF_DEFAULT_HAP_METHOD VCF_HAP_METHOD_CENTER_WEIGHTED
 
 #define VCF_HAP_COLORBY_VAR "hapClusterColorBy"
 #define VCF_HAP_COLORBY_ALTONLY "altOnly"
 #define VCF_HAP_COLORBY_FUNCTION "function"
 #define VCF_HAP_COLORBY_REFALT "refAlt"
@@ -43,47 +44,108 @@
 #define VCF_DO_QUAL_UI "vcfDoQual"
 #define VCF_MIN_QUAL_VAR "minQual"
 #define VCF_DEFAULT_MIN_QUAL 0
 
 #define VCF_DO_FILTER_UI "vcfDoFilter"
 
 #define VCF_EXCLUDE_FILTER_VAR "excludeFilterValues"
 
 #define VCF_DO_MAF_UI "vcfDoMaf"
 #define VCF_MIN_ALLELE_FREQ_VAR "minFreq"
 #define VCF_DEFAULT_MIN_ALLELE_FREQ 0.0
 
 #define VCF_DO_MIN_AC_UI "vcfDoMinAc"
 #define VCF_MIN_AC_VAR "minAc"
 #define VCF_DEFAULT_MIN_AC 0
+#define VCF_DO_INFOFILTER_UI "vcfDoInfoFilter"
 
 #define VCF_PHASED_CHILD_SAMPLE_SETTING "vcfChildSample"
 #define VCF_PHASED_PARENTS_SAMPLE_SETTING "vcfParentSamples"
 #define VCF_PHASED_SAMPLE_ORDER_VAR "vcfSampleOrder"
 #define VCF_PHASED_MAX_OTHER_SAMPLES 2
 #define VCF_PHASED_DEFAULT_LABEL_VAR "doDefaultLabel"
 #define VCF_PHASED_ALIAS_LABEL_VAR "doAliasLabel"
 #define VCF_PHASED_HIDE_OTHER_VAR "hideParents"
 #define VCF_PHASED_TDB_USE_ALT_NAMES "vcfUseAltSampleNames"
 #define VCF_PHASED_CHILD_BELOW_VAR "sortChildBelow"
 
 #define VCF_PHASED_COLORBY_VAR "vcfPhasedColorBy"
 #define VCF_PHASED_COLORBY_MENDEL_DIFF "mendelDiff"
 #define VCF_PHASED_COLORBY_DE_NOVO "deNovo"
 #define VCF_PHASED_COLORBY_FUNCTION "function"
 #define VCF_PHASED_COLORBY_DEFAULT "noColor"
 
+#define VCF_COLOR_BY_INFO "colorByInfo"
+
+struct vcfColorByInfo
+/* Parsed trackDb mapping from one INFO field's values to display colors. */
+    {
+    char *fieldKey;             // INFO key chosen by `colorByInfo <FIELD>`
+    struct hash *valueToRgb;    // string value -> struct rgbColor *; used for top-level lookup
+    struct slPair *orderedColors; // declaration-order list (name=value string, val=struct rgbColor *)
+                                  // walked in priority order for sub-field lookup
+    int subFieldIndex;          // 0-based column in pipe-separated INFO annotation;
+                                // -1 when this map targets the top-level value
+    char *subFieldName;         // diagnostic; NULL when subFieldIndex == -1
+    };
+
+int vcfInfoDefSubFieldIndex(const struct vcfInfoDef *def, const char *subFieldName);
+/* Parse the "Format: A|B|C|..." clause out of def->description (same syntax
+ * looksTabular() in lib/vcf.c keys off of) and return the 0-based index of
+ * subFieldName, or -1 if the description has no Format clause or the name is
+ * absent. */
+
+struct vcfColorByInfo *vcfColorByInfoFromTdb(struct trackDb *tdb, struct vcfFile *vcff);
+/* Parse colorByInfo / colorByInfo.<FIELD> settings; returns NULL when
+ * the feature is not configured on this track. The vcff header is used to check
+ * that the field is a String INFO field and to resolve the named sub-field of a
+ * pipe-separated INFO annotation (e.g. vep.Consequence). Warns and returns NULL
+ * when the field can't be used. */
+
+boolean vcfColorByInfoLookup(struct vcfColorByInfo *cbi,
+                             const struct vcfRecord *rec,
+                             struct rgbColor *out);
+/* Look up rec's value for cbi->fieldKey and copy its RGB into *out.
+ * Returns FALSE when no mapping applies (caller should use a fallback). */
+
+struct vcfInfoFilter
+/* A linked list of optional trackDb defined filters on the INFO fields. This
+ * is largely derived from bigBedFilter.h, but is limited by the type of the
+ * INFO sub-field itself */
+    {
+    struct vcfInfoFilter *next;
+    struct vcfInfoDef *infoDef;
+    enum bigBedFilterType comparisonType;  // the type of the comparison
+    double value1, value2;
+    struct hash *valueHash;
+    unsigned numValuesInHash;
+    regex_t regEx;
+    char *wildCardString;
+    boolean isHighlight; // are we highlighting this record or filtering it?
+    int subFieldIndex;   // 0-based column in pipe-separated INFO annotation (e.g. vep);
+                         // -1 when this filter targets the top-level value
+    char *subFieldName;  // sub-field name from trackDb (e.g. "Consequence"); NULL when
+                         // this filter is not a sub-field filter
+    };
+
+struct vcfInfoFilter *buildVcfInfoFilters(struct vcfFile *vcff, struct cart *cart, struct trackDb *tdb);
+/* Parse the cart/trackDb current filters into something we can filter the records on.
+ * Warns about and skips any filter whose INFO field is missing or has the wrong type. */
+
+boolean vcfInfoFilterOneRecord(struct vcfRecord *rec, struct vcfInfoFilter *vcfInfoFilters);
+/* Return true if rec passes all the filters on the INFO fields defined in vcfInfoFilters */
+
 void vcfCfgHaplotypeCenter(struct cart *cart, struct trackDb *tdb, char *track,
 			   boolean parentLevel, struct vcfFile *vcff,
 			   char *thisName, char *thisChrom, int thisPos, char *formName);
 /* If vcff has genotype data, show status and controls for choosing the center variant
  * for haplotype clustering/sorting in hgTracks. */
 
 struct slPair *vcfPhasedGetSampleOrder(struct cart *cart, struct trackDb *tdb, boolean parentLevel, boolean hideOtherSamples);
 /* Parse out a trio sample order from trackDb */
 
 void vcfCfgUi(struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed);
 /* Complete track controls for VCF. */
 
 char *vcfHaplotypeOrSample(struct cart *cart);
 /* Return "Sample" if the current organism is uniploid (like SARS-CoV-2), "Haplotype" otherwise. */