0144c4390a73ff6f2b690a904baa7fcd84c3bd25 angie Fri Jun 5 11:16:40 2015 -0700 For GBiB support, we can't simply assume that wib files are on local disk; we must use hReplaceGbdb and UDC in case they are remote. Following suit with Max's changes to wigTrack.c wigLoadPreDraw (225c0d55). refs #14579 note 106 diff --git src/hg/lib/annoStreamWig.c src/hg/lib/annoStreamWig.c index c9c3ad9..e37bef6 100644 --- src/hg/lib/annoStreamWig.c +++ src/hg/lib/annoStreamWig.c @@ -12,75 +12,80 @@ "table annoRowWig\n" "\"autoSql description of a single annoRowWig value, for filtering\"\n" " (\n" " string chrom; \"Reference sequence chromosome or scaffold\"\n" " uint chromStart; \"Start position in chromosome\"\n" " uint chromEnd; \"End position in chromosome\"\n" " float value; \"data value for this range\"\n" " )\n" ; struct annoStreamWig { struct annoStreamer streamer; // Parent class members & methods / external interface // Private members struct annoStreamer *wigStr; // Internal streamer for .wig as in wiggle db tables - FILE *wibF; // wib file handle - char *wibFile; // name of wib file on which wibF was opened + struct udcFile *wibFH; // wib file udcFile handle + char *wibFile; // name of wib file on which wibFH was opened }; static void aswSetRegion(struct annoStreamer *vSelf, char *chrom, uint regionStart, uint regionEnd) /* Set region -- and free current sqlResult if there is one. */ { annoStreamerSetRegion(vSelf, chrom, regionStart, regionEnd); struct annoStreamWig *self = (struct annoStreamWig *)vSelf; self->wigStr->setRegion(self->wigStr, chrom, regionStart, regionEnd); } static void checkWibFile(struct annoStreamWig *self, char *wibFile) /* If self doesn't have a .wib file name and handle open, or if the new wibFile is * not the same as the old one, update self to use new wibFile. */ { -if (self->wibFile == NULL || !sameString(self->wibFile, wibFile)) +char *realWibFile = hReplaceGbdb(wibFile); +if (self->wibFile == NULL || !sameString(self->wibFile, realWibFile)) { - carefulClose(&(self->wibF)); + udcFileClose(&self->wibFH); freeMem(self->wibFile); - self->wibFile = cloneString(wibFile); - self->wibF = mustOpen(self->wibFile, "r"); + self->wibFile = cloneString(realWibFile); + self->wibFH = udcFileMayOpen(self->wibFile, NULL); + if (self->wibFH == NULL) + errAbort("annoStreamWig: udc can't open wibFile '%s'", self->wibFile); } +freeMem(realWibFile); } static void paranoidCheckSize(struct annoStreamWig *self, struct wiggle *wiggle) /* paranoid, consider taking this out when code is stable: */ { int bpLen = wiggle->chromEnd - wiggle->chromStart; if (bpLen != (wiggle->span * wiggle->count)) errAbort("annoStreamWig %s: length in bases (%u - %u = %d) != span*count (%u * %u = %u)", self->streamer.name, wiggle->chromEnd, wiggle->chromStart, bpLen, wiggle->span, wiggle->count, (wiggle->span * wiggle->count)); } 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! */ { -fseek(self->wibF, wiggle->offset, SEEK_SET); +udcSeek(self->wibFH, wiggle->offset); UBYTE wigBuf[wiggle->count]; -size_t bytesRead = fread(wigBuf, 1, wiggle->count, self->wibF); -if (bytesRead != wiggle->count) - errnoAbort("annoStreamWig: failed to read %u bytes from %s (got %llu)\n", - wiggle->count, wiggle->file, (unsigned long long)bytesRead); +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++; } @@ -117,31 +122,31 @@ { rowOut = annoRowWigNew(wigRow->chrom, wigRow->start, wigRow->end, rightFail, vector, callerLm); done = TRUE; } } return rowOut; } static void aswClose(struct annoStreamer **pVSelf) /* Free wiggleDataStream and self. */ { if (pVSelf == NULL) return; struct annoStreamWig *self = *(struct annoStreamWig **)pVSelf; -carefulClose(&(self->wibF)); +udcFileClose(&(self->wibFH)); freeMem(self->wibFile); annoStreamerFree(pVSelf); } struct annoStreamer *annoStreamWigDbNew(char *db, char *table, struct annoAssembly *aa, int maxOutput) /* Create an annoStreamer (subclass) object from a wiggle database table. */ { struct annoStreamWig *self = NULL; AllocVar(self); self->wigStr = annoStreamDbNew(db, table, aa, asParseText(wiggleAsText), maxOutput); struct annoStreamer *streamer = &(self->streamer); annoStreamerInit(streamer, aa, asParseText(annoRowWigAsText), self->wigStr->name); streamer->rowType = arWig; streamer->setRegion = aswSetRegion;