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/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index 7a2b788..7e0f84b 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -820,87 +820,92 @@ struct linkedFeatures *lf = item; return pcrResultItemAccName(lf->name, lf->extra, (struct psl *)lf->original); } void pcrResultLoad(struct track *tg) /* Load locations of primer matches into linkedFeatures items. */ { char *pslFileName, *primerFileName; struct targetDb *target; if (! pcrResultParseCart(database, cart, &pslFileName, &primerFileName, &target)) return; /* Don't free psl -- used in drawing phase by baseColor code. */ struct psl *pslList = pslLoadAll(pslFileName), *psl; struct linkedFeatures *itemList = NULL; -if (target != NULL) - { - int rowOffset = hOffsetPastBin(database, chromName, target->pslTable); struct sqlConnection *conn = hAllocConn(database); struct sqlResult *sr; +for (psl = pslList; psl != NULL; psl = psl->next) + { + // pcr result matches to a targetDb are of the format transcript__gene + if (stringIn("__", psl->tName)) + { + int rowOffset = hOffsetPastBin(database, chromName, target->pslTable); char **row; char query[2048]; - struct psl *tpsl; - for (tpsl = pslList; tpsl != NULL; tpsl = tpsl->next) - { - char *itemAcc = pcrResultItemAccession(tpsl->tName); - char *itemName = pcrResultItemName(tpsl->tName); + char *itemAcc = pcrResultItemAccession(psl->tName); + char *itemName = pcrResultItemName(psl->tName); /* Query target->pslTable to get target-to-genomic mapping: */ sqlSafef(query, sizeof(query), "select * from %s where qName = '%s'", target->pslTable, itemAcc); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { struct psl *gpsl = pslLoad(row+rowOffset); if (sameString(gpsl->tName, chromName) && gpsl->tStart < winEnd && gpsl->tEnd > winStart) { - struct psl *trimmed = pslTrimToQueryRange(gpsl, tpsl->tStart, - tpsl->tEnd); + struct psl *trimmed = pslTrimToQueryRange(gpsl, psl->tStart, + psl->tEnd); struct linkedFeatures *lf; char *targetStyle = cartUsualString(cart, PCR_RESULT_TARGET_STYLE, PCR_RESULT_TARGET_STYLE_DEFAULT); if (sameString(targetStyle, PCR_RESULT_TARGET_STYLE_TALL)) { lf = lfFromPslx(gpsl, 1, FALSE, FALSE, tg); lf->tallStart = trimmed->tStart; lf->tallEnd = trimmed->tEnd; } else { lf = lfFromPslx(trimmed, 1, FALSE, FALSE, tg); } lf->name = cloneString(itemAcc); char extraInfo[512]; safef(extraInfo, sizeof(extraInfo), "%s|%d|%d", - (itemName ? itemName : ""), tpsl->tStart, tpsl->tEnd); + (itemName ? itemName : ""), psl->tStart, psl->tEnd); lf->extra = cloneString(extraInfo); + // now that there may be more than one primer pair result + // in the pcrResults list, we need make sure we are using the + // right primer pair later + ((struct psl *)(lf->original))->qName = cloneString(psl->qName); slAddHead(&itemList, lf); } } } - hFreeConn(&conn); - } else - for (psl = pslList; psl != NULL; psl = psl->next) + { if (sameString(psl->tName, chromName) && psl->tStart < winEnd && psl->tEnd > winStart) { struct linkedFeatures *lf = lfFromPslx(psl, 1, FALSE, FALSE, tg); lf->name = cloneString(""); lf->extra = cloneString(""); lf->original = psl; slAddHead(&itemList, lf); } + } + } +hFreeConn(&conn); slSort(&itemList, linkedFeaturesCmp); tg->items = itemList; } char *pcrResultTrackItemName(struct track *tg, void *item) /* If lf->extra is non-empty, return it (display name for item). * Otherwise default to item name. */ { struct linkedFeatures *lf = item; char *extra = (char *)lf->extra; if (isNotEmpty(extra)) { static char displayName[512]; safecpy(displayName, sizeof(displayName), extra); char *ptr = strchr(displayName, '|');