Published
Edited
Feb 3, 2022
Importers
2 stars
Insert cell
Insert cell
esearch = async function* (options, doFetch = false) {
yield { loading: true, data: null, error: null, detail: null };

const body = new URLSearchParams();
body.set("db", "nuccore");
body.set("retmode", "json");
body.set("retmax", "0");
body.set("usehistory", "y");

for (const key in options) {
body.set(key, options[key]);
}

const response = await fetch(
"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi",
{ method: "POST", body }
);

const { esearchresult } = await response.json();

if (doFetch) {
for await (const result of efetch(esearchresult)) {
yield result;
}
} else {
yield {
loading: false,
data: esearchresult,
error: null,
detail: null
};
}
}
Insert cell
efetch = async function* (esearchresult) {
const url = new URL(
"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
);
url.searchParams.set("db", "nuccore");
url.searchParams.set("retmode", "text");
url.searchParams.set("rettype", "fasta");
url.searchParams.set("retstart", "0");
url.searchParams.set("retmax", "10000");
url.searchParams.set("webenv", esearchresult.webenv);
url.searchParams.set("query_key", esearchresult.querykey);

const response = await fetch(url);

const data = await response.text();

yield {
loading: false,
data,
error: null,
detail: esearchresult
};
}
Insert cell
blast = async function* (query, subjects) {
if (!subjects) return null;

yield {
loading: true,
data: null,
error: null,
detail: null
};

const alignURL = new URL(
"https://blast.ncbi.nlm.nih.gov/blast/BlastAlign.cgi"
);

const body = new FormData();
body.set("CMD", "Put");
body.set("PROGRAM", "blastn");
body.set("DATABASE", "nr");
body.set("MAX_NUM_SEQ", "5000");
body.set("QUERY", query);
body.set("SUBJECTS", subjects);

const response = await fetch(alignURL, { method: "POST", body });
const html = await response.text();
const doc = new DOMParser().parseFromString(html, "text/html");
const rid = doc.querySelector('input[name="RID"]').value;

yield {
loading: true,
data: null,
error: null,
detail: { rid }
};

const url = new URL("https://blast.ncbi.nlm.nih.gov/Blast.cgi");
url.searchParams.set("CMD", "Get");
url.searchParams.set("FORMAT_OBJECT", "Alignment");
url.searchParams.set("FORMAT_TYPE", "JSON2_S");
url.searchParams.set("RID", rid);

let tries = 0;
do {
const response = await fetch(url);
if (response.ok && response.headers.get("Content-Type").includes("json")) {
const data = await response.json();

yield {
loading: false,
data,
error: null,
detail: { rid }
};

break;
}

await new Promise((resolve) => setTimeout(resolve, 5000));
} while (++tries < 100);
}
Insert cell
parseBlastResults = (data) => {
if (!data) return null;

return data.BlastOutput2[0].report.results.bl2seq
.filter((item) => item.hits && item.hits.length > 0)
.map((item) => {
const [hit] = item.hits;
const [hsp] = hit.hsps;
const [{ title }] = hit.description;

const ticks = new Set();
for (const hsp of hit.hsps) {
if (hsp.query_strand === "Plus" && hsp.hit_strand === "Plus") {
for (const [i, match] of hsp.midline.split("").entries()) {
if (match === "|") {
ticks.add(hsp.query_from + i);
}
}
}
}

// const from = hsp.query_from - hsp.hit_from;
// const to = from + hit.len;
const from = hsp.query_from;
const to = hsp.query_to;
const size = to - from;
const identity = (ticks.size / hit.len) * 100;

return {
from,
// to: hsp.query_to,
to,
size,
identity,
title,
ticks: [...ticks].sort((a, b) => a - b)
};
});
}
Insert cell
plotHits = (hits, options = {}) => {
{
if (!hits) return null;

const ticks = hits
.map((hit) => hit.ticks.map((tick) => [hit.title, tick]))
.flat();

return Plot.plot({
marginLeft: options.marginLeft || 350,
marginRight: 50,
width: 1200,
height: options.height,
x: {
domain: options.domain
},
marks: [
Plot.barX(ticks, {
x1: (d) => d[1],
x2: (d) => d[1] + 1,
y: (d) => d[0],
fill: "#777"
// mixBlendMode: "multiply"
})
]
});
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more