static char getPslTSideStrand(struct psl *psl) /* get the strand to use for a PSL when doing target side overlaps */ { if (psl->strand[1] != '\0') { // translated char strand = pslTStrand(psl); if (pslQStrand(psl) == '-') strand = (strand == '-') ? '+' : '-'; // query reverse complemented return strand; } else return pslQStrand(psl); // untranslated }
static void addPslToChained(struct psl* chainedPsl, struct psl* nextPsl, int insertIdx) /* add blocks form a psl to the chained psl at the given point */ { assert(insertIdx <= chainedPsl->blockCount); // expand arrays and copy in entries pslArrayInsert(&chainedPsl->blockSizes, chainedPsl->blockCount, nextPsl->blockSizes, nextPsl->blockCount, insertIdx); pslArrayInsert(&chainedPsl->qStarts, chainedPsl->blockCount, nextPsl->qStarts, nextPsl->blockCount, insertIdx); pslArrayInsert(&chainedPsl->tStarts, chainedPsl->blockCount, nextPsl->tStarts, nextPsl->blockCount, insertIdx); chainedPsl->blockCount += nextPsl->blockCount; // update bounds if needed if (pslQStrand(chainedPsl) == '+') { chainedPsl->qStart = pslQStartStrand(chainedPsl, 0, '+'); chainedPsl->qEnd = pslQEndStrand(chainedPsl, chainedPsl->blockCount-1, '+'); } else { chainedPsl->qStart = pslQStartStrand(chainedPsl, chainedPsl->blockCount-1, '+'); chainedPsl->qEnd = pslQEndStrand(chainedPsl, 0, '+'); } assert(pslTStrand(chainedPsl) == '+'); chainedPsl->tStart = pslTStartStrand(chainedPsl, 0, '+'); chainedPsl->tEnd = pslTEndStrand(chainedPsl, chainedPsl->blockCount-1, '+'); // update counts chainedPsl->match += nextPsl->match; chainedPsl->misMatch += nextPsl->misMatch; chainedPsl->repMatch += nextPsl->repMatch; chainedPsl->nCount += nextPsl->nCount; }
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, strand, mappedPslMax, 0); }
static void liftIt(struct psl *psl, struct hash *qSizes, struct hash *tSizes) /* lift one subrange PSL based on tName */ { if (qSizes != NULL) liftSide("qName", qSizes, psl, psl->qName, pslQStrand(psl), &psl->qSize, &psl->qStart, &psl->qEnd, psl->qStarts); if (tSizes != NULL) liftSide("tName", tSizes, psl, psl->tName, pslTStrand(psl), &psl->tSize, &psl->tStart, &psl->tEnd, psl->tStarts); }
static void setPslBounds(struct psl* mappedPsl) /* set sequences bounds on mapped PSL */ { int lastBlk = mappedPsl->blockCount-1; /* set start/end of sequences */ mappedPsl->qStart = mappedPsl->qStarts[0]; mappedPsl->qEnd = mappedPsl->qStarts[lastBlk] + mappedPsl->blockSizes[lastBlk]; if (pslQStrand(mappedPsl) == '-') reverseIntRange(&mappedPsl->qStart, &mappedPsl->qEnd, mappedPsl->qSize); mappedPsl->tStart = mappedPsl->tStarts[0]; mappedPsl->tEnd = mappedPsl->tStarts[lastBlk] + mappedPsl->blockSizes[lastBlk]; if (pslTStrand(mappedPsl) == '-') reverseIntRange(&mappedPsl->tStart, &mappedPsl->tEnd, mappedPsl->tSize); }
static void addPslBlocks(struct chromAnn* ca, unsigned opts, struct psl* psl) /* add blocks from a psl */ { boolean blkStrand = (opts & chromAnnUseQSide) ? pslQStrand(psl) : pslTStrand(psl); int size = (opts & chromAnnUseQSide) ? psl->qSize : psl->tSize; unsigned *blocks = (opts & chromAnnUseQSide) ? psl->qStarts : psl->tStarts; boolean blkSizeMult = pslIsProtein(psl) ? 3 : 1; int iBlk; for (iBlk = 0; iBlk < psl->blockCount; iBlk++) { int start = blocks[iBlk]; int end = start + (blkSizeMult * psl->blockSizes[iBlk]); if (blkStrand == '-') reverseIntRange(&start, &end, size); chromAnnBlkNew(ca, start, end); } }
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. */ { int mappedPslMax = 8; /* allocated space in output psl */ int iMapBlk = 0; char inPslOrigStrand[3]; boolean rcInPsl = (pslTStrand(inPsl) != pslQStrand(mapPsl)); boolean cnv1 = (pslIsProtein(inPsl) && !pslIsProtein(mapPsl)); boolean cnv2 = (pslIsProtein(mapPsl) && !pslIsProtein(inPsl)); int iBlock; struct psl* mappedPsl; /* 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 */ safef(inPslOrigStrand, sizeof(inPslOrigStrand), "%s", inPsl->strand); if (rcInPsl) pslRc(inPsl); mappedPsl = createMappedPsl(inPsl, mapPsl, mappedPslMax); /* Fill in ungapped blocks. */ for (iBlock = 0; iBlock < inPsl->blockCount; iBlock++) { struct block align1Blk = blockFromPslBlock(inPsl, iBlock); while (mapBlock(inPsl, mapPsl, &iMapBlk, &align1Blk, mappedPsl, &mappedPslMax)) continue; } /* finish up psl, or free if no blocks were added */ assert(mappedPsl->blockCount <= mappedPslMax); if (mappedPsl->blockCount == 0) pslFree(&mappedPsl); /* nothing made it */ else { setPslBounds(mappedPsl); adjustOrientation(opts, inPsl, inPslOrigStrand, mappedPsl); } /* restore input */ if (rcInPsl) { pslRc(inPsl); strcpy(inPsl->strand, inPslOrigStrand); } if (cnv1) pslNAToProt(inPsl); if (cnv2) pslNAToProt(mapPsl); return mappedPsl; }