]> git.donarmstrong.com Git - mothur.git/blob - mothurout.cpp
Merge remote-tracking branch 'mothur/master'
[mothur.git] / mothurout.cpp
1 /*
2  *  mothurOut.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 2/25/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "mothurout.h"
11
12
13 /******************************************************/
14 MothurOut* MothurOut::getInstance() {
15         if( _uniqueInstance == 0) {
16                 _uniqueInstance = new MothurOut();
17         }
18         return _uniqueInstance;
19 }
20 /*********************************************************************************************/
21 void MothurOut::printCurrentFiles()  {
22         try {
23                 if (accnosfile != "")           {  mothurOut("accnos=" + accnosfile); mothurOutEndLine();                       }
24                 if (columnfile != "")           {  mothurOut("column=" + columnfile); mothurOutEndLine();                       }
25                 if (designfile != "")           {  mothurOut("design=" + designfile); mothurOutEndLine();                       }
26                 if (fastafile != "")            {  mothurOut("fasta=" + fastafile); mothurOutEndLine();                         }
27                 if (groupfile != "")            {  mothurOut("group=" + groupfile); mothurOutEndLine();                         }
28                 if (listfile != "")                     {  mothurOut("list=" + listfile); mothurOutEndLine();                           }
29                 if (namefile != "")                     {  mothurOut("name=" + namefile); mothurOutEndLine();                           }
30                 if (oligosfile != "")           {  mothurOut("oligos=" + oligosfile); mothurOutEndLine();                       }
31                 if (orderfile != "")            {  mothurOut("order=" + orderfile); mothurOutEndLine();                         }
32                 if (ordergroupfile != "")       {  mothurOut("ordergroup=" + ordergroupfile); mothurOutEndLine();       }
33                 if (phylipfile != "")           {  mothurOut("phylip=" + phylipfile); mothurOutEndLine();                       }
34                 if (qualfile != "")                     {  mothurOut("qfile=" + qualfile); mothurOutEndLine();                          }
35                 if (rabundfile != "")           {  mothurOut("rabund=" + rabundfile); mothurOutEndLine();                       }
36                 if (relabundfile != "")         {  mothurOut("relabund=" + relabundfile); mothurOutEndLine();           }
37                 if (sabundfile != "")           {  mothurOut("sabund=" + sabundfile); mothurOutEndLine();                       }
38                 if (sfffile != "")                      {  mothurOut("sff=" + sfffile); mothurOutEndLine();                                     }
39                 if (sharedfile != "")           {  mothurOut("shared=" + sharedfile); mothurOutEndLine();                       }
40                 if (taxonomyfile != "")         {  mothurOut("taxonomy=" + taxonomyfile); mothurOutEndLine();           }
41                 if (treefile != "")                     {  mothurOut("tree=" + treefile); mothurOutEndLine();                           }
42                 if (flowfile != "")                     {  mothurOut("flow=" + flowfile); mothurOutEndLine();                           }
43         if (biomfile != "")                     {  mothurOut("biom=" + biomfile); mothurOutEndLine();                           }
44                 if (processors != "1")          {  mothurOut("processors=" + processors); mothurOutEndLine();           }
45                 
46         }
47         catch(exception& e) {
48                 errorOut(e, "MothurOut", "printCurrentFiles");
49                 exit(1);
50         }
51 }
52 /*********************************************************************************************/
53 bool MothurOut::hasCurrentFiles()  {
54         try {
55                 bool hasCurrent = false;
56                 
57                 if (accnosfile != "")           {  return true;                 }
58                 if (columnfile != "")           {  return true;                 }
59                 if (designfile != "")           {  return true;                 }
60                 if (fastafile != "")            {  return true;                 }
61                 if (groupfile != "")            {  return true;                 }
62                 if (listfile != "")                     {  return true;                 }
63                 if (namefile != "")                     {  return true;                 }
64                 if (oligosfile != "")           {  return true;                 }
65                 if (orderfile != "")            {  return true;                 }
66                 if (ordergroupfile != "")       {  return true;                 }
67                 if (phylipfile != "")           {  return true;                 }
68                 if (qualfile != "")                     {  return true;                 }
69                 if (rabundfile != "")           {  return true;                 }
70                 if (relabundfile != "")         {  return true;                 }
71                 if (sabundfile != "")           {  return true;                 }
72                 if (sfffile != "")                      {  return true;                 }
73                 if (sharedfile != "")           {  return true;                 }
74                 if (taxonomyfile != "")         {  return true;                 }
75                 if (treefile != "")                     {  return true;                 }
76                 if (flowfile != "")                     {  return true;                 }
77         if (biomfile != "")                     {  return true;                 }
78                 if (processors != "1")          {  return true;                 }
79                 
80                 return hasCurrent;
81                 
82         }
83         catch(exception& e) {
84                 errorOut(e, "MothurOut", "hasCurrentFiles");
85                 exit(1);
86         }
87 }
88
89 /*********************************************************************************************/
90 void MothurOut::clearCurrentFiles()  {
91         try {
92                 phylipfile = "";
93                 columnfile = "";
94                 listfile = "";
95                 rabundfile = "";
96                 sabundfile = "";
97                 namefile = "";
98                 groupfile = "";
99                 designfile = "";
100                 orderfile = "";
101                 treefile = "";
102                 sharedfile = "";
103                 ordergroupfile = "";
104                 relabundfile = "";
105                 fastafile = "";
106                 qualfile = "";
107                 sfffile = "";
108                 oligosfile = "";
109                 accnosfile = "";
110                 taxonomyfile = "";      
111                 flowfile = "";
112         biomfile = "";
113                 processors = "1";
114         }
115         catch(exception& e) {
116                 errorOut(e, "MothurOut", "clearCurrentFiles");
117                 exit(1);
118         }
119 }
120 /*********************************************************************************************/
121 void MothurOut::setFileName(string filename)  {
122         try {
123                 logFileName = filename;
124                 
125                 #ifdef USE_MPI
126                         int pid;
127                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
128                                         
129                         if (pid == 0) { //only one process should output to screen
130                 #endif
131                 
132                 openOutputFile(filename, out);
133                 
134                 #ifdef USE_MPI
135                         }
136                 #endif
137         }
138         catch(exception& e) {
139                 errorOut(e, "MothurOut", "setFileName");
140                 exit(1);
141         }
142 }
143 /*********************************************************************************************/
144 void MothurOut::setDefaultPath(string pathname)  {
145         try {
146         
147                 //add / to name if needed
148                 string lastChar = pathname.substr(pathname.length()-1);
149                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
150                         if (lastChar != "/") { pathname += "/"; }
151                 #else
152                         if (lastChar != "\\") { pathname += "\\"; }     
153                 #endif
154                 
155                 defaultPath = pathname;
156                 
157         }
158         catch(exception& e) {
159                 errorOut(e, "MothurOut", "setDefaultPath");
160                 exit(1);
161         }
162 }
163 /*********************************************************************************************/
164 void MothurOut::setOutputDir(string pathname)  {
165         try {
166                 outputDir = pathname;
167         }
168         catch(exception& e) {
169                 errorOut(e, "MothurOut", "setOutputDir");
170                 exit(1);
171         }
172 }
173 /*********************************************************************************************/
174 void MothurOut::closeLog()  {
175         try {
176                 
177                 #ifdef USE_MPI
178                         int pid;
179                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
180                                         
181                         if (pid == 0) { //only one process should output to screen
182                 #endif
183                 
184                 out.close();
185                 
186                 #ifdef USE_MPI
187                         }
188                 #endif
189         }
190         catch(exception& e) {
191                 errorOut(e, "MothurOut", "closeLog");
192                 exit(1);
193         }
194 }
195
196 /*********************************************************************************************/
197 MothurOut::~MothurOut() {
198         try {
199                 _uniqueInstance = 0;
200                 
201         }
202         catch(exception& e) {
203                 errorOut(e, "MothurOut", "MothurOut");
204                 exit(1);
205         }
206 }
207 /*********************************************************************************************/
208 void MothurOut::mothurOut(string output) {
209         try {
210                 
211                 #ifdef USE_MPI
212                         int pid;
213                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
214                                         
215                         if (pid == 0) { //only one process should output to screen
216                 #endif
217                 
218                 out << output;
219         logger() << output;
220                 
221                 #ifdef USE_MPI
222                         }
223                 #endif
224         }
225         catch(exception& e) {
226                 errorOut(e, "MothurOut", "MothurOut");
227                 exit(1);
228         }
229 }
230 /*********************************************************************************************/
231 void MothurOut::mothurOutEndLine() {
232         try {
233                 #ifdef USE_MPI
234                         int pid;
235                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
236                                         
237                         if (pid == 0) { //only one process should output to screen
238                 #endif
239                 
240                 out << endl;
241         logger() << endl;
242                 
243                 #ifdef USE_MPI
244                         }
245                 #endif
246         }
247         catch(exception& e) {
248                 errorOut(e, "MothurOut", "MothurOutEndLine");
249                 exit(1);
250         }
251 }
252 /*********************************************************************************************/
253 void MothurOut::mothurOut(string output, ofstream& outputFile) {
254         try {
255                 
256 #ifdef USE_MPI
257                 int pid;
258                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
259                 
260                 if (pid == 0) { //only one process should output to screen
261 #endif
262                         
263                         
264                         out << output;
265                         outputFile << output;
266             logger() << output;
267                         
268 #ifdef USE_MPI
269                 }
270 #endif
271         
272         }
273         catch(exception& e) {
274                 errorOut(e, "MothurOut", "MothurOut");
275                 exit(1);
276         }
277 }
278 /*********************************************************************************************/
279 void MothurOut::mothurOutEndLine(ofstream& outputFile) {
280         try {
281 #ifdef USE_MPI
282                 int pid;
283                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
284                 
285                 if (pid == 0) { //only one process should output to screen
286 #endif
287                         
288                         out << endl;
289                         outputFile << endl;
290             logger() << endl;
291                         
292 #ifdef USE_MPI
293                 }
294 #endif
295         }
296         catch(exception& e) {
297                 errorOut(e, "MothurOut", "MothurOutEndLine");
298                 exit(1);
299         }
300 }
301 /*********************************************************************************************/
302 void MothurOut::mothurOutJustToLog(string output) {
303         try {
304                 #ifdef USE_MPI
305                         int pid;
306                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); 
307                                         
308                         if (pid == 0) { //only one process should output to screen
309                 #endif
310                 
311                 out << output;
312                 
313                 #ifdef USE_MPI
314                         }
315                 #endif
316         }
317         catch(exception& e) {
318                 errorOut(e, "MothurOut", "MothurOutJustToLog");
319                 exit(1);
320         }
321 }
322 /*********************************************************************************************/
323 void MothurOut::errorOut(exception& e, string object, string function) {
324         //double vm, rss;
325         //mem_usage(vm, rss);
326         
327         mothurOut("[ERROR]: ");
328         mothurOut(toString(e.what()));
329         mothurOut(" has occurred in the " + object + " class function " + function + ". Please contact Pat Schloss at mothur.bugs@gmail.com, and be sure to include the mothur.logFile with your inquiry.");
330         mothurOutEndLine();
331 }
332 /*********************************************************************************************/
333 //The following was originally from http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c 
334 // process_mem_usage(double &, double &) - takes two doubles by reference,
335 // attempts to read the system-dependent data for a process' virtual memory
336 // size and resident set size, and return the results in KB.
337 //
338 // On failure, returns 0.0, 0.0
339 int MothurOut::mem_usage(double& vm_usage, double& resident_set) {
340   #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
341   
342            vm_usage     = 0.0;
343            resident_set = 0.0;
344
345            // 'file' stat seems to give the most reliable results
346            //
347            ifstream stat_stream("/proc/self/stat",ios_base::in);
348
349            // dummy vars for leading entries in stat that we don't care about
350            //
351            string pid, comm, state, ppid, pgrp, session, tty_nr;
352            string tpgid, flags, minflt, cminflt, majflt, cmajflt;
353            string utime, stime, cutime, cstime, priority, nice;
354            string O, itrealvalue, starttime;
355
356            // the two fields we want
357            //
358            unsigned long vsize;
359            long rss;
360
361            stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
362                                    >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
363                                    >> utime >> stime >> cutime >> cstime >> priority >> nice
364                                    >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
365
366            long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
367            vm_usage     = vsize / 1024.0;
368            resident_set = rss * page_size_kb;
369            
370            mothurOut("Memory Usage: vm = " + toString(vm_usage) + " rss = " + toString(resident_set) + "\n");
371                 return 0;
372
373         #else
374 /*              //windows memory usage
375                 // Get the list of process identifiers.
376                 DWORD aProcesses[1024], cbNeeded, cProcesses;
377                 
378                 if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ){ return 1; }
379
380                 // Calculate how many process identifiers were returned.
381                 cProcesses = cbNeeded / sizeof(DWORD);
382
383                 // Print the memory usage for each process
384                 for (int i = 0; i < cProcesses; i++ ) {
385                         DWORD processID = aProcesses[i];
386                         
387                         PROCESS_MEMORY_COUNTERS pmc;
388
389                         HANDLE hProcess = OpenProcess((PROCESS_QUERY_INFORMATION | PROCESS_VM_READ), FALSE, processID);
390
391                         // Print the process identifier.
392                         printf( "\nProcess ID: %u\n", processID);
393                         
394                         if (NULL != hProcess) {
395
396                                 if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
397                                         printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
398                                         printf( "\tPeakWorkingSetSize: 0x%08X\n", pmc.PeakWorkingSetSize );
399                                         printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
400                                         printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakPagedPoolUsage );
401                                         printf( "\tQuotaPagedPoolUsage: 0x%08X\n", pmc.QuotaPagedPoolUsage );
402                                         printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakNonPagedPoolUsage );
403                                         printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", pmc.QuotaNonPagedPoolUsage );
404                                         printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); 
405                                         printf( "\tPeakPagefileUsage: 0x%08X\n", pmc.PeakPagefileUsage );
406                                 }
407                                 CloseHandle(hProcess);
408                         }
409                 }
410 */
411                         return 0;
412
413         #endif
414 }
415
416
417 /***********************************************************************/
418 int MothurOut::openOutputFileAppend(string fileName, ofstream& fileHandle){
419         try {
420                 fileName = getFullPathName(fileName);
421                 
422                 fileHandle.open(fileName.c_str(), ios::app);
423                 if(!fileHandle) {
424                         mothurOut("[ERROR]: Could not open " + fileName); mothurOutEndLine();
425                         return 1;
426                 }
427                 else {
428                         return 0;
429                 }
430         }
431         catch(exception& e) {
432                 errorOut(e, "MothurOut", "openOutputFileAppend");
433                 exit(1);
434         }
435 }
436 /***********************************************************************/
437 void MothurOut::gobble(istream& f){
438         try {
439                 
440                 char d;
441                 while(isspace(d=f.get()))               { ;}
442                 if(!f.eof()) { f.putback(d); }
443         }
444         catch(exception& e) {
445                 errorOut(e, "MothurOut", "gobble");
446                 exit(1);
447         }
448 }
449 /***********************************************************************/
450 void MothurOut::gobble(istringstream& f){
451         try {
452                 char d;
453                 while(isspace(d=f.get()))               {;}
454                 if(!f.eof()) { f.putback(d); }
455         }
456         catch(exception& e) {
457                 errorOut(e, "MothurOut", "gobble");
458                 exit(1);
459         }
460 }
461
462 /***********************************************************************/
463
464 string MothurOut::getline(istringstream& fileHandle) {
465         try {
466         
467                 string line = "";
468                 
469                 while (!fileHandle.eof())       {
470                         //get next character
471                         char c = fileHandle.get(); 
472                         
473                         //are you at the end of the line
474                         if ((c == '\n') || (c == '\r') || (c == '\f')){  break; }       
475                         else {          line += c;              }
476                 }
477                 
478                 return line;
479                 
480         }
481         catch(exception& e) {
482                 errorOut(e, "MothurOut", "getline");
483                 exit(1);
484         }
485 }
486 /***********************************************************************/
487
488 string MothurOut::getline(ifstream& fileHandle) {
489         try {
490         
491                 string line = "";
492                 
493                 while (fileHandle)      {
494                         //get next character
495                         char c = fileHandle.get(); 
496                         
497                         //are you at the end of the line
498                         if ((c == '\n') || (c == '\r') || (c == '\f') || (c == EOF)){  break;   }       
499                         else {          line += c;              }
500                 }
501                 
502                 return line;
503                 
504         }
505         catch(exception& e) {
506                 errorOut(e, "MothurOut", "getline");
507                 exit(1);
508         }
509 }
510 /***********************************************************************/
511
512 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
513 #ifdef USE_COMPRESSION
514 inline bool endsWith(string s, const char * suffix){
515   size_t suffixLength = strlen(suffix);
516   return s.size() >= suffixLength && s.substr(s.size() - suffixLength, suffixLength).compare(suffix) == 0;
517 }
518 #endif
519 #endif
520
521 string MothurOut::getRootName(string longName){
522         try {
523         
524                 string rootName = longName;
525
526 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
527 #ifdef USE_COMPRESSION
528     if (endsWith(rootName, ".gz") || endsWith(rootName, ".bz2")) {
529       int pos = rootName.find_last_of('.');
530       rootName = rootName.substr(0, pos);
531       cerr << "shortening " << longName << " to " << rootName << "\n";
532     }
533 #endif
534 #endif
535                 if(rootName.find_last_of(".") != rootName.npos){
536                         int pos = rootName.find_last_of('.')+1;
537                         rootName = rootName.substr(0, pos);
538                 }
539
540                 return rootName;
541         }
542         catch(exception& e) {
543                 errorOut(e, "MothurOut", "getRootName");
544                 exit(1);
545         }
546 }
547 /***********************************************************************/
548
549 string MothurOut::getSimpleName(string longName){
550         try {
551                 string simpleName = longName;
552                 
553                 size_t found;
554                 found=longName.find_last_of("/\\");
555
556                 if(found != longName.npos){
557                         simpleName = longName.substr(found+1);
558                 }
559                 
560                 return simpleName;
561         }
562         catch(exception& e) {
563                 errorOut(e, "MothurOut", "getSimpleName");
564                 exit(1);
565         }
566 }
567
568 /***********************************************************************/
569
570 int MothurOut::getRandomIndex(int highest){
571         try {
572                 
573                 int random = (int) ((float)(highest+1) * (float)(rand()) / ((float)RAND_MAX+1.0));
574                 
575                 return random;
576         }
577         catch(exception& e) {
578                 errorOut(e, "MothurOut", "getRandomIndex");
579                 exit(1);
580         }       
581         
582 }
583 /**********************************************************************/
584
585 string MothurOut::getPathName(string longName){
586         try {
587                 string rootPathName = longName;
588                 
589                 if(longName.find_last_of("/\\") != longName.npos){
590                         int pos = longName.find_last_of("/\\")+1;
591                         rootPathName = longName.substr(0, pos);
592                 }
593                 
594                 return rootPathName;
595         }
596         catch(exception& e) {
597                 errorOut(e, "MothurOut", "getPathName");
598                 exit(1);
599         }       
600
601 }
602 /***********************************************************************/
603
604 bool MothurOut::dirCheck(string& dirName){
605         try {
606         
607         string tag = "";
608         #ifdef USE_MPI
609             int pid; 
610             MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
611                 
612             tag = toString(pid);
613         #endif
614
615         //add / to name if needed
616         string lastChar = dirName.substr(dirName.length()-1);
617         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
618         if (lastChar != "/") { dirName += "/"; }
619         #else
620         if (lastChar != "\\") { dirName += "\\"; }      
621         #endif
622
623         //test to make sure directory exists
624         dirName = getFullPathName(dirName);
625         string outTemp = dirName + tag + "temp";
626         ofstream out;
627         out.open(outTemp.c_str(), ios::trunc);
628         if(!out) {
629             mothurOut(dirName + " directory does not exist or is not writable."); mothurOutEndLine(); 
630         }else{
631             out.close();
632             mothurRemove(outTemp);
633             return true;
634         }
635         
636         return false;
637     }
638         catch(exception& e) {
639                 errorOut(e, "MothurOut", "dirCheck");
640                 exit(1);
641         }       
642     
643 }
644 /***********************************************************************/
645
646 string MothurOut::hasPath(string longName){
647         try {
648                 string path = "";
649                 
650                 size_t found;
651                 found=longName.find_last_of("~/\\");
652
653                 if(found != longName.npos){
654                         path = longName.substr(0, found+1);
655                 }
656                 
657                 return path;
658         }
659         catch(exception& e) {
660                 errorOut(e, "MothurOut", "hasPath");
661                 exit(1);
662         }       
663 }
664
665 /***********************************************************************/
666
667 string MothurOut::getExtension(string longName){
668         try {
669                 string extension = "";
670                 
671                 if(longName.find_last_of('.') != longName.npos){
672                         int pos = longName.find_last_of('.');
673                         extension = longName.substr(pos, longName.length());
674                 }
675                 
676                 return extension;
677         }
678         catch(exception& e) {
679                 errorOut(e, "MothurOut", "getExtension");
680                 exit(1);
681         }       
682 }
683 /***********************************************************************/
684 bool MothurOut::isBlank(string fileName){
685         try {
686                 
687                 fileName = getFullPathName(fileName);
688                 
689                 ifstream fileHandle;
690                 fileHandle.open(fileName.c_str());
691                 if(!fileHandle) {
692                         mothurOut("[ERROR]: Could not open " + fileName); mothurOutEndLine();
693                         return false;
694                 }else {
695                         //check for blank file
696                         gobble(fileHandle);
697                         if (fileHandle.eof()) { fileHandle.close(); return true;  }
698                         fileHandle.close();
699                 }
700                 return false;
701         }
702         catch(exception& e) {
703                 errorOut(e, "MothurOut", "isBlank");
704                 exit(1);
705         }       
706 }
707 /***********************************************************************/
708
709 string MothurOut::getFullPathName(string fileName){
710         try{
711         
712         string path = hasPath(fileName);
713         string newFileName;
714         int pos;
715         
716         if (path == "") { return fileName; } //its a simple name
717         else { //we need to complete the pathname
718                 // ex. ../../../filename 
719                 // cwd = /user/work/desktop
720                                 
721                 string cwd;
722                 //get current working directory 
723                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)  
724                         
725                         if (path.find("~") != -1) { //go to home directory
726                                 string homeDir;
727                         
728                                 char *homepath = NULL;
729                                 homepath = getenv ("HOME");
730                                 if ( homepath != NULL) { homeDir = homepath; }
731                                 else { homeDir = "";  }
732
733                                 newFileName = homeDir + fileName.substr(fileName.find("~")+1);
734                                 return newFileName;
735                         }else { //find path
736                                 if (path.rfind("./") == string::npos) { return fileName; } //already complete name
737                                 else { newFileName = fileName.substr(fileName.rfind("./")+2); } //save the complete part of the name
738                                 
739                                 //char* cwdpath = new char[1024];
740                                 //size_t size;
741                                 //cwdpath=getcwd(cwdpath,size);
742                                 //cwd = cwdpath;
743                                 
744                                 char *cwdpath = NULL;
745                                 cwdpath = getcwd(NULL, 0); // or _getcwd
746                                 if ( cwdpath != NULL) { cwd = cwdpath; }
747                                 else { cwd = "";  }
748
749                                 
750                                 //rip off first '/'
751                                 string simpleCWD;
752                                 if (cwd.length() > 0) { simpleCWD = cwd.substr(1); }
753                                 
754                                 //break apart the current working directory
755                                 vector<string> dirs;
756                                 while (simpleCWD.find_first_of('/') != string::npos) {
757                                         string dir = simpleCWD.substr(0,simpleCWD.find_first_of('/'));
758                                         simpleCWD = simpleCWD.substr(simpleCWD.find_first_of('/')+1, simpleCWD.length());
759                                         dirs.push_back(dir);
760                                 }
761                                 //get last one              // ex. ../../../filename = /user/work/desktop/filename
762                                 dirs.push_back(simpleCWD);  //ex. dirs[0] = user, dirs[1] = work, dirs[2] = desktop
763                                 
764                         
765                                 int index = dirs.size()-1;
766                 
767                                 while((pos = path.rfind("./")) != string::npos) { //while you don't have a complete path
768                                         if (pos == 0) { break;  //you are at the end
769                                         }else if (path[(pos-1)] == '.') { //you want your parent directory ../
770                                                 path = path.substr(0, pos-1);
771                                                 index--;
772                                                 if (index == 0) {  break; }
773                                         }else if (path[(pos-1)] == '/') { //you want the current working dir ./
774                                                 path = path.substr(0, pos);
775                                         }else if (pos == 1) { break;  //you are at the end
776                                         }else { mothurOut("cannot resolve path for " +  fileName + "\n"); return fileName; }
777                                 }
778                         
779                                 for (int i = index; i >= 0; i--) {
780                                         newFileName = dirs[i] +  "/" + newFileName;             
781                                 }
782                                 
783                                 newFileName =  "/" +  newFileName;
784                                 return newFileName;
785                         }       
786                 #else
787                         if (path.find("~") != string::npos) { //go to home directory
788                                 string homeDir = getenv ("HOMEPATH");
789                                 newFileName = homeDir + fileName.substr(fileName.find("~")+1);
790                                 return newFileName;
791                         }else { //find path
792                                 if (path.rfind(".\\") == string::npos) { return fileName; } //already complete name
793                                 else { newFileName = fileName.substr(fileName.rfind(".\\")+2); } //save the complete part of the name
794                                                         
795                                 char *cwdpath = NULL;
796                                 cwdpath = getcwd(NULL, 0); // or _getcwd
797                                 if ( cwdpath != NULL) { cwd = cwdpath; }
798                                 else { cwd = "";  }
799                                 
800                                 //break apart the current working directory
801                                 vector<string> dirs;
802                                 while (cwd.find_first_of('\\') != -1) {
803                                         string dir = cwd.substr(0,cwd.find_first_of('\\'));
804                                         cwd = cwd.substr(cwd.find_first_of('\\')+1, cwd.length());
805                                         dirs.push_back(dir);
806                 
807                                 }
808                                 //get last one
809                                 dirs.push_back(cwd);  //ex. dirs[0] = user, dirs[1] = work, dirs[2] = desktop
810                                         
811                                 int index = dirs.size()-1;
812                                         
813                                 while((pos = path.rfind(".\\")) != string::npos) { //while you don't have a complete path
814                                         if (pos == 0) { break;  //you are at the end
815                                         }else if (path[(pos-1)] == '.') { //you want your parent directory ../
816                                                 path = path.substr(0, pos-1);
817                                                 index--;
818                                                 if (index == 0) {  break; }
819                                         }else if (path[(pos-1)] == '\\') { //you want the current working dir ./
820                                                 path = path.substr(0, pos);
821                                         }else if (pos == 1) { break;  //you are at the end
822                                         }else { mothurOut("cannot resolve path for " +  fileName + "\n"); return fileName; }
823                                 }
824                         
825                                 for (int i = index; i >= 0; i--) {
826                                         newFileName = dirs[i] +  "\\" + newFileName;            
827                                 }
828                                 
829                                 return newFileName;
830                         }
831                         
832                 #endif
833         }
834         }
835         catch(exception& e) {
836                 errorOut(e, "MothurOut", "getFullPathName");
837                 exit(1);
838         }       
839 }
840 /***********************************************************************/
841
842 int MothurOut::openInputFile(string fileName, ifstream& fileHandle, string m){
843         try {
844                         //get full path name
845                         string completeFileName = getFullPathName(fileName);
846 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
847 #ifdef USE_COMPRESSION
848       // check for gzipped or bzipped file
849       if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
850         string tempName = string(tmpnam(0));
851         mkfifo(tempName.c_str(), 0666);
852         int fork_result = fork();
853         if (fork_result < 0) {
854           cerr << "Error forking.\n";
855           exit(1);
856         } else if (fork_result == 0) {
857           string command = (endsWith(completeFileName, ".gz") ? "zcat " : "bzcat ") + completeFileName + string(" > ") + tempName;
858           cerr << "Decompressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
859           system(command.c_str());
860           cerr << "Done decompressing " << completeFileName << "\n";
861           mothurRemove(tempName);
862           exit(EXIT_SUCCESS);
863         } else {
864           cerr << "waiting on child process " << fork_result << "\n";
865           completeFileName = tempName;
866         }
867       }
868 #endif
869 #endif
870                         fileHandle.open(completeFileName.c_str());
871                         if(!fileHandle) {
872                                 //mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
873                                 return 1;
874                         }else {
875                                 //check for blank file
876                                 gobble(fileHandle);
877                                 return 0;
878                         }
879         }
880         catch(exception& e) {
881                 errorOut(e, "MothurOut", "openInputFile - no Error");
882                 exit(1);
883         }
884 }
885 /***********************************************************************/
886
887 int MothurOut::openInputFile(string fileName, ifstream& fileHandle){
888         try {
889
890                 //get full path name
891                 string completeFileName = getFullPathName(fileName);
892 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
893 #ifdef USE_COMPRESSION
894   // check for gzipped or bzipped file
895   if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
896     string tempName = string(tmpnam(0));
897     mkfifo(tempName.c_str(), 0666);
898     int fork_result = fork();
899     if (fork_result < 0) {
900       cerr << "Error forking.\n";
901       exit(1);
902     } else if (fork_result == 0) {
903       string command = (endsWith(completeFileName, ".gz") ? "zcat " : "bzcat ") + completeFileName + string(" > ") + tempName;
904       cerr << "Decompressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
905       system(command.c_str());
906       cerr << "Done decompressing " << completeFileName << "\n";
907       mothurRemove(tempName);
908       exit(EXIT_SUCCESS);
909     } else {
910       cerr << "waiting on child process " << fork_result << "\n";
911       completeFileName = tempName;
912     }
913   }
914 #endif
915 #endif
916
917                 fileHandle.open(completeFileName.c_str());
918                 if(!fileHandle) {
919                         mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
920                         return 1;
921                 }
922                 else {
923                         //check for blank file
924                         gobble(fileHandle);
925                         if (fileHandle.eof()) { mothurOut("[ERROR]: " + completeFileName + " is blank. Please correct."); mothurOutEndLine();  }
926                         
927                         return 0;
928                 }
929         }
930         catch(exception& e) {
931                 errorOut(e, "MothurOut", "openInputFile");
932                 exit(1);
933         }       
934 }
935 /***********************************************************************/
936
937 int MothurOut::renameFile(string oldName, string newName){
938         try {
939                 ifstream inTest;
940                 int exist = openInputFile(newName, inTest, "");
941                 inTest.close();
942                 
943         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)          
944                 if (exist == 0) { //you could open it so you want to delete it
945                         string command = "rm " + newName;
946                         system(command.c_str());
947                 }
948                                 
949                 string command = "mv " + oldName + " " + newName;
950                 system(command.c_str());
951         #else
952                 mothurRemove(newName);
953                 int renameOk = rename(oldName.c_str(), newName.c_str());
954         #endif
955                 return 0;
956                 
957         }
958         catch(exception& e) {
959                 errorOut(e, "MothurOut", "renameFile");
960                 exit(1);
961         }       
962 }
963
964 /***********************************************************************/
965
966 int MothurOut::openOutputFile(string fileName, ofstream& fileHandle){
967         try { 
968         
969                 string completeFileName = getFullPathName(fileName);
970 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
971 #ifdef USE_COMPRESSION
972     // check for gzipped file
973     if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
974       string tempName = string(tmpnam(0));
975       mkfifo(tempName.c_str(), 0666);
976       cerr << "Compressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
977       int fork_result = fork();
978       if (fork_result < 0) {
979         cerr << "Error forking.\n";
980         exit(1);
981       } else if (fork_result == 0) {
982         string command = string(endsWith(completeFileName, ".gz") ?  "gzip" : "bzip2") + " -v > " + completeFileName + string(" < ") + tempName;
983         system(command.c_str());
984         exit(0);
985       } else {
986         completeFileName = tempName;
987       }
988     }
989 #endif
990 #endif
991                 fileHandle.open(completeFileName.c_str(), ios::trunc);
992                 if(!fileHandle) {
993                         mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
994                         return 1;
995                 }
996                 else {
997                         return 0;
998                 }
999         }
1000         catch(exception& e) {
1001                 errorOut(e, "MothurOut", "openOutputFile");
1002                 exit(1);
1003         }       
1004
1005 }
1006
1007 /**************************************************************************************************/
1008 int MothurOut::appendFiles(string temp, string filename) {
1009         try{
1010                 ofstream output;
1011                 ifstream input;
1012         
1013                 //open output file in append mode
1014                 openOutputFileAppend(filename, output);
1015                 int ableToOpen = openInputFile(temp, input, "no error");
1016                 //int ableToOpen = openInputFile(temp, input);
1017                 
1018                 int numLines = 0;
1019                 if (ableToOpen == 0) { //you opened it
1020                         while(!input.eof()){
1021                 char c = input.get();
1022                                 if(input.eof())         {       break;                  }
1023                                 else                            {       output << c;    if (c == '\n') {numLines++;} }
1024                         }
1025                         input.close();
1026                 }
1027                 
1028                 output.close();
1029                 
1030                 return numLines;
1031         }
1032         catch(exception& e) {
1033                 errorOut(e, "MothurOut", "appendFiles");
1034                 exit(1);
1035         }       
1036 }
1037
1038 /**************************************************************************************************/
1039 string MothurOut::sortFile(string distFile, string outputDir){
1040         try {   
1041         
1042                 //if (outputDir == "") {  outputDir += hasPath(distFile);  }
1043                 string outfile = getRootName(distFile) + "sorted.dist";
1044
1045                 
1046                 //if you can, use the unix sort since its been optimized for years
1047                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
1048                         string command = "sort -n -k +3 " + distFile + " -o " + outfile;
1049                         system(command.c_str());
1050                 #else //you are stuck with my best attempt...
1051                         //windows sort does not have a way to specify a column, only a character in the line
1052                         //since we cannot assume that the distance will always be at the the same character location on each line
1053                         //due to variable sequence name lengths, I chose to force the distance into first position, then sort and then put it back.
1054                 
1055                         //read in file line by file and put distance first
1056                         string tempDistFile = distFile + ".temp";
1057                         ifstream input;
1058                         ofstream output;
1059                         openInputFile(distFile, input);
1060                         openOutputFile(tempDistFile, output);
1061
1062                         string firstName, secondName;
1063                         float dist;
1064                         while (input) {
1065                                 input >> firstName >> secondName >> dist;
1066                                 output << dist << '\t' << firstName << '\t' << secondName << endl;
1067                                 gobble(input);
1068                         }
1069                         input.close();
1070                         output.close();
1071                 
1072         
1073                         //sort using windows sort
1074                         string tempOutfile = outfile + ".temp";
1075                         string command = "sort " + tempDistFile + " /O " + tempOutfile;
1076                         system(command.c_str());
1077                 
1078                         //read in sorted file and put distance at end again
1079                         ifstream input2;
1080                         openInputFile(tempOutfile, input2);
1081                         openOutputFile(outfile, output);
1082                 
1083                         while (input2) {
1084                                 input2 >> dist >> firstName >> secondName;
1085                                 output << firstName << '\t' << secondName << '\t' << dist << endl;
1086                                 gobble(input2);
1087                         }
1088                         input2.close();
1089                         output.close();
1090                 
1091                         //remove temp files
1092                         mothurRemove(tempDistFile);
1093                         mothurRemove(tempOutfile);
1094                 #endif
1095                 
1096                 return outfile;
1097         }
1098         catch(exception& e) {
1099                 errorOut(e, "MothurOut", "sortFile");
1100                 exit(1);
1101         }       
1102 }
1103 /**************************************************************************************************/
1104 vector<unsigned long long> MothurOut::setFilePosFasta(string filename, int& num) {
1105         try {
1106                         vector<unsigned long long> positions;
1107                         ifstream inFASTA;
1108                         //openInputFile(filename, inFASTA);
1109                         inFASTA.open(filename.c_str(), ios::binary);
1110                                                 
1111                         string input;
1112                         unsigned long long count = 0;
1113                         while(!inFASTA.eof()){
1114                                 //input = getline(inFASTA); 
1115                                 //cout << input << '\t' << inFASTA.tellg() << endl;
1116                                 //if (input.length() != 0) {
1117                                 //      if(input[0] == '>'){    unsigned long int pos = inFASTA.tellg(); positions.push_back(pos - input.length() - 1);  cout << (pos - input.length() - 1) << endl; }
1118                                 //}
1119                                 //gobble(inFASTA); //has to be here since windows line endings are 2 characters and mess up the positions
1120                                 char c = inFASTA.get(); count++;
1121                                 if (c == '>') {
1122                                         positions.push_back(count-1);
1123                                         //cout << count << endl;
1124                                 }
1125                         }
1126                         inFASTA.close();
1127                 
1128                         num = positions.size();
1129                 
1130                         /*FILE * pFile;
1131                         long size;
1132                 
1133                         //get num bytes in file
1134                         pFile = fopen (filename.c_str(),"rb");
1135                         if (pFile==NULL) perror ("Error opening file");
1136                         else{
1137                                 fseek (pFile, 0, SEEK_END);
1138                                 size=ftell (pFile);
1139                                 fclose (pFile);
1140                         }*/
1141                         
1142                         unsigned long long size = positions[(positions.size()-1)];
1143                         ifstream in;
1144                         openInputFile(filename, in);
1145                         
1146                         in.seekg(size);
1147                 
1148                         while(in.get()){
1149                                 if(in.eof())            {       break;  }
1150                                 else                            {       size++; }
1151                         }
1152                         in.close();
1153                 
1154                         positions.push_back(size);
1155                         positions[0] = 0;
1156                 
1157                         return positions;
1158         }
1159         catch(exception& e) {
1160                 errorOut(e, "MothurOut", "setFilePosFasta");
1161                 exit(1);
1162         }
1163 }
1164 /**************************************************************************************************/
1165 vector<unsigned long long> MothurOut::setFilePosEachLine(string filename, int& num) {
1166         try {
1167                         filename = getFullPathName(filename);
1168                         
1169                         vector<unsigned long long> positions;
1170                         ifstream in;
1171                         //openInputFile(filename, in);
1172                         in.open(filename.c_str(), ios::binary);
1173                 
1174                         string input;
1175                         unsigned long long count = 0;
1176                         positions.push_back(0);
1177                 
1178                         while(!in.eof()){
1179                                 //unsigned long long lastpos = in.tellg();
1180                                 //input = getline(in); 
1181                                 //if (input.length() != 0) {
1182                                         //unsigned long long pos = in.tellg(); 
1183                                         //if (pos != -1) { positions.push_back(pos - input.length() - 1);       }
1184                                         //else {  positions.push_back(lastpos);  }
1185                                 //}
1186                                 //gobble(in); //has to be here since windows line endings are 2 characters and mess up the positions
1187                                 
1188                                 
1189                                 //getline counting reads
1190                                 char d = in.get(); count++;
1191                                 while ((d != '\n') && (d != '\r') && (d != '\f') && (d != in.eof()))    {
1192                                         //get next character
1193                                         d = in.get(); 
1194                                         count++;
1195                                 }
1196                                 
1197                                 if (!in.eof()) {
1198                                         d=in.get(); count++;
1199                                         while(isspace(d) && (d != in.eof()))            { d=in.get(); count++;}
1200                                 }
1201                                 positions.push_back(count-1);
1202                                 //cout << count-1 << endl;
1203                         }
1204                         in.close();
1205                 
1206                         num = positions.size()-1;
1207                 
1208                         FILE * pFile;
1209                         unsigned long long size;
1210                         
1211                         //get num bytes in file
1212                         pFile = fopen (filename.c_str(),"rb");
1213                         if (pFile==NULL) perror ("Error opening file");
1214                         else{
1215                                 fseek (pFile, 0, SEEK_END);
1216                                 size=ftell (pFile);
1217                                 fclose (pFile);
1218                         }
1219                 
1220                         positions[(positions.size()-1)] = size;
1221                 
1222                         return positions;
1223         }
1224         catch(exception& e) {
1225                 errorOut(e, "MothurOut", "setFilePosEachLine");
1226                 exit(1);
1227         }
1228 }
1229 /**************************************************************************************************/
1230
1231 vector<unsigned long long> MothurOut::divideFile(string filename, int& proc) {
1232         try{
1233                 vector<unsigned long long> filePos;
1234                 filePos.push_back(0);
1235                 
1236                 FILE * pFile;
1237                 unsigned long long size;
1238                 
1239                 filename = getFullPathName(filename);
1240         
1241                 //get num bytes in file
1242                 pFile = fopen (filename.c_str(),"rb");
1243                 if (pFile==NULL) perror ("Error opening file");
1244                 else{
1245                         fseek (pFile, 0, SEEK_END);
1246                         size=ftell (pFile);
1247                         fclose (pFile);
1248                 }
1249                 
1250         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
1251                                 
1252                 //estimate file breaks
1253                 unsigned long long chunkSize = 0;
1254                 chunkSize = size / proc;
1255
1256                 //file to small to divide by processors
1257                 if (chunkSize == 0)  {  proc = 1;       filePos.push_back(size); return filePos;        }
1258         
1259                 //for each process seekg to closest file break and search for next '>' char. make that the filebreak
1260                 for (int i = 0; i < proc; i++) {
1261                         unsigned long long spot = (i+1) * chunkSize;
1262                         
1263                         ifstream in;
1264                         openInputFile(filename, in);
1265                         in.seekg(spot);
1266                         
1267                         //look for next '>'
1268                         unsigned long long newSpot = spot;
1269                         while (!in.eof()) {
1270                            char c = in.get();
1271                                 
1272                            if (c == '>') {   in.putback(c); newSpot = in.tellg(); break;  }
1273                            else if (int(c) == -1) { break; }
1274                                 
1275                         }
1276                 
1277                         //there was not another sequence before the end of the file
1278                         unsigned long long sanityPos = in.tellg();
1279
1280                         if (sanityPos == -1) {  break;  }
1281                         else {  filePos.push_back(newSpot);  }
1282                         
1283                         in.close();
1284                 }
1285                 
1286                 //save end pos
1287                 filePos.push_back(size);
1288                 
1289                 //sanity check filePos
1290                 for (int i = 0; i < (filePos.size()-1); i++) {
1291                         if (filePos[(i+1)] <= filePos[i]) {  filePos.erase(filePos.begin()+(i+1)); i--; }
1292                 }
1293
1294                 proc = (filePos.size() - 1);
1295 #else
1296                 mothurOut("[ERROR]: Windows version should not be calling the divideFile function."); mothurOutEndLine();
1297                 proc=1;
1298                 filePos.push_back(size);
1299 #endif
1300                 return filePos;
1301         }
1302         catch(exception& e) {
1303                 errorOut(e, "MothurOut", "divideFile");
1304                 exit(1);
1305         }
1306 }
1307 /**************************************************************************************************/
1308 int MothurOut::divideFile(string filename, int& proc, vector<string>& files) {
1309         try{
1310                 
1311                 vector<unsigned long long> filePos = divideFile(filename, proc);
1312                 
1313                 for (int i = 0; i < (filePos.size()-1); i++) {
1314                         
1315                         //read file chunk
1316                         ifstream in;
1317                         openInputFile(filename, in);
1318                         in.seekg(filePos[i]);
1319                         unsigned long long size = filePos[(i+1)] - filePos[i];
1320                         char* chunk = new char[size];
1321                         in.read(chunk, size);
1322                         in.close();
1323                         
1324                         //open new file
1325                         string fileChunkName = filename + "." + toString(i) + ".tmp";
1326                         ofstream out; 
1327                         openOutputFile(fileChunkName, out);
1328                         
1329                         out << chunk << endl;
1330                         out.close();
1331                         delete[] chunk;
1332                         
1333                         //save name
1334                         files.push_back(fileChunkName);
1335                 }
1336                                 
1337                 return 0;
1338         }
1339         catch(exception& e) {
1340                 errorOut(e, "MothurOut", "divideFile");
1341                 exit(1);
1342         }
1343 }
1344 /***********************************************************************/
1345
1346 bool MothurOut::isTrue(string f){
1347         try {
1348                 
1349                 for (int i = 0; i < f.length(); i++) { f[i] = toupper(f[i]); }
1350                 
1351                 if ((f == "TRUE") || (f == "T")) {      return true;    }
1352                 else {  return false;  }
1353         }
1354         catch(exception& e) {
1355                 errorOut(e, "MothurOut", "isTrue");
1356                 exit(1);
1357         }
1358 }
1359
1360 /***********************************************************************/
1361
1362 float MothurOut::roundDist(float dist, int precision){
1363         try {
1364                 return int(dist * precision + 0.5)/float(precision);
1365         }
1366         catch(exception& e) {
1367                 errorOut(e, "MothurOut", "roundDist");
1368                 exit(1);
1369         }
1370 }
1371 /***********************************************************************/
1372
1373 float MothurOut::ceilDist(float dist, int precision){
1374         try {
1375                 return int(ceil(dist * precision))/float(precision);
1376         }
1377         catch(exception& e) {
1378                 errorOut(e, "MothurOut", "ceilDist");
1379                 exit(1);
1380         }
1381 }
1382 /**********************************************************************************************************************/
1383 int MothurOut::readNames(string namefile, map<string, string>& nameMap) { 
1384         try {
1385                 
1386                 //open input file
1387                 ifstream in;
1388                 openInputFile(namefile, in);
1389                 
1390                 while (!in.eof()) {
1391                         if (control_pressed) { break; }
1392                         
1393                         string firstCol, secondCol;
1394                         in >> firstCol >> secondCol; gobble(in);
1395                         
1396                         nameMap[firstCol] = secondCol;
1397                 }
1398                 in.close();
1399                 
1400                 return nameMap.size();
1401                 
1402         }
1403         catch(exception& e) {
1404                 errorOut(e, "MothurOut", "readNames");
1405                 exit(1);
1406         }
1407 }
1408 /**********************************************************************************************************************/
1409 int MothurOut::readNames(string namefile, map<string, vector<string> >& nameMap) { 
1410         try {
1411                 
1412                 //open input file
1413                 ifstream in;
1414                 openInputFile(namefile, in);
1415                 
1416                 while (!in.eof()) {
1417                         if (control_pressed) { break; }
1418                         
1419                         string firstCol, secondCol;
1420                         in >> firstCol >> secondCol; gobble(in);
1421                         
1422                         vector<string> temp;
1423                         splitAtComma(secondCol, temp);
1424                         
1425                         nameMap[firstCol] = temp;
1426                 }
1427                 in.close();
1428                 
1429                 return nameMap.size();
1430                 
1431         }
1432         catch(exception& e) {
1433                 errorOut(e, "MothurOut", "readNames");
1434                 exit(1);
1435         }
1436 }
1437 /**********************************************************************************************************************/
1438 map<string, int> MothurOut::readNames(string namefile) { 
1439         try {
1440                 
1441                 map<string, int> nameMap;
1442                 
1443                 //open input file
1444                 ifstream in;
1445                 openInputFile(namefile, in);
1446                 
1447                 while (!in.eof()) {
1448                         if (control_pressed) { break; }
1449                         
1450                         string firstCol, secondCol;
1451                         in >> firstCol;  gobble(in);
1452             in >> secondCol; gobble(in);
1453                         
1454                         int num = getNumNames(secondCol);
1455                         
1456                         nameMap[firstCol] = num;
1457                 }
1458                 in.close();
1459                 
1460                 return nameMap;
1461                 
1462         }
1463         catch(exception& e) {
1464                 errorOut(e, "MothurOut", "readNames");
1465                 exit(1);
1466         }
1467 }
1468 /**********************************************************************************************************************/
1469 int MothurOut::readNames(string namefile, vector<seqPriorityNode>& nameVector, map<string, string>& fastamap) { 
1470         try {
1471                 int error = 0;
1472                 
1473                 //open input file
1474                 ifstream in;
1475                 openInputFile(namefile, in);
1476                 
1477                 while (!in.eof()) {
1478                         if (control_pressed) { break; }
1479                         
1480                         string firstCol, secondCol;
1481                         in >> firstCol >> secondCol; gobble(in);
1482                         
1483                         int num = getNumNames(secondCol);
1484                         
1485                         map<string, string>::iterator it = fastamap.find(firstCol);
1486                         if (it == fastamap.end()) {
1487                                 error = 1;
1488                                 mothurOut("[ERROR]: " + firstCol + " is not in your fastafile, but is in your namesfile, please correct."); mothurOutEndLine();
1489                         }else {
1490                                 seqPriorityNode temp(num, it->second, firstCol);
1491                                 nameVector.push_back(temp);
1492                         }
1493                 }
1494                 in.close();
1495                 
1496                 return error;
1497                 
1498         }
1499         catch(exception& e) {
1500                 errorOut(e, "MothurOut", "readNames");
1501                 exit(1);
1502         }
1503 }
1504
1505 /***********************************************************************/
1506
1507 int MothurOut::getNumNames(string names){
1508         try {
1509                 int count = 0;
1510                 
1511                 if(names != ""){
1512                         count = 1;
1513                         for(int i=0;i<names.size();i++){
1514                                 if(names[i] == ','){
1515                                         count++;
1516                                 }
1517                         }
1518                 }
1519                 
1520                 return count;
1521         }
1522         catch(exception& e) {
1523                 errorOut(e, "MothurOut", "getNumNames");
1524                 exit(1);
1525         }
1526 }
1527 /***********************************************************************/
1528
1529 int MothurOut::getNumChar(string line, char c){
1530         try {
1531                 int count = 0;
1532                 
1533                 if(line != ""){
1534                         for(int i=0;i<line.size();i++){
1535                                 if(line[i] == c){
1536                                         count++;
1537                                 }
1538                         }
1539                 }
1540                 
1541                 return count;
1542         }
1543         catch(exception& e) {
1544                 errorOut(e, "MothurOut", "getNumChar");
1545                 exit(1);
1546         }
1547 }
1548 /***********************************************************************/
1549 int MothurOut::mothurRemove(string filename){
1550         try {
1551                 filename = getFullPathName(filename);
1552                 int error = remove(filename.c_str());
1553                 //if (error != 0) { 
1554                 //      if (errno != ENOENT) { //ENOENT == file does not exist
1555                 //              string message = "Error deleting file " + filename;
1556                 //              perror(message.c_str()); 
1557                 //      }
1558                 //}
1559                 return error;
1560         }
1561         catch(exception& e) {
1562                 errorOut(e, "MothurOut", "mothurRemove");
1563                 exit(1);
1564         }
1565 }
1566 /***********************************************************************/
1567 bool MothurOut::mothurConvert(string item, int& num){
1568         try {
1569                 bool error = false;
1570                 
1571                 if (isNumeric1(item)) {
1572                         convert(item, num);
1573                 }else {
1574                         num = 0;
1575                         error = true;
1576                         mothurOut("[ERROR]: cannot convert " + item + " to an integer."); mothurOutEndLine();
1577                         commandInputsConvertError = true;
1578                 }
1579                 
1580                 return error;
1581         }
1582         catch(exception& e) {
1583                 errorOut(e, "MothurOut", "mothurConvert");
1584                 exit(1);
1585         }
1586 }
1587 /***********************************************************************/
1588 bool MothurOut::isNumeric1(string stringToCheck){
1589         try {
1590                 bool numeric = false;
1591                 
1592                 if(stringToCheck.find_first_not_of("0123456789.-") == string::npos) { numeric = true; }
1593                         
1594                 return numeric;
1595         }
1596         catch(exception& e) {
1597                 errorOut(e, "MothurOut", "isNumeric1");
1598                 exit(1);
1599         }
1600         
1601 }
1602 /***********************************************************************/
1603 bool MothurOut::mothurConvert(string item, float& num){
1604         try {
1605                 bool error = false;
1606                 
1607                 if (isNumeric1(item)) {
1608                         convert(item, num);
1609                 }else {
1610                         num = 0;
1611                         error = true;
1612                         mothurOut("[ERROR]: cannot convert " + item + " to a float."); mothurOutEndLine();
1613                         commandInputsConvertError = true;
1614                 }
1615                 
1616                 return error;
1617         }
1618         catch(exception& e) {
1619                 errorOut(e, "MothurOut", "mothurConvert");
1620                 exit(1);
1621         }
1622 }
1623 /***********************************************************************/
1624 bool MothurOut::mothurConvert(string item, double& num){
1625         try {
1626                 bool error = false;
1627                 
1628                 if (isNumeric1(item)) {
1629                         convert(item, num);
1630                 }else {
1631                         num = 0;
1632                         error = true;
1633                         mothurOut("[ERROR]: cannot convert " + item + " to a double."); mothurOutEndLine();
1634                         commandInputsConvertError = true;
1635                 }
1636                 
1637                 return error;
1638         }
1639         catch(exception& e) {
1640                 errorOut(e, "MothurOut", "mothurConvert");
1641                 exit(1);
1642         }
1643 }
1644 /**************************************************************************************************/
1645
1646 vector<vector<double> > MothurOut::binomial(int maxOrder){
1647         try {
1648         vector<vector<double> > binomial(maxOrder+1);
1649         
1650     for(int i=0;i<=maxOrder;i++){
1651                 binomial[i].resize(maxOrder+1);
1652                 binomial[i][0]=1;
1653                 binomial[0][i]=0;
1654     }
1655     binomial[0][0]=1;
1656         
1657     binomial[1][0]=1;
1658     binomial[1][1]=1;
1659         
1660     for(int i=2;i<=maxOrder;i++){
1661                 binomial[1][i]=0;
1662     }
1663         
1664     for(int i=2;i<=maxOrder;i++){
1665                 for(int j=1;j<=maxOrder;j++){
1666                         if(i==j){       binomial[i][j]=1;                                                                       }
1667                         if(j>i) {       binomial[i][j]=0;                                                                       }
1668                         else    {       binomial[i][j]=binomial[i-1][j-1]+binomial[i-1][j];     }
1669                 }
1670     }
1671         
1672         return binomial;
1673         
1674         }
1675         catch(exception& e) {
1676                 errorOut(e, "MothurOut", "binomial");
1677                 exit(1);
1678         }
1679 }
1680 /**************************************************************************************************/
1681 unsigned int MothurOut::fromBase36(string base36){
1682         try {
1683                 unsigned int num = 0;
1684                 
1685                 map<char, int> converts;
1686                 converts['A'] = 0;
1687                 converts['a'] = 0;
1688                 converts['B'] = 1;
1689                 converts['b'] = 1;
1690                 converts['C'] = 2;
1691                 converts['c'] = 2;
1692                 converts['D'] = 3;
1693                 converts['d'] = 3;
1694                 converts['E'] = 4;
1695                 converts['e'] = 4;
1696                 converts['F'] = 5;
1697                 converts['f'] = 5;
1698                 converts['G'] = 6;
1699                 converts['g'] = 6;
1700                 converts['H'] = 7;
1701                 converts['h'] = 7;
1702                 converts['I'] = 8;
1703                 converts['i'] = 8;
1704                 converts['J'] = 9;
1705                 converts['j'] = 9;
1706                 converts['K'] = 10;
1707                 converts['k'] = 10;
1708                 converts['L'] = 11;
1709                 converts['l'] = 11;
1710                 converts['M'] = 12;
1711                 converts['m'] = 12;
1712                 converts['N'] = 13;
1713                 converts['n'] = 13;
1714                 converts['O'] = 14;
1715                 converts['o'] = 14;
1716                 converts['P'] = 15;
1717                 converts['p'] = 15;
1718                 converts['Q'] = 16;
1719                 converts['q'] = 16;
1720                 converts['R'] = 17;
1721                 converts['r'] = 17;
1722                 converts['S'] = 18;
1723                 converts['s'] = 18;
1724                 converts['T'] = 19;
1725                 converts['t'] = 19;
1726                 converts['U'] = 20;
1727                 converts['u'] = 20;
1728                 converts['V'] = 21;
1729                 converts['v'] = 21;
1730                 converts['W'] = 22;
1731                 converts['w'] = 22;
1732                 converts['X'] = 23;
1733                 converts['x'] = 23;
1734                 converts['Y'] = 24;
1735                 converts['y'] = 24;
1736                 converts['Z'] = 25;
1737                 converts['z'] = 25;
1738                 converts['0'] = 26;
1739                 converts['1'] = 27;
1740                 converts['2'] = 28;
1741                 converts['3'] = 29;
1742                 converts['4'] = 30;
1743                 converts['5'] = 31;
1744                 converts['6'] = 32;
1745                 converts['7'] = 33;
1746                 converts['8'] = 34;
1747                 converts['9'] = 35;             
1748                 
1749                 int i = 0;
1750                 while (i < base36.length()) {
1751                         char c = base36[i];
1752                         num = 36 * num + converts[c];
1753                         i++;
1754                 }
1755                 
1756                 return num;
1757                 
1758         }
1759         catch(exception& e) {
1760                 errorOut(e, "MothurOut", "fromBase36");
1761                 exit(1);
1762         }
1763 }
1764 /***********************************************************************/
1765
1766 int MothurOut::factorial(int num){
1767         try {
1768                 int total = 1;
1769                 
1770                 for (int i = 1; i <= num; i++) {
1771                         total *= i;
1772                 }
1773                 
1774                 return total;
1775         }
1776         catch(exception& e) {
1777                 errorOut(e, "MothurOut", "factorial");
1778                 exit(1);
1779         }
1780 }
1781 /***********************************************************************/
1782
1783 int MothurOut::getNumSeqs(ifstream& file){
1784         try {
1785                 int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
1786                 file.seekg(0);
1787                 return numSeqs;
1788         }
1789         catch(exception& e) {
1790                 errorOut(e, "MothurOut", "getNumSeqs");
1791                 exit(1);
1792         }       
1793 }
1794 /***********************************************************************/
1795 void MothurOut::getNumSeqs(ifstream& file, int& numSeqs){
1796         try {
1797                 string input;
1798                 numSeqs = 0;
1799                 while(!file.eof()){
1800                         input = getline(file);
1801                         if (input.length() != 0) {
1802                                 if(input[0] == '>'){ numSeqs++; }
1803                         }
1804                 }
1805         }
1806         catch(exception& e) {
1807                 errorOut(e, "MothurOut", "getNumSeqs");
1808                 exit(1);
1809         }       
1810 }
1811 /***********************************************************************/
1812
1813 //This function parses the estimator options and puts them in a vector
1814 void MothurOut::splitAtChar(string& estim, vector<string>& container, char symbol) {
1815         try {
1816                 string individual = "";
1817                 int estimLength = estim.size();
1818                 for(int i=0;i<estimLength;i++){
1819                         if(estim[i] == symbol){
1820                                 container.push_back(individual);
1821                                 individual = "";                                
1822                         }
1823                         else{
1824                                 individual += estim[i];
1825                         }
1826                 }
1827                 container.push_back(individual);
1828
1829         }
1830         catch(exception& e) {
1831                 errorOut(e, "MothurOut", "splitAtChar");
1832                 exit(1);
1833         }       
1834 }
1835
1836 /***********************************************************************/
1837
1838 //This function parses the estimator options and puts them in a vector
1839 void MothurOut::splitAtDash(string& estim, vector<string>& container) {
1840         try {
1841                 string individual = "";
1842                 int estimLength = estim.size();
1843                 for(int i=0;i<estimLength;i++){
1844                         if(estim[i] == '-'){
1845                                 container.push_back(individual);
1846                                 individual = "";                                
1847                         }
1848                         else{
1849                                 individual += estim[i];
1850                         }
1851                 }
1852                 container.push_back(individual);
1853
1854         
1855         /*      string individual;
1856                 
1857                 while (estim.find_first_of('-') != -1) {
1858                         individual = estim.substr(0,estim.find_first_of('-'));
1859                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
1860                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
1861                                 container.push_back(individual);
1862                         }
1863                 }
1864                 //get last one
1865                 container.push_back(estim); */
1866         }
1867         catch(exception& e) {
1868                 errorOut(e, "MothurOut", "splitAtDash");
1869                 exit(1);
1870         }       
1871 }
1872
1873 /***********************************************************************/
1874 //This function parses the label options and puts them in a set
1875 void MothurOut::splitAtDash(string& estim, set<string>& container) {
1876         try {
1877                 string individual = "";
1878                 int estimLength = estim.size();
1879                 for(int i=0;i<estimLength;i++){
1880                         if(estim[i] == '-'){
1881                                 container.insert(individual);
1882                                 individual = "";                                
1883                         }
1884                         else{
1885                                 individual += estim[i];
1886                         }
1887                 }
1888                 container.insert(individual);
1889
1890         //      string individual;
1891                 
1892         //      while (estim.find_first_of('-') != -1) {
1893         //              individual = estim.substr(0,estim.find_first_of('-'));
1894         //              if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
1895         //                      estim = estim.substr(estim.find_first_of('-')+1, estim.length());
1896         //                      container.insert(individual);
1897         //              }
1898         //      }
1899                 //get last one
1900         //      container.insert(estim);
1901         
1902         }
1903         catch(exception& e) {
1904                 errorOut(e, "MothurOut", "splitAtDash");
1905                 exit(1);
1906         }       
1907 }
1908 /***********************************************************************/
1909 //This function parses the line options and puts them in a set
1910 void MothurOut::splitAtDash(string& estim, set<int>& container) {
1911         try {
1912                 string individual;
1913                 int lineNum;
1914                 
1915                 while (estim.find_first_of('-') != -1) {
1916                         individual = estim.substr(0,estim.find_first_of('-'));
1917                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
1918                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
1919                                 convert(individual, lineNum); //convert the string to int
1920                                 container.insert(lineNum);
1921                         }
1922                 }
1923                 //get last one
1924                 convert(estim, lineNum); //convert the string to int
1925                 container.insert(lineNum);
1926         }
1927         catch(exception& e) {
1928                 errorOut(e, "MothurOut", "splitAtDash");
1929                 exit(1);
1930         }       
1931 }
1932 /***********************************************************************/
1933 //This function parses the a string and puts peices in a vector
1934 void MothurOut::splitAtComma(string& estim, vector<string>& container) {
1935         try {
1936                 string individual = "";
1937                 int estimLength = estim.size();
1938                 for(int i=0;i<estimLength;i++){
1939                         if(estim[i] == ','){
1940                                 container.push_back(individual);
1941                                 individual = "";                                
1942                         }
1943                         else{
1944                                 individual += estim[i];
1945                         }
1946                 }
1947                 container.push_back(individual);
1948                 
1949                 
1950                 
1951                 
1952 //              string individual;
1953 //              
1954 //              while (estim.find_first_of(',') != -1) {
1955 //                      individual = estim.substr(0,estim.find_first_of(','));
1956 //                      if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
1957 //                              estim = estim.substr(estim.find_first_of(',')+1, estim.length());
1958 //                              container.push_back(individual);
1959 //                      }
1960 //              }
1961 //              //get last one
1962 //              container.push_back(estim);
1963         }
1964         catch(exception& e) {
1965                 errorOut(e, "MothurOut", "splitAtComma");
1966                 exit(1);
1967         }       
1968 }
1969 /***********************************************************************/
1970 //This function splits up the various option parameters
1971 void MothurOut::splitAtChar(string& prefix, string& suffix, char c){
1972         try {
1973                 prefix = suffix.substr(0,suffix.find_first_of(c));
1974                 if ((suffix.find_first_of(c)+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
1975                         suffix = suffix.substr(suffix.find_first_of(c)+1, suffix.length());
1976                         string space = " ";
1977                         while(suffix.at(0) == ' ')
1978                                 suffix = suffix.substr(1, suffix.length());
1979                 }
1980         
1981         }
1982         catch(exception& e) {
1983                 errorOut(e, "MothurOut", "splitAtComma");
1984                 exit(1);
1985         }       
1986 }
1987
1988 /***********************************************************************/
1989
1990 //This function splits up the various option parameters
1991 void MothurOut::splitAtComma(string& prefix, string& suffix){
1992         try {
1993                 prefix = suffix.substr(0,suffix.find_first_of(','));
1994                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
1995                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
1996                         string space = " ";
1997                         while(suffix.at(0) == ' ')
1998                                 suffix = suffix.substr(1, suffix.length());
1999                 }
2000
2001         }
2002         catch(exception& e) {
2003                 errorOut(e, "MothurOut", "splitAtComma");
2004                 exit(1);
2005         }       
2006 }
2007 /***********************************************************************/
2008
2009 //This function separates the key value from the option value i.e. dist=96_...
2010 void MothurOut::splitAtEquals(string& key, string& value){              
2011         try {
2012                 if(value.find_first_of('=') != -1){
2013                         key = value.substr(0,value.find_first_of('='));
2014                         if ((value.find_first_of('=')+1) <= value.length()) {
2015                                 value = value.substr(value.find_first_of('=')+1, value.length());
2016                         }
2017                 }else{
2018                         key = value;
2019                         value = 1;
2020                 }
2021         }
2022         catch(exception& e) {
2023                 errorOut(e, "MothurOut", "splitAtEquals");
2024                 exit(1);
2025         }       
2026 }
2027
2028 /**************************************************************************************************/
2029
2030 bool MothurOut::inUsersGroups(string groupname, vector<string> Groups) {
2031         try {
2032                 for (int i = 0; i < Groups.size(); i++) {
2033                         if (groupname == Groups[i]) { return true; }
2034                 }
2035                 return false;
2036         }
2037         catch(exception& e) {
2038                 errorOut(e, "MothurOut", "inUsersGroups");
2039                 exit(1);
2040         }       
2041 }
2042 /**************************************************************************************************/
2043 //returns true if any of the strings in first vector are in second vector
2044 bool MothurOut::inUsersGroups(vector<string> groupnames, vector<string> Groups) {
2045         try {
2046                 
2047                 for (int i = 0; i < groupnames.size(); i++) {
2048                         if (inUsersGroups(groupnames[i], Groups)) { return true; }
2049                 }
2050                 return false;
2051         }
2052         catch(exception& e) {
2053                 errorOut(e, "MothurOut", "inUsersGroups");
2054                 exit(1);
2055         }       
2056 }
2057 /***********************************************************************/
2058 //this function determines if the user has given us labels that are smaller than the given label.
2059 //if so then it returns true so that the calling function can run the previous valid distance.
2060 //it's a "smart" distance function.  It also checks for invalid labels.
2061 bool MothurOut::anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
2062         try {
2063                 
2064                 set<string>::iterator it;
2065                 vector<float> orderFloat;
2066                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
2067                 map<string, float>::iterator it2;
2068                 float labelFloat;
2069                 bool smaller = false;
2070                 
2071                 //unique is the smallest line
2072                 if (label == "unique") {  return false;  }
2073                 else { 
2074                         if (convertTestFloat(label, labelFloat)) {
2075                                 convert(label, labelFloat); 
2076                         }else { //cant convert 
2077                                 return false;
2078                         }
2079                 }
2080                 
2081                 //go through users set and make them floats
2082                 for(it = userLabels.begin(); it != userLabels.end();) {
2083                         
2084                         float temp;
2085                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
2086                                 convert(*it, temp);
2087                                 orderFloat.push_back(temp);
2088                                 userMap[*it] = temp;
2089                                 it++;
2090                         }else if (*it == "unique") { 
2091                                 orderFloat.push_back(-1.0);
2092                                 userMap["unique"] = -1.0;
2093                                 it++;
2094                         }else {
2095                                 if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
2096                                 userLabels.erase(it++); 
2097                         }
2098                 }
2099                 
2100                 //sort order
2101                 sort(orderFloat.begin(), orderFloat.end());
2102                 
2103                 /*************************************************/
2104                 //is this label bigger than any of the users labels
2105                 /*************************************************/
2106                                 
2107                 //loop through order until you find a label greater than label
2108                 for (int i = 0; i < orderFloat.size(); i++) {
2109                         if (orderFloat[i] < labelFloat) {
2110                                 smaller = true;
2111                                 if (orderFloat[i] == -1) { 
2112                                         if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
2113                                         userLabels.erase("unique");
2114                                 }
2115                                 else {  
2116                                         if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
2117                                         string s = "";
2118                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
2119                                                 if (it2->second == orderFloat[i]) {  
2120                                                         s = it2->first;  
2121                                                         //remove small labels
2122                                                         userLabels.erase(s);
2123                                                         break;
2124                                                 }
2125                                         }
2126                                         if (errorOff == "") {mothurOut( s +  ". I will use the next smallest distance. "); mothurOutEndLine(); }
2127                                 }
2128                         //since they are sorted once you find a bigger one stop looking
2129                         }else { break; }
2130                 }
2131                 
2132                 return smaller;
2133                                                 
2134         }
2135         catch(exception& e) {
2136                 errorOut(e, "MothurOut", "anyLabelsToProcess");
2137                 exit(1);
2138         }       
2139 }
2140
2141 /**************************************************************************************************/
2142 bool MothurOut::checkReleaseVersion(ifstream& file, string version) {
2143         try {
2144                 
2145                 bool good = true;
2146                 
2147                 string line = getline(file);  
2148
2149                 //before we added this check
2150                 if (line[0] != '#') {  good = false;  }
2151                 else {
2152                         //rip off #
2153                         line = line.substr(1);
2154                         
2155                         vector<string> versionVector;
2156                         splitAtChar(version, versionVector, '.');
2157                         
2158                         //check file version
2159                         vector<string> linesVector;
2160                         splitAtChar(line, linesVector, '.');
2161                         
2162                         if (versionVector.size() != linesVector.size()) { good = false; }
2163                         else {
2164                                 for (int j = 0; j < versionVector.size(); j++) {
2165                                         int num1, num2;
2166                                         convert(versionVector[j], num1);
2167                                         convert(linesVector[j], num2);
2168                                         
2169                                         //if mothurs version is newer than this files version, then we want to remake it
2170                                         if (num1 > num2) {  good = false; break;  }
2171                                 }
2172                         }
2173                         
2174                 }
2175                 
2176                 if (!good) {  file.close();  }
2177                 else { file.seekg(0);  }
2178                 
2179                 return good;
2180         }
2181         catch(exception& e) {
2182                 errorOut(e, "MothurOut", "checkReleaseVersion");                
2183                 exit(1);
2184         }
2185 }
2186 /**************************************************************************************************/
2187 bool MothurOut::isContainingOnlyDigits(string input) {
2188         try{
2189                 
2190                 //are you a digit in ascii code
2191                 for (int i = 0;i < input.length(); i++){
2192                         if( input[i]>47 && input[i]<58){}
2193                         else { return false; }
2194                 }
2195                 
2196                 return true;
2197         }
2198         catch(exception& e) {
2199                 errorOut(e, "MothurOut", "isContainingOnlyDigits");             
2200                 exit(1);
2201         }
2202 }
2203 /**************************************************************************************************/
2204 int MothurOut::removeConfidences(string& tax) {
2205         try {
2206                 
2207                 string taxon;
2208                 string newTax = "";
2209                 
2210                 while (tax.find_first_of(';') != -1) {
2211                         
2212                         if (control_pressed) { return 0; }
2213                         
2214                         //get taxon
2215                         taxon = tax.substr(0,tax.find_first_of(';'));
2216         
2217                         int pos = taxon.find_last_of('(');
2218                         if (pos != -1) {
2219                                 //is it a number?
2220                                 int pos2 = taxon.find_last_of(')');
2221                                 if (pos2 != -1) {
2222                                         string confidenceScore = taxon.substr(pos+1, (pos2-(pos+1)));
2223                                         if (isNumeric1(confidenceScore)) {
2224                                                 taxon = taxon.substr(0, pos); //rip off confidence 
2225                                         }
2226                                 }
2227                         }
2228                         taxon += ";";
2229                         
2230                         tax = tax.substr(tax.find_first_of(';')+1, tax.length());
2231                         newTax += taxon;
2232                 }
2233                 
2234                 tax = newTax;
2235                 
2236                 return 0;
2237         }
2238         catch(exception& e) {
2239                 errorOut(e, "MothurOut", "removeConfidences");
2240                 exit(1);
2241         }
2242 }
2243 /**************************************************************************************************/
2244
2245
2246
2247
2248