953748cd6cac972d5472b72e07e579dd6abc90dc braney Sat Aug 16 14:23:50 2025 -0700 make the indel track for quickLift a little more useful diff --git src/hg/hgTracks/quickLift.c src/hg/hgTracks/quickLift.c index b36e4f6dbfe..404b622c6d3 100644 --- src/hg/hgTracks/quickLift.c +++ src/hg/hgTracks/quickLift.c @@ -5,31 +5,32 @@ #include "hgConfig.h" #include "bigChain.h" #include "bigLink.h" #include "trackHub.h" struct highRegions // store highlight information { struct highRegions *next; long chromStart; long chromEnd; long oChromStart; long oChromEnd; char strand; unsigned hexColor; -char otherBase; +char *otherBases; +unsigned otherCount; }; #define INSERT_COLOR 0 #define DEL_COLOR 1 #define DOUBLE_COLOR 2 #define MISMATCH_COLOR 3 static Color *highlightColors; static unsigned lengthLimit; static Color getColor(char *confVariable, char *defaultRgba) { Color color = 0xff0000ff; char *str = cloneString(cfgOptionDefault(confVariable, defaultRgba)); @@ -95,108 +96,111 @@ int previousTEnd = -1; int previousQEnd = -1; for (bbLink = bbLinkList; bbLink != NULL; bbLink = bbLink->next) { bigBedIntervalToRow(bbLink, chromName, startBuf, endBuf, linkRow, ArraySize(linkRow)); struct bigLink *bl = bigLinkLoad(linkRow); if (!sameString(bl->name, bc->name)) continue; int tStart = bl->chromStart; int tEnd = bl->chromEnd; int qStart = bl->qStart; int qEnd = qStart + (tEnd - tStart); + // crop the chain block if it's bigger than the window + int tMin, tMax; + int qMin, qMax; + tMin = bl->chromStart; + tMax = bl->chromEnd; + qMin = bl->qStart; + if (seqStart > bl->chromStart) + { + tMin = seqStart; + qMin = qStart + (seqStart - bl->chromStart); + } + if (seqEnd < bl->chromEnd) + { + tMax = seqEnd; + } + qMax = qMin + (tMax - tMin); + + if (bc->strand[0] == '-') + { + qMin = bc->qSize - qMax; + qMax = qMin + (tMax - tMin); + } + + struct dnaSeq *tSeq = hDnaFromSeq(database, chromName, tMin, tMax, dnaUpper); + struct dnaSeq *qSeq = hDnaFromSeq(liftDb, bc->qName, qMin, qMax, dnaUpper); + if (bc->strand[0] == '-') + reverseComplement(qSeq->dna, qSeq->size); struct highRegions *hr; if ((previousTEnd != -1) && (previousTEnd == tStart)) { AllocVar(hr); slAddHead(&hrList, hr); // hr->strand = hr->chromStart = previousTEnd; hr->chromEnd = tStart; hr->oChromStart = previousQEnd; hr->oChromEnd = qStart; hr->hexColor = highlightColors[DEL_COLOR]; + hr->otherBases = &qSeq->dna[qStart - qMin]; + hr->otherCount = hr->oChromEnd - hr->oChromStart; } if ( (previousQEnd != -1) && (previousQEnd == qStart)) { AllocVar(hr); slAddHead(&hrList, hr); hr->chromStart = previousTEnd; hr->chromEnd = tStart; hr->oChromStart = previousQEnd; hr->oChromEnd = qStart; hr->hexColor = highlightColors[INSERT_COLOR]; } if ( ((previousQEnd != -1) && (previousQEnd != qStart)) && ((previousTEnd != -1) && (previousTEnd != tStart))) { AllocVar(hr); slAddHead(&hrList, hr); hr->chromStart = previousTEnd; hr->chromEnd = tStart; hr->oChromStart = previousQEnd; hr->oChromEnd = qStart; hr->hexColor = highlightColors[DOUBLE_COLOR]; } previousQEnd = qEnd; previousTEnd = tEnd; - // crop the chain block if it's bigger than the window - int tMin, tMax; - int qMin, qMax; - tMin = bl->chromStart; - tMax = bl->chromEnd; - qMin = bl->qStart; - if (seqStart > bl->chromStart) - { - tMin = seqStart; - qMin = qStart + (seqStart - bl->chromStart); - } - if (seqEnd < bl->chromEnd) - { - tMax = seqEnd; - } - qMax = qMin + (tMax - tMin); - - if (bc->strand[0] == '-') - { - qMin = bc->qSize - qMax; - qMax = qMin + (tMax - tMin); - } - - struct dnaSeq *tSeq = hDnaFromSeq(database, chromName, tMin, tMax, dnaUpper); - struct dnaSeq *qSeq = hDnaFromSeq(liftDb, bc->qName, qMin, qMax, dnaUpper); - if (bc->strand[0] == '-') - reverseComplement(qSeq->dna, qSeq->size); unsigned tAddr = tMin; unsigned qAddr = qMin; int count = 0; for(; tAddr < tEnd; tAddr++, qAddr++, count++) { if (tSeq->dna[count] != qSeq->dna[count]) { AllocVar(hr); slAddHead(&hrList, hr); hr->chromStart = tAddr; hr->chromEnd = tAddr + 1; hr->oChromStart = qAddr; hr->oChromEnd = qAddr + 1; - hr->otherBase = qSeq->dna[count]; + hr->otherBases = &qSeq->dna[count]; + hr->otherCount = 1; hr->hexColor = highlightColors[MISMATCH_COLOR]; } } } } hashAdd(highLightsHash, quickLiftFile, hrList); return hrList; } static void drawTri(struct hvGfx *hvg, int x1, int x2, int y, Color color) /* Draw traingle. */ { struct gfxPoly *poly = gfxPolyNew(); @@ -239,25 +243,27 @@ double scale = scaleForWindow(width, seqStart, seqEnd); int x1 = xOff + scale * (hr->chromStart - seqStart); int w = scale * (hr->chromEnd - hr->chromStart); if (w == 0) w = 1; hvGfxSetClip(hvg, xOff, yOff, width, height); // we're drawing in the center label at the moment if (drawTriangle) { drawTri(hvg, x1 + w/2 - fontHeight/2, x1 + w/2 + fontHeight/2 , yOff, hexColor); } else hvGfxBox(hvg, x1, yOff, w, height, hexColor); char mouseOver[4096]; - if (hr->otherBase != 0) - safef(mouseOver, sizeof mouseOver, "mismatch %c", hr->otherBase); + if (hr->hexColor == highlightColors[MISMATCH_COLOR]) + safef(mouseOver, sizeof mouseOver, "mismatch %.*s", hr->otherCount, hr->otherBases); else if (hr->chromStart == hr->chromEnd) - safef(mouseOver, sizeof mouseOver, "deletion %ldbp", hr->oChromStart - hr->oChromStart); + safef(mouseOver, sizeof mouseOver, "deletion %ldbp (%.*s)", hr->oChromEnd - hr->oChromStart, hr->otherCount, hr->otherBases); + else if (hr->oChromStart == hr->oChromEnd) + safef(mouseOver, sizeof mouseOver, "insertion %ldbp", hr->chromEnd - hr->chromStart); else - safef(mouseOver, sizeof mouseOver, "insertion %ldbp", hr->oChromEnd - hr->oChromStart); - mapBoxHc(hvg, seqStart, seqEnd, x1, yOff, width, height, tg->track, "insert", mouseOver); + safef(mouseOver, sizeof mouseOver, "double %ldbp", hr->oChromEnd - hr->oChromStart); + mapBoxHc(hvg, seqStart, seqEnd, x1, yOff, width, height, tg->track, "indel", mouseOver); } }