4fd52b1b34d170c15d3aacfeaf4fbb26fff224b1 hiram Wed Mar 25 12:52:00 2026 -0700 fix bugs for chrom size at 2^31 and manage partial computation windows at beginning or end of drawing window for gcOnFly refs #35958 diff --git src/hg/lib/wigDataStream.c src/hg/lib/wigDataStream.c index af7a2a235e7..80c7cf9b373 100644 --- src/hg/lib/wigDataStream.c +++ src/hg/lib/wigDataStream.c @@ -2307,42 +2307,65 @@ * retWindows with an allocated array. Caller must freeMem(*retWindows). */ { struct dnaSeq *seq = hChromSeq(db, chrom, start, end); if (seq == NULL) { *retWindows = NULL; return 0; } int seqLen = end - start; /* Align to winSize-base chromosome boundary, not the fetch boundary. * startOffset is the number of bases into the fetched sequence where * the first chromosome-aligned window begins. */ int startOffset = (winSize - (start % winSize)) % winSize; -/* Upper bound on number of windows */ -int maxWindows = (seqLen - startOffset + winSize - 1) / winSize; +/* Upper bound on number of windows (+ 1 for possible leading partial) */ +int maxWindows = (seqLen - startOffset + winSize - 1) / winSize + 1; struct gcOnTheFlyWindow *windows; AllocArray(windows, maxWindows); int count = 0; + +/* Handle leading partial window if fetch starts mid-window */ +if (startOffset > 0) + { + int gcCount = 0, validBases = 0; + int i; + for (i = 0; i < startOffset; i++) + { + char b = seq->dna[i]; + if (b == 'g' || b == 'c') { gcCount++; validBases++; } + else if (b != 'n') validBases++; + } + if (validBases > 0) + { + windows[count].chromStart = start; + windows[count].gcPct = 100.0 * gcCount / validBases; + count++; + } + } + int pos; -for (pos = startOffset; pos + winSize <= seqLen; pos += winSize) +for (pos = startOffset; pos < seqLen; pos += winSize) { + int windowEnd = pos + winSize; + if (windowEnd > seqLen) + windowEnd = seqLen; /* partial window at end of chrom */ int gcCount = 0, validBases = 0; int i; - for (i = pos; i < pos + winSize; i++) + for (i = pos; i < windowEnd; i++) { char b = seq->dna[i]; if (b == 'g' || b == 'c') { gcCount++; validBases++; } else if (b != 'n') validBases++; } if (validBases == 0) continue; windows[count].chromStart = start + pos; windows[count].gcPct = 100.0 * gcCount / validBases; count++; } dnaSeqFree(&seq); *retWindows = windows; return count;