294e28961da0eab069c44113ff02dbd6008bb9cf
angie
  Mon Oct 27 22:13:02 2014 -0700
I was under the mistaken impression that VCF header ##INFO andencouraged."  This change remove errors about missing descriptions
that were causing hgTables to give up after 101 errors on a track
hub VCF.  While inspecting the code I found that hgc's vcfClick.c
printKeysWithDescriptions had never made use of its infoDefs arg
as intended, so descriptions from ##ALT (symbolic alternate alleles)
and ##FILTER were not displayed -- fixed that.
refs #14231

diff --git src/hg/hgc/vcfClick.c src/hg/hgc/vcfClick.c
index e366656..c1d23ac 100644
--- src/hg/hgc/vcfClick.c
+++ src/hg/hgc/vcfClick.c
@@ -10,105 +10,123 @@
 #include "hdb.h"
 #include "hgc.h"
 #include "htmshell.h"
 #include "jsHelper.h"
 #include "pgSnp.h"
 #include "regexHelper.h"
 #include "trashDir.h"
 #include "knetUdc.h"
 #include "udc.h"
 #include "vcf.h"
 #include "vcfUi.h"
 
 #define NA "<em>n/a</em>"
 
 static void printKeysWithDescriptions(struct vcfFile *vcff, int wordCount, char **words,
-				      struct vcfInfoDef *infoDefs)
-/* Given an array of keys, print out a list of values with
- * descriptions if descriptions are available. */
+				      struct vcfInfoDef *infoDefs, boolean stripToSymbol)
+/* Given an array of keys, print out a list of values with descriptions if descriptions are
+ * available.  If stripToSymbol, when searching infoDefs, pick the actual key out of
+ * <>'s and other extraneous stuff (e.g. "(C)<DEL>" --> "DEL"). */
 {
 int i;
 for (i = 0;  i < wordCount; i++)
     {
     if (i > 0)
 	printf(", ");
-    char *key = words[i];
-    const struct vcfInfoDef *def = vcfInfoDefForKey(vcff, key);
-    char *htmlKey = htmlEncode(key);
-    if (def != NULL)
-	printf("%s (%s)", htmlKey, def->description);
+    char *displayKey = words[i];
+    char *descKey = displayKey;
+    if (stripToSymbol)
+        {
+        char *p = strchr(displayKey, '<');
+        if (p)
+            {
+            descKey = cloneString(p+1);
+            p = strchr(descKey, '>');
+            if (p)
+                *p = '\0';
+            }
+        }
+    char *description = NULL;
+    struct vcfInfoDef *def;
+    for (def = infoDefs;  def != NULL;  def = def->next)
+        if (sameString(descKey, def->key))
+            {
+            description = def->description;
+            break;
+            }
+    char *htmlKey = htmlEncode(displayKey);
+    if (description)
+	printf("%s (%s)", htmlKey, description);
     else
 	printf("%s", htmlKey);
     }
 printf("<BR>\n");
 }
 
 static void vcfAltAlleleDetails(struct vcfRecord *rec, char **displayAls)
 /* If VCF header specifies any symbolic alternate alleles, pull in descriptions. */
 {
 printf("<B>Alternate allele(s):</B> ");
 if (rec->alleleCount < 2 || sameString(rec->alleles[1], "."))
     {
     printf(NA"<BR>\n");
     return;
     }
 struct vcfFile *vcff = rec->file;
-printKeysWithDescriptions(vcff, rec->alleleCount-1, &(displayAls[1]), vcff->altDefs);
+printKeysWithDescriptions(vcff, rec->alleleCount-1, &(displayAls[1]), vcff->altDefs, TRUE);
 }
 
 static void vcfQualDetails(struct vcfRecord *rec)
 /* If VCF header specifies a quality/confidence score (not "."), print it out. */
 {
 printf("<B>Quality/confidence score:</B> %s<BR>\n", sameString(rec->qual, ".") ? NA : rec->qual);
 }
 
 static void vcfFilterDetails(struct vcfRecord *rec)
 /* If VCF header specifies any filters, pull in descriptions. */
 {
 if (rec->filterCount == 0 || sameString(rec->filters[0], "."))
     printf("<B>Filter:</B> "NA"<BR>\n");
 else if (rec->filterCount == 1 && sameString(rec->filters[0], "PASS"))
     printf("<B>Filter:</B> PASS<BR>\n");
 else
     {
     printf("<B>Filter failures:</B> ");
     printf("<font style='font-weight: bold; color: #FF0000;'>\n");
     struct vcfFile *vcff = rec->file;
-    printKeysWithDescriptions(vcff, rec->filterCount, rec->filters, vcff->filterDefs);
+    printKeysWithDescriptions(vcff, rec->filterCount, rec->filters, vcff->filterDefs, FALSE);
     printf("</font>\n");
     }
 }
 
 static void vcfInfoDetails(struct vcfRecord *rec)
 /* Expand info keys to descriptions, then print out keys and values. */
 {
 if (rec->infoCount == 0)
     return;
 struct vcfFile *vcff = rec->file;
 puts("<B>INFO column annotations:</B><BR>");
 puts("<TABLE border=0 cellspacing=0 cellpadding=2>");
 int i;
 for (i = 0;  i < rec->infoCount;  i++)
     {
     struct vcfInfoElement *el = &(rec->infoElements[i]);
     const struct vcfInfoDef *def = vcfInfoDefForKey(vcff, el->key);
-    if (def == NULL)
-	continue;
     printf("<TR valign='top'><TD align=\"right\"><B>%s:</B></TD><TD style=width:15%%;'>",
            el->key);
     int j;
-    enum vcfInfoType type = def->type;
+    enum vcfInfoType type = def ? def->type : vcfInfoString;
     if (type == vcfInfoFlag && el->count == 0)
 	printf("Yes"); // no values, so we can't call vcfPrintDatum...
     // However, if this is older VCF, type vcfInfoFlag might have a value.
     for (j = 0;  j < el->count;  j++)
 	{
 	if (j > 0)
 	    printf(", ");
 	if (el->missingData[j])
 	    printf(".");
 	else
 	    vcfPrintDatum(stdout, el->values[j], type);
 	}
     if (def != NULL)
 	printf("&nbsp;&nbsp;</TD><TD>%s", def->description);
     else