f9c9519372b406cf392f199cdd23d1b032fa8e22 braney Tue Jun 3 12:02:11 2025 -0700 put quickLifted tracks in the right order and with the right visibilities diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c index d5f10976ee6..c94873984bd 100644 --- src/hg/lib/trackHub.c +++ src/hg/lib/trackHub.c @@ -1606,92 +1606,94 @@ enabled = TRUE; return enabled; } static void dumpTdbAndChildren(struct cart *cart, struct dyString *dy, struct trackDb *tdb) /* Put a trackDb entry into a dyString, stepping up the tree for some variables. */ { struct hashCookie cookie = hashFirst(tdb->settingsHash); struct hashEl *hel; dyStringPrintf(dy, "visibility %s\n", hStringFromTv(tdb->visibility)); while ((hel = hashNext(&cookie)) != NULL) { if (differentString(hel->name, "track") && differentString(hel->name, "visibility")) { - if (sameString(hel->name, "parent") ) - dyStringPrintf(dy, "parent %s on\n", tdb->parent->track); - else if (sameString(hel->name, "html")) + if (sameString(hel->name, "html")) dyStringPrintf(dy, "%s %s\n", hel->name, trackHubSkipHubName((char *)hel->val)); else dyStringPrintf(dy, "%s %s\n", hel->name, ((char *)hel->val)); } } if (tdb->subtracks) { for (tdb = tdb->subtracks; tdb; tdb = tdb->next) { char *track = trackHubSkipHubName(tdb->track); dyStringPrintf(dy, "\ntrack %s\nquickLifted on\n", track); if (!isVetted(track)) dyStringPrintf(dy, "avoidHandler on\n"); if (isParentVisible(cart, tdb) && isSubtrackVisible(cart, tdb)) // child of supertrack { char *cartVis = cartOptionalString(cart, tdb->parent->track); if (cartVis != NULL) tdb->visibility = hTvFromString(cartVis); - //else if (tdbIsSuperTrack(tdb->parent)) - // tdb->visibility = tdb->parent->isShow; } dumpTdbAndChildren(cart, dy, tdb); } } } struct dyString *trackDbString(struct cart *cart, struct trackDb *tdb) /* Convert a trackDb entry into a dyString. */ { struct dyString *dy; // add a note that the name based handler shouldn't be used on this track // add a note that this is a quickLifted track so the browser will accept tracks that aren't big* dy = dyStringNew(200); char *track = trackHubSkipHubName(tdb->track); dyStringPrintf(dy, "track %s\nquickLifted on\n", track); +if (tdbIsSuperTrack(tdb)) + { + dyStringPrintf(dy, "superTrack on show\n"); + } + if (!isVetted(track)) dyStringPrintf(dy, "avoidHandler on\n"); dumpTdbAndChildren(cart, dy, tdb); return dy; } static boolean validateOneTdb(char *db, struct trackDb *tdb, struct trackDb **badList) /* Make sure the tdb is a track type we grok. */ { if (!( startsWith("bigBed", tdb->type) || \ startsWith("bigWig", tdb->type) || \ startsWith("bigDbSnp", tdb->type) || \ startsWith("bigGenePred", tdb->type) || \ startsWith("gvf", tdb->type) || \ startsWith("genePred", tdb->type) || \ startsWith("narrowPeak", tdb->type) || \ startsWith("bigLolly", tdb->type) || \ + sameString("bed", tdb->type) || startsWith("bed ", tdb->type))) { printf("%s %s
\n",tdb->track,tdb->type); return FALSE; } // make sure we have a bigDataUrl if (startsWith("bigBed", tdb->type) || \ startsWith("bigWig", tdb->type)) { char *fileName = cloneString(trackDbSetting(tdb, "bigDataUrl")); if (fileName == NULL) { struct sqlConnection *conn = hAllocConnTrack(db, tdb); @@ -1752,92 +1754,130 @@ if (tdb->subtracks) { tdb->subtracks = validateTdbChildren(cart, db, tdb->subtracks, badList); if (tdb->subtracks == NULL) return FALSE; return TRUE; } return validateOneTdb(db, tdb, badList); } static void walkTree(FILE *f, char *db, struct cart *cart, struct trackDb *tdb, struct dyString *visDy, struct trackDb **badList) /* walk tree looking for visible tracks. */ { +unsigned priority = 0; +struct hash *haveSuper = newHash(0); +char buffer[1024]; + for(; tdb; tdb = tdb->next) { boolean isVisible = FALSE; if (tdb->parent == NULL) // not in super track { char *cartVis = cartOptionalString(cart, tdb->track); if (cartVis != NULL) { tdb->visibility = hTvFromString(cartVis); } isVisible = tdb->visibility != tvHide; } else if (isParentVisible(cart, tdb) && isSubtrackVisible(cart, tdb)) // child of supertrack + { + if (hashLookup(haveSuper, tdb->parent->track) == NULL) // output yet? { char *cartVis = cartOptionalString(cart, tdb->parent->track); + if (cartVis != NULL) + { + tdb->parent->visibility = hTvFromString(cartVis); + } + safef(buffer, sizeof buffer, "%d", priority++); + hashReplace(tdb->parent->settingsHash, "priority", cloneString(buffer)); + struct dyString *dy = trackDbString(cart, tdb->parent); + fprintf(f, "%s\n", dy->string); + + hashStore(haveSuper, tdb->parent->track); + } + char *cartVis = cartOptionalString(cart, tdb->track); if (cartVis != NULL) tdb->visibility = hTvFromString(cartVis); - else if (tdbIsSuperTrack(tdb->parent)) - tdb->visibility = tdb->parent->isShow; - isVisible = TRUE; + isVisible = tdb->visibility != tvHide; } if (isVisible && validateTdb(cart, db, tdb, badList)) { - dyStringPrintf(visDy, "&%s=%s", trackHubSkipHubName(tdb->track),hStringFromTv(tdb->visibility)); - //if (hashLookup(tdb->settingsHash, "customized") == NULL) - { - hashRemove(tdb->settingsHash, "maxHeightPixels"); - hashRemove(tdb->settingsHash, "superTrack"); - hashRemove(tdb->settingsHash, "subGroups"); - hashRemove(tdb->settingsHash, "polished"); - hashRemove(tdb->settingsHash, "noInherit"); - hashRemove(tdb->settingsHash, "group"); - hashRemove(tdb->settingsHash, "parent"); - } + hashRemove(tdb->settingsHash, "superTrack"); // this gets inherited by subTracks(?) - //hashReplace(tdb->settingsHash, "customized", "on"); + safef(buffer, sizeof buffer, "%d", priority++); + hashReplace(tdb->settingsHash, "priority", cloneString(buffer)); // is this a custom track? char *tdbType = trackDbSetting(tdb, "tdbType"); if (tdbType != NULL) { hashReplace(tdb->settingsHash, "type", tdbType); hashReplace(tdb->settingsHash, "shortLabel", trackDbSetting(tdb, "name")); hashReplace(tdb->settingsHash, "longLabel", trackDbSetting(tdb, "description")); } struct dyString *dy = trackDbString(cart, tdb); fprintf(f, "%s\n", dy->string); } } } +static int cmpPriority(const void *va, const void *vb) +/* Compare to sort based on priority; use shortLabel as secondary sort key. */ +{ +const struct trackDb *a = *((struct trackDb **)va); +const struct trackDb *b = *((struct trackDb **)vb); +float dif = 0; + +dif = a->groupPriority - b->groupPriority; +if (dif == 0) + dif = a->priority - b->priority; +if (dif < 0) + return -1; +else if (dif == 0.0) + /* secondary sort on label */ + return strcasecmp(a->shortLabel, b->shortLabel); +else + return 1; +} + char *trackHubBuild(char *db, struct cart *cart, struct dyString *visDy, struct trackDb **badList) /* Build a track hub using trackDb and the cart. */ { -struct trackDb *tdbList; +struct trackDb *tdbList, *tdb; struct grp *grpList; cartTrackDbInit(cart, &tdbList, &grpList, FALSE); +struct hash *groupHash = newHash(0); +struct grp *grp; +for(grp = grpList; grp; grp = grp->next) + hashAdd(groupHash, grp->name, grp); + +for(tdb = tdbList; tdb; tdb = tdb->next) + { + grp = hashFindVal(groupHash, tdb->grp); + tdb->groupPriority = grp->priority; + } +slSort(&tdbList, cmpPriority); + char *filename = getHubName(cart, db); FILE *f = mustOpen(filename, "a"); chmod(filename, 0666); walkTree(f, db, cart, tdbList, visDy, badList); fclose(f); return cloneString(filename); } struct grp *trackHubGetGrps() /* Get the groups defined by attached track hubs. */ { return trackHubGrps;