f80b3826a921197488ece1440ff08038ec9e572d braney Mon Jun 29 12:28:07 2026 -0700 hgConvert/hgTracks: add option to hide target default tracks on QuickLift convert Adds a "Hide all default tracks on the target" checkbox (on by default) to the Convert page when QuickLift is enabled. When set, the QuickLift link appends hideTracks=on, and hgTracks now leaves QuickLifted tracks visible when hiding the target assembly's default tracks. refs #37815 diff --git src/hg/hgConvert/hgConvert.c src/hg/hgConvert/hgConvert.c index 8f0fce284aa..55eacd11b4c 100644 --- src/hg/hgConvert/hgConvert.c +++ src/hg/hgConvert/hgConvert.c @@ -60,35 +60,37 @@ } 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 quickLift = FALSE; +boolean hideOtherTracks = TRUE; if (quickLiftEnabled(cart)) { askAboutQuickLift = TRUE; quickLift = cartUsualBoolean(cart, "doQuickLift", FALSE); + hideOtherTracks = cartUsualBoolean(cart, "hideTracksOnConvert", TRUE); } cartWebStart(cart, database, "Convert %s to New Assembly", fromPos); /* Include autocomplete libraries */ jsIncludeAutoCompleteLibs(); /* create HTML form */ puts("<FORM ACTION=\"../cgi-bin/hgConvert\" NAME=\"mainForm\">\n"); cartSaveSession(cart); cgiParagraph( "This tool converts the current genome browser position to the corresponding " "region in another assembly or species using genome sequence alignments. " "Select a target assembly below and click Submit to jump to the matching region. " @@ -135,30 +137,51 @@ hPrintf("<div class='currentSelection' id='toGenomeLabel'>%s</div>\n", selectedLabel); /* Assembly dropdown (updates based on genome selection) */ puts("<div class='fieldRow'>\n"); puts("<span class='fieldLabel'>Assembly:</span>\n"); dbList = hGetLiftOverToDatabases(liftOver->fromDb); printAllAssemblyListHtmlParm(liftOver->toDb, dbList, "hglft_toDbSelect", TRUE, "change", onChangeToOrg); puts("</div>\n"); /* QuickLift option */ if (askAboutQuickLift) { puts("<div class='fieldRow' style='margin-top: 15px;'>\n"); cgiMakeCheckBoxWithId("doQuickLift", quickLift, "doQuickLift"); puts(" <label for='doQuickLift' title='Display tracks from the source assembly mapped onto the target assembly'>QuickLift tracks</label>\n"); puts("</div>\n"); + + puts("<div class='fieldRow' id='hideTracksOnConvertRow' style='margin-top: 8px;'>\n"); + cgiMakeCheckBoxWithId("hideTracksOnConvert", hideOtherTracks, "hideTracksOnConvert"); + puts(" <label for='hideTracksOnConvert' title='Hide all of the target assembly default tracks, showing only the QuickLifted tracks'>Hide all default tracks on the target</label>\n"); + puts("</div>\n"); + + /* The hide option only applies when QuickLift is on; gray it out otherwise. */ + jsInline( + "function hgcUpdateHideTracks() {\n" + " let ql = document.getElementById('doQuickLift');\n" + " let hideBox = document.getElementById('hideTracksOnConvert');\n" + " let hideRow = document.getElementById('hideTracksOnConvertRow');\n" + " if (!ql || !hideBox || !hideRow) return;\n" + " hideBox.disabled = !ql.checked;\n" + " hideRow.style.opacity = ql.checked ? '1' : '0.5';\n" + "}\n" + "document.addEventListener('DOMContentLoaded', function() {\n" + " let ql = document.getElementById('doQuickLift');\n" + " if (ql) ql.addEventListener('change', hgcUpdateHideTracks);\n" + " hgcUpdateHideTracks();\n" + "});\n"); } puts("</div>\n"); /* end destination section */ puts("</div>\n"); /* end grid */ /* Submit button centered below */ puts("<div style='text-align: center; margin-top: 20px;'>\n"); cgiMakeButton(HGLFT_DO_CONVERT, "Submit"); puts("</div>\n"); /* JavaScript initialization for autocomplete with liftOver filtering */ jsInlineF( "let validTargets = new Set();\n" "\n" "fetch('../cgi-bin/hubApi/liftOver/listExisting?fromGenome=%s')\n" @@ -247,30 +270,36 @@ , liftOver->fromDb , HGLFT_TOORG_VAR , HGLFT_TODB_VAR , searchBarId, searchBarId, searchBarId, searchBarId , searchBarId, searchBarId, searchBarId ); puts("</FORM>\n"); webNewSection("Notes"); cgiParagraph( "<B>QuickLift tracks:</B> When enabled, QuickLift displays tracks from " "the source assembly mapped onto the target assembly, allowing you to view " "your current tracks in the context of the new genome. For more information, see the " "<A HREF=\"../goldenPath/help/quickLift.html\">QuickLift documentation</A>."); +cgiParagraph( + "<B>Hide all default tracks on the target:</B> When QuickLift is enabled, this " + "option (on by default) hides the target assembly's default tracks so that only " + "your QuickLifted tracks are shown, letting you focus on the tracks carried over " + "from the source assembly. Uncheck it to display the target assembly's default " + "tracks alongside the QuickLifted tracks."); cgiParagraph( "If your desired target assembly is not available, you can search for it " "and request it on our " "<A HREF=\"../assemblySearch.html\">Assembly Search</A> page."); cartWebEnd(); } static double scoreLiftOverChain(struct liftOverChain *chain, char *fromOrg, char *fromDb, char *toOrg, char *toDb, struct hash *dbRank ) /* Score the chain in terms of best match for cart settings */ { double score = 0; char *chainFromOrg = hOrganism(chain->fromDb); @@ -613,30 +642,32 @@ errAbort("Unable to find a chain file from %s to %s - please contact support", fromDb->name, toDb->name); fileName = hReplaceGbdbMustDownload(fileName); char *chrom; int start, end; int origSize; struct chain *chainList, *chain; 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"); +boolean hideOtherTracks = cartUsualBoolean(cart, "hideTracksOnConvert", TRUE); +cartRemove(cart, "hideTracksOnConvert"); unsigned quickChain = 0; unsigned quickHub = 0; struct trackDb *badList = NULL; if (doQuickLift) { 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; @@ -668,32 +699,33 @@ /* Check if the toDb database exists and if the chromosome sequence file (of the hgConvert result) exists in the location specified in chromInfo for the toDb. */ boolean chromSeqExists = (sqlDatabaseExists(toDb->name) && chromSeqFileExists(toDb->name, chain->qName)); /* Check if the toDb has active set to 1 in dbDb if the toDb database exists. If these conditions are met then print position link to browser for toDb, otherwise just print position without link. */ boolean startedAnchor = FALSE; visDy = newDyString(20); if ((hDbIsActive(toDb->name) && chromSeqExists) || startsWith("hub:",toDb->nibPath) || sameString(toDb->nibPath, "genark")) { if (quickChain) - printf("<A HREF=\"%s?db=%s&position=%s:%d-%d&quickLift.%d.%s=%d\">", - hgTracksName(), toDb->name, chain->qName, qStart+1, qEnd, quickHub, toDb->name, quickChain); + printf("<A HREF=\"%s?db=%s&position=%s:%d-%d&quickLift.%d.%s=%d%s\">", + hgTracksName(), toDb->name, chain->qName, qStart+1, qEnd, quickHub, toDb->name, quickChain, + hideOtherTracks ? "&hideTracks=on" : ""); else printf("<A HREF=\"%s?db=%s&position=%s:%d-%d\">", hgTracksName(), toDb->name, chain->qName, qStart+1, qEnd); startedAnchor = TRUE; } printf("%s:%d-%d", chain->qName, qStart+1, qEnd); if (startedAnchor) printf("</A>"); printf(" (%3.1f%% of bases, %3.1f%% of span)<BR>\n", 100.0 * blockSize/origSize, 100.0 * (chain->tEnd - chain->tStart) / origSize); #ifdef NTONOW if (doSegments) drawSegments(fromDb->name, toDb->name, chain); break;