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, &gtHapEnd);
 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));