6823728f16334d9b53bd595688c8f5780cf833fe
braney
  Sun Feb 16 12:13:13 2025 -0800
ongoing work on quickLift.  Added support for SQL beds

diff --git src/hg/lib/quickLift.c src/hg/lib/quickLift.c
index 64ce5872a01..8e0da05aa8c 100644
--- src/hg/lib/quickLift.c
+++ src/hg/lib/quickLift.c
@@ -5,55 +5,56 @@
 #include "common.h"
 #include "obscure.h"
 #include "limits.h"
 #include "float.h"
 #include "asParse.h"
 #include "chain.h"
 #include "binRange.h"
 #include "basicBed.h"
 #include "liftOver.h"
 #include "hash.h"
 #include "bigBed.h"
 #include "bbiFile.h"
 #include "chainNetDbLoad.h"
 #include "hdb.h"
 #include "jksql.h"
+#include "hgConfig.h"
 #include "quickLift.h"
 
 char *getLinkFile(char *quickLiftFile)
 /* Construct the file name of the chain link file from the name of a chain file. 
  * That is, change file.bb to file.link.bb */
 {
 char linkBuffer[4096];
 
 if (!endsWith(quickLiftFile, ".bb"))
     errAbort("quickLift file (%s) must end in .bb", quickLiftFile);
 
 safef(linkBuffer, sizeof linkBuffer, "%s", quickLiftFile);
 
 // truncate string at ending ".bb"
 int insertOffset = strlen(linkBuffer) - sizeof ".bb" + 1;
 char *insert = &linkBuffer[insertOffset];
 *insert = 0;
 
 // add .link.bb
 strcpy(insert, ".link.bb");
 
 return cloneString(linkBuffer);
 }
 
-struct bigBedInterval *quickLiftIntervals(char *quickLiftFile, struct bbiFile *bbi,   char *chrom, int start, int end, struct hash **pChainHash)
+struct bigBedInterval *quickLiftGetIntervals(char *quickLiftFile, struct bbiFile *bbi,   char *chrom, int start, int end, struct hash **pChainHash)
 /* Return intervals from "other" species that will map to the current window.
  * These intervals are NOT YET MAPPED to the current assembly.
  */
 {
 char *linkFileName = getLinkFile(quickLiftFile);
 // need to add some padding to these coordinates
 int padStart = start - 100000;
 if (padStart < 0)
     padStart = 0;
 struct chain *chain, *chainList = chainLoadIdRangeHub(NULL, quickLiftFile, linkFileName, chrom, padStart, end+100000, -1);
 struct lm *lm = lmInit(0);
 struct bigBedInterval *bbList = NULL;
 
 for(chain = chainList; chain; chain = chain->next)
     {
@@ -82,40 +83,41 @@
     else
         thisInterval = bigBedIntervalQuery(bbi, chain->qName, qStart, qEnd, 10000, lm);
     bbList = slCat(thisInterval, bbList);
     
     // for the mapping we're going to use the same chain we queried on to map the items, but we need to swap it
     chainSwap(chain);
 
     if (*pChainHash == NULL)
         *pChainHash = newHash(0);
     liftOverAddChainHash(*pChainHash, chain);
     }
 
 return bbList;
 }
 
-void make12(struct bed *bed)
+static void make12(struct bed *bed)
+/* Make a bed12 out of something less than that. */
 {
 bed->blockCount = 1;
 bed->blockSizes = needMem(sizeof(int));
 bed->blockSizes[0] = bed->chromEnd - bed->chromStart;
 bed->chromStarts = needMem(sizeof(int));
 bed->chromStarts[0] = 0;
 }
 
-struct bed *quickLiftBed(struct bbiFile *bbi, struct hash *chainHash, struct bigBedInterval *bb)
+struct bed *quickLiftIntervalsToBed(struct bbiFile *bbi, struct hash *chainHash, struct bigBedInterval *bb)
 /* Using chains stored in chainHash, port a bigBedInterval from another assembly to a bed
  * on the reference.
  */
 {
 char startBuf[16], endBuf[16];
 char *bedRow[bbi->fieldCount];
 char chromName[256];
 static int lastChromId = -1;
 
 bbiCachedChromLookup(bbi, bb->chromId, lastChromId, chromName, sizeof(chromName));
 //lastChromId=bb->chromId;
 
 bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow));
 
 struct bed *bed = bedLoadN(bedRow, bbi->definedFieldCount);
@@ -198,44 +200,50 @@
     while ((row = sqlNextRow(sr)) != NULL)
         {
         item = loader(row + rowOffset, numFields);
         slAddHead(&itemList, item);
         }
 
     // now squirrel the swapped chains we used to use to make the retrieved items back to us
     chainSwap(chain);
     liftOverAddChainHash(chainHash, chain);
     }
 
 return itemList;
 }
 
 struct bed *quickLiftBeds(struct bed *bedList, struct hash *chainHash, boolean blocked)
-// Map a bed in query coordinates to our current reference
+// Map a list of bedd in query coordinates to our current reference
 {
 struct bed *liftedBedList = NULL;
 struct bed *nextBed;
 struct bed *bed;
 for(bed = bedList; bed; bed = nextBed)
     {
     // remapBlockedBed may want to add new beds after this bed if the region maps to more than one location
     nextBed = bed->next;
     bed->next = NULL;
 
     char *error;
     if (!blocked)
         {
         error = liftOverRemapRange(chainHash, 0.0, bed->chrom, bed->chromStart, bed->chromEnd, bed->strand[0],
                              
                             0.1, &bed->chrom, (int *)&bed->chromStart, (int *)&bed->chromEnd, &bed->strand[0]);
         }
     else
         error = remapBlockedBed(chainHash, bed, 0.0, 0.1, TRUE, TRUE, NULL, NULL);
 
     if (error == NULL)
         {
         slAddHead(&liftedBedList, bed);
         }
     }
 return liftedBedList;
 }
 
+boolean quickLiftEnabled()
+/* Return TRUE if feature is available */
+{
+char *cfgEnabled = cfgOption("browser.quickLift");
+return cfgEnabled && (sameString(cfgEnabled, "on") || sameString(cfgEnabled, "true")) ;
+}