e4406bcd83a67929f2c980c338eba9071818d461
angie
  Wed Sep 26 10:54:01 2018 -0700
Add chromAlias to multi-region alt/fix autocomplete, so we can match RefSeq accessions and Assembly names.  refs #18854

diff --git src/hg/hgSuggest/hgSuggest.c src/hg/hgSuggest/hgSuggest.c
index 5ac118b..ff81841 100644
--- src/hg/hgSuggest/hgSuggest.c
+++ src/hg/hgSuggest/hgSuggest.c
@@ -125,51 +125,97 @@
 {
 struct slName *match;
 for (match = matches; match != NULL; match = match->next)
     {
     if (strchr(match->name, '_'))
         {
         jsonWriteObjectStart(jw, NULL);
         jsonWriteString(jw, "value", match->name);
         if (isNotEmpty(category))
             jsonWriteString(jw, "category", category);
         jsonWriteObjectEnd(jw);
         }
     }
 }
 
+struct slPair *queryChromAlias(struct sqlConnection *conn, char *term)
+/* Search chromAlias for prefix matches for term. */
+{
+struct slPair *matches = NULL;
+if (sqlTableExists(conn, "chromAlias"))
+    {
+    char query[1024];
+    sqlSafef(query, sizeof query, "select chrom, alias from chromAlias where alias like '%s%%' "
+             "order by chrom", term);
+    matches = sqlQuickPairList(conn, query);
+    }
+return matches;
+}
+
+void writeValLabelMatches(struct jsonWrite *jw, struct slPair *matches, char *category)
+/* Append JSON objects containing alt/fix seqs with extra label info & optional category. */
+{
+struct slPair *match;
+for (match = matches; match != NULL; match = match->next)
+    {
+    char *seqName = match->name;
+    if (strchr(seqName, '_') && !endsWith(seqName, "_random") && !startsWith("chrUn", seqName))
+        {
+        jsonWriteObjectStart(jw, NULL);
+        jsonWriteString(jw, "value", seqName);
+        char *extraInfo = match->val;
+        if (isNotEmpty(extraInfo))
+            {
+            int len = strlen(seqName) + strlen(extraInfo) + 32;
+            char label[len];
+            safef(label, sizeof label, "%s (%s)", seqName, extraInfo);
+            jsonWriteString(jw, "label", label);
+            }
+        if (isNotEmpty(category))
+            jsonWriteString(jw, "category", category);
+        jsonWriteObjectEnd(jw);
+        }
+    }
+}
+
 void suggestAltOrPatch(char *database, char *term)
 /* Print out a Javascript list of objects describing alternate haplotype or fix patch sequences
  * from database that match term. */
 {
 struct jsonWrite *jw = jsonWriteNew();
 jsonWriteListStart(jw, NULL);
 struct sqlConnection *conn = hAllocConn(database);
 // First, search for prefix matches
 struct slName *fixMatches = queryQNames(conn, "fixSeqLiftOverPsl", term, TRUE);
 struct slName *altMatches = queryQNames(conn, "altSeqLiftOverPsl", term, TRUE);
 // Add category labels only if we get both types of matches.
 writeAltFixMatches(jw, fixMatches, altMatches ? "Fix Patches" : "");
 writeAltFixMatches(jw, altMatches, fixMatches ? "Alt Patches" : "");
 // If there are no prefix matches, look for partial matches
 if (fixMatches == NULL && altMatches == NULL)
     {
     fixMatches = queryQNames(conn, "fixSeqLiftOverPsl", term, FALSE);
     altMatches = queryQNames(conn, "altSeqLiftOverPsl", term, FALSE);
     writeAltFixMatches(jw, fixMatches, altMatches ? "Fix Patches" : "");
     writeAltFixMatches(jw, altMatches, fixMatches ? "Alt Patches" : "");
     }
+// If there are still no matches, try chromAlias.
+if (fixMatches == NULL && altMatches == NULL)
+    {
+    struct slPair *aliasMatches = queryChromAlias(conn, term);
+    writeValLabelMatches(jw, aliasMatches, "");
+    }
 hFreeConn(&conn);
 jsonWriteListEnd(jw);
 puts(jw->dy->string);
 jsonWriteFree(&jw);
 }
 
 char *checkParams(char *database, char *prefix, char *type)
 /* If we don't have valid CGI parameters, quit with a Bad Request HTTP response. */
 {
 pushWarnHandler(htmlVaBadRequestAbort);
 pushAbortHandler(htmlVaBadRequestAbort);
 if(prefix == NULL || database == NULL)
     errAbort("%s", "Missing prefix and/or db CGI parameter");
 if (! hDbIsActive(database))
     errAbort("'%s' is not a valid, active database", htmlEncode(database));