]> git.donarmstrong.com Git - mothur.git/blob - readtree.cpp
When Pat tried to compile mothur in Ubuntu linux, there were a number of minor proble...
[mothur.git] / readtree.cpp
1 /*
2  *  readtree.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 "readtree.h"
11
12 /***********************************************************************/
13 //Parent Class
14 // The following functions are used by all reading formats.
15 /***********************************************************************/
16 ReadTree::ReadTree() { 
17         try {
18                 globaldata = GlobalData::getInstance(); 
19                 T = new Tree(); 
20                 numNodes = T->getNumNodes();
21                 numLeaves = T->getNumLeaves();
22         }
23         catch(exception& e) {
24                 cout << "Standard Error: " << e.what() << " has occurred in the ReadTree class Function ReadTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
25                 exit(1);
26         }
27         catch(...) {
28                 cout << "An unknown error has occurred in the ReadTree class function ReadTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
29                 exit(1);
30         }               
31 }
32 /***********************************************************************/
33 int ReadTree::readSpecialChar(istream& f, char c, string name) {
34     try {
35                 char d;
36         
37                 while(isspace(d=f.get()))               {;}
38                 if(d == EOF){
39                         cerr << "Error: Input file ends prematurely, expecting a " << name << "\n";
40                         exit(1);
41                 }
42                 if(d != c){
43                         cerr << "Error: Expected " << name << " in input file.  Found " << d << ".\n";
44                         exit(1);
45                 }
46                 if(d == ')' && f.peek() == '\n'){
47                         while(isspace(d=f.get()))               {;}
48                         f.putback(d);
49                 }       
50         
51                 return d;
52         }
53         catch(exception& e) {
54                 cout << "Standard Error: " << e.what() << " has occurred in the ReadTree class Function readSpecialChar. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
55                 exit(1);
56         }
57         catch(...) {
58                 cout << "An unknown error has occurred in the ReadTree class function readSpecialChar. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
59                 exit(1);
60         }               
61 }
62 /**************************************************************************************************/
63
64 int ReadTree::readNodeChar(istream& f) {
65         try {
66                 char d;
67                 while(isspace(d=f.get()))               {;}
68                 if(d == EOF){
69                         cerr << "Error: Input file ends prematurely, expecting a left parenthesis\n";
70                         exit(1);
71                 }
72                 return d;
73         }
74         catch(exception& e) {
75                 cout << "Standard Error: " << e.what() << " has occurred in the ReadTree class Function readNodeChar. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
76                 exit(1);
77         }
78         catch(...) {
79                 cout << "An unknown error has occurred in the ReadTree class function readNodeChar. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
80                 exit(1);
81         }               
82 }
83
84 /**************************************************************************************************/
85
86 float ReadTree::readBranchLength(istream& f) {
87     try {
88                 float b;
89         
90                 if(!(f >> b)){
91                         cerr << "Error: Missing branch length in input tree.\n";
92                         exit(1);
93                 }
94     
95                 return b;
96         }
97         catch(exception& e) {
98                 cout << "Standard Error: " << e.what() << " has occurred in the ReadTree class Function readBranchLength. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
99                 exit(1);
100         }
101         catch(...) {
102                 cout << "An unknown error has occurred in the ReadTree class function readBranchLength. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
103                 exit(1);
104         }               
105 }
106
107
108 /***********************************************************************/
109 /***********************************************************************/
110
111
112 //Child Classes Below
113
114 /***********************************************************************/
115 /***********************************************************************/
116 //This class reads a file in Newick form and stores it in a tree.
117
118 void ReadNewickTree::read() {
119         try {
120                 int n = 0;
121                 int lc, rc; 
122                 
123                 int rooted = 0;
124         
125                 int ch = filehandle.peek();     
126                 
127                 if(ch == '('){
128                         n = numLeaves;  //number of leaves / sequences, we want node 1 to start where the leaves left off
129                         lc = readNewickInt(filehandle, n, T);
130                 
131                         if(filehandle.peek()==','){                                                     
132                                 readSpecialChar(filehandle,',',"comma");
133                         }
134                         // ';' means end of tree.                                                                                               
135                         else if((ch=filehandle.peek())==';' || ch=='['){                
136                                 rooted = 1;                                                                     
137                         }                                                                                               
138                         if(rooted != 1){                                                                
139                                 rc = readNewickInt(filehandle, n, T);
140                                 if(filehandle.peek() == ')'){                                   
141                                         readSpecialChar(filehandle,')',"right parenthesis");
142                                 }                                                                                       
143                         }                                                                                               
144                 }
145                 //note: treeclimber had the code below added - not sure why?
146                  else{
147                         filehandle.putback(ch);
148                         char name[MAX_LINE];
149                         filehandle.get(name, MAX_LINE,'\n');
150                         SKIPLINE(filehandle, ch);
151                 
152                 
153                         n = T->getIndex(name);
154                         if(n!=0){
155                                 cerr << "Internal error: The only taxon is not taxon 0.\n";
156                                 exit(1);
157                         }
158                         lc = rc = -1;
159                 } 
160                 
161                 while((ch=filehandle.get())!=';'){;}                                            
162                         if(rooted != 1){                                                                        
163                         T->tree[n].setChildren(lc,rc);
164                         T->tree[n].setBranchLength(0);
165                         T->tree[n].setParent(-1);
166                         if(lc!=-1){             T->tree[lc].setParent(n);               }
167                         if(rc!=-1){             T->tree[rc].setParent(n);               }
168                 }
169                 
170                 //save tree for later commands
171                 globaldata->gTree = T;
172         }
173         catch(exception& e) {
174                 cout << "Standard Error: " << e.what() << " has occurred in the ReadNewickTree class Function read. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
175                 exit(1);
176         }
177         catch(...) {
178                 cout << "An unknown error has occurred in the ReadNewickTree class function read. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
179                 exit(1);
180         }               
181 }
182 /**************************************************************************************************/
183
184 int ReadNewickTree::readNewickInt(istream& f, int& n, Tree* T) {
185         try {
186                 int c = readNodeChar(f);
187     
188                 if(c == '('){
189                         int lc = readNewickInt(f, n, T);
190                         readSpecialChar(f,',',"comma");
191                 
192                         int rc = readNewickInt(f, n, T);                
193                         if(f.peek()==')'){      
194                                 readSpecialChar(f,')',"right parenthesis");                                     
195                         }                       
196                 
197                         if(f.peek() == ':'){                                                                          
198                                 readSpecialChar(f,':',"colon");                                                 
199                                 if(n >= numNodes){      cerr << "Error: Too many nodes in input tree\n";  exit(1); }
200                                 T->tree[n].setBranchLength(readBranchLength(f));
201                         }else{T->tree[n].setBranchLength(0.0); }                                                
202                 
203                         T->tree[n].setChildren(lc,rc);
204                         T->tree[lc].setParent(n);
205                         T->tree[rc].setParent(n);
206                 
207                         return n++;
208                 }else{
209                         f.putback(c);
210                         string name = "";
211                         char d=f.get();
212                         while(d != ':' && d != ',' && d!=')' && d!='\n'){                                       
213                                 name += d;
214                                 d=f.get();
215                         }
216                 
217                         int blen = 0;
218                         if(d == ':')    {               blen = 1;                       }               
219                 
220                         f.putback(d);
221                 
222                         //set group info
223                         string group = globaldata->gTreemap->getGroup(name);
224                         
225                         //find index in tree of name
226                         int n1 = T->getIndex(name);
227                         
228                         if(n1 == -1){cerr << "Name: " << name << " not found\n"; exit(1);}
229                         
230                         else T->tree[n1].setGroup(group);
231                 
232                         T->tree[n1].setChildren(-1,-1);
233                 
234                         if(blen == 1){  
235                                 f.get();                
236                                 T->tree[n1].setBranchLength(readBranchLength(f));
237                         }else{
238                                 T->tree[n1].setBranchLength(0.0);
239                         }
240                 
241                         while((c=f.get())!=0 && (c != ':' && c != ',' && c!=')') )              {;}             
242                         f.putback(c);
243                 
244                         return n1;
245                 }
246         }
247         catch(exception& e) {
248                 cout << "Standard Error: " << e.what() << " has occurred in the ReadNewickTree class Function readNewickInt. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
249                 exit(1);
250         }
251         catch(...) {
252                 cout << "An unknown error has occurred in the ReadNewickTree class function readNewickInt. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
253                 exit(1);
254         }               
255 }
256 /**************************************************************************************************/
257 /**************************************************************************************************/
258