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