Match if ");
cgiMakeRadioButton(cartSettingString, FILTERBY_MULTIPLE_LIST_AND, sameString(setting, FILTERBY_MULTIPLE_LIST_AND));
printf(" all ");
cgiMakeRadioButton(cartSettingString, FILTERBY_MULTIPLE_LIST_OR, sameString(setting, FILTERBY_MULTIPLE_LIST_OR));
printf(" one or more match
");
}
- // TODO: columnCount (Number of filterBoxes per row) should be configurable through tdb setting
-
+ puts("
");
// value is always "All", even if label is different, to simplify javascript code
int valIx = 0;
- if (isMultiple)
+ if (filterByColumnIsMultiple(cart, tdb, filterBy->column))
{
printf( "
");
+ }
puts("
");
}
void filterBySetCfgUi(struct cart *cart, struct trackDb *tdb,
filterBy_t *filterBySet, boolean onOneLine, char *prefix)
/* Does the filter UI for a list of filterBy structure */
{
filterBySetCfgUiGuts(cart, tdb, filterBySet, onOneLine, "Filter", "fbc", "All", prefix);
}
void highlightBySetCfgUi(struct cart *cart, struct trackDb *tdb,
filterBy_t *filterBySet, boolean onOneLine, char *prefix)
/* Does the highlight UI for a list of filterBy structure */
{
@@ -4273,30 +4292,112 @@
/*
printf("
");
cfgEndBox(boxed);
}
+void labelMakeCheckBox(struct cart *cart, struct trackDb *tdb, char *sym, char *desc,
+ boolean defaultOn)
+/* add a checkbox for the user to select a component of a label (e.g. ID, name, other info).
+ * NOTE: This does not have a track name argument, so the correct tdb must be passed in:
+ * if setting is at composite level, then pass in composite tdb, likewise for view. */
+{
+char suffix[512];
+safef(suffix, sizeof(suffix), "label.%s", sym);
+boolean option = cartUsualBooleanClosestToHome(cart, tdb, FALSE, suffix, defaultOn);
+char cartVar[1024];
+safef(cartVar, sizeof cartVar, "%s.%s", tdb->track, suffix);
+cgiMakeCheckBox(cartVar, option);
+printf(" %s ", desc);
+}
+
+static void freqSourceSelect(struct cart *cart, struct trackDb *tdb, char *name)
+/* Make a select input for preferred source of allele frequencies from
+ * trackDb setting freqSourceOrder. */
+{
+char *freqSourceOrder = cloneString(trackDbSetting(tdb, "freqSourceOrder"));
+if (isEmpty(freqSourceOrder))
+ return;
+int fsCount = countSeparatedItems(freqSourceOrder, ',');
+char *menu[fsCount];
+chopCommas(freqSourceOrder, menu);
+boolean parentLevel = isNameAtParentLevel(tdb, name);
+char *freqProj = cartOptionalStringClosestToHome(cart, tdb, parentLevel, "freqProj");
+puts("Frequency source/project to use for Minor Allele Frequency (MAF):");
+char cartVar[1024];
+safef(cartVar, sizeof cartVar, "%s.freqProj", name);
+cgiMakeDropList(cartVar, menu, ArraySize(menu), freqProj);
+puts(" ");
+}
+
+static struct trackDb *tdbOrAncestorByName(struct trackDb *tdb, char *name)
+/* For reasons Angie cannot fathom, if a composite or view is passed to cfgByCfgType then
+ * cfgByCfgType passes a leaf subtrack to its callees like bigDbSnpCfgUi. That is why we
+ * see so many calls to isNameAtParentLevel, which returns true if the tdb was originally
+ * at the composite or view level, which we can only tell by comparing with the original track name.
+ * labelMakeCheckBox, called by many handlers in hgTrackUi that must be always top-level
+ * (or have a special handler that bypasses cfgByCfgType like refSeqComposite),
+ * is blissfully unaware of this. It uses the same tdb for looking in cart ClosestToHome
+ * and for making the HTML element's cart var name, trusting that the correct tdb has been
+ * handed to it.
+ * So in order for a callee of cfgByCfgType to call labelMakeCheckBox with the correct tdb,
+ * we need to walk back up comparing name like isNameAtParentLevel does.
+ * If name doesn't match tdb or any of its ancestors then this returns NULL. */
+{
+struct trackDb *correctTdb;
+for (correctTdb = tdb; correctTdb != NULL; correctTdb = correctTdb->parent)
+ if (startsWithWordByDelimiter(correctTdb->track, '.', name))
+ return correctTdb;
+return NULL;
+}
+
+void bigDbSnpCfgUi(char *db, struct cart *cart, struct trackDb *leafTdb, char *name, char *title,
+ boolean boxed)
+/* UI for bigDbSnp a.k.a. "dbSNP 2.0". */
+{
+boxed = cfgBeginBoxAndTitle(leafTdb, boxed, title);
+freqSourceSelect(cart, leafTdb, name);
+puts(" ");
+puts("Label:");
+struct trackDb *correctTdb = tdbOrAncestorByName(leafTdb, name);
+labelMakeCheckBox(cart, correctTdb, "rsId", "rs# identifier", TRUE);
+labelMakeCheckBox(cart, correctTdb, "refAlt", "reference/alternate allele", TRUE);
+labelMakeCheckBox(cart, correctTdb, "majMin", "major/minor allele", FALSE);
+labelMakeCheckBox(cart, correctTdb, "maf", "MAF if available", FALSE);
+labelMakeCheckBox(cart, correctTdb, "func", "Most severe functional impact on gene if any", FALSE);
+puts(" ");
+scoreCfgUi(db, cart, leafTdb, name, "", 0, FALSE);
+puts(" ");
+puts("Minimum MAF:");
+boolean parentLevel = isNameAtParentLevel(leafTdb, name);
+double minMaf = cartUsualDoubleClosestToHome(cart, leafTdb, parentLevel, "minMaf", 0.0);
+char cartVar[1024];
+safef(cartVar, sizeof cartVar, "%s.minMaf", name);
+cgiMakeDoubleVarWithLimits(cartVar, minMaf, "MAF", 0, 0.0, 0.5);
+puts("range: 0.0 - 0.5");
+cfgEndBox(boxed);
+}
+
void cfgByCfgType(eCfgType cType,char *db, struct cart *cart, struct trackDb *tdb,char *prefix,
char *title, boolean boxed)
// Methods for putting up type specific cfgs used by composites/subtracks in hui.c
{
// When only one subtrack, then show it's cfg settings instead of composite/view level settings
// This simplifies the UI where hgTrackUi won't have 2 levels of cfg,
// while hgTracks still supports rightClick cfg of the subtrack.
if (configurableByAjax(tdb,cType) > 0) // Only if subtrack's configurable by ajax do we
{ // consider this option
if (tdbIsComposite(tdb) // called for the composite
&& !isCustomComposite(tdb)
&& !tdbIsCompositeView(tdb->subtracks) // and there is no view level
&& slCount(tdb->subtracks) == 1) // and there is only one subtrack
{
@@ -4354,30 +4455,32 @@
case cfgLong: longRangeCfgUi(cart, tdb, prefix, title, boxed);
break;
case cfgSnake: snakeCfgUi(cart, tdb, prefix, title, boxed);
break;
case cfgPsl: pslCfgUi(db,cart,tdb,prefix,title,boxed);
break;
case cfgBarChart: barChartCfgUi(db,cart,tdb,prefix,title,boxed);
break;
case cfgInteract: interactCfgUi(db,cart,tdb,prefix,title,boxed);
break;
case cfgLollipop: lollyCfgUi(db,cart,tdb,prefix,title,boxed);
scoreCfgUi(db, cart,tdb,prefix,title,1000,boxed);
break;
case cfgHic: hicCfgUi(db,cart,tdb,prefix,title,boxed);
break;
+ case cfgBigDbSnp: bigDbSnpCfgUi(db, cart, tdb, prefix, title, boxed);
+ break;
default: warn("Track type is not known to multi-view composites. type is: %d ",
cType);
break;
}
}
char *encodeRestrictionDate(char *db,struct trackDb *trackDb,boolean excludePast)
// Create a string for ENCODE restriction date of this track
// if return is not null, then free it after use
{
if (!trackDb)
return NULL;
char *date = NULL;
@@ -8893,38 +8996,34 @@
if (isCustomTrack(tdb->track))
{
if (ct)
{
conn = hAllocConn(CUSTOM_TRASH);
tableName = ct->dbTableName;
}
}
else if (startsWith("big", tdb->type))
{
char *tableName = hTableForTrack(database, tdb->table);
struct sqlConnection *conn = hAllocConnTrack(database, tdb);
char *bbiFileName = bbiNameFromSettingOrTable(tdb, conn, tableName);
hFreeConn(&conn);
struct bbiFile *bbi = NULL;
- if (startsWith("bigBed", tdb->type) || sameString("bigBarChart", tdb->type)
- || sameString("bigMaf", tdb->type) || sameString("bigPsl", tdb->type)
- || sameString("bigChain", tdb->type) || sameString("bigGenePred", tdb->type)
- || startsWith("bigLolly", tdb->type)
- || sameString("bigInteract", tdb->type))
- bbi = bigBedFileOpen(bbiFileName);
- else if (startsWith("bigWig", tdb->type))
+ if (startsWith("bigWig", tdb->type))
bbi = bigWigFileOpen(bbiFileName);
+ else
+ bbi = bigBedFileOpen(bbiFileName);
time_t timep = 0;
if (bbi)
{
timep = bbiUpdateTime(bbi);
bbiFileClose(&bbi);
}
printBbiUpdateTime(&timep);
}
else
{
tableName = hTableForTrack(database, tdb->table);
conn = hAllocConnTrack(database, tdb);
}
if (tableName)
{