9174a163b341bfd2dd5c8fe84952265e74bef32a
angie
Sun Sep 27 23:50:14 2020 -0700
Added setting sampleColorFile so one or more sample coloring schemes can be offered for the tree in VCF+tree tracks. refs #26177
TODO: document the new setting
diff --git src/hg/lib/vcfUi.c src/hg/lib/vcfUi.c
index 83066d9..53600c9 100644
--- src/hg/lib/vcfUi.c
+++ src/hg/lib/vcfUi.c
@@ -170,31 +170,36 @@
printf("
using the tree specified in file associated with track | ");
}
printf("");
cgiMakeRadioButton(varName, VCF_HAP_METHOD_CENTER_WEIGHTED,
sameString(hapMethod, VCF_HAP_METHOD_CENTER_WEIGHTED));
printf(" | ");
vcfCfgHaplotypeCenter(cart, tdb, track, parentLevel, vcff, NULL, NULL, 0, "mainForm");
puts(" |
");
cgiMakeRadioButton(varName, VCF_HAP_METHOD_FILE_ORDER,
sameString(hapMethod, VCF_HAP_METHOD_FILE_ORDER));
puts(" | using the order in which samples appear in the underlying VCF file |
");
puts("");
jsInlineF("$('input[type=radio][name=\"%s\"]').change(function() { "
"if (this.value == '"VCF_HAP_METHOD_CENTER_WEIGHTED"') {"
" $('#leafShapeContainer').show();"
+ " $('#sampleColorContainer').hide();"
+ "} else if (this.value == '"VCF_HAP_METHOD_TREE_FILE"') {"
+ " $('#sampleColorContainer').show();"
+ " $('#leafShapeContainer').hide();"
"} else {"
+ " $('#sampleColorContainer').hide();"
" $('#leafShapeContainer').hide();"
"}});\n",
varName);
}
}
//TODO: share this code w/hgTracks, hgc in hg/lib/vcfFile.c
static struct vcfFile *vcfHopefullyOpenHeader(struct cart *cart, struct trackDb *tdb)
/* Defend against network errors and return the vcfFile object with header data, or NULL. */
{
knetUdcInstall();
if (udcCacheTimeout() < 300)
udcSetCacheTimeout(300);
char *fileOrUrl = trackDbSetting(tdb, "bigDataUrl");
if (isEmpty(fileOrUrl))
@@ -266,30 +271,71 @@
{
cgiMakeRadioButton(varName, VCF_HAP_COLORBY_FUNCTION,
sameString(colorBy, VCF_HAP_COLORBY_FUNCTION));
printf("reference alleles invisible, alternate alleles in "
"red for non-synonymous, "
"green for synonymous, "
"blue for UTR/noncoding, "
"black otherwise
\n");
}
cgiMakeRadioButton(varName, VCF_HAP_COLORBY_REFALT, sameString(colorBy, VCF_HAP_COLORBY_REFALT));
printf("reference alleles in blue, alternate alleles in red
\n");
cgiMakeRadioButton(varName, VCF_HAP_COLORBY_BASE, sameString(colorBy, VCF_HAP_COLORBY_BASE));
printf("first base of allele (A = red, C = blue, G = green, T = magenta)
\n");
}
+static void vcfCfgHapClusterSampleColor(struct cart *cart, struct trackDb *tdb, char *name,
+ boolean parentLevel)
+/* If sampleColorFile specifies multiple files, when hapClusterMethod treeFile is selected,
+ * let the user choose sample-coloring scheme for the tree. */
+{
+char *tdbSetting = trackDbSetting(tdb, VCF_SAMPLE_COLOR_FILE);
+if (tdbSetting && strchr(tdbSetting, ' '))
+ {
+ char *hapMethod = cartOrTdbString(cart, tdb, VCF_HAP_METHOD_VAR, VCF_DEFAULT_HAP_METHOD);
+ printf("\n",
+ startsWithWord(VCF_HAP_METHOD_TREE_FILE, hapMethod) ? "" : " style='display: none;'");
+ printf("Sample coloring scheme for tree:
\n");
+ char *setting = cartOrTdbString(cart, tdb, VCF_SAMPLE_COLOR_FILE, tdbSetting);
+ char *options[16];
+ int optionCount = chopLine(tdbSetting, options);
+ char *labels[optionCount];
+ char *values[optionCount];
+ int i;
+ for (i = 0; i < optionCount; i++)
+ {
+ char *eq = strchr(options[i], '=');
+ if (eq)
+ {
+ *eq = '\0';
+ labels[i] = options[i];
+ replaceChar(options[i], '_', ' ');
+ values[i] = eq+1;
+ }
+ else
+ {
+ labels[i] = values[i] = options[i];
+ }
+ }
+ char *selected = strchr(setting, ' ') ? values[0] : setting;
+ char varName[1024];
+ safef(varName, sizeof varName, "%s." VCF_SAMPLE_COLOR_FILE, name);
+ cgiMakeDropListWithVals(varName, labels, values, optionCount, selected);
+ puts("
");
+ }
+}
+
static void vcfCfgHapClusterTreeAngle(struct cart *cart, struct trackDb *tdb, char *name,
boolean parentLevel)
/* Let the user choose branch shape. */
{
// This option applies only to center-weighted clustering; don't show option when some other
// method is selected.
char *hapMethod = cartOrTdbString(cart, tdb, VCF_HAP_METHOD_VAR, VCF_DEFAULT_HAP_METHOD);
printf("\n",
differentString(hapMethod, VCF_HAP_METHOD_CENTER_WEIGHTED) ? " style='display: none;'" : "");
printf("%s clustering tree leaf shape:
\n", vcfHaplotypeOrSample(cart));
char *treeAngle = cartOrTdbString(cart, tdb, VCF_HAP_TREEANGLE_VAR, VCF_DEFAULT_HAP_TREEANGLE);
char varName[1024];
safef(varName, sizeof(varName), "%s." VCF_HAP_TREEANGLE_VAR, name);
cgiMakeRadioButton(varName, VCF_HAP_TREEANGLE_TRIANGLE,
sameString(treeAngle, VCF_HAP_TREEANGLE_TRIANGLE));
@@ -313,30 +359,31 @@
cgiMakeIntVarInRange(varName, cartHeight, "Height (in pixels) of track", 5, "4", "10000");
puts("
");
}
}
static void vcfCfgHapCluster(struct cart *cart, struct trackDb *tdb, struct vcfFile *vcff,
char *name, boolean parentLevel)
/* Show controls for haplotype-sorting display, which only makes sense to do when
* the VCF file describes multiple genotypes. */
{
char *hapOrSample = vcfHaplotypeOrSample(cart);
printf("
%s sorting display
\n", hapOrSample);
vcfCfgHapClusterEnable(cart, tdb, name, parentLevel);
vcfCfgHaplotypeMethod(cart, tdb, name, parentLevel, vcff);
vcfCfgHapClusterTreeAngle(cart, tdb, name, parentLevel);
+vcfCfgHapClusterSampleColor(cart, tdb, name, parentLevel);
vcfCfgHapClusterColor(cart, tdb, name, parentLevel);
vcfCfgHapClusterHeight(cart, tdb, vcff, name, parentLevel);
}
static void vcfCfgMinQual(struct cart *cart, struct trackDb *tdb, struct vcfFile *vcff,
char *name, boolean parentLevel)
/* If checkbox is checked, apply minimum value filter to QUAL column. */
{
char cartVar[1024];
safef(cartVar, sizeof(cartVar), "%s." VCF_APPLY_MIN_QUAL_VAR, name);
boolean applyFilter = cartOrTdbBoolean(cart, tdb, VCF_APPLY_MIN_QUAL_VAR,
VCF_DEFAULT_APPLY_MIN_QUAL);
cgiMakeCheckBox(cartVar, applyFilter);
printf("Exclude variants with Quality/confidence score (QUAL) score less than\n");
double minQual = cartOrTdbDouble(cart, tdb, VCF_MIN_QUAL_VAR, VCF_DEFAULT_MIN_QUAL);