74badd35b7df2aef1be18519fb05beda8af1a4e4
angie
  Mon Jul 10 16:45:24 2023 -0700
Doh, forgot to deal with strand in codonVpTxToAaChange, but MPXV has strands.

diff --git src/hg/hgPhyloPlace/treeToAuspiceJson.c src/hg/hgPhyloPlace/treeToAuspiceJson.c
index 8de17ee..6f4aeb8 100644
--- src/hg/hgPhyloPlace/treeToAuspiceJson.c
+++ src/hg/hgPhyloPlace/treeToAuspiceJson.c
@@ -403,42 +403,45 @@
                                           struct geneInfo *gi)
 /* Given a list of vpTx from the same codon, combine their changes with inherited mutations
  * in the same codon to get the amino acid change at this node.
  * Note: this assumes there is no UTR in transcript, only CDS.  True so far for pathogens... */
 {
 struct slName *aaChange = NULL;
 if (codonVpTxList != NULL)
     {
     struct vpTx *vpTx = codonVpTxList;
     int firstAaStart = vpTx->start.txOffset / 3;
     int codonStart = firstAaStart * 3;
     int codonOffset = vpTx->start.txOffset - codonStart;
     char oldCodon[4];
     safencpy(oldCodon, sizeof oldCodon, gi->txSeq->dna + codonStart, 3);
     touppers(oldCodon);
-    int codonStartG = vpTx->start.gOffset - codonOffset;
+    boolean isRc = (pslOrientation(gi->psl) < 0);
+    int codonStartG = isRc ? vpTx->start.gOffset + codonOffset : vpTx->start.gOffset - codonOffset;
     struct singleNucChange *anc;
     for (anc = ancestorMuts;  anc != NULL;  anc = anc->next)
         {
-        int ancCodonOffset = anc->chromStart - codonStartG;
+        int ancCodonOffset = isRc ? codonStartG - (anc->chromStart + 1) : anc->chromStart - codonStartG;
         if (ancCodonOffset >= 0 && ancCodonOffset < 3)
             {
-            if (anc->parBase != oldCodon[ancCodonOffset])
+            char parBase = isRc ? ntCompTable[(int)anc->parBase] : anc->parBase;
+            if (parBase != oldCodon[ancCodonOffset])
                 errAbort("codonVpTxToAaChange: expected parBase for ancestral mutation at %d "
-                         "(%s codon %d offset %d) to be '%c' but it's '%c'",
+                         "(%s codon %d offset %d) to be '%c' but it's '%c'%s",
                          anc->chromStart+1, gi->psl->qName, firstAaStart, ancCodonOffset,
-                         oldCodon[ancCodonOffset], anc->parBase);
+                         oldCodon[ancCodonOffset], parBase,
+                         isRc ? " (rev-comp'd)" : "");
             oldCodon[ancCodonOffset] = maybeComplement(anc->newBase, gi->psl);
             }
         }
     char oldAa = lookupCodon(oldCodon);
     if (oldAa == '\0')
         oldAa = '*';
     char newCodon[4];
     safecpy(newCodon, sizeof newCodon, oldCodon);
     for (vpTx = codonVpTxList;  vpTx != NULL;  vpTx = vpTx->next)
         {
         int aaStart = vpTx->start.txOffset / 3;
         if (aaStart != firstAaStart)
             errAbort("codonVpTxToAaChange: program error: firstAaStart %d != aaStart %d",
                      firstAaStart, aaStart);
         int codonOffset = vpTx->start.txOffset - codonStart;