f72d8b57a77755e64ef594ae2d4395a12c19712d
hiram
Tue Mar 19 21:46:37 2019 -0700
now showing a sample getData URL for supported tracks refs #18869
diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index f9a2b0c..a58944f 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -20,33 +20,87 @@
static struct cart *cart; /* CGI and other variables */
static struct hash *oldVars = NULL;
static struct hash *trackCounter = NULL;
static long totalTracks = 0;
static boolean measureTiming = FALSE; /* set by CGI parameters */
static boolean allTrackSettings = FALSE; /* checkbox setting */
static char **shortLabels = NULL; /* public hub short labels in array */
// struct hubPublic *publicHubList = NULL;
static int publicHubCount = 0;
static char *defaultHub = "Plants";
static char *defaultDb = "ce11";
static long enteredMainTime = 0; /* will become = clock1000() on entry */
/* to allow calculation of when to bail out, taking too long */
static long timeOutSeconds = 100;
static boolean timedOut = FALSE;
+static char *urlPrefix = ""; /* initalized to support self references */
+static struct slName *supportedTypes = NULL;
+ /* will be initialized to a known supported set */
+
+static void initSupportedTypes()
+/* initalize the list of supported track types,
+ */
+{
+struct slName *el = newSlName("bed");
+slAddHead(&supportedTypes, el);
+el = newSlName("wig");
+slAddHead(&supportedTypes, el);
+el = newSlName("broadPeak");
+slAddHead(&supportedTypes, el);
+el = newSlName("narrowPeak");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigBed");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigWig");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigNarrowPeak");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigGenePred");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigPsl");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigBarChart");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigInteract");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigMaf");
+slAddHead(&supportedTypes, el);
+el = newSlName("bigChain");
+slAddHead(&supportedTypes, el);
+slNameSort(&supportedTypes);
+}
+
+static boolean isSupportedType(char *type)
+/* is given type in the supportedTypes list ? */
+{
+boolean ret = FALSE;
+if (startsWith("wigMaf", type))
+ return ret;
+struct slName *el;
+for (el = supportedTypes; el; el = el->next)
+ {
+ if (startsWith(el->name, type))
+ {
+ ret = TRUE;
+ break;
+ }
+ }
+return ret;
+}
static int publicHubCmpCase(const void *va, const void *vb)
-/* Compare two slNames, ignore case. */
+/* Compare two shortLabels, ignore case. */
{
const struct hubPublic *a = *((struct hubPublic **)va);
const struct hubPublic *b = *((struct hubPublic **)vb);
return strcasecmp(a->shortLabel, b->shortLabel);
}
static void publicHubSortCase(struct hubPublic **pList)
/* Sort slName list, ignore case. */
{
slSort(pList, publicHubCmpCase);
}
static struct hubPublic *hubPublicLoad(char **row)
/* Load a hubPublic from row fetched with select * from hubPublic
* from database. Dispose of this with hubPublicFree(). */
@@ -152,46 +206,72 @@
hashIncInt(countTracks, "superTrack child");
hashIncInt(countTracks, stripType);
hashIncInt(countTracks, "track count");
}
else if (isEmpty(tdb->type))
hashIncInt(countTracks, "no type specified");
else
{
hashIncInt(countTracks, stripType);
hashIncInt(countTracks, "track count");
}
freeMem(stripType);
// showCounts(countTracks);
}
-static void showSubTracks(struct trackDb *tdb, struct hash *countTracks)
+static void sampleUrl(char *db, struct trackDb *tdb, char *chrom, long long chromSize)
+/* print out a sample getData URL */
+{
+long long start = chromSize / 4;
+long long end = start + 10000;
+if (end > chromSize)
+ end = chromSize;
+
+if (db)
+ {
+ if (tdb->parent)
+ hPrintf("
%s : %s subtrack of parent: %s (sample getData)\n", tdb->track, tdb->type, tdb->parent->track, urlPrefix, db, chrom, tdb->track, start, end );
+ else
+ hPrintf("%s : %s (sample getData)\n", tdb->track, tdb->type, urlPrefix, db, chrom, tdb->track, start, end );
+ }
+}
+
+static void showSubTracks(char *db, struct trackDb *tdb, struct hash *countTracks,
+ char *chromName, long long chromSize)
/* tdb has subtracks, show only subTracks, no details */
{
hPrintf(" \n");
if (tdb->subtracks)
{
struct trackDb *tdbEl = NULL;
for (tdbEl = tdb->subtracks; tdbEl; tdbEl = tdbEl->next)
{
if (tdbIsCompositeView(tdbEl))
hPrintf("- %s : %s : composite view of parent: %s
\n", tdbEl->track, tdbEl->type, tdbEl->parent->track);
else
+ {
+ if (isSupportedType(tdbEl->type))
+ {
+ sampleUrl(db, tdbEl, chromName, chromSize);
+// hPrintf("- %s : %s : subtrack of parent: %s (with sample)
\n", tdbEl->track, tdbEl->type, tdbEl->parent->track, getData);
+ }
+ else
hPrintf("- %s : %s : subtrack of parent: %s
\n", tdbEl->track, tdbEl->type, tdbEl->parent->track);
+ }
hashCountTrack(tdbEl, countTracks);
if (tdbEl->subtracks)
- showSubTracks(tdbEl, countTracks);
+ showSubTracks(db, tdbEl, countTracks, chromName, chromSize);
}
}
hPrintf("
\n");
}
static void trackSettings(struct trackDb *tdb, struct hash *countTracks)
/* process the settingsHash for a trackDb, recursive when subtracks */
{
hPrintf(" \n");
// if (tdb->children) haven't yet seen a track with children ?
// hPrintf(" - %s: has children
\n", tdb->track);
// else
// hPrintf(" - %s: NO children
\n", tdb->track);
struct hashEl *hel;
struct hashCookie hc = hashFirst(tdb->settingsHash);
@@ -302,32 +382,32 @@
retVal = 1;
}
}
errCatchEnd(errCatch);
if (errCatch->gotError)
{
retVal = 1;
dyStringPrintf(errors, "%s", errCatch->message->string);
}
errCatchFree(&errCatch);
return retVal;
} /* static int bbiBriefMeasure() */
-static void countOneTdb(struct trackDb *tdb, char *bigDataIndex,
- struct hash *countTracks)
+static void countOneTdb(char *db, struct trackDb *tdb, char *bigDataIndex,
+ struct hash *countTracks, char *chromName, long long chromSize)
{
char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl");
// char *compositeTrack = trackDbSetting(tdb, "compositeTrack");
boolean compositeContainer = tdbIsComposite(tdb);
boolean compositeView = tdbIsCompositeView(tdb);
// char *superTrack = trackDbSetting(tdb, "superTrack");
boolean superChild = tdbIsSuperTrackChild(tdb);
boolean depthSearch = cartUsualBoolean(cart, "depthSearch", FALSE);
hashCountTrack(tdb, countTracks);
if (depthSearch && bigDataUrl)
{
long chromCount = 0;
long itemCount = 0;
struct dyString *errors = newDyString(1024);
@@ -345,80 +425,89 @@
else
hPrintf(" - %s : %s : %ld chroms : %ld count
\n", tdb->track, tdb->type, chromCount, itemCount);
}
}
else
{
if (compositeContainer)
hPrintf(" - %s : %s : composite track container has %d subtracks
\n", tdb->track, tdb->type, slCount(tdb->subtracks));
else if (compositeView)
hPrintf(" - %s : %s : composite view of parent: %s
\n", tdb->track, tdb->type, tdb->parent->track);
else if (superChild)
hPrintf(" - %s : %s : superTrack child of parent: %s
\n", tdb->track, tdb->type, tdb->parent->track);
else if (! depthSearch && bigDataUrl)
hPrintf(" - %s : %s : %s
\n", tdb->track, tdb->type, bigDataUrl);
else
+ {
+ if (isSupportedType(tdb->type))
+ sampleUrl(db, tdb, chromName, chromSize);
+ else
hPrintf(" - %s : %s
\n", tdb->track, tdb->type);
}
+ }
if (allTrackSettings)
{
hPrintf(" \n");
trackSettings(tdb, countTracks); /* show all settings */
hPrintf("
\n");
}
else if (tdb->subtracks)
{
- showSubTracks(tdb, countTracks);
+ showSubTracks(db, tdb, countTracks, chromName, chromSize);
}
return;
-} /* static void countOneTdb(struct trackDb *tdb,
- * char *bigDataIndex, struct hash *countTracks)
+} /* static void countOneTdb(char *db, struct trackDb *tdb,
+ * char *bigDataIndex, struct hash *countTracks,
+ * char *chromName, long long chromSize)
*/
static void hubTrackList(struct trackDb *topTrackDb, struct trackHubGenome *genome)
/* process the track list in a hub to show all tracks */
{
hPrintf(" \n");
if (topTrackDb)
{
struct hash *countTracks = hashNew(0);
struct trackDb *tdb = NULL;
for ( tdb = topTrackDb; tdb; tdb = tdb->next )
{
char *bigDataIndex = NULL;
char *relIdxUrl = trackDbSetting(topTrackDb, "bigDataIndex");
if (relIdxUrl != NULL)
bigDataIndex = trackHubRelativeUrl(genome->trackDbFile, relIdxUrl);
- countOneTdb(tdb, bigDataIndex, countTracks);
+ countOneTdb(NULL, tdb, bigDataIndex, countTracks, NULL, 0);
if (timeOutReached())
break;
} /* for ( tdb = topTrackDb; tdb; tdb = tdb->next ) */
hPrintf(" - %d different track types
\n",countTracks->elCount - 1);
/* add this single genome count to the overall multi-genome counts */
if (countTracks->elCount)
{
hPrintf(" \n");
struct hashEl *hel, *helList = hashElListHash(countTracks);
slSort(&helList, hashElCmpIntValDesc);
for (hel = helList; hel; hel = hel->next)
{
if (sameOk("track count", hel->name))
continue;
int prevCount = ptToInt(hashFindVal(trackCounter, hel->name));
if (differentStringNullOk("track count", hel->name))
totalTracks += ptToInt(hel->val);
hashReplace(trackCounter, hel->name, intToPt(prevCount + ptToInt(hel->val)));
+ if (isSupportedType(hel->name))
+ hPrintf(" - %d - %s - supported
\n", ptToInt(hel->val), hel->name);
+ else
hPrintf(" - %d - %s
\n", ptToInt(hel->val), hel->name);
}
hPrintf("
\n");
}
}
else
hPrintf(" - no trackTopDb
\n");
hPrintf("
- \n");
} /* static struct trackDb *hubTrackList() */
static struct trackDb *assemblySettings(struct trackHubGenome *genome)
/* display all the assembly 'settingsHash' */
{
struct trackDb *tdb = obtainTdb(genome, NULL);
@@ -565,85 +654,84 @@
* parse that and return a function pointer and the parsed words
* Returns NULL if not recognized
*/
{
char *tmp = cloneString(pathInfo);
/* skip the first leading slash to simplify chopByChar parsing */
tmp += 1;
int wordCount = chopByChar(tmp, '/', words, MAX_PATH_INFO);
if (wordCount < 1)
return NULL;
struct hashEl *hel = hashLookup(apiFunctionHash, words[0]);
return hel;
}
-#ifdef NOT
-static void apiFunctionSwitch(struct hashEl *hel, char *words[MAX_PATH_INFO])
-/* given a pathInfo string: /command/subCommand/etc...
- * parse that and decide on which function to acll
+static long long largestChrom(char *db, char **nameReturn)
+/* return the length and get the chrom name for the largest chrom
+ * from chromInfo table. For use is sample getData URLs
*/
{
-hPrintDisable(); /* turn off all normal HTML output, doing JSON output */
-
-/* the leading slash has been removed from the pathInfo, therefore, the
- * chop will have the first word in words[0]
- */
-#ifdef NOT
-char *words[MAX_PATH_INFO];/*expect no more than MAX_PATH_INFO number of words*/
-int wordCount = chopByChar(pathInfo, '/', words, ArraySize(words));
-if (wordCount < 2)
- apiErrAbort("unknown endpoint command: '/%s'", pathInfo);
-
-struct hashEl *hel = hashLookup(apiFunctionHash, words[0]);
-if (hel == NULL)
- apiErrAbort("no such command: '%s' for endpoint '/%s'", words[0], pathInfo);
-#endif
-void (*apiFunction)(char **) = hel->val;
-// void (*apiFunction)(char **) = hashMustFindVal(apiFunctionHash, words[0]);
-
-(*apiFunction)(words);
-
-} /* static void apiFunctionSwitch(char *pathInfo) */
-#endif
+char query[1024];
+struct sqlConnection *conn = hAllocConn(db);
+// Build a query to select the hubUrl for the given shortLabel
+sqlSafef(query, sizeof(query), "select chrom,size from chromInfo order by size desc limit 1");
+struct sqlResult *sr = sqlGetResult(conn, query);
+char **row = sqlNextRow(sr);
+long long length = 0;
+if (row)
+ {
+ *nameReturn = cloneString(row[0]);
+ length = sqlLongLong(row[1]);
+ }
+sqlFreeResult(&sr);
+hFreeConn(&conn);
+return length;
+}
static void tracksForUcscDb(char *db)
/* scan the specified database for all tracks */
{
struct hash *countTracks = hashNew(0);
-hPrintf("
Tracks in UCSC genome: '%s'
\n", db);
+char *chromName = NULL;
+long long chromSize = largestChrom(db, &chromName);
+hPrintf("
Tracks in UCSC genome: '%s', longest chrom: %s:%lld
\n", db, chromName, chromSize);
struct trackDb *tdbList = obtainTdb(NULL, db);
struct trackDb *tdb;
hPrintf("
\n");
+hPrintf("- %s:%lld
\n", chromName, chromSize);
for (tdb = tdbList; tdb != NULL; tdb = tdb->next )
{
- countOneTdb(tdb, NULL, countTracks);
+ countOneTdb(db, tdb, NULL, countTracks, chromName, chromSize);
if (timeOutReached())
break;
}
int trackCount = ptToInt(hashFindVal(countTracks, "track count"));
/* elCount - 1 since the 'track count' element isn't a track */
hPrintf(" - %d total tracks counted, %d different track types
\n", trackCount, countTracks->elCount - 1);
if (countTracks->elCount)
{
hPrintf(" \n");
struct hashEl *hel, *helList = hashElListHash(countTracks);
slSort(&helList, hashElCmpIntValDesc);
for (hel = helList; hel; hel = hel->next)
{
if (sameOk("track count", hel->name))
continue;
+ if (isSupportedType(hel->name))
+ hPrintf(" - %d - %s - supported
\n", ptToInt(hel->val), hel->name);
+ else
hPrintf(" - %d - %s
\n", ptToInt(hel->val), hel->name);
}
hPrintf("
\n");
}
hPrintf("
\n");
hPrintf("\n");
} // static void tracksForUcscDb(char * db)
static void introductionText()
/* output explanation text */
{
char *scriptUri = getenv("SCRIPT_URI");
hPrintf("JSON data API interface to U.C. Santa Cruz genome browser data
\n");
hPrintf("Data access URL: %s
\n", scriptUri);
@@ -662,44 +750,56 @@
hPrintf(" - /getData/sequence - return sequence from specified hub or database genome
\n");
hPrintf("- /getData/track - return data from specified track in hub or database genome
\n");
hPrintf("
\n");
hPrintf("\n");
hPrintf("Parameters to endpoint functions:
\n");
hPrintf("\n");
hPrintf("- hubUrl=<url> - specify track hub or assembly hub URL
\n");
hPrintf("- genome=<name> - specify genome assemby in track or assembly hub
\n");
hPrintf("- db=<ucscDb> - specify database (aka genome assembly) in UCSC genome browser
\n");
hPrintf("- track=<trackName> - specify data track in hub or UCSC database genome assembly
\n");
hPrintf("- chrom=<chrN> - specify chromosome name for sequence or track data
\n");
hPrintf("- start=<123> - specify start coordinate (0 relative) for data from track or sequence retrieval
\n");
hPrintf("- end=<456> - specify end coordinate (1 relative) for data from track or sequence retrieval
\n");
hPrintf("- (see also: UCSC browser coordinate counting systems)
");
hPrintf("
\n");
+hPrintf("Supported track types, at this time, for getData functions:
\n");
+hPrintf("\n");
+static struct slName *el;
+for (el = supportedTypes; el; el = el->next)
+ {
+ hPrintf("- %s
\n", el->name);
+ }
+hPrintf("
\n");
}
-static void showExamples(char *url, struct trackHubGenome *hubGenome, char *ucscDb)
+static void initUrlPrefix()
+/* set up urlPrefix for self referenes */
{
-char *urlPrefix = "";
char *httpHost = getenv("HTTP_HOST");
-if (! startsWith("hgwdev-api", httpHost)) {
+if (! startsWith("hgwdev-api", httpHost))
+ {
if (startsWith("hgwdev",httpHost) || startsWith("genome-test", httpHost))
{
urlPrefix = "../cgi-bin/hubApi";
}
}
+}
+static void showExamples(char *url, struct trackHubGenome *hubGenome, char *ucscDb)
+{
hPrintf("Example URLs to return json data structures:
\n");
hPrintf("listing functions
\n");
hPrintf("\n");
hPrintf("- list public hubs %s/list/publicHubs
\n", urlPrefix, urlPrefix);
hPrintf("- list database genomes %s/list/ucscGenomes
\n", urlPrefix, urlPrefix);
hPrintf("- list genomes from specified hub %s/list/hubGenomes?hubUrl=%s
\n", urlPrefix, url, urlPrefix, url);
hPrintf("- list tracks from specified hub and genome %s/list/tracks?hubUrl=%s&genome=%s
\n", urlPrefix, url, hubGenome->name, urlPrefix, url, hubGenome->name);
hPrintf("- list tracks from specified UCSC database %s/list/tracks?db=%s
\n", urlPrefix, ucscDb, urlPrefix, ucscDb);
hPrintf("- list chromosomes from specified UCSC database %s/list/chromosomes?db=%s
\n", urlPrefix, ucscDb, urlPrefix, ucscDb);
hPrintf("- list chromosomes from specified track from UCSC databaset %s/list/chromosomes?db=%s&track=gap
\n", urlPrefix, ucscDb, urlPrefix, ucscDb);
hPrintf("
\n");
hPrintf("getData functions
\n");
hPrintf("\n");
@@ -736,30 +836,32 @@
}
static void doMiddle(struct cart *theCart)
/* Set up globals and make web page */
{
cart = theCart;
measureTiming = hPrintStatus() && isNotEmpty(cartOptionalString(cart, "measureTiming"));
measureTiming = TRUE;
char *database = NULL;
char *genome = NULL;
cgiVarSet("ignoreCookie", "1");
getDbAndGenome(cart, &database, &genome, oldVars);
initGenbankTableNames(database);
+initSupportedTypes();
+initUrlPrefix();
char *docRoot = cfgOptionDefault("browser.documentRoot", DOCUMENT_ROOT);
int timeout = cartUsualInt(cart, "udcTimeout", 300);
if (udcCacheTimeout() < timeout)
udcSetCacheTimeout(timeout);
knetUdcInstall();
char *pathInfo = getenv("PATH_INFO");
/* nothing on incoming path, then display the WEB page instead */
if (sameOk("/",pathInfo))
pathInfo = NULL;
boolean commandError = FALSE;
/*expect no more than MAX_PATH_INFO number of words*/