fd6b31a3f5776f7f3fa7ddc617a559de6ab3ff5c chmalee Fri May 2 16:01:20 2025 -0700 Add bigGenePred to 'zoomToExon' and 'zoomToCodon' feature, refs #33963 diff --git src/hg/hgApi/hgApi.c src/hg/hgApi/hgApi.c index 59d489437a9..b2e74711e2a 100644 --- src/hg/hgApi/hgApi.c +++ src/hg/hgApi/hgApi.c @@ -27,45 +27,48 @@ codonToPos: returns genomic position for given exon; parameters: exon, table and name (which is gene name). */ #include "common.h" #include "hdb.h" #include "mdb.h" #include "cheapcgi.h" #include "htmshell.h" #include "hPrint.h" #include "dystring.h" #include "hui.h" #include "search.h" #include "cv.h" #include "api.h" +#include "chromAlias.h" +#include "bigBed.h" +#include "trackHub.h" int main(int argc, char *argv[]) { long enteredMainTime = clock1000(); struct dyString *output = dyStringNew(10000); setUdcCacheDir(); cgiSpoof(&argc, argv); pushWarnHandler(htmlVaBadRequestAbort); pushAbortHandler(htmlVaBadRequestAbort); char *database = cgiString("db"); char *cmd = cgiString("cmd"); char *jsonp = cgiOptionalString("jsonp"); -if (!hDbExists(database)) +if (!trackHubDatabase(database) && !hDbExists(database)) errAbort("Invalid database '%s'", database); if (!strcmp(cmd, "defaultPos")) { dyStringPrintf(output, "{\"pos\": \"%s\"}", hDefaultPos(database)); } else if (!strcmp(cmd, "metaDb")) { // Return list of values for given metaDb var // e.g. http://genome.ucsc.edu/hgApi?db=hg18&cmd=metaDb&var=cell struct sqlConnection *conn = hAllocConn(database); boolean metaDbExists = sqlTableExists(conn, "metaDb"); if (metaDbExists) { @@ -180,48 +183,67 @@ } else dyStringPrintf(output,"Track %s not found",trackName); } else dyStringAppend(output,"No track variable found"); } else if (sameString(cmd, "codonToPos") || sameString(cmd, "exonToPos")) { char query[256]; struct sqlResult *sr; char **row; struct genePred *gp; char *name = cgiString("name"); char *table = cgiString("table"); + char *chrom = cgiString("chrom"); int num = cgiInt("num"); - struct sqlConnection *conn = hAllocConn(database); - sqlSafef(query, sizeof(query), "select name, chrom, strand, txStart, txEnd, cdsStart, cdsEnd, exonCount, exonStarts, exonEnds from %s where name = '%s'", table, name); - sr = sqlGetResult(conn, query); - if ((row = sqlNextRow(sr)) != NULL) + struct sqlConnection *conn; + if (!trackHubDatabase(database)) + conn = hAllocConn(database); + struct trackDb *tdb = tdbForTrack(database, table, NULL); + if (sameString(tdb->type, "genePred")) { + sqlSafef(query, sizeof(query), "select name, chrom, strand, txStart, txEnd, cdsStart, cdsEnd, exonCount, exonStarts, exonEnds from %s where name = '%s' and chrom='%s'", table, name, chrom); + sr = sqlGetResult(conn, query); + row = sqlNextRow(sr); gp = genePredLoad(row); - boolean found; - int start, end; + sqlFreeResult(&sr); + } + else if (sameString(tdb->type, "bigGenePred") || + startsWith("bigGenePred", tdb->type)) // makes knownGene work + { + // TODO: what bigBed types can we even support? bigBed12 at a minimum for the blocks? + // bigPsl should work maybe? + // for now just support genePred and bigGenePred + char *fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table); + struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases); + int fieldIx; + struct bptFile *bpt = bigBedOpenExtraIndex(bbi, "name", &fieldIx); + struct lm *lm = lmInit(0); + struct bigBedInterval *bbList = bigBedNameQuery(bbi, bpt, fieldIx, name, lm); + if (bbList) + gp = (struct genePred *)genePredFromBigGenePred(chrom, bbList); + } + if (!gp) + dyStringPrintf(output, "{\"error\": \"Couldn't find item: %s\"}", name); + boolean found; int start, end; if (sameString(cmd, "codonToPos")) found = codonToPos(gp, num, &start, &end); else found = exonToPos(gp, num, &start, &end); if (found) dyStringPrintf(output, "{\"pos\": \"%s:%d-%d\"}", gp->chrom, start + 1, end); else dyStringPrintf(output, "{\"error\": \"%d is an invalid %s for this gene\"}", num, sameString(cmd, "codonToPos") ? "codon" : "exon"); - } - else - dyStringPrintf(output, "{\"error\": \"Couldn't find item: %s\"}", name); - sqlFreeResult(&sr); hFreeConn(&conn); } else { warn("unknown cmd: %s",cmd); errAbort("Unsupported 'cmd' parameter"); } apiOut(dyStringContents(output), jsonp); cgiExitTime("hgApi", enteredMainTime); return 0; }