26c2f650359cc1c74fb31d96109bc0f8dedbc3d7 angie Thu May 30 10:32:19 2019 -0700 Adding BAM and VCF item counts to hubApi's list/tracks function. Note: older index files may not contain counts. refs #18869, #23521 diff --git src/hg/hubApi/list.c src/hg/hubApi/list.c index e41e290..37e2bce 100644 --- src/hg/hubApi/list.c +++ src/hg/hubApi/list.c @@ -1,18 +1,20 @@ /* manage endpoint /list/ functions */ #include "dataApi.h" +#include "bamFile.h" +#include "htslib/tbx.h" static void hubPublicJsonData(struct jsonWrite *jw, struct hubPublic *el, int columnCount, char **columnNames) /* Print array data for one row from hubPublic table, order here * must be same as was stated in the columnName header element * This code should be in hg/lib/hubPublic.c (which does not exist) */ { int i = 0; jsonWriteObjectStart(jw, NULL); jsonWriteString(jw, columnNames[i++], el->hubUrl); jsonWriteString(jw, columnNames[i++], el->shortLabel); jsonWriteString(jw, columnNames[i++], el->longLabel); jsonWriteString(jw, columnNames[i++], el->registrationTime); jsonWriteNumber(jw, columnNames[i++], (long long)el->dbCount); @@ -321,116 +323,126 @@ jsonWriteString(jw, "track", table); jsonWriteNumber(jw, "dataTimeStamp", (long long)dataTimeStamp); freeMem(dataTime); jsonWriteNumber(jw, "chromCount", (long long)slCount(ciList)); jsonWriteObjectStart(jw, "chromosomes"); for ( ; el != NULL; el = el->next ) { jsonWriteNumber(jw, el->chrom, (long long)el->size); } jsonWriteObjectEnd(jw); /* chromosomes */ apiFinishOutput(0, NULL, jw); } hFreeConn(&conn); } -static long long bbiItemCount(char *bigDataUrl, char *type) +static long long bbiItemCount(char *bigDataUrl, char *type, char *indexFileOrUrl) /* check the bigDataUrl to see what the itemCount is there */ { long long itemCount = 0; struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { if (allowedBigBedType(type)) { struct bbiFile *bbi = NULL; bbi = bigBedFileOpen(bigDataUrl); itemCount = bigBedItemCount(bbi); bbiFileClose(&bbi); } else if (startsWithWord("bigWig", type)) { struct bbiFile *bwf = bigWigFileOpen(bigDataUrl); struct bbiSummaryElement sum = bbiTotalSummary(bwf); itemCount = sum.validCount; bbiFileClose(&bwf); } - // NOTE: htslib does not appear to have a function to extract a count from BAI or TBI (tabix) - // indexes. One could probably be added by adding code similar to samtools' idxstats subcommand, - // But in the meantime, this is not supported for types vcfTabix and bam. + else if (sameString("bam", type)) + { + itemCount = bamFileItemCount(bigDataUrl, indexFileOrUrl); + } + else if (sameString("vcfTabix", type)) + { + itemCount = vcfTabixItemCount(bigDataUrl, indexFileOrUrl); + } } errCatchEnd(errCatch); +if (isNotEmpty(errCatch->message->string)) + fprintf(stderr, "%s", errCatch->message->string); errCatchFree(&errCatch); return itemCount; } static long long bbiTableItemCount(struct sqlConnection *conn, char *type, char *tableName) /* Given a tableName that has a fileName column pointing to big*, bam or vcfTabix files, return the * total itemCount from all rows (BAM and VCF tables may have one row per chrom). */ { long long itemCount = 0; char query[2048]; sqlSafef(query, sizeof query, "select fileName from %s", tableName); struct sqlResult *sr = sqlGetResult(conn, query); char **row; while ((row = sqlNextRow(sr)) != NULL) { - itemCount += bbiItemCount(row[0], type); + itemCount += bbiItemCount(hReplaceGbdb(row[0]), type, NULL); } sqlFreeResult(&sr); return itemCount; } static long long dataItemCount(char *db, struct trackDb *tdb) /* determine how many items are in this data set */ { boolean isContainer = tdbIsComposite(tdb) || tdbIsCompositeView(tdb); if (trackDbSetting(tdb, "container")) isContainer = TRUE; long long itemCount = 0; if (isContainer) /* containers have no data items */ return itemCount; if (sameWord("downloadsOnly", tdb->type)) return itemCount; -char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); +char *bigDataUrl = hReplaceGbdb(trackDbSetting(tdb, "bigDataUrl")); if (isNotEmpty(bigDataUrl)) - itemCount = bbiItemCount(bigDataUrl, tdb->type); + { + char *indexFileOrUrl = hReplaceGbdb(trackDbSetting(tdb, "bigDataIndex")); + itemCount = bbiItemCount(bigDataUrl, tdb->type, indexFileOrUrl); + } else { /* prepare for getting table row count, find table name */ /* the trackDb might have a specific table defined */ char *tableName = trackDbSetting(tdb, "table"); if (isEmpty(tableName)) tableName = trackDbSetting(tdb, "track"); if (isNotEmpty(tableName)) { struct sqlConnection *conn = hAllocConnMaybe(db); if (conn) { if ((startsWith("big", tdb->type) || sameString("vcfTabix", tdb->type) || sameString("bam", tdb->type)) && sqlColumnExists(conn, tableName, "fileName")) { itemCount = bbiTableItemCount(conn, tdb->type, tableName); } else { /* punting on split tables, return zero */ struct hTableInfo *hti = hFindTableInfoWithConn(conn, NULL, tableName); - if (hti && hti->isSplit) + if (!hti || hti->isSplit) { itemCount = 0; } else { char query[2048]; sqlSafef(query, sizeof(query), "select count(*) from %s", tableName); itemCount = sqlQuickNum(conn, query); } } hFreeConn(&conn); } } } return itemCount;