2ab977674ff8aa920d078fa3c8e263298de74529
angie
  Mon Aug 17 15:54:37 2020 -0700
Prevent page from crashing just because the list of alts includes an IUPAC ambiguous character that vpGenomicToTranscript doesn't know how to deal with.  Use alpha channel for the highlighted samples so they don't hide the vertical guidelines.  refs #25943

diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c
index b7cb2e2..f04efae 100644
--- src/hg/hgTracks/vcfTrack.c
+++ src/hg/hgTracks/vcfTrack.c
@@ -2,30 +2,31 @@
 
 /* Copyright (C) 2014 The Regents of the University of California 
  * See README in this or parent directory 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 "iupac.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"
 
 // Russ Corbett-Detig suggested darker shades for coloring non-synonymous variants green
 Color darkerShadesOfGreenOnWhite[EXPR_DATA_SHADES];
 
 static boolean getMinQual(struct trackDb *tdb, double *retMinQual)
@@ -1062,30 +1063,33 @@
 struct bed3 variantBed3 = { NULL, chromName, rec->chromStart, rec->chromEnd };
 enum soTerm maxImpactTerm = soUnknown;
 struct txInfo *txi;
 for (txi = txiList;  txi != NULL;  txi = txi->next)
     {
     int alIx;
     // Sometimes reference allele is actually a change to the transcript
     for (alIx = 0;  alIx < rec->alleleCount;  alIx++)
         {
         char *allele = rec->alleles[alIx];
         // Watch out for weird symbolic alleles like "<INS:ME:ALU>".
         if (sameString(allele, "<DEL>"))
             allele = "";
         else if (allele[0] == '<')
             continue;
+        // Ignore IUPAC ambiguous values in alts (can leak in from hgPhyloPlace)
+        if (anyIupac(allele))
+            continue;
         struct vpTx *vpTx = vpGenomicToTranscript(gSeqWin, &variantBed3, allele,
                                                   txi->psl, txi->txSeq);
         struct vpPep *vpPep = vpTranscriptToProtein(vpTx, txi->cds, txi->txSeq, txi->protSeq);
         struct gpFx *gpFx = vpTranscriptToGpFx(vpTx, txi->psl, txi->cds, txi->txSeq, vpPep,
                                                txi->protSeq, lm);
         enum soTerm term = gpFx->soNumber;
         if (soTermCmp(&term, &maxImpactTerm) < 0)
             maxImpactTerm = term;
         vpPepFree(&vpPep);
         vpTxFree(&vpTx);
         }
     }
 lmCleanup(&lm);
 return maxImpactTerm;
 }
@@ -1955,31 +1959,31 @@
     hvGfxLine(hvg, x, minY, x, maxY, color);
     }
 else
     {
     // Leaf node -- draw a horizontal line, and label if there is space to right of tree
     struct nodeCoords *coords = node->priv;
     int yLine = yOff + ((0.5 + coords->rank) * pxPerHap);
     int yBox = yLine - pxPerHap / 2;
     int yText = yLine - tl.fontHeight / 2;
     // Dunno why but the default font seems to draw with the baseline at y while the other fonts
     // draw with the mid line at y.
     if (sameOk(tl.textSize, "8"))
         yText += 2;
     if (highlightSamples && node->ident->name && hashLookup(highlightSamples, node->ident->name))
         hvGfxBox(hvg, leftLabelX, yBox, leftLabelWidth, pxPerHap,
-                 MAKECOLOR_32(170, 255, 255));
+                 MAKECOLOR_32_A(170, 255, 255, 128));
     hvGfxLine(hvg, x, yLine, x+branchW, yLine, color);
     int textX = x + branchW + 3;
     if (pxPerHap >= tl.fontHeight+1 && textX < labelEnd)
         hvGfxText(hvg, textX, yText, MG_BLACK, font, node->ident->name);
     }
 }
 
 static void drawPhyloTreeInLabelArea(struct phyloTree *tree, struct hvGfx *hvg, int yOff,
                                      int clipHeight, int gtHapCount,
                                      MgFont *font, struct hash *highlightSamples)
 {
 struct hvGfx *hvgLL = (hvgSide != NULL) ? hvgSide : hvg;
 int clipXBak, clipYBak, clipWidthBak, clipHeightBak;
 hvGfxGetClip(hvgLL, &clipXBak, &clipYBak, &clipWidthBak, &clipHeightBak);
 hvGfxUnclip(hvgLL);
@@ -2001,31 +2005,31 @@
     {
     int ix;
     for (ix = 0;  ix < node->numEdges;  ix++)
         {
         struct phyloTree *child = node->edges[ix];
         rHighlightSampleRows(child, hvg, yOff, pxPerHap, highlightSamples);
         }
     }
 else
     {
     // leaf node; highlight if it's in highlightSamples
     if (node->ident->name && hashLookup(highlightSamples, node->ident->name))
         {
         struct nodeCoords *coords = node->priv;
         int y = yOff + (coords->rank * pxPerHap);
-        hvGfxBox(hvg, insideX, y, insideWidth, pxPerHap, MAKECOLOR_32(170, 255, 255));
+        hvGfxBox(hvg, insideX, y, insideWidth, pxPerHap, MAKECOLOR_32_A(170, 255, 255, 128));
         }
     }
 }
 
 struct hash *getHighlightSamples(struct trackDb *tdb)
 /* Return a hash of node IDs to highlight in the phylo tree display, or NULL if none specified. */
 {
 struct hash *highlightSamples = NULL;
 char *setting = cartOrTdbString(cart, tdb, "highlightIds", NULL);
 if (isNotEmpty(setting))
     {
     struct slName *list = slNameListFromComma(setting);
     highlightSamples = hashFromSlNameList(list);
     }
 return highlightSamples;