5839fc5f68fc919fc61fad936929af799c52f577 angie Fri Apr 3 12:08:21 2020 -0700 Add RGB colors to Nextstrain trees as fake branch lengths. Make hapClusterMethod treeFile use branch lengths as RGB colors. refs #25278 diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c index 76913db..90b611f 100644 --- src/hg/hgTracks/vcfTrack.c +++ src/hg/hgTracks/vcfTrack.c @@ -1387,118 +1387,120 @@ coords->depth = maxDepth + 1; } else { // Leaf (sample) double rankStart = leafOrderToHapOrderStart[leafIx]; double rankEnd = leafOrderToHapOrderStart[leafIx]; coords->rank = (rankStart + rankEnd) / 2.0; leafIx++; coords->depth = 0; } return leafIx; } static void rDrawPhyloTreeInLabelArea(struct phyloTree *node, struct hvGfx *hvg, int x, - int yOff, double pxPerHap, Color color, MgFont *font, + int yOff, double pxPerHap, MgFont *font, boolean drawRectangle) -/* Recursively draw the tree in the left label area. - * Returns pixel height for use at non-leaf levels of tree. */ +/* Recursively draw the tree in the left label area. */ { const int branchW = 4; int labelEnd = leftLabelX + leftLabelWidth; - +// Misuse the branch length value as RGB color (if it's the typical small number, will still +// draw as approximately black): +unsigned int rgb = node->ident->length; +Color color = MAKECOLOR_32( ((rgb>>16)&0xff), ((rgb>>8)&0xff), (rgb&0xff) ); if (node->numEdges > 0) { // Draw each child and a horizontal line to child int minY = -1, maxY = 0; int ix; for (ix = 0; ix < node->numEdges; ix++) { struct phyloTree *child = node->edges[ix]; - rDrawPhyloTreeInLabelArea(child, hvg, x+branchW, yOff, pxPerHap, color, font, drawRectangle); + rDrawPhyloTreeInLabelArea(child, hvg, x+branchW, yOff, pxPerHap, font, drawRectangle); struct nodeCoords *childCoords = child->priv; int childY = yOff + ((0.5 + childCoords->rank) * pxPerHap); - hvGfxLine(hvg, x, childY, x+branchW, childY, MG_BLACK); + hvGfxLine(hvg, x, childY, x+branchW, childY, color); if (minY < 0 || childY < minY) minY = childY; if (childY > maxY) maxY = childY; } // Draw a vertical line to connect the children - hvGfxLine(hvg, x, minY, x, maxY, MG_BLACK); + hvGfxLine(hvg, x, minY, x, maxY, color); } else { - // Leaf node -- draw a horizontal line + // Leaf node -- draw a horizontal line, and label if there is space to right of tree struct nodeCoords *coords = node->priv; int y = yOff + ((0.5 + coords->rank) * pxPerHap); hvGfxLine(hvg, x, y, x+branchW, y, color); int textX = x + branchW + 3; if (pxPerHap >= tl.fontHeight+1 && textX < labelEnd) - hvGfxText(hvg, textX, y, color, font, node->ident->name); + hvGfxText(hvg, textX, y, MG_BLACK, font, node->ident->name); } } static void drawPhyloTreeInLabelArea(struct phyloTree *tree, struct hvGfx *hvg, int yOff, int clipHeight, int gtHapCount, - Color color, MgFont *font, boolean drawRectangle, + MgFont *font, boolean drawRectangle, unsigned short *leafOrderToHapOrderStart, unsigned short *leafOrderToHapOrderEnd) { struct hvGfx *hvgLL = (hvgSide != NULL) ? hvgSide : hvg; int clipXBak, clipYBak, clipWidthBak, clipHeightBak; hvGfxGetClip(hvgLL, &clipXBak, &clipYBak, &clipWidthBak, &clipHeightBak); hvGfxUnclip(hvgLL); hvGfxSetClip(hvgLL, leftLabelX, yOff, leftLabelWidth, clipHeight); // Figure out rank (vertical position) and depth (horizontal position) of every node in tree: phyloTreeAddNodeCoords(tree, leafOrderToHapOrderStart, leafOrderToHapOrderEnd, 0); // Draw the tree: int x = leftLabelX; double pxPerHap = (double)clipHeight / gtHapCount; -rDrawPhyloTreeInLabelArea(tree, hvgLL, x, yOff, pxPerHap, color, font, drawRectangle); +rDrawPhyloTreeInLabelArea(tree, hvgLL, x, yOff, pxPerHap, font, drawRectangle); // Restore the prior clipping: hvGfxUnclip(hvgLL); hvGfxSetClip(hvgLL, clipXBak, clipYBak, clipWidthBak, clipHeightBak); } static void vcfGtHapTreeFileDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw rows in the same fashion as vcfHapClusterDraw, but instead of clustering, use the * order in which samples appear in the VCF file. */ { struct vcfFile *vcff = tg->extraUiData; enum hapColorMode colorMode; if (!vcfHapClusterDrawInit(tg, vcff, hvg, &colorMode)) return; struct phyloTree *tree = getTreeFromFile(tg->tdb); int gtHapCount; unsigned short *leafOrderToHapOrderStart, *leafOrderToHapOrderEnd; unsigned short *gtHapOrder = gtHapOrderFromTree(vcff, tree, &leafOrderToHapOrderStart, &leafOrderToHapOrderEnd, >HapCount); struct vcfRecord *rec; for (rec = vcff->records; rec != NULL; rec = rec->next) drawOneRec(rec, gtHapOrder, gtHapCount, tg, hvg, xOff, yOff, width, FALSE, FALSE, colorMode); int extraPixel = (colorMode == altOnlyMode) ? 1 : 0; int hapHeight = tg->height - CLIP_PAD - 2*extraPixel; char *treeAngle = cartOrTdbString(cart, tg->tdb, VCF_HAP_TREEANGLE_VAR, VCF_DEFAULT_HAP_TREEANGLE); boolean drawRectangle = sameString(treeAngle, VCF_HAP_TREEANGLE_RECTANGLE); -drawPhyloTreeInLabelArea(tree, hvg, yOff+extraPixel, hapHeight, gtHapCount, color, font, +drawPhyloTreeInLabelArea(tree, hvg, yOff+extraPixel, hapHeight, gtHapCount, font, drawRectangle, leafOrderToHapOrderStart, leafOrderToHapOrderEnd); drawSampleTitles(vcff, yOff+extraPixel, hapHeight, gtHapOrder, gtHapCount, tg->track); } static int vcfHapClusterTotalHeight(struct track *tg, enum trackVisibility vis) /* Return height of haplotype graph (2 * #samples * lineHeight); * 2 because we're assuming diploid genomes here, no XXY, tetraploid etc. */ { const struct vcfFile *vcff = tg->extraUiData; if (vcff->records == NULL) return 0; int ploidy = sameString(chromName, "chrY") ? 1 : 2; int simpleHeight = ploidy * vcff->genotypeCount * tg->lineHeight; int defaultHeight = min(simpleHeight, VCF_DEFAULT_HAP_HEIGHT); char *tdbHeight = trackDbSettingOrDefault(tg->tdb, VCF_HAP_HEIGHT_VAR, NULL);