6648b8b2419629b3d401c01f38086be43a2eeff8 kent Fri Mar 8 16:27:46 2013 -0800 Making bedToBigBed and bedGraphToBigWig share more code. Cure is only half as bad as disease (trading sharing 64 lines for having a function with 16 parameters.) diff --git src/utils/bedGraphToBigWig/bedGraphToBigWig.c src/utils/bedGraphToBigWig/bedGraphToBigWig.c index c306bff..b0c176b 100644 --- src/utils/bedGraphToBigWig/bedGraphToBigWig.c +++ src/utils/bedGraphToBigWig/bedGraphToBigWig.c @@ -203,32 +203,32 @@ } /* Save values in output array. */ struct sectionItem *b = &items[itemIx]; b->start = start; b->end = end; b->val = val; lastB = b; itemIx += 1; } assert(sectionIx == sectionCount); *retMaxSectionSize = maxSectionSize; } -static struct bbiSummary *writeReducedOnceReturnReducedTwice(struct bbiChromUsage *usageList, - struct lineFile *lf, bits32 initialReduction, bits32 initialReductionCount, +static struct bbiSummary *bedGraphWriteReducedOnceReturnReducedTwice(struct bbiChromUsage *usageList, + int fieldCount, struct lineFile *lf, bits32 initialReduction, bits32 initialReductionCount, int zoomIncrement, int blockSize, int itemsPerSlot, boolean doCompress, struct lm *lm, FILE *f, bits64 *retDataStart, bits64 *retIndexStart, struct bbiSummaryElement *totalSum) /* Write out data reduced by factor of initialReduction. Also calculate and keep in memory * next reduction level. This is more work than some ways, but it keeps us from having to * keep the first reduction entirely in memory. */ { struct bbiSummary *twiceReducedList = NULL; bits32 doubleReductionSize = initialReduction * zoomIncrement; struct bbiChromUsage *usage = usageList; struct bbiSummary oneSummary, *sum = NULL; struct bbiBoundsArray *boundsArray, *boundsPt, *boundsEnd; boundsPt = AllocArray(boundsArray, initialReductionCount); boundsEnd = boundsPt + initialReductionCount; @@ -403,99 +403,38 @@ writeSections(usageList, lf, itemsPerSlot, boundsArray, sectionCount, f, resTryCount, resScales, resSizes, doCompress, &maxSectionSize); verboseTime(2, "pass2"); /* Write out primary data index. */ bits64 indexOffset = ftell(f); cirTreeFileBulkIndexToOpenFile(boundsArray, sizeof(boundsArray[0]), sectionCount, blockSize, 1, NULL, bbiBoundsArrayFetchKey, bbiBoundsArrayFetchOffset, indexOffset, f); verboseTime(2, "index write"); /* Declare arrays and vars that track the zoom levels we actually output. */ bits32 zoomAmounts[bbiMaxZoomLevels]; bits64 zoomDataOffsets[bbiMaxZoomLevels]; bits64 zoomIndexOffsets[bbiMaxZoomLevels]; -int zoomLevels = 0; -/* Write out first zoomed section while storing in memory next zoom level. */ -/* This is just a block to make some variables more local. */ - { - assert(resTryCount > 0); - bits64 dataSize = indexOffset - dataOffset; - int maxReducedSize = dataSize/2; - int initialReduction = 0, initialReducedCount = 0; - - /* Figure out initialReduction for zoom. */ - int resTry; - for (resTry = 0; resTry < resTryCount; ++resTry) - { - bits64 reducedSize = resSizes[resTry] * sizeof(struct bbiSummaryOnDisk); - if (doCompress) - reducedSize /= 2; // Estimate! - if (reducedSize <= maxReducedSize) - { - initialReduction = resScales[resTry]; - initialReducedCount = resSizes[resTry]; - break; - } - } - verbose(2, "initialReduction %d, initialReducedCount = %d\n", - initialReduction, initialReducedCount); +/* Call monster zoom maker library function that bedToBigBed also uses. */ +int zoomLevels = bbiWriteZoomLevels(lf, f, blockSize, itemsPerSlot, + bedGraphWriteReducedOnceReturnReducedTwice, 4, + doCompress, indexOffset - dataOffset, + usageList, resTryCount, resScales, resSizes, + zoomAmounts, zoomDataOffsets, zoomIndexOffsets, &totalSum); - /* Force there to always be at least one zoom. It may waste a little space on small - * files, but it makes files more uniform, and avoids special case code for calculating - * overall file summary. */ - if (initialReduction == 0) - { - initialReduction = resScales[0]; - initialReducedCount = resSizes[0]; - } - /* This is just a block to make some variables more local. */ - { - struct lm *lm = lmInit(0); - int zoomIncrement = bbiResIncrement; - lineFileRewind(lf); - struct bbiSummary *rezoomedList = writeReducedOnceReturnReducedTwice(usageList, - lf, initialReduction, initialReducedCount, - zoomIncrement, blockSize, itemsPerSlot, doCompress, lm, - f, &zoomDataOffsets[0], &zoomIndexOffsets[0], &totalSum); - verboseTime(2, "writeReducedOnceReturnReducedTwice"); - zoomAmounts[0] = initialReduction; - zoomLevels = 1; - - int zoomCount = initialReducedCount; - int reduction = initialReduction * zoomIncrement; - while (zoomLevels < bbiMaxZoomLevels) - { - int rezoomCount = slCount(rezoomedList); - if (rezoomCount >= zoomCount) - break; - zoomCount = rezoomCount; - zoomDataOffsets[zoomLevels] = ftell(f); - zoomIndexOffsets[zoomLevels] = bbiWriteSummaryAndIndex(rezoomedList, - blockSize, itemsPerSlot, doCompress, f); - zoomAmounts[zoomLevels] = reduction; - ++zoomLevels; - reduction *= zoomIncrement; - rezoomedList = bbiSummarySimpleReduce(rezoomedList, reduction, lm); - } - lmCleanup(&lm); - verboseTime(2, "further reductions"); - } - - } /* Figure out buffer size needed for uncompression if need be. */ if (doCompress) { int maxZoomUncompSize = itemsPerSlot * sizeof(struct bbiSummaryOnDisk); uncompressBufSize = max(maxSectionSize, maxZoomUncompSize); } /* Go back and rewrite header. */ rewind(f); bits32 sig = bigWigSig; bits16 version = bbiCurrentVersion; bits16 summaryCount = zoomLevels; bits16 reserved16 = 0; bits32 reserved32 = 0;