]> git.donarmstrong.com Git - mothur.git/blob - sharedchao1.cpp
fixed multiple bugs for 1.4 release
[mothur.git] / sharedchao1.cpp
1 /*
2  *  sharedchao1.cpp
3  *  Dotur
4  *
5  *  Created by Sarah Westcott on 1/8/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "sharedchao1.h"
11
12 /***********************************************************************/
13 EstOutput SharedChao1::getValues(vector<SharedRAbundVector*> shared){
14         try {
15                 data.resize(1,0);               
16                 vector<int> temp; 
17                 int numGroups = shared.size();
18                 float Chao = 0.0; float leftvalue, rightvalue;
19                                 
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.
28                 
29                 //create and initialize trees to 0.
30                 initialTree(numGroups); 
31                 
32                 //loop through vectors calculating the f11, f1A, f2A, f1B, f2B, S12 values
33                 for (int i = 0; i < shared[0]->size(); i++) {
34                         //get bin values and calc shared 
35                         bool sharedByAll = true;
36                         temp.clear();
37                         for (int j = 0; j < numGroups; j++) {
38                                 temp.push_back(shared[j]->getAbundance(i));
39                                 if (temp[j] == 0) { sharedByAll = false; }
40                         }
41                         
42                         //they are shared
43                         if (sharedByAll == true) { 
44                                 // cout << "temp = ";
45                                 // for (int h = 0; h < temp.size(); h++) { cout << temp[h] << " "; } cout << endl;
46                                 //find f1 and f2values
47                                 updateTree(temp);
48                         }
49                 }
50
51                         
52                 //cout << "Entering " << endl;
53                 //calculate chao1, (numleaves-1) because numleaves contains the ++ values.
54                 bool bias;
55                 for(int i=0;i<numLeaves;i++){
56                         if (f2leaves[i]->lvalue == 0) { bias = true;}// break;}
57                 }
58
59                 if(bias){
60                         for (int i = 0; i < numLeaves; i++) {
61                                 
62                                 leftvalue = (float)(f1leaves[i]->lvalue * (f1leaves[i]->lvalue - 1)) / (float)((pow(2, (float)f2leaves[i]->lcoef)) * (f2leaves[i]->lvalue + 1));
63                                 if (i != (numLeaves-1)) {
64                                         rightvalue = (float)(f1leaves[i]->rvalue * (f1leaves[i]->rvalue - 1)) / (float)((pow(2, (float)f2leaves[i]->rcoef)) * (f2leaves[i]->rvalue + 1));
65                                 }else{
66                                         rightvalue = (float)(f1leaves[i]->rvalue);
67                                 }
68                                 Chao += leftvalue + rightvalue;
69                         }
70                 }
71                 else{
72                         
73                         for (int i = 0; i < numLeaves; i++) {
74                                 
75                                 leftvalue = (float)(f1leaves[i]->lvalue * f1leaves[i]->lvalue) / (float)((pow(2, (float)f2leaves[i]->lcoef)) * f2leaves[i]->lvalue);
76                                 if (i != (numLeaves-1)) {
77                                         rightvalue = (float)(f1leaves[i]->rvalue * f1leaves[i]->rvalue) / (float)((pow(2, (float)f2leaves[i]->rcoef)) * f2leaves[i]->rvalue);
78                                 }else{
79                                         rightvalue = (float)(f1leaves[i]->rvalue);
80                                 }
81                                 Chao += leftvalue + rightvalue;
82                         }
83                 }
84                 
85                 for (int i = 0; i < numNodes; i++) {
86                         delete f1leaves[i];
87                         delete f2leaves[i];
88                 }
89                 
90         //      cout << "exiting " << endl;
91                 data[0] = Chao;
92                 return data;
93         }
94         catch(exception& e) {
95                 cout << "Standard Error: " << e.what() << " has occurred in the SharedChao1 class Function getValues. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
96                 exit(1);
97         }
98         catch(...) {
99                 cout << "An unknown error has occurred in the SharedChao1 class function getValues. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
100                 exit(1);
101         }       
102 }
103
104 /***********************************************************************/
105 //builds trees structure with n leaf nodes initialized to 0.
106 void SharedChao1::initialTree(int n) {  
107         try {
108                 // (2^n) / 2. Divide by 2 because each leaf node contains 2 values. One for + and one for 1 or 2.
109                 numLeaves = pow(2, (float)n) / 2;
110                 numNodes = 2*numLeaves - 1;
111                 int countleft = 0;
112                 int countright = 1;
113                 
114                 f1leaves.resize(numNodes);
115                 f2leaves.resize(numNodes);
116                 
117                 //initialize leaf values
118                 for (int i = 0; i < numLeaves; i++) {
119                         f1leaves[i] = new IntNode;
120                         f1leaves[i]->lvalue = 0;
121                         f1leaves[i]->rvalue = 0;
122                         f1leaves[i]->left = NULL;
123                         f1leaves[i]->right = NULL;
124                         
125                         f2leaves[i] = new IntNode;
126                         f2leaves[i]->lvalue = 0;
127                         f2leaves[i]->rvalue = 0;
128                         f2leaves[i]->left = NULL;
129                         f2leaves[i]->right = NULL;
130                 }
131                 
132                 //set pointers to children
133                 for (int j = numLeaves; j < numNodes; j++) {
134                         f1leaves[j] = new IntNode;
135                         f1leaves[j]->left = f1leaves[countleft];
136                         f1leaves[j]->right = f1leaves[countright];
137                                                 
138                         f2leaves[j] = new IntNode;
139                         f2leaves[j]->left = f2leaves[countleft];
140                         f2leaves[j]->right =f2leaves[countright];
141                                                 
142                         countleft = countleft + 2;
143                         countright = countright + 2;
144                 }
145                 
146                 //point to root
147                 f1root = f1leaves[numNodes-1];
148                 
149                 //point to root
150                 f2root = f2leaves[numNodes-1];
151                 
152                 //set coeffients
153                 setCoef(f2root, 0);
154         }
155         catch(exception& e) {
156                 cout << "Standard Error: " << e.what() << " has occurred in the SharedChao1 class Function initialTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
157                 exit(1);
158         }
159         catch(...) {
160                 cout << "An unknown error has occurred in the SharedChao1 class function initialTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
161                 exit(1);
162         }       
163 }
164
165 /***********************************************************************/
166 //take vector containing the abundance info. for a bin and updates trees.
167 void SharedChao1::updateTree(vector<int> bin) { 
168         try {
169                 updateBranchf1(f1root, bin, 0);  
170                 updateBranchf2(f2root, bin, 0); 
171         }
172         catch(exception& e) {
173                 cout << "Standard Error: " << e.what() << " has occurred in the SharedChao1 class Function updateTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
174                 exit(1);
175         }
176         catch(...) {
177                 cout << "An unknown error has occurred in the SharedChao1 class function updateTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
178                 exit(1);
179         }       
180 }
181
182 /***********************************************************************/
183 void SharedChao1::updateBranchf1(IntNode* node, vector<int> bin, int index) {
184         try {
185                 //if you have more than one group
186                 if (index == (bin.size()-1)) {
187                         if (bin[index] == 1) { node->lvalue++; node->rvalue++; }
188                         else { node->rvalue++;  }
189                 }else {
190                         if (bin[index] == 1) {
191                                 //follow path as if you are 1
192                                 updateBranchf1(node->left, bin, index+1);
193                         }
194                         //follow path as if you are +
195                         updateBranchf1(node->right, bin, index+1);
196                 }
197         }
198         catch(exception& e) {
199                 cout << "Standard Error: " << e.what() << " has occurred in the SharedChao1 class Function updateBranchf1. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
200                 exit(1);
201         }
202         catch(...) {
203                 cout << "An unknown error has occurred in the SharedChao1 class function updateBranchf1. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
204                 exit(1);
205         }       
206 }
207
208 /***********************************************************************/
209 void SharedChao1::updateBranchf2(IntNode* node, vector<int> bin, int index) {
210         try {
211                 //if you have more than one group
212                 if (index == (bin.size()-1)) {
213                         if (bin[index] == 2) { node->lvalue++; node->rvalue++; }
214                         else { node->rvalue++;  }
215                 }else {
216                         if (bin[index] == 2) {
217                                 //follow path as if you are 1
218                                 updateBranchf2(node->left, bin, index+1);
219                         }
220                         //follow path as if you are +
221                         updateBranchf2(node->right, bin, index+1);
222                 }
223         }
224         catch(exception& e) {
225                 cout << "Standard Error: " << e.what() << " has occurred in the SharedChao1 class Function updateBranchf2. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
226                 exit(1);
227         }
228         catch(...) {
229                 cout << "An unknown error has occurred in the SharedChao1 class function updateBranchf2. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
230                 exit(1);
231         }       
232 }
233
234 /***********************************************************************/
235 void SharedChao1::setCoef(IntNode* node, int coef) {
236         try {
237                 if (node->left != NULL) {
238                         setCoef(node->left, coef+1);
239                         setCoef(node->right, coef);
240                 }else {
241                         node->lcoef = coef+1;
242                         node->rcoef = coef;
243                 }
244         }
245         catch(exception& e) {
246                 cout << "Standard Error: " << e.what() << " has occurred in the SharedChao1 class Function getCoef. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
247                 exit(1);
248         }
249         catch(...) {
250                 cout << "An unknown error has occurred in the SharedChao1 class function getCoef. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
251                 exit(1);
252         }       
253 }
254
255 /***********************************************************************/
256 //for debugging purposes
257 void SharedChao1::printTree() {
258         
259         cout << "F1 leaves" << endl;
260         printBranch(f1root);
261         
262         cout << "F2 leaves" << endl;
263         printBranch(f2root);
264
265
266 }
267 /*****************************************************************/
268 void SharedChao1::printBranch(IntNode* node) {
269         try {
270                 
271                 // you are not a leaf
272                 if (node->left != NULL) {
273                         printBranch(node->left);
274                         printBranch(node->right);
275                 }else { //you are a leaf
276                         cout << node->lvalue << endl;
277                         cout << node->rvalue << endl;
278                 }
279                 
280         }
281         catch(exception& e) {
282                 cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function printBranch. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
283                 exit(1);
284         }
285         catch(...) {
286                 cout << "An unknown error has occurred in the Tree class function printBranch. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
287                 exit(1);
288         }               
289 }
290
291 /*****************************************************************/
292
293
294
295