f00ee8d8e407da35c50e5d61815250a49960dabe angie Tue Dec 5 13:52:12 2023 -0800 More refinements for displaying RSV results. Still need to make it more config-driven. diff --git src/hg/hgPhyloPlace/treeToAuspiceJson.c src/hg/hgPhyloPlace/treeToAuspiceJson.c index cc70972..b5e945f 100644 --- src/hg/hgPhyloPlace/treeToAuspiceJson.c +++ src/hg/hgPhyloPlace/treeToAuspiceJson.c @@ -182,31 +182,31 @@ auspiceMetaColoringCategorical(jw, col->name, "RGCC lineage assigned by nextclade"); else if (sameString(col->name, "GCC_usher")) auspiceMetaColoringCategorical(jw, col->name, "RGCC lineage assigned by UShER"); else if (sameString(col->name, "GCC_assigned_2023-11")) auspiceMetaColoringCategorical(jw, col->name, "RGCC designated lineage"); else if (sameString(col->name, "country")) auspiceMetaColoringCategorical(jw, col->name, "Country"); else auspiceMetaColoringCategorical(jw, col->name, col->name); } jsonWriteListEnd(jw); } static void writeAuspiceMeta(struct jsonWrite *jw, struct slName *subtreeUserSampleIds, char *source, char *db, struct slName *colorFields, struct geneInfo *geneInfoList, - uint genomeSize) + uint genomeSize, boolean isRsv, boolean isFlu) /* Write metadata to configure Auspice display. */ { jsonWriteObjectStart(jw, "meta"); // Title struct dyString *dy = dyStringCreate("Subtree with %s", subtreeUserSampleIds->name); int sampleCount = slCount(subtreeUserSampleIds); if (sampleCount > 10) dyStringPrintf(dy, " and %d other uploaded samples", sampleCount - 1); else { struct slName *sln; for (sln = subtreeUserSampleIds->next; sln != NULL; sln = sln->next) dyStringPrintf(dy, ", %s", sln->name); } jsonWriteString(jw, "title", dy->string); @@ -233,39 +233,39 @@ auspiceMetaColorings(jw, source, colorFields, db); // Filters didn't work when I tried them a long time ago... revisit someday. jsonWriteListStart(jw, "filters"); jsonWriteString(jw, NULL, "userOrOld"); jsonWriteString(jw, NULL, "country"); //#*** FIXME: TODO: either pass in along with sampleMetadata, or take from JSON file specified //#*** in config, or better yet, compute while building tree object in memory, then write the //#*** header object, then write the tree. if (sameString(db, "wuhCor1")) { jsonWriteString(jw, NULL, "pango_lineage_usher"); jsonWriteString(jw, NULL, "pango_lineage"); jsonWriteString(jw, NULL, "Nextstrain_clade_usher"); jsonWriteString(jw, NULL, "Nextstrain_clade"); } -else if (stringIn("GCF_000855545", db) || stringIn("GCF_002815475", db) || stringIn("RGCC", db)) +else if (isRsv) { jsonWriteString(jw, NULL, "GCC_usher"); jsonWriteString(jw, NULL, "GCC_nextclade"); jsonWriteString(jw, NULL, "GCC_assigned_2023-11"); jsonWriteString(jw, NULL, "goya_usher"); jsonWriteString(jw, NULL, "goya_nextclade"); } -else if (stringIn("GCF_000865085", db) || stringIn("GCF_001343785", db)) +else if (isFlu) { jsonWriteString(jw, NULL, "Nextstrain_clade"); } else { jsonWriteString(jw, NULL, "Nextstrain_lineage"); } jsonWriteListEnd(jw); // Annotations for coloring/filtering by base writeAuspiceMetaGenomeAnnotations(jw, geneInfoList, genomeSize); jsonWriteObjectEnd(jw); } static void jsonWriteObjectValueUrl(struct jsonWrite *jw, char *name, char *value, char *url) /* Write an object with member "value" set to value, and if url is non-empty, "url" set to url. */ @@ -824,62 +824,64 @@ void treeToAuspiceJson(struct subtreeInfo *sti, char *db, struct geneInfo *geneInfoList, struct seqWindow *gSeqWin, struct hash *sampleMetadata, struct hash *sampleUrls, struct hash *samplePlacements, char *jsonFile, char *source) /* Write JSON for tree in Nextstrain's Augur/Auspice V2 JSON format * (https://github.com/nextstrain/augur/blob/master/augur/data/schema-export-v2.json). */ { struct phyloTree *tree = sti->subtree; FILE *outF = mustOpen(jsonFile, "w"); struct jsonWrite *jw = jsonWriteNew(); jsonWriteObjectStart(jw, NULL); jsonWriteString(jw, "version", "v2"); //#*** FIXME: TODO: either pass in along with sampleMetadata, or take from JSON file specified //#*** in config, or better yet, compute while building tree object in memory, then write the //#*** header object, then write the tree. -boolean isRsv = (stringIn("GCF_000855545", db) || stringIn("GCF_002815475", db) || stringIn("RGCC", db)); +boolean isRsv = (stringIn("GCF_000855545", db) || stringIn("GCF_002815475", db) || + startsWith("RGCC", db)); +boolean isFlu = (stringIn("GCF_000865085", db) || stringIn("GCF_001343785", db)); struct slName *colorFields = NULL; if (sameString(db, "wuhCor1")) { slNameAddHead(&colorFields, "country"); slNameAddHead(&colorFields, "Nextstrain_clade_usher"); slNameAddHead(&colorFields, "pango_lineage_usher"); slNameAddHead(&colorFields, "Nextstrain_clade"); slNameAddHead(&colorFields, "pango_lineage"); } else if (isRsv) { slNameAddHead(&colorFields, "country"); slNameAddHead(&colorFields, "GCC_nextclade"); slNameAddHead(&colorFields, "GCC_usher"); slNameAddHead(&colorFields, "GCC_assigned_2023-11"); slNameAddHead(&colorFields, "goya_nextclade"); slNameAddHead(&colorFields, "goya_usher"); } -else if (stringIn("GCF_000865085", db) || stringIn("GCF_001343785", db)) +else if (isFlu) { slNameAddHead(&colorFields, "country"); slNameAddHead(&colorFields, "Nextstrain_clade"); } else { slNameAddHead(&colorFields, "country"); slNameAddHead(&colorFields, "Nextstrain_lineage"); } //#*** END FIXME writeAuspiceMeta(jw, sti->subtreeUserSampleIds, source, db, colorFields, geneInfoList, - gSeqWin->end); + gSeqWin->end, isRsv, isFlu); jsonWriteObjectStart(jw, "tree"); int nodeNum = 10000; // Auspice.us starting node number for newick -> json int depth = 0; // Add an extra root node because otherwise Auspice won't draw branch from big tree root to subtree struct phyloTree *root = phyloTreeNewNode("wrapper"); phyloAddEdge(root, tree); tree = root; struct auspiceJsonInfo aji = { jw, sti->subtreeUserSampleIds, geneInfoList, gSeqWin, sampleMetadata, sampleUrls, samplePlacements, nodeNum, source }; rTreeToAuspiceJson(tree, depth, &aji, NULL, isRsv, NULL, NULL, NULL, NULL, NULL, NULL, NULL); jsonWriteObjectEnd(jw); // tree jsonWriteObjectEnd(jw); // top-level object fputs(jw->dy->string, outF); jsonWriteFree(&jw);