fd802431971bf493181727133d48e13beea7d74e markd Sun May 14 19:28:01 2023 -0700 as long as hood is up, make pslTransMap function thread-safe diff --git src/lib/pslTransMap.c src/lib/pslTransMap.c index 555140e..dd89577 100644 --- src/lib/pslTransMap.c +++ src/lib/pslTransMap.c @@ -58,45 +58,30 @@ static void pslProtToNA(struct psl *psl) /* convert a protein/NA alignment to a NA/NA alignment */ { int iBlk; psl->qStart *= 3; psl->qEnd *= 3; psl->qSize *= 3; for (iBlk = 0; iBlk < psl->blockCount; iBlk++) { psl->blockSizes[iBlk] *= 3; psl->qStarts[iBlk] *= 3; } } -static void pslNAToProt(struct psl *psl) -/* undo pslProtToNA */ -{ -int iBlk; - -psl->qStart /= 3; -psl->qEnd /= 3; -psl->qSize /= 3; -for (iBlk = 0; iBlk < psl->blockCount; iBlk++) - { - psl->blockSizes[iBlk] /= 3; - psl->qStarts[iBlk] /= 3; - } -} - static struct psl* createMappedPsl(struct psl* inPsl, struct psl *mapPsl, int mappedPslMax) /* setup a PSL for the output alignment */ { char strand[3]; assert(pslTStrand(inPsl) == pslQStrand(mapPsl)); /* strand can be taken from both alignments, since common sequence is in same * orientation. */ strand[0] = pslQStrand(inPsl); strand[1] = pslTStrand(mapPsl); strand[2] = '\n'; return pslNew(inPsl->qName, inPsl->qSize, 0, 0, mapPsl->tName, mapPsl->tSize, 0, 0, @@ -306,62 +291,59 @@ { struct block align1Blk = blockFromPslBlock(inPsl, iBlock); while (mapBlock(inPsl, mapPsl, &iMapBlk, &align1Blk, mappedPsl, &mappedPslMax)) continue; } assert(mappedPsl->blockCount <= mappedPslMax); return mappedPsl; } struct psl* pslTransMap(unsigned opts, struct psl *inPsl, struct psl *mapPsl) /* map a psl via a mapping psl, a single psl is returned, or NULL if it * couldn't be mapped. */ { -char inPslOrigStrand[3]; boolean rcInPsl = (pslTStrand(inPsl) != pslQStrand(mapPsl)); -boolean cnv1 = (pslIsProtein(inPsl) && !pslIsProtein(mapPsl)); -boolean cnv2 = (pslIsProtein(mapPsl) && !pslIsProtein(inPsl)); +boolean cnvIn = (pslIsProtein(inPsl) && !pslIsProtein(mapPsl)); +boolean cnvMap = (pslIsProtein(mapPsl) && !pslIsProtein(inPsl)); /* sanity check size, but allow names to vary to allow ids to have * unique-ifying suffixes. */ if (inPsl->tSize != mapPsl->qSize) errAbort("Error: inPsl %s tSize (%d) != mapPsl %s qSize (%d)", inPsl->tName, inPsl->tSize, mapPsl->qName, mapPsl->qSize); -/* convert protein PSLs */ -if (cnv1) - pslProtToNA(inPsl); -if (cnv2) - pslProtToNA(mapPsl); - -/* need to ensure common sequence is in same orientation, save strand for later */ +/* ensure common sequence is in same orientation and convert protein PSLs */ +char inPslOrigStrand[3]; safef(inPslOrigStrand, sizeof(inPslOrigStrand), "%s", inPsl->strand); +if (cnvIn || rcInPsl) + inPsl = pslClone(inPsl); +if (cnvIn) + pslProtToNA(inPsl); if (rcInPsl) pslRc(inPsl); +if (cnvMap) + { + mapPsl = pslClone(mapPsl); + pslProtToNA(mapPsl); + } struct psl* mappedPsl = doMapping(inPsl, mapPsl); /* finish up psl, or free if no blocks were added */ if (mappedPsl->blockCount == 0) pslFree(&mappedPsl); /* nothing made it */ else { setPslBoundsCounts(mappedPsl); adjustOrientation(opts, inPsl, inPslOrigStrand, mappedPsl); } -/* restore input */ -if (rcInPsl) - { - pslRc(inPsl); - strcpy(inPsl->strand, inPslOrigStrand); - } -if (cnv1) - pslNAToProt(inPsl); -if (cnv2) - pslNAToProt(mapPsl); +if (cnvIn || rcInPsl) + pslFree(&inPsl); +if (cnvMap) + pslFree(&mapPsl); return mappedPsl; }