536e32480cf89093ba8b82ff4e73b0a9ca6ac389
chmalee
  Fri Oct 28 13:29:33 2022 -0700
Fix multiTerm searches and plain chromosome searches, refs #29693

diff --git src/hg/cgilib/cartJson.c src/hg/cgilib/cartJson.c
index 89785df..748a49f 100644
--- src/hg/cgilib/cartJson.c
+++ src/hg/cgilib/cartJson.c
@@ -130,116 +130,116 @@
                 {
                 stripString(pos->description, "\n");
                 jsonWriteString(jw, "description", stripAnchor(pos->description));
                 }
             jsonWriteObjectEnd(jw); // end one match
             }
         jsonWriteListEnd(jw); // end matches
         if (table->searchTime >= 0)
             jsonWriteNumber(jw, "searchTime", table->searchTime);
         jsonWriteObjectEnd(jw); // end one table
         }
     }
     jsonWriteListEnd(jw); // end positionMatches
 }
 
-static struct hgPositions *genomePosCJ(struct jsonWrite *jw,
+struct hgPositions *genomePosCJ(struct jsonWrite *jw,
 				       char *db, char *spec, char **retChromName,
-				       int *retWinStart, int *retWinEnd, struct cart *cart)
+				       int *retWinStart, int *retWinEnd, struct cart *cart, struct searchCategory *categories, boolean categorySearch)
 /* Search for positions in genome that match user query.
  * Return an hgp unless there is a problem.  hgp->singlePos will be set if a single
  * position matched.
  * Otherwise display list of positions, put # of positions in retWinStart,
  * and return NULL. */
 {
 char *hgAppName = "cartJson";
 struct hgPositions *hgp = NULL;
 char *chrom = NULL;
 int start = BIGNUM;
 int end = 0;
 boolean measureTiming = cartUsualBoolean(cart, "measureTiming", FALSE);
 
 char *terms[16];
 int termCount = chopByChar(cloneString(spec), ';', terms, ArraySize(terms));
 boolean multiTerm = (termCount > 1);
 
 int i = 0;
 for (i = 0;  i < termCount;  i++)
     {
     trimSpaces(terms[i]);
     if (isEmpty(terms[i]))
     continue;
-    hgp = hgPositionsFind(db, terms[i], "", hgAppName, cart, multiTerm, measureTiming, NULL);
+    hgp = hgPositionsFind(db, terms[i], "", hgAppName, cart, multiTerm, measureTiming, categories);
     if (hgp == NULL || hgp->posCount == 0)
         {
         jsonWriteStringf(jw, "error",
                  "Sorry, couldn't locate %s in %s %s", htmlEncode(terms[i]),
                              trackHubSkipHubName(hOrganism(db)), hFreezeDate(db));
         if (multiTerm)
             jsonWriteStringf(jw, "error",
                      "%s not uniquely determined -- can't do multi-position search.",
                      terms[i]);
         *retWinStart = 0;
         return NULL;
         }
     if (hgp->singlePos != NULL)
         {
-	if (chrom != NULL && !sameString(chrom, hgp->singlePos->chrom))
+        if (!categorySearch && chrom != NULL && !sameString(chrom, hgp->singlePos->chrom))
             {
             jsonWriteStringf(jw, "error",
                      "Sites occur on different chromosomes: %s, %s.",
                      chrom, hgp->singlePos->chrom);
             return NULL;
             }
         chrom = hgp->singlePos->chrom;
         if (hgp->singlePos->chromStart < start)
             start = hgp->singlePos->chromStart;
         if (hgp->singlePos->chromEnd > end)
             end = hgp->singlePos->chromEnd;
         }
     else
         {
         hgPositionsJson(jw, db, hgp, cart);
-	if (multiTerm && hgp->posCount != 1)
+        if (multiTerm && !categorySearch && hgp->posCount != 1)
             {
             jsonWriteStringf(jw, "error",
                      "%s not uniquely determined (%d locations) -- "
                      "can't do multi-position search.",
                      terms[i], hgp->posCount);
             return NULL;
             }
         break;
         }
     }
 if (hgp != NULL)
     {
     *retChromName = chrom;
     *retWinStart  = start;
     *retWinEnd    = end;
     }
 return hgp;
 }
 
 static void changePosition(struct cartJson *cj, char *newPosition)
 /* Update position in cart, after performing lookup if necessary.
  * Usually we don't report what we just changed, but since we might modify it,
  * print out the final value. */
 {
 char *db = cartString(cj->cart, "db");
 char *chrom = NULL;
 int start=0, end=0;
-struct hgPositions *hgp = genomePosCJ(cj->jw, db, newPosition, &chrom, &start, &end, cj->cart);
+struct hgPositions *hgp = genomePosCJ(cj->jw, db, newPosition, &chrom, &start, &end, cj->cart, NULL, TRUE);
 // If it resolved to a single position, update the cart; otherwise the app can
 // present the error (or list of matches) to the user.
 if (hgp && hgp->singlePos)
     {
     char newPosBuf[128];
     safef(newPosBuf, sizeof(newPosBuf), "%s:%d-%d", chrom, start+1, end);
     cartSetString(cj->cart, "position", newPosBuf);
     jsonWriteString(cj->jw, "position", newPosBuf);
     }
 else
     // Search failed; restore position from cart
     jsonWriteString(cj->jw, "position", cartUsualString(cj->cart, "position", hDefaultPos(db)));
 }
 
 static void changePositionHandler(struct cartJson *cj, struct hash *paramHash)