struct dataVector *bedGraphDataVector(char *table, struct sqlConnection *conn, struct region *region) /* Read in bedGraph as dataVector and return it. Filtering, subtrack merge * and intersection are handled. */ { struct dataVector *dv = NULL; if (anySubtrackMerge(database, table)) dv = mergedWigDataVector(table, conn, region); else { struct trackDb *tdb; if (isCustomTrack(table)) { struct customTrack *ct = ctLookupName(table); tdb = ct->tdb; conn = hAllocConn(CUSTOM_TRASH); } else { tdb = hTrackDbForTrack(database, table); } struct trackTable *tt1 = trackTableNew(tdb, table, conn); dv = dataVectorFetchOneRegion(tt1, region, conn); intersectDataVector(table, dv, region, conn); if (isCustomTrack(table)) hFreeConn(&conn); } return dv; }
struct dataVector *bigWigDataVector(char *table, struct sqlConnection *conn, struct region *region) /* Read in bigWig as dataVector and return it. Filtering, subtrack merge * and intersection are handled. */ { if (anySubtrackMerge(database, table)) return mergedWigDataVector(table, conn, region); else { struct dataVector *dv = dataVectorNew(region->chrom, region->end - region->start); bigWigFillDataVector(table, region, conn, dv); return dv; } }
struct dataVector *wiggleDataVector(struct trackDb *tdb, char *table, struct sqlConnection *conn, struct region *region) /* Read in wiggle as dataVector and return it. Filtering, subtrack merge * and intersection are handled. */ { struct dataVector *dv = NULL; if (anySubtrackMerge(database, table)) dv = mergedWigDataVector(table, conn, region); else { struct trackTable *tt1 = trackTableNew(tdb, table, conn); dv = dataVectorFetchOneRegion(tt1, region, conn); } return dv; }
int bigWigOutRegion(char *table, struct sqlConnection *conn, struct region *region, int maxOut, enum wigOutputType wigOutType) /* Write out bigWig for region, doing intersecting and filtering as need be. */ { boolean isMerged = anySubtrackMerge(table, database); int resultCount = 0; char *wigFileName = bigWigFileName(table, conn); if (wigFileName) { struct bbiFile *bwf = bigWigFileOpen(wigFileName); if (bwf) { /* Easy case, just dump out data. */ if (!anyFilter() && !anyIntersection() && !isMerged && wigOutType == wigOutData) resultCount = bigWigIntervalDump(bwf, region->chrom, region->start, region->end, maxOut, stdout); /* Pretty easy case, still do it ourselves. */ else if (!isMerged && wigOutType == wigOutData) { double ll, ul; enum wigCompare cmp; getWigFilter(database, curTable, &cmp, &ll, &ul); struct lm *lm = lmInit(0); struct bbiInterval *ivList, *iv; ivList = intersectedFilteredBbiIntervalsOnRegion(conn, bwf, region, cmp, ll, ul, lm); for (iv=ivList; iv != NULL && resultCount < maxOut; iv = iv->next, ++resultCount) { fprintf(stdout, "%s\t%d\t%d\t%g\n", region->chrom, iv->start, iv->end, iv->val); } lmCleanup(&lm); } /* Harder cases - resort to making a data vector and letting that machinery handle it. */ else { struct dataVector *dv = bigWigDataVector(table, conn, region); resultCount = wigPrintDataVectorOut(dv, wigOutType, maxOut, NULL); dataVectorFree(&dv); } } bbiFileClose(&bwf); } freeMem(wigFileName); return resultCount; }
void doOutSelectedFields(char *table, struct sqlConnection *conn) /* Put up select fields (for tab-separated output) page. */ { if (anySubtrackMerge(database, curTable)) errAbort("Can't do selected fields output when subtrack merge is on. " "Please go back and select another output type, or clear the subtrack merge."); else if (anyIntersection()) errAbort("Can't do selected fields output when intersection is on. " "Please go back and select another output type, or clear the intersection."); else { char *fsTable = cartOptionalString(cart, hgtaFieldSelectTable); char *dbTable = NULL; table = connectingTableForTrack(table); dbTable = getDbTable(database, table); /* Remove cart state if table has been changed: */ if (fsTable && ! sameString(fsTable, dbTable)) { cartRemovePrefix(cart, hgtaFieldSelectPrefix); cartRemove(cart, hgtaFieldSelectTable); } doBigSelectPage(database, table); } }
boolean doGetBedOrCt(struct sqlConnection *conn, boolean doCt, boolean doCtFile, boolean redirectToGb) /* Actually output bed or custom track. Return TRUE unless no results. */ { char *db = cloneString(database); char *table = curTable; struct hTableInfo *hti = getHti(db, table, conn); struct featureBits *fbList = NULL, *fbPtr; struct customTrack *ctNew = NULL; boolean doCtHdr = (cartUsualBoolean(cart, hgtaPrintCustomTrackHeaders, FALSE) || doCt || doCtFile); char *ctWigOutType = cartCgiUsualString(cart, hgtaCtWigOutType, outWigData); char *fbQual = fbOptionsToQualifier(); char fbTQ[128]; int fields = hTableInfoBedFieldCount(hti); boolean gotResults = FALSE; struct region *region, *regionList = getRegions(); boolean isBedGr = isBedGraph(curTable); boolean isBgWg = isBigWigTable(curTable); boolean needSubtrackMerge = anySubtrackMerge(database, curTable); boolean doDataPoints = FALSE; boolean isWig = isWiggle(database, table); struct wigAsciiData *wigDataList = NULL; struct dataVector *dataVectorList = NULL; boolean doRgb = bedItemRgb(hTrackDbForTrack(db, curTable)); if (!cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE) && !doCt) { textOpen(); } if (cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE)) fputs("#", stdout); if ((isWig || isBedGr || isBgWg) && sameString(outWigData, ctWigOutType)) doDataPoints = TRUE; for (region = regionList; region != NULL; region = region->next) { struct bed *bedList = NULL, *bed; struct lm *lm = lmInit(64*1024); struct dataVector *dv = NULL; if (isWig && doDataPoints) { if (needSubtrackMerge) { dv = wiggleDataVector(curTrack, curTable, conn, region); if (dv != NULL) slAddHead(&dataVectorList, dv); } else { int count = 0; struct wigAsciiData *wigData = NULL; struct wigAsciiData *asciiData; struct wigAsciiData *next; wigData = getWiggleAsData(conn, curTable, region); for (asciiData = wigData; asciiData; asciiData = next) { next = asciiData->next; if (asciiData->count) { slAddHead(&wigDataList, asciiData); ++count; } } slReverse(&wigDataList); } } else if (isBedGr && doDataPoints) { dv = bedGraphDataVector(curTable, conn, region); if (dv != NULL) slAddHead(&dataVectorList, dv); } else if (isBgWg && doDataPoints) { dv = bigWigDataVector(curTable, conn, region); if (dv != NULL) slAddHead(&dataVectorList, dv); } else if (isWig || isBgWg) { dv = wiggleDataVector(curTrack, curTable, conn, region); bedList = dataVectorToBedList(dv); dataVectorFree(&dv); } else if (isBedGr) { bedList = getBedGraphAsBed(conn, curTable, region); } else { bedList = cookedBedList(conn, curTable, region, lm, &fields); } /* this is a one-time only initial creation of the custom track * structure to receive the results. gotResults turns it off after * the first time. */ if (doCtHdr && !gotResults && ((bedList != NULL) || (wigDataList != NULL) || (dataVectorList != NULL))) { ctNew = beginCustomTrack(table, fields, doCt, (isWig || isBedGr || isBgWg), doDataPoints); } if (doDataPoints && (wigDataList || dataVectorList)) gotResults = TRUE; else { if ((fbQual == NULL) || (fbQual[0] == 0)) { for (bed = bedList; bed != NULL; bed = bed->next) { if (bed->name != NULL) { subChar(bed->name, ' ', '_'); } if (doCt) { struct bed *dupe = cloneBed(bed); /* Out of local memory. */ slAddHead(&ctNew->bedList, dupe); } else { if (doRgb) bedTabOutNitemRgb(bed, fields, stdout); else bedTabOutN(bed, fields, stdout); } gotResults = TRUE; } } else { safef(fbTQ, sizeof(fbTQ), "%s:%s", hti->rootName, fbQual); fbList = fbFromBed(db, fbTQ, hti, bedList, 0, 0, FALSE, FALSE); if (fields >= 6) fields = 6; else if (fields >= 4) fields = 4; else fields = 3; if (doCt && ctNew) { ctNew->fieldCount = fields; safef(ctNew->tdb->type, strlen(ctNew->tdb->type)+1, "bed %d", fields); } for (fbPtr=fbList; fbPtr != NULL; fbPtr=fbPtr->next) { if (fbPtr->name != NULL) { char *ptr = strchr(fbPtr->name, ' '); if (ptr != NULL) *ptr = 0; } if (doCt) { struct bed *fbBed = fbToBedOne(fbPtr); slAddHead(&ctNew->bedList, fbBed ); } else { if (fields >= 6) hPrintf("%s\t%d\t%d\t%s\t%d\t%c\n", fbPtr->chrom, fbPtr->start, fbPtr->end, fbPtr->name, 0, fbPtr->strand); else if (fields >= 4) hPrintf("%s\t%d\t%d\t%s\n", fbPtr->chrom, fbPtr->start, fbPtr->end, fbPtr->name); else hPrintf("%s\t%d\t%d\n", fbPtr->chrom, fbPtr->start, fbPtr->end); } gotResults = TRUE; } featureBitsFreeList(&fbList); } } bedList = NULL; lmCleanup(&lm); } if (!gotResults) { hPrintf(NO_RESULTS); } else if (doCt) { int wigDataSize = 0; /* Load existing custom tracks and add this new one: */ struct customTrack *ctList = getCustomTracks(); removeNamedCustom(&ctList, ctNew->tdb->table); if (doDataPoints) { if (needSubtrackMerge || isBedGr || isBgWg) { slReverse(&dataVectorList); wigDataSize = dataVectorWriteWigAscii(dataVectorList, ctNew->wigAscii, 0, NULL); // TODO: see if can make prettier wig output here that // doesn't necessarily have one value per base } else { struct wiggleDataStream *wds = NULL; /* create an otherwise empty wds so we can print out the list */ wds = wiggleDataStreamNew(); wds->ascii = wigDataList; wigDataSize = wds->asciiOut(wds, db, ctNew->wigAscii, TRUE, FALSE); #if defined(DEBUG) /* dbg */ /* allow file readability for debug */ chmod(ctNew->wigAscii, 0666); #endif wiggleDataStreamFree(&wds); } } else slReverse(&ctNew->bedList); slAddHead(&ctList, ctNew); /* Save the custom tracks out to file (overwrite the old file): */ customTracksSaveCart(db, cart, ctList); /* Put up redirect-to-browser page. */ if (redirectToGb) { char browserUrl[256]; char headerText[512]; int redirDelay = 3; safef(browserUrl, sizeof(browserUrl), "%s?%s&db=%s", hgTracksName(), cartSidUrlString(cart), database); safef(headerText, sizeof(headerText), "<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"%d;URL=%s\">", redirDelay, browserUrl); webStartHeader(cart, database, headerText, "Table Browser: %s %s: %s", hOrganism(database), freezeName, "get custom track"); if (doDataPoints) { hPrintf("There are %d data points in custom track. ", wigDataSize); } else { hPrintf("There are %d items in custom track. ", slCount(ctNew->bedList)); } hPrintf("You will be automatically redirected to the genome browser in\n" "%d seconds, or you can \n" "<A HREF=\"%s\">click here to continue</A>.\n", redirDelay, browserUrl); } } else if (doDataPoints) { if (needSubtrackMerge || isBedGr || isBgWg) { slReverse(&dataVectorList); dataVectorWriteWigAscii(dataVectorList, "stdout", 0, NULL); } else { /* create an otherwise empty wds so we can print out the list */ struct wiggleDataStream *wds = NULL; wds = wiggleDataStreamNew(); wds->ascii = wigDataList; wds->asciiOut(wds, db, "stdout", TRUE, FALSE); wiggleDataStreamFree(&wds); } } return gotResults; }
void doBedOrCtOptions(char *table, struct sqlConnection *conn, boolean doCt) /* Put up form to get options on BED or custom track output. */ /* (Taken from hgText.c/doBedCtOptions) */ { char *table2 = NULL; /* For now... */ struct hTableInfo *hti = getHti(database, table, conn); char buf[256]; char *setting; htmlOpen("Output %s as %s", table, (doCt ? "Custom Track" : "BED")); if (doGalaxy()) startGalaxyForm(); else if (doGreat()) { verifyGreatAssemblies(); startGreatForm(); } else hPrintf("<FORM ACTION=\"%s\" METHOD=GET>\n", getScriptName()); cartSaveSession(cart); if (!doGreat()) { hPrintf("%s\n", "<TABLE><TR><TD>"); if (doCt) { hPrintf("%s\n", "</TD><TD>" "<A HREF=\"../goldenPath/help/customTrack.html\" TARGET=_blank>" "Custom track</A> header: </B>"); } else { cgiMakeCheckBox(hgtaPrintCustomTrackHeaders, cartCgiUsualBoolean(cart, hgtaPrintCustomTrackHeaders, FALSE)); hPrintf("%s\n", "</TD><TD> <B> Include " "<A HREF=\"../goldenPath/help/customTrack.html\" TARGET=_blank>" "custom track</A> header: </B>"); } hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>name="); safef(buf, sizeof(buf), "tb_%s", hti->rootName); setting = cgiUsualString(hgtaCtName, buf); cgiMakeTextVar(hgtaCtName, setting, 16); hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>description="); safef(buf, sizeof(buf), "table browser query on %s%s%s", table, (table2 ? ", " : ""), (table2 ? table2 : "")); setting = cgiUsualString(hgtaCtDesc, buf); cgiMakeTextVar(hgtaCtDesc, setting, 50); hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>visibility="); if (isWiggle(database, table) || isBigWigTable(table)) { setting = cartCgiUsualString(cart, hgtaCtVis, ctVisWigMenu[2]); cgiMakeDropList(hgtaCtVis, ctVisWigMenu, ctVisWigMenuSize, setting); } else { setting = cartCgiUsualString(cart, hgtaCtVis, ctVisMenu[3]); cgiMakeDropList(hgtaCtVis, ctVisMenu, ctVisMenuSize, setting); } hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>url="); setting = cartCgiUsualString(cart, hgtaCtUrl, ""); cgiMakeTextVar(hgtaCtUrl, setting, 50); hPrintf("%s\n", "</TD></TR><TR><TD></TD><TD>"); hPrintf("%s\n", "</TD></TR></TABLE>"); } if (isWiggle(database, table) || isBedGraph(table) || isBigWigTable(table) ) { char *setting = NULL; hPrintf("<P> <B> Select type of data output: </B> <BR>\n"); setting = cartCgiUsualString(cart, hgtaCtWigOutType, outWigData); cgiMakeRadioButton(hgtaCtWigOutType, outWigBed, sameString(setting, outWigBed)); hPrintf("BED format (no data value information, only position)<BR>\n"); cgiMakeRadioButton(hgtaCtWigOutType, outWigData, sameString(setting, outWigData)); hPrintf("DATA VALUE format (position and real valued data)</P>\n"); } else { cgiDown(0.9); hPrintf("<B> Create one BED record per: </B>\n"); if ((anyIntersection() && intersectionIsBpWise()) || (anySubtrackMerge(database, table) && subtrackMergeIsBpWise())) { /* The original table may have blocks/CDS, described in hti, but * that info will be lost after base pair-wise operations. So make * a temporary copy of hti with its flags tweaked: */ struct hTableInfo simplifiedHti; memcpy(&simplifiedHti, hti, sizeof(simplifiedHti)); simplifiedHti.hasBlocks = FALSE; simplifiedHti.hasCDS = FALSE; fbOptionsHtiCart(&simplifiedHti, cart); } else fbOptionsHtiCart(hti, cart); } if (doCt) { if (doGalaxy()) { /* send the action parameter with the form as well */ cgiMakeHiddenVar(hgtaDoGetCustomTrackFile, "get custom track in file"); printGalaxySubmitButtons(); } else { cgiMakeButton(hgtaDoGetCustomTrackTb, "get custom track in table browser"); hPrintf(" "); cgiMakeButton(hgtaDoGetCustomTrackFile, "get custom track in file"); hPrintf("<BR>\n"); cgiMakeButton(hgtaDoGetCustomTrackGb, "get custom track in genome browser"); } } else { if (doGalaxy()) { cgiMakeHiddenVar(hgtaDoGetBed, "get BED"); printGalaxySubmitButtons(); } else if (doGreat()) { cgiMakeHiddenVar(hgtaDoGetBed, "get BED"); printGreatSubmitButtons(); } else cgiMakeButton(hgtaDoGetBed, "get BED"); } if (!doGalaxy() && !doGreat()) { hPrintf(" "); cgiMakeButton(hgtaDoMainPage, "cancel"); hPrintf("</FORM>\n"); } cgiDown(0.9); htmlClose(); }
void doSummaryStatsWiggle(struct sqlConnection *conn) /* Put up page showing summary stats for wiggle track. */ { // grab the right trackDb for the current table. The curTrack variable // has the composite trackDb in it struct trackDb *track = hTrackDbForTrack(database, curTable); char *table = curTable; struct region *region, *regionList = getRegions(); char *regionName = getRegionName(); long long regionSize = 0; long long gapTotal = 0; long startTime = 0, wigFetchTime = 0; char splitTableOrFileName[HDB_MAX_TABLE_STRING]; struct customTrack *ct = NULL; boolean isCustom = FALSE; struct wiggleDataStream *wds = NULL; unsigned long long valuesMatched = 0; int regionCount = 0; int regionsDone = 0; unsigned span = 0; char *dataConstraint; double ll = 0.0; double ul = 0.0; boolean hasConstraint = FALSE; char *table2 = NULL; boolean fullGenome = FALSE; boolean statsHeaderDone = FALSE; boolean gotSome = FALSE; char *shortLabel = table; long long statsItemCount = 0; /* global accumulators for overall */ int statsSpan = 0; /* stats summary on a multiple region */ double statsSumData = 0.0; /* output */ double statsSumSquares = 0.0; /* " " */ double lowerLimit = INFINITY; /* " " */ double upperLimit = -1.0 * INFINITY; /* " " */ startTime = clock1000(); if (track != NULL) shortLabel = track->shortLabel; /* Count the regions, when only one, we can do more stats */ for (region = regionList; region != NULL; region = region->next) ++regionCount; htmlOpen("%s (%s) Wiggle Summary Statistics", shortLabel, table); if (anySubtrackMerge(database, curTable)) hPrintf("<P><EM><B>Note:</B> subtrack merge is currently ignored on this " "page (not implemented yet). Statistics shown here are only for " "the primary table %s (%s).</EM>", shortLabel, table); fullGenome = fullGenomeRegion(); WIG_INIT; /* ct, isCustom, hasConstraint, wds and table2 are set here */ for (region = regionList; region != NULL; region = region->next) { struct bed *intersectBedList = NULL; int operations; ++regionsDone; if (table2) intersectBedList = bedTable2(conn, region, table2); operations = wigFetchStats; #if defined(NOT) /* can't do the histogram now, that operation times out */ if (1 == regionCount) operations |= wigFetchAscii; #endif wds->setChromConstraint(wds, region->chrom); if (fullGenome) wds->setPositionConstraint(wds, 0, 0); else wds->setPositionConstraint(wds, region->start, region->end); if (hasConstraint) wds->setDataConstraint(wds, dataConstraint, ll, ul); /* depending on what is coming in on regionList, we may need to be * smart about how often we call getData for these custom tracks * since that is potentially a large file read each time. */ if (isCustom) { if (ct->dbTrack) { struct sqlConnection *trashConn = hAllocConn(CUSTOM_TRASH); struct trackDb *tdb = findTdbForTable(database, curTrack, table, ctLookupName); span = minSpan(trashConn, splitTableOrFileName, region->chrom, region->start, region->end, cart, tdb); wds->setSpanConstraint(wds, span); valuesMatched = getWigglePossibleIntersection(wds, region, CUSTOM_TRASH, table2, &intersectBedList, splitTableOrFileName, operations); hFreeConn(&trashConn); } else { valuesMatched = getWigglePossibleIntersection(wds, region, NULL, table2, &intersectBedList, splitTableOrFileName, operations); /* XXX We need to properly get the smallest span for custom tracks */ /* This is not necessarily the correct answer here */ if (wds->stats) span = wds->stats->span; else span = 1; } } else { if (hFindSplitTable(database, region->chrom, table, splitTableOrFileName, sizeof splitTableOrFileName, NULL)) { span = minSpan(conn, splitTableOrFileName, region->chrom, region->start, region->end, cart, track); wds->setSpanConstraint(wds, span); valuesMatched = getWigglePossibleIntersection(wds, region, database, table2, &intersectBedList, splitTableOrFileName, operations); if (intersectBedList) span = 1; } } /* when doing multiple regions, we need to print out each result as * it happens to keep the connection open to the browser and * prevent any timeout since this could take a while. * (worst case test is quality track on panTro1) */ if (wds->stats) statsItemCount += wds->stats->count; if (wds->stats && (regionCount > 1) && (valuesMatched > 0)) { double sumData = wds->stats->mean * wds->stats->count; double sumSquares; if (wds->stats->count > 1) sumSquares = (wds->stats->variance * (wds->stats->count - 1)) + ((sumData * sumData)/wds->stats->count); else sumSquares = sumData * sumData; /* global accumulators for overall summary */ statsSpan = wds->stats->span; statsSumData += sumData; statsSumSquares += sumSquares; if (wds->stats->lowerLimit < lowerLimit) lowerLimit = wds->stats->lowerLimit; if ((wds->stats->lowerLimit + wds->stats->dataRange) > upperLimit) upperLimit = wds->stats->lowerLimit + wds->stats->dataRange; if (statsHeaderDone) wds->statsOut(wds, database, "stdout", TRUE, TRUE, FALSE, TRUE); else { wds->statsOut(wds, database, "stdout", TRUE, TRUE, TRUE, TRUE); statsHeaderDone = TRUE; } wds->freeStats(wds); gotSome = TRUE; } if ((regionCount > MAX_REGION_DISPLAY) && (regionsDone >= MAX_REGION_DISPLAY)) { hPrintf("<TR><TH ALIGN=CENTER COLSPAN=12> Can not display more " "than %d regions, <BR> would take too much time </TH></TR>\n", MAX_REGION_DISPLAY); break; /* exit this for loop */ } } /*for (region = regionList; region != NULL; region = region->next) */ if (hasConstraint) freeMem(dataConstraint); /* been cloned into wds */ if (1 == regionCount) { statsPreamble(wds, regionList->chrom, regionList->start, regionList->end, span, valuesMatched, table2); /* 3 X TRUE = sort results, html table output, with header, * the FALSE means close the table after printing, no more rows to * come. The case in the if() statement was already taken care of * in the statsPreamble() printout. No need to do that again. */ if ( ! ((valuesMatched == 0) && table2) ) wds->statsOut(wds, database, "stdout", TRUE, TRUE, TRUE, FALSE); regionSize = basesInRegion(regionList,0); gapTotal = gapsInRegion(conn, regionList,0); } else { /* this is a bit of a kludge here since these printouts are done in the * library source wigDataStream.c statsOut() function and * this is a clean up of that. That function should be * pulled out of there and made independent and more * versatile. */ long long realSize; double variance; double stddev; /* Too expensive to lookup the numbers for thousands of regions */ regionSize = basesInRegion(regionList,MAX_REGION_DISPLAY); gapTotal = gapsInRegion(conn, regionList,MAX_REGION_DISPLAY); realSize = regionSize - gapTotal; /* close the table which was left open in the loop above */ if (!gotSome) hPrintf("<TR><TH ALIGN=CENTER COLSPAN=12> No data found matching this request </TH></TR>\n"); hPrintf("<TR><TH ALIGN=LEFT> SUMMARY: </TH>\n"); hPrintf("\t<TD> </TD>\n"); /* chromStart */ hPrintf("\t<TD> </TD>\n"); /* chromEnd */ hPrintf("\t<TD ALIGN=RIGHT> "); printLongWithCommas(stdout, statsItemCount); hPrintf(" </TD>\n" ); hPrintf("\t<TD ALIGN=RIGHT> %d </TD>\n", statsSpan); hPrintf("\t<TD ALIGN=RIGHT> "); printLongWithCommas(stdout, statsItemCount*statsSpan); hPrintf(" (%.2f%%) </TD>\n", 100.0*(double)(statsItemCount*statsSpan)/(double)realSize); hPrintf("\t<TD ALIGN=RIGHT> %g </TD>\n", lowerLimit); hPrintf("\t<TD ALIGN=RIGHT> %g </TD>\n", upperLimit); hPrintf("\t<TD ALIGN=RIGHT> %g </TD>\n", upperLimit - lowerLimit); if (statsItemCount > 0) hPrintf("\t<TD ALIGN=RIGHT> %g </TD>\n", statsSumData/statsItemCount); else hPrintf("\t<TD ALIGN=RIGHT> 0.0 </TD>\n"); stddev = 0.0; variance = 0.0; if (statsItemCount > 1) { variance = (statsSumSquares - ((statsSumData * statsSumData)/(double) statsItemCount)) / (double) (statsItemCount - 1); if (variance > 0.0) stddev = sqrt(variance); } hPrintf("\t<TD ALIGN=RIGHT> %g </TD>\n", variance); hPrintf("\t<TD ALIGN=RIGHT> %g </TD>\n", stddev); hPrintf("</TR>\n"); wigStatsTableHeading(stdout, TRUE); hPrintf("</TABLE></TD></TR></TABLE></P>\n"); } #if defined(NOT) /* can't do the histogram now, that operation times out */ /* Single region, we can do the histogram */ if ((valuesMatched > 1) && (1 == regionCount)) { float *valuesArray = NULL; size_t valueCount = 0; struct histoResult *histoGramResult; /* convert the ascii data listings to one giant float array */ valuesArray = wds->asciiToDataArray(wds, valuesMatched, &valueCount); /* histoGram() may return NULL if it doesn't work */ histoGramResult = histoGram(valuesArray, valueCount, NAN, (unsigned) 0, NAN, (float) wds->stats->lowerLimit, (float) (wds->stats->lowerLimit + wds->stats->dataRange), (struct histoResult *)NULL); printHistoGram(histoGramResult, TRUE); /* TRUE == html output */ freeHistoGram(&histoGramResult); wds->freeAscii(wds); wds->freeArray(wds); } #endif wds->freeStats(wds); wiggleDataStreamFree(&wds); wigFetchTime = clock1000() - startTime; webNewSection("Region and Timing Statistics"); hTableStart(); stringStatRow("region", regionName); numberStatRow("bases in region", regionSize); numberStatRow("bases in gaps", gapTotal); floatStatRow("load and calc time", 0.001*wigFetchTime); wigFilterStatRow(conn); stringStatRow("intersection", cartUsualString(cart, hgtaIntersectTable, "off")); hTableEnd(); htmlClose(); } /* void doSummaryStatsWiggle(struct sqlConnection *conn) */
static void doOutWig(struct trackDb *track, char *table, struct sqlConnection *conn, enum wigOutputType wigOutType) { struct region *regionList = getRegions(), *region; int maxOut = 0, outCount, curOut = 0; char *shortLabel = table, *longLabel = table; if (track == NULL) errAbort("Sorry, can't find necessary track information for %s. " "If you reached this page by selecting \"All tables\" as the " "group, please go back and select the same table via a regular " "track group if possible.", table); maxOut = bigFileMaxOutput(); if (cartUsualBoolean(cart, hgtaDoGreatOutput, FALSE)) fputs("#", stdout); else textOpen(); if (track != NULL) { if (!sameString(track->table, table) && track->subtracks != NULL) { struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(track->subtracks); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { struct trackDb *tdb = tdbRef->val; if (sameString(tdb->table, table)) { track = tdb; break; } } slFreeList(&tdbRefList); } shortLabel = track->shortLabel; longLabel = track->longLabel; } wigDataHeader(shortLabel, longLabel, NULL, wigOutType); for (region = regionList; region != NULL; region = region->next) { int curMaxOut = maxOut - curOut; if (anySubtrackMerge(database, table)) outCount = mergedWigOutRegion(table, conn, region, curMaxOut, wigOutType); else if (startsWithWord("bedGraph", track->type)) outCount = bedGraphOutRegion(table, conn, region, curMaxOut, wigOutType); else if (startsWithWord("mathWig", track->type)) outCount = mathWigOutRegion(track, table, conn, region, curMaxOut, wigOutType); else if (startsWithWord("bigWig", track->type)) outCount = bigWigOutRegion(table, conn, region, curMaxOut, wigOutType); else outCount = wigOutRegion(table, conn, region, curMaxOut, wigOutType, NULL, 0); curOut += outCount; if (curOut >= maxOut) break; } if (curOut >= maxOut) errAbort("Reached output limit of %d data values, please make region smaller,\n\tor set a higher output line limit with the filter settings.", curOut); }
struct bed *getRegionAsMergedBed( char *db, char *table, /* Database and table. */ struct region *region, /* Region to get data for. */ char *filter, /* Filter to add to SQL where clause if any. */ struct hash *idHash, /* Restrict to id's in this hash if non-NULL. */ struct lm *lm, /* Where to allocate memory. */ int *retFieldCount) /* Number of fields. */ /* Return a bed list of all items in the given range in subtrack-merged table. * Cleanup result via lmCleanup(&lm) rather than bedFreeList. */ { if (! anySubtrackMerge(db, table)) return getRegionAsBed(db, table, region, filter, idHash, lm, retFieldCount); else { struct hTableInfo *hti = getHtiOnDb(database, table); int chromSize = hChromSize(database, region->chrom); Bits *bits1 = NULL; Bits *bits2 = NULL; struct bed *bedMerged = NULL; struct trackDb *subtrack = NULL; char *primaryType = findTypeForTable(database,curTrack,table, ctLookupName); char *op = cartString(cart, hgtaSubtrackMergeOp); boolean isBpWise = (sameString(op, "and") || sameString(op, "or")); double moreThresh = cartDouble(cart, hgtaSubtrackMergeMoreThreshold); double lessThresh = cartDouble(cart, hgtaSubtrackMergeLessThreshold); boolean firstTime = TRUE; if (sameString(op, "cat")) { struct bed *bedList = getRegionAsBed(db, table, region, filter, idHash, lm, retFieldCount); struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(curTrack->subtracks); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { subtrack = tdbRef->val; if (! sameString(curTable, subtrack->table) && isSubtrackMerged(subtrack->table) && sameString(subtrack->type, primaryType)) { struct bed *bedList2 = getRegionAsBed(db, subtrack->table, region, NULL, idHash, lm, retFieldCount); bedList = slCat(bedList, bedList2); } } slFreeList(&tdbRefList); return bedList; } bits1 = bitAlloc(chromSize+8); bits2 = bitAlloc(chromSize+8); /* If doing a base-pair-wise operation, then start with the primary * subtrack's ranges in bits1, and AND/OR all the selected subtracks' * ranges into bits1. If doing a non-bp-wise intersection, then * start with all bits clear in bits1, and then OR selected subtracks' * ranges into bits1. */ if (isBpWise) { struct lm *lm2 = lmInit(64*1024); struct bed *bedList1 = getRegionAsBed(db, table, region, filter, idHash, lm2, retFieldCount); bedOrBits(bits1, chromSize, bedList1, hti->hasBlocks, 0); lmCleanup(&lm2); } struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(curTrack->subtracks); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { subtrack = tdbRef->val; if (! sameString(curTable, subtrack->table) && isSubtrackMerged(subtrack->table) && sameString(subtrack->type, primaryType)) { struct hTableInfo *hti2 = getHtiOnDb(database, subtrack->table); struct lm *lm2 = lmInit(64*1024); struct bed *bedList2 = getRegionAsBed(db, subtrack->table, region, NULL, idHash, lm2, NULL); if (firstTime) firstTime = FALSE; else bitClear(bits2, chromSize); bedOrBits(bits2, chromSize, bedList2, hti2->hasBlocks, 0); if (sameString(op, "and")) bitAnd(bits1, bits2, chromSize); else bitOr(bits1, bits2, chromSize); lmCleanup(&lm2); } } slFreeList(&tdbRefList); if (isBpWise) { bedMerged = bitsToBed4List(bits1, chromSize, region->chrom, 1, region->start, region->end, lm); if (retFieldCount != NULL) *retFieldCount = 4; } else { struct bed *bedList1 = getRegionAsBed(db, table, region, filter, idHash, lm, retFieldCount); bedMerged = filterBedByOverlap(bedList1, hti->hasBlocks, op, moreThresh, lessThresh, bits1, chromSize); } bitFree(&bits1); bitFree(&bits2); return bedMerged; } }
void showMainControlTable(struct sqlConnection *conn) /* Put up table with main controls for main page. */ { struct grp *selGroup; boolean isWig = FALSE, isPositional = FALSE, isMaf = FALSE, isBedGr = FALSE, isChromGraphCt = FALSE, isPal = FALSE, isArray = FALSE, isBam = FALSE, isVcf = FALSE, isHalSnake = FALSE, isLongTabix = FALSE; boolean gotClade = hGotClade(); struct hTableInfo *hti = NULL; hPrintf("<TABLE BORDER=0>\n"); /* Print clade, genome and assembly line. */ { if (gotClade) { hPrintf("<TR><TD><B>clade:</B>\n"); printCladeListHtml(hGenome(database), onChangeClade()); nbSpaces(3); hPrintf("<B>genome:</B>\n"); printGenomeListForCladeHtml(database, onChangeOrg()); } else { hPrintf("<TR><TD><B>genome:</B>\n"); printGenomeListHtml(database, onChangeOrg()); } nbSpaces(3); hPrintf("<B>assembly:</B>\n"); printAssemblyListHtml(database, onChangeDb()); hPrintf("</TD></TR>\n"); } /* Print group and track line. */ { hPrintf("<TR><TD>"); selGroup = showGroupField(hgtaGroup, onChangeGroupOrTrack(), conn, hAllowAllTables()); nbSpaces(3); curTrack = showTrackField(selGroup, hgtaTrack, onChangeGroupOrTrack(), FALSE); nbSpaces(3); boolean hasCustomTracks = FALSE; struct trackDb *t; for (t = fullTrackList; t != NULL; t = t->next) { if (isCustomTrack(t->table)) { hasCustomTracks = TRUE; break; } } hOnClickButton("document.customTrackForm.submit();return false;", hasCustomTracks ? CT_MANAGE_BUTTON_LABEL : CT_ADD_BUTTON_LABEL); hPrintf(" "); if (hubConnectTableExists()) hOnClickButton("document.trackHubForm.submit();return false;", "track hubs"); hPrintf("</TD></TR>\n"); } /* Print table line. */ { hPrintf("<TR><TD>"); curTable = showTableField(curTrack, hgtaTable, TRUE); if (isHubTrack(curTable) || (strchr(curTable, '.') == NULL)) /* In same database */ { hti = getHti(database, curTable, conn); isPositional = htiIsPositional(hti); } isLongTabix = isLongTabixTable( curTable); isBam = isBamTable( curTable); isVcf = isVcfTable(curTable, NULL); isWig = isWiggle(database, curTable); if (isBigWigTable(curTable)) { isPositional = TRUE; isWig = TRUE; } isHalSnake = isHalTable( curTable); isMaf = isMafTable(database, curTrack, curTable); isBedGr = isBedGraph(curTable); isArray = isMicroarray(curTrack, curTable); struct trackDb *tdb = findTdbForTable(database, curTrack, curTable, ctLookupName); isPal = isPalCompatible(conn, tdb, curTable); nbSpaces(1); if (isCustomTrack(curTable)) { isChromGraphCt = isChromGraph(tdb); } cgiMakeButton(hgtaDoSchema, "describe table schema"); hPrintf("</TD></TR>\n"); } if (curTrack == NULL) { struct trackDb *tdb = hTrackDbForTrack(database, curTable); struct trackDb *cTdb = hCompositeTrackDbForSubtrack(database, tdb); if (cTdb) curTrack = cTdb; else curTrack = tdb; isMaf = isMafTable(database, curTrack, curTable); } /* Region line */ { char *regionType = cartUsualString(cart, hgtaRegionType, hgtaRegionTypeGenome); char *range = cartUsualString(cart, hgtaRange, ""); if (isPositional) { boolean doEncode = FALSE; if (!trackHubDatabase(database)) doEncode = sqlTableExists(conn, "encodeRegions"); hPrintf("<TR><TD><B>region:</B>\n"); /* If regionType not allowed force it to "genome". */ if ((sameString(regionType, hgtaRegionTypeUserRegions) && userRegionsFileName() == NULL) || (sameString(regionType, hgtaRegionTypeEncode) && !doEncode)) regionType = hgtaRegionTypeGenome; // Is "genome" is not allowed because of tdb 'tableBrowser noGenome'? boolean disableGenome = ((curTrack && cartTrackDbIsNoGenome(database, curTrack->table)) || (curTable && cartTrackDbIsNoGenome(database, curTable))); // If "genome" is selected but not allowed, force it to "range": if (sameString(regionType, hgtaRegionTypeGenome) && disableGenome) regionType = hgtaRegionTypeRange; jsTrackingVar("regionType", regionType); if (disableGenome) { makeRegionButtonExtraHtml(hgtaRegionTypeGenome, regionType, "DISABLED"); hPrintf(" <span"NO_GENOME_CLASS">genome (unavailable for selected track)</span>" " "); } else { makeRegionButton(hgtaRegionTypeGenome, regionType); hPrintf(" genome "); } if (doEncode) { makeRegionButton(hgtaRegionTypeEncode, regionType); hPrintf(" ENCODE Pilot regions "); } makeRegionButton(hgtaRegionTypeRange, regionType); hPrintf(" position "); hPrintf("<INPUT TYPE=TEXT NAME=\"%s\" SIZE=26 VALUE=\"%s\" onFocus=\"%s\">\n", hgtaRange, range, jsRadioUpdate(hgtaRegionType, "regionType", "range")); cgiMakeButton(hgtaDoLookupPosition, "lookup"); hPrintf(" "); if (userRegionsFileName() != NULL) { makeRegionButton(hgtaRegionTypeUserRegions, regionType); hPrintf(" defined regions "); cgiMakeButton(hgtaDoSetUserRegions, "change"); hPrintf(" "); cgiMakeButton(hgtaDoClearUserRegions, "clear"); } else cgiMakeButton(hgtaDoSetUserRegions, "define regions"); hPrintf("</TD></TR>\n"); } else { /* Need to put at least stubs of cgi variables in for JavaScript to work. */ jsTrackingVar("regionType", regionType); cgiMakeHiddenVar(hgtaRange, range); cgiMakeHiddenVar(hgtaRegionType, regionType); } /* Select identifiers line (if applicable). */ if (!isWig && getIdField(database, curTrack, curTable, hti) != NULL) { hPrintf("<TR><TD><B>identifiers (names/accessions):</B>\n"); cgiMakeButton(hgtaDoPasteIdentifiers, "paste list"); hPrintf(" "); cgiMakeButton(hgtaDoUploadIdentifiers, "upload list"); if (identifierFileName() != NULL) { hPrintf(" "); cgiMakeButton(hgtaDoClearIdentifiers, "clear list"); } hPrintf("</TD></TR>\n"); } } /* microarray options */ /* button for option page here (median/log-ratio, etc) */ /* Filter line. */ { hPrintf("<TR><TD><B>filter:</B>\n"); if (anyFilter()) { cgiMakeButton(hgtaDoFilterPage, "edit"); hPrintf(" "); cgiMakeButton(hgtaDoClearFilter, "clear"); if (isWig || isBedGr) wigShowFilter(conn); } else { cgiMakeButton(hgtaDoFilterPage, "create"); } hPrintf("</TD></TR>\n"); } /* Composite track subtrack merge line. */ boolean canSubtrackMerge = (curTrack && tdbIsComposite(curTrack) && !isBam && !isVcf && !isLongTabix); if (canSubtrackMerge) { hPrintf("<TR><TD><B>subtrack merge:</B>\n"); if (anySubtrackMerge(database, curTable)) { cgiMakeButton(hgtaDoSubtrackMergePage, "edit"); hPrintf(" "); cgiMakeButton(hgtaDoClearSubtrackMerge, "clear"); } else { cgiMakeButton(hgtaDoSubtrackMergePage, "create"); } hPrintf("</TD></TR>\n"); } /* Intersection line. */ if (isPositional) { if (anyIntersection()) { hPrintf("<TR><TD><B>intersection with %s:</B>\n", cartString(cart, hgtaIntersectTable)); cgiMakeButton(hgtaDoIntersectPage, "edit"); hPrintf(" "); cgiMakeButton(hgtaDoClearIntersect, "clear"); hPrintf("</TD></TR>\n"); } else if (canIntersect(database, curTable)) { hPrintf("<TR><TD><B>intersection:</B>\n"); cgiMakeButton(hgtaDoIntersectPage, "create"); hPrintf("</TD></TR>\n"); } } /* Correlation line. */ struct trackDb *tdb = findTdbForTable(database, curTrack, curTable, ctLookupName); if (correlateTrackTableOK(tdb, curTable)) { char *table2 = cartUsualString(cart, hgtaCorrelateTable, "none"); hPrintf("<TR><TD><B>correlation:</B>\n"); if (differentWord(table2, "none") && strlen(table2) && ! isNoGenomeDisabled(database, table2)) { struct grp *groupList = fullGroupList; struct grp *selGroup = findSelectedGroup(groupList, hgtaCorrelateGroup); struct trackDb *tdb2 = findSelectedTrack(fullTrackList, selGroup,hgtaCorrelateTrack); if (tdbIsComposite(tdb2)) { struct slRef *tdbRefList = trackDbListGetRefsToDescendantLeaves(tdb2->subtracks); struct slRef *tdbRef; for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { struct trackDb *subTdb = tdbRef->val; if (sameString(table2, subTdb->table)) { tdb2 = subTdb; break; } } slFreeList(&tdbRefList); } cgiMakeButton(hgtaDoCorrelatePage, "calculate"); cgiMakeButton(hgtaDoClearCorrelate, "clear"); if (tdb2 && tdb2->shortLabel) hPrintf(" (with: %s)", tdb2->shortLabel); #ifdef NOT_YET /* debugging dbg vvvvv */ if (curTrack && curTrack->type) /* dbg */ { hPrintf("<BR> (debug: '%s', '%s(%s)')", curTrack->type, tdb2->type, table2); } /* debugging debug ^^^^^ */ #endif } else cgiMakeButton(hgtaDoCorrelatePage, "create"); hPrintf("</TD></TR>\n"); } /* Print output type line. */ showOutputTypeRow(isWig, isBedGr, isPositional, isMaf, isChromGraphCt, isPal, isArray, isHalSnake); /* Print output destination line. */ { char *compressType = cartUsualString(cart, hgtaCompressType, textOutCompressNone); char *fileName = cartUsualString(cart, hgtaOutFileName, ""); hPrintf("<TR><TD>\n"); hPrintf("<B>output file:</B> "); cgiMakeTextVar(hgtaOutFileName, fileName, 29); hPrintf(" (leave blank to keep output in browser)</TD></TR>\n"); hPrintf("<TR><TD>\n"); hPrintf("<B>file type returned: </B>"); cgiMakeRadioButton(hgtaCompressType, textOutCompressNone, sameWord(textOutCompressNone, compressType)); hPrintf(" plain text  "); cgiMakeRadioButton(hgtaCompressType, textOutCompressGzip, sameWord(textOutCompressGzip, compressType)); hPrintf(" gzip compressed"); hPrintf("</TD></TR>\n"); } hPrintf("</TABLE>\n"); /* Submit buttons. */ { hPrintf("<BR>\n"); if (isWig || isBam || isVcf || isLongTabix) { char *name; extern char *maxOutMenu[]; char *maxOutput = maxOutMenu[0]; if (isCustomTrack(curTable)) name=filterFieldVarName("ct", curTable, "_", filterMaxOutputVar); else name=filterFieldVarName(database,curTable, "_",filterMaxOutputVar); maxOutput = cartUsualString(cart, name, maxOutMenu[0]); if (isWig) hPrintf( "<I>Note: to return more than %s lines, change the filter setting" " (above). The entire data set may be available for download as" " a very large file that contains the original data values (not" " compressed into the wiggle format) -- see the Downloads page." "</I><BR>", maxOutput); else if (isBam || isVcf || isLongTabix) hPrintf( "<I>Note: to return more than %s lines, change the filter setting" " (above). Please consider downloading the entire data from our Download pages." "</I><BR>", maxOutput); } else if (anySubtrackMerge(database, curTable) || anyIntersection()) { hPrintf("<I>Note: The all fields and selected fields output formats " "are not available when a%s has been specified.</I><BR>", canSubtrackMerge ? " subtrack merge or intersection" : "n intersection"); } cgiMakeButton(hgtaDoTopSubmit, "get output"); hPrintf(" "); if (isPositional || isWig) { cgiMakeButton(hgtaDoSummaryStats, "summary/statistics"); hPrintf(" "); } #ifdef SOMETIMES hPrintf(" "); cgiMakeButton(hgtaDoTest, "test"); #endif /* SOMETIMES */ } hPrintf("<P>" "To reset <B>all</B> user cart settings (including custom tracks), \n" "<A HREF=\"/cgi-bin/cartReset?destination=%s\">click here</A>.\n", getScriptName()); }
static void showOutputTypeRow(boolean isWig, boolean isBedGr, boolean isPositional, boolean isMaf, boolean isChromGraphCt, boolean isPal, boolean isMicroarray, boolean isHalSnake) /* Print output line. */ { struct outputType *otList = NULL, *otDefault = NULL; boolean bedifiedOnly = (anySubtrackMerge(database, curTable) || anyIntersection()); hPrintf("<TR><TD><B>output format:</B>\n"); if (isBedGr) { if (! bedifiedOnly) { slAddTail(&otList, &otAllFields); slAddTail(&otList, &otSelected); } slAddTail(&otList, &otWigData); slAddTail(&otList, &otWigBed); slAddTail(&otList, &otCustomTrack); slAddTail(&otList, &otHyperlinks); } else if (isWig) { slAddTail(&otList, &otWigData); slAddTail(&otList, &otWigBed); slAddTail(&otList, &otCustomTrack); // hyperlinks output works for db-wiggle but not for bigWig } else if (isHalSnake) { slAddTail(&otList, &otMaf); } else if (isMaf) { slAddTail(&otList, &otMaf); if (! bedifiedOnly) slAddTail(&otList, &otAllFields); } else if (isChromGraphCt) { slAddTail(&otList, &otChromGraphData); } else if (isMicroarray) { slAddTail(&otList, &otMicroarrayNames); slAddTail(&otList, &otAllFields); slAddTail(&otList, &otSelected); slAddTail(&otList, &otHyperlinks); } else if (isPositional) { if (! bedifiedOnly) { slAddTail(&otList, &otAllFields); slAddTail(&otList, &otSelected); } else otDefault = &otBed; slAddTail(&otList, &otSequence); slAddTail(&otList, &otGff); if (isPal) slAddTail(&otList, &otPal); slAddTail(&otList, &otBed); slAddTail(&otList, &otCustomTrack); slAddTail(&otList, &otHyperlinks); } else { slAddTail(&otList, &otAllFields); slAddTail(&otList, &otSelected); } showOutDropDown(otList, otDefault); }
void doSummaryStatsBigWig(struct sqlConnection *conn) /* Put up page showing summary stats for bigWig track. */ { struct trackDb *track = curTrack; char *table = curTable; char *shortLabel = (track == NULL ? table : track->shortLabel); char *fileName = bigWigFileName(table, conn); long startTime = clock1000(); htmlOpen("%s (%s) Big Wig Summary Statistics", shortLabel, table); if (anySubtrackMerge(database, curTable)) hPrintf("<P><EM><B>Note:</B> subtrack merge is currently ignored on this " "page (not implemented yet). Statistics shown here are only for " "the primary table %s (%s).</EM>", shortLabel, table); struct bbiFile *bwf = bigWigFileOpen(fileName); struct region *region, *regionList = getRegions(); double sumData = 0, sumSquares = 0, minVal = 0, maxVal = 0; bits64 validCount = 0; if (!anyFilter() && !anyIntersection()) { for (region = regionList; region != NULL; region = region->next) { struct bbiSummaryElement sum; if (bbiSummaryArrayExtended(bwf, region->chrom, region->start, region->end, bigWigIntervalQuery, 1, &sum)) { if (validCount == 0) { minVal = sum.minVal; maxVal = sum.maxVal; } else { if (sum.minVal < minVal) minVal = sum.minVal; if (sum.maxVal > maxVal) maxVal = sum.maxVal; } sumData += sum.sumData; sumSquares += sum.sumSquares; validCount += sum.validCount; } } } else { double ll, ul; enum wigCompare cmp; getWigFilter(database, curTable, &cmp, &ll, &ul); for (region = regionList; region != NULL; region = region->next) { struct lm *lm = lmInit(0); struct bbiInterval *iv, *ivList; ivList = intersectedFilteredBbiIntervalsOnRegion(conn, bwf, region, cmp, ll, ul, lm); for (iv = ivList; iv != NULL; iv = iv->next) { double val = iv->val; double size = iv->end - iv->start; if (validCount == 0) minVal = maxVal = val; else { if (val < minVal) minVal = val; if (val > maxVal) maxVal = val; } sumData += size*val; sumSquares += size*val*val; validCount += size; } lmCleanup(&lm); } } hTableStart(); floatStatRow("mean", sumData/validCount); floatStatRow("min", minVal); floatStatRow("max", maxVal); floatStatRow("standard deviation", calcStdFromSums(sumData, sumSquares, validCount)); numberStatRow("bases with data", validCount); long long regionSize = basesInRegion(regionList,0); long long gapTotal = gapsInRegion(conn, regionList,0); numberStatRow("bases with sequence", regionSize - gapTotal); numberStatRow("bases in region", regionSize); wigFilterStatRow(conn); stringStatRow("intersection", cartUsualString(cart, hgtaIntersectTable, "off")); long wigFetchTime = clock1000() - startTime; floatStatRow("load and calc time", 0.001*wigFetchTime); hTableEnd(); bbiFileClose(&bwf); htmlClose(); }