ee9a6c5c63eba2d963a5d7581185b1004fffe964 angie Mon Apr 15 14:06:10 2013 -0700 Added indentifying name to annoStreamer for output header info and better error messages. refs #6152 diff --git src/lib/annoGrator.c src/lib/annoGrator.c index 4386787..1c85286 100644 --- src/lib/annoGrator.c +++ src/lib/annoGrator.c @@ -1,34 +1,34 @@ /* annoGrator -- join two inputs on position, keeping all original fields intact. */ #include "annoGrator.h" INLINE void agCheckPrimarySorting(struct annoGrator *self, struct annoRow *primaryRow) /* Die if primaryRow seems to have arrived out of order. */ { if (self->prevPChrom == NULL) self->prevPChrom = cloneString(primaryRow->chrom); else if (differentString(primaryRow->chrom, self->prevPChrom)) { if (strcmp(primaryRow->chrom, self->prevPChrom) < 0) - errAbort("Unsorted input from primarySource (%s < %s)", - primaryRow->chrom, self->prevPChrom); + errAbort("annoGrator %s: Unsorted input from primary source (%s < %s)", + self->streamer.name, primaryRow->chrom, self->prevPChrom); self->prevPChrom = cloneString(primaryRow->chrom); } else if (primaryRow->start < self->prevPStart) - errAbort("Unsorted input from primarySource (%s, %u < %u)", - primaryRow->chrom, primaryRow->start, self->prevPStart); + errAbort("annoGrator %s:Unsorted input from primary source (%s, %u < %u)", + self->streamer.name, primaryRow->chrom, primaryRow->start, self->prevPStart); self->prevPStart = primaryRow->start; } INLINE void agTrimToStart(struct annoGrator *self, char *chrom, uint start) /* If queue contains items whose end is to the left of start, splice them out. */ { struct annoRow *qRow, *prevQRow = NULL, *nextQRow; for (qRow = self->qHead; qRow != NULL; qRow = nextQRow) { nextQRow = qRow->next; int cDifRowP = strcmp(qRow->chrom, chrom); if (cDifRowP > 0 || (cDifRowP == 0 && qRow->start >= start)) break; else if (cDifRowP < 0 || qRow->end < start) { @@ -38,66 +38,68 @@ prevQRow->next = qRow->next; if (self->qTail == qRow) self->qTail = prevQRow; } else prevQRow = qRow; } if (self->qHead == NULL) { // Queue is empty - clean up lm lmCleanup(&(self->qLm)); self->qLm = lmInit(0); } } -INLINE void agCheckInternalSorting(struct annoRow *newRow, struct annoRow *qTail) +INLINE void agCheckInternalSorting(struct annoGrator *self, struct annoRow *newRow) /* Die if newRow precedes qTail. */ { -if (qTail != NULL) +if (self->qTail != NULL) { - int cDifNewTail = strcmp(newRow->chrom, qTail->chrom); + int cDifNewTail = strcmp(newRow->chrom, self->qTail->chrom); if (cDifNewTail < 0) - errAbort("Unsorted input from internal source (%s < %s)", - newRow->chrom, qTail->chrom); - else if (cDifNewTail == 0 && newRow->start < qTail->start) - errAbort("Unsorted input from internal source (%s, %u < %u)", - newRow->chrom, newRow->start, qTail->start); + errAbort("annoGrator %s: Unsorted input from internal source %s (%s < %s)", + self->streamer.name, self->mySource->name, newRow->chrom, self->qTail->chrom); + else if (cDifNewTail == 0 && newRow->start < self->qTail->start) + errAbort("annoGrator %s: Unsorted input from internal source %s (%s, %u < %u)", + self->streamer.name, self->mySource->name, + newRow->chrom, newRow->start, self->qTail->start); } } INLINE void agFetchToEnd(struct annoGrator *self, char *chrom, uint end) /* Fetch rows until we are sure we have all items that start to the left of end, * i.e. we have an item that starts at/after end or we hit eof. */ { while (!self->eof && (self->qTail == NULL || strcmp(self->qTail->chrom, chrom) < 0 || self->qTail->start < end)) { struct annoRow *newRow = self->mySource->nextRow(self->mySource, self->qLm); if (newRow == NULL) self->eof = TRUE; else { - agCheckInternalSorting(newRow, self->qTail); + agCheckInternalSorting(self, newRow); int cDifNewP = strcmp(newRow->chrom, chrom); if (cDifNewP >= 0) { // Add newRow to qTail if (self->qTail == NULL) { if (self->qHead != NULL) - errAbort("qTail is NULL but qHead is non-NULL"); + errAbort("annoGrator %s: qTail is NULL but qHead is non-NULL", + self->streamer.name); self->qHead = self->qTail = newRow; } else { self->qTail->next = newRow; self->qTail = newRow; } if (cDifNewP > 0) // newRow->chrom comes after chrom; we're done for now break; } } } } @@ -148,31 +150,32 @@ void annoGratorClose(struct annoStreamer **pSelf) /* Free self (including mySource). */ { if (pSelf == NULL) return; struct annoGrator *self = *(struct annoGrator **)pSelf; lmCleanup(&(self->qLm)); self->mySource->close(&(self->mySource)); freeMem(self->prevPChrom); freez(pSelf); } static struct annoRow *noNextRow(struct annoStreamer *self, struct lm *callerLm) /* nextRow() is N/A for annoGrator, which needs caller to use integrate() instead. */ { -errAbort("nextRow() called on annoGrator object, but integrate() should be called instead"); +errAbort("annoGrator %s: nextRow() called, but integrate() should be called instead", + self->name); return NULL; } static void agReset(struct annoGrator *self) /* Reset all state associated with position */ { freez(&(self->prevPChrom)); self->prevPStart = 0; self->eof = FALSE; lmCleanup(&(self->qLm)); self->qLm = lmInit(0); self->qHead = self->qTail = NULL; } static boolean filtersHaveRJInclude(struct annoFilter *filters) @@ -209,31 +212,32 @@ gSelf->haveRJIncludeFilter = filtersHaveRJInclude(sSelf->filters); } void agSetOverlapRule(struct annoGrator *self, enum annoGratorOverlap rule) /* Tell annoGrator how to handle overlap of its rows with primary row. */ { self->overlapRule = rule; } void annoGratorInit(struct annoGrator *self, struct annoStreamer *mySource) /* Initialize an integrator of columns from mySource with (positions of) * rows passed to integrate(). * mySource becomes property of the annoGrator. */ { struct annoStreamer *streamer = &(self->streamer); -annoStreamerInit(streamer, mySource->assembly, mySource->getAutoSqlObject(mySource)); +annoStreamerInit(streamer, mySource->assembly, mySource->getAutoSqlObject(mySource), + mySource->name); streamer->rowType = mySource->rowType; streamer->setAutoSqlObject = agSetAutoSqlObject; streamer->setFilters = agSetFilters; streamer->setRegion = annoGratorSetRegion; streamer->nextRow = noNextRow; streamer->close = annoGratorClose; self->qLm = lmInit(0); self->integrate = annoGratorIntegrate; self->setOverlapRule = agSetOverlapRule; self->overlapRule = agoNoConstraint; self->mySource = mySource; self->haveRJIncludeFilter = filtersHaveRJInclude(streamer->filters); } struct annoGrator *annoGratorNew(struct annoStreamer *mySource)