0fbc4aeaa5dc8cc1be2ddf15500790407ed9df91
braney
  Sat Aug 16 11:18:40 2025 -0700
support bed8 and bed9 in quickLift

diff --git src/hg/hgTracks/bedTrack.c src/hg/hgTracks/bedTrack.c
index 60fd4e9fcc1..9f2cb9e332d 100644
--- src/hg/hgTracks/bedTrack.c
+++ src/hg/hgTracks/bedTrack.c
@@ -281,108 +281,175 @@
 int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tdb, "scoreMax", "1000"));
 boolean useItemRgb = FALSE;
 
 useItemRgb = bedItemRgb(tdb);
 
 if (tg->isBigBed)
     { // avoid opening an unneeded db connection for bigBed; required not to use mysql for parallel fetch tracks
     struct bbiFile *bbi = fetchBbiForTrack(tg);
     if (bbi->fieldCount < 9)
         errAbort("track %s has a bigBed being read as a bed9 that has %d columns.", tg->track, bbi->fieldCount);
     bigBedLabelCalculateFields(cart, tg->tdb, bbi,  &tg->labelColumns);
     bigBedAddLinkedFeaturesFrom(tg, chromName, winStart, winEnd,
           scoreMin, scoreMax, useItemRgb, 9, &lfList);
     }
 else
+    {
+    char *liftDb = cloneString(trackDbSetting(tg->tdb, "quickLiftDb"));
+    char *scoreFilterClause = getScoreFilterClause(cart, tg->tdb,NULL);
+
+    if (liftDb == NULL)
         {
         struct sqlConnection *conn = hAllocConnTrack(database, tdb);
         struct sqlResult *sr;
         char **row;
         int rowOffset;
         char *scoreFilterClause = getScoreFilterClause(cart, tg->tdb,NULL);
         if (scoreFilterClause != NULL)
             {
             sr = hRangeQuery(conn, tg->table, chromName, winStart, winEnd,scoreFilterClause, &rowOffset);
             freeMem(scoreFilterClause);
             }
         else
             {
             sr = hRangeQuery(conn, tg->table, chromName, winStart, winEnd,
                              NULL, &rowOffset);
             }
 
         while ((row = sqlNextRow(sr)) != NULL)
             {
             bed = bedLoadN(row+rowOffset, 9);
             lf = bedMungToLinkedFeatures(&bed, tdb, 9, scoreMin, scoreMax, useItemRgb);
             slAddHead(&lfList, lf);
             }
         sqlFreeResult(&sr);
         hFreeConn(&conn);
         }
+    else
+        {
+        char *table;
+        if (isCustomTrack(tg->table))
+            {
+            liftDb = CUSTOM_TRASH;
+            table = trackDbSetting(tg->tdb, "dbTableName");
+            }
+        else
+            table = tg->table;
+        struct hash *chainHash = newHash(8);
+        struct sqlConnection *conn = hAllocConn(liftDb);
+        char *quickLiftFile = cloneString(trackDbSetting(tg->tdb, "quickLiftUrl"));
+        bed = (struct bed *)quickLiftSql(conn, quickLiftFile, table, chromName, winStart, winEnd,  NULL, scoreFilterClause, (ItemLoader2)bedLoadN, 9, chainHash);
+
+        struct bed *liftedBeds = quickLiftBeds(bed, chainHash, TRUE);
+        for(bed = liftedBeds; bed; bed = bed->next)
+            {
+            lf = lfFromBedExtra(bed, scoreMin, scoreMax);
+            if (useItemRgb)
+                {
+                lf->useItemRgb = TRUE;
+                lf->filterColor=bed->itemRgb;
+                }
+            slAddHead(&lfList, lf);
+            }
+        hFreeConn(&conn);
+        }
+    }
 slReverse(&lfList);
 slSort(&lfList, linkedFeaturesCmp);
 tg->items = lfList;
 }
 
 
 void loadBed8(struct track *tg)
 /* Convert bed 8 info in window to linked feature. */
 {
 struct bed *bed;
 struct linkedFeatures *lfList = NULL, *lf;
 struct trackDb *tdb = tg->tdb;
 int scoreMin = atoi(trackDbSettingClosestToHomeOrDefault(tdb, "scoreMin", "0"));
 int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tdb, "scoreMax", "1000"));
 boolean useItemRgb = FALSE;
 
 useItemRgb = bedItemRgb(tdb);
 
 if (tg->isBigBed)
     { // avoid opening an unneeded db connection for bigBed; required not to use mysql for parallel fetch tracks
     struct bbiFile *bbi = fetchBbiForTrack(tg);
     bigBedLabelCalculateFields(cart, tg->tdb, bbi,  &tg->labelColumns);
     bigBedAddLinkedFeaturesFrom(tg, chromName, winStart, winEnd,
           scoreMin, scoreMax, useItemRgb, 8, &lfList);
     }
 else
+    {
+    char *liftDb = cloneString(trackDbSetting(tg->tdb, "quickLiftDb"));
+    char *scoreFilterClause = getScoreFilterClause(cart, tg->tdb,NULL);
+
+    if (liftDb == NULL)
         {
         struct sqlConnection *conn = hAllocConn(database);
         struct sqlResult *sr;
         char **row;
         int rowOffset;
-    char *scoreFilterClause = getScoreFilterClause(cart, tg->tdb,NULL);
         if (scoreFilterClause != NULL)
             {
             sr = hRangeQuery(conn, tg->table, chromName, winStart, winEnd,scoreFilterClause, &rowOffset);
             freeMem(scoreFilterClause);
             }
         else
             {
             sr = hRangeQuery(conn, tg->table, chromName, winStart, winEnd,
                              NULL, &rowOffset);
             }
 
         while ((row = sqlNextRow(sr)) != NULL)
             {
             bed = bedLoadN(row+rowOffset, 8);
             lf = bedMungToLinkedFeatures(&bed, tdb, 8, scoreMin, scoreMax, useItemRgb);
             slAddHead(&lfList, lf);
             }
         sqlFreeResult(&sr);
         hFreeConn(&conn);
         }
+    else
+        {
+        char *table;
+        if (isCustomTrack(tg->table))
+            {
+            liftDb = CUSTOM_TRASH;
+            table = trackDbSetting(tg->tdb, "dbTableName");
+            }
+        else
+            table = tg->table;
+        struct hash *chainHash = newHash(8);
+        struct sqlConnection *conn = hAllocConn(liftDb);
+        char *quickLiftFile = cloneString(trackDbSetting(tg->tdb, "quickLiftUrl"));
+        bed = (struct bed *)quickLiftSql(conn, quickLiftFile, table, chromName, winStart, winEnd,  NULL, scoreFilterClause, (ItemLoader2)bedLoadN, 8, chainHash);
+
+        struct bed *liftedBeds = quickLiftBeds(bed, chainHash, TRUE);
+        for(bed = liftedBeds; bed; bed = bed->next)
+            {
+            lf = lfFromBedExtra(bed, scoreMin, scoreMax);
+            if (useItemRgb)
+                {
+                lf->useItemRgb = TRUE;
+                lf->filterColor=bed->itemRgb;
+                }
+            slAddHead(&lfList, lf);
+            }
+        hFreeConn(&conn);
+        }
+    }
 slReverse(&lfList);
 slSort(&lfList, linkedFeaturesCmp);
 tg->items = lfList;
 }
 
 static void filterBed(struct track *tg, struct linkedFeatures **pLfList)
 /* Apply filters if any to mRNA linked features. */
 {
 struct linkedFeatures *lf, *next, *newList = NULL, *oldList = NULL;
 struct mrnaUiData *mud = tg->extraUiData;
 struct mrnaFilter *fil;
 char *type;
 boolean anyFilter = FALSE;
 boolean colorIx = 0;
 boolean isExclude = FALSE;