84fc7dd7df5303df374f00530a8d590ae550e5db angie Wed Aug 10 08:12:11 2011 -0700 Feature #3710 (vcfTabix UI options): added option to use pgSnp colors instead of blueRef/redAlt in haplotype sorting display. diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c index 5d3d96f..2e73653 100644 --- src/hg/hgTracks/vcfTrack.c +++ src/hg/hgTracks/vcfTrack.c @@ -290,51 +290,41 @@ while (c != NULL && c->next != NULL) { if (c->next->leafCount == 0) c->next = c->next->next; c = c->next; } } } struct hacTree *ht = hacTreeFromItems((struct slList *)(hapArray[0]), lm, cwaDistance, cwaMerge, cwaCmp, &helper); unsigned short *gtHapOrder = needMem(vcff->genotypeCount * 2 * sizeof(unsigned short)); rSetGtHapOrder(ht, gtHapOrder, retGtHapEnd); return gtHapOrder; } -//#*** unused... add UI option... -INLINE Color colorFromGt(struct vcfGenotype *gt, int ploidIx, char **alleles, - boolean grayUnphasedHet) -/* Color allele by base. */ -{ -int hapIx = ploidIx ? gt->hapIxB : gt->hapIxA; -char *allele = alleles[hapIx]; -if (gt->isHaploid && hapIx > 0) - return shadesOfGray[5]; -if (grayUnphasedHet && !gt->isPhased && gt->hapIxA != gt->hapIxB) - return shadesOfGray[5]; -// Copying pgSnp color scheme here, using first base of allele which is not ideal for multibase -// but allows us to simplify it to 5 colors: -else if (allele[0] == 'A') - return MG_RED; +INLINE Color pgSnpColor(char *allele) +/* Color allele by first base according to pgSnp palette. */ +{ +if (allele[0] == 'A') + return revCmplDisp ? MG_MAGENTA : MG_RED; else if (allele[0] == 'C') - return MG_BLUE; + return revCmplDisp ? darkGreenColor : MG_BLUE; else if (allele[0] == 'G') - return darkGreenColor; + return revCmplDisp ? MG_BLUE : darkGreenColor; else if (allele[0] == 'T') - return MG_MAGENTA; + return revCmplDisp ? MG_RED : MG_MAGENTA; else return shadesOfGray[5]; } INLINE char *gtSummaryString(struct vcfRecord *rec) // Make pgSnp-like mouseover text, but with genotype counts instead of allele counts. // NOTE: Returned string is statically allocated, don't free it! { static struct dyString *dy = NULL; if (dy == NULL) dy = dyStringNew(0); else dyStringClear(dy); if (rec->alleleCount < 2) return ""; @@ -366,31 +356,31 @@ dyStringPrintf(dy, " other:%d", gtOtherCount); // Restore original values of pooled strings. if (revCmplDisp) { for (i=0; i < rec->alleleCount; i++) reverseComplement(rec->alleles[i], strlen(rec->alleles[i])); } return dy->string; } // This is initialized when we start drawing: static Color purple = 0; static void drawOneRec(struct vcfRecord *rec, unsigned short *gtHapOrder, int gtHapEnd, struct track *tg, struct hvGfx *hvg, int xOff, int yOff, int width, - boolean isCenter) + boolean isCenter, boolean colorByRefAlt) /* Draw a stack of genotype bars for this record */ { const double scale = scaleForPixels(width); int x1 = round((double)(rec->chromStart-winStart)*scale) + xOff; int x2 = round((double)(rec->chromEnd-winStart)*scale) + xOff; int w = x2-x1; if (w <= 1) { x1--; w = 3; } double hapsPerPix = (2 * (double)rec->file->genotypeCount / tg->height); int pixIx; for (pixIx = 0; pixIx < tg->height; pixIx++) { @@ -410,35 +400,35 @@ unks++; else { int alIx = hapIx ? gt->hapIxB : gt->hapIxA; if (alIx) alts++; else refs++; } } const int fudgeFactor = 4; Color col = MG_BLACK; if (unks > (refs + alts)) col = shadesOfGray[5]; else if (alts > fudgeFactor * refs) - col = MG_RED; + col = colorByRefAlt ? MG_RED : pgSnpColor(rec->alleles[1]); else if (refs > fudgeFactor * alts) - col = MG_BLUE; + col = colorByRefAlt ? MG_BLUE : pgSnpColor(rec->alleles[0]); else - col = purple; + col = colorByRefAlt ? purple : shadesOfGray[5]; int y = yOff + pixIx; hvGfxLine(hvg, x1, y, x2, y, col); } char *mouseoverText = gtSummaryString(rec); if (isCenter) { // Thick black lines to distinguish this variant: int yBot = yOff + tg->height - 2; hvGfxBox(hvg, x1-3, yOff, 3, tg->height, MG_BLACK); hvGfxBox(hvg, x2, yOff, 3, tg->height, MG_BLACK); hvGfxLine(hvg, x1-2, yOff, x2+2, yOff, MG_BLACK); hvGfxLine(hvg, x1-2, yBot, x2+2, yBot, MG_BLACK); // Special mouseover instructions: static struct dyString *dy = NULL; if (dy == NULL) @@ -484,43 +474,47 @@ } } return defaultIx; } static void vcfHapClusterDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Split samples' chromosomes (haplotypes), cluster them by center-weighted * alpha similarity, and draw in the order determined by clustering. */ { const struct vcfFile *vcff = tg->extraUiData; if (vcff->records == NULL) return; purple = hvGfxFindColorIx(hvg, 0x99, 0x00, 0xcc); +boolean compositeLevel = isNameAtCompositeLevel(tg->tdb, tg->tdb->track); +char *colorBy = cartUsualStringClosestToHome(cart, tg->tdb, compositeLevel, + VCF_HAP_COLORBY_VAR, VCF_HAP_COLORBY_REFALT); +boolean colorByRefAlt = sameString(colorBy, VCF_HAP_COLORBY_REFALT); unsigned short gtHapEnd = 0; int ix, centerIx = getCenterVariantIx(tg, seqStart, seqEnd, vcff->records); unsigned short *gtHapOrder = clusterChroms(vcff, centerIx, >HapEnd); struct vcfRecord *rec, *centerRec = NULL; for (rec = vcff->records, ix=0; rec != NULL; rec = rec->next, ix++) { if (ix == centerIx) centerRec = rec; else - drawOneRec(rec, gtHapOrder, gtHapEnd, tg, hvg, xOff, yOff, width, FALSE); + drawOneRec(rec, gtHapOrder, gtHapEnd, tg, hvg, xOff, yOff, width, FALSE, colorByRefAlt); } // Draw the center rec on top, outlined with black lines, to make sure it is very visible: -drawOneRec(centerRec, gtHapOrder, gtHapEnd, tg, hvg, xOff, yOff, width, TRUE); +drawOneRec(centerRec, gtHapOrder, gtHapEnd, tg, hvg, xOff, yOff, width, TRUE, colorByRefAlt); } 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. */ { // Should we make it single-height when on chrY? 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); int cartHeight = cartOrTdbInt(cart, tg->tdb, VCF_HAP_HEIGHT_VAR, defaultHeight); tg->height = min(cartHeight, maximumTrackHeight(tg));