639c013f2f7cd7553674c60372a3208cd85a47be braney Thu Oct 31 14:14:28 2024 -0700 fix a bug in calculating summaries with the size of the summaries is more than the number of bases in the region. Refs #26932 diff --git src/lib/bbiRead.c src/lib/bbiRead.c index f5c6277..eb93f22 100644 --- src/lib/bbiRead.c +++ src/lib/bbiRead.c @@ -633,53 +633,84 @@ return validCount; } static boolean bbiSummaryArrayFromFull(struct bbiFile *bbi, char *chrom, bits32 start, bits32 end, BbiFetchIntervals fetchIntervals, int summarySize, struct bbiSummaryElement *summary) /* Summarize data, not using zoom. */ { struct bbiInterval *intervalList = NULL, *interval; struct lm *lm = lmInit(0); intervalList = (*fetchIntervals)(bbi, chrom, start, end, lm); boolean result = FALSE; if (intervalList != NULL) { + bits32 baseCount = end - start; + if (baseCount > summarySize) // more bases than pixels + { int i; bits32 baseStart = start, baseEnd; - bits32 baseCount = end - start; interval = intervalList; for (i=0; i<summarySize; ++i) { /* Calculate end of this part of summary */ baseEnd = start + (bits64)baseCount*(i+1)/summarySize; int end1 = baseEnd; if (end1 == baseStart) end1 = baseStart+1; /* Advance interval to skip over parts we are no longer interested in. */ while (interval != NULL && interval->end <= baseStart) interval = interval->next; if (bbiIntervalSlice(bbi, baseStart, end1, interval, &summary[i])) result = TRUE; /* Next time round start where we left off. */ baseStart = baseEnd; } } + else // more pixels than bases + { + double pixelsPerBase = (double)summarySize / baseCount; + for (interval = intervalList; interval != NULL; interval = interval->next) + { + bits32 base; + for(base = interval->start; base < end && base < interval->end; base++); + { + unsigned offset = base - start; + unsigned startPos = round(offset * pixelsPerBase); + unsigned endPos = round((offset + 1) * pixelsPerBase); + struct bbiSummaryElement summaryForBase; + + // the whole range will have the same value, so only ask once + if (bbiIntervalSlice(bbi, base, base + 1, interval, &summaryForBase)) + result = TRUE; + + for(;startPos < endPos; startPos++) + { + if (startPos >= summarySize) + break; + + // copy structure + summary[startPos] = summaryForBase; + } + } + } + } + } lmCleanup(&lm); return result; } boolean bbiSummaryArrayExtended(struct bbiFile *bbi, char *chrom, bits32 start, bits32 end, BbiFetchIntervals fetchIntervals, int summarySize, struct bbiSummaryElement *summary) /* Fill in summary with data from indicated chromosome range in bigWig file. * Returns FALSE if no data at that position. */ { boolean result = FALSE; /* Protect from bad input. */ if (start >= end) return result;