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/hgc/hgc.c src/hg/hgc/hgc.c index 2d4b10c..c8ca223 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -7024,40 +7024,40 @@ pslFree(&itemPsl); pslFreeList(&otherPsls); } static void upperMatch(char *dna, char *primer, int size) /* Uppercase DNA where it matches primer. -- copied from gfPcrLib.c. */ { int i; for (i=0; itEnd - psl->tStart; char *ffPrimer = cloneString(fPrimer); char *rrPrimer = cloneString(rPrimer); int rPrimerSize = strlen(rPrimer); struct dnaSeq *seq; -if (target != NULL) +if (stringIn("__", item) && target != NULL) { /* Use seq+extFile if specified; otherwise just retrieve from seqFile. */ if (isNotEmpty(target->seqTable) && isNotEmpty(target->extFileTable)) { struct sqlConnection *conn = hAllocConn(database); seq = hDnaSeqGet(database, psl->tName, target->seqTable, target->extFileTable); hFreeConn(&conn); char *dna = cloneStringZ(seq->dna + psl->tStart, productSize); freeMem(seq->dna); seq->dna = dna; } else { struct twoBitFile *tbf = twoBitOpen(target->seqFile); @@ -7084,102 +7084,133 @@ productSize, fPrimer, rPrimer); /* Flip reverse primer to be in same direction and case as sequence, to * compare with sequence: */ reverseComplement(rrPrimer, rPrimerSize); tolowers(rrPrimer); tolowers(ffPrimer); /* Capitalize where sequence and primer match, and write out sequence. */ upperMatch(dna, ffPrimer, strlen(ffPrimer)); upperMatch(dna + productSize - rPrimerSize, rrPrimer, rPrimerSize); faWriteNext(stdout, NULL, dna, productSize); printf(""); } +static void pslFileGetPrimers(char *pslFileName, char *transcript, char **retFPrimer, char **retRPrimer) +/* Use a psl file to get primers associated with the transcript */ +{ +char *pslFields[21]; +struct lineFile *lf = lineFileOpen(pslFileName, TRUE); +char *target = cloneString(transcript); +char *pipe = strchr(target, '|'); +*pipe = '\0'; +while (lineFileRow(lf, pslFields)) + { + struct psl *psl = pslLoad(pslFields); + if (sameString(psl->tName, target)) + { + char *pair = psl->qName; + char *under = strchr(pair, '_'); + *under = '\0'; + *retFPrimer = cloneString(pair); + *retRPrimer = cloneString(under+1); + break; + } + } +lineFileClose(&lf); +} + void doPcrResult(char *track, char *item) /* Process click on PCR of user's primers. */ { struct trackDb *tdb = pcrResultFakeTdb(); char *pslFileName, *primerFileName; struct targetDb *target; cartWebStart(cart, database, "PCR Results"); if (! pcrResultParseCart(database, cart, &pslFileName, &primerFileName, &target)) errAbort("PCR Result track has disappeared!"); char *fPrimer, *rPrimer; +boolean targetSearch = stringIn("__", item) != NULL; +if (targetSearch) + { + // use the psl file to find the right primer pair + pslFileGetPrimers(pslFileName, item, &fPrimer, &rPrimer); + } +else + { // the item name contains the forward and reverse primers int maxSplits = 2; char *splitQName[maxSplits]; int numSplits = chopString(cloneString(item), "_", splitQName, sizeof(splitQName)); if (numSplits == maxSplits) { fPrimer = splitQName[0]; touppers(fPrimer); rPrimer = splitQName[1]; touppers(rPrimer); } -else - pcrResultGetPrimers(primerFileName, &fPrimer, &rPrimer); + } printf("

PCR Results (%s %s)

\n", fPrimer, rPrimer); printf("Forward primer: 5' %s 3'
\n", fPrimer); printf("Reverse primer: 5' %s 3'
\n", rPrimer); -if (target != NULL) +if (targetSearch) printf("Search target: %s
\n", target->description); struct psl *itemPsl = NULL, *otherPsls = NULL, *psl; -if (target != NULL) +if (targetSearch) { /* item (from hgTracks) is |-separated: target sequence name, * amplicon start offset in target sequence, and amplicon end offset. */ char *words[3]; int wordCount = chopByChar(cloneString(item), '|', words, ArraySize(words)); if (wordCount != 3) errAbort("doPcrResult: expected 3 |-sep'd words but got '%s'", item); char *targetSeqName = words[0]; if (endsWith(targetSeqName, "__")) targetSeqName[strlen(targetSeqName)-2] = '\0'; int ampStart = atoi(words[1]), ampEnd = atoi(words[2]); pcrResultGetPsl(pslFileName, target, targetSeqName, seqName, ampStart, ampEnd, - &itemPsl, &otherPsls); + &itemPsl, &otherPsls, fPrimer, rPrimer); printPcrTargetMatch(target, itemPsl, TRUE); } else { - pcrResultGetPsl(pslFileName, target, item, + pcrResultGetPsl(pslFileName, NULL, item, seqName, cartInt(cart, "o"), cartInt(cart, "t"), - &itemPsl, &otherPsls); + &itemPsl, &otherPsls, fPrimer, rPrimer); printPosOnChrom(itemPsl->tName, itemPsl->tStart, itemPsl->tEnd, itemPsl->strand, FALSE, NULL); } if (otherPsls != NULL) { puts("
"); printf("Other matches for these primers:
\n"); for (psl = otherPsls; psl != NULL; psl = psl->next) { puts("
"); if (target != NULL) printPcrTargetMatch(target, psl, FALSE); else printPosOnChrom(psl->tName, psl->tStart, psl->tEnd, psl->strand, FALSE, NULL); } puts("
"); } -printPcrSequence(target, itemPsl, fPrimer, rPrimer); +printPcrSequence(item, target, itemPsl, fPrimer, rPrimer); puts("

"); printTrackHtml(tdb); } void doUserPsl(char *track, char *item) /* Process click on user-defined alignment. */ { int start = cartInt(cart, "o"); struct lineFile *lf; struct psl *pslList = NULL, *psl; char *pslName, *faName, *qName; enum gfType qt, tt; cartWebStart(cart, database, "BLAT Search Alignments");