static void getFloatArray(struct annoStreamWig *self, struct wiggle *wiggle, boolean *retRightFail, int *retValidCount, float *vector) /* expand wiggle bytes & spans to per-bp floats; filter values here! */ { udcSeek(self->wibFH, wiggle->offset); UBYTE wigBuf[wiggle->count]; size_t expectedBytes = sizeof(wigBuf); size_t bytesRead = udcRead(self->wibFH, wigBuf, expectedBytes); if (bytesRead != expectedBytes) errnoAbort("annoStreamWig: failed to udcRead %llu bytes from %s (got %llu)\n", (unsigned long long)expectedBytes, wiggle->file, (unsigned long long)bytesRead); paranoidCheckSize(self, wiggle); int i, j, validCount = 0; for (i = 0; i < wiggle->count; i++) { float value; if (wigBuf[i] == WIG_NO_DATA) value = NAN; else { value = BIN_TO_VALUE(wigBuf[i], wiggle->lowerLimit, wiggle->dataRange); if (annoFilterWigValueFails(self->streamer.filters, value, retRightFail)) value = NAN; else validCount++; } int bpOffset = i * wiggle->span; for (j = 0; j < wiggle->span; j++) vector[bpOffset + j] = value; } if (retValidCount != NULL) *retValidCount = validCount; }
static struct annoRow *asbwNextRow(struct annoStreamer *sSelf, char *minChrom, uint minEnd, struct lm *callerLm) /* Return a single annoRow, or NULL if there are no more items. */ { struct annoStreamBigWig *self = (struct annoStreamBigWig *)sSelf; if (self->eof) return NULL; else if (self->nextInterval == NULL) { asbwDoQuery(self, minChrom, minEnd); if (self->eof) return NULL; } // Skip past any left-join failures until we get a right-join failure, a passing interval, or EOF. boolean rightFail = FALSE; struct bbiInterval *startIv = self->nextInterval; while (annoFilterWigValueFails(sSelf->filters, self->nextInterval->val, &rightFail)) { if (rightFail) break; startIv = self->nextInterval = self->nextInterval->next; if (self->nextInterval == NULL) return NULL; } char *chrom = sSelf->chrom ? sSelf->chrom : self->queryChrom->name; if (rightFail) return annoRowFromContigBbiIntervals(sSelf->name, chrom, startIv, startIv, rightFail, callerLm); // Collect up to maxCount contiguous intervals; then make annoRow with vector. struct bbiInterval *endIv = startIv, *iv; int maxCount = 16 * 1024, count; for (iv = startIv->next, count = 0; iv != NULL && count < maxCount; iv = iv->next, count++) { if (annoFilterWigValueFails(sSelf->filters, iv->val, &rightFail)) break; if (iv->start == endIv->end) endIv = iv; else break; } // If there's a query region and we have reached the end of its intervals, we're done. if (sSelf->chrom != NULL && endIv->next == NULL) self->eof = TRUE; self->nextInterval = endIv->next; return annoRowFromContigBbiIntervals(sSelf->name, chrom, startIv, endIv, rightFail, callerLm); }