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)