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