]> git.donarmstrong.com Git - mothur.git/blob - mothurout.cpp
added uchime_src folder. added biom parameter to make.shared. added biom as a current...
[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 >> secondCol; gobble(in);
1452                         
1453                         int num = getNumNames(secondCol);
1454                         
1455                         nameMap[firstCol] = num;
1456                 }
1457                 in.close();
1458                 
1459                 return nameMap;
1460                 
1461         }
1462         catch(exception& e) {
1463                 errorOut(e, "MothurOut", "readNames");
1464                 exit(1);
1465         }
1466 }
1467 /**********************************************************************************************************************/
1468 int MothurOut::readNames(string namefile, vector<seqPriorityNode>& nameVector, map<string, string>& fastamap) { 
1469         try {
1470                 int error = 0;
1471                 
1472                 //open input file
1473                 ifstream in;
1474                 openInputFile(namefile, in);
1475                 
1476                 while (!in.eof()) {
1477                         if (control_pressed) { break; }
1478                         
1479                         string firstCol, secondCol;
1480                         in >> firstCol >> secondCol; gobble(in);
1481                         
1482                         int num = getNumNames(secondCol);
1483                         
1484                         map<string, string>::iterator it = fastamap.find(firstCol);
1485                         if (it == fastamap.end()) {
1486                                 error = 1;
1487                                 mothurOut("[ERROR]: " + firstCol + " is not in your fastafile, but is in your namesfile, please correct."); mothurOutEndLine();
1488                         }else {
1489                                 seqPriorityNode temp(num, it->second, firstCol);
1490                                 nameVector.push_back(temp);
1491                         }
1492                 }
1493                 in.close();
1494                 
1495                 return error;
1496                 
1497         }
1498         catch(exception& e) {
1499                 errorOut(e, "MothurOut", "readNames");
1500                 exit(1);
1501         }
1502 }
1503
1504 /***********************************************************************/
1505
1506 int MothurOut::getNumNames(string names){
1507         try {
1508                 int count = 0;
1509                 
1510                 if(names != ""){
1511                         count = 1;
1512                         for(int i=0;i<names.size();i++){
1513                                 if(names[i] == ','){
1514                                         count++;
1515                                 }
1516                         }
1517                 }
1518                 
1519                 return count;
1520         }
1521         catch(exception& e) {
1522                 errorOut(e, "MothurOut", "getNumNames");
1523                 exit(1);
1524         }
1525 }
1526 /***********************************************************************/
1527
1528 int MothurOut::getNumChar(string line, char c){
1529         try {
1530                 int count = 0;
1531                 
1532                 if(line != ""){
1533                         for(int i=0;i<line.size();i++){
1534                                 if(line[i] == c){
1535                                         count++;
1536                                 }
1537                         }
1538                 }
1539                 
1540                 return count;
1541         }
1542         catch(exception& e) {
1543                 errorOut(e, "MothurOut", "getNumChar");
1544                 exit(1);
1545         }
1546 }
1547 /***********************************************************************/
1548 int MothurOut::mothurRemove(string filename){
1549         try {
1550                 filename = getFullPathName(filename);
1551                 int error = remove(filename.c_str());
1552                 //if (error != 0) { 
1553                 //      if (errno != ENOENT) { //ENOENT == file does not exist
1554                 //              string message = "Error deleting file " + filename;
1555                 //              perror(message.c_str()); 
1556                 //      }
1557                 //}
1558                 return error;
1559         }
1560         catch(exception& e) {
1561                 errorOut(e, "MothurOut", "mothurRemove");
1562                 exit(1);
1563         }
1564 }
1565 /***********************************************************************/
1566 bool MothurOut::mothurConvert(string item, int& num){
1567         try {
1568                 bool error = false;
1569                 
1570                 if (isNumeric1(item)) {
1571                         convert(item, num);
1572                 }else {
1573                         num = 0;
1574                         error = true;
1575                         mothurOut("[ERROR]: cannot convert " + item + " to an integer."); mothurOutEndLine();
1576                         commandInputsConvertError = true;
1577                 }
1578                 
1579                 return error;
1580         }
1581         catch(exception& e) {
1582                 errorOut(e, "MothurOut", "mothurConvert");
1583                 exit(1);
1584         }
1585 }
1586 /***********************************************************************/
1587 bool MothurOut::isNumeric1(string stringToCheck){
1588         try {
1589                 bool numeric = false;
1590                 
1591                 if(stringToCheck.find_first_not_of("0123456789.-") == string::npos) { numeric = true; }
1592                         
1593                 return numeric;
1594         }
1595         catch(exception& e) {
1596                 errorOut(e, "MothurOut", "isNumeric1");
1597                 exit(1);
1598         }
1599         
1600 }
1601 /***********************************************************************/
1602 bool MothurOut::mothurConvert(string item, float& num){
1603         try {
1604                 bool error = false;
1605                 
1606                 if (isNumeric1(item)) {
1607                         convert(item, num);
1608                 }else {
1609                         num = 0;
1610                         error = true;
1611                         mothurOut("[ERROR]: cannot convert " + item + " to a float."); mothurOutEndLine();
1612                         commandInputsConvertError = true;
1613                 }
1614                 
1615                 return error;
1616         }
1617         catch(exception& e) {
1618                 errorOut(e, "MothurOut", "mothurConvert");
1619                 exit(1);
1620         }
1621 }
1622 /***********************************************************************/
1623 bool MothurOut::mothurConvert(string item, double& num){
1624         try {
1625                 bool error = false;
1626                 
1627                 if (isNumeric1(item)) {
1628                         convert(item, num);
1629                 }else {
1630                         num = 0;
1631                         error = true;
1632                         mothurOut("[ERROR]: cannot convert " + item + " to a double."); mothurOutEndLine();
1633                         commandInputsConvertError = true;
1634                 }
1635                 
1636                 return error;
1637         }
1638         catch(exception& e) {
1639                 errorOut(e, "MothurOut", "mothurConvert");
1640                 exit(1);
1641         }
1642 }
1643 /**************************************************************************************************/
1644
1645 vector<vector<double> > MothurOut::binomial(int maxOrder){
1646         try {
1647         vector<vector<double> > binomial(maxOrder+1);
1648         
1649     for(int i=0;i<=maxOrder;i++){
1650                 binomial[i].resize(maxOrder+1);
1651                 binomial[i][0]=1;
1652                 binomial[0][i]=0;
1653     }
1654     binomial[0][0]=1;
1655         
1656     binomial[1][0]=1;
1657     binomial[1][1]=1;
1658         
1659     for(int i=2;i<=maxOrder;i++){
1660                 binomial[1][i]=0;
1661     }
1662         
1663     for(int i=2;i<=maxOrder;i++){
1664                 for(int j=1;j<=maxOrder;j++){
1665                         if(i==j){       binomial[i][j]=1;                                                                       }
1666                         if(j>i) {       binomial[i][j]=0;                                                                       }
1667                         else    {       binomial[i][j]=binomial[i-1][j-1]+binomial[i-1][j];     }
1668                 }
1669     }
1670         
1671         return binomial;
1672         
1673         }
1674         catch(exception& e) {
1675                 errorOut(e, "MothurOut", "binomial");
1676                 exit(1);
1677         }
1678 }
1679 /**************************************************************************************************/
1680 unsigned int MothurOut::fromBase36(string base36){
1681         try {
1682                 unsigned int num = 0;
1683                 
1684                 map<char, int> converts;
1685                 converts['A'] = 0;
1686                 converts['a'] = 0;
1687                 converts['B'] = 1;
1688                 converts['b'] = 1;
1689                 converts['C'] = 2;
1690                 converts['c'] = 2;
1691                 converts['D'] = 3;
1692                 converts['d'] = 3;
1693                 converts['E'] = 4;
1694                 converts['e'] = 4;
1695                 converts['F'] = 5;
1696                 converts['f'] = 5;
1697                 converts['G'] = 6;
1698                 converts['g'] = 6;
1699                 converts['H'] = 7;
1700                 converts['h'] = 7;
1701                 converts['I'] = 8;
1702                 converts['i'] = 8;
1703                 converts['J'] = 9;
1704                 converts['j'] = 9;
1705                 converts['K'] = 10;
1706                 converts['k'] = 10;
1707                 converts['L'] = 11;
1708                 converts['l'] = 11;
1709                 converts['M'] = 12;
1710                 converts['m'] = 12;
1711                 converts['N'] = 13;
1712                 converts['n'] = 13;
1713                 converts['O'] = 14;
1714                 converts['o'] = 14;
1715                 converts['P'] = 15;
1716                 converts['p'] = 15;
1717                 converts['Q'] = 16;
1718                 converts['q'] = 16;
1719                 converts['R'] = 17;
1720                 converts['r'] = 17;
1721                 converts['S'] = 18;
1722                 converts['s'] = 18;
1723                 converts['T'] = 19;
1724                 converts['t'] = 19;
1725                 converts['U'] = 20;
1726                 converts['u'] = 20;
1727                 converts['V'] = 21;
1728                 converts['v'] = 21;
1729                 converts['W'] = 22;
1730                 converts['w'] = 22;
1731                 converts['X'] = 23;
1732                 converts['x'] = 23;
1733                 converts['Y'] = 24;
1734                 converts['y'] = 24;
1735                 converts['Z'] = 25;
1736                 converts['z'] = 25;
1737                 converts['0'] = 26;
1738                 converts['1'] = 27;
1739                 converts['2'] = 28;
1740                 converts['3'] = 29;
1741                 converts['4'] = 30;
1742                 converts['5'] = 31;
1743                 converts['6'] = 32;
1744                 converts['7'] = 33;
1745                 converts['8'] = 34;
1746                 converts['9'] = 35;             
1747                 
1748                 int i = 0;
1749                 while (i < base36.length()) {
1750                         char c = base36[i];
1751                         num = 36 * num + converts[c];
1752                         i++;
1753                 }
1754                 
1755                 return num;
1756                 
1757         }
1758         catch(exception& e) {
1759                 errorOut(e, "MothurOut", "fromBase36");
1760                 exit(1);
1761         }
1762 }
1763 /***********************************************************************/
1764
1765 int MothurOut::factorial(int num){
1766         try {
1767                 int total = 1;
1768                 
1769                 for (int i = 1; i <= num; i++) {
1770                         total *= i;
1771                 }
1772                 
1773                 return total;
1774         }
1775         catch(exception& e) {
1776                 errorOut(e, "MothurOut", "factorial");
1777                 exit(1);
1778         }
1779 }
1780 /***********************************************************************/
1781
1782 int MothurOut::getNumSeqs(ifstream& file){
1783         try {
1784                 int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
1785                 file.seekg(0);
1786                 return numSeqs;
1787         }
1788         catch(exception& e) {
1789                 errorOut(e, "MothurOut", "getNumSeqs");
1790                 exit(1);
1791         }       
1792 }
1793 /***********************************************************************/
1794 void MothurOut::getNumSeqs(ifstream& file, int& numSeqs){
1795         try {
1796                 string input;
1797                 numSeqs = 0;
1798                 while(!file.eof()){
1799                         input = getline(file);
1800                         if (input.length() != 0) {
1801                                 if(input[0] == '>'){ numSeqs++; }
1802                         }
1803                 }
1804         }
1805         catch(exception& e) {
1806                 errorOut(e, "MothurOut", "getNumSeqs");
1807                 exit(1);
1808         }       
1809 }
1810 /***********************************************************************/
1811
1812 //This function parses the estimator options and puts them in a vector
1813 void MothurOut::splitAtChar(string& estim, vector<string>& container, char symbol) {
1814         try {
1815                 string individual = "";
1816                 int estimLength = estim.size();
1817                 for(int i=0;i<estimLength;i++){
1818                         if(estim[i] == symbol){
1819                                 container.push_back(individual);
1820                                 individual = "";                                
1821                         }
1822                         else{
1823                                 individual += estim[i];
1824                         }
1825                 }
1826                 container.push_back(individual);
1827
1828         }
1829         catch(exception& e) {
1830                 errorOut(e, "MothurOut", "splitAtChar");
1831                 exit(1);
1832         }       
1833 }
1834
1835 /***********************************************************************/
1836
1837 //This function parses the estimator options and puts them in a vector
1838 void MothurOut::splitAtDash(string& estim, vector<string>& container) {
1839         try {
1840                 string individual = "";
1841                 int estimLength = estim.size();
1842                 for(int i=0;i<estimLength;i++){
1843                         if(estim[i] == '-'){
1844                                 container.push_back(individual);
1845                                 individual = "";                                
1846                         }
1847                         else{
1848                                 individual += estim[i];
1849                         }
1850                 }
1851                 container.push_back(individual);
1852
1853         
1854         /*      string individual;
1855                 
1856                 while (estim.find_first_of('-') != -1) {
1857                         individual = estim.substr(0,estim.find_first_of('-'));
1858                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
1859                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
1860                                 container.push_back(individual);
1861                         }
1862                 }
1863                 //get last one
1864                 container.push_back(estim); */
1865         }
1866         catch(exception& e) {
1867                 errorOut(e, "MothurOut", "splitAtDash");
1868                 exit(1);
1869         }       
1870 }
1871
1872 /***********************************************************************/
1873 //This function parses the label options and puts them in a set
1874 void MothurOut::splitAtDash(string& estim, set<string>& container) {
1875         try {
1876                 string individual = "";
1877                 int estimLength = estim.size();
1878                 for(int i=0;i<estimLength;i++){
1879                         if(estim[i] == '-'){
1880                                 container.insert(individual);
1881                                 individual = "";                                
1882                         }
1883                         else{
1884                                 individual += estim[i];
1885                         }
1886                 }
1887                 container.insert(individual);
1888
1889         //      string individual;
1890                 
1891         //      while (estim.find_first_of('-') != -1) {
1892         //              individual = estim.substr(0,estim.find_first_of('-'));
1893         //              if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
1894         //                      estim = estim.substr(estim.find_first_of('-')+1, estim.length());
1895         //                      container.insert(individual);
1896         //              }
1897         //      }
1898                 //get last one
1899         //      container.insert(estim);
1900         
1901         }
1902         catch(exception& e) {
1903                 errorOut(e, "MothurOut", "splitAtDash");
1904                 exit(1);
1905         }       
1906 }
1907 /***********************************************************************/
1908 //This function parses the line options and puts them in a set
1909 void MothurOut::splitAtDash(string& estim, set<int>& container) {
1910         try {
1911                 string individual;
1912                 int lineNum;
1913                 
1914                 while (estim.find_first_of('-') != -1) {
1915                         individual = estim.substr(0,estim.find_first_of('-'));
1916                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
1917                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
1918                                 convert(individual, lineNum); //convert the string to int
1919                                 container.insert(lineNum);
1920                         }
1921                 }
1922                 //get last one
1923                 convert(estim, lineNum); //convert the string to int
1924                 container.insert(lineNum);
1925         }
1926         catch(exception& e) {
1927                 errorOut(e, "MothurOut", "splitAtDash");
1928                 exit(1);
1929         }       
1930 }
1931 /***********************************************************************/
1932 //This function parses the a string and puts peices in a vector
1933 void MothurOut::splitAtComma(string& estim, vector<string>& container) {
1934         try {
1935                 string individual = "";
1936                 int estimLength = estim.size();
1937                 for(int i=0;i<estimLength;i++){
1938                         if(estim[i] == ','){
1939                                 container.push_back(individual);
1940                                 individual = "";                                
1941                         }
1942                         else{
1943                                 individual += estim[i];
1944                         }
1945                 }
1946                 container.push_back(individual);
1947                 
1948                 
1949                 
1950                 
1951 //              string individual;
1952 //              
1953 //              while (estim.find_first_of(',') != -1) {
1954 //                      individual = estim.substr(0,estim.find_first_of(','));
1955 //                      if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
1956 //                              estim = estim.substr(estim.find_first_of(',')+1, estim.length());
1957 //                              container.push_back(individual);
1958 //                      }
1959 //              }
1960 //              //get last one
1961 //              container.push_back(estim);
1962         }
1963         catch(exception& e) {
1964                 errorOut(e, "MothurOut", "splitAtComma");
1965                 exit(1);
1966         }       
1967 }
1968 /***********************************************************************/
1969 //This function splits up the various option parameters
1970 void MothurOut::splitAtChar(string& prefix, string& suffix, char c){
1971         try {
1972                 prefix = suffix.substr(0,suffix.find_first_of(c));
1973                 if ((suffix.find_first_of(c)+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
1974                         suffix = suffix.substr(suffix.find_first_of(c)+1, suffix.length());
1975                         string space = " ";
1976                         while(suffix.at(0) == ' ')
1977                                 suffix = suffix.substr(1, suffix.length());
1978                 }
1979         
1980         }
1981         catch(exception& e) {
1982                 errorOut(e, "MothurOut", "splitAtComma");
1983                 exit(1);
1984         }       
1985 }
1986
1987 /***********************************************************************/
1988
1989 //This function splits up the various option parameters
1990 void MothurOut::splitAtComma(string& prefix, string& suffix){
1991         try {
1992                 prefix = suffix.substr(0,suffix.find_first_of(','));
1993                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
1994                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
1995                         string space = " ";
1996                         while(suffix.at(0) == ' ')
1997                                 suffix = suffix.substr(1, suffix.length());
1998                 }
1999
2000         }
2001         catch(exception& e) {
2002                 errorOut(e, "MothurOut", "splitAtComma");
2003                 exit(1);
2004         }       
2005 }
2006 /***********************************************************************/
2007
2008 //This function separates the key value from the option value i.e. dist=96_...
2009 void MothurOut::splitAtEquals(string& key, string& value){              
2010         try {
2011                 if(value.find_first_of('=') != -1){
2012                         key = value.substr(0,value.find_first_of('='));
2013                         if ((value.find_first_of('=')+1) <= value.length()) {
2014                                 value = value.substr(value.find_first_of('=')+1, value.length());
2015                         }
2016                 }else{
2017                         key = value;
2018                         value = 1;
2019                 }
2020         }
2021         catch(exception& e) {
2022                 errorOut(e, "MothurOut", "splitAtEquals");
2023                 exit(1);
2024         }       
2025 }
2026
2027 /**************************************************************************************************/
2028
2029 bool MothurOut::inUsersGroups(string groupname, vector<string> Groups) {
2030         try {
2031                 for (int i = 0; i < Groups.size(); i++) {
2032                         if (groupname == Groups[i]) { return true; }
2033                 }
2034                 return false;
2035         }
2036         catch(exception& e) {
2037                 errorOut(e, "MothurOut", "inUsersGroups");
2038                 exit(1);
2039         }       
2040 }
2041 /**************************************************************************************************/
2042 //returns true if any of the strings in first vector are in second vector
2043 bool MothurOut::inUsersGroups(vector<string> groupnames, vector<string> Groups) {
2044         try {
2045                 
2046                 for (int i = 0; i < groupnames.size(); i++) {
2047                         if (inUsersGroups(groupnames[i], Groups)) { return true; }
2048                 }
2049                 return false;
2050         }
2051         catch(exception& e) {
2052                 errorOut(e, "MothurOut", "inUsersGroups");
2053                 exit(1);
2054         }       
2055 }
2056 /***********************************************************************/
2057 //this function determines if the user has given us labels that are smaller than the given label.
2058 //if so then it returns true so that the calling function can run the previous valid distance.
2059 //it's a "smart" distance function.  It also checks for invalid labels.
2060 bool MothurOut::anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
2061         try {
2062                 
2063                 set<string>::iterator it;
2064                 vector<float> orderFloat;
2065                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
2066                 map<string, float>::iterator it2;
2067                 float labelFloat;
2068                 bool smaller = false;
2069                 
2070                 //unique is the smallest line
2071                 if (label == "unique") {  return false;  }
2072                 else { 
2073                         if (convertTestFloat(label, labelFloat)) {
2074                                 convert(label, labelFloat); 
2075                         }else { //cant convert 
2076                                 return false;
2077                         }
2078                 }
2079                 
2080                 //go through users set and make them floats
2081                 for(it = userLabels.begin(); it != userLabels.end();) {
2082                         
2083                         float temp;
2084                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
2085                                 convert(*it, temp);
2086                                 orderFloat.push_back(temp);
2087                                 userMap[*it] = temp;
2088                                 it++;
2089                         }else if (*it == "unique") { 
2090                                 orderFloat.push_back(-1.0);
2091                                 userMap["unique"] = -1.0;
2092                                 it++;
2093                         }else {
2094                                 if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
2095                                 userLabels.erase(it++); 
2096                         }
2097                 }
2098                 
2099                 //sort order
2100                 sort(orderFloat.begin(), orderFloat.end());
2101                 
2102                 /*************************************************/
2103                 //is this label bigger than any of the users labels
2104                 /*************************************************/
2105                                 
2106                 //loop through order until you find a label greater than label
2107                 for (int i = 0; i < orderFloat.size(); i++) {
2108                         if (orderFloat[i] < labelFloat) {
2109                                 smaller = true;
2110                                 if (orderFloat[i] == -1) { 
2111                                         if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
2112                                         userLabels.erase("unique");
2113                                 }
2114                                 else {  
2115                                         if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
2116                                         string s = "";
2117                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
2118                                                 if (it2->second == orderFloat[i]) {  
2119                                                         s = it2->first;  
2120                                                         //remove small labels
2121                                                         userLabels.erase(s);
2122                                                         break;
2123                                                 }
2124                                         }
2125                                         if (errorOff == "") {mothurOut( s +  ". I will use the next smallest distance. "); mothurOutEndLine(); }
2126                                 }
2127                         //since they are sorted once you find a bigger one stop looking
2128                         }else { break; }
2129                 }
2130                 
2131                 return smaller;
2132                                                 
2133         }
2134         catch(exception& e) {
2135                 errorOut(e, "MothurOut", "anyLabelsToProcess");
2136                 exit(1);
2137         }       
2138 }
2139
2140 /**************************************************************************************************/
2141 bool MothurOut::checkReleaseVersion(ifstream& file, string version) {
2142         try {
2143                 
2144                 bool good = true;
2145                 
2146                 string line = getline(file);  
2147
2148                 //before we added this check
2149                 if (line[0] != '#') {  good = false;  }
2150                 else {
2151                         //rip off #
2152                         line = line.substr(1);
2153                         
2154                         vector<string> versionVector;
2155                         splitAtChar(version, versionVector, '.');
2156                         
2157                         //check file version
2158                         vector<string> linesVector;
2159                         splitAtChar(line, linesVector, '.');
2160                         
2161                         if (versionVector.size() != linesVector.size()) { good = false; }
2162                         else {
2163                                 for (int j = 0; j < versionVector.size(); j++) {
2164                                         int num1, num2;
2165                                         convert(versionVector[j], num1);
2166                                         convert(linesVector[j], num2);
2167                                         
2168                                         //if mothurs version is newer than this files version, then we want to remake it
2169                                         if (num1 > num2) {  good = false; break;  }
2170                                 }
2171                         }
2172                         
2173                 }
2174                 
2175                 if (!good) {  file.close();  }
2176                 else { file.seekg(0);  }
2177                 
2178                 return good;
2179         }
2180         catch(exception& e) {
2181                 errorOut(e, "MothurOut", "checkReleaseVersion");                
2182                 exit(1);
2183         }
2184 }
2185 /**************************************************************************************************/
2186 bool MothurOut::isContainingOnlyDigits(string input) {
2187         try{
2188                 
2189                 //are you a digit in ascii code
2190                 for (int i = 0;i < input.length(); i++){
2191                         if( input[i]>47 && input[i]<58){}
2192                         else { return false; }
2193                 }
2194                 
2195                 return true;
2196         }
2197         catch(exception& e) {
2198                 errorOut(e, "MothurOut", "isContainingOnlyDigits");             
2199                 exit(1);
2200         }
2201 }
2202 /**************************************************************************************************/
2203 int MothurOut::removeConfidences(string& tax) {
2204         try {
2205                 
2206                 string taxon;
2207                 string newTax = "";
2208                 
2209                 while (tax.find_first_of(';') != -1) {
2210                         
2211                         if (control_pressed) { return 0; }
2212                         
2213                         //get taxon
2214                         taxon = tax.substr(0,tax.find_first_of(';'));
2215         
2216                         int pos = taxon.find_last_of('(');
2217                         if (pos != -1) {
2218                                 //is it a number?
2219                                 int pos2 = taxon.find_last_of(')');
2220                                 if (pos2 != -1) {
2221                                         string confidenceScore = taxon.substr(pos+1, (pos2-(pos+1)));
2222                                         if (isNumeric1(confidenceScore)) {
2223                                                 taxon = taxon.substr(0, pos); //rip off confidence 
2224                                         }
2225                                 }
2226                         }
2227                         taxon += ";";
2228                         
2229                         tax = tax.substr(tax.find_first_of(';')+1, tax.length());
2230                         newTax += taxon;
2231                 }
2232                 
2233                 tax = newTax;
2234                 
2235                 return 0;
2236         }
2237         catch(exception& e) {
2238                 errorOut(e, "MothurOut", "removeConfidences");
2239                 exit(1);
2240         }
2241 }
2242 /**************************************************************************************************/
2243
2244
2245
2246
2247