0b9c2a6f9930555f65104385a9edcb00147a5bc6 braney Mon Feb 3 09:31:56 2025 -0800 add support for quikLifting mySQL beds. diff --git src/hg/lib/quickLift.c src/hg/lib/quickLift.c index fcf90e57225..4ffa08e46f5 100644 --- src/hg/lib/quickLift.c +++ src/hg/lib/quickLift.c @@ -4,33 +4,34 @@ #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 "quickLift.h" -static char *getLinkFile(char *quickLiftFile) +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; @@ -134,15 +135,107 @@ /* Return the id from the quickLiftChain table for given assemblies. */ { unsigned ret = 0; struct sqlConnection *conn = hConnectCentral(); char query[2048]; sqlSafef(query, sizeof(query), "select q.id from quickLiftChain q where q.fromDb='%s' and q.toDb='%s'", fromDb, toDb); char *geneId = sqlQuickString(conn, query); hDisconnectCentral(&conn); if (geneId) ret = atoi(geneId); return ret; } + +struct slList *quickLiftSql(struct sqlConnection *conn, char *quickLiftFile, char *table, char *chrom, int start, int end, char *query, char *extraWhere, ItemLoader loader, struct hash *chainHash) +// retrieve items for which we have a loader from a SQL database for which we have a set quickLift chains. +// Save the chains we used to map the item back to the current reference. +{ +// need to add some padding to these coordinates +int padStart = start - 100000; +if (padStart < 0) + padStart = 0; + +char *linkFileName = getLinkFile(quickLiftFile); +struct chain *chain, *chainList = chainLoadIdRangeHub(NULL, quickLiftFile, linkFileName, chrom, padStart, end+100000, -1); + +struct slList *item, *itemList = NULL; +int rowOffset = 0; +struct sqlResult *sr = NULL; +char **row = NULL; + +for(chain = chainList; chain; chain = chain->next) + { + struct cBlock *cb; + cb = chain->blockList; + + if (cb == NULL) + continue; + + int qStart = cb->qStart; + int qEnd = cb->qEnd; + + // get the range for the links on the "other" species + for(; cb; cb = cb->next) + { + if (cb->qStart < qStart) + qStart = cb->qStart; + if (cb->qEnd > qEnd) + qEnd = cb->qEnd; + } + + if (chain->qStrand == '-') + qStart = chain->qSize - qStart; + + // now grab the items + if (query == NULL) + sr = hRangeQuery(conn, table, chain->qName, + qStart, qEnd, extraWhere, &rowOffset); + else + sr = sqlGetResult(conn, query); + + while ((row = sqlNextRow(sr)) != NULL) + { + item = loader(row + rowOffset); + 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 +{ +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; +} +