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