@gmod/jbrowse
Version:
JBrowse - client-side genome browser
129 lines (110 loc) • 3.8 kB
JavaScript
define( [
'dojo/_base/declare',
'dojo/_base/array',
'dojo/Deferred',
'JBrowse/has',
'JBrowse/Util',
'JBrowse/Errors',
'JBrowse/Model/SimpleFeature'
],
function(
declare,
array,
Deferred,
has,
Util,
Errors,
SimpleFeature
) {
return declare( null,
{
constructor: function( args ) {
this.store = args.store;
this.data = args.data;
this.features = {};
this.refseqs = [];
},
init: function( args ) {
var fasta = this.data;
var thisB = this;
var successCallback = args.success || function() {};
var failCallback = args.failure || function(e) { console.error(e, e.stack); };
this.parseFile( fasta, function(data) {
array.forEach( data, function(rs) {
thisB.features[rs.name] = {
seq_id: rs.name,
name: rs.name,
start: 0,
end: rs.seq.length,
seq: rs.seq
};
thisB.refseqs.push({
name: rs.name,
start: 0,
end: rs.seq.length,
length: rs.seq.length
});
});
successCallback();
}, failCallback );
},
fetch: function(chr, min, max, featCallback, endCallback, errorCallback ) {
errorCallback = errorCallback || function(e) { console.error(e); };
var refname = chr;
if( ! this.store.browser.compareReferenceNames( chr, refname ) ) {
refname = chr;
}
featCallback(new SimpleFeature({
data: {
start: this.features[refname].start,
end: this.features[refname].end,
residues: this.features[refname].seq,
seq_id: refname,
name: refname
}
}));
endCallback();
},
parseFile: function(fastaFile, successCallback, failCallback ) {
this.data.fetch( dojo.hitch( this, function(text) {
var fastaString = "";
var bytes = new Uint8Array(text);
var length = bytes.length;
for (var i = 0; i < length; i++) {
fastaString += String.fromCharCode(bytes[i]);
}
if (!(fastaString && fastaString.length))
failCallback ("Could not read file: " + fastaFile.name);
else {
var data = this.parseString (fastaString);
if (!data.length)
failCallback ("File contained no (FASTA) sequences");
else
successCallback(data);
}
}), failCallback );
},
parseString: function(fastaString) {
var data = [];
var addSeq = function (s) {
if ("name" in s && s.seq.length) // ignore empty sequences
data.push (s);
};
var current = { seq: "" };
var lines = fastaString.match(/^.*((\r\n|\n|\r)|$)/gm); // this is wasteful, maybe try to avoid storing split lines separately later
for (var i = 0; i < lines.length; i++) {
var m;
if (m = /^>(\S*)/.exec(lines[i])) {
addSeq (current);
current = { seq: "" };
if (m[1].length)
current.name = m[1];
} else if (m = /^\s*(\S+)\s*$/.exec(lines[i])) {
current.seq += m[1];
}
}
addSeq (current);
return data;
}
});
});