b622d147b7dbac52dbf3ba26928cd18e02d42bd8
braney
  Sat Feb 26 12:34:37 2022 -0800
add support for using a bigBed as the chromAlias file

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index f2f15d3..c4ea42a 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -4658,31 +4658,31 @@
 /* Support setting to suppress display of empty subtracks. 
  * If multiBed is available, return hash with subtrack names as keys
  */
 
 char *multiBedFile = NULL;
 char *subtrackIdFile = NULL;
 if (!compositeHideEmptySubtracks(cart, track->tdb, &multiBedFile, &subtrackIdFile))
     return NULL;
 if (!multiBedFile)
     return NULL;
 
 // load multiBed items in window
 // TODO: filters here ?
 // TODO:  protect against temporary network error ? */
 struct lm *lm = lmInit(0);
-struct bbiFile *bbi =  bigBedFileOpenAlias(multiBedFile, chromAliasChromToAliasHash(database));
+struct bbiFile *bbi =  bigBedFileOpenAlias(multiBedFile, chromAliasFindAliases);
 struct bigBedInterval *bb, *bbList =  bigBedIntervalQuery(bbi, chromName, winStart, winEnd, 0, lm);
 char *row[bbi->fieldCount];
 char startBuf[16], endBuf[16];
 struct hash *nonEmptySubtracksHash = hashNew(0);
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     bigBedIntervalToRow(bb, chromName, startBuf, endBuf, row, ArraySize(row));
     // TODO: do this in bed3Sources.c
     char *idList = row[4];
     struct slName *ids = slNameListFromComma(idList);
     struct slName *id = NULL;
     for (id = ids; id != NULL; id = id->next)
         hashStore(nonEmptySubtracksHash, id->name);
     // TODO: free some stuff ?
     }
@@ -10104,75 +10104,66 @@
 printf("Total: %d", count);
 cgiTableFieldEnd();
 cgiTableFieldStartAlignRight();
 printLongWithCommas(stdout, total);
 puts("  ");
 cgiTableFieldEnd();
 if (hasAlias)
     {
     cgiSimpleTableFieldStart();
     puts("&nbsp");
     cgiTableFieldEnd();
     }
 cgiTableRowEnd();
 }
 
-static char *chrAliases(struct hash *aliasHash, char *sequenceName)
+static char *chrAliases(struct slName *names, char *sequenceName)
 /* lookup the sequenceName in the aliasHash and return csv string
  * of alias names
  */
 {
-if (NULL == aliasHash)
+if (NULL == names)
     return NULL;
 struct dyString *returned = dyStringNew(512);
-struct hashEl *hel = hashLookup(aliasHash, sequenceName);
-if (hel)
-    {
-    dyStringPrintf(returned, "%s", ((struct chromAlias *)hel->val)->alias);
-    hel = hashLookupNext(hel);
-    while (hel != NULL)
-        {
-        dyStringPrintf(returned, ", %s",((struct chromAlias *)hel->val)->alias);
-        hel = hashLookupNext(hel);
-        }
-    }
+dyStringPrintf(returned, "%s", names->name);
+for(names = names->next; names; names = names->next)
+    dyStringPrintf(returned, ", %s",names->name);
 return dyStringCannibalize(&returned);
 }
 
 void chromInfoRowsChromExt(char *sortType)
 /* Make table rows of chromosomal chromInfo name & size, sorted by name. */
 {
 struct slName *chromList = hAllChromNames(database);
 struct slName *chromPtr = NULL;
 long long total = 0;
 boolean hasAlias = hTableExists(database, "chromAlias");
-struct hash *aliasHash = chromAliasMakeReverseLookupTable(database);
 /* key is database sequence name, value is an alias name, can be multiple
  *   entries for the same sequence name.  NULL if no chromAlias available
  */
 
 if (sameString(sortType,"default"))
     slSort(&chromList, chrSlNameCmp);
 else if (sameString(sortType,"withAltRandom"))
     slSort(&chromList, chrSlNameCmpWithAltRandom);
 else
     errAbort("unknown sort type in chromInfoRowsChromExt: %s", sortType);
 
 for (chromPtr = chromList;  chromPtr != NULL;  chromPtr = chromPtr->next)
     {
     unsigned size = hChromSize(database, chromPtr->name);
-    char *aliasNames = chrAliases(aliasHash, chromPtr->name);
+    char *aliasNames = chrAliases(chromAliasFindAliases(chromPtr->name), chromPtr->name);
     cgiSimpleTableRowStart();
     cgiSimpleTableFieldStart();
     htmlPrintf("<A HREF=\"%s|none|?%s|url|=%s|url|&position=%s|url|\">%s</A>",
            hgTracksName(), cartSessionVarName(), cartSessionId(cart),
            chromPtr->name, chromPtr->name);
     cgiTableFieldEnd();
     cgiTableFieldStartAlignRight();
     printLongWithCommas(stdout, size);
     puts("&nbsp;&nbsp;");
     cgiTableFieldEnd();
     if (hasAlias)
 	{
 	cgiSimpleTableFieldStart();
 	if (aliasNames)
             htmlPrintf("%s", aliasNames);
@@ -10190,54 +10181,50 @@
 void chromInfoRowsChrom()
 /* Make table rows of chromosomal chromInfo name & size, sorted by name. */
 {
 chromInfoRowsChromExt("default");
 }
 
 static int  chromInfoCmpSize(const void *va, const void *vb)
 /* Compare to sort based on chrom size */
 {
 const struct chromInfo *a = *((struct chromInfo **)va);
 const struct chromInfo *b = *((struct chromInfo **)vb);
 
 return b->size - a->size;
 }
 
-void chromInfoRowsNonChromTrackHub(int limit)
+void chromInfoRowsNonChromTrackHub(boolean hasAlias, int limit)
 /* Make table rows of non-chromosomal chromInfo name & size */
 /* leaks chromInfo list */
 {
 struct chromInfo *chromInfo = trackHubAllChromInfo(database);
 slSort(&chromInfo, chromInfoCmpSize);
 int seqCount = slCount(chromInfo);
-struct hash *aliasHash =  chromAliasMakeReverseLookupTable(database);
-boolean hasAlias = FALSE;
-if (aliasHash)
-    hasAlias = TRUE;
 long long total = 0;
 char msg1[512], msg2[512];
 boolean truncating;
 int lineCount = 0;
 
 truncating = (limit > 0) && (seqCount > limit);
 
 for( ;lineCount < seqCount && (chromInfo != NULL); ++lineCount, chromInfo = chromInfo->next)
     {
     unsigned size = chromInfo->size;
     if (lineCount < limit)
 	{
-	char *aliasNames = chrAliases(aliasHash, chromInfo->chrom);
+	char *aliasNames = chrAliases(chromAliasFindAliases(chromInfo->chrom), chromInfo->chrom);
 	cgiSimpleTableRowStart();
 	cgiSimpleTableFieldStart();
 	htmlPrintf("<A HREF=\"%s|none|?%s|url|=%s|url|&position=%s|url|\">%s</A>",
 	    hgTracksName(), cartSessionVarName(), cartSessionId(cart),
 	    chromInfo->chrom,chromInfo->chrom);
 	cgiTableFieldEnd();
 	cgiTableFieldStartAlignRight();
 	printLongWithCommas(stdout, size);
 	puts("&nbsp;&nbsp;");
 	cgiTableFieldEnd();
 	if (hasAlias)
 	    {
 	    cgiSimpleTableFieldStart();
 	    if (aliasNames)
 		htmlPrintf("%s", aliasNames);
@@ -10276,42 +10263,40 @@
     cgiSimpleTableFieldStart();
     puts(msg2);
     cgiTableFieldEnd();
     cgiTableRowEnd();
     cgiSimpleTableRowStart();
     cgiSimpleTableFieldStart();
     printLongWithCommas(stdout, scafCount);
     cgiTableFieldEnd();
     cgiSimpleTableFieldStart();
     printLongWithCommas(stdout, total);
     cgiTableFieldEnd();
     cgiTableRowEnd();
     }
 }
 
-void chromInfoRowsNonChrom(int limit)
+void chromInfoRowsNonChrom(boolean hasAlias, int limit)
 /* Make table rows of non-chromosomal chromInfo name & size, sorted by size. */
 {
 if (trackHubDatabase(database))
     {
-    chromInfoRowsNonChromTrackHub(limit);
+    chromInfoRowsNonChromTrackHub(hasAlias, limit);
     return;
     }
 
 struct sqlConnection *conn = hAllocConn(database);
-boolean hasAlias = hTableExists(database, "chromAlias");
-struct hash *aliasHash = chromAliasMakeReverseLookupTable(database);
 /* key is database sequence name, value is an alias name, can be multiple
  *   entries for the same sequence name.  NULL if no chromAlias available
  */
 struct sqlResult *sr = NULL;
 char **row = NULL;
 long long total = 0;
 char query[512];
 char msg1[512], msg2[512];
 int seqCount = 0;
 boolean truncating;
 
 seqCount = sqlQuickNum(conn, NOSQLINJ "select count(*) from chromInfo");
 truncating = (limit > 0) && (seqCount > limit);
 
 if (!truncating)
@@ -10321,31 +10306,31 @@
 else
     {
 
     sqlSafef(query, sizeof(query), "select chrom,size from chromInfo order by size desc limit %d", limit);
     sr = sqlGetResult(conn, query);
     }
 
 while ((row = sqlNextRow(sr)) != NULL)
     {
     unsigned size = sqlUnsigned(row[1]);
     cgiSimpleTableRowStart();
     cgiSimpleTableFieldStart();
     htmlPrintf("<A HREF=\"%s|none|?%s|url|=%s|url|&position=%s|url|\">%s</A>",
            hgTracksName(), cartSessionVarName(), cartSessionId(cart),
            row[0], row[0]);
-    char *aliasNames = chrAliases(aliasHash, row[0]);
+    char *aliasNames = chrAliases(chromAliasFindAliases(row[0]), row[0]);
     cgiTableFieldEnd();
     cgiTableFieldStartAlignRight();
     printLongWithCommas(stdout, size);
     puts("&nbsp;&nbsp;");
     cgiTableFieldEnd();
     if (hasAlias)
         {
         cgiSimpleTableFieldStart();
         if (aliasNames)
             htmlPrintf("%s", aliasNames);
         else
             htmlPrintf("&nbsp;");
         cgiTableFieldEnd();
         }
     cgiTableRowEnd();
@@ -10504,36 +10489,36 @@
     cgiSimpleTableFieldStart();
     puts("alias sequence names &nbsp;");
     cgiTableFieldEnd();
     }
 else if (hasAlias)
     {
     cgiSimpleTableFieldStart();
     puts("alias sequence names &nbsp;");
     cgiTableFieldEnd();
     }
 cgiTableRowEnd();
 
 if (sameString(database,"hg38"))
     chromInfoRowsChromExt("withAltRandom");
 else if (trackHubDatabase(database))
-    chromInfoRowsNonChrom(1000);
+    chromInfoRowsNonChrom(hasAlias, 1000);
 else if ((startsWith("chr", defaultChrom) || startsWith("Group", defaultChrom)) &&
     hChromCount(database) < 100)
     chromInfoRowsChrom();
 else
-    chromInfoRowsNonChrom(1000);
+    chromInfoRowsNonChrom(hasAlias, 1000);
 chromSizesDownloadRow(hasAlias, aliasFile, chromSizesFile);
 
 hTableEnd();
 cgiDown(0.9);
 
 hgPositionsHelpHtml(organism, database);
 puts("</FORM>");
 dyStringFree(&title);
 webEndSectionTables();
 }	/*	void chromInfoPage()	*/
 
 void resetVars()
 /* Reset vars except for position and database. */
 {
 static char *except[] = {"db", "position", NULL};
@@ -10745,31 +10730,35 @@
 char *debugTmp = NULL;
 /* Uncomment this to see parameters for debugging. */
 /* struct dyString *state = NULL; */
 /* Initialize layout and database. */
 if (measureTiming)
     measureTime("Get cart of %d for user:%s session:%s", theCart->hash->elCount,
 	    theCart->userId, theCart->sessionId);
 /* #if 1 this to see parameters for debugging. */
 /* Be careful though, it breaks if custom track
  * is more than 4k */
 #if 0
 printf("State: %s\n", cgiUrlString()->string);
 #endif
 
 getDbAndGenome(cart, &database, &organism, oldVars);
+if (measureTiming)
+    measureTime("before chromAliasSetup");
 chromAliasSetup(database);
+if (measureTiming)
+    measureTime("after chromAliasSetup");
 
 genomeIsRna = !isHubTrack(database) && hgPdbOk(database);
 
 initGenbankTableNames(database);
 
 protDbName = hPdbFromGdb(database);
 debugTmp = cartUsualString(cart, "hgDebug", "off");
 if(sameString(debugTmp, "on"))
     hgDebug = TRUE;
 else
     hgDebug = FALSE;
 
 int timeout = cartUsualInt(cart, "udcTimeout", 300);
 if (udcCacheTimeout() < timeout)
     udcSetCacheTimeout(timeout);