Skip to content

Commit

Permalink
added functional nucleotide density storage classes
Browse files Browse the repository at this point in the history
  • Loading branch information
bhofmei committed Nov 10, 2016
1 parent a340cd5 commit 3e966f7
Show file tree
Hide file tree
Showing 2 changed files with 222 additions and 0 deletions.
114 changes: 114 additions & 0 deletions js/Store/SeqFeature/NucContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
define([
'dojo/_base/declare',
'dojo/_base/array',
'JBrowse/Store/SeqFeature',
'JBrowse/Store/DeferredFeaturesMixin',
'JBrowse/Util',
'NucleotideDensityPlugin/Model/NamedCoverageFeature',
'NucleotideDensityPlugin/Store/Util'
],
function(
declare,
array,
SeqFeatureStore,
DeferredFeaturesMixin,
Util,
CoverageFeature,
StoreUtil
) {
/*
Based on GCContent Plugin
Adapted for nucleotide context and to be used with multitracks
*/
return declare([SeqFeatureStore, DeferredFeaturesMixin], {
constructor: function(args) {
this.store = args.store;
this.refSeq = this.store.refSeq;
this.windowSize = args.windowSize;
this.windowDelta = args.windowDelta;
this.nuc = args.nuc;
this.nucLength = args.nuc.length;
this.nucAr = StoreUtil.getPossibilities(this.nuc);
this._deferred.features.resolve({success: true});
},

_getGlobalStats: function(callback){
return this.getGlobalStats(callback);
},

getGlobalStats: function(callback /* , errorCallback */) {
var s = dojo.mixin(this.stats, {mean: this.stats.sum / this.stats.count});
callback(s);
},

_getFeatures: function(query, featureCallback, finishCallback, errorCallback){
//console.log(query.end-query.start,this.nuc);

this.getFeatures(query, featureCallback, finishCallback, errorCallback);

},

getFeatures: function(query, featureCallback, finishCallback, errorCallback) {
//console.log('getFeatures', this.nuc);
var hw = this.windowSize / 2; // Half the window size
query.start = Math.max(0, query.start - hw);
query.end = Math.min(query.end + hw, this.browser.refSeq.length);
var thisB = this;

if (query.end < 0 || query.start > query.end) {
finishCallback();
return;
}
thisB.stats = {sum: 0, count: 0, min: 5, max: 0};

this.store.getReferenceSequence(query, function(residues) {
//console.log(residues.length);
for (var i = hw; i < residues.length - hw; i += thisB.windowDelta) {

//console.log(thisB.nuc);
var r = residues.slice(i - hw, i + hw);
var rn = r.length - thisB.nucLength;
var nc = 0;
var ng = 0;
for (var j = 0; j < rn; j++) {
/*if (r[j] === 'c' || r[j] === 'C') {
nc++;
} else if (r[j] === 'g' || r[j] === 'G') {
ng++;
}*/
var rs = r.slice(j, j+thisB.nucLength);
if(array.indexOf(thisB.nucAr, rs.toUpperCase()) !== -1)
nc++;
}
var pos = query.start;
var score = nc / rn;

// add to stats
thisB.stats.count++;
thisB.stats.sum += score;
if(score < thisB.stats.min)
thisB.stats.min = score;
if(score > thisB.stats.max)
thisB.stats.max = score;
/*if (thisB.gcMode === 'content') {
score = (ng + nc) / r.length;
} else if (thisB.gcMode === 'skew') {
score = (ng - nc) / (ng + nc);
}*/
var n = thisB.nuc;

var feat = new CoverageFeature({
start: pos + i,
end: pos + i + thisB.windowDelta,
score: score,
name: n
});
featureCallback(feat);
}
finishCallback();
},
finishCallback,
errorCallback);
}
});
});
108 changes: 108 additions & 0 deletions js/Store/SeqFeature/NucContentMulti.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
define([
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/_base/array',
'dojo/promise/all',
'dojo/when',
'JBrowse/Store/SeqFeature',
'JBrowse/Store/DeferredStatsMixin',
'JBrowse/Store/DeferredFeaturesMixin',
'NucleotideDensityPlugin/Store/SeqFeature/NucContent'
],
function(
declare,
lang,
array,
all,
when,
SeqFeatureStore,
DeferredFeaturesMixin,
DeferredStatsMixin,
NucContent
) {
/*
Based on MultiBigWig storage class but adapted for use with nucleotide density
specifically, adapted for storage classes not fetching data from backend
*/
return declare([SeqFeatureStore, DeferredFeaturesMixin, DeferredStatsMixin], {
constructor: function(args) {
var thisB = this;
this.contexts = args.contexts;
this.stores = array.map(args.contexts, function(context) {
return new NucContent(lang.mixin(args, { nuc: context }));
});
//console.log(this.stores);
all(array.map(this.stores, function(store) {
return store._deferred.features;
})).then(function() {
thisB._deferred.features.resolve({success: true});
thisB._deferred.stats.resolve({success: true});
},
lang.hitch(this, '_failAllDeferred'));
},

_getFeatures: function(query, featureCallback, endCallback, errorCallback) {
var thisB = this;
var finished = 0;
var finishCallback = function() {
if (thisB.stores.length === ++finished) {
endCallback();
}
};
array.forEach(thisB.stores, function(store) {
store._getFeatures(lang.clone(query),
featureCallback, finishCallback, errorCallback
);
}, this);
},

_getGlobalStats: function(successCallback, errorCallback) {
// TODO update
var thisB = this;
var finished = 0;
var stats = { scoreMin: 100000000, scoreMax: -10000000 };

var finishCallback = function(t) {
if (t.scoreMin < stats.scoreMin) {
stats.scoreMin = t.scoreMin;
}
if (t.scoreMax > stats.scoreMax) {
stats.scoreMax = t.scoreMax;
}
if (thisB.stores.length === ++finished) {
successCallback(stats);
}
};
array.forEach(this.stores, function(store) {
store._getGlobalStats(finishCallback, errorCallback);
});
},

getRegionStats: function(query, successCallback, errorCallback) {
var thisB = this;
var finished = 0;
var stats = { scoreMin: 100000000, scoreMax: -10000000 };

var finishCallback = function(t) {
if (t.scoreMin < stats.scoreMin) {
stats.scoreMin = t.scoreMin;
}
if (t.scoreMax > stats.scoreMax) {
stats.scoreMax = t.scoreMax;
}
if (thisB.stores.length === ++finished) {
successCallback(stats);
}
};
array.forEach(this.stores, function(store) {
store.getRegionStats(query, finishCallback, errorCallback);
});
},

saveStore: function() {
return {
contexts: this.contexts
};
}
});
});

0 comments on commit 3e966f7

Please sign in to comment.