15e8651da02e09bbd37dbb404a966ed8c7d75167 braney Fri Sep 4 13:32:47 2026 -0700 hgc: show the lifted alignment on a quickLifted maf track's details page The page read the track's own file with reference coordinates and then went looking for a reference row named for the assembly on screen. Both kinds of maf track failed, differently: bigMaf aborted with "Couldn't find hg38.chr7 in maf" out of mafFindComponent, and wigMaf drew a page with a title and nothing under it, which is the worse of the two. quickLiftClickMafs reads the blocks over the ranges in the other assembly, on connections to that assembly, and maps them onto the reference, the same way the track loader does. refs #38249 diff --git src/hg/hgc/mafClick.c src/hg/hgc/mafClick.c index fb20647e4dd..7c22ecaecae 100644 --- src/hg/hgc/mafClick.c +++ src/hg/hgc/mafClick.c @@ -7,30 +7,31 @@ #include "hash.h" #include "linefile.h" #include "hgc.h" #include "maf.h" #include "obscure.h" #include "cheapcgi.h" #include "genePred.h" #include "botDelay.h" #include "hgMaf.h" #include "hui.h" #include "hCommon.h" #include "hubConnect.h" #include "trackHub.h" #include "chromAlias.h" #include "genark.h" +#include "quickLift.h" extern boolean issueBotWarning; #define ADDEXONCAPITAL /* Javascript to help make a selection from a drop-down * go back to the server. */ static char *autoSubmit = "document.gpForm.submit();"; static char *splitMafSrc(char *src, char *dbOnly, int dbOnlySize, struct hash *labelHash) /* Split a maf component src ("db.chrom") into db (in dbOnly) and chrom * (return value). If labelHash has an entry whose key is a prefix of src * ending at a dot, prefer that. This handles multi-dot db names like assembly * hub accessions ("GCF_000009085.1.NC_002163v1"). * Falls back to chopping at the first dot when no labelHash hit. */ @@ -536,30 +537,74 @@ "all", "diff", }; static void conservationStatsLink(struct trackDb *tdb, char *label, char *table) /* write link that to display statistics of phastCons table */ { char *chrom = cartCgiUsualString(cart, "c", "chr7"); printf("<A HREF=\"%s&g=%s&i=%s&c=%s&l=%d&r=%d&o=%d&db=%s" "&parentWigMaf=%s\" TARGET=\"_blank\">%s</A>", hgcPathAndSettings(), table, table, chrom, winStart, winEnd, winStart, database, tdb->track, label); } +static struct mafAli *quickLiftClickMafs(struct trackDb *tdb, char *fileName) +/* Load MAF blocks out of the assembly the track came from and map them onto the reference. + * The window is on the reference, and the blocks are not, so neither the coordinates nor + * the connections the caller has can be used as they stand. */ +{ +char *liftDb = trackDbSetting(tdb, "quickLiftDb"); +char *table = NULL; +quickLiftResolveTable(tdb, trackHubSkipHubName(tdb->table), &table, &liftDb); +char *quickLiftFile = trackDbSetting(tdb, "quickLiftUrl"); +boolean isBig = sameString(tdb->type, "bigMaf"); + +struct hash *chainHash = newHash(8); +struct quickLiftRange *range, *rangeList = quickLiftSourceRanges(quickLiftFile, seqName, + winStart, winEnd, chainHash); +struct mafAli *srcList = NULL; + +for (range = rangeList; range != NULL; range = range->next) + { + struct mafAli *someMafs = NULL; + if (isBig) + { + char *bigFile = trackDbSetting(tdb, "bigDataUrl"); + struct bbiFile *bbi = bigBedFileOpenAlias(bigFile, chromAliasFindAliases); + someMafs = bigMafLoadInRegion(bbi, range->chrom, range->start, range->end); + bbiFileClose(&bbi); + } + else + { + struct sqlConnection *srcConn = hAllocConn(liftDb); + struct sqlConnection *srcConn2 = hAllocConn(liftDb); + someMafs = mafLoadInRegion2(srcConn, srcConn2, table, range->chrom, + range->start, range->end, fileName); + hFreeConn(&srcConn); + hFreeConn(&srcConn2); + } + srcList = slCat(srcList, someMafs); + } + +// the reference row has to be named the way the code below goes looking for it +char refSrc[512]; +safef(refSrc, sizeof refSrc, "%s.%s", hubConnectSkipHubPrefix(database), seqName); +return quickLiftMafs(chainHash, srcList, liftDb, refSrc, hChromSize(database, seqName)); +} + static void mafOrAxtClick2(struct sqlConnection *conn, struct sqlConnection *conn2, struct trackDb *tdb, char *axtOtherDb, char *fileName) /* Display details for MAF or AXT tracks. */ { if (issueBotWarning) { char *ip = getenv("REMOTE_ADDR"); botDelayMessage(ip, botDelayMillis); } if (winEnd - winStart > 30000) { printf("Zoom so that window is 30,000 bases or less to see alignments and conservation statistics\n"); } else { struct mafAli *mafList = NULL, *maf, *subList = NULL; @@ -583,31 +628,33 @@ safef(buffer, sizeof(buffer), "%s.vis",tdb->track); if (useIrowChains) { if (!cartVarExists(cart, buffer) && (speciesTarget != NULL)) useTarg = TRUE; else { char *val; val = cartUsualString(cart, buffer, "useCheck"); useTarg = sameString("useTarg",val); } } - if (sameString(tdb->type, "bigMaf")) + if (quickLiftIsLifted(tdb)) + mafList = quickLiftClickMafs(tdb, fileName); + else if (sameString(tdb->type, "bigMaf")) { char *fileName = trackDbSetting(tdb, "bigDataUrl"); struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases); mafList = bigMafLoadInRegion(bbi, seqName, winStart, winEnd); } else mafList = mafOrAxtLoadInRegion2(conn,conn2, tdb, seqName, winStart, winEnd, axtOtherDb, fileName); safef(dbChrom, sizeof(dbChrom), "%s.%s", hubConnectSkipHubPrefix(database), seqName); safef(option, sizeof(option), "%s.speciesOrder", tdb->track); speciesOrder = cartUsualString(cart, option, NULL); if (speciesOrder == NULL) speciesOrder = trackDbSetting(tdb, "speciesOrder");