b83116855bd919a0da2b417f07d4473828c94845
angie
  Wed Oct 20 13:37:23 2021 -0700
Oops, lookupCodon returns '\0' for stop codon but we want to display '*'.  Reported by Cornelius Roemer in https://github.com/yatisht/usher/issues/178

diff --git src/hg/hgPhyloPlace/treeToAuspiceJson.c src/hg/hgPhyloPlace/treeToAuspiceJson.c
index 9297fa9..f704622 100644
--- src/hg/hgPhyloPlace/treeToAuspiceJson.c
+++ src/hg/hgPhyloPlace/treeToAuspiceJson.c
@@ -260,53 +260,58 @@
 }
 
 static boolean changesProtein(struct singleNucChange *snc, struct geneInfo *gi,
                               struct seqWindow *gSeqWin,
                               int *retAaStart, char *retOldAa, char *retNewAa)
 /* If snc changes the coding sequence of gene, return TRUE and set ret values accordingly
  * (note amino acid values are single-base not strings). */
 {
 boolean isCodingChange = FALSE;
 if (snc->chromStart < gi->psl->tEnd && snc->chromStart >= gi->psl->tStart)
     {
     struct bed3 gBed3 = { NULL, chrom, snc->chromStart, snc->chromStart+1 };
     char gAlt[2];
     safef(gAlt, sizeof(gAlt), "%c", snc->newBase);
     if (!sameString(gi->psl->strand, "+"))
-        errAbort("changesProtein: only worlds for psl->strand='+', but gene '%s' has strand '%s'",
+        errAbort("changesProtein: only works for psl->strand='+', but gene '%s' has strand '%s'",
                  gi->psl->qName, gi->psl->strand);
     struct vpTx *vpTx = vpGenomicToTranscript(gSeqWin, &gBed3, gAlt, gi->psl, gi->txSeq);
     if (vpTx->start.region == vpExon)
         {
         int aaStart = vpTx->start.txOffset / 3;
         int codonStart = aaStart * 3;
         char newCodon[4];
         safencpy(newCodon, sizeof newCodon, gi->txSeq->dna + codonStart, 3);
         int codonOffset = vpTx->start.txOffset - codonStart;
         assert(codonOffset < sizeof newCodon);
         newCodon[codonOffset] = snc->newBase;
         char newAa = lookupCodon(newCodon);
         char oldAa;
         if (snc->parBase == snc->refBase)
             oldAa = lookupCodon(gi->txSeq->dna + codonStart);
         else
             {
             char oldCodon[4];
             safencpy(oldCodon, sizeof oldCodon, gi->txSeq->dna + codonStart, 3);
             oldCodon[codonOffset] = snc->parBase;
             oldAa = lookupCodon(oldCodon);
             }
+        // Watch out for lookupCodon's null-character return value for stop codon; we want '*'.
+        if (newAa == '\0')
+            newAa = '*';
+        if (oldAa == '\0')
+            oldAa = '*';
         if (newAa != oldAa)
             {
             isCodingChange = TRUE;
             *retAaStart = aaStart;
             *retOldAa = oldAa;
             *retNewAa = newAa;
             }
         }
     vpTxFree(&vpTx);
     }
 return isCodingChange;
 }
 
 struct slPair *getAaMutations(struct singleNucChange *sncList, struct geneInfo *geneInfoList,
                               struct seqWindow *gSeqWin)