13324df7d810e3cd1d64d93e8f83de7f7611e473 hiram Fri Sep 25 18:55:52 2026 -0700 claude found and error in the code and added a test for the bug refs #34360 diff --git src/utils/pafToPsl/pafToPsl.c src/utils/pafToPsl/pafToPsl.c index bceab7ac11f..68eef244f4c 100644 --- src/utils/pafToPsl/pafToPsl.c +++ src/utils/pafToPsl/pafToPsl.c @@ -140,53 +140,61 @@ pushBlock(psl, blockSpace, qPos-lens, tPos-lens, lens); if (qPos != psl->qEnd - psl->qStart) { warn("%s:%d: CIGAR length does not match alignment length (query): %d != %d", fileName, lineIx, psl->qEnd - psl->qStart, qPos); return FALSE; } if (tPos != psl->tEnd - psl->tStart) { warn("%s:%d: CIGAR length does not match alignment length (target): %d != %d", fileName, lineIx, psl->tEnd - psl->tStart, tPos); return FALSE; } +// block offsets computed above are measured from position 0 of the CIGAR, +// which is the *untrimmed* qStart/tStart the PAF reported -- save those +// before trimming for leading/trailing indels below, so the shift to +// absolute coordinates doesn't double-count the trim. +int origQStart = psl->qStart; +int origQEnd = psl->qEnd; +int origTStart = psl->tStart; + // handle leading and trailing indels: PSL blocks must start and end on a match if (insl > 0) { qNumInsert -= 1; qBaseInsert -= insl; psl->qStart += insl; } else if (insl < 0) { tNumInsert -= 1; tBaseInsert += insl; psl->tStart -= insl; } if (insr > 0) { qNumInsert -= 1; qBaseInsert -= insr; psl->qEnd -= insr; } else if (insr < 0) { tNumInsert -= 1; tBaseInsert += insr; psl->tEnd += insr; } // shift target block positions to absolute target coordinates for (i = 0; i < psl->blockCount; i++) - psl->tStarts[i] += psl->tStart; + psl->tStarts[i] += origTStart; // shift query block positions to absolute coordinates, taking the query // strand into account if (psl->strand[0] == '-') for (i = 0; i < psl->blockCount; i++) - psl->qStarts[i] = psl->qSize - psl->qEnd + psl->qStarts[i]; + psl->qStarts[i] = psl->qSize - origQEnd + psl->qStarts[i]; else for (i = 0; i < psl->blockCount; i++) - psl->qStarts[i] += psl->qStart; + psl->qStarts[i] += origQStart; psl->qNumInsert = qNumInsert; psl->qBaseInsert = qBaseInsert; psl->tNumInsert = tNumInsert; psl->tBaseInsert = tBaseInsert; int misMatch = psl->qEnd - psl->qStart - qBaseInsert - (int)psl->match; if (misMatch < 0) { warn("%s:%d: negative misMatch value: %d", fileName, lineIx, misMatch); return FALSE; } psl->misMatch = misMatch; lens = 0;