taxonium-component
Version:
React component for exploring large phylogenetic trees in the browser
247 lines (246 loc) • 8.37 kB
JavaScript
import { B as E } from "./index-CpJXUZUB.js";
import { r as F } from "./rxjs-L4bS73F7.js";
import { S as k } from "./simpleFeature-DimH8SQV.js";
import { u as A, bs as O, O as $, bN as N, $ as P, a0 as R } from "./JBrowsePanel-BNE3gNW1.js";
import { g as T, a as B } from "./getMethBins-CvqMYb7k.js";
function I({ feature: s, bins: e, region: t }) {
const o = s.get("start"), r = s.get("end"), n = s.get("strand"), d = t.end - t.start;
for (let i = o; i < r + 1; i++) {
const c = i - t.start;
c >= 0 && c < d && (e[c] === void 0 && (e[c] = {
depth: 0,
readsCounted: 0,
ref: {
probabilities: [],
entryDepth: 0,
"-1": 0,
0: 0,
1: 0
},
snps: {},
mods: {},
nonmods: {},
delskips: {},
noncov: {}
}), i !== r && (e[c].depth++, e[c].readsCounted++, e[c].ref.entryDepth++, e[c].ref[n]++));
}
}
function L(s) {
return q(s.type) ? 1 : s.length;
}
function q(s) {
return s === "softclip" || s === "hardclip" || s === "insertion";
}
function x(s, e, t, o) {
let r = s[t][o];
r === void 0 && (r = s[t][o] = {
entryDepth: 0,
probabilities: [],
"-1": 0,
0: 0,
1: 0
}), r.entryDepth++, r[e]++;
}
function D(s, e, t, o, r) {
let n = s[t][o];
n === void 0 && (n = s[t][o] = {
entryDepth: 0,
probabilities: [],
"-1": 0,
0: 0,
1: 0
}), n.entryDepth++, n.probabilities.push(r), n[e]++;
}
function G({ feature: s, region: e, bins: t, skipmap: o }) {
var r;
const n = s.get("start"), d = s.get("strand"), i = (r = s.get("mismatches")) !== null && r !== void 0 ? r : [];
for (const c of i) {
const p = n + c.start, l = L(c), h = p + l;
for (let a = p; a < p + l; a++) {
const f = a - e.start;
if (f >= 0 && f < t.length) {
const b = t[f], { base: u, altbase: m, type: g } = c, S = q(g);
g === "deletion" || g === "skip" ? (x(b, d, "delskips", g), b.depth--) : S ? x(b, d, "noncov", g) : (x(b, d, "snps", u), b.ref.entryDepth--, b.ref[d]--, b.refbase = m);
}
}
if (c.type === "skip") {
const a = s.get("tags"), f = (a == null ? void 0 : a.XS) || (a == null ? void 0 : a.TS), b = a == null ? void 0 : a.ts, u = f === "+" ? 1 : f === "-" ? -1 : (b === "+" ? 1 : f === "-" ? -1 : 0) * d, m = `${p}_${h}_${u}`;
o[m] === void 0 && (o[m] = {
feature: s,
start: p,
end: h,
strand: d,
effectiveStrand: u,
score: 0
}), o[m].score++;
}
}
}
function V({ feature: s, colorBy: e, region: t, bins: o, regionSequence: r }) {
var n, d, i;
const c = s.get("start"), p = s.get("strand"), l = s.get("end"), h = (n = e == null ? void 0 : e.modifications) === null || n === void 0 ? void 0 : n.twoColor, a = (d = e == null ? void 0 : e.modifications) === null || d === void 0 ? void 0 : d.isolatedModification;
(i = T(s)) === null || i === void 0 || i.forEach(({ allProbs: f, prob: b, type: u }, m) => {
if (a && u !== a)
return;
const g = m + c - t.start;
if (g >= 0 && g < o.length && m + c < l) {
o[g] === void 0 && (o[g] = {
depth: 0,
readsCounted: 0,
snps: {},
ref: {
probabilities: [],
entryDepth: 0,
"-1": 0,
0: 0,
1: 0
},
mods: {},
nonmods: {},
delskips: {},
noncov: {}
});
const S = 1 - A.sum(f), v = o[g];
v.refbase = r[g], h && S > A.max(f) ? D(v, p, "nonmods", `nonmod_${u}`, S) : D(v, p, "mods", `mod_${u}`, b);
}
m++;
});
}
function W({ feature: s, region: e, bins: t, regionSequence: o }) {
var r;
const n = s.get("start"), d = s.get("end"), i = s.get("strand"), c = s.get("seq"), p = (r = s.get("mismatches")) !== null && r !== void 0 ? r : [], l = o.toLowerCase();
if (c) {
const h = O(s.get("CIGAR")), { methBins: a, methProbs: f } = B(s, h), b = p.filter((u) => u.type === "deletion");
for (let u = 0; u < d - n; u++) {
const m = u + n, g = l[m - e.start + 1], S = l[m - e.start + 2];
if (g === "c" && S === "g") {
const v = t[m - e.start], y = t[m - e.start + 1], M = a[u], j = a[u + 1], C = f[u], _ = f[u + 1];
M && (C === void 0 || C > 0.5) || j && (_ === void 0 || _ > 0.5) ? (v && (D(v, i, "mods", "cpg_meth", C || 0), v.ref.entryDepth--, v.ref[i]--), y && (D(y, i, "mods", "cpg_meth", _ || 0), y.ref.entryDepth--, y.ref[i]--)) : (v && (b.some((w) => A.doesIntersect2(m, m + 1, w.start + n, w.start + n + w.length)) || (D(v, i, "nonmods", "cpg_unmeth", 1 - (C || 0)), v.ref.entryDepth--, v.ref[i]--)), y && (b.some((w) => A.doesIntersect2(m + 1, m + 2, w.start + n, w.start + n + w.length)) || (D(y, i, "nonmods", "cpg_unmeth", 1 - (_ || 0)), y.ref.entryDepth--, y.ref[i]--)));
}
}
}
}
async function X({ fetchSequence: s, features: e, region: t, opts: o }) {
const { stopToken: r, colorBy: n } = o, d = {}, i = [], c = Math.max(0, t.start - 1), p = t.start - c;
let l = performance.now();
for (const h of e) {
if (performance.now() - l > 400 && ($.checkStopToken(r), l = performance.now()), I({
feature: h,
bins: i,
region: t
}), (n == null ? void 0 : n.type) === "modifications") {
const a = await s({
...t,
start: c,
end: t.end + 1
}) || "";
V({
feature: h,
colorBy: n,
bins: i,
region: t,
regionSequence: a.slice(p)
});
} else if ((n == null ? void 0 : n.type) === "methylation") {
const a = await s({
...t,
start: c,
end: t.end + 1
}) || "";
W({
feature: h,
bins: i,
region: t,
regionSequence: a
});
}
G({ feature: h, skipmap: d, bins: i, region: t });
}
for (const h of i)
h && (h.mods = Object.fromEntries(Object.entries(h.mods).map(([a, f]) => [
a,
{
...f,
avgProbability: f.probabilities.length ? A.sum(f.probabilities) / f.probabilities.length : void 0
}
])), h.nonmods = Object.fromEntries(Object.entries(h.nonmods).map(([a, f]) => [
a,
{
...f,
avgProbability: f.probabilities.length ? A.sum(f.probabilities) / f.probabilities.length : void 0
}
])));
return {
bins: i,
skipmap: d
};
}
class U extends E.BaseFeatureDataAdapter {
async configure() {
var e, t;
const o = this.getConf("subadapter"), r = o.sequenceAdapter, n = await ((e = this.getSubAdapter) === null || e === void 0 ? void 0 : e.call(this, o)), d = r ? await ((t = this.getSubAdapter) === null || t === void 0 ? void 0 : t.call(this, r)) : void 0;
if (!n)
throw new Error("Failed to get subadapter");
return {
subadapter: n.dataAdapter,
sequenceAdapter: d == null ? void 0 : d.dataAdapter
};
}
async fetchSequence(e) {
const { sequenceAdapter: t } = await this.configure();
if (t)
return N(e, t);
}
getFeatures(e, t = {}) {
return F.ObservableCreate(async (o) => {
const { subadapter: r } = await this.configure(), n = await P(r.getFeatures(e, t).pipe(R())), { bins: d, skipmap: i } = await X({
features: n,
region: e,
opts: t,
fetchSequence: (p) => this.fetchSequence(p)
});
let c = 0;
for (const p of d) {
if (p) {
const l = e.start + c;
o.next(new k({
id: `${this.id}-${l}`,
data: {
score: p.depth,
snpinfo: p,
start: l,
end: l + 1,
refName: e.refName
}
}));
}
c++;
}
for (const [p, l] of Object.entries(i))
o.next(new k({
id: p,
data: {
type: "skip",
start: l.start,
end: l.end,
strand: l.strand,
score: l.score,
effectiveStrand: l.effectiveStrand
}
}));
o.complete();
}, t.stopToken);
}
async getMultiRegionFeatureDensityStats(e, t) {
const { subadapter: o } = await this.configure();
return o.getMultiRegionFeatureDensityStats(e, t);
}
async getRefNames(e = {}) {
const { subadapter: t } = await this.configure();
return t.getRefNames(e);
}
}
export {
U as default
};
//# sourceMappingURL=SNPCoverageAdapter-B0LRA71f.js.map