46a8a2fde9e17a401843959b8c0197c95d43ea45
braney
  Fri Mar 15 15:54:50 2024 -0700
add quickLiftover chain to the list of tracks coming from an exported
hub

diff --git src/hg/lib/hubConnect.c src/hg/lib/hubConnect.c
index 5b08b86..4fee1b1 100644
--- src/hg/lib/hubConnect.c
+++ src/hg/lib/hubConnect.c
@@ -240,30 +240,31 @@
             // commenting this out, but leaving it in the source because we might use it later.
             //else
                 //warn("Could not connect to hub \"%s\": %s", hub->shortLabel, hub->errorMessage);
 	    }
         if ((hub->trackHub != NULL) && (replaceDb != NULL))
             {
             struct trackHubGenome *genome = hub->trackHub->genomeList;
 
             for(; genome; genome = genome->next)
                 {
                 if (sameString(genome->name, replaceDb))
                     {
                     genome->name = newDb;
                     hashAdd(hub->trackHub->genomeHash, newDb, genome);
                     genome->quickLiftChain = quickLiftChain;
+                    genome->quickLiftDb = replaceDb;
                     }
                 }
             }
 	}
     }
 sqlFreeResult(&sr);
 return hub;
 }
 
 struct hubConnectStatus *hubConnectStatusForId(struct sqlConnection *conn, int id)
 {
 return hubConnectStatusForIdExt(conn, id, NULL, NULL, NULL);
 }
 
 struct hubConnectStatus *hubConnectStatusListFromCartAll(struct cart *cart)
@@ -440,50 +441,89 @@
 static void assignQuickLift(struct trackDb *tdbList, char *quickLiftChain)
 /* step through a trackDb list and assign a quickLift chain to each track */
 {
 if (tdbList == NULL)
     return;
 
 struct trackDb *tdb;
 for(tdb = tdbList; tdb; tdb = tdb->next)
     {
     assignQuickLift(tdb->subtracks, quickLiftChain);
 
     hashAdd(tdb->settingsHash, "quickLiftUrl", quickLiftChain);
     }
 }
 
+// a string to define trackDb for quickLift chain
+static char *chainTdbString = 
+    "shortLabel chain to %s\n"
+    "longLabel chain to %s\n"
+    "type bigChain %s\n"
+    "chainType reverse\n"
+    "bigDataUrl %s\n";
+
+static struct trackDb *makeQuickLiftChainTdb(struct trackHubGenome *hubGenome,  struct hubConnectStatus *hub)
+// make a trackDb entry for a quickLift chain
+{
+struct trackDb *tdb;
+
+AllocVar(tdb);
+
+char buffer[4096];
+safef(buffer, sizeof buffer, "hub_%d_quickLiftChain", hub->id);
+tdb->table = tdb->track = cloneString(buffer);
+safef(buffer, sizeof buffer, chainTdbString, hubGenome->quickLiftDb, hubGenome->quickLiftDb, hubGenome->quickLiftDb, hubGenome->quickLiftChain);
+tdb->settings = cloneString(buffer);
+tdb->settingsHash = trackDbSettingsFromString(tdb, buffer);
+trackDbFieldsFromSettings(tdb);
+tdb->visibility = tvDense;
+
+return tdb;
+}
+
+static struct trackDb *fixForQuickLift(struct trackDb *tdbList, struct trackHubGenome *hubGenome, struct hubConnectStatus *hub)
+// assign a quickLift chain to the tdbList and make a trackDb entry for the chain. 
+{
+assignQuickLift(tdbList, hubGenome->quickLiftChain);
+
+struct trackDb *quickLiftTdb = makeQuickLiftChainTdb(hubGenome, hub);
+quickLiftTdb->grp = tdbList->grp;
+slAddHead(&tdbList, quickLiftTdb);
+
+return tdbList;
+}
+
 struct trackDb *hubConnectAddHubForTrackAndFindTdb( char *database, 
     char *trackName, struct trackDb **pTdbList, struct hash *trackHash)
 /* Go find hub for trackName (which will begin with hub_), and load the tracks
  * for it, appending to end of list and adding to trackHash.  Return the
  * trackDb associated with trackName. This will also fill in the html fields,
  * but just for that track and it's parents. */ 
 {
 unsigned hubId = hubIdFromTrackName(trackName);
 struct hubConnectStatus *hub = hubFromId(hubId);
 struct trackHubGenome *hubGenome = trackHubFindGenome(hub->trackHub, database);
 if (hubGenome == NULL)
     errAbort("Cannot find genome %s in hub %s", database, hub->hubUrl);
 boolean foundFirstGenome = FALSE;
 struct trackDb *tdbList = trackHubTracksForGenome(hub->trackHub, hubGenome, NULL, &foundFirstGenome);
 tdbList = trackDbLinkUpGenerations(tdbList);
 tdbList = trackDbPolishAfterLinkup(tdbList, database);
 //this next line causes warns to print outside of warn box on hgTrackUi
 //trackDbPrioritizeContainerItems(tdbList);
 if (hubGenome->quickLiftChain)
-    assignQuickLift(tdbList, hubGenome->quickLiftChain);
+    tdbList = fixForQuickLift(tdbList, hubGenome, hub);
 trackHubPolishTrackNames(hub->trackHub, tdbList);
 char *fixTrackName = cloneString(trackName);
 trackHubFixName(fixTrackName);
 rAddTrackListToHash(trackHash, tdbList, NULL, FALSE);
 if (pTdbList != NULL)
     *pTdbList = slCat(*pTdbList, tdbList);
 struct trackDb *tdb = hashFindVal(trackHash, fixTrackName);
 if (tdb == NULL) 
     // superTracks aren't in the hash... look in tdbList
     tdb = findSuperTrack(tdbList, fixTrackName);
 
 if (tdb == NULL) 
     errAbort("Can't find track %s in %s", fixTrackName, hub->trackHub->url);
 
 /* Add html for track and parents. */
@@ -858,49 +898,52 @@
     if (hubGenome != NULL)
 	{
         boolean doCache = trackDbCacheOn();
 
         if (doCache)
             {
             // we have to open the trackDb file to get the udc cache to check for an update
             struct udcFile *checkCache = udcFileMayOpen(hubGenome->trackDbFile, NULL);
             if (checkCache != NULL)
                 {
                 time_t time = udcUpdateTime(checkCache);
                 udcFileClose(&checkCache);
 
                 struct trackDb *cacheTdb = trackDbHubCache(hubGenome->trackDbFile, time);
 
+                if (cacheTdb && hubGenome->quickLiftChain)
+                    cacheTdb = fixForQuickLift(cacheTdb, hubGenome, hub);
+
                 if (cacheTdb != NULL)
                     return cacheTdb;
                 }
 
             memCheckPoint(); // we want to know how much memory is used to build the tdbList
             }
 
         struct dyString *incFiles = dyStringNew(4096);
         tdbList = trackHubTracksForGenome(trackHub, hubGenome, incFiles, foundFirstGenome);
         tdbList = trackDbLinkUpGenerations(tdbList);
         tdbList = trackDbPolishAfterLinkup(tdbList, database);
         trackDbPrioritizeContainerItems(tdbList);
         trackHubPolishTrackNames(trackHub, tdbList);
 
         if (doCache)
             trackDbHubCloneTdbListToSharedMem(hubGenome->trackDbFile, tdbList, memCheckPoint(), incFiles->string);
 
-        if (hubGenome->quickLiftChain)
-            assignQuickLift(tdbList, hubGenome->quickLiftChain);
+        if (tdbList && hubGenome->quickLiftChain)
+            tdbList = fixForQuickLift(tdbList, hubGenome, hub);
 	}
     }
 return tdbList;
 }
 
 static struct grp *grpFromHub(struct hubConnectStatus *hub)
 /* Make up a grp structur from hub */
 {
 struct grp *grp;
 AllocVar(grp);
 char name[16];
 safef(name, sizeof(name), "hub_%d", hub->id);
 grp->name = cloneString(name);
 grp->label = cloneString(hub->shortLabel);
 return grp;