4cab7f311cadce7428c1d7e1c4dfdcb0d3a43033
angie
Wed Jul 27 10:32:19 2011 -0700
Feature #3710 (vcfTabix UI options): Added controls for selection of centervariant for haplotype clustering/sorting. Also, some hgc improvements:
made the Genotype Details table into a collapsible section; better display
of QUAL and FILTER column values, which also involved improving the
representation of those columns in src/inc/vcf.h.
diff --git src/hg/lib/vcfUi.c src/hg/lib/vcfUi.c
new file mode 100644
index 0000000..a4927cd
--- /dev/null
+++ src/hg/lib/vcfUi.c
@@ -0,0 +1,182 @@
+/* vcfUi - Variant Call Format user interface controls that are shared
+ * between more than one CGI. */
+
+#include "common.h"
+#include "cheapcgi.h"
+#include "errCatch.h"
+#include "hCommon.h"
+#include "hui.h"
+#include "vcf.h"
+#include "vcfUi.h"
+#if (defined USE_TABIX && defined KNETFILE_HOOKS)
+#include "knetUdc.h"
+#include "udc.h"
+#endif//def USE_TABIX && KNETFILE_HOOKS
+
+INLINE char *nameOrDefault(char *thisName, char *defaultVal)
+/* If thisName is not a placeholder value, return it; otherwise return default. */
+{
+if (isNotEmpty(thisName) && !sameString(thisName, "."))
+ return thisName;
+return defaultVal;
+}
+
+#define VCF_HAPLOSORT_DEFAULT_DESC "middle variant in viewing window"
+
+static void vcfCfgHaplotypeCenterHiddens(char *track, char *ctrName, char *ctrChrom, int ctrPos)
+/* Make hidden form inputs and button for setting the center variant for haplotype
+ * clustering/sorting in hgTracks. */
+{
+char cartVar[1024];
+safef(cartVar, sizeof(cartVar), "%s.centerVariantChrom", track);
+cgiMakeHiddenVar(cartVar, ctrChrom);
+safef(cartVar, sizeof(cartVar), "%s.centerVariantPos", track);
+char ctrPosStr[16];
+safef(ctrPosStr, sizeof(ctrPosStr), "%d", ctrPos);
+cgiMakeHiddenVar(cartVar, ctrPosStr);
+safef(cartVar, sizeof(cartVar), "%s.centerVariantName", track);
+cgiMakeHiddenVar(cartVar, ctrName);
+}
+
+void vcfCfgHaplotypeCenter(struct cart *cart, struct trackDb *tdb, struct vcfFile *vcff,
+ char *thisName, char *thisChrom, int thisPos, char *formName)
+/* If vcff has genotype data, show status and controls for choosing the center variant
+ * for haplotype clustering/sorting in hgTracks. */
+{
+if (vcff != NULL && vcff->genotypeCount > 1)
+ {
+// cluster haplotypes or just show allele summary?
+// if clustering haplotypes:
+// track height?
+// thicken lines?
+// outline center variant?
+// choose center variant? [hgc option to make this variant's coords the center of viewed region?]
+// color haplotypes by red/blue or allele bases?
+ printf("
"
+ "Haplotype sorting: using ");
+ char cartVar[1024];
+ safef(cartVar, sizeof(cartVar), "%s.centerVariantChrom", tdb->track);
+ char *centerChrom = cartOptionalString(cart, cartVar);
+ if (isEmpty(centerChrom))
+ {
+ // Unspecified in cart -- describe the default action
+ printf(VCF_HAPLOSORT_DEFAULT_DESC " as anchor. |
\n");
+ if (isNotEmpty(thisChrom))
+ {
+ // but we do have a candidate, so offer to make it the center:
+ puts("");
+ vcfCfgHaplotypeCenterHiddens(tdb->track, thisName, thisChrom, thisPos);
+ char label[256];
+ safef(label, sizeof(label), "Use %s", nameOrDefault(thisName, "this variant"));
+ cgiMakeButton("submit", label);
+ printf(" as anchor |
\n");
+ }
+ else
+ printf("To anchor the sorting to a particular variant, "
+ "click on the variant in the genome browser, "
+ "and then click on the 'Use this variant' button on the next page."
+ " |
\n");
+ }
+ else
+ {
+ // Describe the one specified in cart.
+ cgiMakeHiddenVar(cartVar, "");
+ safef(cartVar, sizeof(cartVar), "%s.centerVariantPos", tdb->track);
+ int centerPos = cartInt(cart, cartVar);
+ safef(cartVar, sizeof(cartVar), "%s.centerVariantName", tdb->track);
+ char *centerName = cartString(cart, cartVar);
+ if (isNotEmpty(thisChrom))
+ {
+ // These form inputs are for either "use me" or clear:
+ vcfCfgHaplotypeCenterHiddens(tdb->track, thisName, thisChrom, thisPos);
+ // Is this variant the same as the center variant specified in cart?
+ if (sameString(thisChrom, centerChrom) && sameString(thisName, centerName) &&
+ thisPos == centerPos)
+ printf("this variant as anchor.\n");
+ else
+ {
+ // make a "use me" button
+ printf("%s at %s:%d as anchor.\n\n",
+ nameOrDefault(centerName, "variant"), centerChrom, centerPos+1);
+ char label[256];
+ safef(label, sizeof(label), "Use %s", nameOrDefault(thisName, "this variant"));
+ cgiMakeButton("submit", label);
+ printf(" as anchor |
\n");
+ }
+ }
+ else
+ {
+ // Form inputs (in case the clear button is clicked)
+ vcfCfgHaplotypeCenterHiddens(tdb->track, centerName, centerChrom, centerPos);
+ printf("%s at %s:%d as anchor.\n",
+ nameOrDefault(centerName, "variant"), centerChrom, centerPos+1);
+ }
+ // Make a clear button that modifies the hiddens using onClick
+ puts("");
+ struct dyString *onClick = dyStringNew(0);
+ dyStringPrintf(onClick, "updateOrMakeNamedVariable(%s, '%s.centerVariantChrom', ''); ",
+ formName, tdb->track);
+ dyStringPrintf(onClick, "updateOrMakeNamedVariable(%s, '%s.centerVariantName', ''); ",
+ formName, tdb->track);
+ dyStringPrintf(onClick, "updateOrMakeNamedVariable(%s, '%s.centerVariantPos', 0);",
+ formName, tdb->track);
+ dyStringPrintf(onClick, "document.%s.submit(); return false;", formName);
+ cgiMakeButtonWithOnClick("submit", "Clear selection", NULL, onClick->string);
+ printf(" (use " VCF_HAPLOSORT_DEFAULT_DESC ") |
\n");
+ }
+ puts("
");
+ }
+}
+
+//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. */
+{
+#if (defined USE_TABIX && defined KNETFILE_HOOKS)
+knetUdcInstall();
+if (udcCacheTimeout() < 300)
+ udcSetCacheTimeout(300);
+#endif//def USE_TABIX && KNETFILE_HOOKS
+char *db = cartString(cart, "db");
+struct sqlConnection *conn = hAllocConnTrack(db, tdb);
+char *fileOrUrl = bbiNameFromSettingOrTable(tdb, conn, tdb->table);
+hFreeConn(&conn);
+int vcfMaxErr = 100;
+struct vcfFile *vcff = NULL;
+/* protect against temporary network error */
+struct errCatch *errCatch = errCatchNew();
+if (errCatchStart(errCatch))
+ {
+ vcff = vcfTabixFileMayOpen(fileOrUrl, NULL, 0, 0, vcfMaxErr);
+ }
+errCatchEnd(errCatch);
+if (errCatch->gotError)
+ {
+ if (isNotEmpty(errCatch->message->string))
+ warn("unable to open %s: %s", fileOrUrl, errCatch->message->string);
+ }
+errCatchFree(&errCatch);
+return vcff;
+}
+
+void vcfCfgUi(struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed)
+/* VCF: Variant Call Format. redmine #3710 */
+{
+boxed = cfgBeginBoxAndTitle(tdb, boxed, title);
+printf("", boxed ? " width='100%'" : "");
+struct vcfFile *vcff = vcfHopefullyOpenHeader(cart, tdb);
+vcfCfgHaplotypeCenter(cart, tdb, vcff, NULL, NULL, 0, "mainForm");
+// filter:
+// by qual column
+// by filter column
+// color bases like pgSnp or some better palette?
+
+
+printf(" |
");
+
+if (!boxed && fileExists(hHelpFile("hgVcfTrackHelp")))
+ printf("VCF "
+ "configuration help
");
+cfgEndBox(boxed);
+}
+