]> git.donarmstrong.com Git - mothur.git/blob - tree.cpp
created mothurOut class to handle logfiles
[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 /*****************************************************************/
14 Tree::Tree() {
15         try {
16                 globaldata = GlobalData::getInstance();
17                 m = MothurOut::getInstance();
18                 
19                 if (globaldata->runParse == true) {  parseTreeFile();  globaldata->runParse = false;  }
20 //for(int i = 0; i <    globaldata->Treenames.size(); i++) { cout << i << '\t' << globaldata->Treenames[i] << endl;  }  
21                 numLeaves = globaldata->Treenames.size();
22                 numNodes = 2*numLeaves - 1;
23                 
24                 tree.resize(numNodes);
25
26                 //initialize tree with correct number of nodes, name and group info.
27                 for (int i = 0; i < numNodes; i++) {
28                         //initialize leaf nodes
29                         if (i <= (numLeaves-1)) {
30                                 tree[i].setName(globaldata->Treenames[i]);
31                                 vector<string> tempGroups; tempGroups.push_back(globaldata->gTreemap->getGroup(globaldata->Treenames[i]));
32                                 tree[i].setGroup(tempGroups);
33                                 //set pcount and pGroup for groupname to 1.
34                                 tree[i].pcount[globaldata->gTreemap->getGroup(globaldata->Treenames[i])] = 1;
35                                 tree[i].pGroups[globaldata->gTreemap->getGroup(globaldata->Treenames[i])] = 1;
36                                 //Treemap knows name, group and index to speed up search
37                                 globaldata->gTreemap->setIndex(globaldata->Treenames[i], i);
38         
39                         //intialize non leaf nodes
40                         }else if (i > (numLeaves-1)) {
41                                 tree[i].setName("");
42                                 vector<string> tempGroups;
43                                 tree[i].setGroup(tempGroups);
44                         }
45                 }
46         }
47         catch(exception& e) {
48                 m->errorOut(e, "Tree", "Tree");
49                 exit(1);
50         }
51 }
52
53 /*****************************************************************/
54 Tree::~Tree() {}
55 /*****************************************************************/
56 void Tree::addNamesToCounts() {
57         try {
58                 //ex. seq1      seq2,seq3,se4
59                 //              seq1 = pasture
60                 //              seq2 = forest
61                 //              seq4 = pasture
62                 //              seq3 = ocean
63                 
64                 //before this function seq1.pcount = pasture -> 1
65                 //after                            seq1.pcount = pasture -> 2, forest -> 1, ocean -> 1
66                 
67                 //before this function seq1.pgroups = pasture -> 1
68                 //after                            seq1.pgroups = pasture -> 1 since that is the dominant group
69
70                                 
71                 //go through each leaf and update its pcounts and pgroups
72                 for (int i = 0; i < numLeaves; i++) {
73                         string name = tree[i].getName();
74                         
75                         map<string, string>::iterator itNames = globaldata->names.find(name);
76                         
77                         if (itNames == globaldata->names.end()) { m->mothurOut(name + " is not in your name file, please correct."); m->mothurOutEndLine(); exit(1);  }
78                         else {
79                                 vector<string> dupNames;
80                                 splitAtComma(globaldata->names[name], dupNames);
81                                 
82                                 map<string, int>::iterator itCounts;
83                                 int maxPars = 1;
84                                 for (int j = 0; j < dupNames.size(); j++) {
85                                 
86                                         if (dupNames[j] != name) {//you already added yourself in the constructor
87                                                 string group = globaldata->gTreemap->getGroup(dupNames[j]);
88                                                 
89                                                 //update pcounts
90                                                 itCounts = tree[i].pcount.find(group);
91                                                 if (itCounts == tree[i].pcount.end()) { //new group, add it
92                                                         tree[i].pcount[group] = 1;
93                                                 }else {
94                                                         tree[i].pcount[group]++;
95                                                 }
96                                                         
97                                                 //update pgroups
98                                                 itCounts = tree[i].pGroups.find(group);
99                                                 if (itCounts == tree[i].pGroups.end()) { //new group, add it
100                                                         tree[i].pGroups[group] = 1;
101                                                 }else {
102                                                         tree[i].pGroups[group]++;
103                                                 }
104                                                 
105                                                 //keep highest group
106                                                 if(tree[i].pGroups[group] > maxPars){
107                                                         maxPars = tree[i].pGroups[group];
108                                                 }
109                                         }//end if
110                                 }//end for
111                                 
112                                 if (maxPars > 1) { //then we have some more dominant groups
113                                         //erase all the groups that are less than maxPars because you found a more dominant group.
114                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();){
115                                                 if(it->second < maxPars){
116                                                         tree[i].pGroups.erase(it++);
117                                                 }else { it++; }
118                                         }
119                                         //set one remaining groups to 1
120                                         for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();it++){
121                                                 tree[i].pGroups[it->first] = 1;
122                                         }
123                                 }//end if
124                                 
125                                 //update groups to reflect all the groups this node represents
126                                 vector<string> nodeGroups;
127                                 map<string, int>::iterator itGroups;
128                                 for (itGroups = tree[i].pcount.begin(); itGroups != tree[i].pcount.end(); itGroups++) {
129                                         nodeGroups.push_back(itGroups->first);
130                                 }
131                                 tree[i].setGroup(nodeGroups);
132                                 
133                         }//end else
134                 }//end for
135                                 
136         }
137         catch(exception& e) {
138                 m->errorOut(e, "Tree", "addNamesToCounts");
139                 exit(1);
140         }
141 }
142 /*****************************************************************/
143 int Tree::getIndex(string searchName) {
144         try {
145                 //Treemap knows name, group and index to speed up search
146                 // getIndex function will return the vector index or -1 if seq is not found.
147                 int index = globaldata->gTreemap->getIndex(searchName);
148                 return index;
149                 
150         }
151         catch(exception& e) {
152                 m->errorOut(e, "Tree", "getIndex");
153                 exit(1);
154         }
155 }
156 /*****************************************************************/
157
158 void Tree::setIndex(string searchName, int index) {
159         try {
160                 //set index in treemap
161                 globaldata->gTreemap->setIndex(searchName, index);
162         }
163         catch(exception& e) {
164                 m->errorOut(e, "Tree", "setIndex");
165                 exit(1);
166         }
167 }
168 /*****************************************************************/
169 void Tree::assembleTree() {
170         try {
171         
172                 //if user has given a names file we want to include that info in the pgroups and pcount info.
173                 if(globaldata->names.size() != 0) {  addNamesToCounts();  }
174                 
175                 //build the pGroups in non leaf nodes to be used in the parsimony calcs.
176                 for (int i = numLeaves; i < numNodes; i++) {
177                         tree[i].pGroups = (mergeGroups(i));
178                         tree[i].pcount = (mergeGcounts(i));
179                 }
180         }
181         catch(exception& e) {
182                 m->errorOut(e, "Tree", "assembleTree");
183                 exit(1);
184         }
185 }
186 /*****************************************************************/
187 void Tree::getCopy(Tree* copy) {
188         try {
189         
190                 //for each node in the tree copy its info
191                 for (int i = 0; i < numNodes; i++) {
192                         //copy name
193                         tree[i].setName(copy->tree[i].getName());
194                 
195                         //copy group
196                         tree[i].setGroup(copy->tree[i].getGroup());
197                         
198                         //copy branch length
199                         tree[i].setBranchLength(copy->tree[i].getBranchLength());
200                 
201                         //copy parent
202                         tree[i].setParent(copy->tree[i].getParent());
203                 
204                         //copy children
205                         tree[i].setChildren(copy->tree[i].getLChild(), copy->tree[i].getRChild());
206                 
207                         //copy index in node and tmap
208                         tree[i].setIndex(copy->tree[i].getIndex());
209                         setIndex(copy->tree[i].getName(), getIndex(copy->tree[i].getName()));
210                         
211                         //copy pGroups
212                         tree[i].pGroups = copy->tree[i].pGroups;
213                 
214                         //copy pcount
215                         tree[i].pcount = copy->tree[i].pcount;
216                 }
217                 
218         }
219         catch(exception& e) {
220                 m->errorOut(e, "Tree", "getCopy");
221                 exit(1);
222         }
223 }
224 /*****************************************************************/
225 //returns a map with a groupname and the number of times that group was seen in the children
226 //for instance if your children are white and black then it would return a map with 2 entries
227 // p[white] = 1 and p[black] = 1.  Now go up a level and merge that with a node who has p[white] = 1
228 //and you get p[white] = 2, p[black] = 1, but you erase the p[black] because you have a p value higher than 1.
229
230 map<string, int> Tree::mergeGroups(int i) {
231         try {
232                 int lc = tree[i].getLChild();
233                 int rc = tree[i].getRChild();
234
235                 //set parsimony groups to left child
236                 map<string,int> parsimony = tree[lc].pGroups;
237                 
238                 int maxPars = 1;
239
240                 //look at right child groups and update maxPars if right child has something higher for that group.
241                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();it++){
242                         it2 = parsimony.find(it->first);
243                         if (it2 != parsimony.end()) {
244                                 parsimony[it->first]++;
245                         }else {
246                                 parsimony[it->first] = 1;
247                         }
248                         
249                         if(parsimony[it->first] > maxPars){
250                                 maxPars = parsimony[it->first];
251                         }
252                 }
253         
254                 // this is true if right child had a greater parsimony for a certain group
255                 if(maxPars > 1){
256                         //erase all the groups that are only 1 because you found something with 2.
257                         for(it=parsimony.begin();it!=parsimony.end();){
258                                 if(it->second == 1){
259                                         parsimony.erase(it++);
260                                 }else { it++; }
261                         }
262                         //set one remaining groups to 1
263                         //so with our above example p[white] = 2 would be left and it would become p[white] = 1
264                         for(it=parsimony.begin();it!=parsimony.end();it++){
265                                 parsimony[it->first] = 1;
266                         }
267                 
268                 }
269         
270                 return parsimony;
271         }
272         catch(exception& e) {
273                 m->errorOut(e, "Tree", "mergeGroups");
274                 exit(1);
275         }
276 }
277 /*****************************************************************/
278 //returns a map with a groupname and the number of times that group was seen in the children
279 //for instance if your children are white and black then it would return a map with 2 entries
280 // p[white] = 1 and p[black] = 1.  Now go up a level and merge that with a node who has p[white] = 1
281 //and you get p[white] = 2, p[black] = 1, but you erase the p[black] because you have a p value higher than 1.
282
283 map<string, int> Tree::mergeUserGroups(int i, vector<string> g) {
284         try {
285         
286                 int lc = tree[i].getLChild();
287                 int rc = tree[i].getRChild();
288                 
289                 //loop through nodes groups removing the ones the user doesn't want
290                 for(it=tree[lc].pGroups.begin();it!=tree[lc].pGroups.end();){
291                                 if (inUsersGroups(it->first, g) != true) {
292                                         tree[lc].pGroups.erase(it++);
293                                 }else { it++; }
294                 }
295
296                 //loop through nodes groups removing the ones the user doesn't want
297                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();){
298                                 if (inUsersGroups(it->first, g) != true) {
299                                         tree[rc].pGroups.erase(it++);
300                                 }else { it++; }
301                 }
302
303                 //set parsimony groups to left child
304                 map<string,int> parsimony = tree[lc].pGroups;
305                 
306                 int maxPars = 1;
307
308                 //look at right child groups and update maxPars if right child has something higher for that group.
309                 for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();it++){
310                         it2 = parsimony.find(it->first);
311                         if (it2 != parsimony.end()) {
312                                 parsimony[it->first]++;
313                         }else {
314                                 parsimony[it->first] = 1;
315                         }
316                         
317                         if(parsimony[it->first] > maxPars){
318                                 maxPars = parsimony[it->first];
319                         }
320                 }
321                         
322                 // this is true if right child had a greater parsimony for a certain group
323                 if(maxPars > 1){
324                         //erase all the groups that are only 1 because you found something with 2.
325                         for(it=parsimony.begin();it!=parsimony.end();){
326                                 if(it->second == 1){
327                                         parsimony.erase(it++);
328                                 }else { it++; }
329                         }
330
331                         for(it=parsimony.begin();it!=parsimony.end();it++){
332                                 parsimony[it->first] = 1;
333                         }
334                 }               
335                 
336                 return parsimony;
337         }
338         catch(exception& e) {
339                 m->errorOut(e, "Tree", "mergeUserGroups");
340                 exit(1);
341         }
342 }
343
344
345 /**************************************************************************************************/
346
347 map<string,int> Tree::mergeGcounts(int position) {
348         try{
349                 map<string,int>::iterator pos;
350         
351                 int lc = tree[position].getLChild();
352                 int rc = tree[position].getRChild();
353         
354                 map<string,int> sum = tree[lc].pcount;
355     
356                 for(it=tree[rc].pcount.begin();it!=tree[rc].pcount.end();it++){
357                         sum[it->first] += it->second;
358                 }
359                 return sum;
360         }
361         catch(exception& e) {
362                 m->errorOut(e, "Tree", "mergeGcounts");
363                 exit(1);
364         }
365 }
366 /**************************************************************************************************/
367
368 void Tree::randomLabels(vector<string> g) {
369         try {
370                 
371                 for(int i = 0; i < numLeaves; i++){
372                         int z;
373                         //get random index to switch with
374                         z = int((float)(i+1) * (float)(rand()) / ((float)RAND_MAX+1.0));        
375                         
376                         //you only want to randomize the nodes that are from a group the user wants analyzed, so
377                         //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.
378                         bool treez, treei;
379                 
380                         treez = inUsersGroups(tree[z].getGroup(), g);
381                         treei = inUsersGroups(tree[i].getGroup(), g);
382                         
383                         if ((treez == true) && (treei == true)) {
384                                 //switches node i and node z's info.
385                                 map<string,int> lib_hold = tree[z].pGroups;
386                                 tree[z].pGroups = (tree[i].pGroups);
387                                 tree[i].pGroups = (lib_hold);
388                                 
389                                 vector<string> zgroup = tree[z].getGroup();
390                                 tree[z].setGroup(tree[i].getGroup());
391                                 tree[i].setGroup(zgroup);
392                                 
393                                 string zname = tree[z].getName();
394                                 tree[z].setName(tree[i].getName());
395                                 tree[i].setName(zname);
396                                 
397                                 map<string,int> gcount_hold = tree[z].pcount;
398                                 tree[z].pcount = (tree[i].pcount);
399                                 tree[i].pcount = (gcount_hold);
400                         }
401                 }
402         }
403         catch(exception& e) {
404                 m->errorOut(e, "Tree", "randomLabels");
405                 exit(1);
406         }
407 }
408 /**************************************************************************************************
409
410 void Tree::randomLabels(string groupA, string groupB) {
411         try {
412                 int numSeqsA = globaldata->gTreemap->seqsPerGroup[groupA];
413                 int numSeqsB = globaldata->gTreemap->seqsPerGroup[groupB];
414
415                 vector<string> randomGroups(numSeqsA+numSeqsB, groupA);
416                 for(int i=numSeqsA;i<randomGroups.size();i++){
417                         randomGroups[i] = groupB;
418                 }
419                 random_shuffle(randomGroups.begin(), randomGroups.end());
420                                 
421                 int randomCounter = 0;                          
422                 for(int i=0;i<numLeaves;i++){
423                         if(tree[i].getGroup() == groupA || tree[i].getGroup() == groupB){
424                                 tree[i].setGroup(randomGroups[randomCounter]);
425                                 tree[i].pcount.clear();
426                                 tree[i].pcount[randomGroups[randomCounter]] = 1;
427                                 tree[i].pGroups.clear();
428                                 tree[i].pGroups[randomGroups[randomCounter]] = 1;
429                                 randomCounter++;
430                         }
431                 }
432         }               
433         catch(exception& e) {
434                 m->errorOut(e, "Tree", "randomLabels");
435                 exit(1);
436         }
437 }
438 /**************************************************************************************************/
439 void Tree::randomBlengths()  {
440         try {
441                 for(int i=numNodes-1;i>=0;i--){
442                         int z = int((float)(i+1) * (float)(rand()) / ((float)RAND_MAX+1.0));    
443                 
444                         float bl_hold = tree[z].getBranchLength();
445                         tree[z].setBranchLength(tree[i].getBranchLength());
446                         tree[i].setBranchLength(bl_hold);
447                 }
448         }
449         catch(exception& e) {
450                 m->errorOut(e, "Tree", "randomBlengths");
451                 exit(1);
452         }
453 }
454 /*************************************************************************************************/
455 void Tree::assembleRandomUnifracTree(vector<string> g) {
456         randomLabels(g);
457         assembleTree();
458 }
459 /*************************************************************************************************/
460 void Tree::assembleRandomUnifracTree(string groupA, string groupB) {
461
462         vector<string> temp; temp.push_back(groupA); temp.push_back(groupB);
463         randomLabels(temp);
464         assembleTree();
465 }
466
467 /*************************************************************************************************/
468 //for now it's just random topology but may become random labels as well later that why this is such a simple function now...
469 void Tree::assembleRandomTree() {
470         randomTopology();
471         assembleTree();
472 }
473 /**************************************************************************************************/
474
475 void Tree::randomTopology() {
476         try {
477                 for(int i=0;i<numNodes;i++){
478                         tree[i].setParent(-1);
479                 }
480                 for(int i=numLeaves;i<numNodes;i++){
481                         tree[i].setChildren(-1, -1); 
482                 }
483     
484                 for(int i=numLeaves;i<numNodes;i++){
485                         int escape =0;
486                         int rnd_index1, rnd_index2;
487                         while(escape == 0){
488                                 rnd_index1 = (int)(((double)rand() / (double) RAND_MAX)*i);
489                                 if(tree[rnd_index1].getParent() == -1){escape = 1;}
490                         }
491                 
492                         escape = 0;
493                         while(escape == 0){
494                                 rnd_index2 = (int)(((double)rand() / (double) RAND_MAX)*i);
495                                 if(rnd_index2 != rnd_index1 && tree[rnd_index2].getParent() == -1){
496                                         escape = 1;
497                                 }               
498                         }
499         
500                         tree[i].setChildren(rnd_index1,rnd_index2);
501                         tree[i].setParent(-1);
502                         tree[rnd_index1].setParent(i);
503                         tree[rnd_index2].setParent(i);
504                 }
505         }
506         catch(exception& e) {
507                 m->errorOut(e, "Tree", "randomTopology");
508                 exit(1);
509         }
510 }
511 /*****************************************************************/
512 void Tree::print(ostream& out) {
513         try {
514                 int root = findRoot();
515                 printBranch(root, out, "branch");
516                 out << ";" << endl;
517         }
518         catch(exception& e) {
519                 m->errorOut(e, "Tree", "print");
520                 exit(1);
521         }
522 }
523 /*****************************************************************/
524 void Tree::printForBoot(ostream& out) {
525         try {
526                 int root = findRoot();
527                 printBranch(root, out, "boot");
528                 out << ";" << endl;
529         }
530         catch(exception& e) {
531                 m->errorOut(e, "Tree", "printForBoot");
532                 exit(1);
533         }
534 }
535
536 /*****************************************************************/
537 // This prints out the tree in Newick form.
538 void Tree::createNewickFile(string f) {
539         try {
540                 int root = findRoot();
541                 //filename = getRootName(globaldata->getTreeFile()) + "newick";
542                 filename = f;
543
544                 openOutputFile(filename, out);
545                 
546                 printBranch(root, out, "branch");
547                 
548                 // you are at the end of the tree
549                 out << ";" << endl;
550                 out.close();
551         }
552         catch(exception& e) {
553                 m->errorOut(e, "Tree", "createNewickFile");
554                 exit(1);
555         }
556 }
557
558 /*****************************************************************/
559 //This function finds the index of the root node.
560
561 int Tree::findRoot() {
562         try {
563                 for (int i = 0; i < numNodes; i++) {
564                         //you found the root
565                         if (tree[i].getParent() == -1) { return i; }
566                         //cout << "i = " << i << endl;
567                         //cout << "i's parent = " << tree[i].getParent() << endl;  
568                 }
569                 return -1;
570         }
571         catch(exception& e) {
572                 m->errorOut(e, "Tree", "findRoot");
573                 exit(1);
574         }
575 }
576
577 /*****************************************************************/
578 void Tree::printBranch(int node, ostream& out, string mode) {
579         try {
580                 
581                 // you are not a leaf
582                 if (tree[node].getLChild() != -1) {
583                         out << "(";
584                         printBranch(tree[node].getLChild(), out, mode);
585                         out << ",";
586                         printBranch(tree[node].getRChild(), out, mode);
587                         out << ")";
588                         if (mode == "branch") {
589                                 //if there is a branch length then print it
590                                 if (tree[node].getBranchLength() != -1) {
591                                         out << ":" << tree[node].getBranchLength();
592                                 }
593                         }else if (mode == "boot") {
594                                 //if there is a label then print it
595                                 if (tree[node].getLabel() != -1) {
596                                         out << tree[node].getLabel();
597                                 }
598                         }
599                 }else { //you are a leaf
600                         string leafGroup = globaldata->gTreemap->getGroup(tree[node].getName());
601                         
602                         out << leafGroup; 
603                         if (mode == "branch") {
604                                 //if there is a branch length then print it
605                                 if (tree[node].getBranchLength() != -1) {
606                                         out << ":" << tree[node].getBranchLength();
607                                 }
608                         }else if (mode == "boot") {
609                                 //if there is a label then print it
610                                 if (tree[node].getLabel() != -1) {
611                                         out << tree[node].getLabel();
612                                 }
613                         }
614                 }
615                 
616         }
617         catch(exception& e) {
618                 m->errorOut(e, "Tree", "printBranch");
619                 exit(1);
620         }
621 }
622
623 /*****************************************************************/
624
625 void Tree::printTree() {
626         
627         for(int i=0;i<numNodes;i++){
628                 cout << i << '\t';
629                 tree[i].printNode();
630         }
631         
632 }
633
634 /*****************************************************************/
635 //this code is a mess and should be rethought...-slw
636 void Tree::parseTreeFile() {
637         
638         //only takes names from the first tree and assumes that all trees use the same names.
639         try {
640                 string filename = globaldata->getTreeFile();
641                 ifstream filehandle;
642                 openInputFile(filename, filehandle);
643                 int c, comment;
644                 comment = 0;
645                 int done = 1;
646                 
647                 //ifyou are not a nexus file 
648                 if((c = filehandle.peek()) != '#') {  
649                         while((c = filehandle.peek()) != ';') { 
650                                 while ((c = filehandle.peek()) != ';') {
651                                         // get past comments
652                                         if(c == '[') {
653                                                 comment = 1;
654                                         }
655                                         if(c == ']'){
656                                                 comment = 0;
657                                         }
658                                         if((c == '(') && (comment != 1)){ break; }
659                                         filehandle.get();
660                                 }
661
662                                 done = readTreeString(filehandle); 
663                                 if (done == 0) { break; }
664                         }
665                 //ifyou are a nexus file
666                 }else if((c = filehandle.peek()) == '#') {
667                         string holder = "";
668                                         
669                         // get past comments
670                         while(holder != "translate" && holder != "Translate"){  
671                                 if(holder == "[" || holder == "[!"){
672                                         comment = 1;
673                                 }
674                                 if(holder == "]"){
675                                         comment = 0;
676                                 }
677                                 filehandle >> holder; 
678
679                                 //if there is no translate then you must read tree string otherwise use translate to get names
680                                 if((holder == "tree") && (comment != 1)){       
681                                         //pass over the "tree rep.6878900 = "
682                                         while (((c = filehandle.get()) != '(') && ((c = filehandle.peek()) != EOF)) {;}
683
684                                         if(c == EOF) { break; }
685                                         filehandle.putback(c);  //put back first ( of tree.
686                                         done = readTreeString(filehandle);
687         
688                                         break;
689                                 }
690                         
691                                 if (done == 0) { break;  }
692                         }
693                         
694                         //use nexus translation rather than parsing tree to save time
695                         if((holder == "translate") || (holder == "Translate")) {
696
697                                 string number, name, h;
698                                 h = ""; // so it enters the loop the first time
699                                 while((h != ";") && (number != ";")) { 
700                                         filehandle >> number;
701                                         filehandle >> name;
702         
703                                         //c = , until done with translation then c = ;
704                                         h = name.substr(name.length()-1, name.length()); 
705                                         name.erase(name.end()-1);  //erase the comma
706                                         globaldata->Treenames.push_back(number);
707                                 }
708                                 if(number == ";") { globaldata->Treenames.pop_back(); }  //in case ';' from translation is on next line instead of next to last name
709                         }
710                 }
711                 filehandle.close();
712         }
713         catch(exception& e) {
714                 m->errorOut(e, "Tree", "parseTreeFile");
715                 exit(1);
716         }
717 }
718 /*******************************************************/
719
720 /*******************************************************/
721 int Tree::readTreeString(ifstream& filehandle)  {
722         try {
723                 int c;
724                 string name;  //, k
725                 
726                 while((c = filehandle.peek()) != ';') { 
727 //k = c;
728 //cout << " at beginning of while " <<  k << endl;                      
729                         if(c == ')')  {    
730                                 //to pass over labels in trees
731                                 c=filehandle.get();
732                                 while((c!=',') && (c != -1) && (c!= ':') && (c!=';')){ c=filehandle.get(); }
733                                 filehandle.putback(c);
734                         }
735                         if(c == ';') { return 0; }
736                         if(c == -1) { return 0; }
737                         //if you are a name
738                         if((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != '\t') && (c != 32)) { //32 is space
739                                 name = "";
740                                 c = filehandle.get();
741                         //k = c;
742 //cout << k << endl;
743                                 while ((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != 32) && (c != '\t')) {                       
744                                         name += c;
745                                         c = filehandle.get();
746                         //k = c;
747 //cout << " in name while " << k << endl;
748                                 }
749                                 
750 //cout << "name = " << name << endl;
751                                 globaldata->Treenames.push_back(name);
752                                 filehandle.putback(c);
753 //k = c;
754 //cout << " after putback" <<  k << endl;
755                         } 
756                         
757                         if(c  == ':') { //read until you reach the end of the branch length
758                                 while ((c != '(') && (c != ')') && (c != ',') && (c != ';') && (c != '\n') && (c != '\t') && (c != 32)) {
759                                         c = filehandle.get();
760         //k = c;
761         //cout << " in branch while " << k << endl;
762                                 }
763                                 filehandle.putback(c);
764                         }
765                 
766                         c = filehandle.get();
767 //k = c;
768         //cout << " here after get " << k << endl;
769                         if(c == ';') { return 0; }
770                         if(c == ')') { filehandle.putback(c); }
771         //k = c;
772 //cout << k << endl;
773
774                 }
775                 return 0;
776         }
777         catch(exception& e) {
778                 m->errorOut(e, "Tree", "readTreeString");
779                 exit(1);
780         }
781 }       
782
783 /*******************************************************/
784
785 /*******************************************************/
786