d3aaebb71ef2b82ece4340766c0de67541ce7362
chmalee
  Wed Jul 5 16:41:56 2023 -0700
Fix for multiple hgPcr results feature, actually use the stored primer pair in the psl qName, refs #31608

diff --git src/hg/cgilib/pcrResult.c src/hg/cgilib/pcrResult.c
index c8f67a5..655f280 100644
--- src/hg/cgilib/pcrResult.c
+++ src/hg/cgilib/pcrResult.c
@@ -58,82 +58,106 @@
     {
     cartRemove(cart, cartVar);
     setPtIfNotNull(retPslFile, NULL);
     setPtIfNotNull(retPrimerFile, NULL);
     setPtIfNotNull(retTarget, NULL);
     return FALSE;
     }
 setPtIfNotNull(retPslFile, cloneString(pslFile));
 setPtIfNotNull(retPrimerFile, cloneString(primerFile));
 setPtIfNotNull(retTarget, target);
 if (retTarget == NULL)
     targetDbFreeList(&target);
 return TRUE;
 }
 
-void pcrResultGetPrimers(char *fileName, char **retFPrimer, char **retRPrimer)
+void pcrResultGetPrimers(char *fileName, char **retFPrimer, char **retRPrimer, char *primerKey)
 /* Given a file whose first line is 2 words (forward primer, reverse primer)
- * set the ret's to upper-cased primer sequences.  
+ * set the ret's to upper-cased primer sequences. If primerKey is non NULL, the
+ * first two words of the line joined with "_" must equal the primerKey:
+ * primerKey == word1_word2
+ * Used when there are multiple pcr results in a single track
  * Do not free the statically allocated ret's. */
 {
 static char fPrimer[1024], rPrimer[1024];;
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
+struct dyString *primerPair = dyStringNew(0);
 char *words[2];
-if (! lineFileRow(lf, words))
-    lineFileAbort(lf, "Couldn't read primers");
+while (lineFileRow(lf, words))
+    {
+    dyStringClear(primerPair);
+    dyStringPrintf(primerPair, "%s_%s", words[0], words[1]);
+    if (!primerKey || (primerKey && sameString(primerPair->string, primerKey)))
+        {
         if (retFPrimer != NULL)
             {
             safecpy(fPrimer, sizeof(fPrimer), words[0]);
             touppers(fPrimer);
             *retFPrimer = fPrimer;
             }
         if (retRPrimer != NULL)
             {
             safecpy(rPrimer, sizeof(rPrimer), words[1]);
             touppers(rPrimer);
             *retRPrimer = rPrimer;
             }
+        break;
+        }
+    }
+dyStringFree(&primerPair);
 lineFileClose(&lf);
 }
 
 void pcrResultGetPsl(char *fileName, struct targetDb *target, char *item,
 		     char *chrom, int itemStart, int itemEnd,
-		     struct psl **retItemPsl, struct psl **retOtherPsls)
+		     struct psl **retItemPsl, struct psl **retOtherPsls, char *fPrimer, char *rPrimer)
 /* Read in psl from file.  If a psl matches the given item position, set 
  * retItemPsl to that; otherwise add it to retOtherPsls.  Die if no psl
  * matches the given item position. */
 {
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 struct psl *itemPsl = NULL, *otherPsls = NULL;
 char *pslFields[21];
+boolean targetSearchResult = stringIn("__", item) != NULL;
 while (lineFileRow(lf, pslFields))
     {
     struct psl *psl = pslLoad(pslFields);
     boolean gotIt = FALSE;
-    if (target != NULL)
+    char *pair = cloneString(psl->qName);
+    char *under = strchr(pair, '_');
+    *under = '\0';
+    char *thisFPrimer = pair;
+    char *thisRPrimer = under+1;
+    if (!differentWord(thisFPrimer, fPrimer) && !differentWord(thisRPrimer, rPrimer))
+        {
+        if (targetSearchResult)
             {
             if (sameString(psl->tName, item) && psl->tStart == itemStart && psl->tEnd == itemEnd)
                 gotIt = TRUE;
             }
         else if (sameString(psl->tName, chrom) && psl->tStart == itemStart &&
                  psl->tEnd == itemEnd)
+            {
             gotIt = TRUE;
+            }
+
         if (gotIt)
             itemPsl = psl;
         else
             slAddHead(&otherPsls, psl);
         }
+    }
 lineFileClose(&lf);
 if (itemPsl == NULL)
     {
     if (target != NULL)
         errAbort("Did not find record for amplicon in %s sequence %s",
              target->description, item);
     else
         errAbort("Did not find record for amplicon at %s:%d-%d",
              chrom, itemStart, itemEnd);
     }
 if (retItemPsl != NULL)
     *retItemPsl = itemPsl;
 else
     pslFree(&itemPsl);
 if (retOtherPsls != NULL)