5 * Created by Sarah Westcott on 1/8/09.
6 * Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
10 #include "sharedchao1.h"
12 /***********************************************************************/
13 EstOutput SharedChao1::getValues(vector<SharedRAbundVector*> shared){
17 int numGroups = shared.size();
18 float Chao = 0.0; float leftvalue, rightvalue;
20 // IntNode is defined in mothur.h
21 // The tree used here is a binary tree used to represent the f1+++, f+1++, f++1+, f+++1, f11++, f1+1+...
22 // combinations required to solve the chao estimator equation for any number of groups. Conceptually, think
23 // of each node as having a 1 and a + value, or for f2 values a 2 and a + value, and 2 pointers to intnodes, and 2 coeffient values.
24 // The coeffient value is how many times you chose branch 1 to get to that fvalue.
25 // If you choose left you are selecting the 1 or 2 value and right means the + value. For instance, to find
26 // the number of bins that have f1+1+ you would start at the root, go left, right, left, and select the rightvalue.
27 // the coeffient is 2. Note: we only set the coeffient in f2 values.
29 //create and initialize trees to 0.
30 initialTree(numGroups);
32 for (int i = 0; i < shared[0]->size(); i++) {
33 //get bin values and calc shared
34 bool sharedByAll = true;
36 for (int j = 0; j < numGroups; j++) {
37 temp.push_back(shared[j]->getAbundance(i));
38 if (temp[j] == 0) { sharedByAll = false; }
42 if (sharedByAll == true) {
43 //find f1 and f2values
49 //calculate chao1, (numleaves-1) because numleaves contains the ++ values.
51 for(int i=0;i<numLeaves;i++){
52 if (f2leaves[i]->lvalue == 0 || f2leaves[i]->rvalue == 0) { bias = true;}// break;}
56 for (int i = 0; i < numLeaves; i++) {
58 leftvalue = (float)(f1leaves[i]->lvalue * (f1leaves[i]->lvalue - 1)) / (float)((pow(2, (float)f2leaves[i]->lcoef)) * (f2leaves[i]->lvalue + 1));
59 if (i != (numLeaves-1)) {
60 rightvalue = (float)(f1leaves[i]->rvalue * (f1leaves[i]->rvalue - 1)) / (float)((pow(2, (float)f2leaves[i]->rcoef)) * (f2leaves[i]->rvalue + 1));
63 rightvalue = (float)(f1leaves[i]->rvalue);
65 Chao += leftvalue + rightvalue;
70 for (int i = 0; i < numLeaves; i++) {
72 leftvalue = (float)(f1leaves[i]->lvalue * f1leaves[i]->lvalue) / (float)((pow(2, (float)f2leaves[i]->lcoef)) * f2leaves[i]->lvalue);
73 if (i != (numLeaves-1)) {
74 rightvalue = (float)(f1leaves[i]->rvalue * f1leaves[i]->rvalue) / (float)((pow(2, (float)f2leaves[i]->rcoef)) * f2leaves[i]->rvalue);
77 rightvalue = (float)(f1leaves[i]->rvalue);
79 Chao += leftvalue + rightvalue;
83 for (int i = 0; i < numNodes; i++) {
93 m->errorOut(e, "SharedChao1", "getValues");
98 /***********************************************************************/
99 //builds trees structure with n leaf nodes initialized to 0.
100 void SharedChao1::initialTree(int n) {
102 // (2^n) / 2. Divide by 2 because each leaf node contains 2 values. One for + and one for 1 or 2.
103 numLeaves = pow(2, (float)n) / 2;
104 numNodes = 2*numLeaves - 1;
108 f1leaves.resize(numNodes);
109 f2leaves.resize(numNodes);
111 //initialize leaf values
112 for (int i = 0; i < numLeaves; i++) {
113 f1leaves[i] = new IntNode(0, 0, NULL, NULL);
114 f2leaves[i] = new IntNode(0, 0, NULL, NULL);
117 //set pointers to children
118 for (int j = numLeaves; j < numNodes; j++) {
119 f1leaves[j] = new IntNode();
120 f1leaves[j]->left = f1leaves[countleft];
121 f1leaves[j]->right = f1leaves[countright];
123 f2leaves[j] = new IntNode();
124 f2leaves[j]->left = f2leaves[countleft];
125 f2leaves[j]->right =f2leaves[countright];
127 countleft = countleft + 2;
128 countright = countright + 2;
132 f1root = f1leaves[numNodes-1];
135 f2root = f2leaves[numNodes-1];
140 catch(exception& e) {
141 if ((toString(e.what()) == "vector::_M_fill_insert") || (toString(e.what()) == "St9bad_alloc")) { m->mothurOut("You are using " + toString(n) + " groups which creates 2^" + toString(n+1) + " nodes. Try reducing the number of groups you selected. "); m->mothurOutEndLine(); exit(1); }
142 m->errorOut(e, "SharedChao1", "initialTree");
147 /***********************************************************************/
148 //take vector containing the abundance info. for a bin and updates trees.
149 void SharedChao1::updateTree(vector<int> bin) {
151 updateBranchf1(f1root, bin, 0);
152 updateBranchf2(f2root, bin, 0);
154 catch(exception& e) {
155 m->errorOut(e, "SharedChao1", "updateTree");
160 /***********************************************************************/
161 void SharedChao1::updateBranchf1(IntNode* node, vector<int> bin, int index) {
163 //if you have more than one group
164 if (index == (bin.size()-1)) {
165 if (bin[index] == 1) { node->lvalue++; node->rvalue++; }
166 else { node->rvalue++; }
168 if (bin[index] == 1) {
169 //follow path as if you are 1
170 updateBranchf1(node->left, bin, index+1);
172 //follow path as if you are +
173 updateBranchf1(node->right, bin, index+1);
176 catch(exception& e) {
177 m->errorOut(e, "SharedChao1", "updateBranchf1");
182 /***********************************************************************/
183 void SharedChao1::updateBranchf2(IntNode* node, vector<int> bin, int index) {
185 //if you have more than one group
186 if (index == (bin.size()-1)) {
187 if (bin[index] == 2) { node->lvalue++; node->rvalue++; }
188 else { node->rvalue++; }
190 if (bin[index] == 2) {
191 //follow path as if you are 1
192 updateBranchf2(node->left, bin, index+1);
194 //follow path as if you are +
195 updateBranchf2(node->right, bin, index+1);
198 catch(exception& e) {
199 m->errorOut(e, "SharedChao1", "updateBranchf2");
204 /***********************************************************************/
205 void SharedChao1::setCoef(IntNode* node, int coef) {
207 if (node->left != NULL) {
208 setCoef(node->left, coef+1);
209 setCoef(node->right, coef);
211 node->lcoef = coef+1;
215 catch(exception& e) {
216 m->errorOut(e, "SharedChao1", "setCoef");
221 /***********************************************************************/
222 //for debugging purposes
223 void SharedChao1::printTree() {
225 m->mothurOut("F1 leaves"); m->mothurOutEndLine();
228 m->mothurOut("F2 leaves"); m->mothurOutEndLine();
233 /*****************************************************************/
234 void SharedChao1::printBranch(IntNode* node) {
237 // you are not a leaf
238 if (node->left != NULL) {
239 printBranch(node->left);
240 printBranch(node->right);
241 }else { //you are a leaf
242 m->mothurOut(toString(node->lvalue)); m->mothurOutEndLine();
243 m->mothurOut(toString(node->rvalue)); m->mothurOutEndLine();
247 catch(exception& e) {
248 m->errorOut(e, "SharedChao1", "printBranch");
253 /*****************************************************************/