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);
 
     }
 }