530842acf922e67838eab9fa153b7b7c0b90e9c2 braney Thu Apr 18 12:31:31 2024 -0700 allow track hubs to make groups diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c index 1cd8bbf..65b9b02 100644 --- src/hg/lib/trackHub.c +++ src/hg/lib/trackHub.c @@ -43,42 +43,89 @@ #include "bPlusTree.h" #include "hgFind.h" #include "hubConnect.h" #include "trix.h" #include "vcf.h" #include "vcfUi.h" #include "htmshell.h" #include "bigBedFind.h" #include "customComposite.h" #include "interactUi.h" #include "bedTabix.h" #include "hic.h" #include "hui.h" #include "chromAlias.h" #include "trashDir.h" +#include "hgConfig.h" #ifdef USE_HAL #include "halBlockViz.h" #endif +struct grp *trackHubGrps = NULL; // global with grps loaded from track hubs static struct hash *hubCladeHash; // mapping of clade name to hub pointer static struct hash *hubAssemblyHash; // mapping of assembly name to genome struct static struct hash *hubAssemblyUndecoratedHash; // mapping of undecorated assembly name to genome struct static struct hash *hubOrgHash; // mapping from organism name to hub pointer static struct trackHub *globalAssemblyHubList; // list of trackHubs in the user's cart static struct hash *trackHubHash; +static boolean hubsCanAddGroups() +/* can track hubs have their own groups? */ +{ +static boolean canHubs = FALSE; +static boolean canHubsSet = FALSE; + +if (!canHubsSet) + { + canHubs = cfgOptionBooleanDefault("trackHubsCanAddGroups", FALSE); + canHubsSet = TRUE; + } + +return canHubs; +} + +static void tdbListAddHubToGroup(char *hubName, struct trackDb *tdbList) +/* Prepend hub name to group name for every tdb. */ +{ +struct trackDb *tdb; +for (tdb = tdbList; tdb != NULL; tdb = tdb->next) + { + char buffer[4096]; + + char *grp = trackDbSetting(tdb, "group"); + safef(buffer, sizeof buffer, "%s_%s", hubName, grp); + tdb->grp = cloneString(buffer); + hashReplace(tdb->settingsHash, "group", tdb->grp); + } +} + + +static void grpListAddHubName(struct grp *grpList, struct trackHub *hub) +/* Add the hub name to the groups defined by a hub. */ +{ +char buffer[4096]; + +for (; grpList; grpList = grpList->next) + { + safef(buffer, sizeof buffer, "%s_%s", hub->name, grpList->name); + grpList->name = cloneString(buffer); + safef(buffer, sizeof buffer, "Hub: %s : %s", hub->shortLabel, grpList->label); + grpList->label = cloneString(buffer); + } +} + char *trackHubRelativeUrl(char *hubUrl, char *path) /* Return full path (in URL form if it's a remote hub) given * path possibly relative to hubUrl. Do a freeMem of result * when done. */ { /* If path itself is a URL then just return a copy of it. */ if (hasProtocol(path)) return cloneString(path); /* If it's a remote hub, let html path expander handle it. */ if (hasProtocol(hubUrl) && !startsWith("/gbdb",path)) return expandUrlOnBase(hubUrl, path); /* If we got to here hub is local, and so is path. Do standard * path parsing. */ @@ -670,30 +717,41 @@ el->defaultPos = hashFindVal(ra, "defaultPos"); if (el->defaultPos == NULL) errAbort("must have 'defaultPos' set in assembly hub in stanza ending line %d of %s", lf->lineIx, lf->fileName); el->twoBitPath = trackHubRelativeUrl(url, twoBitPath); if (twoBitBptUrl != NULL) el->twoBitBptUrl = trackHubRelativeUrl(url, twoBitBptUrl); char *htmlPath = hashFindVal(ra, "htmlPath"); if (htmlPath != NULL) hashReplace(ra, "htmlPath",trackHubRelativeUrl(url, htmlPath)); if (groups != NULL) el->groups = trackHubRelativeUrl(url, groups); addAssembly(genome, el, hub); } + else + { + if ((groups != NULL) && hubsCanAddGroups()) + { + el->groups = trackHubRelativeUrl(url, groups); + struct grp *list = readGroupRa(el->groups); + grpListAddHubName(list, hub); + + trackHubGrps = slCat(trackHubGrps, list); + } + } el->settingsHash = ra; hashAdd(ra, "hubName", hub->shortLabel); el->chromAuthority = hashFindVal(ra, "chromAuthority"); } /* Clean up and go home. */ lineFileClose(&lf); slReverse(&list); slSort(&list, genomeOrderKeyCmp); return list; } char *trackHubSetting(struct trackHub *hub, char *name) /* Return setting if it exists, otherwise NULL. */ { @@ -1092,34 +1150,39 @@ struct trackDb *tdb; for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { expandBigDataUrl(hub, genome, tdb); if (absStormName) hashReplace(tdb->settingsHash, "metaDb", absStormName); if (absTabName) hashReplace(tdb->settingsHash, "metaTab", absTabName); } validateTracks(hub, genome, tdbList); trackDbAddTableField(tdbList); if (!isEmpty(hub->name)) trackHubAddNamePrefix(hub->name, tdbList); -if (genome->twoBitPath == NULL || *foundFirstGenome) - trackHubAddGroupName(hub->name, tdbList); -else + +if ((genome->twoBitPath != NULL) && (*foundFirstGenome == FALSE)) *foundFirstGenome = TRUE; +else if (genome->groups != NULL) + tdbListAddHubToGroup(hub->name, tdbList); +else + trackHubAddGroupName(hub->name, tdbList); + + for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { trackDbFieldsFromSettings(tdb); trackDbPolish(tdb); } return tdbList; } static void reprefixString(char **pString, char *prefix) /* Replace *pString with prefix + *pString, freeing * whatever was in *pString before. */ { char *oldName = *pString; *pString = catTwoStrings(prefix, oldName); freeMem(oldName); @@ -1606,15 +1669,21 @@ char *trackHubBuild(char *db, struct cart *cart, struct dyString *visDy) /* Build a track hub using trackDb and the cart. */ { struct trackDb *tdb = hTrackDb(db); slSort(&tdb,trackDbCmp); char *filename = getHubName(cart, db); FILE *f = mustOpen(filename, "a"); chmod(filename, 0666); walkTree(f, cart, tdb, visDy); fclose(f); return cloneString(filename); } + +struct grp *trackHubGetGrps() +/* Get the groups defined by attached track hubs. */ +{ +return trackHubGrps; +}