]> git.donarmstrong.com Git - mothur.git/blob - tree.cpp
ed652508ef2e6b049c183777ae5eecab42100d97
[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, TreeMap* t) : tmap(t) {
14         try {
15                 m = MothurOut::getInstance();
16                 
17                 numLeaves = num;  
18                 numNodes = 2*numLeaves - 1;
19         
20                 tree.resize(numNodes);
21         }
22         catch(exception& e) {
23                 m->errorOut(e, "Tree", "Tree - numNodes");
24                 exit(1);
25         }
26 }
27 /*****************************************************************/
28 Tree::Tree(string g) { //do not use tree generated by this its just to extract the treenames, its a chicken before the egg thing that needs to be revisited.
29         try {
30                 m = MothurOut::getInstance();
31                 parseTreeFile();  m->runParse = false;  
32         }
33         catch(exception& e) {
34                 m->errorOut(e, "Tree", "Tree - just parse");
35                 exit(1);
36         }
37 }
38 /*****************************************************************/
39 Tree::Tree(TreeMap* t) : tmap(t) {
40         try {
41                 m = MothurOut::getInstance();
42                 
43                 if (m->runParse == true) {  parseTreeFile();  m->runParse = false;  }
44 //for(int i = 0; i <    globaldata->Treenames.size(); i++) { cout << i << '\t' << globaldata->Treenames[i] << endl;  }  
45                 numLeaves = m->Treenames.size();
46                 numNodes = 2*numLeaves - 1;
47                 
48                 tree.resize(numNodes);
49                         
50                 //initialize groupNodeInfo
51                 for (int i = 0; i < (tmap->getNamesOfGroups()).size(); i++) {
52                         groupNodeInfo[(tmap->getNamesOfGroups())[i]].resize(0);
53                 }
54                 
55                 //initialize tree with correct number of nodes, name and group info.
56                 for (int i = 0; i < numNodes; i++) {
57                         //initialize leaf nodes
58                         if (i <= (numLeaves-1)) {
59                                 tree[i].setName(m->Treenames[i]);
60                                 
61                                 //save group info
62                                 string group = tmap->getGroup(m->Treenames[i]);
63                                 
64                                 vector<string> tempGroups; tempGroups.push_back(group);
65                                 tree[i].setGroup(tempGroups);
66                                 groupNodeInfo[group].push_back(i); 
67                                 
68                                 //set pcount and pGroup for groupname to 1.
69                                 tree[i].pcount[group] = 1;
70                                 tree[i].pGroups[group] = 1;
71                                 
72                                 //Treemap knows name, group and index to speed up search
73                                 tmap->setIndex(m->Treenames[i], i);
74         
75                         //intialize non leaf nodes
76                         }else if (i > (numLeaves-1)) {
77                                 tree[i].setName("");
78                                 vector<string> tempGroups;
79                                 tree[i].setGroup(tempGroups);
80                         }
81                 }
82                 
83         }
84         catch(exception& e) {
85                 m->errorOut(e, "Tree", "Tree");
86                 exit(1);
87         }
88 }
89 /*****************************************************************/
90 Tree::Tree(TreeMap* t, vector< vector<double> >& sims) : tmap(t) {
91         try {
92                 m = MothurOut::getInstance();
93                 
94                 if (m->runParse == true) {  parseTreeFile();  m->runParse = false;  }
95                 numLeaves = m->Treenames.size();
96                 numNodes = 2*numLeaves - 1;
97                 
98                 tree.resize(numNodes);
99         
100                 //initialize groupNodeInfo
101                 for (int i = 0; i < (tmap->getNamesOfGroups()).size(); i++) {
102                         groupNodeInfo[(tmap->getNamesOfGroups())[i]].resize(0);
103                 }
104                 
105                 //initialize tree with correct number of nodes, name and group info.
106                 for (int i = 0; i < numNodes; i++) {
107                         //initialize leaf nodes
108                         if (i <= (numLeaves-1)) {
109                                 tree[i].setName(m->Treenames[i]);
110                                 
111                                 //save group info
112                                 string group = tmap->getGroup(m->Treenames[i]);
113                                 
114                                 vector<string> tempGroups; tempGroups.push_back(group);
115                                 tree[i].setGroup(tempGroups);
116                                 groupNodeInfo[group].push_back(i); 
117                                 
118                                 //set pcount and pGroup for groupname to 1.
119                                 tree[i].pcount[group] = 1;
120                                 tree[i].pGroups[group] = 1;
121                                 
122                                 //Treemap knows name, group and index to speed up search
123                                 tmap->setIndex(m->Treenames[i], i);
124                 
125                 //intialize non leaf nodes
126                         }else if (i > (numLeaves-1)) {
127                                 tree[i].setName("");
128                                 vector<string> tempGroups;
129                                 tree[i].setGroup(tempGroups);
130                         }
131                 }
132         
133         //build tree from matrix
134         //initialize indexes
135         map<int, int> indexes;  //maps row in simMatrix to vector index in the tree
136         for (int g = 0; g < numLeaves; g++) {   indexes[g] = g; }
137                 
138                 //do merges and create tree structure by setting parents and children
139                 //there are numGroups - 1 merges to do
140                 for (int i = 0; i < (numLeaves - 1); i++) {
141                         float largest = -1000.0;
142                         
143                         if (m->control_pressed) { break; }
144                         
145                         int row, column;
146                         //find largest value in sims matrix by searching lower triangle
147                         for (int j = 1; j < sims.size(); j++) {
148                                 for (int k = 0; k < j; k++) {
149                                         if (sims[j][k] > largest) {  largest = sims[j][k]; row = j; column = k;  }
150                                 }
151                         }
152             
153                         //set non-leaf node info and update leaves to know their parents
154                         //non-leaf
155                         tree[numLeaves + i].setChildren(indexes[row], indexes[column]);
156                         
157                         //parents
158                         tree[indexes[row]].setParent(numLeaves + i);
159                         tree[indexes[column]].setParent(numLeaves + i);
160                         
161                         //blength = distance / 2;
162                         float blength = ((1.0 - largest) / 2);
163                         
164                         //branchlengths
165                         tree[indexes[row]].setBranchLength(blength - tree[indexes[row]].getLengthToLeaves());
166                         tree[indexes[column]].setBranchLength(blength - tree[indexes[column]].getLengthToLeaves());
167                         
168                         //set your length to leaves to your childs length plus branchlength
169                         tree[numLeaves + i].setLengthToLeaves(tree[indexes[row]].getLengthToLeaves() + tree[indexes[row]].getBranchLength());
170                         
171                         
172                         //update index 
173                         indexes[row] = numLeaves+i;
174                         indexes[column] = numLeaves+i;
175                         
176                         //remove highest value that caused the merge.
177                         sims[row][column] = -1000.0;
178                         sims[column][row] = -1000.0;
179                         
180                         //merge values in simsMatrix
181                         for (int n = 0; n < sims.size(); n++)   {
182                                 //row becomes merge of 2 groups
183                                 sims[row][n] = (sims[row][n] + sims[column][n]) / 2;
184                                 sims[n][row] = sims[row][n];
185                                 //delete column
186                                 sims[column][n] = -1000.0;
187                                 sims[n][column] = -1000.0;
188                         }
189                 }
190                 
191                 //adjust tree to make sure root to tip length is .5
192                 int root = findRoot();
193                 tree[root].setBranchLength((0.5 - tree[root].getLengthToLeaves()));
194         
195     }
196         catch(exception& e) {
197                 m->errorOut(e, "Tree", "Tree");
198                 exit(1);
199         }
200 }
201 /*****************************************************************/
202 Tree::~Tree() {}
203 /*****************************************************************/
204 void Tree::addNamesToCounts(map<string, string> nameMap) {
205         try {
206                 //ex. seq1      seq2,seq3,se4
207                 //              seq1 = pasture
208                 //              seq2 = forest
209                 //              seq4 = pasture
210                 //              seq3 = ocean
211                 
212                 //before this function seq1.pcount = pasture -> 1
213                 //after                            seq1.pcount = pasture -> 2, forest -> 1, ocean -> 1
214                 
215                 //before this function seq1.pgroups = pasture -> 1
216                 //after                            seq1.pgroups = pasture -> 1 since that is the dominant group
217
218                                 
219                 //go through each leaf and update its pcounts and pgroups
220                 
221                 //float A = clock();
222
223                 for (int i = 0; i < numLeaves; i++) {
224
225                         string name = tree[i].getName();
226                 
227                         map<string, string>::iterator itNames = nameMap.find(name);
228                 
229                         if (itNames == nameMap.end()) { m->mothurOut(name + " is not in your name file, please correct."); m->mothurOutEndLine(); exit(1);  }
230                         else {
231                                 vector<string> dupNames;
232                                 m->splitAtComma(nameMap[name], dupNames);
233                                 
234                                 map<string, int>::iterator itCounts;
235                                 int maxPars = 1;
236                                 set<string> groupsAddedForThisNode;
237                                 for (int j = 0; j < dupNames.size(); j++) {
238                                         
239                                         string group = tmap->getGroup(dupNames[j]);
240                                         
241                                         if (dupNames[j] != name) {//you already added yourself in the constructor
242                                 
243                                                 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
244                                                 
245                                                 //update pcounts
246                                                 itCounts = tree[i].pcount.find(group);
247                                                 if (itCounts == tree[i].pcount.end()) { //new group, add it
248                                                         tree[i].pcount[group] = 1;
249                                                 }else {
250                                                         tree[i].pcount[group]++;
251                                                 }
252                                                         
253                                                 //update pgroups
254                                                 itCounts = tree[i].pGroups.find(group);
255                                                 if (itCounts == tree[i].pGroups.end()) { //new group, add it
256                                                         tree[i].pGroups[group] = 1;
257                                                 }else{
258                                                         tree[i].pGroups[group]++;
259                                                 }
260                                                 
261                                                 //keep highest group
262                                                 if(tree[i].pGroups[group] > maxPars){
263                                                         maxPars = tree[i].pGroups[group];
264                                                 }
265                                         }else {  groupsAddedForThisNode.insert(group);  } //add it so you don't add it to groupNodeInfo again
266                                 }//end for
267                                 
268                                 if (maxPars > 1) { //then we have some more dominant groups
269                                         //erase all the groups that are less than maxPars because you found a more dominant group.
270                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();){
271                                                 if(it->second < maxPars){
272                                                         tree[i].pGroups.erase(it++);
273                                                 }else { it++; }
274                                         }
275                                         //set one remaining groups to 1
276                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();it++){
277                                                 tree[i].pGroups[it->first] = 1;
278                                         }
279                                 }//end if
280                                 
281                                 //update groups to reflect all the groups this node represents
282                                 vector<string> nodeGroups;
283                                 map<string, int>::iterator itGroups;
284                                 for (itGroups = tree[i].pcount.begin(); itGroups != tree[i].pcount.end(); itGroups++) {
285                                         nodeGroups.push_back(itGroups->first);
286                                 }
287                                 tree[i].setGroup(nodeGroups);
288                                 
289                         }//end else
290                 }//end for              
291                 
292                 //float B = clock();
293                 //cout << "addNamesToCounts\t" << (B - A) / CLOCKS_PER_SEC << endl;     
294
295         }
296         catch(exception& e) {
297                 m->errorOut(e, "Tree", "addNamesToCounts");
298                 exit(1);
299         }
300 }
301 /*****************************************************************/
302 int Tree::getIndex(string searchName) {
303         try {
304                 //Treemap knows name, group and index to speed up search
305                 // getIndex function will return the vector index or -1 if seq is not found.
306                 int index = tmap->getIndex(searchName);
307                 return index;
308                 
309         }
310         catch(exception& e) {
311                 m->errorOut(e, "Tree", "getIndex");
312                 exit(1);
313         }
314 }
315 /*****************************************************************/
316
317 void Tree::setIndex(string searchName, int index) {
318         try {
319                 //set index in treemap
320                 tmap->setIndex(searchName, index);
321         }
322         catch(exception& e) {
323                 m->errorOut(e, "Tree", "setIndex");
324                 exit(1);
325         }
326 }
327 /*****************************************************************/
328 int Tree::assembleTree(map<string, string> nameMap) {
329         try {
330                 //save for later
331         names = nameMap;
332
333                 //if user has given a names file we want to include that info in the pgroups and pcount info.
334                 if(nameMap.size() != 0) {  addNamesToCounts(nameMap);  }
335                 
336                 //build the pGroups in non leaf nodes to be used in the parsimony calcs.
337                 for (int i = numLeaves; i < numNodes; i++) {
338                         if (m->control_pressed) { return 1; }
339
340                         tree[i].pGroups = (mergeGroups(i));
341                         tree[i].pcount = (mergeGcounts(i));
342                 }
343                 
344                 return 0;
345         }
346         catch(exception& e) {
347                 m->errorOut(e, "Tree", "assembleTree");
348                 exit(1);
349         }
350 }
351 /*****************************************************************
352 int Tree::assembleTree(string n) {
353         try {
354                 
355                 //build the pGroups in non leaf nodes to be used in the parsimony calcs.
356                 for (int i = numLeaves; i < numNodes; i++) {
357                         if (m->control_pressed) { return 1; }
358
359                         tree[i].pGroups = (mergeGroups(i));
360                         tree[i].pcount = (mergeGcounts(i));
361                 }
362                 //float B = clock();
363                 //cout << "assembleTree\t" << (B-A) / CLOCKS_PER_SEC << endl;
364                 return 0;
365         }
366         catch(exception& e) {
367                 m->errorOut(e, "Tree", "assembleTree");
368                 exit(1);
369         }
370 }
371 /*****************************************************************/
372 //assumes leaf node names are in groups and no names file - used by indicator command
373 void Tree::getSubTree(Tree* Ctree, vector<string> Groups) {
374         try {
375         
376         //copy Tree since we are going to destroy it
377         Tree* copy = new Tree(tmap);
378         copy->getCopy(Ctree);
379         map<string, string> empty;
380         copy->assembleTree(empty);
381         
382                 //we want to select some of the leaf nodes to create the output tree
383                 //go through the input Tree starting at parents of leaves
384                 for (int i = 0; i < numNodes; i++) {
385                         
386                         //initialize leaf nodes
387                         if (i <= (numLeaves-1)) {
388                                 tree[i].setName(Groups[i]);
389                                 
390                                 //save group info
391                                 string group = tmap->getGroup(Groups[i]);
392                                 vector<string> tempGroups; tempGroups.push_back(group);
393                                 tree[i].setGroup(tempGroups);
394                                 groupNodeInfo[group].push_back(i); 
395                                 
396                                 //set pcount and pGroup for groupname to 1.
397                                 tree[i].pcount[group] = 1;
398                                 tree[i].pGroups[group] = 1;
399                                 
400                                 //Treemap knows name, group and index to speed up search
401                                 tmap->setIndex(Groups[i], i);
402                                 
403                                 //intialize non leaf nodes
404                         }else if (i > (numLeaves-1)) {
405                                 tree[i].setName("");
406                                 vector<string> tempGroups;
407                                 tree[i].setGroup(tempGroups);
408                         }
409                 }
410                 
411                 set<int> removedLeaves;
412                 for (int i = 0; i < copy->getNumLeaves(); i++) {
413                         
414                         if (removedLeaves.count(i) == 0) {
415                         
416                         //am I in the group
417                         int parent = copy->tree[i].getParent();
418                         
419                         if (parent != -1) {
420                                 
421                                 if (m->inUsersGroups(copy->tree[i].getName(), Groups)) {
422                                         //find my siblings name
423                                         int parentRC = copy->tree[parent].getRChild();
424                                         int parentLC = copy->tree[parent].getLChild();
425                                         
426                                         //if I am the right child, then my sib is the left child
427                                         int sibIndex = parentRC;
428                                         if (parentRC == i) { sibIndex = parentLC; }
429                                         
430                                         string sibsName = copy->tree[sibIndex].getName();
431                                         
432                                         //if yes, is my sibling
433                                         if ((m->inUsersGroups(sibsName, Groups)) || (sibsName == "")) {
434                                                 //we both are okay no trimming required
435                                         }else{
436                                                 //i am, my sib is not, so remove sib by setting my parent to my grandparent
437                                                 int grandparent = copy->tree[parent].getParent();
438                                                 int grandparentLC = copy->tree[grandparent].getLChild();
439                                                 int grandparentRC = copy->tree[grandparent].getRChild();
440                                                 
441                                                 //whichever of my granparents children was my parent now equals me
442                                                 if (grandparentLC == parent) { grandparentLC = i; }
443                                                 else { grandparentRC = i; }
444                                                 
445                                                 copy->tree[i].setParent(grandparent);
446                                                 copy->tree[i].setBranchLength((copy->tree[i].getBranchLength()+copy->tree[parent].getBranchLength()));
447                                                 if (grandparent != -1) {
448                                                         copy->tree[grandparent].setChildren(grandparentLC, grandparentRC);
449                                                 }
450                                                 removedLeaves.insert(sibIndex);
451                                         }
452                                 }else{
453                                         //find my siblings name
454                                         int parentRC = copy->tree[parent].getRChild();
455                                         int parentLC = copy->tree[parent].getLChild();
456                                         
457                                         //if I am the right child, then my sib is the left child
458                                         int sibIndex = parentRC;
459                                         if (parentRC == i) { sibIndex = parentLC; }
460                                         
461                                         string sibsName = copy->tree[sibIndex].getName();
462                                         
463                                         //if no is my sibling
464                                         if ((m->inUsersGroups(sibsName, Groups)) || (sibsName == "")) {
465                                                 //i am not, but my sib is
466                                                 int grandparent = copy->tree[parent].getParent();
467                                                 int grandparentLC = copy->tree[grandparent].getLChild();
468                                                 int grandparentRC = copy->tree[grandparent].getRChild();
469                                                 
470                                                 //whichever of my granparents children was my parent now equals my sib
471                                                 if (grandparentLC == parent) { grandparentLC = sibIndex; }
472                                                 else { grandparentRC = sibIndex; }
473                                                 
474                                                 copy->tree[sibIndex].setParent(grandparent);
475                                                 copy->tree[sibIndex].setBranchLength((copy->tree[sibIndex].getBranchLength()+copy->tree[parent].getBranchLength()));
476                                                 if (grandparent != -1) {
477                                                         copy->tree[grandparent].setChildren(grandparentLC, grandparentRC);
478                                                 }
479                                                 removedLeaves.insert(i);
480                                         }else{
481                                                 //neither of us are, so we want to eliminate ourselves and our parent
482                                                 //so set our parents sib to our great-grandparent
483                                                 int parent = copy->tree[i].getParent();
484                                                 int grandparent = copy->tree[parent].getParent();
485                                                 int parentsSibIndex;
486                                                 if (grandparent != -1) {
487                                                         int greatgrandparent = copy->tree[grandparent].getParent();
488                                                         int greatgrandparentLC, greatgrandparentRC;
489                                                         if (greatgrandparent != -1) {
490                                                                 greatgrandparentLC = copy->tree[greatgrandparent].getLChild();
491                                                                 greatgrandparentRC = copy->tree[greatgrandparent].getRChild();
492                                                         }
493                                                         
494                                                         int grandparentLC = copy->tree[grandparent].getLChild();
495                                                         int grandparentRC = copy->tree[grandparent].getRChild();
496                                                         
497                                                         parentsSibIndex = grandparentLC;
498                                                         if (grandparentLC == parent) { parentsSibIndex = grandparentRC; }
499
500                                                         //whichever of my greatgrandparents children was my grandparent
501                                                         if (greatgrandparentLC == grandparent) { greatgrandparentLC = parentsSibIndex; }
502                                                         else { greatgrandparentRC = parentsSibIndex; }
503                                                         
504                                                         copy->tree[parentsSibIndex].setParent(greatgrandparent);
505                                                         copy->tree[parentsSibIndex].setBranchLength((copy->tree[parentsSibIndex].getBranchLength()+copy->tree[grandparent].getBranchLength()));
506                                                         if (greatgrandparent != -1) {
507                                                                 copy->tree[greatgrandparent].setChildren(greatgrandparentLC, greatgrandparentRC);
508                                                         }
509                                                 }else{
510                                                         copy->tree[parent].setParent(-1);
511                                                         //cout << "issues with making subtree" << endl;
512                                                 }
513                                                 removedLeaves.insert(sibIndex);
514                                                 removedLeaves.insert(i);
515                                         }
516                                 }
517                         }
518                         }
519                 }
520                 
521                 int root = 0;
522                 for (int i = 0; i < copy->getNumNodes(); i++) {
523                         //you found the root
524                         if (copy->tree[i].getParent() == -1) { root = i; break; }
525                 }
526         
527                 int nextSpot = numLeaves;
528                 populateNewTree(copy->tree, root, nextSpot);
529         
530         delete copy;
531         }
532         catch(exception& e) {
533                 m->errorOut(e, "Tree", "getSubTree");
534                 exit(1);
535         }
536 }
537 /*****************************************************************/
538 //assumes nameMap contains unique names as key or is empty. 
539 //assumes numLeaves defined in tree constructor equals size of seqsToInclude and seqsToInclude only contains unique seqs.
540 int Tree::getSubTree(Tree* copy, vector<string> seqsToInclude, map<string, string> nameMap) {
541         try {
542         
543         if (numLeaves != seqsToInclude.size()) { m->mothurOut("[ERROR]: numLeaves does not equal numUniques, cannot create subtree.\n"); m->control_pressed = true; return 0; }
544         
545         getSubTree(copy, seqsToInclude);
546         if (nameMap.size() != 0) {  addNamesToCounts(nameMap);  }
547         
548         //build the pGroups in non leaf nodes to be used in the parsimony calcs.
549                 for (int i = numLeaves; i < numNodes; i++) {
550                         if (m->control_pressed) { return 1; }
551             
552                         tree[i].pGroups = (mergeGroups(i));
553                         tree[i].pcount = (mergeGcounts(i));
554                 }
555         
556         return 0;
557     }
558         catch(exception& e) {
559                 m->errorOut(e, "Tree", "getSubTree");
560                 exit(1);
561         }
562 }
563 /*****************************************************************/
564 int Tree::populateNewTree(vector<Node>& oldtree, int node, int& index) {
565         try {
566                 
567                 if (oldtree[node].getLChild() != -1) {
568                         int rc = populateNewTree(oldtree, oldtree[node].getLChild(), index);
569                         int lc = populateNewTree(oldtree, oldtree[node].getRChild(), index);
570
571                         tree[index].setChildren(lc, rc);
572                         tree[rc].setParent(index);
573                         tree[lc].setParent(index);
574                         
575                         tree[index].setBranchLength(oldtree[node].getBranchLength());
576                         tree[rc].setBranchLength(oldtree[oldtree[node].getLChild()].getBranchLength());
577                         tree[lc].setBranchLength(oldtree[oldtree[node].getRChild()].getBranchLength());
578                         
579                         return (index++);
580                 }else { //you are a leaf
581                         int indexInNewTree = tmap->getIndex(oldtree[node].getName());
582                         return indexInNewTree;
583                 }
584         }
585         catch(exception& e) {
586                 m->errorOut(e, "Tree", "populateNewTree");
587                 exit(1);
588         }
589 }
590 /*****************************************************************/
591 void Tree::getCopy(Tree* copy, map<string, string> nameMap, vector<string> namesToInclude) {
592         try {
593         
594                 //for each node in the tree copy its info
595                 for (int i = 0; i < numNodes; i++) {
596                         //copy name
597                         tree[i].setName(copy->tree[i].getName());
598             
599                         //copy group
600             vector<string> temp;
601                         tree[i].setGroup(temp);
602                         
603                         //copy branch length
604                         tree[i].setBranchLength(copy->tree[i].getBranchLength());
605             
606                         //copy parent
607                         tree[i].setParent(copy->tree[i].getParent());
608             
609                         //copy children
610                         tree[i].setChildren(copy->tree[i].getLChild(), copy->tree[i].getRChild());
611             
612                         //copy index in node and tmap
613                         tree[i].setIndex(copy->tree[i].getIndex());
614                         setIndex(copy->tree[i].getName(), getIndex(copy->tree[i].getName()));
615                         
616                         //copy pGroups
617                         tree[i].pGroups.clear();
618             
619                         //copy pcount
620                         tree[i].pcount.clear();
621                 }
622                 
623                 groupNodeInfo.clear();
624         
625         //now lets change prune the seqs not in namesToInclude by setting their group to "doNotIncludeMe"
626         for (int i = 0; i < numLeaves; i++) {
627             
628             if (m->control_pressed) { break; }
629             
630                         string name = tree[i].getName();
631             
632                         map<string, string>::iterator itNames = nameMap.find(name);
633             
634                         if (itNames == nameMap.end()) { m->mothurOut(name + " is not in your name file, please correct."); m->mothurOutEndLine(); exit(1);  }
635                         else {
636                                 vector<string> dupNames;
637                                 m->splitAtComma(nameMap[name], dupNames);
638                                 
639                                 map<string, int>::iterator itCounts;
640                                 int maxPars = 1;
641                                 set<string> groupsAddedForThisNode;
642                                 for (int j = 0; j < dupNames.size(); j++) {
643                                         
644                                         string group = tmap->getGroup(dupNames[j]);
645                     bool includeMe = m->inUsersGroups(dupNames[j], namesToInclude);
646                     
647                     if (!includeMe && (group != "doNotIncludeMe")) { m->mothurOut("[ERROR] : creating subtree in copy.\n"); m->control_pressed = true; }
648                                         else if (!includeMe) {
649                                                 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
650                                                 
651                                                 //update pcounts
652                                                 itCounts = tree[i].pcount.find(group);
653                                                 if (itCounts == tree[i].pcount.end()) { //new group, add it
654                                                         tree[i].pcount[group] = 1;
655                                                 }else {
656                                                         tree[i].pcount[group]++;
657                                                 }
658                         
659                                                 //update pgroups
660                                                 itCounts = tree[i].pGroups.find(group);
661                                                 if (itCounts == tree[i].pGroups.end()) { //new group, add it
662                                                         tree[i].pGroups[group] = 1;
663                                                 }else{
664                                                         tree[i].pGroups[group]++;
665                                                 }
666                                                 
667                                                 //keep highest group
668                                                 if(tree[i].pGroups[group] > maxPars){
669                                                         maxPars = tree[i].pGroups[group];
670                                                 }
671                     }
672                                 }//end for
673                                 
674                                 if (maxPars > 1) { //then we have some more dominant groups
675                                         //erase all the groups that are less than maxPars because you found a more dominant group.
676                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();){
677                                                 if(it->second < maxPars){
678                                                         tree[i].pGroups.erase(it++);
679                                                 }else { it++; }
680                                         }
681                                         //set one remaining groups to 1
682                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();it++){
683                                                 tree[i].pGroups[it->first] = 1;
684                                         }
685                                 }//end if
686                                 
687                                 //update groups to reflect all the groups this node represents
688                                 vector<string> nodeGroups;
689                                 map<string, int>::iterator itGroups;
690                                 for (itGroups = tree[i].pcount.begin(); itGroups != tree[i].pcount.end(); itGroups++) {
691                                         nodeGroups.push_back(itGroups->first);
692                                 }
693                                 tree[i].setGroup(nodeGroups);
694                                 
695                         }//end else
696                 }//end for              
697         
698         
699         //build the pGroups in non leaf nodes to be used in the parsimony calcs.
700                 for (int i = numLeaves; i < numNodes; i++) {
701                         if (m->control_pressed) { break; }
702             
703                         tree[i].pGroups = (mergeGroups(i));
704                         tree[i].pcount = (mergeGcounts(i));
705                 }
706         }
707         catch(exception& e) {
708                 m->errorOut(e, "Tree", "getCopy");
709                 exit(1);
710         }
711 }
712 /*****************************************************************/
713 void Tree::getCopy(Tree* copy) {
714         try {
715         
716                 //for each node in the tree copy its info
717                 for (int i = 0; i < numNodes; i++) {
718                         //copy name
719                         tree[i].setName(copy->tree[i].getName());
720                 
721                         //copy group
722                         tree[i].setGroup(copy->tree[i].getGroup());
723                         
724                         //copy branch length
725                         tree[i].setBranchLength(copy->tree[i].getBranchLength());
726                 
727                         //copy parent
728                         tree[i].setParent(copy->tree[i].getParent());
729                 
730                         //copy children
731                         tree[i].setChildren(copy->tree[i].getLChild(), copy->tree[i].getRChild());
732                 
733                         //copy index in node and tmap
734                         tree[i].setIndex(copy->tree[i].getIndex());
735                         setIndex(copy->tree[i].getName(), getIndex(copy->tree[i].getName()));
736                         
737                         //copy pGroups
738                         tree[i].pGroups = copy->tree[i].pGroups;
739                 
740                         //copy pcount
741                         tree[i].pcount = copy->tree[i].pcount;
742                 }
743                 
744                 groupNodeInfo = copy->groupNodeInfo;
745                 
746         }
747         catch(exception& e) {
748                 m->errorOut(e, "Tree", "getCopy");
749                 exit(1);
750         }
751 }
752 /*****************************************************************/
753 //returns a map with a groupname and the number of times that group was seen in the children
754 //for instance if your children are white and black then it would return a map with 2 entries
755 // p[white] = 1 and p[black] = 1.  Now go up a level and merge that with a node who has p[white] = 1
756 //and you get p[white] = 2, p[black] = 1, but you erase the p[black] because you have a p value higher than 1.
757
758 map<string, int> Tree::mergeGroups(int i) {
759         try {
760                 int lc = tree[i].getLChild();
761                 int rc = tree[i].getRChild();
762
763                 //set parsimony groups to left child
764                 map<string,int> parsimony = tree[lc].pGroups;
765                 
766                 int maxPars = 1;
767
768                 //look at right child groups and update maxPars if right child has something higher for that group.
769                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();it++){
770                         it2 = parsimony.find(it->first);
771                         if (it2 != parsimony.end()) {
772                                 parsimony[it->first]++;
773                         }else {
774                                 parsimony[it->first] = 1;
775                         }
776                         
777                         if(parsimony[it->first] > maxPars){
778                                 maxPars = parsimony[it->first];
779                         }
780                 }
781         
782                 // this is true if right child had a greater parsimony for a certain group
783                 if(maxPars > 1){
784                         //erase all the groups that are only 1 because you found something with 2.
785                         for(it=parsimony.begin();it!=parsimony.end();){
786                                 if(it->second == 1){
787                                         parsimony.erase(it++);
788                                 }else { it++; }
789                         }
790                         //set one remaining groups to 1
791                         //so with our above example p[white] = 2 would be left and it would become p[white] = 1
792                         for(it=parsimony.begin();it!=parsimony.end();it++){
793                                 parsimony[it->first] = 1;
794                         }
795                 
796                 }
797         
798                 return parsimony;
799         }
800         catch(exception& e) {
801                 m->errorOut(e, "Tree", "mergeGroups");
802                 exit(1);
803         }
804 }
805 /*****************************************************************/
806 //returns a map with a groupname and the number of times that group was seen in the children
807 //for instance if your children are white and black then it would return a map with 2 entries
808 // p[white] = 1 and p[black] = 1.  Now go up a level and merge that with a node who has p[white] = 1
809 //and you get p[white] = 2, p[black] = 1, but you erase the p[black] because you have a p value higher than 1.
810
811 map<string, int> Tree::mergeUserGroups(int i, vector<string> g) {
812         try {
813         
814                 int lc = tree[i].getLChild();
815                 int rc = tree[i].getRChild();
816                 
817                 //loop through nodes groups removing the ones the user doesn't want
818                 for(it=tree[lc].pGroups.begin();it!=tree[lc].pGroups.end();){
819                                 if (m->inUsersGroups(it->first, g) != true) {
820                                         tree[lc].pGroups.erase(it++);
821                                 }else { it++; }
822                 }
823
824                 //loop through nodes groups removing the ones the user doesn't want
825                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();){
826                                 if (m->inUsersGroups(it->first, g) != true) {
827                                         tree[rc].pGroups.erase(it++);
828                                 }else { it++; }
829                 }
830
831                 //set parsimony groups to left child
832                 map<string,int> parsimony = tree[lc].pGroups;
833                 
834                 int maxPars = 1;
835
836                 //look at right child groups and update maxPars if right child has something higher for that group.
837                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();it++){
838                         it2 = parsimony.find(it->first);
839                         if (it2 != parsimony.end()) {
840                                 parsimony[it->first]++;
841                         }else {
842                                 parsimony[it->first] = 1;
843                         }
844                         
845                         if(parsimony[it->first] > maxPars){
846                                 maxPars = parsimony[it->first];
847                         }
848                 }
849                         
850                 // this is true if right child had a greater parsimony for a certain group
851                 if(maxPars > 1){
852                         //erase all the groups that are only 1 because you found something with 2.
853                         for(it=parsimony.begin();it!=parsimony.end();){
854                                 if(it->second == 1){
855                                         parsimony.erase(it++);
856                                 }else { it++; }
857                         }
858
859                         for(it=parsimony.begin();it!=parsimony.end();it++){
860                                 parsimony[it->first] = 1;
861                         }
862                 }               
863                 
864                 return parsimony;
865         }
866         catch(exception& e) {
867                 m->errorOut(e, "Tree", "mergeUserGroups");
868                 exit(1);
869         }
870 }
871
872
873 /**************************************************************************************************/
874
875 map<string,int> Tree::mergeGcounts(int position) {
876         try{
877                 map<string,int>::iterator pos;
878         
879                 int lc = tree[position].getLChild();
880                 int rc = tree[position].getRChild();
881         
882                 map<string,int> sum = tree[lc].pcount;
883     
884                 for(it=tree[rc].pcount.begin();it!=tree[rc].pcount.end();it++){
885                         sum[it->first] += it->second;
886                 }
887                 return sum;
888         }
889         catch(exception& e) {
890                 m->errorOut(e, "Tree", "mergeGcounts");
891                 exit(1);
892         }
893 }
894 /**************************************************************************************************/
895 void Tree::randomLabels(vector<string> g) {
896         try {
897         
898                 //initialize groupNodeInfo
899                 for (int i = 0; i < (tmap->getNamesOfGroups()).size(); i++) {
900                         groupNodeInfo[(tmap->getNamesOfGroups())[i]].resize(0);
901                 }
902                 
903                 for(int i = 0; i < numLeaves; i++){
904                         int z;
905                         //get random index to switch with
906                         z = int((float)(i+1) * (float)(rand()) / ((float)RAND_MAX+1.0));        
907                         
908                         //you only want to randomize the nodes that are from a group the user wants analyzed, so
909                         //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.
910                         bool treez, treei;
911                 
912                         treez = m->inUsersGroups(tree[z].getGroup(), g);
913                         treei = m->inUsersGroups(tree[i].getGroup(), g);
914                         
915                         if ((treez == true) && (treei == true)) {
916                                 //switches node i and node z's info.
917                                 map<string,int> lib_hold = tree[z].pGroups;
918                                 tree[z].pGroups = (tree[i].pGroups);
919                                 tree[i].pGroups = (lib_hold);
920                                 
921                                 vector<string> zgroup = tree[z].getGroup();
922                                 tree[z].setGroup(tree[i].getGroup());
923                                 tree[i].setGroup(zgroup);
924                                 
925                                 string zname = tree[z].getName();
926                                 tree[z].setName(tree[i].getName());
927                                 tree[i].setName(zname);
928                                 
929                                 map<string,int> gcount_hold = tree[z].pcount;
930                                 tree[z].pcount = (tree[i].pcount);
931                                 tree[i].pcount = (gcount_hold);
932                         }
933                         
934                         for (int k = 0; k < (tree[i].getGroup()).size(); k++) {  groupNodeInfo[(tree[i].getGroup())[k]].push_back(i); }
935                         for (int k = 0; k < (tree[z].getGroup()).size(); k++) {  groupNodeInfo[(tree[z].getGroup())[k]].push_back(z); }
936                 }
937         }
938         catch(exception& e) {
939                 m->errorOut(e, "Tree", "randomLabels");
940                 exit(1);
941         }
942 }
943 /**************************************************************************************************/
944 void Tree::randomBlengths()  {
945         try {
946                 for(int i=numNodes-1;i>=0;i--){
947                         int z = int((float)(i+1) * (float)(rand()) / ((float)RAND_MAX+1.0));    
948                 
949                         float bl_hold = tree[z].getBranchLength();
950                         tree[z].setBranchLength(tree[i].getBranchLength());
951                         tree[i].setBranchLength(bl_hold);
952                 }
953         }
954         catch(exception& e) {
955                 m->errorOut(e, "Tree", "randomBlengths");
956                 exit(1);
957         }
958 }
959 /*************************************************************************************************/
960 void Tree::assembleRandomUnifracTree(vector<string> g) {
961         randomLabels(g);
962     map<string, string> empty;
963         assembleTree(empty);
964 }
965 /*************************************************************************************************/
966 void Tree::assembleRandomUnifracTree(string groupA, string groupB) {
967         vector<string> temp; temp.push_back(groupA); temp.push_back(groupB);
968         randomLabels(temp);
969     map<string, string> empty;
970         assembleTree(empty);
971 }
972
973 /*************************************************************************************************/
974 //for now it's just random topology but may become random labels as well later that why this is such a simple function now...
975 void Tree::assembleRandomTree() {
976         randomTopology();
977     map<string, string> empty;
978         assembleTree(empty);
979 }
980 /**************************************************************************************************/
981
982 void Tree::randomTopology() {
983         try {
984                 for(int i=0;i<numNodes;i++){
985                         tree[i].setParent(-1);
986                 }
987                 for(int i=numLeaves;i<numNodes;i++){
988                         tree[i].setChildren(-1, -1); 
989                 }
990     
991                 for(int i=numLeaves;i<numNodes;i++){
992                         int escape =0;
993                         int rnd_index1, rnd_index2;
994                         while(escape == 0){
995                                 rnd_index1 = (int)(((double)rand() / (double) RAND_MAX)*i);
996                                 if(tree[rnd_index1].getParent() == -1){escape = 1;}
997                         }
998                 
999                         escape = 0;
1000                         while(escape == 0){
1001                                 rnd_index2 = (int)(((double)rand() / (double) RAND_MAX)*i);
1002                                 if(rnd_index2 != rnd_index1 && tree[rnd_index2].getParent() == -1){
1003                                         escape = 1;
1004                                 }               
1005                         }
1006         
1007                         tree[i].setChildren(rnd_index1,rnd_index2);
1008                         tree[i].setParent(-1);
1009                         tree[rnd_index1].setParent(i);
1010                         tree[rnd_index2].setParent(i);
1011                 }
1012         }
1013         catch(exception& e) {
1014                 m->errorOut(e, "Tree", "randomTopology");
1015                 exit(1);
1016         }
1017 }
1018 /*****************************************************************/
1019 void Tree::print(ostream& out) {
1020         try {
1021                 int root = findRoot();
1022                 printBranch(root, out, "branch");
1023                 out << ";" << endl;
1024         }
1025         catch(exception& e) {
1026                 m->errorOut(e, "Tree", "print");
1027                 exit(1);
1028         }
1029 }
1030 /*****************************************************************/
1031 void Tree::print(ostream& out, map<string, string> nameMap) {
1032         try {
1033                 int root = findRoot();
1034                 printBranch(root, out, nameMap);
1035                 out << ";" << endl;
1036         }
1037         catch(exception& e) {
1038                 m->errorOut(e, "Tree", "print");
1039                 exit(1);
1040         }
1041 }
1042 /*****************************************************************/
1043 void Tree::print(ostream& out, string mode) {
1044         try {
1045                 int root = findRoot();
1046                 printBranch(root, out, mode);
1047                 out << ";" << endl;
1048         }
1049         catch(exception& e) {
1050                 m->errorOut(e, "Tree", "print");
1051                 exit(1);
1052         }
1053 }
1054 /*****************************************************************/
1055 // This prints out the tree in Newick form.
1056 void Tree::createNewickFile(string f) {
1057         try {
1058                 int root = findRoot();
1059         
1060                 filename = f;
1061
1062                 m->openOutputFile(filename, out);
1063                 
1064                 printBranch(root, out, "branch");
1065                 
1066                 // you are at the end of the tree
1067                 out << ";" << endl;
1068                 out.close();
1069         }
1070         catch(exception& e) {
1071                 m->errorOut(e, "Tree", "createNewickFile");
1072                 exit(1);
1073         }
1074 }
1075
1076 /*****************************************************************/
1077 //This function finds the index of the root node.
1078
1079 int Tree::findRoot() {
1080         try {
1081                 for (int i = 0; i < numNodes; i++) {
1082                         //you found the root
1083                         if (tree[i].getParent() == -1) { return i; }
1084                         //cout << "i = " << i << endl;
1085                         //cout << "i's parent = " << tree[i].getParent() << endl;  
1086                 }
1087                 return -1;
1088         }
1089         catch(exception& e) {
1090                 m->errorOut(e, "Tree", "findRoot");
1091                 exit(1);
1092         }
1093 }
1094 /*****************************************************************/
1095 void Tree::printBranch(int node, ostream& out, map<string, string> names) {
1096 try {
1097
1098 // you are not a leaf
1099                 if (tree[node].getLChild() != -1) {
1100                         out << "(";
1101                         printBranch(tree[node].getLChild(), out, names);
1102                         out << ",";
1103                         printBranch(tree[node].getRChild(), out, names);
1104                         out << ")";
1105                         
1106             //if there is a branch length then print it
1107             if (tree[node].getBranchLength() != -1) {
1108                 out << ":" << tree[node].getBranchLength();
1109             }
1110                         
1111                 }else { //you are a leaf
1112             map<string, string>::iterator itNames = names.find(tree[node].getName());
1113             
1114             string outputString = "";
1115             if (itNames != names.end()) { 
1116                 
1117                 vector<string> dupNames;
1118                 m->splitAtComma((itNames->second), dupNames);
1119                 
1120                 if (dupNames.size() == 1) {
1121                     outputString += tree[node].getName();
1122                     if (tree[node].getBranchLength() != -1) {
1123                         outputString += ":" + toString(tree[node].getBranchLength());
1124                     }
1125                 }else {
1126                     outputString += "(";
1127                     
1128                     for (int u = 0; u < dupNames.size()-1; u++) {
1129                         outputString += dupNames[u];
1130                         
1131                         if (tree[node].getBranchLength() != -1) {
1132                             outputString += ":" + toString(0.0);
1133                         }
1134                         outputString += ",";
1135                     }
1136                     
1137                     outputString += dupNames[dupNames.size()-1];
1138                     if (tree[node].getBranchLength() != -1) {
1139                         outputString += ":" + toString(0.0);
1140                     }
1141                     
1142                     outputString += ")";
1143                     if (tree[node].getBranchLength() != -1) {
1144                         outputString += ":" + toString(tree[node].getBranchLength());
1145                     }
1146                 }
1147             }else { 
1148                 outputString = tree[node].getName();
1149                 //if there is a branch length then print it
1150                 if (tree[node].getBranchLength() != -1) {
1151                     outputString += ":" + toString(tree[node].getBranchLength());
1152                 }
1153                 
1154                 m->mothurOut("[ERROR]: " + tree[node].getName() + " is not in your namefile, please correct."); m->mothurOutEndLine(); 
1155             }
1156                 
1157             out << outputString;
1158                 }
1159                 
1160         }
1161         catch(exception& e) {
1162                 m->errorOut(e, "Tree", "printBranch");
1163                 exit(1);
1164         }
1165 }
1166 /*****************************************************************/
1167 void Tree::printBranch(int node, ostream& out, string mode) {
1168     try {
1169         
1170         // you are not a leaf
1171                 if (tree[node].getLChild() != -1) {
1172                         out << "(";
1173                         printBranch(tree[node].getLChild(), out, mode);
1174                         out << ",";
1175                         printBranch(tree[node].getRChild(), out, mode);
1176                         out << ")";
1177                         if (mode == "branch") {
1178                                 //if there is a branch length then print it
1179                                 if (tree[node].getBranchLength() != -1) {
1180                                         out << ":" << tree[node].getBranchLength();
1181                                 }
1182                         }else if (mode == "boot") {
1183                                 //if there is a label then print it
1184                                 if (tree[node].getLabel() != -1) {
1185                                         out << tree[node].getLabel();
1186                                 }
1187                         }else if (mode == "both") {
1188                                 if (tree[node].getLabel() != -1) {
1189                                         out << tree[node].getLabel();
1190                                 }
1191                                 //if there is a branch length then print it
1192                                 if (tree[node].getBranchLength() != -1) {
1193                                         out << ":" << tree[node].getBranchLength();
1194                                 }
1195                         }
1196                 }else { //you are a leaf
1197                         string leafGroup = tmap->getGroup(tree[node].getName());
1198                         
1199                         if (mode == "branch") {
1200                                 out << leafGroup; 
1201                                 //if there is a branch length then print it
1202                                 if (tree[node].getBranchLength() != -1) {
1203                                         out << ":" << tree[node].getBranchLength();
1204                                 }
1205                         }else if (mode == "boot") {
1206                                 out << leafGroup; 
1207                                 //if there is a label then print it
1208                                 if (tree[node].getLabel() != -1) {
1209                                         out << tree[node].getLabel();
1210                                 }
1211                         }else if (mode == "both") {
1212                                 out << tree[node].getName();
1213                                 if (tree[node].getLabel() != -1) {
1214                                         out << tree[node].getLabel();
1215                                 }
1216                                 //if there is a branch length then print it
1217                                 if (tree[node].getBranchLength() != -1) {
1218                                         out << ":" << tree[node].getBranchLength();
1219                                 }
1220                         }
1221                 }
1222                 
1223         }
1224         catch(exception& e) {
1225                 m->errorOut(e, "Tree", "printBranch");
1226                 exit(1);
1227         }
1228 }
1229 /*****************************************************************/
1230 void Tree::printBranch(int node, ostream& out, string mode, vector<Node>& theseNodes) {
1231         try {
1232                 
1233                 // you are not a leaf
1234                 if (theseNodes[node].getLChild() != -1) {
1235                         out << "(";
1236                         printBranch(theseNodes[node].getLChild(), out, mode);
1237                         out << ",";
1238                         printBranch(theseNodes[node].getRChild(), out, mode);
1239                         out << ")";
1240                         if (mode == "branch") {
1241                                 //if there is a branch length then print it
1242                                 if (theseNodes[node].getBranchLength() != -1) {
1243                                         out << ":" << theseNodes[node].getBranchLength();
1244                                 }
1245                         }else if (mode == "boot") {
1246                                 //if there is a label then print it
1247                                 if (theseNodes[node].getLabel() != -1) {
1248                                         out << theseNodes[node].getLabel();
1249                                 }
1250                         }else if (mode == "both") {
1251                                 if (theseNodes[node].getLabel() != -1) {
1252                                         out << theseNodes[node].getLabel();
1253                                 }
1254                                 //if there is a branch length then print it
1255                                 if (theseNodes[node].getBranchLength() != -1) {
1256                                         out << ":" << theseNodes[node].getBranchLength();
1257                                 }
1258                         }
1259                 }else { //you are a leaf
1260                         string leafGroup = tmap->getGroup(theseNodes[node].getName());
1261                         
1262                         if (mode == "branch") {
1263                                 out << leafGroup; 
1264                                 //if there is a branch length then print it
1265                                 if (theseNodes[node].getBranchLength() != -1) {
1266                                         out << ":" << theseNodes[node].getBranchLength();
1267                                 }
1268                         }else if (mode == "boot") {
1269                                 out << leafGroup; 
1270                                 //if there is a label then print it
1271                                 if (theseNodes[node].getLabel() != -1) {
1272                                         out << theseNodes[node].getLabel();
1273                                 }
1274                         }else if (mode == "both") {
1275                                 out << theseNodes[node].getName();
1276                                 if (theseNodes[node].getLabel() != -1) {
1277                                         out << theseNodes[node].getLabel();
1278                                 }
1279                                 //if there is a branch length then print it
1280                                 if (theseNodes[node].getBranchLength() != -1) {
1281                                         out << ":" << theseNodes[node].getBranchLength();
1282                                 }
1283                         }
1284                 }
1285                 
1286         }
1287         catch(exception& e) {
1288                 m->errorOut(e, "Tree", "printBranch");
1289                 exit(1);
1290         }
1291 }
1292 /*****************************************************************/
1293
1294 void Tree::printTree() {
1295         
1296         for(int i=0;i<numNodes;i++){
1297                 cout << i << '\t';
1298                 tree[i].printNode();
1299         }
1300         
1301 }
1302
1303 /*****************************************************************/
1304 //this code is a mess and should be rethought...-slw
1305 void Tree::parseTreeFile() {
1306         
1307         //only takes names from the first tree and assumes that all trees use the same names.
1308         try {
1309                 string filename = m->getTreeFile();
1310                 ifstream filehandle;
1311                 m->openInputFile(filename, filehandle);
1312                 int c, comment;
1313                 comment = 0;
1314                 int done = 1;
1315                 
1316                 //ifyou are not a nexus file 
1317                 if((c = filehandle.peek()) != '#') {  
1318                         while((c = filehandle.peek()) != ';') { 
1319                                 while ((c = filehandle.peek()) != ';') {
1320                                         // get past comments
1321                                         if(c == '[') {
1322                                                 comment = 1;
1323                                         }
1324                                         if(c == ']'){
1325                                                 comment = 0;
1326                                         }
1327                                         if((c == '(') && (comment != 1)){ break; }
1328                                         filehandle.get();
1329                                 }
1330
1331                                 done = readTreeString(filehandle); 
1332                                 if (done == 0) { break; }
1333                         }
1334                 //ifyou are a nexus file
1335                 }else if((c = filehandle.peek()) == '#') {
1336                         string holder = "";
1337                                         
1338                         // get past comments
1339                         while(holder != "translate" && holder != "Translate"){  
1340                                 if(holder == "[" || holder == "[!"){
1341                                         comment = 1;
1342                                 }
1343                                 if(holder == "]"){
1344                                         comment = 0;
1345                                 }
1346                                 filehandle >> holder; 
1347
1348                                 //if there is no translate then you must read tree string otherwise use translate to get names
1349                                 if((holder == "tree") && (comment != 1)){       
1350                                         //pass over the "tree rep.6878900 = "
1351                                         while (((c = filehandle.get()) != '(') && ((c = filehandle.peek()) != EOF)) {;}
1352
1353                                         if(c == EOF) { break; }
1354                                         filehandle.putback(c);  //put back first ( of tree.
1355                                         done = readTreeString(filehandle);
1356         
1357                                         break;
1358                                 }
1359                         
1360                                 if (done == 0) { break;  }
1361                         }
1362                         
1363                         //use nexus translation rather than parsing tree to save time
1364                         if((holder == "translate") || (holder == "Translate")) {
1365
1366                                 string number, name, h;
1367                                 h = ""; // so it enters the loop the first time
1368                                 while((h != ";") && (number != ";")) { 
1369                                         filehandle >> number;
1370                                         filehandle >> name;
1371         
1372                                         //c = , until done with translation then c = ;
1373                                         h = name.substr(name.length()-1, name.length()); 
1374                                         name.erase(name.end()-1);  //erase the comma
1375                                         m->Treenames.push_back(number);
1376                                 }
1377                                 if(number == ";") { m->Treenames.pop_back(); }  //in case ';' from translation is on next line instead of next to last name
1378                         }
1379                 }
1380                 filehandle.close();
1381                 
1382                 //for (int i = 0; i < globaldata->Treenames.size(); i++) {
1383 //cout << globaldata->Treenames[i] << endl; }
1384 //cout << globaldata->Treenames.size() << endl;
1385         }
1386         catch(exception& e) {
1387                 m->errorOut(e, "Tree", "parseTreeFile");
1388                 exit(1);
1389         }
1390 }
1391 /*******************************************************/
1392
1393 /*******************************************************/
1394 int Tree::readTreeString(ifstream& filehandle)  {
1395         try {
1396                 int c;
1397                 string name;  //, k
1398                 
1399                 while((c = filehandle.peek()) != ';') { 
1400 //k = c;
1401 //cout << " at beginning of while " <<  k << endl;                      
1402                         if(c == ')')  {    
1403                                 //to pass over labels in trees
1404                                 c=filehandle.get();
1405                                 while((c!=',') && (c != -1) && (c!= ':') && (c!=';')){ c=filehandle.get(); }
1406                                 filehandle.putback(c);
1407                         }
1408                         if(c == ';') { return 0; }
1409                         if(c == -1) { return 0; }
1410                         //if you are a name
1411                         if((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != '\t') && (c != 32)) { //32 is space
1412                                 name = "";
1413                                 c = filehandle.get();
1414                         //k = c;
1415 //cout << k << endl;
1416                                 while ((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != 32) && (c != '\t')) {                       
1417                                         name += c;
1418                                         c = filehandle.get();
1419                         //k = c;
1420 //cout << " in name while " << k << endl;
1421                                 }
1422                                 
1423 //cout << "name = " << name << endl;
1424                                 m->Treenames.push_back(name);
1425                                 filehandle.putback(c);
1426 //k = c;
1427 //cout << " after putback" <<  k << endl;
1428                         } 
1429                         
1430                         if(c  == ':') { //read until you reach the end of the branch length
1431                                 while ((c != '(') && (c != ')') && (c != ',') && (c != ';') && (c != '\n') && (c != '\t') && (c != 32)) {
1432                                         c = filehandle.get();
1433         //k = c;
1434         //cout << " in branch while " << k << endl;
1435                                 }
1436                                 filehandle.putback(c);
1437                         }
1438                 
1439                         c = filehandle.get();
1440 //k = c;
1441         //cout << " here after get " << k << endl;
1442                         if(c == ';') { return 0; }
1443                         if(c == ')') { filehandle.putback(c); }
1444         //k = c;
1445 //cout << k << endl;
1446
1447                 }
1448                 return 0;
1449         }
1450         catch(exception& e) {
1451                 m->errorOut(e, "Tree", "readTreeString");
1452                 exit(1);
1453         }
1454 }       
1455
1456 /*******************************************************/
1457
1458 /*******************************************************/
1459