7bc24686024ec14d351ab208b5179ab251d7c463 tdreszer Fri Oct 14 16:34:15 2011 -0700 Major work on bedFilt, psl and wigMaf to make them properly composite ready. diff --git src/hg/lib/hui.c src/hg/lib/hui.c index d62ee79..5641573 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -1112,31 +1112,31 @@ BASE_COLOR_DRAW_OFF); stringVal = cartUsualStringClosestToHome(cart, tdb, FALSE, BASE_COLOR_VAR_SUFFIX,stringVal); return baseColorDrawOptStringToEnum(stringVal); } /*** Control of fancy indel display code: ***/ static boolean tdbOrCartBoolean(struct cart *cart, struct trackDb *tdb, char *settingName, char *defaultOnOff) /* Query cart & trackDb to determine if a boolean variable is set. */ { boolean alreadySet; alreadySet = !sameString("off",trackDbSettingOrDefault(tdb, settingName, defaultOnOff)); -alreadySet = cartUsualBooleanClosestToHome(cart, tdb, FALSE, settingName, alreadySet); // NOTE: compositeLevel=FALSE because tdb param already is at appropriate level +alreadySet = cartUsualBooleanClosestToHome(cart, tdb, FALSE, settingName, alreadySet); // NOTE: viewLevel=FALSE because tdb param already is at appropriate level return alreadySet; } static boolean indelAppropriate(struct trackDb *tdb) /* Return true if it makes sense to offer indel display options for tdb. */ { return (tdb && (startsWith("psl", tdb->type) || sameString("bam", tdb->type)) && (cfgOptionDefault("browser.indelOptions", NULL) != NULL)); } static void indelEnabledByName(struct cart *cart, struct trackDb *tdb, char *name, float basesPerPixel, boolean *retDoubleInsert, boolean *retQueryInsert, boolean *retPolyA) /* Query cart & trackDb to determine what indel display (if any) is enabled. Set * basesPerPixel to 0.0 to disable check for zoom level. */ @@ -1769,63 +1769,59 @@ void chimpDropDown(char *var, char *curVal) /* Make drop down of options. */ { cgiMakeDropList(var, chimpOptions, ArraySize(chimpOptions), curVal); } /****** Some stuff for mRNA and EST related controls *******/ static void addMrnaFilter(struct mrnaUiData *mud, char *track, char *label, char *key, char *table) /* Add an mrna filter */ { struct mrnaFilter *fil; -char buf[128]; AllocVar(fil); fil->label = label; -safef(buf, sizeof(buf), "%s_%s", track, key); -fil->key = cloneString(buf); +fil->suffix = cloneString(key); fil->table = table; slAddTail(&mud->filterList, fil); } -struct mrnaUiData *newBedUiData(char *track) +static struct mrnaUiData *newEmptyMrnaUiData(char *track) /* Make a new in extra-ui data structure for a bed. */ { struct mrnaUiData *mud; -char buf[128]; /* Expand me here */ AllocVar(mud); -safef(buf, sizeof(buf), "%sFt", track); -mud->filterTypeVar = cloneString(buf); -safef(buf, sizeof(buf), "%sLt", track); -mud->logicTypeVar = cloneString(buf); +mud->filterTypeSuffix = cloneString("Ft"); +mud->logicTypeSuffix = cloneString("Lt"); +return mud; +} + +struct mrnaUiData *newBedUiData(char *track) +/* Make a new in extra-ui data structure for a bed. */ +{ +struct mrnaUiData *mud = newEmptyMrnaUiData(track); addMrnaFilter(mud, track, "name", "name",track); return mud; } struct mrnaUiData *newMrnaUiData(char *track, boolean isXeno) /* Make a new in extra-ui data structure for mRNA. */ { -struct mrnaUiData *mud; -char buf[128]; -AllocVar(mud); -safef(buf, sizeof(buf), "%sFt", track); -mud->filterTypeVar = cloneString(buf); -safef(buf, sizeof(buf), "%sLt", track); -mud->logicTypeVar = cloneString(buf); +struct mrnaUiData *mud = newEmptyMrnaUiData(track); if (isXeno) addMrnaFilter(mud, track, "organism", "org", "organism"); addMrnaFilter(mud, track, "accession", "acc", "acc"); addMrnaFilter(mud, track, "author", "aut", "author"); addMrnaFilter(mud, track, "library", "lib", "library"); addMrnaFilter(mud, track, "tissue", "tis", "tissue"); addMrnaFilter(mud, track, "cell", "cel", "cell"); addMrnaFilter(mud, track, "keyword", "key", "keyword"); addMrnaFilter(mud, track, "gene", "gen", "geneName"); addMrnaFilter(mud, track, "product", "pro", "productName"); addMrnaFilter(mud, track, "description", "des", "description"); return mud; } int trackNameAndLabelCmp(const void *va, const void *vb) @@ -3326,32 +3322,32 @@ errAbort("filterBy values either all have labels (as value|label) or none do."); *chipper++ = 0; // The label is found inside the filters->svValues as the next string strSwapChar(chipper,'_',' '); // Title does not have underscores } else if (filterBy->valueAndLabel) errAbort("filterBy values either all have labels in form of value|label or none do."); } } slAddTail(&filterBySet,filterBy); // Keep them in order (only a few) if(cart != NULL) { char suffix[256]; safef(suffix, sizeof(suffix), "filterBy.%s", filterBy->column); - boolean compositeLevel = isNameAtCompositeLevel(tdb,name); - if(cartLookUpVariableClosestToHome(cart,tdb,compositeLevel,suffix,&(filterBy->htmlName))) + boolean viewLevel = isNameAtCompositeLevel(tdb,name); + if(cartLookUpVariableClosestToHome(cart,tdb,viewLevel,suffix,&(filterBy->htmlName))) filterBy->slChoices = cartOptionalSlNameList(cart,filterBy->htmlName); } if(filterBy->htmlName == NULL) { int len = strlen(name) + strlen(filterBy->column) + 15; filterBy->htmlName = needMem(len); safef(filterBy->htmlName, len, "%s.filterBy.%s", name,filterBy->column); } } freeMem(setting); return filterBySet; } void filterBySetFree(filterBy_t **filterBySet) @@ -3718,61 +3714,60 @@ { #ifdef SUBTRACK_CFG // 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 && !tdbIsCompositeView(tdb->subtracks) // and there is no view level && slCount(tdb->subtracks) == 1) // and there is only one subtrack { //warn("What do you mean by having a composite (%s) with only one subtrack (%s) ???",tdb->track,tdb->subtracks->track); tdb = tdb->subtracks; // show subtrack cfg instead prefix = tdb->track; } - else if (tdb->parent != NULL + else if (tdb->parent != NULL // called with subtrack (tdb is never a view) && tdbIsCompositeView(tdb->parent) // subtrack has view - && differentString(prefix,tdb->track) // and this has been called for the view - && slCount(tdb->parent->subtracks) == 1) // and there is only one subtrack + && differentString(prefix,tdb->track) // and this has been called FOR the view + && slCount(tdb->parent->subtracks) == 1) // and view has only one subtrack prefix = tdb->track; // removes reference to view level } #endif///def SUBTRACK_CFG switch(cType) { case cfgBedScore: { char *scoreMax = trackDbSettingClosestToHome(tdb, SCORE_FILTER _MAX); int maxScore = (scoreMax ? sqlUnsigned(scoreMax):1000); scoreCfgUi(db, cart,tdb,prefix,title,maxScore,boxed); } break; case cfgPeak: encodePeakCfgUi(cart,tdb,prefix,title,boxed); break; case cfgWig: wigCfgUi(cart,tdb,prefix,title,boxed); break; - case cfgWigMaf: // NOTE: wigMaf is using non-standard view level naming methods so isn't configurable by ajax - wigMafCfgUi(cart,tdb,prefix,title,boxed, db); + case cfgWigMaf: wigMafCfgUi(cart,tdb,prefix,title,boxed, db); break; case cfgGenePred: genePredCfgUi(cart,tdb,prefix,title,boxed); break; case cfgChain: chainCfgUi(db,cart,tdb,prefix,title,boxed, NULL); break; case cfgNetAlign: netAlignCfgUi(db,cart,tdb,prefix,title,boxed); break; - case cfgBedFilt: bedUi(tdb,cart,title, boxed); + case cfgBedFilt: bedFiltCfgUi(cart,tdb,prefix,title, boxed); break; #ifdef USE_BAM case cfgBam: bamCfgUi(cart, tdb, prefix, title, boxed); break; #endif case cfgVcf: vcfCfgUi(cart, tdb, prefix, title, boxed); break; case cfgPsl: pslCfgUi(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) @@ -4505,77 +4500,119 @@ radioButton(filterTypeVar, filterTypeVal, "green"); radioButton(filterTypeVar, filterTypeVal, "blue"); radioButton(filterTypeVar, filterTypeVal, "exclude"); radioButton(filterTypeVar, filterTypeVal, "include"); if (none) radioButton(filterTypeVar, filterTypeVal, "none"); } void radioButton(char *var, char *val, char *ourVal) /* Print one radio button */ { cgiMakeRadioButton(var, ourVal, sameString(ourVal, val)); printf("%s ", ourVal); } -void oneMrnaFilterUi(struct controlGrid *cg, char *text, char *var, struct cart *cart) +void oneMrnaFilterUi(struct controlGrid *cg, struct trackDb *tdb, char *text, char *var, char *suffix, struct cart *cart) /* Print out user interface for one type of mrna filter. */ { controlGridStartCell(cg); printf("%s:
", text); -cgiMakeTextVar(var, cartUsualString(cart, var, ""), 19); +boolean viewLevel = isNameAtCompositeLevel(tdb,var); +cgiMakeTextVar(var, cartUsualStringClosestToHome(cart, tdb, viewLevel,suffix, ""), 19); controlGridEndCell(cg); } -void bedUi(struct trackDb *tdb, struct cart *cart, char *title, boolean boxed) -/* Put up UI for an mRNA (or EST) track. */ +void bedFiltCfgUi(struct cart *cart, struct trackDb *tdb, char *prefix, char *title, boolean boxed) +/* Put up UI for an "bedFilter" tracks. */ { -struct mrnaUiData *mud = newBedUiData(tdb->track); +struct mrnaUiData *mud = newBedUiData(prefix); struct mrnaFilter *fil; struct controlGrid *cg = NULL; -char *filterTypeVar = mud->filterTypeVar; -char *filterTypeVal = cartUsualString(cart, filterTypeVar, "red"); +boolean viewLevel = isNameAtCompositeLevel(tdb,prefix); +char *filterTypeVal = cartUsualStringClosestToHome(cart, tdb, viewLevel, mud->filterTypeSuffix, "red"); boxed = cfgBeginBoxAndTitle(tdb, boxed, title); /* Define type of filter. */ printf("
\n"); -filterButtons(filterTypeVar, filterTypeVal, FALSE); +char buffer[256]; +safef(buffer, sizeof buffer,"%s.%s",prefix,mud->filterTypeSuffix); +filterButtons(buffer, filterTypeVal, FALSE); printf("
"); /* List various fields you can filter on. */ cg = startControlGrid(4, NULL); for (fil = mud->filterList; fil != NULL; fil = fil->next) - oneMrnaFilterUi(cg, fil->label, fil->key, cart); + { + safef(buffer, sizeof buffer,"%s.%s",prefix,fil->suffix); + oneMrnaFilterUi(cg, tdb, fil->label, buffer, fil->suffix, cart); + } endControlGrid(&cg); cfgEndBox(boxed); } +void mrnaCfgUi(struct cart *cart, struct trackDb *tdb, char *prefix, char *title, boolean boxed) +/* Put up UI for an mRNA (or EST) track. */ +{ +boolean isXeno = (sameString(tdb->track, "xenoMrna") || sameString(tdb->track, "xenoEst")); +struct mrnaUiData *mud = newMrnaUiData(prefix, isXeno); +struct mrnaFilter *fil; +struct controlGrid *cg = NULL; +boolean viewLevel = isNameAtCompositeLevel(tdb,prefix); +char *filterTypeVal = cartUsualStringClosestToHome(cart, tdb, viewLevel, mud->filterTypeSuffix,"red"); +char *logicTypeVal = cartUsualStringClosestToHome(cart, tdb, viewLevel, mud->logicTypeSuffix, "and"); + +boxed = cfgBeginBoxAndTitle(tdb, boxed, title); +/* Define type of filter. */ +char buffer[256]; +safef(buffer,sizeof buffer,"%s.%s",prefix,mud->filterTypeSuffix); +filterButtons(buffer, filterTypeVal, FALSE); +printf(" Combination Logic: "); +safef(buffer,sizeof buffer,"%s.%s",prefix,mud->logicTypeSuffix); +radioButton(buffer, logicTypeVal, "and"); +radioButton(buffer, logicTypeVal, "or"); +printf("
\n"); + +/* List various fields you can filter on. */ +printf("\n", CONTROL_TABLE_WIDTH); +cg = startControlGrid(4, NULL); +for (fil = mud->filterList; fil != NULL; fil = fil->next) + { + safef(buffer,sizeof buffer,"%s.%s",prefix,fil->suffix); + oneMrnaFilterUi(cg, tdb, fil->label, buffer, fil->suffix, cart); + } +endControlGrid(&cg); +baseColorDrawOptDropDown(cart, tdb); +indelShowOptions(cart, tdb); +cfgEndBox(boxed); +} + void scoreGrayLevelCfgUi(struct cart *cart, struct trackDb *tdb, char *prefix, int scoreMax) /* If scoreMin has been set, let user select the shade of gray for that score, in case * the default is too light to see or darker than necessary. */ { -boolean compositeLevel = isNameAtCompositeLevel(tdb,prefix); +boolean viewLevel = isNameAtCompositeLevel(tdb,prefix); char *scoreMinStr = trackDbSettingClosestToHome(tdb, GRAY_LEVEL_SCORE_MIN); if (scoreMinStr != NULL) { int scoreMin = atoi(scoreMinStr); // maxShade=9 taken from hgTracks/simpleTracks.c. Ignore the 10 in shadesOfGray[10+1] -- // maxShade is used to access the array. int maxShade = 9; int scoreMinGrayLevel = scoreMin * maxShade/scoreMax; if (scoreMinGrayLevel <= 0) scoreMinGrayLevel = 1; char *setting = trackDbSettingClosestToHome(tdb, MIN_GRAY_LEVEL); - int minGrayLevel = cartUsualIntClosestToHome(cart, tdb, compositeLevel, MIN_GRAY_LEVEL, + int minGrayLevel = cartUsualIntClosestToHome(cart, tdb, viewLevel, MIN_GRAY_LEVEL, setting ? atoi(setting) : scoreMinGrayLevel); if (minGrayLevel <= 0) minGrayLevel = 1; if (minGrayLevel > maxShade) minGrayLevel = maxShade; puts("\nShade of lowest-scoring items: "); // Add javascript to select so that its color is consistent with option colors: int level = 255 - (255*minGrayLevel / maxShade); printf("
"); *opened = TRUE; } printf("
%s:",label); char varName[256]; char altLabel[256]; safef(varName, sizeof(varName), "%s%s", scoreName, _BY_RANGE); boolean filterByRange = trackDbSettingClosestToHomeOn(tdb, varName); // NOTE: could determine isFloat = (strchr(setting,'.') != NULL); However, historical trackDb settings of pValueFilter did not always contain '.' if (isFloat) { double minLimit=NO_VALUE,maxLimit=NO_VALUE; double minVal=minLimit,maxVal=maxLimit; colonPairToDoubles(setting,&minVal,&maxVal); - getScoreFloatRangeFromCart(cart,tdb,scoreName,&minLimit,&maxLimit,&minVal,&maxVal); + getScoreFloatRangeFromCart(cart,tdb,viewLevel,scoreName,&minLimit,&maxLimit,&minVal,&maxVal); safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MIN); safef(altLabel, sizeof(altLabel), "%s%s", (filterByRange?"Minimum ":""), htmlEncodeText(htmlTextStripTags(label),FALSE)); cgiMakeDoubleVarWithLimits(varName,minVal, altLabel, 0,minLimit, maxLimit); if(filterByRange) { printf("to"); safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MAX); safef(altLabel, sizeof(altLabel), "%s%s", (filterByRange?"Maximum ":""), label); cgiMakeDoubleVarWithLimits(varName,maxVal, altLabel, 0,minLimit, maxLimit); } safef(altLabel, sizeof(altLabel), "%s", (filterByRange?"": "colspan=3")); if(minLimit != NO_VALUE && maxLimit != NO_VALUE) printf(" (%g to %g)",altLabel,minLimit, maxLimit); else if(minLimit != NO_VALUE) printf(" (minimum %g)",altLabel,minLimit); else if(maxLimit != NO_VALUE) printf(" (maximum %g)",altLabel,maxLimit); else printf("to"); safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MAX); safef(altLabel, sizeof(altLabel), "%s%s", (filterByRange?"Maximum ":""), label); cgiMakeIntVarWithLimits(varName,maxVal, altLabel, 0,minLimit, maxLimit); } safef(altLabel, sizeof(altLabel), "%s", (filterByRange?"": "colspan=3")); if(minLimit != NO_VALUE && maxLimit != NO_VALUE) printf(" (%d to %d)",altLabel,minLimit, maxLimit); else if(minLimit != NO_VALUE) printf(" (minimum %d)",altLabel,minLimit); else if(maxLimit != NO_VALUE) printf(" (maximum %d)",altLabel,maxLimit); else printf(""); return TRUE; } return FALSE; } static int numericFiltersShowAll(struct cart *cart, struct trackDb *tdb, boolean *opened, boolean boxed, - boolean compositeLevel,char *name, char *title) + boolean viewLevel,char *name, char *title) // Shows all *Filter style filters. Note that these are in random order and have no graceful title { int count = 0; struct slName *filterSettings = trackDbSettingsWildMatch(tdb, "*Filter"); if (filterSettings) { puts("
"); struct slName *filter = NULL; struct slPair *extras = NULL; char *extraFields = trackDbSetting(tdb, "extraFields"); // TODo: seems like there should be a cleaner way if (extraFields != NULL) extras = slPairListFromString(extraFields,TRUE); // Quoted strings may be okay while ((filter = slPopHead(&filterSettings)) != NULL) { @@ -4878,31 +4915,31 @@ freeMem(field); field = strchr(foundLabel,']'); if (field == NULL) field = cloneString(foundLabel); else field = cloneString(field + 1); strSwapChar(field,'_',' '); } } char label[128]; safef(label,sizeof(label),"Minimum %s",field); freeMem(field); // Determine floating point or integer char *setting = trackDbSetting(tdb, filter->name); boolean isFloat = (strchr(setting,'.') != NULL); - showScoreFilter(cart,tdb,opened,boxed,compositeLevel,name,title,label,filter->name,isFloat); + showScoreFilter(cart,tdb,opened,boxed,viewLevel,name,title,label,filter->name,isFloat); count++; } slNameFree(&filter); } } if (count > 0) puts("
"); return count; } boolean bedScoreHasCfgUi(struct trackDb *tdb) // Confirms that this track has a bedScore Cfg UI { // Assumes that cfgType == cfgBedScore @@ -4932,37 +4969,37 @@ slNameFreeList(&filterSettings); if (one) return TRUE; } if (!blocked) // scoreFilter is implicit unless NO_SCORE_FILTER return TRUE; return FALSE; } void scoreCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *name, char *title, int maxScore, boolean boxed) /* Put up UI for filtering bed track based on a score */ { char option[256]; -boolean compositeLevel = isNameAtCompositeLevel(tdb,name); +boolean viewLevel = isNameAtCompositeLevel(tdb,name); boolean skipScoreFilter = FALSE; filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); // Numeric filters are first boolean isBoxOpened = FALSE; -if (numericFiltersShowAll(cart, tdb, &isBoxOpened, boxed, compositeLevel, name, title) > 0) +if (numericFiltersShowAll(cart, tdb, &isBoxOpened, boxed, viewLevel, name, title) > 0) skipScoreFilter = TRUE; // Add any multi-selects next if(filterBySet != NULL) { if(!tdbIsComposite(tdb) && cartOptionalString(cart, "ajax") == NULL) jsIncludeFile("hui.js",NULL); if (!isBoxOpened) // Note filterBy boxes are not double "boxed", if there are no other filters printf("
"); filterBySetCfgUi(cart,tdb,filterBySet,TRUE); filterBySetFree(&filterBySet); skipScoreFilter = TRUE; } @@ -4974,31 +5011,31 @@ cfgEndBox(boxed); return; // Cannot have both '*filter' and 'scoreFilter' } boolean scoreFilterOk = (trackDbSettingClosestToHome(tdb, NO_SCORE_FILTER) == NULL); boolean glvlScoreMin = (trackDbSettingClosestToHome(tdb, GRAY_LEVEL_SCORE_MIN) != NULL); if (! (scoreFilterOk || glvlScoreMin)) return; boxed = cfgBeginBoxAndTitle(tdb, boxed, title); if (scoreFilterOk) { int minLimit=0,maxLimit=maxScore,minVal=0,maxVal=maxScore; - getScoreIntRangeFromCart(cart,tdb,SCORE_FILTER,&minLimit,&maxLimit,&minVal,&maxVal); + getScoreIntRangeFromCart(cart,tdb,viewLevel,SCORE_FILTER,&minLimit,&maxLimit,&minVal,&maxVal); boolean filterByRange = trackDbSettingClosestToHomeOn(tdb, SCORE_FILTER _BY_RANGE); if (filterByRange) { puts("Filter score range: min:"); snprintf(option, sizeof(option), "%s.%s", name,SCORE_FILTER _MIN); cgiMakeIntVarWithLimits(option, minVal, "Minimum score",0, minLimit,maxLimit); puts("max:"); snprintf(option, sizeof(option), "%s.%s", name,SCORE_FILTER _MAX); cgiMakeIntVarWithLimits(option, maxVal, "Maximum score",0,minLimit,maxLimit); printf("(%d to %d)\n",minLimit,maxLimit); } else { printf("Show only items with score at or above: "); @@ -5012,40 +5049,40 @@ if (glvlScoreMin) scoreGrayLevelCfgUi(cart, tdb, name, maxScore); /* filter top-scoring N items in track */ char *scoreCtString = trackDbSettingClosestToHome(tdb, "filterTopScorers"); if (scoreCtString != NULL) { /* show only top-scoring items. This option only displayed if trackDb * setting exists. Format: filterTopScorers */ char *words[2]; char *scoreFilterCt = NULL; chopLine(cloneString(scoreCtString), words); safef(option, sizeof(option), "%s.filterTopScorersOn", name); bool doScoreCtFilter = - cartUsualBooleanClosestToHome(cart, tdb, compositeLevel, "filterTopScorersOn", sameString(words[0], "on")); + cartUsualBooleanClosestToHome(cart, tdb, viewLevel, "filterTopScorersOn", sameString(words[0], "on")); puts("

"); cgiMakeCheckBox(option, doScoreCtFilter); safef(option, sizeof(option), "%s.filterTopScorersCt", name); - scoreFilterCt = cartUsualStringClosestToHome(cart, tdb, compositeLevel, "filterTopScorersCt", words[1]); + scoreFilterCt = cartUsualStringClosestToHome(cart, tdb, viewLevel, "filterTopScorersCt", words[1]); puts("  Show only items in top-scoring "); cgiMakeIntVarWithLimits(option,atoi(scoreFilterCt),"Top-scoring count",0,1,100000); /* Only check size of table if track does not have subtracks */ - if ( !compositeLevel && hTableExists(db, tdb->table)) + if ( !viewLevel && hTableExists(db, tdb->table)) printf("  (range: 1 to 100,000 total items: %d)\n",getTableSize(db, tdb->table)); else printf("  (range: 1 to 100,000)\n"); } cfgEndBox(boxed); } // Moved from hgTrackUi for consistency static void filterByChromCfgUi(struct cart *cart, struct trackDb *tdb) { char *filterSetting; char filterVar[256]; char *filterVal = ""; printf("

Filter by chromosome (e.g. chr10): "); @@ -5084,94 +5121,94 @@ char *words[8]; int wordCount = wordCount = chopLine(typeLine, words); if (wordCount == 3 && sameWord(words[1], "xeno")) crossSpeciesCfgUi(cart,tdb); baseColorDropLists(cart, tdb, name); indelShowOptionsWithName(cart, tdb, name); cfgEndBox(boxed); } void netAlignCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *prefix, char *title, boolean boxed) /* Put up UI for net tracks */ { boxed = cfgBeginBoxAndTitle(tdb, boxed, title); -boolean compositeLevel = isNameAtCompositeLevel(tdb,prefix); +boolean viewLevel = isNameAtCompositeLevel(tdb,prefix); -enum netColorEnum netColor = netFetchColorOption(cart, tdb, compositeLevel); +enum netColorEnum netColor = netFetchColorOption(cart, tdb, viewLevel); char optString[256]; /* our option strings here */ safef(optString, ArraySize(optString), "%s.%s", prefix, NET_COLOR ); printf("

Color nets by: "); netColorDropDown(optString, netColorEnumToString(netColor)); #ifdef NOT_YET -enum netLevelEnum netLevel = netFetchLevelOption(cart, tdb, compositeLevel); +enum netLevelEnum netLevel = netFetchLevelOption(cart, tdb, viewLevel); safef( optString, ArraySize(optString), "%s.%s", prefix, NET_LEVEL ); printf("

Limit display of nets to: "); netLevelDropDown(optString, netLevelEnumToString(netLevel)); #endif cfgEndBox(boxed); } void chainCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *prefix, char *title, boolean boxed, char *chromosome) /* Put up UI for chain tracks */ { boxed = cfgBeginBoxAndTitle(tdb, boxed, title); -boolean compositeLevel = isNameAtCompositeLevel(tdb,prefix); +boolean viewLevel = isNameAtCompositeLevel(tdb,prefix); enum chainColorEnum chainColor = - chainFetchColorOption(cart, tdb, compositeLevel); + chainFetchColorOption(cart, tdb, viewLevel); /* check if we have normalized scores available */ boolean normScoreAvailable = chainDbNormScoreAvailable(tdb); char optString[256]; if (normScoreAvailable) { safef(optString, ArraySize(optString), "%s.%s", prefix, OPT_CHROM_COLORS ); printf("

Color chains by: "); chainColorDropDown(optString, chainColorEnumToString(chainColor)); } else { printf("

Color track based on chromosome: "); char optString[256]; /* initial value of chromosome coloring option is "on", unless * overridden by the colorChromDefault setting in the track */ char *binaryColorDefault = trackDbSettingClosestToHomeOrDefault(tdb, "colorChromDefault", "on"); /* allow cart to override trackDb setting */ safef(optString, sizeof(optString), "%s.color", prefix); char * colorSetting = cartUsualStringClosestToHome(cart, tdb, - compositeLevel, "color", binaryColorDefault); + viewLevel, "color", binaryColorDefault); cgiMakeRadioButton(optString, "on", sameString(colorSetting, "on")); printf(" on "); cgiMakeRadioButton(optString, "off", sameString(colorSetting, "off")); printf(" off "); printf("
\n"); } printf("

Filter by chromosome (e.g. chr10): "); safef(optString, ArraySize(optString), "%s.%s", prefix, OPT_CHROM_FILTER); cgiMakeTextVar(optString, - cartUsualStringClosestToHome(cart, tdb, compositeLevel, + cartUsualStringClosestToHome(cart, tdb, viewLevel, OPT_CHROM_FILTER, ""), 15); if (normScoreAvailable) scoreCfgUi(db, cart,tdb,prefix,NULL,CHAIN_SCORE_MAXIMUM,FALSE); cfgEndBox(boxed); } struct dyString *dyAddFilterAsInt(struct cart *cart, struct trackDb *tdb, struct dyString *extraWhere,char *filter,char *defaultLimits, char*field, boolean *and) /* creates the where clause condition to support numeric int filter range. Filters are expected to follow {fiterName}: trackDb min or min:max - default value(s); {filterName}Min or {filterName}: min (user supplied) cart variable; {filterName}Max: max (user supplied) cart variable; @@ -5189,31 +5226,31 @@ if(trackDbSettingClosestToHome(tdb, filterLimitName) != NULL) return extraWhere; char *setting = NULL; if(differentWord(filter,SCORE_FILTER)) setting = trackDbSettingClosestToHome(tdb, filter); else setting = trackDbSettingClosestToHomeOrDefault(tdb, filter,"0:1000"); if(setting || sameWord(filter,NO_SCORE_FILTER)) { boolean invalid = FALSE; int minValueTdb = 0,maxValueTdb = NO_VALUE; colonPairToInts(setting,&minValueTdb,&maxValueTdb); int minLimit=NO_VALUE,maxLimit=NO_VALUE,min=minValueTdb,max=maxValueTdb; colonPairToInts(defaultLimits,&minLimit,&maxLimit); - getScoreIntRangeFromCart(cart,tdb,filter,&minLimit,&maxLimit,&min,&max); + getScoreIntRangeFromCart(cart,tdb,FALSE,filter,&minLimit,&maxLimit,&min,&max); if(minLimit != NO_VALUE || maxLimit != NO_VALUE) { // assume tdb default values within range! (don't give user errors that have no consequence) if((min != minValueTdb && ((minLimit != NO_VALUE && min < minLimit) || (maxLimit != NO_VALUE && min > maxLimit))) || (max != maxValueTdb && ((minLimit != NO_VALUE && max < minLimit) || (maxLimit != NO_VALUE && max > maxLimit)))) { invalid = TRUE; char value[64]; if(max == NO_VALUE) // min only is allowed, but max only is not safef(value, sizeof(value), "entered minimum (%d)", min); else safef(value, sizeof(value), "entered range (min:%d and max:%d)", min, max); char limits[64]; @@ -5269,31 +5306,31 @@ {fiterName}: trackDb min or min:max - default value(s); {filterName}Min or {filterName}: min (user supplied) cart variable; {filterName}Max: max (user supplied) cart variable; {filterName}Limits: trackDb allowed range "0.0:10.0" Optional uses: defaultLimits: function param if no tdb limits settings found) The 'and' param and dyString in/out allows stringing multiple where clauses together */ { char *setting = trackDbSettingClosestToHome(tdb, filter); if(setting) { boolean invalid = FALSE; double minValueTdb = 0,maxValueTdb = NO_VALUE; colonPairToDoubles(setting,&minValueTdb,&maxValueTdb); double minLimit=NO_VALUE,maxLimit=NO_VALUE,min=minValueTdb,max=maxValueTdb; colonPairToDoubles(defaultLimits,&minLimit,&maxLimit); - getScoreFloatRangeFromCart(cart,tdb,filter,&minLimit,&maxLimit,&min,&max); + getScoreFloatRangeFromCart(cart,tdb,FALSE,filter,&minLimit,&maxLimit,&min,&max); if((int)minLimit != NO_VALUE || (int)maxLimit != NO_VALUE) { // assume tdb default values within range! (don't give user errors that have no consequence) if((min != minValueTdb && (((int)minLimit != NO_VALUE && min < minLimit) || ((int)maxLimit != NO_VALUE && min > maxLimit))) || (max != maxValueTdb && (((int)minLimit != NO_VALUE && max < minLimit) || ((int)maxLimit != NO_VALUE && max > maxLimit)))) { invalid = TRUE; char value[64]; if((int)max == NO_VALUE) // min only is allowed, but max only is not safef(value, sizeof(value), "entered minimum (%g)", min); else safef(value, sizeof(value), "entered range (min:%g and max:%g)", min, max); char limits[64]; @@ -5385,49 +5422,49 @@ || sameWord("gappedPeak",tdb->type)) { return (trackDbSettingClosestToHome(tdb, SCORE_FILTER ) || trackDbSettingClosestToHome(tdb, SIGNAL_FILTER) || trackDbSettingClosestToHome(tdb, PVALUE_FILTER) || trackDbSettingClosestToHome(tdb, QVALUE_FILTER) || trackDbSettingClosestToHome(tdb, SCORE_FILTER )); } return FALSE; } void encodePeakCfgUi(struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed) /* Put up UI for filtering wgEnocde peaks based on score, Pval and Qval */ { -boolean compositeLevel = isNameAtCompositeLevel(tdb,name); +boolean viewLevel = isNameAtCompositeLevel(tdb,name); boolean opened = FALSE; -showScoreFilter(cart,tdb,&opened,boxed,compositeLevel,name,title,"Minimum Signal value", SIGNAL_FILTER,TRUE); -showScoreFilter(cart,tdb,&opened,boxed,compositeLevel,name,title,"Minimum P-Value (-log10)",PVALUE_FILTER,TRUE); -showScoreFilter(cart,tdb,&opened,boxed,compositeLevel,name,title,"Minimum Q-Value (-log10)",QVALUE_FILTER,TRUE); +showScoreFilter(cart,tdb,&opened,boxed,viewLevel,name,title,"Minimum Signal value", SIGNAL_FILTER,TRUE); +showScoreFilter(cart,tdb,&opened,boxed,viewLevel,name,title,"Minimum P-Value (-log10)",PVALUE_FILTER,TRUE); +showScoreFilter(cart,tdb,&opened,boxed,viewLevel,name,title,"Minimum Q-Value (-log10)",QVALUE_FILTER,TRUE); char *setting = trackDbSettingClosestToHomeOrDefault(tdb, SCORE_FILTER,NULL);//"0:1000"); if(setting) { if(!opened) { boxed = cfgBeginBoxAndTitle(tdb, boxed, title); puts("

"); opened = TRUE; } char varName[256]; int minLimit=0,maxLimit=1000,minVal=0,maxVal=NO_VALUE; colonPairToInts(setting,&minVal,&maxVal); - getScoreIntRangeFromCart(cart,tdb,SCORE_FILTER,&minLimit,&maxLimit,&minVal,&maxVal); + getScoreIntRangeFromCart(cart,tdb,viewLevel,SCORE_FILTER,&minLimit,&maxLimit,&minVal,&maxVal); if(maxVal != NO_VALUE) puts(""); } } if(opened) { puts("
Score range: min:"); else puts("
Minimum score:"); safef(varName, sizeof(varName), "%s%s", SCORE_FILTER, _BY_RANGE); boolean filterByRange = trackDbSettingClosestToHomeOn(tdb, varName); safef(varName, sizeof(varName), "%s.%s%s", name, SCORE_FILTER, (filterByRange?_MIN:"")); cgiMakeIntVarWithLimits(varName, minVal, "Minimum score", 0, minLimit, maxLimit); if(filterByRange) { if(maxVal == NO_VALUE) maxVal = maxLimit; puts("to"); safef(varName, sizeof(varName), "%s.%s%s", name, SCORE_FILTER,_MAX); cgiMakeIntVarWithLimits(varName, maxVal, "Maximum score", 0, minLimit, maxLimit); @@ -5439,37 +5476,37 @@ scoreGrayLevelCfgUi(cart, tdb, name, 1000); puts("
"); cfgEndBox(boxed); } } void genePredCfgUi(struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed) /* Put up gencode-specific controls */ { char varName[64]; -boolean compositeLevel = isNameAtCompositeLevel(tdb,name); -char *geneLabel = cartUsualStringClosestToHome(cart, tdb,compositeLevel, "label", "gene"); +boolean viewLevel = isNameAtCompositeLevel(tdb,name); +char *geneLabel = cartUsualStringClosestToHome(cart, tdb,viewLevel, "label", "gene"); boxed = cfgBeginBoxAndTitle(tdb, boxed, title); if (sameString(name, "acembly")) { - char *acemblyClass = cartUsualStringClosestToHome(cart,tdb,compositeLevel,"type", acemblyEnumToString(0)); + char *acemblyClass = cartUsualStringClosestToHome(cart,tdb,viewLevel,"type", acemblyEnumToString(0)); printf("

Gene Class: "); acemblyDropDown("acembly.type", acemblyClass); printf(" "); } else if(startsWith("wgEncodeGencode", name) || sameString("wgEncodeSangerGencode", name) || (startsWith("encodeGencode", name) && !sameString("encodeGencodeRaceFrags", name))) { printf("Label: "); safef(varName, sizeof(varName), "%s.label", name); cgiMakeRadioButton(varName, "gene", sameString("gene", geneLabel)); printf("%s ", "gene"); cgiMakeRadioButton(varName, "accession", sameString("accession", geneLabel)); printf("%s ", "accession"); cgiMakeRadioButton(varName, "both", sameString("both", geneLabel)); @@ -5494,161 +5531,130 @@ filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); if(filterBySet != NULL) { printf("
"); filterBySetCfgUi(cart,tdb,filterBySet,FALSE); filterBySetFree(&filterBySet); } cfgEndBox(boxed); } static boolean isSpeciesOn(struct cart *cart, struct trackDb *tdb, char *species, char *option, int optionSize, boolean defaultState) /* check the cart to see if species is turned off or on (default is defaultState) */ { -#ifdef SUBTRACK_CFG - // FIXME: works now in configByAjax but affects not seen in track image!!! -boolean compositeLevel = isNameAtCompositeLevel(tdb,option); +boolean viewLevel = isNameAtCompositeLevel(tdb,option); if (*option == '\0') safef(option, optionSize, "%s.%s", tdb->track, species); else { char *suffix = option + strlen(option); int suffixSize = optionSize - strlen(option); safef(suffix,suffixSize,".%s",species); } -return cartUsualBooleanClosestToHome(cart,tdb, compositeLevel, species,defaultState); -#else///ifndef SUBTRACK_CFG -boolean ret = defaultState; -safef(option, optionSize, "%s.%s", tdb->track, species); - -/* see if this is a simple multiz (not composite track) */ -char *s = cartOptionalString(cart, option); -if (s != NULL) - ret = (sameString(s, "on") || atoi(s) > 0); -else - { - /* check parent to see if it has these variables */ - if (tdb->parent != NULL) - { - char *viewString; - if (subgroupFind(tdb, "view", &viewString)) - { - safef(option, optionSize, "%s.%s.%s", - tdb->parent->track, viewString, species); - ret = cartUsualBoolean(cart, option, ret); - } - } - } - -return ret; -#endif///ndef SUBTRACK_CFG +return cartUsualBooleanClosestToHome(cart,tdb, viewLevel, species,defaultState); } -char **wigMafGetSpecies(struct cart *cart, struct trackDb *tdb, char *db, struct wigMafSpecies **list, int *groupCt) +char **wigMafGetSpecies(struct cart *cart, struct trackDb *tdb, char *prefix, char *db, struct wigMafSpecies **list, int *groupCt) { int speciesCt = 0; -char *speciesGroup = trackDbSettingClosestToHome(tdb, SPECIES_GROUP_VAR); -char *speciesUseFile = trackDbSettingClosestToHome(tdb, SPECIES_USE_FILE); -char *speciesOrder = trackDbSettingClosestToHome(tdb, SPECIES_ORDER_VAR); +char *speciesGroup = trackDbSetting(tdb, SPECIES_GROUP_VAR); +char *speciesUseFile = trackDbSetting(tdb, SPECIES_USE_FILE); +char *speciesOrder = trackDbSetting(tdb, SPECIES_ORDER_VAR); char sGroup[24]; //Ochar *groups[20]; struct wigMafSpecies *wmSpecies, *wmSpeciesList = NULL; int group; int i; #define MAX_SP_SIZE 2000 #define MAX_GROUPS 20 char *species[MAX_SP_SIZE]; char option[MAX_SP_SIZE]; /* determine species and groups for pairwise -- create checkboxes */ if (speciesOrder == NULL && speciesGroup == NULL && speciesUseFile == NULL) { if (isCustomTrack(tdb->track)) return NULL; errAbort("Track %s missing required trackDb setting: speciesOrder, speciesGroups, or speciesUseFile", tdb->track); } char **groups = needMem(MAX_GROUPS * sizeof (char *)); *groupCt = 1; if (speciesGroup) *groupCt = chopByWhite(speciesGroup, groups, MAX_GROUPS); if (speciesUseFile) { if ((speciesGroup != NULL) || (speciesOrder != NULL)) errAbort("Can't specify speciesUseFile and speciesGroup or speciesOrder"); - speciesOrder = cartGetOrderFromFile(db, cart, speciesUseFile); - } + speciesOrder = cartGetOrderFromFile(db, cart, speciesUseFile); // Not sure why this is in cart + } // not tdb based so no ClosestToHome for (group = 0; group < *groupCt; group++) { if (*groupCt != 1 || !speciesOrder) { safef(sGroup, sizeof sGroup, "%s%s", SPECIES_GROUP_PREFIX, groups[group]); speciesOrder = trackDbRequiredSetting(tdb, sGroup); } speciesCt = chopLine(speciesOrder, species); for (i = 0; i < speciesCt; i++) { AllocVar(wmSpecies); wmSpecies->name = cloneString(species[i]); -#ifdef SUBTRACK_CFG - *option = '\0'; // signal to look for the lowest level -#endif///def SUBTRACK_CFG + safecpy(option,sizeof option,prefix); wmSpecies->on = isSpeciesOn(cart, tdb, wmSpecies->name, option, sizeof option, TRUE); wmSpecies->group = group; slAddHead(&wmSpeciesList, wmSpecies); } } slReverse(&wmSpeciesList); *list = wmSpeciesList; return groups; } struct wigMafSpecies * wigMafSpeciesTable(struct cart *cart, struct trackDb *tdb, char *name, char *db) { int groupCt; #define MAX_SP_SIZE 2000 char option[MAX_SP_SIZE]; int group, prevGroup; int i,j; +boolean viewLevel = isNameAtCompositeLevel(tdb,name); bool lowerFirstChar = TRUE; -char *speciesTarget = trackDbSetting(tdb, SPECIES_TARGET_VAR); -char *speciesTree = trackDbSetting(tdb, SPECIES_TREE_VAR); struct wigMafSpecies *wmSpeciesList; -char **groups = wigMafGetSpecies(cart, tdb, db, &wmSpeciesList, &groupCt); +char **groups = wigMafGetSpecies(cart, tdb, name, db, &wmSpeciesList, &groupCt); struct wigMafSpecies *wmSpecies = wmSpeciesList; struct slName *speciesList = NULL; for(; wmSpecies; wmSpecies = wmSpecies->next) { struct slName *newName = slNameNew(wmSpecies->name); slAddHead(&speciesList, newName); //printf("%s
\n",speciesList->name); } slReverse(&speciesList); int numberPerRow; -struct phyloTree *tree; boolean lineBreakJustPrinted; char trackName[255]; char query[256]; char **row; struct sqlConnection *conn; struct sqlResult *sr; char *words[MAX_SP_SIZE]; int defaultOffSpeciesCnt = 0; if(cartOptionalString(cart, "ajax") == NULL) jsIncludeFile("utils.js",NULL); //jsInit(); puts("\n

Species selection: "); PLUS_BUTTON( "id", "plus_pw","cb_maf_","_maf_"); @@ -5660,56 +5666,62 @@ char *defaultOffSpecies = trackDbSetting(tdb, "speciesDefaultOff"); struct hash *offHash = NULL; if (defaultOffSpecies) { offHash = newHash(5); DEFAULT_BUTTON( "id", "default_pw","cb_maf_","_maf_"); int wordCt = chopLine(defaultOffSpecies, words); defaultOffSpeciesCnt = wordCt; /* build hash of species that should be off */ int ii; for(ii=0; ii < wordCt; ii++) hashAdd(offHash, words[ii], NULL); } +#define BRANEY_SAYS_USETARG_IS_OBSOLETE +#ifndef BRANEY_SAYS_USETARG_IS_OBSOLETE +char *speciesTarget = trackDbSetting(tdb, SPECIES_TARGET_VAR); +char *speciesTree = trackDbSetting(tdb, SPECIES_TREE_VAR); +struct phyloTree *tree; if ((speciesTree != NULL) && ((tree = phyloParseString(speciesTree)) != NULL)) { char buffer[128]; char *nodeNames[512]; int numNodes = 0; char *path, *orgName; int ii; safef(buffer, sizeof(buffer), "%s.vis",name); - cartMakeRadioButton(cart, buffer,"useTarg", "useTarg"); + cartMakeRadioButton(cart, buffer,"useTarg", "useTarg");// not closestToHome because BRANEY_SAYS_USETARG_IS_OBSOLETE printf("Show shortest path to target species: "); path = phyloNodeNames(tree); numNodes = chopLine(path, nodeNames); for(ii=0; ii < numNodes; ii++) { if ((orgName = hOrganism(nodeNames[ii])) != NULL) nodeNames[ii] = orgName; nodeNames[ii][0] = toupper(nodeNames[ii][0]); } cgiMakeDropList(SPECIES_HTML_TARGET, nodeNames, numNodes, - cartUsualString(cart, SPECIES_HTML_TARGET, speciesTarget)); + cartUsualString(cart, SPECIES_HTML_TARGET, speciesTarget));// not closestToHome because BRANEY_SAYS_USETARG_IS_OBSOLETE puts("
"); - cartMakeRadioButton(cart,buffer,"useCheck", "useTarg"); + cartMakeRadioButton(cart,buffer,"useCheck", "useTarg"); // not closestToHome because BRANEY_SAYS_USETARG_IS_OBSOLETE printf("Show all species checked : "); } +#endif///ndef BRANEY_SAYS_USETARG_IS_OBSOLETE if (groupCt == 1) puts("\n"); group = -1; lineBreakJustPrinted = FALSE; for (wmSpecies = wmSpeciesList, i = 0, j = 0; wmSpecies != NULL; wmSpecies = wmSpecies->next, i++) { char *label; prevGroup = group; group = wmSpecies->group; if (groupCt != 1 && group != prevGroup) { i = 0; j = 0; @@ -5771,180 +5783,168 @@ /* test if the entry actually is part of the specific maf track data */ if (chp != NULL) { *chp = '\0'; safef(query, sizeof(query), "select id from %sMsa where id = 'ss.%s'", trackName, label); conn = hAllocConn(db); sr = sqlGetResult(conn, query); row = sqlNextRow(sr); /* offer it only if the entry is found in current maf data set */ if (row != NULL) { puts(""); fflush(stdout); lineBreakJustPrinted = FALSE; j++; } sqlFreeResult(&sr); hFreeConn(&conn); } } else { puts(""); lineBreakJustPrinted = FALSE; j++; } } puts("
"); - cgiMakeCheckBoxWithId(option, cartUsualBoolean(cart, option, checked),id); + cgiMakeCheckBoxWithId(option,cartUsualBooleanClosestToHome( + cart, tdb, viewLevel,wmSpecies->name, checked),id); printf ("%s", label); puts(""); boolean defaultState = TRUE; if (offHash != NULL) defaultState = (hashLookup(offHash, wmSpecies->name) == NULL); -#ifdef SUBTRACK_CFG safecpy(option, sizeof(option), name); -#endif///def SUBTRACK_CFG wmSpecies->on = isSpeciesOn(cart, tdb, wmSpecies->name, option, sizeof option, defaultState ); cgiMakeCheckBoxWithId(option, wmSpecies->on,id); label = hOrganism(wmSpecies->name); if (label == NULL) label = wmSpecies->name; if (lowerFirstChar) *label = tolower(*label); printf ("%s
", label); puts("

\n"); return wmSpeciesList; } void wigMafCfgUi(struct cart *cart, struct trackDb *tdb,char *name, char *title, boolean boxed, char *db) /* UI for maf/wiggle track * NOTE: calls wigCfgUi */ { bool lowerFirstChar = TRUE; int i; char option[MAX_SP_SIZE]; -char *viewString = NULL; - -// FIXME: wigMaf is using non-standard view level naming methods so isn't configurable by ajax -#ifndef SUBTRACK_CFG -subgroupFind(tdb, "view", &viewString); -#endif///ndef SUBTRACK_CFG +boolean viewLevel = isNameAtCompositeLevel(tdb,name); boxed = cfgBeginBoxAndTitle(tdb, boxed, title); char *defaultCodonSpecies = trackDbSetting(tdb, SPECIES_CODON_DEFAULT); char *framesTable = trackDbSetting(tdb, "frames"); char *firstCase = trackDbSetting(tdb, ITEM_FIRST_CHAR_CASE); if (firstCase != NULL) { if (sameWord(firstCase, "noChange")) lowerFirstChar = FALSE; } char *treeImage = NULL; struct consWiggle *consWig, *consWiggles = wigMafWiggles(db, tdb); boolean isWigMafProt = FALSE; if (strstr(tdb->type, "wigMafProt")) isWigMafProt = TRUE; puts("
"); if (consWiggles && consWiggles->next) { /* check for alternate conservation wiggles -- create checkboxes */ puts("

Conservation:" ); boolean first = TRUE; for (consWig = consWiggles; consWig != NULL; consWig = consWig->next) { - char *wigVar = wigMafWiggleVar(tdb, consWig); - cgiMakeCheckBox(wigVar, cartUsualBoolean(cart, wigVar, first)); + char *wigVar = wigMafWiggleVar(name, consWig); + char *wigVarSuffix = wigVar + strlen(name) + 1; + cgiMakeCheckBox(wigVar, + cartUsualBooleanClosestToHome(cart, tdb, viewLevel, wigVarSuffix, first)); first = FALSE; subChar(consWig->uiLabel, '_', ' '); printf ("%s ", consWig->uiLabel); } } struct wigMafSpecies *wmSpeciesList = wigMafSpeciesTable(cart, tdb, name, db); struct wigMafSpecies *wmSpecies; if (isWigMafProt) puts("Multiple alignment amino acid-level:
" ); else puts("Multiple alignment base-level:
" ); -if (viewString != NULL) - safef(option, sizeof option, "%s.%s.%s", name, viewString, MAF_DOT_VAR); -else safef(option, sizeof option, "%s.%s", name, MAF_DOT_VAR); -cgiMakeCheckBox(option, cartCgiUsualBoolean(cart, option, FALSE)); +cgiMakeCheckBox(option, cartUsualBooleanClosestToHome(cart, tdb, viewLevel,MAF_DOT_VAR, FALSE)); if (isWigMafProt) puts("Display amino acids identical to reference as dots
" ); else puts("Display bases identical to reference as dots
" ); -if (viewString != NULL) - safef(option, sizeof option, "%s.%s.%s", name, viewString, MAF_CHAIN_VAR); -else safef(option, sizeof option, "%s.%s", name, MAF_CHAIN_VAR); -cgiMakeCheckBox(option, cartCgiUsualBoolean(cart, option, TRUE)); +cgiMakeCheckBox(option, cartUsualBooleanClosestToHome(cart, tdb, viewLevel, MAF_CHAIN_VAR, TRUE)); char *irowStr = trackDbSetting(tdb, "irows"); boolean doIrows = (irowStr == NULL) || !sameString(irowStr, "off"); if (isCustomTrack(tdb->track) || doIrows) puts("Display chains between alignments
"); else { if (isWigMafProt) puts("Display unaligned amino acids with spanning chain as 'o's
"); else puts("Display unaligned bases with spanning chain as 'o's
"); } safef(option, sizeof option, "%s.%s", name, "codons"); if (framesTable) { char *nodeNames[512]; char buffer[128]; printf("
Codon Translation:
"); printf("Default species to establish reading frame: "); nodeNames[0] = db; for (wmSpecies = wmSpeciesList, i = 1; wmSpecies != NULL; wmSpecies = wmSpecies->next, i++) { nodeNames[i] = wmSpecies->name; } cgiMakeDropList(SPECIES_CODON_DEFAULT, nodeNames, i, - cartUsualString(cart, SPECIES_CODON_DEFAULT, defaultCodonSpecies)); + cartUsualString(cart, SPECIES_CODON_DEFAULT, defaultCodonSpecies)); // tdb independent var puts("
"); - if (viewString != NULL) - safef(buffer, sizeof(buffer), "%s.%s.codons",name, viewString); - else + char *cartVal = cartUsualStringClosestToHome(cart, tdb, viewLevel, "codons","codonDefault"); safef(buffer, sizeof(buffer), "%s.codons",name); - cartMakeRadioButton(cart, buffer,"codonNone", "codonDefault"); + cgiMakeRadioButton(buffer,"codonNone", sameWord(cartVal,"codonNone")); printf("No codon translation
"); - cartMakeRadioButton(cart, buffer,"codonDefault", "codonDefault"); + cgiMakeRadioButton(buffer,"codonDefault", sameWord(cartVal,"codonDefault")); printf("Use default species reading frames for translation
"); - cartMakeRadioButton(cart, buffer,"codonFrameNone", "codonDefault"); + cgiMakeRadioButton(buffer,"codonFrameNone",sameWord(cartVal,"codonFrameNone")); printf("Use reading frames for species if available, otherwise no translation
"); - cartMakeRadioButton(cart, buffer,"codonFrameDef", "codonDefault"); + cgiMakeRadioButton(buffer,"codonFrameDef", sameWord(cartVal,"codonFrameDef")); printf("Use reading frames for species if available, otherwise use default species
"); } else { /* Codon highlighting does not apply to wigMafProt type */ if (!strstr(tdb->type, "wigMafProt")) { puts("

Codon highlighting:
" ); #ifdef GENE_FRAMING safef(option, sizeof(option), "%s.%s", name, MAF_FRAME_VAR); char *currentCodonMode = cartCgiUsualString(cart, option, MAF_FRAME_GENE); /* Disable codon highlighting */ @@ -6137,85 +6137,84 @@ { char *visibility = NULL; compositeViewCfgExpandedByDefault(parentTdb,view,&visibility); enum trackVisibility vis = hTvFromString(visibility); freeMem(visibility); return vis; } static boolean hCompositeDisplayViewDropDowns(char *db, struct cart *cart, struct trackDb *parentTdb) /* UI for composite view drop down selections. */ { int ix; char varName[SMALLBUF]; char classes[SMALLBUF]; char javascript[JBUFSIZE]; -#define CFG_LINK "%s" -#define MAKE_CFG_LINK(name,title,tbl,open) printf(CFG_LINK, (name),(name),(title),(title),(tbl),(name),((open)?"on":"off")) +#define CFG_LINK "%s" +#define MAKE_CFG_LINK(name,title,viewTrack,open) printf(CFG_LINK, (name),(name),(title),(title),(viewTrack),((open)?"on":"off")) membersForAll_t *membersForAll = membersForAllSubGroupsGet(parentTdb, cart); // membersForAll is generated once per track, then cached members_t *membersOfView = membersForAll->members[dimV]; if(membersOfView == NULL) return FALSE; char configurable[membersOfView->count]; memset(configurable,cfgNone,sizeof(configurable)); int firstOpened = -1; boolean makeCfgRows = FALSE; struct trackDb **matchedViewTracks = needMem(sizeof(struct trackDb *)*membersOfView->count); for (ix = 0; ix < membersOfView->count; ix++) { - char *viewName = membersOfView->tags[ix]; if (membersOfView->subtrackList != NULL && membersOfView->subtrackList[ix] != NULL) { struct trackDb *subtrack = membersOfView->subtrackList[ix]->val; matchedViewTracks[ix] = subtrack->parent; configurable[ix] = (char)cfgTypeFromTdb(subtrack, TRUE); if(configurable[ix] != cfgNone) { if(firstOpened == -1) { - safef(varName, sizeof(varName), "%s.%s.showCfg", parentTdb->track, viewName); - if(cartUsualBoolean(cart,varName,FALSE)) + safef(varName, sizeof(varName), "%s.showCfg", matchedViewTracks[ix]->track); + if(cartUsualBoolean(cart,varName,FALSE)) // No need for closestToHome: view level input firstOpened = ix; } makeCfgRows = TRUE; } } } toLowerN(membersOfView->groupTitle, 1); printf("Select %s (help):\n", membersOfView->groupTitle); printf("\n"); // Make row of vis drop downs for (ix = 0; ix < membersOfView->count; ix++) { char *viewName = membersOfView->tags[ix]; if (matchedViewTracks[ix] != NULL) { printf(""); - safef(varName, sizeof(varName), "%s.%s.vis", parentTdb->track, viewName); + safef(varName, sizeof(varName), "%s.%s.vis", parentTdb->track, viewName); // FIXME: Time to get rid of "track.view.vis" since viewInTheMiddle enum trackVisibility tv = hTvFromString(cartUsualString(cart, varName,hStringFromTv(visCompositeViewDefault(parentTdb,viewName)))); safef(javascript, sizeof(javascript), "onchange=\"matSelectViewForSubTracks(this,'%s');\" onfocus='this.lastIndex=this.selectedIndex;'", viewName); printf(""); } } puts(""); // Make row of cfg boxes if needed if(makeCfgRows) @@ -6224,37 +6223,36 @@ for (ix = 0; ix < membersOfView->count; ix++) { struct trackDb *view = matchedViewTracks[ix]; if (view != NULL) { char *viewName = membersOfView->tags[ix]; printf("tags[ix],NULL)) || (firstOpened != -1 && firstOpened != ix)) printf(" style=\"display:none\""); printf(">"); int ix2=ix; while(0 < ix2--) printf(""); printf("
"); if(configurable[ix] != cfgNone) { - MAKE_CFG_LINK(membersOfView->tags[ix],membersOfView->titles[ix],parentTdb->track,(firstOpened == ix)); + MAKE_CFG_LINK(membersOfView->tags[ix],membersOfView->titles[ix],matchedViewTracks[ix]->track,(firstOpened == ix)); } else printf("%s",membersOfView->titles[ix]); puts(""); safef(classes, sizeof(classes), "viewDD normalText %s", membersOfView->tags[ix]); hTvDropDownClassWithJavascript(varName, tv, parentTdb->canPack,classes,javascript); puts("      
  ",membersOfView->count+1); - safef(varName, sizeof(varName), "%s", view->track); if(configurable[ix] != cfgNone) - { - cfgByCfgType(configurable[ix],db,cart,view->subtracks,varName, + { // Hint: subtrack is model but named for view + cfgByCfgType(configurable[ix],db,cart,view->subtracks,view->track, membersOfView->titles[ix],TRUE); #ifndef SUBTRACK_CFG - cfgLinkToDependentCfgs(cart,parentTdb,varName); + cfgLinkToDependentCfgs(cart,parentTdb,view->track); #endif///ndef SUBTRACK_CFG } } } } puts("
"); freeMem(matchedViewTracks); return TRUE; } char *compositeLabelWithVocabLink(char *db,struct trackDb *parentTdb, struct trackDb *childTdb, char *vocabType, char *label) /* If the parentTdb has a controlledVocabulary setting and the vocabType is found, then label will be wrapped with the link to display it. Return string is cloned. */ {