af86e1b9d932d0834eee1be7fe2ca77166203c48 angie Wed Mar 3 18:37:10 2021 -0800 Add row of quick download links between button row and summary table. diff --git src/hg/hgPhyloPlace/phyloPlace.c src/hg/hgPhyloPlace/phyloPlace.c index 184faff..cf2966e 100644 --- src/hg/hgPhyloPlace/phyloPlace.c +++ src/hg/hgPhyloPlace/phyloPlace.c @@ -2002,30 +2002,40 @@ struct lm *lm = lmInit(0); struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, chrom, 0, chromSize, 0, lm); for (bb = bbList; bb != NULL; bb = bb->next) { char *extra = bb->rest; char *reason = nextWord(&extra); int i; for (i = bb->start; i < bb->end; i++) slNameAddHead(&pSites[i], reason); } bigBedFileClose(&bbi); } return pSites; } +static void downloadsRow(char *treeFile, char *sampleSummaryFile, char *spikeSummaryFile) +/* Make a row of quick download file links, to appear between the button row & big summary table. */ +{ +printf("<p><b>Downloads:</b> | "); +printf("<a href='%s' download>Global phylogenetic tree with your sequences</a> | ", treeFile); +printf("<a href='%s' download>TSV summary of sequences and placements</a> | ", sampleSummaryFile); +printf("<a href='%s' download>TSV summary of Spike mutations</a> |", spikeSummaryFile); +puts("</p>"); +} + static int subTreeInfoUserSampleCmp(const void *pa, const void *pb) /* Compare subtreeInfo by number of user sample IDs (highest number first). */ { struct subtreeInfo *tiA = *(struct subtreeInfo **)pa; struct subtreeInfo *tiB = *(struct subtreeInfo **)pb; return slCount(tiB->subtreeUserSampleIds) - slCount(tiA->subtreeUserSampleIds); } char *phyloPlaceSamples(struct lineFile *lf, char *db, char *defaultProtobuf, boolean doMeasureTiming, int subtreeSize, int fontHeight) /* Given a lineFile that contains either FASTA or VCF, prepare VCF for usher; * if that goes well then run usher, report results, make custom track files * and return the top-level custom track file; otherwise return NULL. */ { char *ctFile = NULL; @@ -2150,71 +2160,73 @@ { AllocVar(jsonTns[ix]); trashDirFile(jsonTns[ix], "ct", "subtreeAuspice", ".json"); treeToAuspiceJson(ti, db, geneInfoList, gSeqWin, sampleMetadata, jsonTns[ix]->forCgi, source); } puts("<p></p>"); int subtreeButtonCount = subtreeCount; if (seqCount > MAX_SEQ_DETAILS || subtreeCount > MAX_SUBTREE_BUTTONS) subtreeButtonCount = 0; makeButtonRow(singleSubtreeJsonTn, jsonTns, subtreeButtonCount, isFasta); printf("<p>If you have metadata you wish to display, click a 'view subtree in " "Nextstrain' button, and then you can drag on a CSV file to " "<a href='"NEXTSTRAIN_DRAG_DROP_DOC"' target=_blank>add it to the tree view</a>." "</p>\n"); + + // Make custom tracks for uploaded samples and subtree(s). + struct phyloTree *sampleTree = NULL; + struct tempName *ctTn = writeCustomTracks(vcfTn, results, sampleIds, bigTree->tree, + source, fontHeight, &sampleTree, &startTime); + + // Make a sample summary TSV file and accumulate S gene changes + struct hash *spikeChanges = hashNew(0); + struct tempName *tsvTn = writeTsvSummary(results, sampleTree, sampleIds, seqInfoList, + geneInfoList, gSeqWin, spikeChanges, &startTime); + struct tempName *sTsvTn = writeSpikeChangeSummary(spikeChanges, slCount(sampleIds)); + downloadsRow(results->bigTreePlusTn->forHtml, tsvTn->forHtml, sTsvTn->forHtml); + if (seqCount <= MAX_SEQ_DETAILS) { summarizeSequences(seqInfoList, isFasta, results, jsonTns, sampleMetadata, bigTree, refGenome); 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"); makeNextstrainButtonN("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, sampleMetadata, bigTree, source); } reportTiming(&startTime, "describe placements"); } else printf("<p>(Skipping details and subtrees; " "you uploaded %d sequences, and details/subtrees are shown only when " "you upload at most %d sequences.)</p>\n", seqCount, MAX_SEQ_DETAILS); - // Make custom tracks for uploaded samples and subtree(s). - struct phyloTree *sampleTree = NULL; - struct tempName *ctTn = writeCustomTracks(vcfTn, results, sampleIds, bigTree->tree, - source, fontHeight, &sampleTree, &startTime); - - // Make a sample summary TSV file and accumulate S gene changes - struct hash *spikeChanges = hashNew(0); - struct tempName *tsvTn = writeTsvSummary(results, sampleTree, sampleIds, seqInfoList, - geneInfoList, gSeqWin, spikeChanges, &startTime); - struct tempName *sTsvTn = writeSpikeChangeSummary(spikeChanges, slCount(sampleIds)); - // Offer big tree w/new samples for download puts("<h3>Downloads</h3>"); puts("<ul>"); printf("<li><a href='%s' download>SARS-CoV-2 phylogenetic tree " "with your samples (Newick file)</a>\n", results->bigTreePlusTn->forHtml); printf("<li><a href='%s' download>TSV summary of sequences and placements</a>\n", tsvTn->forHtml); printf("<li><a href='%s' download>TSV summary of S (Spike) gene changes</a>\n", sTsvTn->forHtml); for (ix = 0, ti = results->subtreeInfoList; ti != NULL; ti = ti->next, ix++) { int subtreeUserSampleCount = slCount(ti->subtreeUserSampleIds); printf("<li><a href='%s' download>Subtree with %s", ti->subtreeTn->forHtml, ti->subtreeUserSampleIds->name); if (subtreeUserSampleCount > 10) @@ -2231,27 +2243,27 @@ if (subtreeUserSampleCount > 10) printf(" and %d other samples", subtreeUserSampleCount - 1); else { struct slName *sln; for (sln = ti->subtreeUserSampleIds->next; sln != NULL; sln = sln->next) printf(", %s", sln->name); } puts(" (JSON file)</a>"); } puts("</ul>"); // Notify in opposite order of custom track creation. puts("<h3>Custom tracks for viewing in the Genome Browser</h3>"); printf("<p>Added custom track of uploaded samples.</p>\n"); - if (subtreeCount <= MAX_SUBTREE_CTS) + if (subtreeCount > 0 && subtreeCount <= MAX_SUBTREE_CTS) printf("<p>Added %d subtree custom track%s.</p>\n", subtreeCount, (subtreeCount > 1 ? "s" : "")); ctFile = urlFromTn(ctTn); } else { warn("No subtree output from usher.\n"); } } return ctFile; }