4833b6c8e4583d27b99b06a6bdf0357fe786215d galt Mon Sep 8 01:45:07 2025 -0700 Deals with multi-region and bigBeds so limitWiggle optimization works properly with all windows or regions. Fixes error test cases in rm35580 as well as full chromosome and recount3 and lrg and unusual tracks etc. fixes 35580 diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c index 8784208b144..c5aa6ff27bf 100644 --- src/hg/hgTracks/bigBedTrack.c +++ src/hg/hgTracks/bigBedTrack.c @@ -475,79 +475,159 @@ { static boolean set = FALSE; static unsigned maxItems = 0; if (!set) { char *maxItemsStr = cfgOptionDefault("bigBedMaxItems", "10000"); maxItems = sqlUnsigned(maxItemsStr); set = TRUE; } return maxItems; } -struct bigBedInterval *bigBedSelectRangeExt(struct track *track, - char *chrom, int start, int end, struct lm *lm, int maxItems) -/* Return list of intervals in range. */ +static boolean hasOverflowedInWindow(struct track *track) +/* has it overlowed in the given track? */ { -struct bigBedInterval *result = NULL; +int resultCount = -1; +char *resultCountString = trackDbSetting(track->tdb, "bigBedItemsCount"); +if (resultCountString) + resultCount = atoi(resultCountString); +return (resultCount > bigBedMaxItems()); +} + + +static void loadBigBedSummary(struct track *track) +/* Check if summary loading needed for bigBed */ +{ + +if (track->subtracks) // do tracks or subtracks but not parents. + { + return; + } + +struct lm *lm = lmInit(0); + +char *chrom = chromName; +int start = winStart; +int end = winEnd; + /* protect against temporary network error */ struct errCatch *errCatch = errCatchNew(); boolean filtering = FALSE; // for the moment assume we're not filtering if (errCatchStart(errCatch)) { - struct bbiFile *bbi = fetchBbiForTrack(track); - result = bigBedIntervalQuery(bbi, chrom, start, end, bigBedMaxItems() + 1, lm); - if (slCount(result) > bigBedMaxItems()) + // scan all windows for errors and overflows + boolean errorsInWindows = FALSE; + boolean overFlowedInWindows = FALSE; + + struct track *thisTrack; + for(thisTrack=track->prevWindow; thisTrack; thisTrack=thisTrack->prevWindow) + { + if (hasOverflowedInWindow(thisTrack)) + overFlowedInWindows = TRUE; + if (thisTrack->drawItems == bigDrawWarning) + errorsInWindows = TRUE; + } + for(thisTrack=track->nextWindow; thisTrack; thisTrack=thisTrack->nextWindow) + { + if (hasOverflowedInWindow(thisTrack)) + overFlowedInWindows = TRUE; + if (thisTrack->drawItems == bigDrawWarning) + errorsInWindows = TRUE; + } + + if (hasOverflowedInWindow(track)) + overFlowedInWindows = TRUE; + + if (!errorsInWindows && overFlowedInWindows) { if (filtering) errAbort("Too many items in window to filter.Zoom in or remove filters to view track."); else + { + struct bbiFile *bbi = fetchBbiForTrack(track); + if (bbi) { // use summary levels if (track->visibility != tvDense) { track->limitedVis = tvFull; track->limitWiggle = TRUE; track->limitedVisSet = TRUE; } else { track->limitedVis = tvDense; track->limitedVisSet = TRUE; } - result = NULL; AllocArray(track->summary, insideWidth); if (bigBedSummaryArrayExtended(bbi, chrom, start, end, insideWidth, track->summary)) { char *denseCoverage = trackDbSettingClosestToHome(track->tdb, "denseCoverage"); if (denseCoverage != NULL) { double endVal = atof(denseCoverage); if (endVal <= 0) { AllocVar(track->sumAll); *track->sumAll = bbiTotalSummary(bbi); } } } else freez(&track->summary); } } + } + } +errCatchEnd(errCatch); +if (errCatch->gotError) + { + track->networkErrMsg = cloneString(errCatch->message->string); + track->drawItems = bigDrawWarning; + track->totalHeight = bigWarnTotalHeight; + } +errCatchFree(&errCatch); +lmCleanup(&lm); +track->bbiFile = NULL; + +} + +struct bigBedInterval *bigBedSelectRangeExt(struct track *track, + char *chrom, int start, int end, struct lm *lm, int maxItems) +/* Return list of intervals in range. */ +{ +struct bigBedInterval *result = NULL; +/* protect against temporary network error */ +struct errCatch *errCatch = errCatchNew(); +if (errCatchStart(errCatch)) + { + struct bbiFile *bbi = fetchBbiForTrack(track); + result = bigBedIntervalQuery(bbi, chrom, start, end, bigBedMaxItems() + 1, lm); // pass in desired limit or 0 for all. + + char resultCount[32]; + safef(resultCount, sizeof resultCount, "%d", slCount(result)); + trackDbAddSetting(track->tdb, "bigBedItemsCount", resultCount); + + if (slCount(result) > bigBedMaxItems()) + { + result = NULL; + } + track->bbiFile = NULL; } errCatchEnd(errCatch); if (errCatch->gotError) { track->networkErrMsg = cloneString(errCatch->message->string); track->drawItems = bigDrawWarning; track->totalHeight = bigWarnTotalHeight; result = NULL; } errCatchFree(&errCatch); return result; } @@ -978,16 +1058,20 @@ #endif complexBedMethods(track, tdb, TRUE, wordCount, newWords); } void bigBedMethods(struct track *track, struct trackDb *tdb, int wordCount, char *words[]) /* Set up bigBed methods for tracks that are type bigBed. */ { commonBigBedMethods(track, tdb, wordCount, words); if (sameWordOk(trackDbSetting(tdb, "style"), "heatmap")) { // Might want to check here if required heatmap settings/fields are in place, // maybe some combo of row count and labels. heatmapMethods(track); } +//track->loadItems = +// add name loadSummary to the track structure. +track->loadSummary = loadBigBedSummary; } +