Skip to content

Commit

Permalink
Unifrac tested (#123)
Browse files Browse the repository at this point in the history
* Added unifrac calculation and small tests

* Added large test from biocore/unifrac

* Added large test from biocore/unifrac

* fix travis error

* Default to 0 for unspecified branch length

* Fix style

* Update empress/support_files/js/summary-helper.js

Co-Authored-By: Yoshiki Vázquez Baeza <[email protected]>

* Ported all unweighted unifrac tests from scikit-bio

* minor comments error

* Remove maxDiff, add comments, fix test names
  • Loading branch information
YimengYang authored and ElDeveloper committed Nov 14, 2019
1 parent d97e4bc commit 98e1765
Show file tree
Hide file tree
Showing 4 changed files with 444 additions and 7 deletions.
21 changes: 20 additions & 1 deletion empress/support_files/js/biom-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ define([], function() {
this._samp = samp;
}

/**
* Returns a list of observations in the sample
* Example: countArray is [1,0], obsIDs is ['OTU1', 'OTU2'] => returns ['OTU1']
*
* @param {Array} countArray - Array of counts for different tips
* @param {Array} obsIDs - Array of observation IDs for each index of the countArray
*
* @return {Array}
*/
BIOMTable.convertToObs = function(countArray, obsIDs) {
var obs = [];
for (var i = 0; i < countArray.length; i++) {
if (countArray[i] != 0) {
obs.push(obsIDs[i]);
}
}
return obs;
};

/**
* Returns a list of observations in the samples
*
Expand All @@ -51,7 +70,7 @@ define([], function() {
var obs = this._obs[sIds[i]];
obs.forEach(addToResult);
}
return Array(result);
return Array.from(result);
};

/**
Expand Down
67 changes: 67 additions & 0 deletions empress/support_files/js/summary-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
define([], function() {
/**
* @class SummaryHelper
* Class functions for generating summary used in empress
*/
function SummaryHelper() {}

/**
* Returns unifrac value for 2 sets of sample IDs given a biom table
* @param {BiomTable} biomTable - biom table that contains info about samples
* @param {BPTree} tree - bp tree
* @param {Array} sIds1 - First array of sample IDs to calculate unifrac for
* @param {Array} sIds2 - Second array of sample IDs to calculate unifrac for
*
* @return{Number}
*/
SummaryHelper.unifrac = function(biomTable, tree, sIds1, sIds2) {
var uniq = 0;
var total = 0;
var uniqObs1 = biomTable.getObjservationUnionForSamples(sIds1);
var uniqObs2 = biomTable.getObjservationUnionForSamples(sIds2);

// Elements are in postorder with first element at index 0
// To keep track of if the node is in the sample1
var count1 = new Uint8Array(tree.names_.length);
// To keep track of if the node is in the sample2
var count2 = new Uint8Array(tree.names_.length);

// Based on the info in count1 and count2, calculate branch length
// Some optimization can be done, maybe perform the operation on the arrays
for (var i = 1; i < tree.size; i++) {
var treeIndex = tree.postorderselect(i);
var node = tree.name(treeIndex);

// If the node is leaf, check if it is in the union for sample
if (tree.isleaf(treeIndex)) {
count1[i - 1] = uniqObs1.includes(node);
count2[i - 1] = uniqObs2.includes(node);
}

// Update parent status
var parentPostOrder = tree.postorder(tree.parent(treeIndex));
count1[parentPostOrder - 1] |= count1[i - 1];
count2[parentPostOrder - 1] |= count2[i - 1];

var branchLength = tree.length(treeIndex);
if (branchLength) {
// Unique branch
if (count1[i - 1] ^ count2[i - 1]) {
uniq += branchLength;
}
// The branch belongs to either or both samples
if (count1[i - 1] || count2[i - 1]) {
total += branchLength;
}
}
}

console.log(count1);
console.log(count2);
console.log(uniq);
console.log(total);
return total == 0 ? 0 : uniq / total;
};

return SummaryHelper;
});
16 changes: 10 additions & 6 deletions tests/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,31 @@
'BPTree' : './support_files/js/bp-tree',
'Camera' : './support_files/js/camera',
'Colorer' : './support_files/js/colorer',
'BiomTable': './support_files/js/biom-table',
'SummaryHelper': './support_files/js/summary-helper',

/* test paths */
'testBPTree' : './../tests/test-bp-tree',
'testByteTree' : './../tests/test-byte-array',
'testCamera' : './../tests/test-camera'
'testCamera' : './../tests/test-camera',
'testSummaryHelper': './../tests/test-summary-helper'
}
});

// load tests
require(
['jquery', 'glMatrix', 'ByteArray', 'BPTree', 'Camera', 'testBPTree',
'testByteTree', 'testCamera'],
['jquery', 'glMatrix', 'ByteArray', 'BPTree', 'Camera',
'BiomTable', 'SummaryHelper', 'testBPTree', 'testByteTree', 'testCamera',
'testSummaryHelper'],

// start tests
function ($, gl, ByteArray, BPTree, Camera,testBPTree, testByteTree,
testCamera) {
function ($, gl, ByteArray, BPTree, Camera, BiomTable, SummaryHelper,
testBPTree, testByteTree, testCamera, testSummaryHelper) {
$(document).ready(function() {
QUnit.start();
});

});
</script>
</body>
</html>
</html>
Loading

0 comments on commit 98e1765

Please sign in to comment.