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