Commit a8b53164 authored by Mikaël Salson's avatar Mikaël Salson
Browse files

Merge branch 'feature-c/1943-correlate-clones' into 'dev'

Feature c/1943 correlate clones

See merge request !198
parents cee6249a 6cb590bd
Pipeline #29004 passed with stages
in 54 seconds
......@@ -699,6 +699,20 @@ Clone.prototype = {
}, //end getSize
/* return a list of read numbers (sum of all reads of clustered clones) for all samples
* */
getReadsAllSamples: function (f) {
if (typeof(f) == 'undefined')
f = function (x) { return x }
var time_length = this.m.samples.order.length
var reads = []
for (var t = 0; t < time_length; t++) reads.push(f(this.getReads(t))) ;
return reads;
},
/**
* @param: A variable number of arguments which consists of property names that should be found in seg.
* @return true iff all of the property are found in seg.
......@@ -1125,6 +1139,9 @@ Clone.prototype = {
} else {
html = "<h2>Sequence info : " + this.getSequenceName() + "</h2>"
}
html += "<p>select <a class='button' onclick='m.selectCorrelated(" + this.index + ", 0.90); m.closeInfoBox();'>correlated</a> clones</p>"
html += "<p>select <a class='button' onclick='m.selectCorrelated(" + this.index + ", 0.99); m.closeInfoBox();'>strongly correlated</a> clones</p>"
//column
html += "<div id='info_window'><table><tr><th></th>"
......
......@@ -870,6 +870,28 @@ changeAlleleNotation: function(alleleNotation) {
}
this.updateStyle();
},
/**
* select clones correlated to a given clone
* @param {integer} - cloneID - index of the reference clone
*/
selectCorrelated: function(ref, threshold) {
if (typeof threshold === "undefined") {
threshold = 0.95
}
refReads = this.clone(ref).getReadsAllSamples(logadd1)
for (var i=0; i<this.clones.length; i++){
var clone = this.clone(i);
var coeff = pearsonCoeff(refReads, clone.getReadsAllSamples(logadd1))
clone.select = (Math.abs(coeff) > threshold)
}
this.updateStyle();
},
/**
* put a list of clones in the selection
......
......@@ -398,3 +398,33 @@ function warnTextOf(key)
{
return (key in warnTexts) ? warnTexts[key] : '?'
}
/**
* Pearson correlation coefficient
*/
function sum(l) {
return l.reduce(function(a, b) { return a + b; }, 0);
}
function square(x) { return x*x ; }
function pearsonCoeff(l1, l2) {
var sum1 = sum(l1);
var sum2 = sum(l2);
var sum1sq = sum(l1.map(square))
var sum2sq = sum(l2.map(square))
var sum12 = 0;
for (var i=0, n=l1.length; i < n; i++) { sum12 += l1[i] * l2[i] ; }
var d = (n*sum1sq - sum1*sum1) * (n*sum2sq - sum2*sum2)
if (d == 0) return 0
return (n*sum12 - sum1*sum2) / Math.sqrt(d)
}
function logadd1(x) { return Math.log(x + 1) ; }
......@@ -170,10 +170,13 @@ QUnit.test("name, informations, getHtmlInfo", function(assert) {
assert.equal(c1.getSequenceSize(), "0.05", "clone c1 size : 0.05");
assert.equal(c1.getNumberNonZeroSamples(), 4, "clustered clone c1, getNumberNonZeroSamples");
assert.deepEqual(c1.getReadsAllSamples(), [20, 20, 30, 30], "cluster c1+c2 reads on all samples");
console.log(m.samples.order);
html = m.clones[0].getHtmlInfo();
assert.includes(html, "<h2>Cluster info : hello</h2><div id='info_window'><table><tr><th></th><td>Diag</td><td>Fu-1</td><td>Fu-2</td><td>Fu-3</td></tr>",
assert.includes(html, "<h2>Cluster info : hello</h2>")
assert.includes(html, "<div id='info_window'><table><tr><th></th><td>Diag</td><td>Fu-1</td><td>Fu-2</td><td>Fu-3</td></tr>",
"getHtmlInfo: cluster info");
assert.includes(html, "<tr><td>clone name</td><td colspan='4'>hello</td></tr><tr><td>clone short name</td><td colspan='4'>hello</td></tr>",
......
......@@ -106,7 +106,7 @@ json_data = {
"name": "test4",
"germline": "TRG",
"top": 4,
"reads": [5, 5, 5, 5],
"reads": [5, 5, 5, 50],
"seg": {
"3": "TRGJ2*02",
"5": "TRGV4*01",
......@@ -213,8 +213,8 @@ json_data = {
{
"sequence" : "catcatcatgatgctacgatcttac",
"name" : "test5",
"id" : "catgat",
"reads" : [4,4,4,4],
"id" : "id5",
"reads" : [4,4,4,40],
"top" : 5,
"name": "unseg sequence",
"germline" : "IGH",
......
......@@ -53,13 +53,13 @@ QUnit.test("sort", function(assert) {
var clone_list = document.getElementById('list').lastChild.childNodes
list.sortListBy(function(id){return m.clone(id).getSize()});
assert.notEqual(clone_list[0].innerHTML.indexOf("IGH smaller"), -1, "sortBySize: Ok");
assert.notEqual(clone_list[1].innerHTML.indexOf("TRG smaller"), -1, "sortBySize: Ok");
assert.notEqual(clone_list[2].innerHTML.indexOf("test1"), -1, "sortBySize: Ok");
assert.notEqual(clone_list[3].innerHTML.indexOf("test2"), -1, "sortBySize: Ok");
assert.notEqual(clone_list[4].innerHTML.indexOf("test4"), -1, "sortBySize: Ok");
assert.notEqual(clone_list[5].innerHTML.indexOf("unseg sequence"), -1, "sortBySize: Ok");
assert.notEqual(clone_list[6].innerHTML.indexOf("test3"), -1, "sortBySize: Ok");
assert.notEqual(clone_list[4].innerHTML.indexOf("IGH smaller"), -1, "sortBySize, IGH smaller");
assert.notEqual(clone_list[6].innerHTML.indexOf("TRG smaller"), -1, "sortBySize, TRG smaller");
assert.notEqual(clone_list[2].innerHTML.indexOf("test1"), -1, "sortBySize, test1");
assert.notEqual(clone_list[3].innerHTML.indexOf("test2"), -1, "sortBySize, test2");
assert.notEqual(clone_list[0].innerHTML.indexOf("test4"), -1, "sortBySize, test4");
assert.notEqual(clone_list[1].innerHTML.indexOf("unseg sequence"), -1, "sortBySize, unseg sequence");
assert.notEqual(clone_list[5].innerHTML.indexOf("test3"), -1, "sortBySize, test3");
list.sortListByV();
assert.notEqual(clone_list[0].innerHTML.indexOf("test3"), -1, "sortByV: Ok");
......
......@@ -161,6 +161,27 @@ QUnit.test("select/focus", function(assert) {
});
QUnit.test("correlate", function(assert) {
var m = new Model();
m.parseJsonData(json_data,100)
assert.equal(m.clone(0).id, 'id1')
assert.equal(m.clone(1).id, 'id2')
assert.equal(m.clone(2).id, 'id3')
assert.equal(m.clone(3).id, 'id4')
assert.equal(m.clone(4).id, 'id5')
m.selectCorrelated(4, 0.99)
assert.deepEqual(m.getSelected(), [3, 4], "Clone 3 is strongly correlated to clone 4");
m.selectCorrelated(4)
assert.deepEqual(m.getSelected(), [2, 3, 4], "Clones 2 and 3 are correlated to clone 4");
m.selectCorrelated(0, 0.99)
assert.deepEqual(m.getSelected(), [0, 1], "Clone 1 strongly (negatively) correlated to clone 0");
})
QUnit.test("focus/hide/reset_filter", function(assert) {
var m = new Model();
......
......@@ -39,7 +39,7 @@ QUnit.test("segmenter", function(assert) {
m.unselectAll();
//
assert.deepEqual(segment.findPotentialField(), ["","cdr3","fr1", "5", "id", "f1", "V-REGION","J-REGION","D-REGION","CDR3-IMGT"], "potentialField : Ok")
assert.deepEqual(segment.findPotentialField(), ["","cdr3","fr1", "5", "f1", "V-REGION","J-REGION","D-REGION","CDR3-IMGT"], "potentialField : Ok")
m.select(0)
// assert.deepEqual(segment.toFasta(), "> test1 // 5.000%\naaaaaaaaaaaaaaaaaaaAG\n","toFasta :Ok")
......@@ -140,7 +140,7 @@ QUnit.test("segt", function (assert) {
assert.ok(segment.isDNA('CACCCAGGAGGTGGAGCTGGATATTGAGACT'), "test dna")
assert.ok(segment.isAA('CACCCAGGAGGTGGAGCTGGATATTGAGACT'), "test AA")
assert.ok(segment.isPos(h), "test if an object contain pos")
assert.deepEqual(segment.findPotentialField(),["", "cdr3", "fr1", "5", "test_feature", "id", "f1", "V-REGION", "J-REGION", "D-REGION", "CDR3-IMGT"], "find field to highlight")
assert.deepEqual(segment.findPotentialField(),["", "cdr3", "fr1", "5", "test_feature", "f1", "V-REGION", "J-REGION", "D-REGION", "CDR3-IMGT"], "find field to highlight")
})
......
......@@ -205,3 +205,17 @@ QUnit.test("computeStartStop(arrayToProcess,sequence)", function(assert) {
}
);
QUnit.test("Pearson coefficient", function(assert) {
assert.equal(pearsonCoeff([0, 1, 2, 3], [0, 1, 2, 3]), 1)
assert.equal(pearsonCoeff([0, 1, 2, 3], [40, 50, 60, 70]), 1)
assert.ok(pearsonCoeff([0, 1, 2, 3], [41, 49, 68, 69]) > .9)
assert.ok(pearsonCoeff([0, 1, 2, 3], [49, 30, 1, 102]) < .5)
assert.equal(pearsonCoeff([3, 2, 1], [1, 2, 3]), -1)
assert.equal(pearsonCoeff([3, 2, 1], [10, 20, 30]), -1)
}
);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment