ac23b2beea95c281450dcbbaa40b2a03c2f8d141 angie Wed Nov 25 12:09:48 2020 -0800 Add 'view subtree in Nextstrain' button to each subtree section in results (user request). diff --git src/hg/hgPhyloPlace/phyloPlace.c src/hg/hgPhyloPlace/phyloPlace.c index 01ebcb2..c73fbec 100644 --- src/hg/hgPhyloPlace/phyloPlace.c +++ src/hg/hgPhyloPlace/phyloPlace.c @@ -850,53 +850,58 @@ { return cfgOption("nextstrainHost"); } static char *nextstrainUrlFromTn(struct tempName *jsonTn) /* Return a link to Nextstrain to view an annotated subtree. */ { char *jsonUrlForNextstrain = urlFromTn(jsonTn); char *protocol = strstr(jsonUrlForNextstrain, "://"); if (protocol) jsonUrlForNextstrain = protocol + strlen("://"); struct dyString *dy = dyStringCreate("%s/fetch/%s", nextstrainHost(), jsonUrlForNextstrain); return dyStringCannibalize(&dy); } -static void makeButtonRow(struct subtreeInfo *subtreeInfoList, struct tempName *jsonTns[], - boolean isFasta) -/* Russ's suggestion: row of buttons at the top to view results in GB, Nextstrain, Nextclade. */ -{ -puts("<p>"); -cgiMakeButton("submit", "view in Genome Browser"); -if (nextstrainHost()) +static void makeNextstrainButton(char *idBase, int ix, struct tempName *jsonTns[]) +/* Make a button to view results in Nextstrain. idBase is a short string and + * ix is 0-based subtree number. */ { - struct subtreeInfo *ti; - int ix; - for (ix = 0, ti = subtreeInfoList; ti != NULL; ti = ti->next, ix++) - { - printf(" "); char buttonId[256]; - safef(buttonId, sizeof buttonId, "viewNextstrain%d", ix+1); +safef(buttonId, sizeof buttonId, "%s%d", idBase, ix+1); char buttonLabel[256]; safef(buttonLabel, sizeof buttonLabel, "view subtree %d in Nextstrain", ix+1); char *nextstrainUrl = nextstrainUrlFromTn(jsonTns[ix]); struct dyString *js = dyStringCreate("window.open('%s');", nextstrainUrl); cgiMakeOnClickButton(buttonId, js->string, buttonLabel); dyStringFree(&js); freeMem(nextstrainUrl); } + +static void makeButtonRow(struct tempName *jsonTns[], int subtreeCount, boolean isFasta) +/* Russ's suggestion: row of buttons at the top to view results in GB, Nextstrain, Nextclade. */ +{ +puts("<p>"); +cgiMakeButton("submit", "view in Genome Browser"); +if (nextstrainHost()) + { + int ix; + for (ix = 0; ix < subtreeCount; ix++) + { + printf(" "); + makeNextstrainButton("viewNextstrainTopRow", ix, jsonTns); + } } if (0 && isFasta) { printf(" "); struct dyString *js = dyStringCreate("window.open('https://master.clades.nextstrain.org/" "?input-fasta=%s');", "needATn"); //#*** TODO: save FASTA to file cgiMakeOnClickButton("viewNextclade", js->string, "view sequences in Nextclade"); } puts("</p>"); } #define TOOLTIP(text) " <div class='tooltip'>(?)<span class='tooltiptext'>" text "</span></div>" static void printSummaryHeader(boolean isFasta) @@ -1365,42 +1370,44 @@ // Sort subtrees by number of user samples (largest first). slSort(&results->subtreeInfoList, subTreeInfoUserSampleCmp); // Make Nextstrain/auspice JSON file for each subtree. char *bigGenePredFile = phyloPlaceDbSettingPath(db, "bigGenePredFile"); char *metadataFile = phyloPlaceDbSettingPath(db, "metadataFile"); struct tempName *jsonTns[subtreeCount]; struct subtreeInfo *ti; int ix; for (ix = 0, ti = results->subtreeInfoList; ti != NULL; ti = ti->next, ix++) { AllocVar(jsonTns[ix]); trashDirFile(jsonTns[ix], "ct", "subtreeAuspice", ".json"); treeToAuspiceJson(ti, db, refGenome, bigGenePredFile, metadataFile, jsonTns[ix]->forCgi); } puts("<p></p>"); - makeButtonRow(results->subtreeInfoList, jsonTns, isFasta); + makeButtonRow(jsonTns, subtreeCount, isFasta); summarizeSequences(seqInfoList, isFasta, results, jsonTns, db, bigTree); reportTiming(&startTime, "write summary table (including reading in lineages)"); for (ix = 0, ti = results->subtreeInfoList; ti != NULL; ti = ti->next, ix++) { int subtreeUserSampleCount = slCount(ti->subtreeUserSampleIds); printf("<h3>Subtree %d: ", ix+1); if (subtreeUserSampleCount > 1) printf("%d related samples", subtreeUserSampleCount); else if (subtreeCount > 1) printf("Unrelated sample"); printf("</h3>\n"); + makeNextstrainButton("viewNextstrainSub", ix, jsonTns); + puts("<br>"); // Make a sub-subtree with only user samples for display: struct phyloTree *subtree = phyloOpenTree(ti->subtreeTn->forCgi); subtree = phyloPruneToIds(subtree, ti->subtreeUserSampleIds); describeSamplePlacements(ti->subtreeUserSampleIds, results->samplePlacements, subtree, bigTree, db); } reportTiming(&startTime, "describe placements"); // Make custom tracks for uploaded samples and subtree(s). struct tempName *ctTn = writeCustomTracks(vcfTn, results, sampleIds, bigTree->tree, fontHeight, &startTime); // Offer big tree w/new samples for download puts("<h3>Downloads</h3>"); puts("<ul>");