b20d369b166f18509c1fd18682ffc4fc5a5aac09
braney
  Thu Aug 21 17:38:37 2025 -0700
working on detail page for quickLift Chain.

diff --git src/hg/hgTracks/quickLift.c src/hg/hgTracks/quickLift.c
index 3cc01cc8de6..24c925d6078 100644
--- src/hg/hgTracks/quickLift.c
+++ src/hg/hgTracks/quickLift.c
@@ -1,276 +1,127 @@
 
 #include "common.h"
 #include "hgTracks.h"
 #include "chromAlias.h"
 #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 *otherBases;
-unsigned otherCount;
-};
-
-#define INSERT_COLOR     0
-#define DEL_COLOR      1
-#define DOUBLE_COLOR     2
-#define MISMATCH_COLOR     3
+#include "quickLift.h"
 
 static Color *highlightColors;
-static unsigned lengthLimit;
+//static unsigned lengthLimit;
 
 static Color getColor(char *confVariable, char *defaultRgba)
 {
 Color color = 0xff0000ff;
 
 char *str = cloneString(cfgOptionDefault(confVariable, defaultRgba));
 char *words[10];
 if (chopCommas(str, words) != 4)
     errAbort("conf variable '%s' is expected to have a string like  r,g,b,a ", confVariable);
 
 color = MAKECOLOR_32_A(atoi(words[0]),atoi(words[1]),atoi(words[2]),atoi(words[3]));
 return color;
 }
 
 static void initializeHighlightColors()
 {
 if (highlightColors == NULL)
     {
-    highlightColors = needMem(sizeof(Color) * 3);
- 
-    lengthLimit = atoi(cfgOptionDefault("quickLift.lengthLimit", "10000"));
-
-    highlightColors[INSERT_COLOR] = getColor("quickLift.insColor","255,0,0,255");
-    highlightColors[DEL_COLOR] = getColor("quickLift.delColor","0,255,0,255");
-    highlightColors[DOUBLE_COLOR] = getColor("quickLift.doubleColor","0,0,255,255");
-    highlightColors[MISMATCH_COLOR] = getColor("quickLift.mismatchColor","255,0,0,255");
-    }
-}
-
-struct highRegions *getQuickLiftLines(char *liftDb, char *quickLiftFile, int seqStart, int seqEnd)
-/* Figure out the highlight regions and cache them. */
-{
-static struct hash *highLightsHash = NULL;
-struct highRegions *hrList = NULL;
-
-initializeHighlightColors();
-if (seqEnd - seqStart > lengthLimit)
-    return hrList;
-
-if (highLightsHash != NULL)
-    {
-    if ((hrList = (struct highRegions *)hashFindVal(highLightsHash, quickLiftFile)) != NULL)
-        return hrList;
-    }
-else
-    {
-    highLightsHash = newHash(0);
-    }
-
-
-struct bbiFile *bbiChain = bigBedFileOpenAlias(quickLiftFile, chromAliasFindAliases);
-struct lm *lm = lmInit(0);
-struct bigBedInterval *bbChain, *bbChainList =  bigBedIntervalQuery(bbiChain, chromName, seqStart, seqEnd, 0, lm);
-char *links = bigChainGetLinkFile(quickLiftFile);
-struct bbiFile *bbiLink = bigBedFileOpenAlias(links, chromAliasFindAliases);
-struct bigBedInterval  *bbLink, *bbLinkList =  bigBedIntervalQuery(bbiLink, chromName, seqStart, seqEnd, 0, lm);
-
-char *chainRow[1024];
-char *linkRow[1024];
-char startBuf[16], endBuf[16];
-
-for (bbChain = bbChainList; bbChain != NULL; bbChain = bbChain->next)
-    {
-    bigBedIntervalToRow(bbChain, chromName, startBuf, endBuf, chainRow, ArraySize(chainRow));
-    struct bigChain *bc = bigChainLoad(chainRow);
-
-    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;
+    highlightColors = needMem(sizeof(Color) * 5);
  
+    //lengthLimit = atoi(cfgOptionDefault("quickLift.lengthLimit", "10000"));
 
-        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->otherBases = &qSeq->dna[count];
-                hr->otherCount = 1;
-                hr->hexColor = highlightColors[MISMATCH_COLOR];
-                }
-            }
+    highlightColors[QUICKTYPE_INSERT] = getColor("quickLift.insColor","255,0,0,255");
+    highlightColors[QUICKTYPE_DEL] = getColor("quickLift.delColor","0,255,0,255");
+    highlightColors[QUICKTYPE_DOUBLE] = getColor("quickLift.doubleColor","0,0,255,255");
+    highlightColors[QUICKTYPE_MISMATCH] = getColor("quickLift.mismatchColor","255,0,0,255");
+    highlightColors[QUICKTYPE_NOTHING] = getColor("quickLift.nothingColor","1,1,1,1");
     }
 }
 
-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();
 int half = (x2 - x1) / 2;
 
 gfxPolyAddPoint(poly, x1, y);
 gfxPolyAddPoint(poly, x1+half, y+2*half);
 gfxPolyAddPoint(poly, x2, y);
 hvGfxDrawPoly(hvg, poly, color, TRUE);
 gfxPolyFree(&poly);
 }
 
 void maybeDrawQuickLiftLines( struct track *tg, int seqStart, int seqEnd,
                       struct hvGfx *hvg, int xOff, int yOff, int width,
                       MgFont *font, Color color, enum trackVisibility vis)
 /* Draw the indel regions in quickLifted tracks as a highlight. */
 {
 char *quickLiftFile = cloneString(trackDbSetting(tg->tdb, "quickLiftUrl"));
 if (quickLiftFile == NULL)
     return;
 
+initializeHighlightColors();
 boolean drawTriangle = FALSE;
 if (startsWith("quickLiftChain", trackHubSkipHubName(tg->track)))
     drawTriangle = TRUE;
 char *liftDb = trackDbSetting(tg->tdb, "quickLiftDb");
-struct highRegions *regions = getQuickLiftLines(liftDb, quickLiftFile, seqStart, seqEnd);
-struct highRegions *hr = regions;
+struct quickLiftRegions *regions = quickLiftGetRegions(database, liftDb, quickLiftFile, chromName, seqStart, seqEnd);
+struct quickLiftRegions *hr = regions;
 
 int fontHeight = mgFontLineHeight(tl.font);
 int height = tg->height;
 if (!drawTriangle && isCenterLabelIncluded(tg))
     {
     height += fontHeight;
     yOff -= fontHeight;
     }
 
+//mapBoxHc(hvg, seqStart, seqEnd, xOff, yOff, width,  tg->height, tg->track,  "fart", "hallo");
 for(; hr; hr = hr->next)
     {
-    unsigned int hexColor = hr->hexColor;
+    unsigned int hexColor = highlightColors[hr->type];
     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
     int startX, endX;
+    char mouseOver[4096];
+
+    if (hr->type == QUICKTYPE_NOTHING)
+        {
+        safef(mouseOver, sizeof mouseOver, "identical");
+        mapBoxHc(hvg, hr->chromStart, hr->chromEnd, x1, yOff, w, height, tg->track, hr->id, mouseOver);
+        }
+    else
+        {
         if (drawTriangle)
             {
             startX = x1 + w/2 - fontHeight/2;
             endX = x1 + w/2 + fontHeight/2 ;
             drawTri(hvg, startX, endX , yOff, hexColor);
             }
         else
             {
             startX = x1;
             endX = x1 + w;
             hvGfxBox(hvg, startX, yOff, w, height, hexColor);
             }
 
-    char mouseOver[4096];
-
-    if (hr->hexColor == highlightColors[MISMATCH_COLOR])
+        if (hr->type == QUICKTYPE_MISMATCH)
             safef(mouseOver, sizeof mouseOver, "mismatch %.*s", hr->otherCount, hr->otherBases);
         else if (hr->chromStart == hr->chromEnd)
             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, "double %ldbp", hr->oChromEnd - hr->oChromStart);
-    mapBoxHc(hvg, seqStart, seqEnd, startX, yOff, endX - startX, height, tg->track, "indel", mouseOver);
 
+        mapBoxHc(hvg, seqStart, seqEnd, startX, yOff, endX - startX, height, tg->track, hr->id, mouseOver);
+        }
     }
 }