]> git.donarmstrong.com Git - mothur.git/blob - phylotree.cpp
added picrust and ref taxonomy parameters to make.biom
[mothur.git] / phylotree.cpp
1 /*
2  *  doTaxonomy.cpp
3  *  
4  *
5  *  Created by Pat Schloss on 6/17/09.
6  *  Copyright 2009 Patrick D. Schloss. All rights reserved.
7  *
8  */
9
10 #include "phylotree.h"
11
12 /**************************************************************************************************/
13
14 PhyloTree::PhyloTree(){
15         try {
16                 m = MothurOut::getInstance();
17                 numNodes = 1;
18                 numSeqs = 0;
19                 tree.push_back(TaxNode("Root"));
20                 tree[0].heirarchyID = "0";
21                 maxLevel = 0;
22                 calcTotals = true;
23                 addSeqToTree("unknown", "unknown;");
24         }
25         catch(exception& e) {
26                 m->errorOut(e, "PhyloTree", "PhyloTree");
27                 exit(1);
28         }
29 }
30 /**************************************************************************************************/
31
32 PhyloTree::PhyloTree(ifstream& in, string filename){
33         try {
34                 m = MothurOut::getInstance();
35                 calcTotals = false;
36                 numNodes = 0;
37                 numSeqs = 0;
38                 
39                 #ifdef USE_MPI
40                         MPI_File inMPI;
41                         MPI_Offset size;
42                         MPI_Status status;
43
44                         char inFileName[1024];
45                         strcpy(inFileName, filename.c_str());
46
47                         MPI_File_open(MPI_COMM_WORLD, inFileName, MPI_MODE_RDONLY, MPI_INFO_NULL, &inMPI);  
48                         MPI_File_get_size(inMPI, &size);
49                         
50                         char* buffer = new char[size];
51                         MPI_File_read(inMPI, buffer, size, MPI_CHAR, &status);
52
53                         string tempBuf = buffer;
54                         if (tempBuf.length() > size) { tempBuf = tempBuf.substr(0, size);  }
55                         istringstream iss (tempBuf,istringstream::in);
56                         delete buffer;
57                         
58                         //read version
59                         m->getline(iss); m->gobble(iss);
60                         
61                         iss >> numNodes; m->gobble(iss);
62                         
63                         tree.resize(numNodes);
64                         
65                         for (int i = 0; i < tree.size(); i++) {
66                                 iss >> tree[i].name >> tree[i].level >> tree[i].parent; m->gobble(iss);
67                         }
68                         
69                         //read genus nodes
70                         int numGenus = 0;
71                         iss >> numGenus; m->gobble(iss);
72                         
73                         int gnode, gsize;
74                         totals.clear();
75                         for (int i = 0; i < numGenus; i++) {
76                                 iss >> gnode >> gsize; m->gobble(iss);
77                                 
78                                 uniqueTaxonomies.insert(gnode);
79                                 totals.push_back(gsize);
80                         }
81                         
82                         MPI_File_close(&inMPI);
83                         
84                 #else
85                         //read version
86                         string line = m->getline(in); m->gobble(in);
87                         
88                         in >> numNodes; m->gobble(in);
89                         
90                         tree.resize(numNodes);
91                         
92                         for (int i = 0; i < tree.size(); i++) {
93                                 in >> tree[i].name >> tree[i].level >> tree[i].parent; m->gobble(in);
94                         }
95                         
96                         //read genus nodes
97                         int numGenus = 0;
98                         in >> numGenus; m->gobble(in);
99                         
100                         int gnode, gsize;
101                         totals.clear();
102                         for (int i = 0; i < numGenus; i++) {
103                                 in >> gnode >> gsize; m->gobble(in);
104                                 
105                                 uniqueTaxonomies.insert(gnode);
106                                 totals.push_back(gsize);
107                         }
108                         
109                         in.close();
110                         
111                 #endif
112                 
113         }
114         catch(exception& e) {
115                 m->errorOut(e, "PhyloTree", "PhyloTree");
116                 exit(1);
117         }
118 }
119 /**************************************************************************************************/
120
121 PhyloTree::PhyloTree(string tfile){
122         try {
123                 m = MothurOut::getInstance();
124                 numNodes = 1;
125                 numSeqs = 0;
126                 tree.push_back(TaxNode("Root"));
127                 tree[0].heirarchyID = "0";
128                 maxLevel = 0;
129                 calcTotals = true;
130                 string name, tax;
131                 
132                 #ifdef USE_MPI
133                         int pid, num, processors;
134                         vector<unsigned long long> positions;
135                         
136                         MPI_Status status; 
137                         MPI_File inMPI;
138                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
139                         MPI_Comm_size(MPI_COMM_WORLD, &processors);
140
141                         char inFileName[1024];
142                         strcpy(inFileName, tfile.c_str());
143
144                         MPI_File_open(MPI_COMM_WORLD, inFileName, MPI_MODE_RDONLY, MPI_INFO_NULL, &inMPI);  //comm, filename, mode, info, filepointer
145
146                         if (pid == 0) {
147                                 positions = m->setFilePosEachLine(tfile, num);
148                                 
149                                 //send file positions to all processes
150                                 for(int i = 1; i < processors; i++) { 
151                                         MPI_Send(&num, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
152                                         MPI_Send(&positions[0], (num+1), MPI_LONG, i, 2001, MPI_COMM_WORLD);
153                                 }
154                         }else{
155                                 MPI_Recv(&num, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
156                                 positions.resize(num+1);
157                                 MPI_Recv(&positions[0], (num+1), MPI_LONG, 0, 2001, MPI_COMM_WORLD, &status);
158                         }
159                 
160                         //read file 
161                         for(int i=0;i<num;i++){
162                                 //read next sequence
163                                 int length = positions[i+1] - positions[i];
164                                 char* buf4 = new char[length];
165
166                                 MPI_File_read_at(inMPI, positions[i], buf4, length, MPI_CHAR, &status);
167
168                                 string tempBuf = buf4;
169                                 if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length); }
170                                 delete buf4;
171
172                                 istringstream iss (tempBuf,istringstream::in);
173                                 iss >> name >> tax;
174                                 addSeqToTree(name, tax);
175                         }
176                         
177                         MPI_File_close(&inMPI);
178                         MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
179                 
180                 #else
181             map<string, string> temp;
182             m->readTax(tfile, temp);
183         
184             for (map<string, string>::iterator itTemp = temp.begin(); itTemp != temp.end();) {
185                 addSeqToTree(itTemp->first, itTemp->second);
186                 temp.erase(itTemp++);
187             }
188                 #endif
189         
190                 assignHeirarchyIDs(0);
191         
192         
193         string unknownTax = "unknown;";
194         //added last taxon until you get desired level
195                 for (int i = 1; i < maxLevel; i++) {
196                         unknownTax += "unclassfied;";
197                 }
198         
199         addSeqToTree("unknown", unknownTax);
200         
201                 //create file for summary if needed
202                 setUp(tfile);
203         }
204         catch(exception& e) {
205                 m->errorOut(e, "PhyloTree", "PhyloTree");
206                 exit(1);
207         }
208 }
209
210 /**************************************************************************************************/
211
212 string PhyloTree::getNextTaxon(string& heirarchy, string seqname){
213         try {
214                 string currentLevel = "";
215                 if(heirarchy != ""){
216                         int pos = heirarchy.find_first_of(';');
217                         
218                         if (pos == -1) { //you can't find another ;
219                                 currentLevel = heirarchy;
220                                 heirarchy = "";
221                                 m->mothurOut(seqname + " is missing a ;, please check for other errors."); m->mothurOutEndLine();
222                         }else{
223                                 currentLevel=heirarchy.substr(0,pos);
224                                 if (pos != (heirarchy.length()-1)) {  heirarchy=heirarchy.substr(pos+1);  }
225                                 else { heirarchy = ""; }
226                         }
227                         
228                 }
229                 return currentLevel;
230         }
231         catch(exception& e) {
232                 m->errorOut(e, "PhyloTree", "getNextTaxon");
233                 exit(1);
234         }
235 }
236 /**************************************************************************************************/
237
238 vector<string> PhyloTree::getSeqs(string seqTaxonomy){
239         try {
240         string taxCopy = seqTaxonomy;
241         vector<string> names;
242         map<string, int>::iterator childPointer;
243                 
244                 int currentNode = 0;
245
246         m->removeConfidences(seqTaxonomy);
247         
248         string taxon;
249         while(seqTaxonomy != ""){
250                         
251                         if (m->control_pressed) { return names; }
252                         
253                         taxon = getNextTaxon(seqTaxonomy, "");
254             
255             if (m->debug) { m->mothurOut(taxon +'\n'); }
256                         
257                         if (taxon == "") {  m->mothurOut(taxCopy + " has an error in the taxonomy.  This may be due to a ;;"); m->mothurOutEndLine(); break;  }
258                         
259                         childPointer = tree[currentNode].children.find(taxon);
260                         
261                         if(childPointer != tree[currentNode].children.end()){   //if the node already exists, move on
262                                 currentNode = childPointer->second;
263                         }
264                         else{                                                                                   //otherwise, error this taxonomy is not in tree
265                                 m->mothurOut("[ERROR]: " + taxCopy + " is not in taxonomy tree, please correct."); m->mothurOutEndLine(); m->control_pressed = true; return names;
266                         }
267             
268                         if (seqTaxonomy == "") {   names = tree[currentNode].accessions;        }
269                 }
270         
271         return names;
272     }
273         catch(exception& e) {
274                 m->errorOut(e, "PhyloTree", "getSeqs");
275                 exit(1);
276         }
277 }
278
279 /**************************************************************************************************/
280
281 int PhyloTree::addSeqToTree(string seqName, string seqTaxonomy){
282         try {
283                 numSeqs++;
284                 
285                 map<string, int>::iterator childPointer;
286                 
287                 int currentNode = 0;
288                 int level = 1;
289                 
290                 tree[0].accessions.push_back(seqName);
291                 m->removeConfidences(seqTaxonomy);
292                 
293                 string taxon;// = getNextTaxon(seqTaxonomy);
294         
295                 while(seqTaxonomy != ""){
296                         
297                         level++;
298                 
299                         if (m->control_pressed) { return 0; }
300                         
301                         //somehow the parent is getting one too many accnos
302                         //use print to reassign the taxa id
303                         taxon = getNextTaxon(seqTaxonomy, seqName);
304             
305             if (m->debug) { m->mothurOut(seqName +'\t' + taxon +'\n'); }
306                         
307                         if (taxon == "") {  m->mothurOut(seqName + " has an error in the taxonomy.  This may be due to a ;;"); m->mothurOutEndLine(); if (currentNode != 0) {  uniqueTaxonomies.insert(currentNode); } break;  }
308                         
309                         childPointer = tree[currentNode].children.find(taxon);
310                         
311                         if(childPointer != tree[currentNode].children.end()){   //if the node already exists, move on
312                                 currentNode = childPointer->second;
313                                 tree[currentNode].accessions.push_back(seqName);
314                                 name2Taxonomy[seqName] = currentNode;
315                         }
316                         else{                                                                                   //otherwise, create it
317                                 tree.push_back(TaxNode(taxon));
318                                 numNodes++;
319                                 tree[currentNode].children[taxon] = numNodes-1;
320                                 tree[numNodes-1].parent = currentNode;
321                                 
322                                 currentNode = tree[currentNode].children[taxon];
323                                 tree[currentNode].accessions.push_back(seqName);
324                                 name2Taxonomy[seqName] = currentNode;
325                         }
326         
327                         if (seqTaxonomy == "") {   uniqueTaxonomies.insert(currentNode);        }
328                 }
329                 
330                 return 0;
331         }
332         catch(exception& e) {
333                 m->errorOut(e, "PhyloTree", "addSeqToTree");
334                 exit(1);
335         }
336 }
337 /**************************************************************************************************/
338 vector<int> PhyloTree::getGenusNodes()  {
339         try {
340                 genusIndex.clear();
341                 //generate genusIndexes
342                 set<int>::iterator it2;
343         map<int, int> temp;
344                 for (it2=uniqueTaxonomies.begin(); it2!=uniqueTaxonomies.end(); it2++) {  genusIndex.push_back(*it2);   temp[*it2] = genusIndex.size()-1; }
345                 
346         for (map<string, int>::iterator itName = name2Taxonomy.begin(); itName != name2Taxonomy.end(); itName++) {
347             map<int, int>::iterator itTemp = temp.find(itName->second);
348             if (itTemp != temp.end()) { name2GenusNodeIndex[itName->first] = itTemp->second; }
349             else {  m->mothurOut("[ERROR]: trouble making name2GenusNodeIndex, aborting.\n"); m->control_pressed = true; }
350         }
351         
352                 return genusIndex;
353         }
354         catch(exception& e) {
355                 m->errorOut(e, "PhyloTree", "getGenusNodes");
356                 exit(1);
357         }
358 }
359 /**************************************************************************************************/
360 vector<int> PhyloTree::getGenusTotals() {
361         try {
362         
363                 if (calcTotals) {
364                         totals.clear();
365                         //reset counts because we are on a new word
366                         for (int j = 0; j < genusIndex.size(); j++) {
367                                 totals.push_back(tree[genusIndex[j]].accessions.size());
368                         }
369                         return totals;
370                 }else{
371                         return totals;
372                 }
373                 
374         }
375         catch(exception& e) {
376                 m->errorOut(e, "PhyloTree", "getGenusNodes");
377                 exit(1);
378         }
379 }
380 /**************************************************************************************************/
381
382 void PhyloTree::assignHeirarchyIDs(int index){
383         try {
384                 map<string,int>::iterator it;
385                 int counter = 1;
386                 
387                 for(it=tree[index].children.begin();it!=tree[index].children.end();it++){
388             
389             if (m->debug) { m->mothurOut(toString(index) +'\t' + tree[it->second].name +'\n'); }
390                 
391                         tree[it->second].heirarchyID = tree[index].heirarchyID + '.' + toString(counter);
392                         counter++;
393                         tree[it->second].level = tree[index].level + 1;
394                                                 
395                         //save maxLevel for binning the unclassified seqs
396                         if (tree[it->second].level > maxLevel) { maxLevel = tree[it->second].level; } 
397                         
398                         assignHeirarchyIDs(it->second);
399                 }
400         }
401         catch(exception& e) {
402                 m->errorOut(e, "PhyloTree", "assignHeirarchyIDs");
403                 exit(1);
404         }
405 }
406 /**************************************************************************************************/
407 void PhyloTree::setUp(string tfile){
408         try{
409                 string taxFileNameTest = tfile.substr(0,tfile.find_last_of(".")+1) + "tree.sum";
410                 
411                 #ifdef USE_MPI
412                         int pid;
413                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
414
415                         if (pid == 0) {  binUnclassified(taxFileNameTest);  }
416                 
417                 #else
418                         binUnclassified(taxFileNameTest); 
419                 #endif
420         }
421         catch(exception& e) {
422                 m->errorOut(e, "PhyloTree", "setUp");
423                 exit(1);
424         }
425 }
426 /**************************************************************************************************/
427 void PhyloTree::binUnclassified(string file){
428         try {
429         
430                 ofstream out;
431                 m->openOutputFile(file, out);
432                 
433                 map<string, int>::iterator itBin;
434                 map<string, int>::iterator childPointer;
435                 
436                 vector<TaxNode> copy = tree;
437                 
438                 //fill out tree
439                 fillOutTree(0, copy);
440         
441                 //get leaf nodes that may need extension
442                 for (int i = 0; i < copy.size(); i++) {  
443
444                         if (copy[i].children.size() == 0) {
445                                 leafNodes[i] = i;
446                         }
447                 }
448                 
449         if (m->debug) { m->mothurOut("maxLevel = " + toString(maxLevel) +'\n'); }
450         
451                 int copyNodes = copy.size();
452         
453                 //go through the seqs and if a sequence finest taxon is not the same level as the most finely defined taxon then classify it as unclassified where necessary
454                 map<int, int>::iterator itLeaf;
455                 for (itLeaf = leafNodes.begin(); itLeaf != leafNodes.end(); itLeaf++) {
456                         
457                         if (m->control_pressed) {  out.close(); break;  }
458                         
459                         int level = copy[itLeaf->second].level;
460                         int currentNode = itLeaf->second;
461             
462             if (m->debug) { m->mothurOut(copy[currentNode].name +'\n'); }
463                         
464                         //this sequence is unclassified at some levels
465                         while(level < maxLevel){
466                 
467                                 level++;
468                 if (m->debug) { m->mothurOut("level = " + toString(level) +'\n'); }
469                         
470                                 string taxon = "unclassified";  
471                                 
472                                 //does the parent have a child names 'unclassified'?
473                                 childPointer = copy[currentNode].children.find(taxon);
474                                 
475                                 if(childPointer != copy[currentNode].children.end()){   //if the node already exists, move on
476                                         currentNode = childPointer->second; //currentNode becomes 'unclassified'
477                                 }
478                                 else{                                                                                   //otherwise, create it
479                                         copy.push_back(TaxNode(taxon));
480                                         copyNodes++;
481                                         copy[currentNode].children[taxon] = copyNodes-1;
482                                         copy[copyNodes-1].parent = currentNode;
483                                         copy[copyNodes-1].level = copy[currentNode].level + 1;
484                                                                         
485                                         currentNode = copy[currentNode].children[taxon];
486                                 }
487                         }
488                 }
489                 
490                 if (!m->control_pressed) {
491                         //print copy tree
492                         print(out, copy);
493                 }
494                                 
495         }
496         catch(exception& e) {
497                 m->errorOut(e, "PhyloTree", "binUnclassified");
498                 exit(1);
499         }
500 }
501 /**************************************************************************************************/
502 void PhyloTree::fillOutTree(int index, vector<TaxNode>& copy) {
503         try {
504         
505                 map<string,int>::iterator it;
506                 
507                 it = copy[index].children.find("unclassified");
508                 if (it == copy[index].children.end()) { //no unclassified at this level
509                         string taxon = "unclassified";
510                         copy.push_back(TaxNode(taxon));
511                         copy[index].children[taxon] = copy.size()-1;
512                         copy[copy.size()-1].parent = index;
513                         copy[copy.size()-1].level = copy[index].level + 1;
514                 }
515                 
516                 if (tree[index].level < maxLevel) {
517                         for(it=tree[index].children.begin();it!=tree[index].children.end();it++){ //check your children
518                                 fillOutTree(it->second, copy);
519                         }
520                 }
521
522         }
523         catch(exception& e) {
524                 m->errorOut(e, "PhyloTree", "fillOutTree");
525                 exit(1);
526         }
527 }
528 /**************************************************************************************************/
529 string PhyloTree::getFullTaxonomy(string seqName) {
530         try {
531                 string tax = "";
532                 
533                 int currentNode = name2Taxonomy[seqName];
534                 
535                 while (tree[currentNode].parent != -1) {
536                         tax = tree[currentNode].name + ";" + tax;
537                         currentNode = tree[currentNode].parent;
538                 }
539                 
540                 return tax;
541         }
542         catch(exception& e) {
543                 m->errorOut(e, "PhyloTree", "getFullTaxonomy");
544                 exit(1);
545         }
546 }
547 /**************************************************************************************************/
548
549 void PhyloTree::print(ofstream& out, vector<TaxNode>& copy){
550         try {
551                 
552                 //output mothur version
553                 out << "#" << m->getVersion() << endl;
554                 
555                 out << copy.size() << endl;
556                 
557                 out << maxLevel << endl;
558                                 
559                 for (int i = 0; i < copy.size(); i++) {
560                                 
561                         out << copy[i].level << '\t'<< copy[i].name << '\t' << copy[i].children.size() << '\t';
562                         
563                         map<string,int>::iterator it;
564                         for(it=copy[i].children.begin();it!=copy[i].children.end();it++){
565                                 out << it->first << '\t' << it->second << '\t';
566                         }
567                         out << endl;
568                 }
569                 
570                 out.close();
571         }
572         catch(exception& e) {
573                 m->errorOut(e, "PhyloTree", "print");
574                 exit(1);
575         }
576 }
577 /**************************************************************************************************/
578 void PhyloTree::printTreeNodes(string treefilename) {
579         try {
580         
581                 #ifdef USE_MPI
582                         int pid;
583                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
584
585                         if (pid == 0) {  
586                 
587                 #endif
588
589                         ofstream outTree;
590                         m->openOutputFile(treefilename, outTree);
591                         
592                         //output mothur version
593                         outTree << "#" << m->getVersion() << endl;
594                         
595                         //print treenodes
596                         outTree << tree.size() << endl;
597                         for (int i = 0; i < tree.size(); i++) {
598                                 outTree << tree[i].name << '\t' << tree[i].level << '\t' << tree[i].parent << endl;
599                         }
600                         
601                         //print genus nodes
602                         outTree << endl << uniqueTaxonomies.size() << endl;
603                         set<int>::iterator it2;
604                         for (it2=uniqueTaxonomies.begin(); it2!=uniqueTaxonomies.end(); it2++) {  outTree << *it2 << '\t' << tree[*it2].accessions.size() << endl;      }
605                         outTree << endl;
606                         
607                         outTree.close();
608                 
609                 #ifdef USE_MPI
610                         }
611                 #endif
612
613                 
614         }
615         catch(exception& e) {
616                 m->errorOut(e, "PhyloTree", "printTreeNodes");
617                 exit(1);
618         }
619 }
620 /**************************************************************************************************/
621 TaxNode PhyloTree::get(int i ){
622         try {
623                 if (i < tree.size()) {  return tree[i];  }
624                 else {  cout << i << '\t' << tree.size() << endl ; m->mothurOut("Mismatch with taxonomy and template files. Cannot continue."); m->mothurOutEndLine(); exit(1); }
625         }
626         catch(exception& e) {
627                 m->errorOut(e, "PhyloTree", "get");
628                 exit(1);
629         }
630 }
631 /**************************************************************************************************/
632 TaxNode PhyloTree::get(string seqName){
633         try {
634                 map<string, int>::iterator itFind = name2Taxonomy.find(seqName);
635         
636                 if (itFind != name2Taxonomy.end()) {  return tree[name2Taxonomy[seqName]];  }
637                 else { m->mothurOut("Cannot find " + seqName + ". Mismatch with taxonomy and template files. Cannot continue."); m->mothurOutEndLine(); exit(1);}
638         }
639         catch(exception& e) {
640                 m->errorOut(e, "PhyloTree", "get");
641                 exit(1);
642         }
643 }
644 /**************************************************************************************************/
645 string PhyloTree::getName(int i ){
646         try {
647                 if (i < tree.size()) {  return tree[i].name;     }
648                 else { m->mothurOut("Mismatch with taxonomy and template files. Cannot continue."); m->mothurOutEndLine(); exit(1); }
649         }
650         catch(exception& e) {
651                 m->errorOut(e, "PhyloTree", "get");
652                 exit(1);
653         }
654 }
655 /**************************************************************************************************/
656 int PhyloTree::getGenusIndex(string seqName){
657         try {
658                 map<string, int>::iterator itFind = name2GenusNodeIndex.find(seqName);
659         
660                 if (itFind != name2GenusNodeIndex.end()) {  return itFind->second;  }
661                 else { m->mothurOut("Cannot find " + seqName + ". Could be a mismatch with taxonomy and template files. Cannot continue."); m->mothurOutEndLine(); exit(1);}
662         }
663         catch(exception& e) {
664                 m->errorOut(e, "PhyloTree", "get");
665                 exit(1);
666         }
667 }
668 /**************************************************************************************************/
669 bool PhyloTree::ErrorCheck(vector<string> templateFileNames){
670         try {
671         
672                 bool okay = true;
673                 templateFileNames.push_back("unknown");
674                 
675                 map<string, int>::iterator itFind;
676                 map<string, int> taxonomyFileNames = name2Taxonomy;
677                 
678         if (m->debug) { m->mothurOut("[DEBUG]: in error check. Numseqs in template = " + toString(templateFileNames.size()) + ". Numseqs in taxonomy = " + toString(taxonomyFileNames.size()) + ".\n"); }
679         
680                 for (int i = 0; i < templateFileNames.size(); i++) {
681                         itFind = taxonomyFileNames.find(templateFileNames[i]);
682                         
683                         if (itFind != taxonomyFileNames.end()) { //found it so erase it
684                                 taxonomyFileNames.erase(itFind);
685                         }else {
686                                 m->mothurOut("'" +templateFileNames[i] + "' is in your template file and is not in your taxonomy file. Please correct."); m->mothurOutEndLine();
687                                 okay = false;
688                         }
689                         
690                         //templateFileNames.erase(templateFileNames.begin()+i);
691                         //i--;
692                 }
693                 templateFileNames.clear();
694                 
695                 if (taxonomyFileNames.size() > 0) { //there are names in tax file that are not in template
696                         okay = false;
697                         
698                         for (itFind = taxonomyFileNames.begin(); itFind != taxonomyFileNames.end(); itFind++) {
699                                 m->mothurOut(itFind->first + " is in your taxonomy file and is not in your template file. Please correct."); m->mothurOutEndLine();
700                         }
701                 }
702                 
703                 return okay;
704         }
705         catch(exception& e) {
706                 m->errorOut(e, "PhyloTree", "ErrorCheck");
707                 exit(1);
708         }
709 }
710 /**************************************************************************************************/
711         
712
713
714