eb5c9cd277c2bcd521aa461d06e9d8a32509c1d3 braney Thu Oct 9 12:17:30 2025 -0700 make it possible to use a cart variable in addition to an hg.conf variable to turn on quickLift diff --git src/hg/hgConvert/hgConvert.c src/hg/hgConvert/hgConvert.c index 1ee630cb9c7..dc35cb6c0e7 100644 --- src/hg/hgConvert/hgConvert.c +++ src/hg/hgConvert/hgConvert.c @@ -14,30 +14,35 @@ #include "htmshell.h" #include "hdb.h" #include "hui.h" #include "cart.h" #include "web.h" #include "chain.h" #include "liftOver.h" #include "liftOverChain.h" #include "chromInfo.h" #include "net.h" #include "genark.h" #include "trackHub.h" #include "hubConnect.h" #include "quickLift.h" #include "chromAlias.h" +#ifdef NOTNOW +#include "jsHelper.h" +#include "bigChain.h" +#include "bigLink.h" +#endif /* CGI Variables */ #define HGLFT_TOORG_VAR "hglft_toOrg" /* TO organism */ #define HGLFT_TODB_VAR "hglft_toDb" /* TO assembly */ #define HGLFT_DO_CONVERT "hglft_doConvert" /* Do the actual conversion */ /* Global Variables */ static struct cart *cart; /* CGI and other variables */ static struct hash *oldVars = NULL; static char *organism = NULL; static char *database = NULL; /* Javascript to support New Assembly pulldown when New Genome changes. */ /* Copies selected values to a hidden form */ @@ -55,31 +60,31 @@ struct dbDb *toDb = genarkLiftOverDb(name); if (toDb == NULL) errAbort("Can't find %s in matchingDb", name); return toDb; } static void askForDestination(struct liftOverChain *liftOver, char *fromPos, struct dbDb *fromDb, struct dbDb *toDb) /* set up page for entering data */ { struct dbDb *dbList; boolean askAboutQuickLift = FALSE; //boolean quickLiftChainExists = (quickLiftGetChain(fromDb->name, toDb->name) != 0); -if (quickLiftEnabled()) +if (quickLiftEnabled(cart)) askAboutQuickLift = TRUE; cartWebStart(cart, database, "Convert %s to New Assembly", fromPos); /* create HMTL form */ puts("
\n"); cartSaveSession(cart); /* create HTML table for layout purposes */ puts("\n\n"); /* top row -- labels */ cgiSimpleTableRowStart(); cgiTableField("Old genome: "); cgiTableField("Old assembly: "); @@ -274,34 +279,190 @@ rawList = chainLoadIntersecting(fileName, chrom, start, end); for (chain = rawList; chain != NULL; chain = next) { struct chain *subChain, *chainToFree; next = chain->next; chainSubsetOnT(chain, start, end, &subChain, &chainToFree); if (subChain != NULL) slAddHead(&chainList, subChain); if (chainToFree != NULL) chainFree(&chain); } slSort(&chainList, chainCmpScore); return chainList; } +#ifdef NOTNOW +struct segment +{ +struct segment *next; +unsigned start, end; +char strand; +}; + +void compressSegs(struct segment *segs) +{ +struct segment *nextSeg = NULL; +struct segment *growSeg = NULL; + +for(; segs; segs = nextSeg) + { + nextSeg = segs->next; + if (nextSeg == NULL) + break; + + if (growSeg == NULL) + growSeg = segs; + + if ((nextSeg->start < growSeg->end + 10000) || (nextSeg->strand != growSeg->strand)) + { + growSeg->end = nextSeg->end; + //nextSeg = nextSeg->next; + } + else + { + growSeg->next = segs; + growSeg = NULL; + } + } +} + +static void getSegs(char *fromDb, char *toDb, struct segment **fromSegs, struct segment **toSegs, char *chrom, unsigned seqStart, unsigned seqEnd) +{ +char *quickLiftFile = quickLiftGetChainPath(cart, fromDb, toDb); +struct lm *lm = lmInit(0); +//struct bigBedInterval *bbChain, *bbChainList = bigBedIntervalQuery(bbiChain, chrom, seqStart, seqEnd, 0, lm); +struct bbiFile *bbiChain = bigBedFileOpenAlias(quickLiftFile, chromAliasFindAliases); +struct bigBedInterval *bbChain, *bbChainList = bigBedIntervalQuery(bbiChain, chrom, seqStart, seqEnd, 0, lm); + +char *links = bigChainGetLinkFile(quickLiftFile); +struct bbiFile *bbiLink = bigBedFileOpenAlias(links, chromAliasFindAliases); +struct bigBedInterval *bbLink, *bbLinkList = bigBedIntervalQuery(bbiLink, chrom, seqStart, seqEnd, 0, lm); + +char *chainRow[1024]; +char *linkRow[1024]; +char startBuf[16], endBuf[16]; + +bigBedIntervalToRow(bbChainList, chrom, startBuf, endBuf, chainRow, ArraySize(chainRow)); +struct bigChain *fbc = bigChainLoad(chainRow); + +for (bbChain = bbChainList; bbChain != NULL; bbChain = bbChain->next) + { + bigBedIntervalToRow(bbChain, chrom, startBuf, endBuf, chainRow, ArraySize(chainRow)); + struct bigChain *bc = bigChainLoad(chainRow); + if (differentString(bc->chrom, fbc->chrom)) + continue; + + for (bbLink = bbLinkList; bbLink != NULL; bbLink = bbLink->next) + { + bigBedIntervalToRow(bbLink, chrom, startBuf, endBuf, linkRow, ArraySize(linkRow)); + struct bigLink *bl = bigLinkLoad(linkRow); + + if (!sameString(bl->name, bc->name)) + continue; + + boolean isFlipped = fbc->strand[0] != bc->strand[0]; + struct segment *seg; + AllocVar(seg); + seg->start = bl->chromStart; + seg->end = bl->chromEnd; + seg->strand = 0; + slAddHead(fromSegs, seg); + + unsigned width = bl->chromEnd - bl->chromStart; + unsigned qStart = bl->qStart; + unsigned qEnd = bl->qStart + width; + if (bc->strand[0] == '-') + { + qStart = bc->qSize - qStart; + qEnd = bc->qSize - qEnd; + } + + AllocVar(seg); + seg->start = qStart; + seg->end = qEnd; + seg->strand = isFlipped; + slAddHead(toSegs, seg); + } + } +slReverse(toSegs); +//compressSegs(*toSegs); +slReverse(fromSegs); +//compressSegs(*fromSegs); + +} + +static void printSegs(struct segment *segs) +{ +unsigned segNum = 0; + +jsInline("segments: [\n"); +for(; segs; segs = segs->next) + jsInlineF("{ name: '%d', start: %d, end: %d },\n", segNum++, segs->start, segs->end); +jsInline("]\n"); +} + +static void drawSegments(char *fromDb, char *toDb, struct chain *chain) +{ +struct segment *fromSegs = NULL; +struct segment *toSegs = NULL; +/* +unsigned seqStart = chain->tStart; +unsigned seqEnd = chain->tEnd; +char *chrom = chain->tName; +*/ + +unsigned qStart = chain->qStart; +unsigned qEnd = chain->qEnd; +if (chain->qStrand == '-') + { + unsigned saveQStart = qStart; + qStart = chain->qSize - qEnd; + qEnd = chain->qSize - saveQStart; + } + +getSegs(fromDb, toDb, &fromSegs, &toSegs, chain->qName, chain->qStart, chain->qEnd); + +printf(""); +jsIncludeFile("parallelSegments.js", NULL); + +jsInline("function drawCustom() {\n"); +jsInline("const line1Data = {\n"); +jsInlineF("range: { start: %d, end: %d },\n", chain->tStart, chain->tEnd); +jsInlineF("label: \"%s %s:%d-%d\",\n", fromDb, chain->tName, chain->tStart, chain->tEnd); +printSegs(toSegs); +jsInline("}\n"); + +jsInline("const line2Data = {\n"); +jsInlineF("range: { start: %d, end: %d },\n", qStart, qEnd); +jsInlineF("label: \"%s %s:%d-%d\",\n", fromDb, chain->qName, qStart, qEnd); +printSegs(fromSegs); +jsInline("}\n"); + +jsInline("ParallelSegments.drawCoordinateBasedSegments(line1Data, line2Data);\n"); +jsInline("}\n"); +jsInline("drawCustom();\n"); +} +#endif + static void doConvert(char *fromPos) /* Actually do the conversion */ { struct dbDb *fromDb = hDbDb(trackHubSkipHubName(database)), *toDb = hDbDb(cartString(cart, HGLFT_TODB_VAR)); +#ifdef NOTNOW +boolean doSegments = TRUE; +#endif if (fromDb == NULL) { char buffer[4096]; safef(buffer, sizeof buffer, "'%s'", trackHubSkipHubName(database)); fromDb = genarkLiftOverDbs(buffer); } if (toDb == NULL) toDb = genarkLiftOverDb(cartString(cart, HGLFT_TODB_VAR)); if (!fromDb || !toDb) errAbort("Early error - unable to find matching database records in dbDb - please contact support"); chromAliasSetup(database); cartWebStart(cart, database, "%s %s %s to %s %s", fromDb->organism, fromDb->description, @@ -319,31 +480,31 @@ struct dyString *visDy = NULL; if (!hgParseChromRange(database, fromPos, &chrom, &start, &end)) errAbort("position %s is not in chrom:start-end format", fromPos); origSize = end - start; boolean doQuickLift = cartUsualBoolean(cart, "doQuickLift", FALSE); cartRemove(cart, "doQuickLift"); unsigned quickChain = 0; unsigned quickHub = 0; struct trackDb *badList = NULL; if (doQuickLift) { - quickChain = quickLiftGetChain(trackHubSkipHubName(fromDb->name), trackHubSkipHubName(toDb->name)); + quickChain = quickLiftGetChainId(cart, trackHubSkipHubName(fromDb->name), trackHubSkipHubName(toDb->name)); if (quickChain == 0) errAbort("can't find quickChain from %s to %s", fromDb->name, toDb->name); visDy = newDyString(1024); char *newHub = trackHubBuild(fromDb->name, cart, visDy, &badList); char *error = NULL; quickHub = hubFindOrAddUrlInStatusTable(cart, newHub, &error); if (error != NULL) errAbort("can't add quickLift hub (error %s)",error); } chainList = chainLoadAndTrimIntersecting(fileName, chrom, start, end); if (chainList == NULL) printf("Sorry this position couldn't be found in new assembly"); @@ -380,30 +541,35 @@ { if (quickChain) printf("", hgTracksName(), toDb->name, chain->qName, qStart+1, qEnd, quickHub, toDb->name, quickChain); else printf("", hgTracksName(), toDb->name, chain->qName, qStart+1, qEnd); startedAnchor = TRUE; } printf("%s:%d-%d", chain->qName, qStart+1, qEnd); if (startedAnchor) printf(""); printf(" (%3.1f%% of bases, %3.1f%% of span)
\n", 100.0 * blockSize/origSize, 100.0 * (chain->tEnd - chain->tStart) / origSize); +#ifdef NTONOW + if (doSegments) + drawSegments(fromDb->name, toDb->name, chain); + break; +#endif } } if (badList) { printf("
Some of your tracks failed to lift because the type is not supported by quickLift.

"); printf("
"); for(; badList; badList = badList->next) { printf("", badList->shortLabel, badList->type); } printf("
Short labelType
%s%s
"); } cartWebEnd(); }