@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
79 lines (78 loc) • 2.42 kB
JavaScript
import { firstValueFrom } from 'rxjs';
import { reduce } from 'rxjs/operators';
export function calcStdFromSums(sum, sumSquares, n, population = false) {
if (n === 0) {
return 0;
}
let variance;
if (population) {
variance = sumSquares / n - (sum * sum) / (n * n);
}
else {
variance = sumSquares - (sum * sum) / n;
if (n > 1) {
variance /= n - 1;
}
}
return variance < 0 ? 0 : Math.sqrt(variance);
}
export function rectifyStats(s) {
return {
...s,
scoreMean: (s.scoreSum || 0) / (s.featureCount || s.basesCovered || 1),
scoreStdDev: calcStdFromSums(s.scoreSum, s.scoreSumSquares, s.featureCount || s.basesCovered),
featureDensity: (s.featureCount || 1) / s.basesCovered,
};
}
export async function scoresToStats(region, feats) {
const { start, end } = region;
const seed = {
scoreMin: Number.MAX_VALUE,
scoreMax: Number.MIN_VALUE,
scoreMeanMin: Number.MAX_VALUE,
scoreMeanMax: Number.MIN_VALUE,
scoreSum: 0,
scoreSumSquares: 0,
featureCount: 0,
};
let found = false;
const { scoreMin, scoreMax, scoreMeanMin, scoreMeanMax, scoreSum, scoreSumSquares, featureCount, } = await firstValueFrom(feats.pipe(reduce((acc, f) => {
const s = f.get('score');
const summary = f.get('summary');
const { scoreMax, scoreMin } = acc;
acc.scoreMax = Math.max(scoreMax, summary ? f.get('maxScore') : s);
acc.scoreMin = Math.min(scoreMin, summary ? f.get('minScore') : s);
acc.scoreMeanMin = Math.min(acc.scoreMeanMin, s);
acc.scoreMeanMax = Math.max(acc.scoreMeanMax, s);
acc.scoreSum += s;
acc.scoreSumSquares += s * s;
acc.featureCount += 1;
found = true;
return acc;
}, seed)));
return found
? rectifyStats({
scoreMax,
scoreMin,
scoreMeanMin,
scoreMeanMax,
scoreSum,
scoreSumSquares,
featureCount,
basesCovered: end - start + 1,
})
: blankStats();
}
export function blankStats() {
return {
scoreMin: 0,
scoreMax: 0,
scoreMean: 0,
scoreStdDev: 0,
scoreSum: 0,
scoreSumSquares: 0,
featureCount: 0,
featureDensity: 0,
basesCovered: 0,
};
}