0cbeed8fcb8eccd05e18cea41d4954f20d7698bd
angie
  Wed Jul 9 13:45:50 2014 -0700
Added trackDb settings for initializing VCF track controls.This will be useful for CTs/hub tracks to turn off haplotype clustering
or apply minimum QUAL score / minimum minor allele frequency filters.

diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c
index dbd45af..07203bb9 100644
--- src/hg/hgTracks/vcfTrack.c
+++ src/hg/hgTracks/vcfTrack.c
@@ -10,36 +10,34 @@
 #include "hacTree.h"
 #include "hdb.h"
 #include "hgColors.h"
 #include "hgTracks.h"
 #include "pgSnp.h"
 #include "trashDir.h"
 #include "vcf.h"
 #include "vcfUi.h"
 #include "knetUdc.h"
 #include "udc.h"
 
 
 static boolean getMinQual(struct trackDb *tdb, double *retMinQual)
 /* Return TRUE and set retMinQual if cart contains minimum QUAL filter */
 {
-if (cartUsualBooleanClosestToHome(cart, tdb, FALSE,
-				  VCF_APPLY_MIN_QUAL_VAR, VCF_DEFAULT_APPLY_MIN_QUAL))
+if (cartOrTdbBoolean(cart, tdb, VCF_APPLY_MIN_QUAL_VAR, VCF_DEFAULT_APPLY_MIN_QUAL))
     {
     if (retMinQual != NULL)
-	*retMinQual = cartUsualDoubleClosestToHome(cart, tdb, FALSE, VCF_MIN_QUAL_VAR,
-						   VCF_DEFAULT_MIN_QUAL);
+	*retMinQual = cartOrTdbDouble(cart, tdb, VCF_MIN_QUAL_VAR, VCF_DEFAULT_MIN_QUAL);
     return TRUE;
     }
 return FALSE;
 }
 
 static boolean minQualFail(struct vcfRecord *record, double minQual)
 /* Return TRUE if record's QUAL column value is non-numeric or is less than minQual. */
 {
 if (isEmpty(record->qual) ||
     (record->qual[0] != '-' && !isdigit(record->qual[0])) ||
     atof(record->qual) < minQual)
     return TRUE;
 return FALSE;
 }
 
@@ -58,41 +56,37 @@
 }
 
 static boolean filterColumnFail(struct vcfRecord *record, struct slName *filterValues)
 /* Return TRUE if record's FILTER column value(s) matches one of filterValues (from cart). */
 {
 int i;
 for (i = 0;  i < record->filterCount;  i++)
     if (slNameInList(filterValues, record->filters[i]))
 	return TRUE;
 return FALSE;
 }
 
 static boolean getMinFreq(struct trackDb *tdb, double *retMinFreq)
 /* Return TRUE and set retMinFreq if cart contains nonzero minimum minor allele frequency. */
 {
-if (cartVarExistsAnyLevel(cart, tdb, FALSE, VCF_MIN_ALLELE_FREQ_VAR))
-    {
-    double minFreq = cartUsualDoubleClosestToHome(cart, tdb, FALSE,
-					    VCF_MIN_ALLELE_FREQ_VAR, VCF_DEFAULT_MIN_ALLELE_FREQ);
+double minFreq = cartOrTdbDouble(cart, tdb, VCF_MIN_ALLELE_FREQ_VAR, VCF_DEFAULT_MIN_ALLELE_FREQ);
 if (minFreq > 0)
     {
     if (retMinFreq != NULL)
 	*retMinFreq = minFreq;
     return TRUE;
     }
-    }
 return FALSE;
 }
 
 static boolean minFreqFail(struct vcfRecord *record, double minFreq)
 /* Return TRUE if record's INFO include AF (alternate allele frequencies) or AC+AN
  * (alternate allele counts and total count of observed alleles) and the minor allele
  * frequency < minFreq -- or rather, major allele frequency > (1 - minFreq) because
  * variants with > 2 alleles might have some significant minor frequencies along with
  * tiny minor frequencies). */
 {
 struct vcfFile *vcff = record->file;
 boolean gotInfo = FALSE;
 double refFreq = 1.0;
 double maxAltFreq = 0.0;
 int i;
@@ -112,36 +106,36 @@
 	    maxAltFreq = altFreq;
 	}
     }
 else
     {
     // Calculate alternate allele freqs from AC and AN:
     const struct vcfInfoElement *acEl = vcfRecordFindInfo(record, "AC");
     const struct vcfInfoDef *acDef = vcfInfoDefForKey(vcff, "AC");
     const struct vcfInfoElement *anEl = vcfRecordFindInfo(record, "AN");
     const struct vcfInfoDef *anDef = vcfInfoDefForKey(vcff, "AN");
     if (acEl != NULL && acDef != NULL && acDef->type == vcfInfoInteger &&
 	anEl != NULL && anDef != NULL && anDef->type == vcfInfoInteger && anEl->count == 1 &&
 	anEl->missingData[0] == FALSE)
 	{
 	gotInfo = TRUE;
-	int totalCount = anEl->values[0].datFloat;
+	int totalCount = anEl->values[0].datInt;
 	for (i = 0;  i < acEl->count;  i++)
 	    {
 	    if (acEl->missingData[i])
 		continue;
-	    int altCount = acEl->values[i].datFloat;
+	    int altCount = acEl->values[i].datInt;
 	    double altFreq = (double)altCount / totalCount;
 	    refFreq -= altFreq;
 	    if (altFreq < maxAltFreq)
 		maxAltFreq = altFreq;
 	    }
 	}
     else
         // Use MAF for alternate allele freqs from MAF:
         {
         const struct vcfInfoElement *mafEl = vcfRecordFindInfo(record, "MAF");
         const struct vcfInfoDef *mafDef = vcfInfoDefForKey(vcff, "MAF");
         if (mafEl != NULL && mafDef != NULL && mafDef->type == vcfInfoString
         && startsWith("Minor Allele Frequency",mafDef->description))
             {
             // If INFO includes alt allele freqs, use them directly.
@@ -1010,32 +1004,31 @@
 // Restore the prior clipping:
 hvGfxUnclip(hvgLL);
 hvGfxSetClip(hvgLL, clipXBak, clipYBak, clipWidthBak, clipHeightBak);
 }
 
 static void ignoreEm(char *format, va_list args)
 /* Ignore warnings from genotype parsing -- when there's one, there
  * are usually hundreds more just like it. */
 {
 }
 
 static enum hapColorMode getColorMode(struct trackDb *tdb)
 /* Get the hap-cluster coloring mode from cart & tdb. */
 {
 enum hapColorMode colorMode = altOnlyMode;
-char *colorBy = cartUsualStringClosestToHome(cart, tdb, FALSE,
-					     VCF_HAP_COLORBY_VAR, VCF_DEFAULT_HAP_COLORBY);
+char *colorBy = cartOrTdbString(cart, tdb, VCF_HAP_COLORBY_VAR, VCF_DEFAULT_HAP_COLORBY);
 if (sameString(colorBy, VCF_HAP_COLORBY_ALTONLY))
     colorMode = altOnlyMode;
 else if (sameString(colorBy, VCF_HAP_COLORBY_REFALT))
     colorMode = refAltMode;
 else if (sameString(colorBy, VCF_HAP_COLORBY_BASE))
     colorMode = baseMode;
 return colorMode;
 }
 
 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. */
 {
@@ -1080,52 +1073,50 @@
     if (ix != centerIx)
 	drawOneRec(rec, gtHapOrder, gtHapCount, tg, hvg, xOff, yOff, width, isClustered, FALSE,
 		   colorMode);
     }
 // Draw the center rec on top, outlined with black lines, to make sure it is very visible:
 drawOneRec(centerRec, gtHapOrder, gtHapCount, tg, hvg, xOff, yOff, width, TRUE, TRUE,
 	   colorMode);
 // Draw as much of the tree as can fit in the left label area:
 int extraPixel = (colorMode == altOnlyMode) ? 1 : 0;
 int hapHeight = tg->height- CLIP_PAD - 2*extraPixel;
 struct yFromNodeHelper yHelper = {0, NULL, NULL};
 initYFromNodeHelper(&yHelper, yOff+extraPixel, hapHeight, gtHapCount, gtHapOrder,
 		    vcff->genotypeCount);
 struct titleHelper titleHelper = { NULL, 0, 0, 0, 0, NULL, NULL };
 initTitleHelper(&titleHelper, tg->track, startIx, centerIx, endIx, nRecords, vcff);
-char *treeAngle = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, VCF_HAP_TREEANGLE_VAR,
-					       VCF_DEFAULT_HAP_TREEANGLE);
+char *treeAngle = cartOrTdbString(cart, tg->tdb, VCF_HAP_TREEANGLE_VAR, VCF_DEFAULT_HAP_TREEANGLE);
 boolean drawRectangle = sameString(treeAngle, VCF_HAP_TREEANGLE_RECTANGLE);
 drawTreeInLabelArea(ht, hvg, yOff+extraPixel, hapHeight+CLIP_PAD, &yHelper, &titleHelper,
 		    drawRectangle);
 }
 
 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);
 if (isNotEmpty(tdbHeight))
     defaultHeight = atoi(tdbHeight);
-int cartHeight = cartUsualIntClosestToHome(cart, tg->tdb, FALSE, VCF_HAP_HEIGHT_VAR,
-					   defaultHeight);
+int cartHeight = cartOrTdbInt(cart, tg->tdb, VCF_HAP_HEIGHT_VAR, defaultHeight);
 if (tg->visibility == tvSquish)
     cartHeight /= 2;
 int extraPixel = (getColorMode(tg->tdb) == altOnlyMode) ? 1 : 0;
 int totalHeight = cartHeight + CLIP_PAD + 2*extraPixel;
 tg->height = min(totalHeight, maximumTrackHeight(tg));
 return tg->height;
 }
 
 static char *vcfHapClusterTrackName(struct track *tg, void *item)
 /* If someone asks for itemName/mapItemName, just send name of track like wiggle. */
 {
 return tg->track;
 }
 
 static void vcfHapClusterOverloadMethods(struct track *tg, struct vcfFile *vcff)
@@ -1166,32 +1157,31 @@
 if (tg->parallelLoading)
     {
     /* do not use mysql during parallel-fetch load */
     fileOrUrl = trackDbSetting(tg->tdb, "bigDataUrl");
     }
 else
     {
     struct sqlConnection *conn = hAllocConnTrack(database, tg->tdb);
     fileOrUrl = bbiNameFromSettingOrTableChrom(tg->tdb, conn, tg->table, chromName);
     hFreeConn(&conn);
     }
 if (isEmpty(fileOrUrl))
     return;
 int vcfMaxErr = -1;
 struct vcfFile *vcff = NULL;
-boolean hapClustEnabled = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE,
-							VCF_HAP_ENABLED_VAR, TRUE);
+boolean hapClustEnabled = cartOrTdbBoolean(cart, tg->tdb, VCF_HAP_ENABLED_VAR, TRUE);
 /* protect against temporary network error */
 struct errCatch *errCatch = errCatchNew();
 if (errCatchStart(errCatch))
     {
     vcff = vcfTabixFileMayOpen(fileOrUrl, chromName, winStart, winEnd, vcfMaxErr, -1);
     if (vcff != NULL)
 	{
 	filterRecords(vcff, tg->tdb);
 	if (hapClustEnabled && vcff->genotypeCount > 1 && vcff->genotypeCount < 3000 &&
 	    (tg->visibility == tvPack || tg->visibility == tvSquish))
 	    vcfHapClusterOverloadMethods(tg, vcff);
 	else
 	    {
 	    tg->items = vcfFileToPgSnp(vcff, tg->tdb);
 	    // pgSnp bases coloring/display decision on count of items:
@@ -1246,32 +1236,31 @@
 void vcfTabixMethods(struct track *track)
 /* Methods for VCF alignment files, in absence of tabix lib. */
 {
 // NOP warning method to warn users that tabix is not installed.
 messageLineMethods(track);
 track->drawItems = drawUseVcfTabixWarning;
 }
 
 #endif // no USE_TABIX
 
 static void vcfLoadItems(struct track *tg)
 /* Load items in window from VCF file. */
 {
 int vcfMaxErr = -1;
 struct vcfFile *vcff = NULL;
-boolean hapClustEnabled = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE,
-							VCF_HAP_ENABLED_VAR, TRUE);
+boolean hapClustEnabled = cartOrTdbBoolean(cart, tg->tdb, VCF_HAP_ENABLED_VAR, TRUE);
 char *table = tg->table;
 struct customTrack *ct = tg->customPt;
 struct sqlConnection *conn;
 if (ct == NULL)
     conn = hAllocConnTrack(database, tg->tdb);
 else
     {
     conn = hAllocConn(CUSTOM_TRASH);
     table = ct->dbTableName;
     }
 char *vcfFile = bbiNameFromSettingOrTable(tg->tdb, conn, table);
 hFreeConn(&conn);
 /* protect against parse error */
 struct errCatch *errCatch = errCatchNew();
 if (errCatchStart(errCatch))