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;