UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

53 lines (52 loc) 2.43 kB
import { firstValueFrom } from 'rxjs'; import { toArray } from 'rxjs/operators'; import { max, min, sum } from "../../util/index.js"; import { rectifyStats } from "../../util/stats.js"; const DENSITY_SAMPLE_INITIAL_INTERVAL = 1000; const DENSITY_SAMPLE_MIN_FEATURES = 70; const DENSITY_SAMPLE_TIMEOUT_MS = 5000; export function aggregateQuantitativeStats(stats) { const meanMins = stats.map(s => s.scoreMeanMin).filter(s => s !== undefined); const meanMaxs = stats.map(s => s.scoreMeanMax).filter(s => s !== undefined); return rectifyStats({ scoreMax: max(stats.map(s => s.scoreMax)), scoreMin: min(stats.map(s => s.scoreMin)), scoreSum: sum(stats.map(s => s.scoreSum)), scoreSumSquares: sum(stats.map(s => s.scoreSumSquares)), featureCount: sum(stats.map(s => s.featureCount)), basesCovered: sum(stats.map(s => s.basesCovered)), ...(meanMins.length > 0 ? { scoreMeanMin: min(meanMins) } : {}), ...(meanMaxs.length > 0 ? { scoreMeanMax: max(meanMaxs) } : {}), }); } export function sampleFeaturesForInterval(region, interval, getFeatures, opts) { const { start, end } = region; const sampleCenter = start * 0.75 + end * 0.25; return firstValueFrom(getFeatures({ ...region, start: Math.max(0, Math.round(sampleCenter - interval / 2)), end: Math.min(Math.round(sampleCenter + interval / 2), end), }, opts).pipe(toArray())); } export async function calculateFeatureDensityStats(region, getFeatures, opts) { const refLen = region.end - region.start; let interval = DENSITY_SAMPLE_INITIAL_INTERVAL; let expansionTime = 0; let lastTime = performance.now(); while (true) { const features = await sampleFeaturesForInterval(region, interval, getFeatures, opts); const featureCount = features.length; if (featureCount >= DENSITY_SAMPLE_MIN_FEATURES || interval * 2 > refLen) { return { featureDensity: featureCount / interval }; } if (expansionTime > DENSITY_SAMPLE_TIMEOUT_MS) { console.warn("Stats estimation reached timeout, or didn't get enough features"); return { featureDensity: Number.POSITIVE_INFINITY }; } const currTime = performance.now(); expansionTime += currTime - lastTime; lastTime = currTime; interval *= 2; } } export { blankStats } from "../../util/stats.js";