+
@@ -565,14 +569,35 @@
Sequence Settings
});
}
- async function readFastas() {
- const fastas = session.files.filter(f => f.extension.includes('fas'));
+ function sequenceFormat(contents) {
+ if (contents.match(/^\s*#mega$/im)) {
+ return "MEGA";
+ } else if (contents.match(/^\s*>/m)) {
+ return "FASTA";
+ } else {
+ return "UNKNOWN";
+ }
+ }
+
+ async function readSequences() {
+ const seqs = session.files.filter(f => f.extension.includes('fas') | f.extension.includes('meg'));
const nodeCSVsWithSeqs = session.files.filter(f => f.format == "node" && f.field2 != "None" && f.field2 != "");
- if (fastas.length == 0 && nodeCSVsWithSeqs.length == 0) return [];
+ if (seqs.length == 0 && nodeCSVsWithSeqs.length == 0) return [];
let data = [];
- for(let i = 0; i < fastas.length; i++){
- let fasta = fastas[i];
- let nodes = await MT.parseFASTA(fasta.contents);
+ for(let i = 0; i < seqs.length; i++){
+ let seq = seqs[i];
+ let nodes = [];
+
+ switch (sequenceFormat(seq.contents)) {
+ case "MEGA":
+ nodes = await MT.parseMEGA(seq.contents);
+ break;
+ case "FASTA":
+ nodes = await MT.parseFASTA(seq.contents);
+ break;
+ default:
+ }
+
data = data.concat(nodes);
}
// TODO: Cannot presently preview sequences in Node CSV/XLSX tables.
@@ -648,14 +673,29 @@
Sequence Settings
let reader = new FileReader();
reader.onloadend = e => {
if (e.target.readyState == FileReader.DONE) {
- MT.parseFASTA(e.target.result).then(nodes => {
- $('#refSeqID')
- .html(nodes.map((d, i) => `
-
- `))
- .trigger('change');
- });
- $('label[for="refSeqFileLoad"]').text(filterXSS(file.name));
+ switch (sequenceFormat(e.target.result)) {
+ case "MEGA":
+ MT.parseMEGA(e.target.result).then(nodes => {
+ $('#refSeqID')
+ .html(nodes.map((d, i) => `
+
+ `))
+ .trigger('change');
+ });
+ $('label[for="refSeqFileLoad"]').text(filterXSS(file.name));
+ break;
+ case "FASTA":
+ MT.parseFASTA(e.target.result).then(nodes => {
+ $('#refSeqID')
+ .html(nodes.map((d, i) => `
+
+ `))
+ .trigger('change');
+ });
+ $('label[for="refSeqFileLoad"]').text(filterXSS(file.name));
+ break;
+ default:
+ }
}
};
reader.readAsText(file);
@@ -667,7 +707,7 @@
Sequence Settings
`).on('change', function(){ session.data.reference = this.value; });
$('#sequenceControlsButton, #alignment-preview').on('click', () => {
- readFastas().then(data => {
+ readSequences().then(data => {
if(session.style.widgets['reference-source-first']){
session.data.reference = nodes[0].seq;
}
@@ -698,7 +738,7 @@
Sequence Settings
};
$('#audit-launcher').on('click', () => {
- readFastas().then(data => {
+ readSequences().then(data => {
const start = Date.now();
const isGaps = /^-+$/;
const isRNA = /^[ACGURYMKWSBDHVN-]+$/;
@@ -856,10 +896,10 @@
Sequence Settings
const nFiles = session.files.length - 1;
const check = nFiles > 0;
- const hierarchy = ['newick', 'matrix', 'link', 'node', 'fasta'];
+ const hierarchy = ['newick', 'matrix', 'link', 'node', 'fasta', 'mega'];
session.files.sort((a, b) => hierarchy.indexOf(a.format) - hierarchy.indexOf(b.format));
- session.meta.anySequences = session.files.some(file => (file.format == "fasta") || (file.format == "node" && file.field2 !== "None"));
+ session.meta.anySequences = session.files.some(file => (file.format == "fasta") || (file.format == "mega") || (file.format == "node" && file.field2 !== "None"));
session.files.forEach((file, fileNum) => {
const start = Date.now();
@@ -885,6 +925,26 @@
Sequence Settings
if (fileNum == nFiles) processSequences();
});
+ } else if (file.format == 'mega') {
+
+ message(`Parsing ${file.name} as MEGA...`);
+ let newNodes = 0;
+ MT.parseMEGA(file.contents).then(seqs => {
+ const n = seqs.length;
+ for (let i = 0; i < n; i++) {
+ let node = seqs[i];
+ if (!node) continue;
+ newNodes += MT.addNode({
+ _id: filterXSS(node.id),
+ seq: filterXSS(node.seq),
+ origin: origin
+ }, check);
+ }
+ console.log('MEGA Merge time:', (Date.now() - start).toLocaleString(), 'ms');
+ message(` - Parsed ${newNodes} New, ${seqs.length} Total Nodes from MEGA.`);
+ if (fileNum == nFiles) processSequences();
+ });
+
} else if (file.format == 'link') {
message(`Parsing ${file.name} as Link List...`);
diff --git a/workers/parse-mega.js b/workers/parse-mega.js
index b690b125..6f1c7759 100644
--- a/workers/parse-mega.js
+++ b/workers/parse-mega.js
@@ -7,18 +7,36 @@ onmessage = function (e) {
let seqs = [], currentSeq = {};
let lines = text.split(/[\r\n]+/g);
let n = lines.length;
+ let header = true;
+ let firstSeq = true;
for (let i = 0; i < n; i++) {
let line = lines[i];
- if (isblank.test(line) || line[0] == ';') continue;
- if (line[0] == '#') {
- if (i > 0) seqs.push(currentSeq);
- currentSeq = {
- id: line.slice(1),
- seq: '#'
- };
- } else {
- currentSeq.seq += line.toUpperCase();
+ if (isblank.test(line)) continue;
+
+ if (header && line.match(/^title/i)) {
+ header = false;
+ continue;
+ }
+
+ if (!header) {
+ if (line[0] == "#") {
+
+ if (!firstSeq)
+ seqs.push(currentSeq);
+ else
+ firstSeq = false;
+
+ currentSeq = {
+ id: line.slice(1),
+ seq: '#'
+ };
+
+ } else {
+ currentSeq.seq += line.toUpperCase();
+ }
}
+
+
}
seqs.push(currentSeq);
console.log('MEGA Parse time: ', (Date.now() - start).toLocaleString(), 'ms');