Skip to content

Commit

Permalink
move BAM header and index parsing into BAM/File.js
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuels committed Oct 18, 2012
1 parent cff6c38 commit 542e82f
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 97 deletions.
101 changes: 5 additions & 96 deletions src/JBrowse/Store/SeqFeature/BAM.js
Expand Up @@ -12,14 +12,6 @@ define( [
],
function( declare, array, Deferred, lang, Util, SeqFeatureStore, XHRBlob, BAMUtil, BAMFile, BAMFeature ) {

var readInt = BAMUtil.readInt;
var readShort = BAMUtil.readShort;

var BAM_MAGIC = 21840194;
var BAI_MAGIC = 21578050;

var dlog = function(){ console.log.apply(console, arguments); };

var BAMStore = declare( SeqFeatureStore,

/**
Expand Down Expand Up @@ -69,94 +61,11 @@ var BAMStore = declare( SeqFeatureStore,
},

load: function() {
var bam = this.bam;
var bamFetched, baiFetched;
bam.data.slice(0, 65536).fetch( dojo.hitch( this, function(r) {
if (!r) {
dlog("Couldn't access BAM");
return;
}

var unc = BAMUtil.unbgzf(r);
var uncba = new Uint8Array(unc);

var magic = readInt(uncba, 0);
var headLen = readInt(uncba, 4);
var header = '';
for (var i = 0; i < headLen; ++i) {
header += String.fromCharCode(uncba[i + 8]);
}

var nRef = readInt(uncba, headLen + 8);
var p = headLen + 12;

bam.chrToIndex = {};
bam.indexToChr = [];
for (var i = 0; i < nRef; ++i) {
var lName = readInt(uncba, p);
var name = '';
for (var j = 0; j < lName-1; ++j) {
name += String.fromCharCode(uncba[p + 4 + j]);
}
var lRef = readInt(uncba, p + lName + 4);
// dlog(name + ': ' + lRef);
bam.chrToIndex[name] = i;
if (name.indexOf('chr') == 0) {
bam.chrToIndex[name.substring(3)] = i;
} else {
bam.chrToIndex['chr' + name] = i;
}

bam.indexToChr.push(name);

p = p + 8 + lName;
}

if( bam.indices ) {
this._estimateGlobalStats( dojo.hitch( this, 'loadSuccess' ) );
return;
}
}));

bam.bai.fetch( dojo.hitch( this, function(header) { // Do we really need to fetch the whole thing? :-(
if (!header) {
dlog("Couldn't access BAI");
this.loadFail();
return;
}

var uncba = new Uint8Array(header);
var baiMagic = readInt(uncba, 0);
if (baiMagic != BAI_MAGIC) {
dlog('Not a BAI file');
this.loadFail();
return;
}

var nref = readInt(uncba, 4);

bam.indices = [];

var p = 8;
for (var ref = 0; ref < nref; ++ref) {
var blockStart = p;
var nbin = readInt(uncba, p); p += 4;
for (var b = 0; b < nbin; ++b) {
var bin = readInt(uncba, p);
var nchnk = readInt(uncba, p+4);
p += 8 + (nchnk * 16);
}
var nintv = readInt(uncba, p); p += 4;
p += (nintv * 8);
if (nbin > 0) {
bam.indices[ref] = new Uint8Array(header, blockStart, p - blockStart);
}
}
if( bam.chrToIndex ) {
this._estimateGlobalStats( dojo.hitch( this, 'loadSuccess' ) );
return;
}
}));
this.bam.init({
success: dojo.hitch( this, '_estimateGlobalStats',
dojo.hitch( this, 'loadSuccess' )),
failure: dojo.hitch( this, 'loadFail' )
});
},

/**
Expand Down
103 changes: 102 additions & 1 deletion src/JBrowse/Store/SeqFeature/BAM/File.js
Expand Up @@ -5,6 +5,12 @@ define( [
'JBrowse/Store/LRUCache'
],
function( declare, array, BAMUtil, LRUCache ) {

var BAM_MAGIC = 21840194;
var BAI_MAGIC = 21578050;

var dlog = function(){ console.log.apply(console, arguments); };

//
// Binning (transliterated from SAM1.3 spec)
//
Expand Down Expand Up @@ -68,7 +74,7 @@ var Chunk = declare( null, {

var BamRecord = declare( null, {} );

var readInt = BAMUtil.readInt;
var readInt = BAMUtil.readInt;
var readShort = BAMUtil.readInt;

var BamFile = declare( null,
Expand All @@ -88,6 +94,101 @@ var BamFile = declare( null,
*/
constructor: function() {},

init: function( args ) {
var bam = this;
var successCallback = args.success;
var failCallback = args.failure;

var bamFetched, baiFetched;
bam.data.slice(0, 65536).fetch( dojo.hitch( this, function(r) {
if (!r) {
dlog("Couldn't access BAM");
return;
}

var unc = BAMUtil.unbgzf(r);
var uncba = new Uint8Array(unc);

var magic = readInt(uncba, 0);
var headLen = readInt(uncba, 4);
var header = '';
for (var i = 0; i < headLen; ++i) {
header += String.fromCharCode(uncba[i + 8]);
}

var nRef = readInt(uncba, headLen + 8);
var p = headLen + 12;

bam.chrToIndex = {};
bam.indexToChr = [];
for (var i = 0; i < nRef; ++i) {
var lName = readInt(uncba, p);
var name = '';
for (var j = 0; j < lName-1; ++j) {
name += String.fromCharCode(uncba[p + 4 + j]);
}
var lRef = readInt(uncba, p + lName + 4);
// dlog(name + ': ' + lRef);
bam.chrToIndex[name] = i;
if (name.indexOf('chr') == 0) {
bam.chrToIndex[name.substring(3)] = i;
} else {
bam.chrToIndex['chr' + name] = i;
}

bam.indexToChr.push(name);

p = p + 8 + lName;
}

if( bam.indices ) {
successCallback();
return;
}
}));

// Do we really need to fetch the whole thing? :-(
bam.bai.fetch( dojo.hitch( this, function(header) {
if (!header) {
dlog("Couldn't access BAI");
failCallback();
return;
}

var uncba = new Uint8Array(header);
var baiMagic = readInt(uncba, 0);
if (baiMagic != BAI_MAGIC) {
dlog('Not a BAI file');
failCallback();
return;
}

var nref = readInt(uncba, 4);

bam.indices = [];

var p = 8;
for (var ref = 0; ref < nref; ++ref) {
var blockStart = p;
var nbin = readInt(uncba, p); p += 4;
for (var b = 0; b < nbin; ++b) {
var bin = readInt(uncba, p);
var nchnk = readInt(uncba, p+4);
p += 8 + (nchnk * 16);
}
var nintv = readInt(uncba, p); p += 4;
p += (nintv * 8);
if (nbin > 0) {
bam.indices[ref] = new Uint8Array(header, blockStart, p - blockStart);
}
}
if( bam.chrToIndex ) {
successCallback();
return;
}
}));
},

blocksForRange: function(refId, min, max) {
var index = this.indices[refId];
if (!index) {
Expand Down

0 comments on commit 542e82f

Please sign in to comment.