]> git.donarmstrong.com Git - mothur.git/blob - tree.cpp
114b4de0d6e2c408479ae8c03b65d2b1300bb9b8
[mothur.git] / tree.cpp
1 /*
2  *  tree.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 1/22/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "tree.h"
11
12 /*****************************************************************/
13 Tree::Tree(int num) {
14         try {
15                 globaldata = GlobalData::getInstance();
16                 m = MothurOut::getInstance();
17                 
18                 numLeaves = num;  
19                 numNodes = 2*numLeaves - 1;
20                 
21                 tree.resize(numNodes);
22         }
23         catch(exception& e) {
24                 m->errorOut(e, "Tree", "Tree - numNodes");
25                 exit(1);
26         }
27 }
28 /*****************************************************************/
29 Tree::Tree(string g) {
30         try {
31                 globaldata = GlobalData::getInstance();
32                 m = MothurOut::getInstance();
33                 
34                 parseTreeFile();  globaldata->runParse = false;  
35         }
36         catch(exception& e) {
37                 m->errorOut(e, "Tree", "Tree - just parse");
38                 exit(1);
39         }
40 }
41 /*****************************************************************/
42 Tree::Tree() {
43         try {
44                 globaldata = GlobalData::getInstance();
45                 m = MothurOut::getInstance();
46                 
47                 if (globaldata->runParse == true) {  parseTreeFile();  globaldata->runParse = false;  }
48 //for(int i = 0; i <    globaldata->Treenames.size(); i++) { cout << i << '\t' << globaldata->Treenames[i] << endl;  }  
49                 numLeaves = globaldata->Treenames.size();
50                 numNodes = 2*numLeaves - 1;
51                 
52                 tree.resize(numNodes);
53                 
54                 //initialize groupNodeInfo
55                 for (int i = 0; i < globaldata->gTreemap->namesOfGroups.size(); i++) {
56                         groupNodeInfo[globaldata->gTreemap->namesOfGroups[i]].resize(0);
57                 }
58
59                 //initialize tree with correct number of nodes, name and group info.
60                 for (int i = 0; i < numNodes; i++) {
61                         //initialize leaf nodes
62                         if (i <= (numLeaves-1)) {
63                                 tree[i].setName(globaldata->Treenames[i]);
64                                 
65                                 //save group info
66                                 string group = globaldata->gTreemap->getGroup(globaldata->Treenames[i]);
67                                 vector<string> tempGroups; tempGroups.push_back(group);
68                                 tree[i].setGroup(tempGroups);
69                                 groupNodeInfo[group].push_back(i); 
70                                 
71                                 //set pcount and pGroup for groupname to 1.
72                                 tree[i].pcount[group] = 1;
73                                 tree[i].pGroups[group] = 1;
74                                 
75                                 //Treemap knows name, group and index to speed up search
76                                 globaldata->gTreemap->setIndex(globaldata->Treenames[i], i);
77         
78                         //intialize non leaf nodes
79                         }else if (i > (numLeaves-1)) {
80                                 tree[i].setName("");
81                                 vector<string> tempGroups;
82                                 tree[i].setGroup(tempGroups);
83                         }
84                 }
85         }
86         catch(exception& e) {
87                 m->errorOut(e, "Tree", "Tree");
88                 exit(1);
89         }
90 }
91
92 /*****************************************************************/
93 Tree::~Tree() {}
94 /*****************************************************************/
95 void Tree::addNamesToCounts() {
96         try {
97                 //ex. seq1      seq2,seq3,se4
98                 //              seq1 = pasture
99                 //              seq2 = forest
100                 //              seq4 = pasture
101                 //              seq3 = ocean
102                 
103                 //before this function seq1.pcount = pasture -> 1
104                 //after                            seq1.pcount = pasture -> 2, forest -> 1, ocean -> 1
105                 
106                 //before this function seq1.pgroups = pasture -> 1
107                 //after                            seq1.pgroups = pasture -> 1 since that is the dominant group
108
109                                 
110                 //go through each leaf and update its pcounts and pgroups
111                 
112                 //float A = clock();
113
114                 for (int i = 0; i < numLeaves; i++) {
115
116                         string name = tree[i].getName();
117                 
118                         map<string, string>::iterator itNames = globaldata->names.find(name);
119                 
120                         if (itNames == globaldata->names.end()) { m->mothurOut(name + " is not in your name file, please correct."); m->mothurOutEndLine(); exit(1);  }
121                         else {
122                                 vector<string> dupNames;
123                                 m->splitAtComma(globaldata->names[name], dupNames);
124                                 
125                                 map<string, int>::iterator itCounts;
126                                 int maxPars = 1;
127                                 set<string> groupsAddedForThisNode;
128                                 for (int j = 0; j < dupNames.size(); j++) {
129                                         
130                                         string group = globaldata->gTreemap->getGroup(dupNames[j]);
131                                         
132                                         if (dupNames[j] != name) {//you already added yourself in the constructor
133                                 
134                                                 if (groupsAddedForThisNode.count(group) == 0)  {  groupNodeInfo[group].push_back(i);  groupsAddedForThisNode.insert(group);  } //if you have not already added this node for this group, then add it
135                                                 
136                                                 //update pcounts
137                                                 itCounts = tree[i].pcount.find(group);
138                                                 if (itCounts == tree[i].pcount.end()) { //new group, add it
139                                                         tree[i].pcount[group] = 1;
140                                                 }else {
141                                                         tree[i].pcount[group]++;
142                                                 }
143                                                         
144                                                 //update pgroups
145                                                 itCounts = tree[i].pGroups.find(group);
146                                                 if (itCounts == tree[i].pGroups.end()) { //new group, add it
147                                                         tree[i].pGroups[group] = 1;
148                                                 }else{
149                                                         tree[i].pGroups[group]++;
150                                                 }
151                                                 
152                                                 //keep highest group
153                                                 if(tree[i].pGroups[group] > maxPars){
154                                                         maxPars = tree[i].pGroups[group];
155                                                 }
156                                         }else {  groupsAddedForThisNode.insert(group);  } //add it so you don't add it to groupNodeInfo again
157                                 }//end for
158                                 
159                                 if (maxPars > 1) { //then we have some more dominant groups
160                                         //erase all the groups that are less than maxPars because you found a more dominant group.
161                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();){
162                                                 if(it->second < maxPars){
163                                                         tree[i].pGroups.erase(it++);
164                                                 }else { it++; }
165                                         }
166                                         //set one remaining groups to 1
167                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();it++){
168                                                 tree[i].pGroups[it->first] = 1;
169                                         }
170                                 }//end if
171                                 
172                                 //update groups to reflect all the groups this node represents
173                                 vector<string> nodeGroups;
174                                 map<string, int>::iterator itGroups;
175                                 for (itGroups = tree[i].pcount.begin(); itGroups != tree[i].pcount.end(); itGroups++) {
176                                         nodeGroups.push_back(itGroups->first);
177                                 }
178                                 tree[i].setGroup(nodeGroups);
179                                 
180                         }//end else
181                 }//end for              
182                 
183                 //float B = clock();
184                 //cout << "addNamesToCounts\t" << (B - A) / CLOCKS_PER_SEC << endl;     
185
186         }
187         catch(exception& e) {
188                 m->errorOut(e, "Tree", "addNamesToCounts");
189                 exit(1);
190         }
191 }
192 /*****************************************************************/
193 int Tree::getIndex(string searchName) {
194         try {
195                 //Treemap knows name, group and index to speed up search
196                 // getIndex function will return the vector index or -1 if seq is not found.
197                 int index = globaldata->gTreemap->getIndex(searchName);
198                 return index;
199                 
200         }
201         catch(exception& e) {
202                 m->errorOut(e, "Tree", "getIndex");
203                 exit(1);
204         }
205 }
206 /*****************************************************************/
207
208 void Tree::setIndex(string searchName, int index) {
209         try {
210                 //set index in treemap
211                 globaldata->gTreemap->setIndex(searchName, index);
212         }
213         catch(exception& e) {
214                 m->errorOut(e, "Tree", "setIndex");
215                 exit(1);
216         }
217 }
218 /*****************************************************************/
219 int Tree::assembleTree() {
220         try {
221                 //float A = clock();
222
223                 //if user has given a names file we want to include that info in the pgroups and pcount info.
224                 if(globaldata->names.size() != 0) {  addNamesToCounts();  }
225                 
226                 //build the pGroups in non leaf nodes to be used in the parsimony calcs.
227                 for (int i = numLeaves; i < numNodes; i++) {
228                         if (m->control_pressed) { return 1; }
229
230                         tree[i].pGroups = (mergeGroups(i));
231                         tree[i].pcount = (mergeGcounts(i));
232                 }
233                 //float B = clock();
234                 //cout << "assembleTree\t" << (B-A) / CLOCKS_PER_SEC << endl;
235                 return 0;
236         }
237         catch(exception& e) {
238                 m->errorOut(e, "Tree", "assembleTree");
239                 exit(1);
240         }
241 }
242 /*****************************************************************/
243 int Tree::assembleTree(string n) {
244         try {
245                 
246                 //build the pGroups in non leaf nodes to be used in the parsimony calcs.
247                 for (int i = numLeaves; i < numNodes; i++) {
248                         if (m->control_pressed) { return 1; }
249
250                         tree[i].pGroups = (mergeGroups(i));
251                         tree[i].pcount = (mergeGcounts(i));
252                 }
253                 //float B = clock();
254                 //cout << "assembleTree\t" << (B-A) / CLOCKS_PER_SEC << endl;
255                 return 0;
256         }
257         catch(exception& e) {
258                 m->errorOut(e, "Tree", "assembleTree");
259                 exit(1);
260         }
261 }
262 /*****************************************************************/
263 void Tree::getSubTree(Tree* copy, vector<string> Groups) {
264         try {
265                         
266                 //we want to select some of the leaf nodes to create the output tree
267                 //go through the input Tree starting at parents of leaves
268                 for (int i = 0; i < numNodes; i++) {
269                         
270                         //initialize leaf nodes
271                         if (i <= (numLeaves-1)) {
272                                 tree[i].setName(Groups[i]);
273                                 
274                                 //save group info
275                                 string group = globaldata->gTreemap->getGroup(Groups[i]);
276                                 vector<string> tempGroups; tempGroups.push_back(group);
277                                 tree[i].setGroup(tempGroups);
278                                 groupNodeInfo[group].push_back(i); 
279                                 
280                                 //set pcount and pGroup for groupname to 1.
281                                 tree[i].pcount[group] = 1;
282                                 tree[i].pGroups[group] = 1;
283                                 
284                                 //Treemap knows name, group and index to speed up search
285                                 globaldata->gTreemap->setIndex(Groups[i], i);
286                                 
287                                 //intialize non leaf nodes
288                         }else if (i > (numLeaves-1)) {
289                                 tree[i].setName("");
290                                 vector<string> tempGroups;
291                                 tree[i].setGroup(tempGroups);
292                         }
293                 }
294                 
295                 set<int> removedLeaves;
296                 for (int i = 0; i < copy->getNumLeaves(); i++) {
297                         
298                         if (removedLeaves.count(i) == 0) {
299                         
300                         //am I in the group
301                         int parent = copy->tree[i].getParent();
302                         
303                         if (parent != -1) {
304                                 
305                                 if (m->inUsersGroups(copy->tree[i].getName(), Groups)) {
306                                         //find my siblings name
307                                         int parentRC = copy->tree[parent].getRChild();
308                                         int parentLC = copy->tree[parent].getLChild();
309                                         
310                                         //if I am the right child, then my sib is the left child
311                                         int sibIndex = parentRC;
312                                         if (parentRC == i) { sibIndex = parentLC; }
313                                         
314                                         string sibsName = copy->tree[sibIndex].getName();
315                                         
316                                         //if yes, is my sibling
317                                         if ((m->inUsersGroups(sibsName, Groups)) || (sibsName == "")) {
318                                                 //we both are okay no trimming required
319                                         }else{
320                                                 //i am, my sib is not, so remove sib by setting my parent to my grandparent
321                                                 int grandparent = copy->tree[parent].getParent();
322                                                 int grandparentLC = copy->tree[grandparent].getLChild();
323                                                 int grandparentRC = copy->tree[grandparent].getRChild();
324                                                 
325                                                 //whichever of my granparents children was my parent now equals me
326                                                 if (grandparentLC == parent) { grandparentLC = i; }
327                                                 else { grandparentRC = i; }
328                                                 
329                                                 copy->tree[i].setParent(grandparent);
330                                                 copy->tree[i].setBranchLength((copy->tree[i].getBranchLength()+copy->tree[parent].getBranchLength()));
331                                                 copy->tree[grandparent].setChildren(grandparentLC, grandparentRC);
332                                                 removedLeaves.insert(sibIndex);
333                                         }
334                                 }else{
335                                         //find my siblings name
336                                         int parentRC = copy->tree[parent].getRChild();
337                                         int parentLC = copy->tree[parent].getLChild();
338                                         
339                                         //if I am the right child, then my sib is the left child
340                                         int sibIndex = parentRC;
341                                         if (parentRC == i) { sibIndex = parentLC; }
342                                         
343                                         string sibsName = copy->tree[sibIndex].getName();
344                                         
345                                         //if no is my sibling
346                                         if ((m->inUsersGroups(sibsName, Groups)) || (sibsName == "")) {
347                                                 //i am not, but my sib is
348                                                 int grandparent = copy->tree[parent].getParent();
349                                                 int grandparentLC = copy->tree[grandparent].getLChild();
350                                                 int grandparentRC = copy->tree[grandparent].getRChild();
351                                                 
352                                                 //whichever of my granparents children was my parent now equals my sib
353                                                 if (grandparentLC == parent) { grandparentLC = sibIndex; }
354                                                 else { grandparentRC = sibIndex; }
355                                                 
356                                                 copy->tree[sibIndex].setParent(grandparent);
357                                                 copy->tree[sibIndex].setBranchLength((copy->tree[sibIndex].getBranchLength()+copy->tree[parent].getBranchLength()));
358                                                 copy->tree[grandparent].setChildren(grandparentLC, grandparentRC);
359                                                 removedLeaves.insert(i);
360                                         }else{
361                                                 //neither of us are, so we want to eliminate ourselves and our parent
362                                                 //so set our parents sib to our great-grandparent
363                                                 int parent = copy->tree[i].getParent();
364                                                 int grandparent = copy->tree[parent].getParent();
365                                                 int parentsSibIndex;
366                                                 if (grandparent != -1) {
367                                                         int greatgrandparent = copy->tree[grandparent].getParent();
368                                                         int greatgrandparentLC = copy->tree[greatgrandparent].getLChild();
369                                                         int greatgrandparentRC = copy->tree[greatgrandparent].getRChild();
370                                                         
371                                                         int grandparentLC = copy->tree[grandparent].getLChild();
372                                                         int grandparentRC = copy->tree[grandparent].getRChild();
373                                                         
374                                                         parentsSibIndex = grandparentLC;
375                                                         if (grandparentLC == parent) { parentsSibIndex = grandparentRC; }
376
377                                                         //whichever of my greatgrandparents children was my grandparent
378                                                         if (greatgrandparentLC == grandparent) { greatgrandparentLC = parentsSibIndex; }
379                                                         else { greatgrandparentRC = parentsSibIndex; }
380                                                         
381                                                         copy->tree[parentsSibIndex].setParent(greatgrandparent);
382                                                         copy->tree[parentsSibIndex].setBranchLength((copy->tree[parentsSibIndex].getBranchLength()+copy->tree[grandparent].getBranchLength()));
383                                                         copy->tree[greatgrandparent].setChildren(greatgrandparentLC, greatgrandparentRC);
384                                                 }else{
385                                                         copy->tree[parent].setChildren(-1, -1);
386                                                         cout << "issues with making subtree" << endl;
387                                                 }
388                                                 removedLeaves.insert(sibIndex);
389                                                 removedLeaves.insert(i);
390                                         }
391                                 }
392                         }
393                         }
394                 }
395                 
396                 int root = 0;
397                 for (int i = 0; i < copy->getNumNodes(); i++) {
398                         //you found the root
399                         if (copy->tree[i].getParent() == -1) { root = i; break; }
400                 }
401                 
402                 int nextSpot = numLeaves;
403                 populateNewTree(copy->tree, root, nextSpot);
404                 
405         }
406         catch(exception& e) {
407                 m->errorOut(e, "Tree", "getCopy");
408                 exit(1);
409         }
410 }
411 /*****************************************************************/
412 int Tree::populateNewTree(vector<Node>& oldtree, int node, int& index) {
413         try {
414                 
415                 if (oldtree[node].getLChild() != -1) {
416                         int rc = populateNewTree(oldtree, oldtree[node].getLChild(), index);
417                         int lc = populateNewTree(oldtree, oldtree[node].getRChild(), index);
418
419                         tree[index].setChildren(lc, rc);
420                         tree[rc].setParent(index);
421                         tree[lc].setParent(index);
422                         
423                         return (index++);
424                 }else { //you are a leaf
425                         int indexInNewTree = globaldata->gTreemap->getIndex(oldtree[node].getName());
426                         return indexInNewTree;
427                 }
428         }
429         catch(exception& e) {
430                 m->errorOut(e, "Tree", "populateNewTree");
431                 exit(1);
432         }
433 }
434 /*****************************************************************/
435 void Tree::getCopy(Tree* copy) {
436         try {
437         
438                 //for each node in the tree copy its info
439                 for (int i = 0; i < numNodes; i++) {
440                         //copy name
441                         tree[i].setName(copy->tree[i].getName());
442                 
443                         //copy group
444                         tree[i].setGroup(copy->tree[i].getGroup());
445                         
446                         //copy branch length
447                         tree[i].setBranchLength(copy->tree[i].getBranchLength());
448                 
449                         //copy parent
450                         tree[i].setParent(copy->tree[i].getParent());
451                 
452                         //copy children
453                         tree[i].setChildren(copy->tree[i].getLChild(), copy->tree[i].getRChild());
454                 
455                         //copy index in node and tmap
456                         tree[i].setIndex(copy->tree[i].getIndex());
457                         setIndex(copy->tree[i].getName(), getIndex(copy->tree[i].getName()));
458                         
459                         //copy pGroups
460                         tree[i].pGroups = copy->tree[i].pGroups;
461                 
462                         //copy pcount
463                         tree[i].pcount = copy->tree[i].pcount;
464                 }
465                 
466                 groupNodeInfo = copy->groupNodeInfo;
467                 
468         }
469         catch(exception& e) {
470                 m->errorOut(e, "Tree", "getCopy");
471                 exit(1);
472         }
473 }
474 /*****************************************************************/
475 //returns a map with a groupname and the number of times that group was seen in the children
476 //for instance if your children are white and black then it would return a map with 2 entries
477 // p[white] = 1 and p[black] = 1.  Now go up a level and merge that with a node who has p[white] = 1
478 //and you get p[white] = 2, p[black] = 1, but you erase the p[black] because you have a p value higher than 1.
479
480 map<string, int> Tree::mergeGroups(int i) {
481         try {
482                 int lc = tree[i].getLChild();
483                 int rc = tree[i].getRChild();
484
485                 //set parsimony groups to left child
486                 map<string,int> parsimony = tree[lc].pGroups;
487                 
488                 int maxPars = 1;
489
490                 //look at right child groups and update maxPars if right child has something higher for that group.
491                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();it++){
492                         it2 = parsimony.find(it->first);
493                         if (it2 != parsimony.end()) {
494                                 parsimony[it->first]++;
495                         }else {
496                                 parsimony[it->first] = 1;
497                         }
498                         
499                         if(parsimony[it->first] > maxPars){
500                                 maxPars = parsimony[it->first];
501                         }
502                 }
503         
504                 // this is true if right child had a greater parsimony for a certain group
505                 if(maxPars > 1){
506                         //erase all the groups that are only 1 because you found something with 2.
507                         for(it=parsimony.begin();it!=parsimony.end();){
508                                 if(it->second == 1){
509                                         parsimony.erase(it++);
510                                 }else { it++; }
511                         }
512                         //set one remaining groups to 1
513                         //so with our above example p[white] = 2 would be left and it would become p[white] = 1
514                         for(it=parsimony.begin();it!=parsimony.end();it++){
515                                 parsimony[it->first] = 1;
516                         }
517                 
518                 }
519         
520                 return parsimony;
521         }
522         catch(exception& e) {
523                 m->errorOut(e, "Tree", "mergeGroups");
524                 exit(1);
525         }
526 }
527 /*****************************************************************/
528 //returns a map with a groupname and the number of times that group was seen in the children
529 //for instance if your children are white and black then it would return a map with 2 entries
530 // p[white] = 1 and p[black] = 1.  Now go up a level and merge that with a node who has p[white] = 1
531 //and you get p[white] = 2, p[black] = 1, but you erase the p[black] because you have a p value higher than 1.
532
533 map<string, int> Tree::mergeUserGroups(int i, vector<string> g) {
534         try {
535         
536                 int lc = tree[i].getLChild();
537                 int rc = tree[i].getRChild();
538                 
539                 //loop through nodes groups removing the ones the user doesn't want
540                 for(it=tree[lc].pGroups.begin();it!=tree[lc].pGroups.end();){
541                                 if (m->inUsersGroups(it->first, g) != true) {
542                                         tree[lc].pGroups.erase(it++);
543                                 }else { it++; }
544                 }
545
546                 //loop through nodes groups removing the ones the user doesn't want
547                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();){
548                                 if (m->inUsersGroups(it->first, g) != true) {
549                                         tree[rc].pGroups.erase(it++);
550                                 }else { it++; }
551                 }
552
553                 //set parsimony groups to left child
554                 map<string,int> parsimony = tree[lc].pGroups;
555                 
556                 int maxPars = 1;
557
558                 //look at right child groups and update maxPars if right child has something higher for that group.
559                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();it++){
560                         it2 = parsimony.find(it->first);
561                         if (it2 != parsimony.end()) {
562                                 parsimony[it->first]++;
563                         }else {
564                                 parsimony[it->first] = 1;
565                         }
566                         
567                         if(parsimony[it->first] > maxPars){
568                                 maxPars = parsimony[it->first];
569                         }
570                 }
571                         
572                 // this is true if right child had a greater parsimony for a certain group
573                 if(maxPars > 1){
574                         //erase all the groups that are only 1 because you found something with 2.
575                         for(it=parsimony.begin();it!=parsimony.end();){
576                                 if(it->second == 1){
577                                         parsimony.erase(it++);
578                                 }else { it++; }
579                         }
580
581                         for(it=parsimony.begin();it!=parsimony.end();it++){
582                                 parsimony[it->first] = 1;
583                         }
584                 }               
585                 
586                 return parsimony;
587         }
588         catch(exception& e) {
589                 m->errorOut(e, "Tree", "mergeUserGroups");
590                 exit(1);
591         }
592 }
593
594
595 /**************************************************************************************************/
596
597 map<string,int> Tree::mergeGcounts(int position) {
598         try{
599                 map<string,int>::iterator pos;
600         
601                 int lc = tree[position].getLChild();
602                 int rc = tree[position].getRChild();
603         
604                 map<string,int> sum = tree[lc].pcount;
605     
606                 for(it=tree[rc].pcount.begin();it!=tree[rc].pcount.end();it++){
607                         sum[it->first] += it->second;
608                 }
609                 return sum;
610         }
611         catch(exception& e) {
612                 m->errorOut(e, "Tree", "mergeGcounts");
613                 exit(1);
614         }
615 }
616 /**************************************************************************************************/
617
618 void Tree::randomLabels(vector<string> g) {
619         try {
620         
621                 //initialize groupNodeInfo
622                 for (int i = 0; i < globaldata->gTreemap->namesOfGroups.size(); i++) {
623                         groupNodeInfo[globaldata->gTreemap->namesOfGroups[i]].resize(0);
624                 }
625                 
626                 for(int i = 0; i < numLeaves; i++){
627                         int z;
628                         //get random index to switch with
629                         z = int((float)(i+1) * (float)(rand()) / ((float)RAND_MAX+1.0));        
630                         
631                         //you only want to randomize the nodes that are from a group the user wants analyzed, so
632                         //if either of the leaf nodes you are about to switch are not in the users groups then you don't want to switch them.
633                         bool treez, treei;
634                 
635                         treez = m->inUsersGroups(tree[z].getGroup(), g);
636                         treei = m->inUsersGroups(tree[i].getGroup(), g);
637                         
638                         if ((treez == true) && (treei == true)) {
639                                 //switches node i and node z's info.
640                                 map<string,int> lib_hold = tree[z].pGroups;
641                                 tree[z].pGroups = (tree[i].pGroups);
642                                 tree[i].pGroups = (lib_hold);
643                                 
644                                 vector<string> zgroup = tree[z].getGroup();
645                                 tree[z].setGroup(tree[i].getGroup());
646                                 tree[i].setGroup(zgroup);
647                                 
648                                 string zname = tree[z].getName();
649                                 tree[z].setName(tree[i].getName());
650                                 tree[i].setName(zname);
651                                 
652                                 map<string,int> gcount_hold = tree[z].pcount;
653                                 tree[z].pcount = (tree[i].pcount);
654                                 tree[i].pcount = (gcount_hold);
655                         }
656                         
657                         for (int k = 0; k < (tree[i].getGroup()).size(); k++) {  groupNodeInfo[(tree[i].getGroup())[k]].push_back(i); }
658                         for (int k = 0; k < (tree[z].getGroup()).size(); k++) {  groupNodeInfo[(tree[z].getGroup())[k]].push_back(z); }
659                 }
660         }
661         catch(exception& e) {
662                 m->errorOut(e, "Tree", "randomLabels");
663                 exit(1);
664         }
665 }
666 /**************************************************************************************************
667
668 void Tree::randomLabels(string groupA, string groupB) {
669         try {
670                 int numSeqsA = globaldata->gTreemap->seqsPerGroup[groupA];
671                 int numSeqsB = globaldata->gTreemap->seqsPerGroup[groupB];
672
673                 vector<string> randomGroups(numSeqsA+numSeqsB, groupA);
674                 for(int i=numSeqsA;i<randomGroups.size();i++){
675                         randomGroups[i] = groupB;
676                 }
677                 random_shuffle(randomGroups.begin(), randomGroups.end());
678                                 
679                 int randomCounter = 0;                          
680                 for(int i=0;i<numLeaves;i++){
681                         if(tree[i].getGroup() == groupA || tree[i].getGroup() == groupB){
682                                 tree[i].setGroup(randomGroups[randomCounter]);
683                                 tree[i].pcount.clear();
684                                 tree[i].pcount[randomGroups[randomCounter]] = 1;
685                                 tree[i].pGroups.clear();
686                                 tree[i].pGroups[randomGroups[randomCounter]] = 1;
687                                 randomCounter++;
688                         }
689                 }
690         }               
691         catch(exception& e) {
692                 m->errorOut(e, "Tree", "randomLabels");
693                 exit(1);
694         }
695 }
696 /**************************************************************************************************/
697 void Tree::randomBlengths()  {
698         try {
699                 for(int i=numNodes-1;i>=0;i--){
700                         int z = int((float)(i+1) * (float)(rand()) / ((float)RAND_MAX+1.0));    
701                 
702                         float bl_hold = tree[z].getBranchLength();
703                         tree[z].setBranchLength(tree[i].getBranchLength());
704                         tree[i].setBranchLength(bl_hold);
705                 }
706         }
707         catch(exception& e) {
708                 m->errorOut(e, "Tree", "randomBlengths");
709                 exit(1);
710         }
711 }
712 /*************************************************************************************************/
713 void Tree::assembleRandomUnifracTree(vector<string> g) {
714         randomLabels(g);
715         assembleTree("noNameCounts");
716 }
717 /*************************************************************************************************/
718 void Tree::assembleRandomUnifracTree(string groupA, string groupB) {
719
720         vector<string> temp; temp.push_back(groupA); temp.push_back(groupB);
721         randomLabels(temp);
722         assembleTree("noNameCounts");
723 }
724
725 /*************************************************************************************************/
726 //for now it's just random topology but may become random labels as well later that why this is such a simple function now...
727 void Tree::assembleRandomTree() {
728         randomTopology();
729         assembleTree();
730 }
731 /**************************************************************************************************/
732
733 void Tree::randomTopology() {
734         try {
735                 for(int i=0;i<numNodes;i++){
736                         tree[i].setParent(-1);
737                 }
738                 for(int i=numLeaves;i<numNodes;i++){
739                         tree[i].setChildren(-1, -1); 
740                 }
741     
742                 for(int i=numLeaves;i<numNodes;i++){
743                         int escape =0;
744                         int rnd_index1, rnd_index2;
745                         while(escape == 0){
746                                 rnd_index1 = (int)(((double)rand() / (double) RAND_MAX)*i);
747                                 if(tree[rnd_index1].getParent() == -1){escape = 1;}
748                         }
749                 
750                         escape = 0;
751                         while(escape == 0){
752                                 rnd_index2 = (int)(((double)rand() / (double) RAND_MAX)*i);
753                                 if(rnd_index2 != rnd_index1 && tree[rnd_index2].getParent() == -1){
754                                         escape = 1;
755                                 }               
756                         }
757         
758                         tree[i].setChildren(rnd_index1,rnd_index2);
759                         tree[i].setParent(-1);
760                         tree[rnd_index1].setParent(i);
761                         tree[rnd_index2].setParent(i);
762                 }
763         }
764         catch(exception& e) {
765                 m->errorOut(e, "Tree", "randomTopology");
766                 exit(1);
767         }
768 }
769 /*****************************************************************/
770 void Tree::print(ostream& out) {
771         try {
772                 int root = findRoot();
773                 printBranch(root, out, "branch");
774                 out << ";" << endl;
775         }
776         catch(exception& e) {
777                 m->errorOut(e, "Tree", "print");
778                 exit(1);
779         }
780 }
781 /*****************************************************************/
782 void Tree::print(ostream& out, string mode) {
783         try {
784                 int root = findRoot();
785                 printBranch(root, out, mode);
786                 out << ";" << endl;
787         }
788         catch(exception& e) {
789                 m->errorOut(e, "Tree", "print");
790                 exit(1);
791         }
792 }
793 /*****************************************************************/
794 // This prints out the tree in Newick form.
795 void Tree::createNewickFile(string f) {
796         try {
797                 int root = findRoot();
798                 //filename = m->getRootName(globaldata->getTreeFile()) + "newick";
799                 filename = f;
800
801                 m->openOutputFile(filename, out);
802                 
803                 printBranch(root, out, "branch");
804                 
805                 // you are at the end of the tree
806                 out << ";" << endl;
807                 out.close();
808         }
809         catch(exception& e) {
810                 m->errorOut(e, "Tree", "createNewickFile");
811                 exit(1);
812         }
813 }
814
815 /*****************************************************************/
816 //This function finds the index of the root node.
817
818 int Tree::findRoot() {
819         try {
820                 for (int i = 0; i < numNodes; i++) {
821                         //you found the root
822                         if (tree[i].getParent() == -1) { return i; }
823                         //cout << "i = " << i << endl;
824                         //cout << "i's parent = " << tree[i].getParent() << endl;  
825                 }
826                 return -1;
827         }
828         catch(exception& e) {
829                 m->errorOut(e, "Tree", "findRoot");
830                 exit(1);
831         }
832 }
833 /*****************************************************************/
834 void Tree::printBranch(int node, ostream& out, string mode) {
835 try {
836
837 // you are not a leaf
838                 if (tree[node].getLChild() != -1) {
839                         out << "(";
840                         printBranch(tree[node].getLChild(), out, mode);
841                         out << ",";
842                         printBranch(tree[node].getRChild(), out, mode);
843                         out << ")";
844                         if (mode == "branch") {
845                                 //if there is a branch length then print it
846                                 if (tree[node].getBranchLength() != -1) {
847                                         out << ":" << tree[node].getBranchLength();
848                                 }
849                         }else if (mode == "boot") {
850                                 //if there is a label then print it
851                                 if (tree[node].getLabel() != -1) {
852                                         out << tree[node].getLabel();
853                                 }
854                         }else if (mode == "both") {
855                                 if (tree[node].getLabel() != -1) {
856                                         out << tree[node].getLabel();
857                                 }
858                                 //if there is a branch length then print it
859                                 if (tree[node].getBranchLength() != -1) {
860                                         out << ":" << tree[node].getBranchLength();
861                                 }
862                         }
863                 }else { //you are a leaf
864                         string leafGroup = globaldata->gTreemap->getGroup(tree[node].getName());
865                         
866                         if (mode == "branch") {
867                                 out << leafGroup; 
868                                 //if there is a branch length then print it
869                                 if (tree[node].getBranchLength() != -1) {
870                                         out << ":" << tree[node].getBranchLength();
871                                 }
872                         }else if (mode == "boot") {
873                                 out << leafGroup; 
874                                 //if there is a label then print it
875                                 if (tree[node].getLabel() != -1) {
876                                         out << tree[node].getLabel();
877                                 }
878                         }else if (mode == "both") {
879                                 out << tree[node].getName();
880                                 if (tree[node].getLabel() != -1) {
881                                         out << tree[node].getLabel();
882                                 }
883                                 //if there is a branch length then print it
884                                 if (tree[node].getBranchLength() != -1) {
885                                         out << ":" << tree[node].getBranchLength();
886                                 }
887                         }
888                 }
889                 
890         }
891         catch(exception& e) {
892                 m->errorOut(e, "Tree", "printBranch");
893                 exit(1);
894         }
895 }
896 /*****************************************************************/
897 void Tree::printBranch(int node, ostream& out, string mode, vector<Node>& theseNodes) {
898         try {
899                 
900                 // you are not a leaf
901                 if (theseNodes[node].getLChild() != -1) {
902                         out << "(";
903                         printBranch(theseNodes[node].getLChild(), out, mode);
904                         out << ",";
905                         printBranch(theseNodes[node].getRChild(), out, mode);
906                         out << ")";
907                         if (mode == "branch") {
908                                 //if there is a branch length then print it
909                                 if (theseNodes[node].getBranchLength() != -1) {
910                                         out << ":" << theseNodes[node].getBranchLength();
911                                 }
912                         }else if (mode == "boot") {
913                                 //if there is a label then print it
914                                 if (theseNodes[node].getLabel() != -1) {
915                                         out << theseNodes[node].getLabel();
916                                 }
917                         }else if (mode == "both") {
918                                 if (theseNodes[node].getLabel() != -1) {
919                                         out << theseNodes[node].getLabel();
920                                 }
921                                 //if there is a branch length then print it
922                                 if (theseNodes[node].getBranchLength() != -1) {
923                                         out << ":" << theseNodes[node].getBranchLength();
924                                 }
925                         }
926                 }else { //you are a leaf
927                         string leafGroup = globaldata->gTreemap->getGroup(theseNodes[node].getName());
928                         
929                         if (mode == "branch") {
930                                 out << leafGroup; 
931                                 //if there is a branch length then print it
932                                 if (theseNodes[node].getBranchLength() != -1) {
933                                         out << ":" << theseNodes[node].getBranchLength();
934                                 }
935                         }else if (mode == "boot") {
936                                 out << leafGroup; 
937                                 //if there is a label then print it
938                                 if (theseNodes[node].getLabel() != -1) {
939                                         out << theseNodes[node].getLabel();
940                                 }
941                         }else if (mode == "both") {
942                                 out << theseNodes[node].getName();
943                                 if (theseNodes[node].getLabel() != -1) {
944                                         out << theseNodes[node].getLabel();
945                                 }
946                                 //if there is a branch length then print it
947                                 if (theseNodes[node].getBranchLength() != -1) {
948                                         out << ":" << theseNodes[node].getBranchLength();
949                                 }
950                         }
951                 }
952                 
953         }
954         catch(exception& e) {
955                 m->errorOut(e, "Tree", "printBranch");
956                 exit(1);
957         }
958 }
959 /*****************************************************************/
960
961 void Tree::printTree() {
962         
963         for(int i=0;i<numNodes;i++){
964                 cout << i << '\t';
965                 tree[i].printNode();
966         }
967         
968 }
969
970 /*****************************************************************/
971 //this code is a mess and should be rethought...-slw
972 void Tree::parseTreeFile() {
973         
974         //only takes names from the first tree and assumes that all trees use the same names.
975         try {
976                 string filename = globaldata->getTreeFile();
977                 ifstream filehandle;
978                 m->openInputFile(filename, filehandle);
979                 int c, comment;
980                 comment = 0;
981                 int done = 1;
982                 
983                 //ifyou are not a nexus file 
984                 if((c = filehandle.peek()) != '#') {  
985                         while((c = filehandle.peek()) != ';') { 
986                                 while ((c = filehandle.peek()) != ';') {
987                                         // get past comments
988                                         if(c == '[') {
989                                                 comment = 1;
990                                         }
991                                         if(c == ']'){
992                                                 comment = 0;
993                                         }
994                                         if((c == '(') && (comment != 1)){ break; }
995                                         filehandle.get();
996                                 }
997
998                                 done = readTreeString(filehandle); 
999                                 if (done == 0) { break; }
1000                         }
1001                 //ifyou are a nexus file
1002                 }else if((c = filehandle.peek()) == '#') {
1003                         string holder = "";
1004                                         
1005                         // get past comments
1006                         while(holder != "translate" && holder != "Translate"){  
1007                                 if(holder == "[" || holder == "[!"){
1008                                         comment = 1;
1009                                 }
1010                                 if(holder == "]"){
1011                                         comment = 0;
1012                                 }
1013                                 filehandle >> holder; 
1014
1015                                 //if there is no translate then you must read tree string otherwise use translate to get names
1016                                 if((holder == "tree") && (comment != 1)){       
1017                                         //pass over the "tree rep.6878900 = "
1018                                         while (((c = filehandle.get()) != '(') && ((c = filehandle.peek()) != EOF)) {;}
1019
1020                                         if(c == EOF) { break; }
1021                                         filehandle.putback(c);  //put back first ( of tree.
1022                                         done = readTreeString(filehandle);
1023         
1024                                         break;
1025                                 }
1026                         
1027                                 if (done == 0) { break;  }
1028                         }
1029                         
1030                         //use nexus translation rather than parsing tree to save time
1031                         if((holder == "translate") || (holder == "Translate")) {
1032
1033                                 string number, name, h;
1034                                 h = ""; // so it enters the loop the first time
1035                                 while((h != ";") && (number != ";")) { 
1036                                         filehandle >> number;
1037                                         filehandle >> name;
1038         
1039                                         //c = , until done with translation then c = ;
1040                                         h = name.substr(name.length()-1, name.length()); 
1041                                         name.erase(name.end()-1);  //erase the comma
1042                                         globaldata->Treenames.push_back(number);
1043                                 }
1044                                 if(number == ";") { globaldata->Treenames.pop_back(); }  //in case ';' from translation is on next line instead of next to last name
1045                         }
1046                 }
1047                 filehandle.close();
1048                 
1049                 //for (int i = 0; i < globaldata->Treenames.size(); i++) {
1050 //cout << globaldata->Treenames[i] << endl; }
1051 //cout << globaldata->Treenames.size() << endl;
1052         }
1053         catch(exception& e) {
1054                 m->errorOut(e, "Tree", "parseTreeFile");
1055                 exit(1);
1056         }
1057 }
1058 /*******************************************************/
1059
1060 /*******************************************************/
1061 int Tree::readTreeString(ifstream& filehandle)  {
1062         try {
1063                 int c;
1064                 string name;  //, k
1065                 
1066                 while((c = filehandle.peek()) != ';') { 
1067 //k = c;
1068 //cout << " at beginning of while " <<  k << endl;                      
1069                         if(c == ')')  {    
1070                                 //to pass over labels in trees
1071                                 c=filehandle.get();
1072                                 while((c!=',') && (c != -1) && (c!= ':') && (c!=';')){ c=filehandle.get(); }
1073                                 filehandle.putback(c);
1074                         }
1075                         if(c == ';') { return 0; }
1076                         if(c == -1) { return 0; }
1077                         //if you are a name
1078                         if((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != '\t') && (c != 32)) { //32 is space
1079                                 name = "";
1080                                 c = filehandle.get();
1081                         //k = c;
1082 //cout << k << endl;
1083                                 while ((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != 32) && (c != '\t')) {                       
1084                                         name += c;
1085                                         c = filehandle.get();
1086                         //k = c;
1087 //cout << " in name while " << k << endl;
1088                                 }
1089                                 
1090 //cout << "name = " << name << endl;
1091                                 globaldata->Treenames.push_back(name);
1092                                 filehandle.putback(c);
1093 //k = c;
1094 //cout << " after putback" <<  k << endl;
1095                         } 
1096                         
1097                         if(c  == ':') { //read until you reach the end of the branch length
1098                                 while ((c != '(') && (c != ')') && (c != ',') && (c != ';') && (c != '\n') && (c != '\t') && (c != 32)) {
1099                                         c = filehandle.get();
1100         //k = c;
1101         //cout << " in branch while " << k << endl;
1102                                 }
1103                                 filehandle.putback(c);
1104                         }
1105                 
1106                         c = filehandle.get();
1107 //k = c;
1108         //cout << " here after get " << k << endl;
1109                         if(c == ';') { return 0; }
1110                         if(c == ')') { filehandle.putback(c); }
1111         //k = c;
1112 //cout << k << endl;
1113
1114                 }
1115                 return 0;
1116         }
1117         catch(exception& e) {
1118                 m->errorOut(e, "Tree", "readTreeString");
1119                 exit(1);
1120         }
1121 }       
1122
1123 /*******************************************************/
1124
1125 /*******************************************************/
1126