cd3cb167196e74d31050cd822634a4529a1ebf01
hiram
  Thu Sep 17 18:09:51 2020 -0700
show chrom alias names on sequence display page refs #24396

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 2f23fa9..afe705d 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -60,30 +60,31 @@
 #include "search.h"
 #include "errCatch.h"
 #include "iupac.h"
 #include "botDelay.h"
 #include "chromInfo.h"
 #include "extTools.h"
 #include "basicBed.h"
 #include "customFactory.h"
 #include "genbank.h"
 #include "bigWarn.h"
 #include "wigCommon.h"
 #include "knetUdc.h"
 #include "hex.h"
 #include <openssl/sha.h>
 #include "customComposite.h"
+#include "chromAlias.h"
 
 //#include "bed3Sources.h"
 
 /* Other than submit and Submit all these vars should start with hgt.
  * to avoid weeding things out of other program's namespaces.
  * Because the browser is a central program, most of its cart
  * variables are not hgt. qualified.  It's a good idea if other
  * program's unique variables be qualified with a prefix though. */
 char *excludeVars[] = { "submit", "Submit", "dirty", "hgt.reset",
             "hgt.in1", "hgt.in2", "hgt.in3", "hgt.inBase",
             "hgt.out1", "hgt.out2", "hgt.out3", "hgt.out4",
             "hgt.left1", "hgt.left2", "hgt.left3",
             "hgt.right1", "hgt.right2", "hgt.right3",
             "hgt.dinkLL", "hgt.dinkLR", "hgt.dinkRL", "hgt.dinkRR",
             "hgt.tui", "hgt.hideAll", "hgt.visAllFromCt",
@@ -9915,57 +9916,94 @@
 }
 
 void chromInfoTotalRow(int count, long long total)
 /* Make table row with total number of sequences and size from chromInfo. */
 {
 cgiSimpleTableRowStart();
 cgiSimpleTableFieldStart();
 printf("Total: %d", count);
 cgiTableFieldEnd();
 cgiSimpleTableFieldStart();
 printLongWithCommas(stdout, total);
 cgiTableFieldEnd();
 cgiTableRowEnd();
 }
 
+static char *chrAliases(struct hash *aliasHash, char *sequenceName)
+/* lookup the sequenceName in the aliasHash and return csv string
+ * of alias names
+ */
+{
+if (NULL == aliasHash)
+    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);
+        }
+    }
+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);
     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);
+	else
+            htmlPrintf("&nbsp;");
+        cgiTableFieldEnd();
+        }
     cgiTableRowEnd();
     total += size;
     }
 chromInfoTotalRow(slCount(chromList), total);
 slFreeList(&chromList);
 }
 
 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 */
@@ -10045,65 +10083,80 @@
     cgiTableFieldEnd();
     cgiTableRowEnd();
     }
 }
 
 void chromInfoRowsNonChrom(int limit)
 /* Make table rows of non-chromosomal chromInfo name & size, sorted by size. */
 {
 if (trackHubDatabase(database))
     {
     chromInfoRowsNonChromTrackHub(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)
     {
     sr = sqlGetResult(conn, NOSQLINJ "select chrom,size from chromInfo order by size desc");
     }
 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]);
     cgiTableFieldEnd();
     cgiTableFieldStartAlignRight();
     printLongWithCommas(stdout, size);
     puts("&nbsp;&nbsp;");
     cgiTableFieldEnd();
+    if (hasAlias)
+        {
+        cgiSimpleTableFieldStart();
+        if (aliasNames)
+            htmlPrintf("%s", aliasNames);
+        else
+            htmlPrintf("&nbsp;");
+        cgiTableFieldEnd();
+        }
     cgiTableRowEnd();
     total += size;
     }
 if (!truncating)
     {
     chromInfoTotalRow(seqCount, total);
     }
 else
     {
     safef(msg1, sizeof(msg1), "Limit reached");
     safef(msg2, sizeof(msg2), "%d rows displayed", limit);
     cgiSimpleTableRowStart();
     cgiSimpleTableFieldStart();
     puts(msg1);
     cgiTableFieldEnd();
@@ -10182,30 +10235,36 @@
 puts("Enter a position, or click on a sequence name to view the entire "
      "sequence in the genome browser.<P>");
 puts("position ");
 hTextVar("position", addCommasToPos(database, position), 30);
 cgiMakeButton("Submit", "submit");
 puts("<P>");
 
 hTableStart();
 cgiSimpleTableRowStart();
 cgiSimpleTableFieldStart();
 puts("Sequence name &nbsp;");
 cgiTableFieldEnd();
 cgiSimpleTableFieldStart();
 puts("Length (bp) including gaps &nbsp;");
 cgiTableFieldEnd();
+if (hTableExists(database, "chromAlias"))
+    {
+    cgiSimpleTableFieldStart();
+    puts("alias sequence names &nbsp;");
+    cgiTableFieldEnd();
+    }
 cgiTableRowEnd();
 
 if (sameString(database,"hg38"))
     chromInfoRowsChromExt("withAltRandom");
 else if ((startsWith("chr", defaultChrom) || startsWith("Group", defaultChrom)) &&
     hChromCount(database) < 100)
     chromInfoRowsChrom();
 else
     chromInfoRowsNonChrom(1000);
 chromSizesDownloadRow();
 
 hTableEnd();
 cgiDown(0.9);
 
 hgPositionsHelpHtml(organism, database);