e745ccb794a88cf79f4e63a375a3eeb93e918563 braney Mon Jan 26 10:15:44 2026 -0800 move code to reverse exonFrames to calcLiftOverGenePred() so it will work with the liftOver tool diff --git src/hg/lib/liftOver.c src/hg/lib/liftOver.c index 8b7eafc1b84..d8bcafa986b 100644 --- src/hg/lib/liftOver.c +++ src/hg/lib/liftOver.c @@ -1072,31 +1072,31 @@ * through chain. This nulls out *pRangelist after modifying and freeing the contents. */ { *retError = NULL; /* See if best one is good enough. */ if (chain->score < minMatch * bedSize) *retError = "Partially deleted in new"; struct liftRange *rangeList = *pRangeList, *badRanges = NULL, *range; int thickStart = bed->thickStart; int thickEnd = bed->thickEnd; if (*retError == NULL) remapRangeList(chain, &rangeList, &thickStart, &thickEnd, minBlocks, fudgeThick, &rangeList, &badRanges, retError); /* Convert rangeList back to bed blocks. Also calculate start and end. */ -if (*retError == NULL) +if ((*retError == NULL) && (rangeList != NULL)) { int i, start, end = rangeList->end; if (chain->qStrand == '-') { rangeList = reverseRangeList(rangeList, chain->qSize); reverseIntRange(&thickStart, &thickEnd, chain->qSize); bed->strand[0] = otherStrand(bed->strand[0]); } bed->chromStart = start = rangeList->start; //if (slCount(rangeList) > 1) if (bed->blockSizes != NULL) { bed->blockCount = slCount(rangeList); for (i=0, range = rangeList; range != NULL; range = range->next, ++i) { @@ -1675,30 +1675,31 @@ } void calcLiftOverGenePreds( struct genePred *gpList, struct hash *chainHash, double minMatch, double minBlocks, bool fudgeThick, FILE *mapped, FILE *unmapped, boolean multiple, bool preserveInput) /* worker function for liftOverGenePred. */ { char *db = NULL, *chainTable = NULL; struct bed *bed; struct genePred *gp = NULL; char *error; for (gp = gpList ; gp != NULL ; gp = gp->next) { // uglyf("%s %s %d %d %s\n", gp->name, gp->chrom, gp->txStart, gp->txEnd, gp->strand); + char origStrand = gp->strand[0]; if (preserveInput) { char *old = gp->name; gp->name = extendNameWithPosition(gp->name, gp->chrom, gp->txStart, gp->txEnd, TRUE); free(old); // genePredExtLoadAll uses cloneString to populate this } bed = genePredToBed(gp); error = remapBlockedBed(chainHash, bed, minMatch, minBlocks, fudgeThick, multiple, db, chainTable); if (error) { gp->chrom = NULL; // this gp didn't get lifted so we want to make sure the caller can figure that out bedFree(&bed); if (unmapped) { @@ -1706,43 +1707,46 @@ genePredTabOut(gp, unmapped); } } else { int exonCount = gp->exonCount; struct bed *bedList = bed; for (; bed != NULL; bed = bed->next) { if (bed->blockCount > exonCount) errAbort("program error: need to allocate extra blocks for bed."); freeMem(gp->chrom); gp->chrom = cloneString(bed->chrom); int start = gp->txStart = bed->chromStart; gp->txEnd = bed->chromEnd; - gp->origStrand = gp->strand[0]; + //gp->origStrand = gp->strand[0]; gp->strand[0] = bed->strand[0]; gp->cdsStart = bed->thickStart; gp->cdsEnd = bed->thickEnd; int count = gp->exonCount = bed->blockCount; int i; for (i=0; i<count; ++i) { int s = start + bed->chromStarts[i]; int e = s + bed->blockSizes[i]; gp->exonStarts[i] = s; gp->exonEnds[i] = e; } + if (gp->strand[0] != origStrand) + genePredReverseFrames(gp); + if (mapped) genePredTabOut(gp, mapped); } bedFreeList(&bedList); } } } void liftOverGenePred(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, bool fudgeThick, FILE *mapped, FILE *unmapped, boolean multiple, bool preserveInput) { calcLiftOverGenePreds(genePredExtLoadAll(fileName), chainHash, minMatch, minBlocks, fudgeThick, mapped, unmapped, multiple, preserveInput); }