1cbb143dea2cf4ece990707556b4c2caac7f0311
braney
  Thu Mar 21 13:50:58 2024 -0700
fixing bugs in quickLift

diff --git src/hg/hgTracks/bedTrack.c src/hg/hgTracks/bedTrack.c
index e06b1d4..4debf33 100644
--- src/hg/hgTracks/bedTrack.c
+++ src/hg/hgTracks/bedTrack.c
@@ -5,30 +5,31 @@
 
 #include "common.h"
 #include "jksql.h"
 #include "bed.h"
 #include "hdb.h"
 #include "bedCart.h"
 #include "bbiFile.h"
 #include "bigBed.h"
 #include "hgTracks.h"
 #include "cds.h"
 #include "bedTabix.h"
 #include "obscure.h"
 #include "bigBedFilter.h"
 #include "bigBedLabel.h"
 #include "snake.h"
+#include "quickLift.h"
 
 #define SEQ_DELIM '~'
 
 struct bed *bedLoadPairedTagAlign(char **row)
 /* Load first six fields of bed.
  * Add ~seq1~seq2 to end of name
  * Then remove the sequence to extra field when we convert to linkedFeature.
  * Assumes seq1 and seq2 are in row[6] and row[7], as they would be with a
  * pairedTagAlign type (hg/lib/encode/pairedTagAlign.as). It would be good to be
  * able to check these columns exist but we dont have the sqlResult here. */
 {
 char buf[1024];
 struct bed *ret = bedLoad6(row);
 safef(buf, sizeof(buf), "%s%c%s%c%s", ret->name, SEQ_DELIM, row[6], SEQ_DELIM, row[7]);
 freez(&(ret->name));
@@ -72,52 +73,65 @@
         }
     }
 
 /* Get list of items */
 if (startsWith("bedTabix", tg->tdb->type ) || startsWith("longTabix", tg->tdb->type ))
     {
     struct hash *settings = tg->tdb->settingsHash;
     char *bigDataUrl = hashFindVal(settings, "bigDataUrl");
     struct bedTabixFile *btf = bedTabixFileMayOpen(bigDataUrl, NULL, 0, 0);
     list = bedTabixReadBeds(btf, chromName, winStart, winEnd, loader);
     bedTabixFileClose(&btf);
     }
 else if (tg->isBigBed)
     { // avoid opening an unneeded db connection for bigBed; required not to use mysql for parallel fetch tracks
     struct lm *lm = lmInit(0);
-    struct bigBedInterval *bb, *bbList = bigBedSelectRange(tg, chromName, winStart, winEnd, lm);
     struct bbiFile *bbi = fetchBbiForTrack(tg);
+    char *quickLiftFile = cloneString(trackDbSetting(tg->tdb, "quickLiftUrl"));
+    struct hash *chainHash = NULL;
+    struct bigBedInterval *bb, *bbList = NULL;
+    if (quickLiftFile)
+        bbList = quickLiftIntervals(quickLiftFile, bbi, chromName, winStart, winEnd, &chainHash);
+    else
+        bbList = bigBedSelectRange(tg, chromName, winStart, winEnd, lm);
+
     char *bedRow[bbi->fieldCount];
     char startBuf[16], endBuf[16];
 
     struct bigBedFilter *filters = bigBedBuildFilters(cart, bbi, tg->tdb);
     if (compositeChildHideEmptySubtracks(cart, tg->tdb, NULL, NULL))
        labelTrackAsHideEmpty(tg);
 
      if (tg->itemName == bedName && !trackDbSettingClosestToHomeOn(tg->tdb, "linkIdInName"))
         tg->itemName = bigBedItemName;
 
     bigBedLabelCalculateFields(cart, tg->tdb, bbi,  &tg->labelColumns);
     unsigned filtered = 0;
     for (bb = bbList; bb != NULL; bb = bb->next)
         {
         bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow));
         if (!bigBedFilterInterval(bbi, bedRow, filters))
             {
             filtered++;
             continue;
             }
+        if (quickLiftFile)
+            {
+            if ((bed = quickLiftBed(bbi, chainHash, bb)) == NULL)
+                continue;
+            }
+        else
             bed = loader(bedRow);
         // FIXME BRANEY: either disable for all tracks with NUM_FIELDS > label field or better,
         // fix how label is stored so it doesn't trash custom bed field
         // BRANEY says: the loader should be returning bed structures which include the label field.
         if (differentString(tg->tdb->type, "bigInteract"))
             bed->label = bigBedMakeLabel(tg->tdb, tg->labelColumns, bb, chromName);
 
         slAddHead(&list, bed);
         }
 
     if (filtered)
        labelTrackAsFilteredNumber(tg, filtered);
 
     lmCleanup(&lm);
     }