4942ea5baf9a2b0f232b08e69fa9969fe640b925 angie Mon Mar 14 16:57:17 2022 -0700 Thanks Lou for a test case (mm39 rs3399875136, NM_146282.2) in which a frameshifting deletion causes a stop loss but the transcript has no 3'UTR sequence so we cannot find a new stop codon. Instead, truncated predicted sequence led to incorrect coords from trimRefAlt and then an end < start error from indelShift. Now, just set vpPep->cantPredict and skip the rest of the steps since we just don't have enough info. diff --git src/hg/lib/variantProjector.c src/hg/lib/variantProjector.c index aab92f0..df860f7 100644 --- src/hg/lib/variantProjector.c +++ src/hg/lib/variantProjector.c @@ -1038,54 +1038,62 @@ else { vpPep->ref = cloneStringZ(pSeq+vpPep->start, vpPep->end - vpPep->start); if (endPadding > 0) // Copy the unchanged last base or two of ref codons safencpy(altCodons+altCodonsEnd, sizeof(altCodons)-altCodonsEnd, txSeq->dna + cds->start + endInCds, endPadding); } char *alt = translateString(altCodons); if (endsWith(vpPep->ref, "X") && !endsWith(alt, "X")) { // Stop loss -- recompute alt freeMem(alt); safecpy(altCodons+altCodonsEnd, sizeof(altCodons)-altCodonsEnd, txSeq->dna + txEnd); alt = translateString(altCodons); + // But there might not be enough 3'UTR sequence to find a new stop codon... + if (endsWith(vpPep->ref, "X") && !endsWith(alt, "X")) + { + vpPep->cantPredict = TRUE; + } } + if (! vpPep->cantPredict) + { vpPep->alt = alt; int refLen = strlen(vpPep->ref), altLen = strlen(vpPep->alt); if (differentString(vpPep->ref, vpPep->alt)) { // If alt has a stop codon, temporarily disguise it so it can't get trimmed char *altStop = strchr(vpPep->alt, 'X'); if (altStop) *altStop = 'Z'; trimRefAlt(vpPep->ref, vpPep->alt, &vpPep->start, &vpPep->end, &refLen, &altLen); if (altStop) *strchr(vpPep->alt, 'Z') = 'X'; } if (indelShiftIsApplicable(refLen, altLen)) { struct seqWindow *pSeqWin = memSeqWindowNew(vpPep->name, pSeq); vpPep->rightShiftedBases = indelShift(pSeqWin, &vpPep->start, &vpPep->end, vpPep->alt, INDEL_SHIFT_NO_MAX, isdRight); freeMem(vpPep->ref); vpPep->ref = cloneStringZ(pSeq+vpPep->start, vpPep->end - vpPep->start); memSeqWindowFree(&pSeqWin); } dnaSeqFree((struct dnaSeq **)&txTrans); } + } else { vpPep->cantPredict = TRUE; } return vpPep; } void vpPepFree(struct vpPep **pVp) /* Free up a vpPep. */ { if (pVp && *pVp) { struct vpPep *vp = *pVp; freeMem(vp->name); freeMem(vp->ref);