d147153dbb70eb9018b248543b6f39dde939076a tdreszer Fri Oct 7 16:52:46 2011 -0700 Another set of fixes propted by going through all of hg19 again and another 7 assemblies from different species and clades. diff --git src/hg/lib/hui.c src/hg/lib/hui.c index f996832..cf1dad4 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -2474,40 +2474,36 @@ // Weed out members of a subgroup without any subtracks, alters memory in place! { // First tally all subtrack counts int ixIn=0; struct slRef *subtrackRef, *subtrackRefList = trackDbListGetRefsToDescendantLeaves(parentTdb->subtracks); struct trackDb *subtrack; members->subtrackCount = needMem(members->count * sizeof(int)); members->currentlyVisible = needMem(members->count * sizeof(int)); members->subtrackList = needMem(members->count * sizeof(struct slRef *)); for (subtrackRef = subtrackRefList; subtrackRef != NULL; subtrackRef = subtrackRef->next) { subtrack = subtrackRef->val; char *belongsTo =NULL; if(subgroupFind(subtrack,members->groupTag,&belongsTo)) { - for(ixIn=0;ixIn<members->count;ixIn++) - { - if(sameString(members->tags[ixIn],belongsTo)) + if (-1 != (ixIn = stringArrayIx(belongsTo, members->tags, members->count))) { members->subtrackCount[ixIn]++; if(cart && fourStateVisible(subtrackFourStateChecked(subtrack,cart))) members->currentlyVisible[ixIn]++; refAdd(&(members->subtrackList[ixIn]), subtrack); - break; - } } } } // Now weed out empty subgroup tags. Can do this in place since new count <= old count // NOTE: Don't I wish I had made these as an slList ages ago! (tim) int ixOut=0; for(ixIn=ixOut;ixIn<members->count;ixIn++) { if(members->subtrackCount[ixIn] > 0) { if(ixOut < ixIn) { members->tags[ixOut] = members->tags[ixIn]; members->titles[ixOut] = members->titles[ixIn]; @@ -2645,30 +2641,31 @@ membersForAll->dimMax = ixOut; membersForAll->abcCount = membersForAll->dimMax - dimA; return membersForAll; } static membersForAll_t* membersForAllSubGroupsGet(struct trackDb *parentTdb, struct cart *cart) /* Returns all the parents subGroups and members */ { membersForAll_t *membersForAll = tdbExtrasMembersForAll(parentTdb); if(membersForAll != NULL) return membersForAll; // Already retrieved, so don't do it again int ix; membersForAll = needMem(sizeof(membersForAll_t)); +if (tdbIsCompositeView(parentTdb->subtracks)) // view must have viewInMidle tdb in tree membersForAll->members[dimV]=subgroupMembersGet(parentTdb,"view"); membersForAll->letters[dimV]='V'; membersForAll->dimMax=dimA; // This can expand, depending upon ABC dimensions membersForAll->dimensions = dimensionSettingsGet(parentTdb); if(membersForAll->dimensions != NULL) { for(ix=0;ix<membersForAll->dimensions->count;ix++) { char letter = lastChar(membersForAll->dimensions->names[ix]); if(letter != 'X' && letter != 'Y') { membersForAll->members[membersForAll->dimMax]=subgroupMembersGet(parentTdb, membersForAll->dimensions->subgroups[ix]); membersForAll->letters[membersForAll->dimMax]=letter; if(cart != NULL) membersForAll->checkedTags[membersForAll->dimMax] = abcMembersChecked(parentTdb,cart,membersForAll->members[membersForAll->dimMax],letter); @@ -3805,34 +3802,30 @@ struct slRef *subtrackRef, *subtrackRefList = trackDbListGetRefsToDescendantLeaves(parentTdb->subtracks); // Look for dividers, heirarchy, dimensions, sort and dragAndDrop! char **lastDivide = NULL; dividers_t *dividers = dividersSettingGet(parentTdb); if (dividers) lastDivide = needMem(sizeof(char*)*dividers->count); hierarchy_t *hierarchy = hierarchySettingGet(parentTdb); membersForAll_t* membersForAll = membersForAllSubGroupsGet(parentTdb,NULL); int dimCount=0,di; for(di=0;di<membersForAll->dimMax;di++) { if (membersForAll->members[di]) dimCount++; } sortOrder_t* sortOrder = sortOrderGet(cart,parentTdb); boolean preSorted = FALSE; boolean useDragAndDrop = sameOk("subTracks",trackDbSetting(parentTdb, "dragAndDrop")); -#ifdef SUBTRACK_CFG -if (useDragAndDrop) - useDragAndDrop = (sortOrder == NULL); // Only support drag and drop when not sortable table -#endif///def SUBTRACK_CFG char buffer[SMALLBUF]; char *displaySubs = NULL; int subCount = slCount(subtrackRefList); #define LARGE_COMPOSITE_CUTOFF 30 if (subCount > LARGE_COMPOSITE_CUTOFF) { safef(buffer,SMALLBUF,"%s.displaySubtracks",parentTdb->track); displaySubs = cartUsualString(cart, buffer,"some"); // track specific defaults to only selected } else { displaySubs = cartUsualString(cart, "displaySubtracks", "all"); // browser wide defaults to all } boolean displayAll = sameString(displaySubs, "all"); @@ -3996,55 +3989,60 @@ preSorted = tdbRefSortPrioritiesFromCart(cart, &subtrackRefList); // preserves user's prev sort/drags printf("<TBODY class='%saltColors'>\n",(sortOrder != NULL ? "sortable " : "") ); } else { slSort(&subtrackRefList, trackDbRefCmp); // straight from trackDb.ra preSorted = TRUE; puts("<TBODY>"); } // Finally the big "for loop" to list each subtrack as a table row. printf("\n<!-- ----- subtracks list ----- -->\n"); for (subtrackRef = subtrackRefList; subtrackRef != NULL; subtrackRef = subtrackRef->next) { subtrack = subtrackRef->val; - int ix; + int ix,ix2; // Determine whether subtrack is checked, visible, configurable, has group membership, etc. int fourState = subtrackFourStateChecked(subtrack,cart); boolean checkedCB = fourStateChecked(fourState); boolean enabledCB = fourStateEnabled(fourState); boolean visibleCB = fourStateVisible(fourState); membership_t *membership = subgroupMembershipGet(subtrack); - eCfgType cType = cfgTypeFromTdb(subtrack,FALSE); + eCfgType cType = cfgNone; + if (!tdbIsMultiTrack(parentTdb)) // MultiTracks never have configurable subtracks! + cType = cfgTypeFromTdb(subtrack,FALSE); if (cType != cfgNone) { #ifdef SUBTRACK_CFG // Turn off configuring for certain track type or if explicitly turned off int cfgSubterack = configurableByPopup(subtrack,cType); if (cfgSubterack <= 0) cType = cfgNone; - else if (membersForAll->members[dimV]) - { + else if (membersForAll->members[dimV]) // subtrack only configurable if more than one subtrack in view + { // find "view" in subgroup membership: e.g. "signal" if (-1 != (ix = stringArrayIx(membersForAll->members[dimV]->groupTag, membership->subgroups, membership->count))) - { // Don't make a configurable subtrack if there is only one in the view (assumes view is configurable) - if (slCount(membersForAll->members[dimV]->subtrackList[ix]) < 2) + { // find "signal" in set of all views + if (-1 != (ix2 = stringArrayIx(membership->membership[ix], membersForAll->members[dimV]->tags, membersForAll->members[dimV]->count))) + { + if (membersForAll->members[dimV]->subtrackCount[ix2] < 2) cType = cfgNone; } } - else if (slCount(parentTdb->subtracks) < 2 && cfgTypeFromTdb(parentTdb,FALSE) != cfgNone) + } + else if (slCount(subtrackRefList) < 2 && cfgTypeFromTdb(parentTdb,FALSE) != cfgNone) cType = cfgNone; // don't bother if there is a single subtrack but the composite is configurable. #else///ifndef SUBTRACK_CFG if (trackDbSettingClosestToHomeOn(subtrack, "configurable") == FALSE) cType = cfgNone; #endif///ndef SUBTRACK_CFG } if (sortOrder == NULL && !useDragAndDrop) { if ( divisionIfNeeded(lastDivide,dividers,membership) ) colorIx = (colorIx == COLOR_BG_DEFAULT_IX ? COLOR_BG_ALTDEFAULT_IX : COLOR_BG_DEFAULT_IX); } // Start the TR which must have an id that is directly related to the checkBox id char *id = checkBoxIdMakeForTrack(subtrack,membersForAll->members,membersForAll->dimMax,membership); // view is known tag @@ -4071,46 +4069,50 @@ // And finally the checkBox is made! safef(buffer, sizeof(buffer), "%s_sel", subtrack->track); #ifdef SUBTRACK_CFG if (!enabledCB) { dyStringAppend(dyHtml, " disabled"); cgiMakeCheckBoxFourWay(buffer,checkedCB,enabledCB,id,dyStringContents(dyHtml),"onclick='matSubCbClick(this);' style='cursor:pointer' title='view is hidden'"); } else #endif///def SUBTRACK_CFG cgiMakeCheckBoxFourWay(buffer,checkedCB,enabledCB,id,dyStringContents(dyHtml),"onclick='matSubCbClick(this);' style='cursor:pointer'"); if (useDragAndDrop) printf(" "); #ifdef SUBTRACK_CFG + if (!tdbIsMultiTrack(parentTdb)) // MultiTracks never have independent vis + { enum trackVisibility vis = tdbVisLimitedByAncestors(cart,subtrack,FALSE,FALSE); char *view = NULL; - if (membersForAll->members[dimV] && -1 != (ix = stringArrayIx(membersForAll->members[dimV]->groupTag, membership->subgroups, membership->count))) + if (membersForAll->members[dimV] + && -1 != (ix = stringArrayIx(membersForAll->members[dimV]->groupTag, membership->subgroups, membership->count))) view = membership->membership[ix]; char classList[256]; if (view != NULL) safef(classList,sizeof(classList),"clickable fauxInput%s subVisDD %s",(visibleCB ? "":" disabled"),view); // view should be last! else safef(classList,sizeof(classList),"clickable fauxInput%s subVisDD",(visibleCB ? "":" disabled")); #define SUBTRACK_CFG_VIS "<div id= '%s_faux' class='%s' style='width:65px;' onclick='return subCfg.replaceWithVis(this,\"%s\",true);'>%s</div>\n" printf(SUBTRACK_CFG_VIS,subtrack->track,classList,subtrack->track,hStringFromTv(vis)); if (cType != cfgNone) // make a wrench { #define SUBTRACK_CFG_WRENCH "<span class='clickable%s' onclick='return subCfg.cfgToggle(this,\"%s\");' title='Configure this subtrack'><img src='../images/wrench.png'></span>\n" printf(SUBTRACK_CFG_WRENCH,(visibleCB ? "":" disabled"),subtrack->track); } + } #endif///def SUBTRACK_CFG // A hidden field to keep track of subtrack order if it could change if (sortOrder != NULL || useDragAndDrop) { safef(buffer, sizeof(buffer), "%s.priority", subtrack->track); float priority = (float)cartUsualDouble(cart, buffer, subtrack->priority); printf("<INPUT TYPE=HIDDEN NAME='%s' class='trPos' VALUE=\"%.0f\">", buffer, priority); // keeing track of priority } // A color patch which helps distinguish subtracks in some types of composites if (doColorPatch) { printf("<TD BGCOLOR='#%02X%02X%02X'> </TD>", subtrack->colorR, subtrack->colorG, subtrack->colorB); @@ -4968,32 +4970,34 @@ if (filterByRange) { puts("<B>Filter score range: min:</B>"); snprintf(option, sizeof(option), "%s.%s", name,SCORE_FILTER _MIN); cgiMakeIntVarWithLimits(option, minVal, "Minimum score",0, minLimit,maxLimit); puts("<B>max:</B>"); 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("<b>Show only items with score at or above:</b> "); snprintf(option, sizeof(option), "%s.%s", name,SCORE_FILTER); cgiMakeIntVarWithLimits(option, minVal, "Minimum score",0, minLimit,maxLimit); - printf(" (range: %d to %d)", minLimit, maxLimit); + printf(" (range: %d to %d)\n", minLimit, maxLimit); } + if (glvlScoreMin) + printf("<BR>"); } 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 <on|off> <count> <table> */ char *words[2]; char *scoreFilterCt = NULL; chopLine(cloneString(scoreCtString), words); safef(option, sizeof(option), "%s.filterTopScorersOn", name); @@ -5454,40 +5458,38 @@ if(trackDbSettingClosestToHomeOn(tdb, "nmdFilter")) { boolean nmdDefault = FALSE; safef(varName, sizeof(varName), "hgt.%s.nmdFilter", name); nmdDefault = cartUsualBoolean(cart,varName, FALSE); // TODO: var name (hgt prefix) needs changing before ClosesToHome can be used printf("<p><b>Filter out NMD targets.</b>"); cgiMakeCheckBox(varName, nmdDefault); } if(!sameString(tdb->track, "tigrGeneIndex") && !sameString(tdb->track, "ensGeneNonCoding") && !sameString(tdb->track, "encodeGencodeRaceFrags")) baseColorDropLists(cart, tdb, name); -if (cartOptionalString(cart, "ajax") == NULL) - { filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); if(filterBySet != NULL) { printf("<BR>"); 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) */ { 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 { @@ -6036,118 +6038,103 @@ printf("<BR>\n"); } cgiMakeRadioButton(cartVarName, BAM_COLOR_MODE_OFF, sameString(selected, BAM_COLOR_MODE_OFF)); printf("No additional coloring"); //TODO: include / exclude flags if (!boxed && fileExists(hHelpFile("hgBamTrackHelp"))) printf("<P><A HREF=\"../goldenPath/help/hgBamTrackHelp.html\" TARGET=_BLANK>BAM " "configuration help</A></P>"); cfgEndBox(boxed); } #endif//def USE_BAM -struct trackDb *rFindViewInList(struct trackDb *tdbList, char *view) -/* Return the trackDb on the list (or on any children of the list) that has matching view tag. */ +struct trackDb *rFindView(struct trackDb *forest, char *view) +// Return the trackDb on the list that matches the view tag. Prefers ancestors before decendents { struct trackDb *tdb; -for (tdb = tdbList; tdb != NULL; tdb = tdb->next) +for (tdb = forest; tdb != NULL; tdb = tdb->next) { char *viewSetting = trackDbSetting(tdb, "view"); if (sameOk(viewSetting, view)) return tdb; } -for (tdb = tdbList; tdb != NULL; tdb = tdb->next) +for (tdb = forest; tdb != NULL; tdb = tdb->next) { - struct trackDb *viewTdb = rFindViewInList(tdb->subtracks, view); + struct trackDb *viewTdb = rFindView(tdb->subtracks, view); if (viewTdb != NULL) return viewTdb; } return NULL; } static boolean compositeViewCfgExpandedByDefault(struct trackDb *parentTdb,char *view, char **retVisibility) /* returns true if the view cfg is expanded by default. Optionally allocates string of view * setting (eg 'dense') */ { boolean expanded = FALSE; if ( retVisibility != NULL ) *retVisibility = cloneString(hStringFromTv(parentTdb->visibility)); -struct trackDb *viewTdb = rFindViewInList(parentTdb->subtracks, view); +struct trackDb *viewTdb = rFindView(parentTdb->subtracks, view); if (viewTdb == NULL) return FALSE; if (retVisibility != NULL) *retVisibility = cloneString(hStringFromTv(viewTdb->visibility)); if (trackDbSetting(viewTdb, "viewUi")) expanded = TRUE; return expanded; } enum trackVisibility visCompositeViewDefault(struct trackDb *parentTdb,char *view) /* returns the default track visibility of particular view within a composite track */ { char *visibility = NULL; compositeViewCfgExpandedByDefault(parentTdb,view,&visibility); enum trackVisibility vis = hTvFromString(visibility); freeMem(visibility); return vis; } -struct trackDb *rFindView(struct trackDb *forest, char *viewName) -/* Find a descendent with given view. */ -{ -struct trackDb *tdb; -for (tdb = forest; tdb != NULL; tdb = tdb->next) - { - char *viewSetting = trackDbSetting(tdb, "view"); - if (sameOk(viewSetting, viewName)) - return tdb; - struct trackDb *view = rFindView(tdb->subtracks, viewName); - if (view) - return view; - } -return NULL; -} - 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 "<B><A HREF=\"#a_cfg_%s\" onclick=\"return (showConfigControls('%s') == false);\" title=\"%s Configuration\">%s</A><INPUT TYPE=HIDDEN NAME='%s.%s.showCfg' value='%s'></B>" #define MAKE_CFG_LINK(name,title,tbl,open) printf(CFG_LINK, (name),(name),(title),(title),(tbl),(name),((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) + 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)) firstOpened = ix; } makeCfgRows = TRUE; } }