]> git.donarmstrong.com Git - mothur.git/blob - mothurout.cpp
added checks to make sure windows processes completed their tasks.
[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     string errorType = toString(e.what());
444     
445     int pos = errorType.find("bad_alloc");
446     mothurOut("[ERROR]: ");
447     mothurOut(errorType);
448     
449     if (pos == string::npos) { //not bad_alloc
450         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.");
451         mothurOutEndLine();
452     }else { //bad alloc
453         if (object == "cluster"){
454             mothurOut(" has occurred in the " + object + " class function " + function + ". This error indicates your computer is running out of memory.  There are two common causes for this, file size and format.\n\nFile Size:\nThe cluster command loads your distance matrix into RAM, and your distance file is most likely too large to fit in RAM. There are two options to help with this. The first is to use a cutoff. By using a cutoff mothur will only load distances that are below the cutoff. If that is still not enough, there is a command called cluster.split, http://www.mothur.org/wiki/cluster.split which divides the distance matrix, and clusters the smaller pieces separately. You may also be able to reduce the size of the original distance matrix by using the commands outlined in the Schloss SOP, http://www.mothur.org/wiki/Schloss_SOP. \n\nWrong Format:\nThis error can be caused by trying to read a column formatted distance matrix using the phylip parameter. By default, the dist.seqs command generates a column formatted distance matrix. To make a phylip formatted matrix set the dist.seqs command parameter output to lt.  \n\nIf you are uable to resolve the issue, please contact Pat Schloss at mothur.bugs@gmail.com, and be sure to include the mothur.logFile with your inquiry.");
455         }else {
456             mothurOut(" has occurred in the " + object + " class function " + function + ". This error indicates your computer is running out of memory.  This is most commonly caused by trying to process a dataset too large, or a file format issue. If you are running our 32bit version, your memory usage is limited to 4G.  If you have more than 4G of RAM and are running a 64bit OS, using our 64bit version may resolve your issue.  Also, you may be able to reduce the size of your dataset by using the commands outlined in the Schloss SOP, http://www.mothur.org/wiki/Schloss_SOP. If you are uable to resolve the issue, please contact Pat Schloss at mothur.bugs@gmail.com, and be sure to include the mothur.logFile with your inquiry.");
457         }
458     }
459 }
460 /*********************************************************************************************/
461 //The following was originally from http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c 
462 // process_mem_usage(double &, double &) - takes two doubles by reference,
463 // attempts to read the system-dependent data for a process' virtual memory
464 // size and resident set size, and return the results in KB.
465 //
466 // On failure, returns 0.0, 0.0
467 int MothurOut::mem_usage(double& vm_usage, double& resident_set) {
468   #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
469   
470            vm_usage     = 0.0;
471            resident_set = 0.0;
472
473            // 'file' stat seems to give the most reliable results
474            //
475            ifstream stat_stream("/proc/self/stat",ios_base::in);
476
477            // dummy vars for leading entries in stat that we don't care about
478            //
479            string pid, comm, state, ppid, pgrp, session, tty_nr;
480            string tpgid, flags, minflt, cminflt, majflt, cmajflt;
481            string utime, stime, cutime, cstime, priority, nice;
482            string O, itrealvalue, starttime;
483
484            // the two fields we want
485            //
486            unsigned long vsize;
487            long rss;
488
489            stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
490                                    >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
491                                    >> utime >> stime >> cutime >> cstime >> priority >> nice
492                                    >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
493
494            long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
495            vm_usage     = vsize / 1024.0;
496            resident_set = rss * page_size_kb;
497            
498            mothurOut("Memory Usage: vm = " + toString(vm_usage) + " rss = " + toString(resident_set) + "\n");
499                 return 0;
500
501         #else
502 /*              //windows memory usage
503                 // Get the list of process identifiers.
504                 DWORD aProcesses[1024], cbNeeded, cProcesses;
505                 
506                 if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ){ return 1; }
507
508                 // Calculate how many process identifiers were returned.
509                 cProcesses = cbNeeded / sizeof(DWORD);
510
511                 // Print the memory usage for each process
512                 for (int i = 0; i < cProcesses; i++ ) {
513                         DWORD processID = aProcesses[i];
514                         
515                         PROCESS_MEMORY_COUNTERS pmc;
516
517                         HANDLE hProcess = OpenProcess((PROCESS_QUERY_INFORMATION | PROCESS_VM_READ), FALSE, processID);
518
519                         // Print the process identifier.
520                         printf( "\nProcess ID: %u\n", processID);
521                         
522                         if (NULL != hProcess) {
523
524                                 if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
525                                         printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
526                                         printf( "\tPeakWorkingSetSize: 0x%08X\n", pmc.PeakWorkingSetSize );
527                                         printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
528                                         printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakPagedPoolUsage );
529                                         printf( "\tQuotaPagedPoolUsage: 0x%08X\n", pmc.QuotaPagedPoolUsage );
530                                         printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakNonPagedPoolUsage );
531                                         printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", pmc.QuotaNonPagedPoolUsage );
532                                         printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); 
533                                         printf( "\tPeakPagefileUsage: 0x%08X\n", pmc.PeakPagefileUsage );
534                                 }
535                                 CloseHandle(hProcess);
536                         }
537                 }
538 */
539                         return 0;
540
541         #endif
542 }
543
544
545 /***********************************************************************/
546 int MothurOut::openOutputFileAppend(string fileName, ofstream& fileHandle){
547         try {
548                 fileName = getFullPathName(fileName);
549                 
550                 fileHandle.open(fileName.c_str(), ios::app);
551                 if(!fileHandle) {
552                         mothurOut("[ERROR]: Could not open " + fileName); mothurOutEndLine();
553                         return 1;
554                 }
555                 else {
556                         return 0;
557                 }
558         }
559         catch(exception& e) {
560                 errorOut(e, "MothurOut", "openOutputFileAppend");
561                 exit(1);
562         }
563 }
564 /***********************************************************************/
565 void MothurOut::gobble(istream& f){
566         try {
567                 
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 void MothurOut::gobble(istringstream& f){
579         try {
580                 char d;
581                 while(isspace(d=f.get()))               {;}
582                 if(!f.eof()) { f.putback(d); }
583         }
584         catch(exception& e) {
585                 errorOut(e, "MothurOut", "gobble");
586                 exit(1);
587         }
588 }
589
590 /***********************************************************************/
591
592 string MothurOut::getline(istringstream& fileHandle) {
593         try {
594         
595                 string line = "";
596                 
597                 while (!fileHandle.eof())       {
598                         //get next character
599                         char c = fileHandle.get(); 
600                         
601                         //are you at the end of the line
602                         if ((c == '\n') || (c == '\r') || (c == '\f')){  break; }       
603                         else {          line += c;              }
604                 }
605                 
606                 return line;
607                 
608         }
609         catch(exception& e) {
610                 errorOut(e, "MothurOut", "getline");
611                 exit(1);
612         }
613 }
614 /***********************************************************************/
615
616 string MothurOut::getline(ifstream& fileHandle) {
617         try {
618         
619                 string line = "";
620                 
621                 while (fileHandle)      {
622                         //get next character
623                         char c = fileHandle.get(); 
624                         
625                         //are you at the end of the line
626                         if ((c == '\n') || (c == '\r') || (c == '\f') || (c == EOF)){  break;   }       
627                         else {          line += c;              }
628                 }
629                 
630                 return line;
631                 
632         }
633         catch(exception& e) {
634                 errorOut(e, "MothurOut", "getline");
635                 exit(1);
636         }
637 }
638 /***********************************************************************/
639
640 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
641 #ifdef USE_COMPRESSION
642 inline bool endsWith(string s, const char * suffix){
643   size_t suffixLength = strlen(suffix);
644   return s.size() >= suffixLength && s.substr(s.size() - suffixLength, suffixLength).compare(suffix) == 0;
645 }
646 #endif
647 #endif
648
649 string MothurOut::getRootName(string longName){
650         try {
651         
652                 string rootName = longName;
653
654 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
655 #ifdef USE_COMPRESSION
656     if (endsWith(rootName, ".gz") || endsWith(rootName, ".bz2")) {
657       int pos = rootName.find_last_of('.');
658       rootName = rootName.substr(0, pos);
659       cerr << "shortening " << longName << " to " << rootName << "\n";
660     }
661 #endif
662 #endif
663                 if(rootName.find_last_of(".") != rootName.npos){
664                         int pos = rootName.find_last_of('.')+1;
665                         rootName = rootName.substr(0, pos);
666                 }
667
668                 return rootName;
669         }
670         catch(exception& e) {
671                 errorOut(e, "MothurOut", "getRootName");
672                 exit(1);
673         }
674 }
675 /***********************************************************************/
676
677 string MothurOut::getSimpleName(string longName){
678         try {
679                 string simpleName = longName;
680                 
681                 size_t found;
682                 found=longName.find_last_of("/\\");
683
684                 if(found != longName.npos){
685                         simpleName = longName.substr(found+1);
686                 }
687                 
688                 return simpleName;
689         }
690         catch(exception& e) {
691                 errorOut(e, "MothurOut", "getSimpleName");
692                 exit(1);
693         }
694 }
695
696 /***********************************************************************/
697
698 int MothurOut::getRandomIndex(int highest){
699         try {
700                 
701                 int random = (int) ((float)(highest+1) * (float)(rand()) / ((float)RAND_MAX+1.0));
702                 
703                 return random;
704         }
705         catch(exception& e) {
706                 errorOut(e, "MothurOut", "getRandomIndex");
707                 exit(1);
708         }       
709         
710 }
711 /**********************************************************************/
712
713 string MothurOut::getPathName(string longName){
714         try {
715                 string rootPathName = longName;
716                 
717                 if(longName.find_last_of("/\\") != longName.npos){
718                         int pos = longName.find_last_of("/\\")+1;
719                         rootPathName = longName.substr(0, pos);
720                 }
721                 
722                 return rootPathName;
723         }
724         catch(exception& e) {
725                 errorOut(e, "MothurOut", "getPathName");
726                 exit(1);
727         }       
728
729 }
730 /***********************************************************************/
731
732 bool MothurOut::dirCheck(string& dirName){
733         try {
734         
735         string tag = "";
736         #ifdef USE_MPI
737             int pid; 
738             MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
739                 
740             tag = toString(pid);
741         #endif
742
743         //add / to name if needed
744         string lastChar = dirName.substr(dirName.length()-1);
745         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
746         if (lastChar != "/") { dirName += "/"; }
747         #else
748         if (lastChar != "\\") { dirName += "\\"; }      
749         #endif
750
751         //test to make sure directory exists
752         dirName = getFullPathName(dirName);
753         string outTemp = dirName + tag + "temp";
754         ofstream out;
755         out.open(outTemp.c_str(), ios::trunc);
756         if(!out) {
757             mothurOut(dirName + " directory does not exist or is not writable."); mothurOutEndLine(); 
758         }else{
759             out.close();
760             mothurRemove(outTemp);
761             return true;
762         }
763         
764         return false;
765     }
766         catch(exception& e) {
767                 errorOut(e, "MothurOut", "dirCheck");
768                 exit(1);
769         }       
770     
771 }
772 /***********************************************************************/
773
774 string MothurOut::hasPath(string longName){
775         try {
776                 string path = "";
777                 
778                 size_t found;
779                 found=longName.find_last_of("~/\\");
780
781                 if(found != longName.npos){
782                         path = longName.substr(0, found+1);
783                 }
784                 
785                 return path;
786         }
787         catch(exception& e) {
788                 errorOut(e, "MothurOut", "hasPath");
789                 exit(1);
790         }       
791 }
792
793 /***********************************************************************/
794
795 string MothurOut::getExtension(string longName){
796         try {
797                 string extension = "";
798                 
799                 if(longName.find_last_of('.') != longName.npos){
800                         int pos = longName.find_last_of('.');
801                         extension = longName.substr(pos, longName.length());
802                 }
803                 
804                 return extension;
805         }
806         catch(exception& e) {
807                 errorOut(e, "MothurOut", "getExtension");
808                 exit(1);
809         }       
810 }
811 /***********************************************************************/
812 bool MothurOut::isBlank(string fileName){
813         try {
814                 
815                 fileName = getFullPathName(fileName);
816                 
817                 ifstream fileHandle;
818                 fileHandle.open(fileName.c_str());
819                 if(!fileHandle) {
820                         mothurOut("[ERROR]: Could not open " + fileName); mothurOutEndLine();
821                         return false;
822                 }else {
823                         //check for blank file
824                         gobble(fileHandle);
825                         if (fileHandle.eof()) { fileHandle.close(); return true;  }
826                         fileHandle.close();
827                 }
828                 return false;
829         }
830         catch(exception& e) {
831                 errorOut(e, "MothurOut", "isBlank");
832                 exit(1);
833         }       
834 }
835 /***********************************************************************/
836
837 string MothurOut::getFullPathName(string fileName){
838         try{
839         
840         string path = hasPath(fileName);
841         string newFileName;
842         int pos;
843         
844         if (path == "") { return fileName; } //its a simple name
845         else { //we need to complete the pathname
846                 // ex. ../../../filename 
847                 // cwd = /user/work/desktop
848                                 
849                 string cwd;
850                 //get current working directory 
851                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)  
852                         
853                         if (path.find("~") != -1) { //go to home directory
854                                 string homeDir;
855                         
856                                 char *homepath = NULL;
857                                 homepath = getenv ("HOME");
858                                 if ( homepath != NULL) { homeDir = homepath; }
859                                 else { homeDir = "";  }
860
861                                 newFileName = homeDir + fileName.substr(fileName.find("~")+1);
862                                 return newFileName;
863                         }else { //find path
864                                 if (path.rfind("./") == string::npos) { return fileName; } //already complete name
865                                 else { newFileName = fileName.substr(fileName.rfind("./")+2); } //save the complete part of the name
866                                 
867                                 //char* cwdpath = new char[1024];
868                                 //size_t size;
869                                 //cwdpath=getcwd(cwdpath,size);
870                                 //cwd = cwdpath;
871                                 
872                                 char *cwdpath = NULL;
873                                 cwdpath = getcwd(NULL, 0); // or _getcwd
874                                 if ( cwdpath != NULL) { cwd = cwdpath; }
875                                 else { cwd = "";  }
876
877                                 
878                                 //rip off first '/'
879                                 string simpleCWD;
880                                 if (cwd.length() > 0) { simpleCWD = cwd.substr(1); }
881                                 
882                                 //break apart the current working directory
883                                 vector<string> dirs;
884                                 while (simpleCWD.find_first_of('/') != string::npos) {
885                                         string dir = simpleCWD.substr(0,simpleCWD.find_first_of('/'));
886                                         simpleCWD = simpleCWD.substr(simpleCWD.find_first_of('/')+1, simpleCWD.length());
887                                         dirs.push_back(dir);
888                                 }
889                                 //get last one              // ex. ../../../filename = /user/work/desktop/filename
890                                 dirs.push_back(simpleCWD);  //ex. dirs[0] = user, dirs[1] = work, dirs[2] = desktop
891                                 
892                         
893                                 int index = dirs.size()-1;
894                 
895                                 while((pos = path.rfind("./")) != string::npos) { //while you don't have a complete path
896                                         if (pos == 0) { break;  //you are at the end
897                                         }else if (path[(pos-1)] == '.') { //you want your parent directory ../
898                                                 path = path.substr(0, pos-1);
899                                                 index--;
900                                                 if (index == 0) {  break; }
901                                         }else if (path[(pos-1)] == '/') { //you want the current working dir ./
902                                                 path = path.substr(0, pos);
903                                         }else if (pos == 1) { break;  //you are at the end
904                                         }else { mothurOut("cannot resolve path for " +  fileName + "\n"); return fileName; }
905                                 }
906                         
907                                 for (int i = index; i >= 0; i--) {
908                                         newFileName = dirs[i] +  "/" + newFileName;             
909                                 }
910                                 
911                                 newFileName =  "/" +  newFileName;
912                                 return newFileName;
913                         }       
914                 #else
915                         if (path.find("~") != string::npos) { //go to home directory
916                                 string homeDir = getenv ("HOMEPATH");
917                                 newFileName = homeDir + fileName.substr(fileName.find("~")+1);
918                                 return newFileName;
919                         }else { //find path
920                                 if (path.rfind(".\\") == string::npos) { return fileName; } //already complete name
921                                 else { newFileName = fileName.substr(fileName.rfind(".\\")+2); } //save the complete part of the name
922                                                         
923                                 char *cwdpath = NULL;
924                                 cwdpath = getcwd(NULL, 0); // or _getcwd
925                                 if ( cwdpath != NULL) { cwd = cwdpath; }
926                                 else { cwd = "";  }
927                                 
928                                 //break apart the current working directory
929                                 vector<string> dirs;
930                                 while (cwd.find_first_of('\\') != -1) {
931                                         string dir = cwd.substr(0,cwd.find_first_of('\\'));
932                                         cwd = cwd.substr(cwd.find_first_of('\\')+1, cwd.length());
933                                         dirs.push_back(dir);
934                 
935                                 }
936                                 //get last one
937                                 dirs.push_back(cwd);  //ex. dirs[0] = user, dirs[1] = work, dirs[2] = desktop
938                                         
939                                 int index = dirs.size()-1;
940                                         
941                                 while((pos = path.rfind(".\\")) != string::npos) { //while you don't have a complete path
942                                         if (pos == 0) { break;  //you are at the end
943                                         }else if (path[(pos-1)] == '.') { //you want your parent directory ../
944                                                 path = path.substr(0, pos-1);
945                                                 index--;
946                                                 if (index == 0) {  break; }
947                                         }else if (path[(pos-1)] == '\\') { //you want the current working dir ./
948                                                 path = path.substr(0, pos);
949                                         }else if (pos == 1) { break;  //you are at the end
950                                         }else { mothurOut("cannot resolve path for " +  fileName + "\n"); return fileName; }
951                                 }
952                         
953                                 for (int i = index; i >= 0; i--) {
954                                         newFileName = dirs[i] +  "\\\\" + newFileName;          
955                                 }
956                                 
957                                 return newFileName;
958                         }
959                         
960                 #endif
961         }
962         }
963         catch(exception& e) {
964                 errorOut(e, "MothurOut", "getFullPathName");
965                 exit(1);
966         }       
967 }
968 /***********************************************************************/
969
970 int MothurOut::openInputFile(string fileName, ifstream& fileHandle, string m){
971         try {
972                         //get full path name
973                         string completeFileName = getFullPathName(fileName);
974 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
975 #ifdef USE_COMPRESSION
976       // check for gzipped or bzipped file
977       if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
978         string tempName = string(tmpnam(0));
979         mkfifo(tempName.c_str(), 0666);
980         int fork_result = fork();
981         if (fork_result < 0) {
982           cerr << "Error forking.\n";
983           exit(1);
984         } else if (fork_result == 0) {
985           string command = (endsWith(completeFileName, ".gz") ? "zcat " : "bzcat ") + completeFileName + string(" > ") + tempName;
986           cerr << "Decompressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
987           system(command.c_str());
988           cerr << "Done decompressing " << completeFileName << "\n";
989           mothurRemove(tempName);
990           exit(EXIT_SUCCESS);
991         } else {
992           cerr << "waiting on child process " << fork_result << "\n";
993           completeFileName = tempName;
994         }
995       }
996 #endif
997 #endif
998                         fileHandle.open(completeFileName.c_str());
999                         if(!fileHandle) {
1000                                 //mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
1001                                 return 1;
1002                         }else {
1003                                 //check for blank file
1004                                 gobble(fileHandle);
1005                                 return 0;
1006                         }
1007         }
1008         catch(exception& e) {
1009                 errorOut(e, "MothurOut", "openInputFile - no Error");
1010                 exit(1);
1011         }
1012 }
1013 /***********************************************************************/
1014
1015 int MothurOut::openInputFile(string fileName, ifstream& fileHandle){
1016         try {
1017
1018                 //get full path name
1019                 string completeFileName = getFullPathName(fileName);
1020 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
1021 #ifdef USE_COMPRESSION
1022   // check for gzipped or bzipped file
1023   if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
1024     string tempName = string(tmpnam(0));
1025     mkfifo(tempName.c_str(), 0666);
1026     int fork_result = fork();
1027     if (fork_result < 0) {
1028       cerr << "Error forking.\n";
1029       exit(1);
1030     } else if (fork_result == 0) {
1031       string command = (endsWith(completeFileName, ".gz") ? "zcat " : "bzcat ") + completeFileName + string(" > ") + tempName;
1032       cerr << "Decompressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
1033       system(command.c_str());
1034       cerr << "Done decompressing " << completeFileName << "\n";
1035       mothurRemove(tempName);
1036       exit(EXIT_SUCCESS);
1037     } else {
1038       cerr << "waiting on child process " << fork_result << "\n";
1039       completeFileName = tempName;
1040     }
1041   }
1042 #endif
1043 #endif
1044
1045                 fileHandle.open(completeFileName.c_str());
1046                 if(!fileHandle) {
1047                         mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
1048                         return 1;
1049                 }
1050                 else {
1051                         //check for blank file
1052                         gobble(fileHandle);
1053                         if (fileHandle.eof()) { mothurOut("[ERROR]: " + completeFileName + " is blank. Please correct."); mothurOutEndLine();  }
1054                         
1055                         return 0;
1056                 }
1057         }
1058         catch(exception& e) {
1059                 errorOut(e, "MothurOut", "openInputFile");
1060                 exit(1);
1061         }       
1062 }
1063 /***********************************************************************/
1064
1065 int MothurOut::renameFile(string oldName, string newName){
1066         try {
1067         
1068         if (oldName == newName) { return 0; }
1069         
1070                 ifstream inTest;
1071                 int exist = openInputFile(newName, inTest, "");
1072                 inTest.close();
1073                 
1074         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)          
1075                 if (exist == 0) { //you could open it so you want to delete it
1076                         string command = "rm " + newName;
1077                         system(command.c_str());
1078                 }
1079                                 
1080                 string command = "mv " + oldName + " " + newName;
1081                 system(command.c_str());
1082         #else
1083                 mothurRemove(newName);
1084                 int renameOk = rename(oldName.c_str(), newName.c_str());
1085         #endif
1086                 return 0;
1087                 
1088         }
1089         catch(exception& e) {
1090                 errorOut(e, "MothurOut", "renameFile");
1091                 exit(1);
1092         }       
1093 }
1094
1095 /***********************************************************************/
1096
1097 int MothurOut::openOutputFile(string fileName, ofstream& fileHandle){
1098         try { 
1099         
1100                 string completeFileName = getFullPathName(fileName);
1101 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
1102 #ifdef USE_COMPRESSION
1103     // check for gzipped file
1104     if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
1105       string tempName = string(tmpnam(0));
1106       mkfifo(tempName.c_str(), 0666);
1107       cerr << "Compressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
1108       int fork_result = fork();
1109       if (fork_result < 0) {
1110         cerr << "Error forking.\n";
1111         exit(1);
1112       } else if (fork_result == 0) {
1113         string command = string(endsWith(completeFileName, ".gz") ?  "gzip" : "bzip2") + " -v > " + completeFileName + string(" < ") + tempName;
1114         system(command.c_str());
1115         exit(0);
1116       } else {
1117         completeFileName = tempName;
1118       }
1119     }
1120 #endif
1121 #endif
1122                 fileHandle.open(completeFileName.c_str(), ios::trunc);
1123                 if(!fileHandle) {
1124                         mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
1125                         return 1;
1126                 }
1127                 else {
1128                         return 0;
1129                 }
1130         }
1131         catch(exception& e) {
1132                 errorOut(e, "MothurOut", "openOutputFile");
1133                 exit(1);
1134         }       
1135
1136 }
1137
1138 /**************************************************************************************************/
1139 int MothurOut::appendFiles(string temp, string filename) {
1140         try{
1141                 ofstream output;
1142                 ifstream input;
1143         
1144                 //open output file in append mode
1145                 openOutputFileAppend(filename, output);
1146                 int ableToOpen = openInputFile(temp, input, "no error");
1147                 //int ableToOpen = openInputFile(temp, input);
1148                 
1149                 int numLines = 0;
1150                 if (ableToOpen == 0) { //you opened it
1151             
1152             char buffer[4096];        
1153             while (!input.eof()) {
1154                 input.read(buffer, 4096);
1155                 output.write(buffer, input.gcount());
1156                 //count number of lines
1157                 for (int i = 0; i < input.gcount(); i++) {  if (buffer[i] == '\n') {numLines++;} }
1158             }
1159                         input.close();
1160                 }
1161                 
1162                 output.close();
1163                 
1164                 return numLines;
1165         }
1166         catch(exception& e) {
1167                 errorOut(e, "MothurOut", "appendFiles");
1168                 exit(1);
1169         }       
1170 }
1171
1172 /**************************************************************************************************/
1173 string MothurOut::sortFile(string distFile, string outputDir){
1174         try {   
1175         
1176                 //if (outputDir == "") {  outputDir += hasPath(distFile);  }
1177                 string outfile = getRootName(distFile) + "sorted.dist";
1178
1179                 
1180                 //if you can, use the unix sort since its been optimized for years
1181                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
1182                         string command = "sort -n -k +3 " + distFile + " -o " + outfile;
1183                         system(command.c_str());
1184                 #else //you are stuck with my best attempt...
1185                         //windows sort does not have a way to specify a column, only a character in the line
1186                         //since we cannot assume that the distance will always be at the the same character location on each line
1187                         //due to variable sequence name lengths, I chose to force the distance into first position, then sort and then put it back.
1188                 
1189                         //read in file line by file and put distance first
1190                         string tempDistFile = distFile + ".temp";
1191                         ifstream input;
1192                         ofstream output;
1193                         openInputFile(distFile, input);
1194                         openOutputFile(tempDistFile, output);
1195
1196                         string firstName, secondName;
1197                         float dist;
1198                         while (!input.eof()) {
1199                                 input >> firstName >> secondName >> dist;
1200                                 output << dist << '\t' << firstName << '\t' << secondName << endl;
1201                                 gobble(input);
1202                         }
1203                         input.close();
1204                         output.close();
1205                 
1206         
1207                         //sort using windows sort
1208                         string tempOutfile = outfile + ".temp";
1209                         string command = "sort " + tempDistFile + " /O " + tempOutfile;
1210                         system(command.c_str());
1211                 
1212                         //read in sorted file and put distance at end again
1213                         ifstream input2;
1214             ofstream output2;
1215                         openInputFile(tempOutfile, input2);
1216                         openOutputFile(outfile, output2);
1217                 
1218             while (!input2.eof()) {
1219                                 input2 >> dist >> firstName >> secondName;
1220                                 output2 << firstName << '\t' << secondName << '\t' << dist << endl;
1221                                 gobble(input2);
1222                         }
1223                         input2.close();
1224                         output2.close();
1225                 
1226                         //remove temp files
1227                         mothurRemove(tempDistFile);
1228                         mothurRemove(tempOutfile);
1229                 #endif
1230                 
1231                 return outfile;
1232         }
1233         catch(exception& e) {
1234                 errorOut(e, "MothurOut", "sortFile");
1235                 exit(1);
1236         }       
1237 }
1238 /**************************************************************************************************/
1239 vector<unsigned long long> MothurOut::setFilePosFasta(string filename, int& num) {
1240         try {
1241                         vector<unsigned long long> positions;
1242                         ifstream inFASTA;
1243                         //openInputFile(filename, inFASTA);
1244                         inFASTA.open(filename.c_str(), ios::binary);
1245                                                 
1246                         string input;
1247                         unsigned long long count = 0;
1248                         while(!inFASTA.eof()){
1249                                 //input = getline(inFASTA); 
1250                                 //cout << input << '\t' << inFASTA.tellg() << endl;
1251                                 //if (input.length() != 0) {
1252                                 //      if(input[0] == '>'){    unsigned long int pos = inFASTA.tellg(); positions.push_back(pos - input.length() - 1);  cout << (pos - input.length() - 1) << endl; }
1253                                 //}
1254                                 //gobble(inFASTA); //has to be here since windows line endings are 2 characters and mess up the positions
1255                                 char c = inFASTA.get(); count++;
1256                                 if (c == '>') {
1257                                         positions.push_back(count-1);
1258                                         //cout << count << endl;
1259                                 }
1260                         }
1261                         inFASTA.close();
1262                 
1263                         num = positions.size();
1264                 
1265                         /*FILE * pFile;
1266                         long size;
1267                 
1268                         //get num bytes in file
1269                         pFile = fopen (filename.c_str(),"rb");
1270                         if (pFile==NULL) perror ("Error opening file");
1271                         else{
1272                                 fseek (pFile, 0, SEEK_END);
1273                                 size=ftell (pFile);
1274                                 fclose (pFile);
1275                         }*/
1276                         
1277                         unsigned long long size = positions[(positions.size()-1)];
1278                         ifstream in;
1279                         openInputFile(filename, in);
1280                         
1281                         in.seekg(size);
1282                 
1283                         while(in.get()){
1284                                 if(in.eof())            {       break;  }
1285                                 else                            {       size++; }
1286                         }
1287                         in.close();
1288                 
1289                         positions.push_back(size);
1290                         positions[0] = 0;
1291                 
1292                         return positions;
1293         }
1294         catch(exception& e) {
1295                 errorOut(e, "MothurOut", "setFilePosFasta");
1296                 exit(1);
1297         }
1298 }
1299 /**************************************************************************************************/
1300 vector<unsigned long long> MothurOut::setFilePosEachLine(string filename, int& num) {
1301         try {
1302                         filename = getFullPathName(filename);
1303                         
1304                         vector<unsigned long long> positions;
1305                         ifstream in;
1306                         //openInputFile(filename, in);
1307                         in.open(filename.c_str(), ios::binary);
1308                 
1309                         string input;
1310                         unsigned long long count = 0;
1311                         positions.push_back(0);
1312                 
1313                         while(!in.eof()){
1314                                 //getline counting reads
1315                                 char d = in.get(); count++;
1316                                 while ((d != '\n') && (d != '\r') && (d != '\f') && (d != in.eof()))    {
1317                                         //get next character
1318                                         d = in.get(); 
1319                                         count++;
1320                                 }
1321                                 
1322                                 if (!in.eof()) {
1323                                         d=in.get(); count++;
1324                                         while(isspace(d) && (d != in.eof()))            { d=in.get(); count++;}
1325                                 }
1326                                 positions.push_back(count-1);
1327                                 //cout << count-1 << endl;
1328                         }
1329                         in.close();
1330                 
1331                         num = positions.size()-1;
1332                 
1333                         FILE * pFile;
1334                         unsigned long long size;
1335                         
1336                         //get num bytes in file
1337                         pFile = fopen (filename.c_str(),"rb");
1338                         if (pFile==NULL) perror ("Error opening file");
1339                         else{
1340                                 fseek (pFile, 0, SEEK_END);
1341                                 size=ftell (pFile);
1342                                 fclose (pFile);
1343                         }
1344                 
1345                         positions[(positions.size()-1)] = size;
1346                 
1347                         return positions;
1348         }
1349         catch(exception& e) {
1350                 errorOut(e, "MothurOut", "setFilePosEachLine");
1351                 exit(1);
1352         }
1353 }
1354 /**************************************************************************************************/
1355
1356 vector<unsigned long long> MothurOut::divideFile(string filename, int& proc) {
1357         try{
1358                 vector<unsigned long long> filePos;
1359                 filePos.push_back(0);
1360                 
1361                 FILE * pFile;
1362                 unsigned long long size;
1363                 
1364                 filename = getFullPathName(filename);
1365         
1366                 //get num bytes in file
1367                 pFile = fopen (filename.c_str(),"rb");
1368                 if (pFile==NULL) perror ("Error opening file");
1369                 else{
1370                         fseek (pFile, 0, SEEK_END);
1371                         size=ftell (pFile);
1372                         fclose (pFile);
1373                 }
1374                 
1375         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
1376                                 
1377                 //estimate file breaks
1378                 unsigned long long chunkSize = 0;
1379                 chunkSize = size / proc;
1380
1381                 //file to small to divide by processors
1382                 if (chunkSize == 0)  {  proc = 1;       filePos.push_back(size); return filePos;        }
1383         
1384                 //for each process seekg to closest file break and search for next '>' char. make that the filebreak
1385                 for (int i = 0; i < proc; i++) {
1386                         unsigned long long spot = (i+1) * chunkSize;
1387                         
1388                         ifstream in;
1389                         openInputFile(filename, in);
1390                         in.seekg(spot);
1391                         
1392                         //look for next '>'
1393                         unsigned long long newSpot = spot;
1394                         while (!in.eof()) {
1395                            char c = in.get();
1396                                 
1397                            if (c == '>') {   in.putback(c); newSpot = in.tellg(); break;  }
1398                            else if (int(c) == -1) { break; }
1399                                 
1400                         }
1401                 
1402                         //there was not another sequence before the end of the file
1403                         unsigned long long sanityPos = in.tellg();
1404
1405                         if (sanityPos == -1) {  break;  }
1406                         else {  filePos.push_back(newSpot);  }
1407                         
1408                         in.close();
1409                 }
1410                 
1411                 //save end pos
1412                 filePos.push_back(size);
1413                 
1414                 //sanity check filePos
1415                 for (int i = 0; i < (filePos.size()-1); i++) {
1416                         if (filePos[(i+1)] <= filePos[i]) {  filePos.erase(filePos.begin()+(i+1)); i--; }
1417                 }
1418
1419                 proc = (filePos.size() - 1);
1420 #else
1421                 mothurOut("[ERROR]: Windows version should not be calling the divideFile function."); mothurOutEndLine();
1422                 proc=1;
1423                 filePos.push_back(size);
1424 #endif
1425                 return filePos;
1426         }
1427         catch(exception& e) {
1428                 errorOut(e, "MothurOut", "divideFile");
1429                 exit(1);
1430         }
1431 }
1432 /**************************************************************************************************/
1433 int MothurOut::divideFile(string filename, int& proc, vector<string>& files) {
1434         try{
1435                 
1436                 vector<unsigned long long> filePos = divideFile(filename, proc);
1437                 
1438                 for (int i = 0; i < (filePos.size()-1); i++) {
1439                         
1440                         //read file chunk
1441                         ifstream in;
1442                         openInputFile(filename, in);
1443                         in.seekg(filePos[i]);
1444                         unsigned long long size = filePos[(i+1)] - filePos[i];
1445                         char* chunk = new char[size];
1446                         in.read(chunk, size);
1447                         in.close();
1448                         
1449                         //open new file
1450                         string fileChunkName = filename + "." + toString(i) + ".tmp";
1451                         ofstream out; 
1452                         openOutputFile(fileChunkName, out);
1453                         
1454                         out << chunk << endl;
1455                         out.close();
1456                         delete[] chunk;
1457                         
1458                         //save name
1459                         files.push_back(fileChunkName);
1460                 }
1461                                 
1462                 return 0;
1463         }
1464         catch(exception& e) {
1465                 errorOut(e, "MothurOut", "divideFile");
1466                 exit(1);
1467         }
1468 }
1469 /***********************************************************************/
1470
1471 bool MothurOut::isTrue(string f){
1472         try {
1473                 
1474                 for (int i = 0; i < f.length(); i++) { f[i] = toupper(f[i]); }
1475                 
1476                 if ((f == "TRUE") || (f == "T")) {      return true;    }
1477                 else {  return false;  }
1478         }
1479         catch(exception& e) {
1480                 errorOut(e, "MothurOut", "isTrue");
1481                 exit(1);
1482         }
1483 }
1484
1485 /***********************************************************************/
1486
1487 float MothurOut::roundDist(float dist, int precision){
1488         try {
1489                 return int(dist * precision + 0.5)/float(precision);
1490         }
1491         catch(exception& e) {
1492                 errorOut(e, "MothurOut", "roundDist");
1493                 exit(1);
1494         }
1495 }
1496 /***********************************************************************/
1497
1498 float MothurOut::ceilDist(float dist, int precision){
1499         try {
1500                 return int(ceil(dist * precision))/float(precision);
1501         }
1502         catch(exception& e) {
1503                 errorOut(e, "MothurOut", "ceilDist");
1504                 exit(1);
1505         }
1506 }
1507 /***********************************************************************/
1508
1509 vector<string> MothurOut::splitWhiteSpace(string& rest, char buffer[], int size){
1510         try {
1511         vector<string> pieces;
1512         
1513         for (int i = 0; i < size; i++) {
1514             if (!isspace(buffer[i]))  { rest += buffer[i];  }
1515             else {
1516                 if (rest != "") { pieces.push_back(rest);  rest = ""; }
1517                 while (i < size) {  //gobble white space
1518                     if (isspace(buffer[i])) { i++; }
1519                     else { rest = buffer[i];  break; } //cout << "next piece buffer = " << nextPiece << endl;
1520                 } 
1521             }
1522         }
1523         
1524         return pieces;
1525         }
1526         catch(exception& e) {
1527                 errorOut(e, "MothurOut", "splitWhiteSpace");
1528                 exit(1);
1529         }
1530 }
1531 /***********************************************************************/
1532 vector<string> MothurOut::splitWhiteSpace(string input){
1533         try {
1534         vector<string> pieces;
1535         string rest = "";
1536         
1537         for (int i = 0; i < input.length(); i++) {
1538             if (!isspace(input[i]))  { rest += input[i];  }
1539             else {
1540                 if (rest != "") { pieces.push_back(rest);  rest = ""; }
1541                 while (i < input.length()) {  //gobble white space
1542                     if (isspace(input[i])) { i++; }
1543                     else { rest = input[i];  break; } //cout << "next piece buffer = " << nextPiece << endl;
1544                 } 
1545             }
1546         }
1547         
1548         if (rest != "") { pieces.push_back(rest); }
1549         
1550         return pieces;
1551         }
1552         catch(exception& e) {
1553                 errorOut(e, "MothurOut", "splitWhiteSpace");
1554                 exit(1);
1555         }
1556 }
1557 /***********************************************************************/
1558 vector<string> MothurOut::splitWhiteSpaceWithQuotes(string input){
1559         try {
1560         vector<string> pieces;
1561         string rest = "";
1562         
1563         int pos = input.find('\'');
1564         int pos2 = input.find('\"');
1565         
1566         if ((pos == string::npos) && (pos2 == string::npos)) { return splitWhiteSpace(input); } //no quotes to worry about
1567         else {
1568             for (int i = 0; i < input.length(); i++) {
1569                 if ((input[i] == '\'') || (input[i] == '\"') || (rest == "\'") || (rest == "\"")) { //grab everything til end or next ' or "
1570                     rest += input[i];
1571                     for (int j = i+1; j < input.length(); j++) {
1572                         if ((input[j] == '\'') || (input[j] == '\"')) {  //then quit
1573                             rest += input[j];
1574                             i = j+1;
1575                             j+=input.length();
1576                         }else { rest += input[j]; }
1577                     }
1578                 }else if (!isspace(input[i]))  { rest += input[i];  }
1579                 else {
1580                     if (rest != "") { pieces.push_back(rest);  rest = ""; }
1581                     while (i < input.length()) {  //gobble white space
1582                         if (isspace(input[i])) { i++; }
1583                         else { rest = input[i];  break; } //cout << "next piece buffer = " << nextPiece << endl;
1584                     } 
1585                 }
1586             }
1587             
1588             if (rest != "") { pieces.push_back(rest); }
1589         }
1590         return pieces;
1591         }
1592         catch(exception& e) {
1593                 errorOut(e, "MothurOut", "splitWhiteSpace");
1594                 exit(1);
1595         }
1596 }
1597 //**********************************************************************************************************************
1598 int MothurOut::readTax(string namefile, map<string, string>& taxMap) {
1599         try {
1600         //open input file
1601                 ifstream in;
1602                 openInputFile(namefile, in);
1603         
1604         string rest = "";
1605         char buffer[4096];
1606         bool pairDone = false;
1607         bool columnOne = true;
1608         string firstCol, secondCol;
1609         
1610                 while (!in.eof()) {
1611                         if (control_pressed) { break; }
1612                         
1613             in.read(buffer, 4096);
1614             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1615             
1616             for (int i = 0; i < pieces.size(); i++) {
1617                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1618                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1619                 
1620                 if (pairDone) { 
1621                     checkName(firstCol);
1622                     //are there confidence scores, if so remove them
1623                     if (secondCol.find_first_of('(') != -1) {  removeConfidences(secondCol);    }
1624                     map<string, string>::iterator itTax = taxMap.find(firstCol);
1625                     
1626                     if(itTax == taxMap.end()) {
1627                         bool ignore = false;
1628                         if (secondCol != "") { if (secondCol[secondCol.length()-1] != ';') { mothurOut("[ERROR]: " + firstCol + " is missing the final ';', ignoring.\n"); ignore=true; }
1629                         }
1630                         if (!ignore) { taxMap[firstCol] = secondCol; }
1631                         if (debug) {  mothurOut("[DEBUG]: name = '" + firstCol + "' tax = '" + secondCol + "'\n");  }
1632                     }else {
1633                         mothurOut("[ERROR]: " + firstCol + " is already in your taxonomy file, names must be unique./n"); control_pressed = true;
1634                     }
1635                     pairDone = false; 
1636                 }
1637             }
1638                 }
1639                 in.close();
1640         
1641         if (rest != "") {
1642             vector<string> pieces = splitWhiteSpace(rest);
1643             
1644             for (int i = 0; i < pieces.size(); i++) {
1645                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1646                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1647                 
1648                 if (pairDone) { 
1649                     checkName(firstCol);
1650                     //are there confidence scores, if so remove them
1651                     if (secondCol.find_first_of('(') != -1) {  removeConfidences(secondCol);    }
1652                     map<string, string>::iterator itTax = taxMap.find(firstCol);
1653                     
1654                     if(itTax == taxMap.end()) {
1655                         bool ignore = false;
1656                         if (secondCol != "") { if (secondCol[secondCol.length()-1] != ';') { mothurOut("[ERROR]: " + firstCol + " is missing the final ';', ignoring.\n"); ignore=true; }
1657                         }
1658                         if (!ignore) { taxMap[firstCol] = secondCol; }
1659                         if (debug) {  mothurOut("[DEBUG]: name = '" + firstCol + "' tax = '" + secondCol + "'\n");  }
1660                     }else {
1661                         mothurOut("[ERROR]: " + firstCol + " is already in your taxonomy file, names must be unique./n"); control_pressed = true;
1662                     }
1663
1664                     pairDone = false; 
1665                 }
1666             } 
1667         }
1668                 
1669                 return taxMap.size();
1670
1671         }
1672         catch(exception& e) {
1673                 errorOut(e, "MothurOut", "readTax");
1674                 exit(1);
1675         }
1676 }
1677 /**********************************************************************************************************************/
1678 int MothurOut::readNames(string namefile, map<string, string>& nameMap, bool redund) { 
1679         try {
1680                 //open input file
1681                 ifstream in;
1682                 openInputFile(namefile, in);
1683         
1684         string rest = "";
1685         char buffer[4096];
1686         bool pairDone = false;
1687         bool columnOne = true;
1688         string firstCol, secondCol;
1689         
1690                 while (!in.eof()) {
1691                         if (control_pressed) { break; }
1692                         
1693             in.read(buffer, 4096);
1694             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1695             
1696             for (int i = 0; i < pieces.size(); i++) {
1697                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1698                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1699                 
1700                 if (pairDone) { 
1701                     checkName(firstCol);
1702                     checkName(secondCol);
1703                     
1704                     //parse names into vector
1705                     vector<string> theseNames;
1706                     splitAtComma(secondCol, theseNames);
1707                     for (int i = 0; i < theseNames.size(); i++) {  nameMap[theseNames[i]] = firstCol;  }
1708                     pairDone = false; 
1709                 }
1710             }
1711                 }
1712                 in.close();
1713         
1714         if (rest != "") {
1715             vector<string> pieces = splitWhiteSpace(rest);
1716             
1717             for (int i = 0; i < pieces.size(); i++) {
1718                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1719                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1720                 
1721                 if (pairDone) { 
1722                     checkName(firstCol);
1723                     checkName(secondCol);
1724                     
1725                     //parse names into vector
1726                     vector<string> theseNames;
1727                     splitAtComma(secondCol, theseNames);
1728                     for (int i = 0; i < theseNames.size(); i++) {   nameMap[theseNames[i]] = firstCol;  }
1729                     pairDone = false; 
1730                 }
1731             }  
1732         }
1733                 
1734                 return nameMap.size();
1735                 
1736         }
1737         catch(exception& e) {
1738                 errorOut(e, "MothurOut", "readNames");
1739                 exit(1);
1740         }
1741 }
1742 /**********************************************************************************************************************/
1743 int MothurOut::readNames(string namefile, map<string, string>& nameMap, int flip) { 
1744         try {
1745                 //open input file
1746                 ifstream in;
1747                 openInputFile(namefile, in);
1748         
1749         string rest = "";
1750         char buffer[4096];
1751         bool pairDone = false;
1752         bool columnOne = true;
1753         string firstCol, secondCol;
1754         
1755                 while (!in.eof()) {
1756                         if (control_pressed) { break; }
1757                         
1758             in.read(buffer, 4096);
1759             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1760             
1761             for (int i = 0; i < pieces.size(); i++) {
1762                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1763                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1764                 
1765                 if (pairDone) { 
1766                     checkName(firstCol);
1767                     checkName(secondCol);
1768                     nameMap[secondCol] = firstCol;
1769                     pairDone = false; 
1770                 }
1771             }
1772                 }
1773                 in.close();
1774         
1775         if (rest != "") {
1776             vector<string> pieces = splitWhiteSpace(rest);
1777             
1778             for (int i = 0; i < pieces.size(); i++) {
1779                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1780                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1781                 
1782                 if (pairDone) { 
1783                     checkName(firstCol);
1784                     checkName(secondCol);
1785                     nameMap[secondCol] = firstCol;
1786                     pairDone = false; 
1787                 }
1788             } 
1789         }
1790                 
1791                 return nameMap.size();
1792                 
1793         }
1794         catch(exception& e) {
1795                 errorOut(e, "MothurOut", "readNames");
1796                 exit(1);
1797         }
1798 }
1799 /**********************************************************************************************************************/
1800 int MothurOut::readNames(string namefile, map<string, string>& nameMap, map<string, int>& nameCount) { 
1801         try {
1802                 nameMap.clear(); nameCount.clear();
1803                 //open input file
1804                 ifstream in;
1805                 openInputFile(namefile, in);
1806         
1807         string rest = "";
1808         char buffer[4096];
1809         bool pairDone = false;
1810         bool columnOne = true;
1811         string firstCol, secondCol;
1812         
1813                 while (!in.eof()) {
1814                         if (control_pressed) { break; }
1815                         
1816             in.read(buffer, 4096);
1817             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1818             
1819             for (int i = 0; i < pieces.size(); i++) {
1820                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1821                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1822                 
1823                 if (pairDone) { 
1824                     checkName(firstCol);
1825                     checkName(secondCol);
1826                     //parse names into vector
1827                     vector<string> theseNames;
1828                     splitAtComma(secondCol, theseNames);
1829                     for (int i = 0; i < theseNames.size(); i++) {  nameMap[theseNames[i]] = firstCol;  }
1830                     nameCount[firstCol] = theseNames.size();
1831                     pairDone = false; 
1832                 }
1833             }
1834                 }
1835                 in.close();
1836                 
1837         if (rest != "") {
1838             vector<string> pieces = splitWhiteSpace(rest);
1839             
1840             for (int i = 0; i < pieces.size(); i++) {
1841                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1842                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1843                 
1844                 if (pairDone) { 
1845                     checkName(firstCol);
1846                     checkName(secondCol);
1847                     //parse names into vector
1848                     vector<string> theseNames;
1849                     splitAtComma(secondCol, theseNames);
1850                     for (int i = 0; i < theseNames.size(); i++) {  nameMap[theseNames[i]] = firstCol;  }
1851                     nameCount[firstCol] = theseNames.size();
1852                     pairDone = false; 
1853                 }
1854             }
1855
1856         }
1857                 return nameMap.size();
1858                 
1859         }
1860         catch(exception& e) {
1861                 errorOut(e, "MothurOut", "readNames");
1862                 exit(1);
1863         }
1864 }
1865 /**********************************************************************************************************************/
1866 int MothurOut::readNames(string namefile, map<string, string>& nameMap) { 
1867         try {
1868                 //open input file
1869                 ifstream in;
1870                 openInputFile(namefile, in);
1871
1872         string rest = "";
1873         char buffer[4096];
1874         bool pairDone = false;
1875         bool columnOne = true;
1876         string firstCol, secondCol;
1877         
1878                 while (!in.eof()) {
1879                         if (control_pressed) { break; }
1880                         
1881             in.read(buffer, 4096);
1882             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1883              
1884             for (int i = 0; i < pieces.size(); i++) {
1885                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1886                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1887                 
1888                 if (pairDone) { 
1889                     checkName(firstCol);
1890                     checkName(secondCol);
1891                     nameMap[firstCol] = secondCol; pairDone = false; }
1892             }
1893                 }
1894                 in.close();
1895         
1896         if (rest != "") {
1897             vector<string> pieces = splitWhiteSpace(rest);
1898             
1899             for (int i = 0; i < pieces.size(); i++) {
1900                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1901                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1902                 
1903                 if (pairDone) { 
1904                     checkName(firstCol);
1905                     checkName(secondCol);
1906                     nameMap[firstCol] = secondCol; pairDone = false; }
1907             }
1908         }
1909                 
1910                 return nameMap.size();
1911                 
1912         }
1913         catch(exception& e) {
1914                 errorOut(e, "MothurOut", "readNames");
1915                 exit(1);
1916         }
1917 }
1918 /**********************************************************************************************************************/
1919 int MothurOut::readNames(string namefile, map<string, vector<string> >& nameMap) { 
1920         try {        
1921                 //open input file
1922                 ifstream in;
1923                 openInputFile(namefile, in);
1924                 
1925         string rest = "";
1926         char buffer[4096];
1927         bool pairDone = false;
1928         bool columnOne = true;
1929         string firstCol, secondCol;
1930         
1931                 while (!in.eof()) {
1932                         if (control_pressed) { break; }
1933                         
1934             in.read(buffer, 4096);
1935             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1936             
1937             for (int i = 0; i < pieces.size(); i++) {
1938                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1939                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1940                 
1941                 if (pairDone) { 
1942                     checkName(firstCol);
1943                     checkName(secondCol);
1944                     vector<string> temp;
1945                     splitAtComma(secondCol, temp);
1946                     nameMap[firstCol] = temp;
1947                     pairDone = false;  
1948                 } 
1949             }
1950                 }
1951                 in.close();
1952         
1953         if (rest != "") {
1954             vector<string> pieces = splitWhiteSpace(rest);
1955             
1956             for (int i = 0; i < pieces.size(); i++) {
1957                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1958                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1959                 
1960                 if (pairDone) { 
1961                     checkName(firstCol);
1962                     checkName(secondCol);
1963                     vector<string> temp;
1964                     splitAtComma(secondCol, temp);
1965                     nameMap[firstCol] = temp;
1966                     pairDone = false;  
1967                 } 
1968             }
1969         }
1970         
1971                 return nameMap.size();
1972         }
1973         catch(exception& e) {
1974                 errorOut(e, "MothurOut", "readNames");
1975                 exit(1);
1976         }
1977 }
1978 /**********************************************************************************************************************/
1979 map<string, int> MothurOut::readNames(string namefile) { 
1980         try {
1981                 map<string, int> nameMap;
1982                 
1983                 //open input file
1984                 ifstream in;
1985                 openInputFile(namefile, in);
1986                 
1987         string rest = "";
1988         char buffer[4096];
1989         bool pairDone = false;
1990         bool columnOne = true;
1991         string firstCol, secondCol;
1992         
1993                 while (!in.eof()) {
1994                         if (control_pressed) { break; }
1995                         
1996             in.read(buffer, 4096);
1997             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1998             
1999             for (int i = 0; i < pieces.size(); i++) {
2000                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2001                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2002                 
2003                 if (pairDone) { 
2004                     checkName(firstCol);
2005                     checkName(secondCol);
2006                     int num = getNumNames(secondCol);
2007                     nameMap[firstCol] = num;
2008                     pairDone = false;  
2009                 } 
2010             }
2011                 }
2012         in.close();
2013         
2014         if (rest != "") {
2015             vector<string> pieces = splitWhiteSpace(rest);
2016             for (int i = 0; i < pieces.size(); i++) {
2017                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2018                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2019                 
2020                 if (pairDone) { 
2021                     checkName(firstCol);
2022                     checkName(secondCol);
2023                     int num = getNumNames(secondCol);
2024                     nameMap[firstCol] = num;
2025                     pairDone = false;  
2026                 } 
2027             }
2028         }
2029                 
2030                 return nameMap;
2031                 
2032         }
2033         catch(exception& e) {
2034                 errorOut(e, "MothurOut", "readNames");
2035                 exit(1);
2036         }
2037 }
2038 /**********************************************************************************************************************/
2039 map<string, int> MothurOut::readNames(string namefile, unsigned long int& numSeqs) { 
2040         try {
2041                 map<string, int> nameMap;
2042         numSeqs = 0;
2043                 
2044                 //open input file
2045                 ifstream in;
2046                 openInputFile(namefile, in);
2047                 
2048         string rest = "";
2049         char buffer[4096];
2050         bool pairDone = false;
2051         bool columnOne = true;
2052         string firstCol, secondCol;
2053         
2054                 while (!in.eof()) {
2055                         if (control_pressed) { break; }
2056                         
2057             in.read(buffer, 4096);
2058             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2059             
2060             for (int i = 0; i < pieces.size(); i++) {
2061                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2062                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2063                 
2064                 if (pairDone) { 
2065                     checkName(firstCol);
2066                     checkName(secondCol);
2067                     int num = getNumNames(secondCol);
2068                     nameMap[firstCol] = num;
2069                     pairDone = false;  
2070                     numSeqs += num;
2071                 } 
2072             }
2073                 }
2074         in.close();
2075         
2076         if (rest != "") {
2077             vector<string> pieces = splitWhiteSpace(rest);
2078             for (int i = 0; i < pieces.size(); i++) {
2079                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2080                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2081                 
2082                 if (pairDone) { 
2083                     checkName(firstCol);
2084                     checkName(secondCol);
2085                     int num = getNumNames(secondCol);
2086                     nameMap[firstCol] = num;
2087                     pairDone = false;  
2088                     numSeqs += num;
2089                 } 
2090             }
2091         }
2092                 
2093                 return nameMap;
2094                 
2095         }
2096         catch(exception& e) {
2097                 errorOut(e, "MothurOut", "readNames");
2098                 exit(1);
2099         }
2100 }
2101 /************************************************************/
2102 int MothurOut::checkName(string& name) {
2103     try {
2104         for (int i = 0; i < name.length(); i++) {
2105             if (name[i] == ':') { name[i] = '_'; changedSeqNames = true; }
2106         }        
2107         return 0;
2108     }
2109         catch(exception& e) {
2110                 errorOut(e, "MothurOut", "checkName");
2111                 exit(1);
2112         }
2113 }
2114 /**********************************************************************************************************************/
2115 int MothurOut::readNames(string namefile, vector<seqPriorityNode>& nameVector, map<string, string>& fastamap) { 
2116         try {
2117                 int error = 0;
2118                 
2119                 //open input file
2120                 ifstream in;
2121                 openInputFile(namefile, in);
2122                 
2123         string rest = "";
2124         char buffer[4096];
2125         bool pairDone = false;
2126         bool columnOne = true;
2127         string firstCol, secondCol;
2128         
2129                 while (!in.eof()) {
2130                         if (control_pressed) { break; }
2131                         
2132             in.read(buffer, 4096);
2133             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2134             
2135             for (int i = 0; i < pieces.size(); i++) {
2136                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2137                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2138                 
2139                 if (pairDone) { 
2140                     checkName(firstCol);
2141                     checkName(secondCol);
2142                     int num = getNumNames(secondCol);
2143                     
2144                     map<string, string>::iterator it = fastamap.find(firstCol);
2145                     if (it == fastamap.end()) {
2146                         error = 1;
2147                         mothurOut("[ERROR]: " + firstCol + " is not in your fastafile, but is in your namesfile, please correct."); mothurOutEndLine();
2148                     }else {
2149                         seqPriorityNode temp(num, it->second, firstCol);
2150                         nameVector.push_back(temp);
2151                     }
2152                     
2153                     pairDone = false;  
2154                 } 
2155             }
2156                 }
2157         in.close();
2158         
2159         if (rest != "") {
2160             vector<string> pieces = splitWhiteSpace(rest);
2161             
2162             for (int i = 0; i < pieces.size(); i++) {
2163                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2164                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2165                 
2166                 if (pairDone) { 
2167                     checkName(firstCol);
2168                     checkName(secondCol);
2169                     int num = getNumNames(secondCol);
2170                     
2171                     map<string, string>::iterator it = fastamap.find(firstCol);
2172                     if (it == fastamap.end()) {
2173                         error = 1;
2174                         mothurOut("[ERROR]: " + firstCol + " is not in your fastafile, but is in your namesfile, please correct."); mothurOutEndLine();
2175                     }else {
2176                         seqPriorityNode temp(num, it->second, firstCol);
2177                         nameVector.push_back(temp);
2178                     }
2179                     
2180                     pairDone = false;  
2181                 } 
2182             }
2183         }
2184                 return error;
2185         }
2186         catch(exception& e) {
2187                 errorOut(e, "MothurOut", "readNames");
2188                 exit(1);
2189         }
2190 }
2191 //**********************************************************************************************************************
2192 set<string> MothurOut::readAccnos(string accnosfile){
2193         try {
2194                 set<string> names;
2195                 ifstream in;
2196                 openInputFile(accnosfile, in);
2197                 string name;
2198                 
2199         string rest = "";
2200         char buffer[4096];
2201         
2202                 while (!in.eof()) {
2203                         if (control_pressed) { break; }
2204                         
2205             in.read(buffer, 4096);
2206             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2207             
2208             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.insert(pieces[i]);  }
2209         }
2210                 in.close();     
2211                 
2212         if (rest != "") {
2213             vector<string> pieces = splitWhiteSpace(rest);
2214             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.insert(pieces[i]);  } 
2215         }
2216                 return names;
2217         }
2218         catch(exception& e) {
2219                 errorOut(e, "MothurOut", "readAccnos");
2220                 exit(1);
2221         }
2222 }
2223 //**********************************************************************************************************************
2224 int MothurOut::readAccnos(string accnosfile, vector<string>& names){
2225         try {
2226         names.clear();
2227                 ifstream in;
2228                 openInputFile(accnosfile, in);
2229                 string name;
2230                 
2231         string rest = "";
2232         char buffer[4096];
2233         
2234                 while (!in.eof()) {
2235                         if (control_pressed) { break; }
2236                         
2237             in.read(buffer, 4096);
2238             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2239             
2240             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.push_back(pieces[i]);  }
2241         }
2242                 in.close();     
2243         
2244         if (rest != "") {
2245             vector<string> pieces = splitWhiteSpace(rest);
2246             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.push_back(pieces[i]);  }
2247         }
2248                 
2249                 return 0;
2250         }
2251         catch(exception& e) {
2252                 errorOut(e, "MothurOut", "readAccnos");
2253                 exit(1);
2254         }
2255 }
2256 /***********************************************************************/
2257
2258 int MothurOut::getNumNames(string names){
2259         try {
2260                 int count = 0;
2261                 
2262                 if(names != ""){
2263                         count = 1;
2264                         for(int i=0;i<names.size();i++){
2265                                 if(names[i] == ','){
2266                                         count++;
2267                                 }
2268                         }
2269                 }
2270                 
2271                 return count;
2272         }
2273         catch(exception& e) {
2274                 errorOut(e, "MothurOut", "getNumNames");
2275                 exit(1);
2276         }
2277 }
2278 /***********************************************************************/
2279
2280 int MothurOut::getNumChar(string line, char c){
2281         try {
2282                 int count = 0;
2283                 
2284                 if(line != ""){
2285                         for(int i=0;i<line.size();i++){
2286                                 if(line[i] == c){
2287                                         count++;
2288                                 }
2289                         }
2290                 }
2291                 
2292                 return count;
2293         }
2294         catch(exception& e) {
2295                 errorOut(e, "MothurOut", "getNumChar");
2296                 exit(1);
2297         }
2298 }
2299 //**********************************************************************************************************************
2300 bool MothurOut::isSubset(vector<string> bigset, vector<string> subset) {
2301         try {
2302                 
2303         
2304                 if (subset.size() > bigset.size()) { return false;  }
2305                 
2306                 //check if each guy in suset is also in bigset
2307                 for (int i = 0; i < subset.size(); i++) {
2308                         bool match = false;
2309                         for (int j = 0; j < bigset.size(); j++) {
2310                                 if (subset[i] == bigset[j]) { match = true; break; }
2311                         }
2312                         
2313                         //you have a guy in subset that had no match in bigset
2314                         if (match == false) { return false; }
2315                 }
2316                 
2317                 return true;
2318         
2319         }
2320         catch(exception& e) {
2321                 errorOut(e, "MothurOut", "isSubset");
2322                 exit(1);
2323         }
2324 }
2325 /***********************************************************************/
2326 int MothurOut::mothurRemove(string filename){
2327         try {
2328                 filename = getFullPathName(filename);
2329                 int error = remove(filename.c_str());
2330                 //if (error != 0) { 
2331                 //      if (errno != ENOENT) { //ENOENT == file does not exist
2332                 //              string message = "Error deleting file " + filename;
2333                 //              perror(message.c_str()); 
2334                 //      }
2335                 //}
2336                 return error;
2337         }
2338         catch(exception& e) {
2339                 errorOut(e, "MothurOut", "mothurRemove");
2340                 exit(1);
2341         }
2342 }
2343 /***********************************************************************/
2344 bool MothurOut::mothurConvert(string item, int& num){
2345         try {
2346                 bool error = false;
2347                 
2348                 if (isNumeric1(item)) {
2349                         convert(item, num);
2350                 }else {
2351                         num = 0;
2352                         error = true;
2353                         mothurOut("[ERROR]: cannot convert " + item + " to an integer."); mothurOutEndLine();
2354                         commandInputsConvertError = true;
2355                 }
2356                 
2357                 return error;
2358         }
2359         catch(exception& e) {
2360                 errorOut(e, "MothurOut", "mothurConvert");
2361                 exit(1);
2362         }
2363 }
2364 /***********************************************************************/
2365 bool MothurOut::mothurConvert(string item, intDist& num){
2366         try {
2367                 bool error = false;
2368                 
2369                 if (isNumeric1(item)) {
2370                         convert(item, num);
2371                 }else {
2372                         num = 0;
2373                         error = true;
2374                         mothurOut("[ERROR]: cannot convert " + item + " to an integer."); mothurOutEndLine();
2375                         commandInputsConvertError = true;
2376                 }
2377                 
2378                 return error;
2379         }
2380         catch(exception& e) {
2381                 errorOut(e, "MothurOut", "mothurConvert");
2382                 exit(1);
2383         }
2384 }
2385
2386 /***********************************************************************/
2387 bool MothurOut::isNumeric1(string stringToCheck){
2388         try {
2389                 bool numeric = false;
2390                 
2391                 if(stringToCheck.find_first_not_of("0123456789.-") == string::npos) { numeric = true; }
2392                         
2393                 return numeric;
2394         }
2395         catch(exception& e) {
2396                 errorOut(e, "MothurOut", "isNumeric1");
2397                 exit(1);
2398         }
2399         
2400 }
2401 /***********************************************************************/
2402 bool MothurOut::mothurConvert(string item, float& num){
2403         try {
2404                 bool error = false;
2405                 
2406                 if (isNumeric1(item)) {
2407                         convert(item, num);
2408                 }else {
2409                         num = 0;
2410                         error = true;
2411                         mothurOut("[ERROR]: cannot convert " + item + " to a float."); mothurOutEndLine();
2412                         commandInputsConvertError = true;
2413                 }
2414                 
2415                 return error;
2416         }
2417         catch(exception& e) {
2418                 errorOut(e, "MothurOut", "mothurConvert");
2419                 exit(1);
2420         }
2421 }
2422 /***********************************************************************/
2423 bool MothurOut::mothurConvert(string item, double& num){
2424         try {
2425                 bool error = false;
2426                 
2427                 if (isNumeric1(item)) {
2428                         convert(item, num);
2429                 }else {
2430                         num = 0;
2431                         error = true;
2432                         mothurOut("[ERROR]: cannot convert " + item + " to a double."); mothurOutEndLine();
2433                         commandInputsConvertError = true;
2434                 }
2435                 
2436                 return error;
2437         }
2438         catch(exception& e) {
2439                 errorOut(e, "MothurOut", "mothurConvert");
2440                 exit(1);
2441         }
2442 }
2443 /**************************************************************************************************/
2444
2445 vector<vector<double> > MothurOut::binomial(int maxOrder){
2446         try {
2447         vector<vector<double> > binomial(maxOrder+1);
2448         
2449     for(int i=0;i<=maxOrder;i++){
2450                 binomial[i].resize(maxOrder+1);
2451                 binomial[i][0]=1;
2452                 binomial[0][i]=0;
2453     }
2454     binomial[0][0]=1;
2455         
2456     binomial[1][0]=1;
2457     binomial[1][1]=1;
2458         
2459     for(int i=2;i<=maxOrder;i++){
2460                 binomial[1][i]=0;
2461     }
2462         
2463     for(int i=2;i<=maxOrder;i++){
2464                 for(int j=1;j<=maxOrder;j++){
2465                         if(i==j){       binomial[i][j]=1;                                                                       }
2466                         if(j>i) {       binomial[i][j]=0;                                                                       }
2467                         else    {       binomial[i][j]=binomial[i-1][j-1]+binomial[i-1][j];     }
2468                 }
2469     }
2470         
2471         return binomial;
2472         
2473         }
2474         catch(exception& e) {
2475                 errorOut(e, "MothurOut", "binomial");
2476                 exit(1);
2477         }
2478 }
2479 /**************************************************************************************************/
2480 unsigned int MothurOut::fromBase36(string base36){
2481         try {
2482                 unsigned int num = 0;
2483                 
2484                 map<char, int> converts;
2485                 converts['A'] = 0;
2486                 converts['a'] = 0;
2487                 converts['B'] = 1;
2488                 converts['b'] = 1;
2489                 converts['C'] = 2;
2490                 converts['c'] = 2;
2491                 converts['D'] = 3;
2492                 converts['d'] = 3;
2493                 converts['E'] = 4;
2494                 converts['e'] = 4;
2495                 converts['F'] = 5;
2496                 converts['f'] = 5;
2497                 converts['G'] = 6;
2498                 converts['g'] = 6;
2499                 converts['H'] = 7;
2500                 converts['h'] = 7;
2501                 converts['I'] = 8;
2502                 converts['i'] = 8;
2503                 converts['J'] = 9;
2504                 converts['j'] = 9;
2505                 converts['K'] = 10;
2506                 converts['k'] = 10;
2507                 converts['L'] = 11;
2508                 converts['l'] = 11;
2509                 converts['M'] = 12;
2510                 converts['m'] = 12;
2511                 converts['N'] = 13;
2512                 converts['n'] = 13;
2513                 converts['O'] = 14;
2514                 converts['o'] = 14;
2515                 converts['P'] = 15;
2516                 converts['p'] = 15;
2517                 converts['Q'] = 16;
2518                 converts['q'] = 16;
2519                 converts['R'] = 17;
2520                 converts['r'] = 17;
2521                 converts['S'] = 18;
2522                 converts['s'] = 18;
2523                 converts['T'] = 19;
2524                 converts['t'] = 19;
2525                 converts['U'] = 20;
2526                 converts['u'] = 20;
2527                 converts['V'] = 21;
2528                 converts['v'] = 21;
2529                 converts['W'] = 22;
2530                 converts['w'] = 22;
2531                 converts['X'] = 23;
2532                 converts['x'] = 23;
2533                 converts['Y'] = 24;
2534                 converts['y'] = 24;
2535                 converts['Z'] = 25;
2536                 converts['z'] = 25;
2537                 converts['0'] = 26;
2538                 converts['1'] = 27;
2539                 converts['2'] = 28;
2540                 converts['3'] = 29;
2541                 converts['4'] = 30;
2542                 converts['5'] = 31;
2543                 converts['6'] = 32;
2544                 converts['7'] = 33;
2545                 converts['8'] = 34;
2546                 converts['9'] = 35;             
2547                 
2548                 int i = 0;
2549                 while (i < base36.length()) {
2550                         char c = base36[i];
2551                         num = 36 * num + converts[c];
2552                         i++;
2553                 }
2554                 
2555                 return num;
2556                 
2557         }
2558         catch(exception& e) {
2559                 errorOut(e, "MothurOut", "fromBase36");
2560                 exit(1);
2561         }
2562 }
2563 /***********************************************************************/
2564
2565 int MothurOut::factorial(int num){
2566         try {
2567                 int total = 1;
2568                 
2569                 for (int i = 1; i <= num; i++) {
2570                         total *= i;
2571                 }
2572                 
2573                 return total;
2574         }
2575         catch(exception& e) {
2576                 errorOut(e, "MothurOut", "factorial");
2577                 exit(1);
2578         }
2579 }
2580 /***********************************************************************/
2581
2582 int MothurOut::getNumSeqs(ifstream& file){
2583         try {
2584                 int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
2585                 file.seekg(0);
2586                 return numSeqs;
2587         }
2588         catch(exception& e) {
2589                 errorOut(e, "MothurOut", "getNumSeqs");
2590                 exit(1);
2591         }       
2592 }
2593 /***********************************************************************/
2594 void MothurOut::getNumSeqs(ifstream& file, int& numSeqs){
2595         try {
2596                 string input;
2597                 numSeqs = 0;
2598                 while(!file.eof()){
2599                         input = getline(file);
2600                         if (input.length() != 0) {
2601                                 if(input[0] == '>'){ numSeqs++; }
2602                         }
2603                 }
2604         }
2605         catch(exception& e) {
2606                 errorOut(e, "MothurOut", "getNumSeqs");
2607                 exit(1);
2608         }       
2609 }
2610 /***********************************************************************/
2611
2612 //This function parses the estimator options and puts them in a vector
2613 void MothurOut::splitAtChar(string& estim, vector<string>& container, char symbol) {
2614         try {
2615         
2616         if (symbol == '-') { splitAtDash(estim, container); return; }
2617         
2618                 string individual = "";
2619                 int estimLength = estim.size();
2620                 for(int i=0;i<estimLength;i++){
2621                         if(estim[i] == symbol){
2622                                 container.push_back(individual);
2623                                 individual = "";                                
2624                         }
2625                         else{
2626                                 individual += estim[i];
2627                         }
2628                 }
2629                 container.push_back(individual);
2630
2631         }
2632         catch(exception& e) {
2633                 errorOut(e, "MothurOut", "splitAtChar");
2634                 exit(1);
2635         }       
2636 }
2637
2638 /***********************************************************************/
2639
2640 //This function parses the estimator options and puts them in a vector
2641 void MothurOut::splitAtDash(string& estim, vector<string>& container) {
2642         try {
2643                 string individual = "";
2644                 int estimLength = estim.size();
2645                 bool prevEscape = false;
2646                 for(int i=0;i<estimLength;i++){
2647                         if(prevEscape){
2648                                 individual += estim[i];
2649                                 prevEscape = false;
2650                         }
2651                         else{
2652                                 if(estim[i] == '\\'){
2653                                         prevEscape = true;
2654                                 }
2655                                 else if(estim[i] == '-'){
2656                                         container.push_back(individual);
2657                                         individual = "";
2658                                         prevEscape = false;                             
2659                                 }
2660                                 else{
2661                                         individual += estim[i];
2662                                         prevEscape = false;
2663                                 }
2664                         }
2665                 }
2666                 container.push_back(individual);
2667         }
2668         catch(exception& e) {
2669                 errorOut(e, "MothurOut", "splitAtDash");
2670                 exit(1);
2671         }       
2672 }
2673
2674 /***********************************************************************/
2675 //This function parses the label options and puts them in a set
2676 void MothurOut::splitAtDash(string& estim, set<string>& container) {
2677         try {
2678                 string individual = "";
2679                 int estimLength = estim.size();
2680                 bool prevEscape = false;
2681                 for(int i=0;i<estimLength;i++){
2682                         if(prevEscape){
2683                                 individual += estim[i];
2684                                 prevEscape = false;
2685                         }
2686                         else{
2687                                 if(estim[i] == '\\'){
2688                                         prevEscape = true;
2689                                 }
2690                                 else if(estim[i] == '-'){
2691                                         container.insert(individual);
2692                                         individual = "";
2693                                         prevEscape = false;                             
2694                                 }
2695                                 else{
2696                                         individual += estim[i];
2697                                         prevEscape = false;
2698                                 }
2699                         }
2700                 }
2701                 container.insert(individual);
2702         
2703         }
2704         catch(exception& e) {
2705                 errorOut(e, "MothurOut", "splitAtDash");
2706                 exit(1);
2707         }       
2708 }
2709 /***********************************************************************/
2710 //This function parses the line options and puts them in a set
2711 void MothurOut::splitAtDash(string& estim, set<int>& container) {
2712         try {
2713                 string individual = "";
2714                 int lineNum;
2715                 int estimLength = estim.size();
2716                 bool prevEscape = false;
2717                 for(int i=0;i<estimLength;i++){
2718                         if(prevEscape){
2719                                 individual += estim[i];
2720                                 prevEscape = false;
2721                         }
2722                         else{
2723                                 if(estim[i] == '\\'){
2724                                         prevEscape = true;
2725                                 }
2726                                 else if(estim[i] == '-'){
2727                                         convert(individual, lineNum); //convert the string to int
2728                                         container.insert(lineNum);
2729                                         individual = "";
2730                                         prevEscape = false;                             
2731                                 }
2732                                 else{
2733                                         individual += estim[i];
2734                                         prevEscape = false;
2735                                 }
2736                         }
2737                 }
2738                 convert(individual, lineNum); //convert the string to int
2739                 container.insert(lineNum);
2740         }
2741         catch(exception& e) {
2742                 errorOut(e, "MothurOut", "splitAtDash");
2743                 exit(1);
2744         }       
2745 }
2746 /***********************************************************************/
2747 string MothurOut::makeList(vector<string>& names) {
2748         try {
2749                 string list = "";
2750         
2751         if (names.size() == 0) { return list; }
2752                 
2753         for (int i = 0; i < names.size()-1; i++) { list += names[i] + ",";  }
2754         
2755         //get last name
2756         list += names[names.size()-1];
2757         
2758         return list;
2759     }
2760         catch(exception& e) {
2761                 errorOut(e, "MothurOut", "makeList");
2762                 exit(1);
2763         }       
2764 }
2765
2766 /***********************************************************************/
2767 //This function parses the a string and puts peices in a vector
2768 void MothurOut::splitAtComma(string& estim, vector<string>& container) {
2769         try {
2770                 string individual = "";
2771                 int estimLength = estim.size();
2772                 for(int i=0;i<estimLength;i++){
2773                         if(estim[i] == ','){
2774                                 container.push_back(individual);
2775                                 individual = "";                                
2776                         }
2777                         else{
2778                                 individual += estim[i];
2779                         }
2780                 }
2781                 container.push_back(individual);
2782                 
2783                 
2784                 
2785                 
2786 //              string individual;
2787 //              
2788 //              while (estim.find_first_of(',') != -1) {
2789 //                      individual = estim.substr(0,estim.find_first_of(','));
2790 //                      if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
2791 //                              estim = estim.substr(estim.find_first_of(',')+1, estim.length());
2792 //                              container.push_back(individual);
2793 //                      }
2794 //              }
2795 //              //get last one
2796 //              container.push_back(estim);
2797         }
2798         catch(exception& e) {
2799                 errorOut(e, "MothurOut", "splitAtComma");
2800                 exit(1);
2801         }       
2802 }
2803 /***********************************************************************/
2804 //This function splits up the various option parameters
2805 void MothurOut::splitAtChar(string& prefix, string& suffix, char c){
2806         try {
2807                 prefix = suffix.substr(0,suffix.find_first_of(c));
2808                 if ((suffix.find_first_of(c)+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
2809                         suffix = suffix.substr(suffix.find_first_of(c)+1, suffix.length());
2810                         string space = " ";
2811                         while(suffix.at(0) == ' ')
2812                                 suffix = suffix.substr(1, suffix.length());
2813                 }
2814         
2815         }
2816         catch(exception& e) {
2817                 errorOut(e, "MothurOut", "splitAtComma");
2818                 exit(1);
2819         }       
2820 }
2821
2822 /***********************************************************************/
2823
2824 //This function splits up the various option parameters
2825 void MothurOut::splitAtComma(string& prefix, string& suffix){
2826         try {
2827                 prefix = suffix.substr(0,suffix.find_first_of(','));
2828                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
2829                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
2830                         string space = " ";
2831                         while(suffix.at(0) == ' ')
2832                                 suffix = suffix.substr(1, suffix.length());
2833                 }
2834
2835         }
2836         catch(exception& e) {
2837                 errorOut(e, "MothurOut", "splitAtComma");
2838                 exit(1);
2839         }       
2840 }
2841 /***********************************************************************/
2842
2843 //This function separates the key value from the option value i.e. dist=96_...
2844 void MothurOut::splitAtEquals(string& key, string& value){              
2845         try {
2846                 if(value.find_first_of('=') != -1){
2847                         key = value.substr(0,value.find_first_of('='));
2848                         if ((value.find_first_of('=')+1) <= value.length()) {
2849                                 value = value.substr(value.find_first_of('=')+1, value.length());
2850                         }
2851                 }else{
2852                         key = value;
2853                         value = 1;
2854                 }
2855         }
2856         catch(exception& e) {
2857                 errorOut(e, "MothurOut", "splitAtEquals");
2858                 exit(1);
2859         }       
2860 }
2861
2862 /**************************************************************************************************/
2863
2864 bool MothurOut::inUsersGroups(string groupname, vector<string> Groups) {
2865         try {
2866                 for (int i = 0; i < Groups.size(); i++) {
2867                         if (groupname == Groups[i]) { return true; }
2868                 }
2869                 return false;
2870         }
2871         catch(exception& e) {
2872                 errorOut(e, "MothurOut", "inUsersGroups");
2873                 exit(1);
2874         }       
2875 }
2876 /**************************************************************************************************/
2877
2878 bool MothurOut::inUsersGroups(vector<int> set, vector< vector<int> > sets) {
2879         try {
2880                 for (int i = 0; i < sets.size(); i++) {
2881                         if (set == sets[i]) { return true; }
2882                 }
2883                 return false;
2884         }
2885         catch(exception& e) {
2886                 errorOut(e, "MothurOut", "inUsersGroups");
2887                 exit(1);
2888         }       
2889 }
2890 /**************************************************************************************************/
2891
2892 bool MothurOut::inUsersGroups(int groupname, vector<int> Groups) {
2893         try {
2894                 for (int i = 0; i < Groups.size(); i++) {
2895                         if (groupname == Groups[i]) { return true; }
2896                 }
2897                 return false;
2898         }
2899         catch(exception& e) {
2900                 errorOut(e, "MothurOut", "inUsersGroups");
2901                 exit(1);
2902         }       
2903 }
2904
2905 /**************************************************************************************************/
2906 //returns true if any of the strings in first vector are in second vector
2907 bool MothurOut::inUsersGroups(vector<string> groupnames, vector<string> Groups) {
2908         try {
2909                 
2910                 for (int i = 0; i < groupnames.size(); i++) {
2911                         if (inUsersGroups(groupnames[i], Groups)) { return true; }
2912                 }
2913                 return false;
2914         }
2915         catch(exception& e) {
2916                 errorOut(e, "MothurOut", "inUsersGroups");
2917                 exit(1);
2918         }       
2919 }
2920 /***********************************************************************/
2921 //this function determines if the user has given us labels that are smaller than the given label.
2922 //if so then it returns true so that the calling function can run the previous valid distance.
2923 //it's a "smart" distance function.  It also checks for invalid labels.
2924 bool MothurOut::anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
2925         try {
2926                 
2927                 set<string>::iterator it;
2928                 vector<float> orderFloat;
2929                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
2930                 map<string, float>::iterator it2;
2931                 float labelFloat;
2932                 bool smaller = false;
2933                 
2934                 //unique is the smallest line
2935                 if (label == "unique") {  return false;  }
2936                 else { 
2937                         if (convertTestFloat(label, labelFloat)) {
2938                                 convert(label, labelFloat); 
2939                         }else { //cant convert 
2940                                 return false;
2941                         }
2942                 }
2943                 
2944                 //go through users set and make them floats
2945                 for(it = userLabels.begin(); it != userLabels.end();) {
2946                         
2947                         float temp;
2948                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
2949                                 convert(*it, temp);
2950                                 orderFloat.push_back(temp);
2951                                 userMap[*it] = temp;
2952                                 it++;
2953                         }else if (*it == "unique") { 
2954                                 orderFloat.push_back(-1.0);
2955                                 userMap["unique"] = -1.0;
2956                                 it++;
2957                         }else {
2958                                 if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
2959                                 userLabels.erase(it++); 
2960                         }
2961                 }
2962                 
2963                 //sort order
2964                 sort(orderFloat.begin(), orderFloat.end());
2965                 
2966                 /*************************************************/
2967                 //is this label bigger than any of the users labels
2968                 /*************************************************/
2969                                 
2970                 //loop through order until you find a label greater than label
2971                 for (int i = 0; i < orderFloat.size(); i++) {
2972                         if (orderFloat[i] < labelFloat) {
2973                                 smaller = true;
2974                                 if (orderFloat[i] == -1) { 
2975                                         if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
2976                                         userLabels.erase("unique");
2977                                 }
2978                                 else {  
2979                                         if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
2980                                         string s = "";
2981                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
2982                                                 if (it2->second == orderFloat[i]) {  
2983                                                         s = it2->first;  
2984                                                         //remove small labels
2985                                                         userLabels.erase(s);
2986                                                         break;
2987                                                 }
2988                                         }
2989                                         if (errorOff == "") {mothurOut( s +  ". I will use the next smallest distance. "); mothurOutEndLine(); }
2990                                 }
2991                         //since they are sorted once you find a bigger one stop looking
2992                         }else { break; }
2993                 }
2994                 
2995                 return smaller;
2996                                                 
2997         }
2998         catch(exception& e) {
2999                 errorOut(e, "MothurOut", "anyLabelsToProcess");
3000                 exit(1);
3001         }       
3002 }
3003
3004 /**************************************************************************************************/
3005 bool MothurOut::checkReleaseVersion(ifstream& file, string version) {
3006         try {
3007                 
3008                 bool good = true;
3009                 
3010                 string line = getline(file);  
3011
3012                 //before we added this check
3013                 if (line[0] != '#') {  good = false;  }
3014                 else {
3015                         //rip off #
3016                         line = line.substr(1);
3017                         
3018                         vector<string> versionVector;
3019                         splitAtChar(version, versionVector, '.');
3020                         
3021                         //check file version
3022                         vector<string> linesVector;
3023                         splitAtChar(line, linesVector, '.');
3024                         
3025                         if (versionVector.size() != linesVector.size()) { good = false; }
3026                         else {
3027                                 for (int j = 0; j < versionVector.size(); j++) {
3028                                         int num1, num2;
3029                                         convert(versionVector[j], num1);
3030                                         convert(linesVector[j], num2);
3031                                         
3032                                         //if mothurs version is newer than this files version, then we want to remake it
3033                                         if (num1 > num2) {  good = false; break;  }
3034                                 }
3035                         }
3036                         
3037                 }
3038                 
3039                 if (!good) {  file.close();  }
3040                 else { file.seekg(0);  }
3041                 
3042                 return good;
3043         }
3044         catch(exception& e) {
3045                 errorOut(e, "MothurOut", "checkReleaseVersion");                
3046                 exit(1);
3047         }
3048 }
3049 /**************************************************************************************************/
3050 vector<double> MothurOut::getAverages(vector< vector<double> >& dists) {
3051         try{
3052         vector<double> averages; //averages.resize(numComp, 0.0);
3053         for (int i = 0; i < dists[0].size(); i++) { averages.push_back(0.0); }
3054       
3055         for (int thisIter = 0; thisIter < dists.size(); thisIter++) {
3056             for (int i = 0; i < dists[thisIter].size(); i++) {  
3057                 averages[i] += dists[thisIter][i];
3058             }
3059         }
3060         
3061         //finds average.
3062         for (int i = 0; i < averages.size(); i++) {  averages[i] /= (double) dists.size(); }
3063         
3064         return averages;
3065     }
3066         catch(exception& e) {
3067                 errorOut(e, "MothurOut", "getAverages");                
3068                 exit(1);
3069         }
3070 }
3071 /**************************************************************************************************/
3072 vector<double> MothurOut::getStandardDeviation(vector< vector<double> >& dists) {
3073         try{
3074         
3075         vector<double> averages = getAverages(dists);
3076         
3077         //find standard deviation
3078         vector<double> stdDev; //stdDev.resize(numComp, 0.0);
3079         for (int i = 0; i < dists[0].size(); i++) { stdDev.push_back(0.0); }
3080         
3081         for (int thisIter = 0; thisIter < dists.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3082             for (int j = 0; j < dists[thisIter].size(); j++) {
3083                 stdDev[j] += ((dists[thisIter][j] - averages[j]) * (dists[thisIter][j] - averages[j]));
3084             }
3085         }
3086         for (int i = 0; i < stdDev.size(); i++) {  
3087             stdDev[i] /= (double) dists.size(); 
3088             stdDev[i] = sqrt(stdDev[i]);
3089         }
3090         
3091         return stdDev;
3092     }
3093         catch(exception& e) {
3094                 errorOut(e, "MothurOut", "getAverages");                
3095                 exit(1);
3096         }
3097 }
3098 /**************************************************************************************************/
3099 vector<double> MothurOut::getStandardDeviation(vector< vector<double> >& dists, vector<double>& averages) {
3100         try{
3101         //find standard deviation
3102         vector<double> stdDev; //stdDev.resize(numComp, 0.0);
3103         for (int i = 0; i < dists[0].size(); i++) { stdDev.push_back(0.0); }
3104         
3105         for (int thisIter = 0; thisIter < dists.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3106             for (int j = 0; j < dists[thisIter].size(); j++) {
3107                 stdDev[j] += ((dists[thisIter][j] - averages[j]) * (dists[thisIter][j] - averages[j]));
3108             }
3109         }
3110         for (int i = 0; i < stdDev.size(); i++) {  
3111             stdDev[i] /= (double) dists.size(); 
3112             stdDev[i] = sqrt(stdDev[i]);
3113         }
3114         
3115         return stdDev;
3116     }
3117         catch(exception& e) {
3118                 errorOut(e, "MothurOut", "getAverages");                
3119                 exit(1);
3120         }
3121 }
3122 /**************************************************************************************************/
3123 vector< vector<seqDist> > MothurOut::getAverages(vector< vector< vector<seqDist> > >& calcDistsTotals, string mode) {
3124         try{
3125         
3126         vector< vector<seqDist>  > calcAverages; //calcAverages.resize(calcDistsTotals[0].size()); 
3127         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3128             //calcAverages[i].resize(calcDistsTotals[0][i].size());
3129             vector<seqDist> temp;
3130             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3131                 seqDist tempDist;
3132                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3133                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3134                 tempDist.dist = 0.0;
3135                 temp.push_back(tempDist);
3136             }
3137             calcAverages.push_back(temp);
3138         }
3139         
3140         if (mode == "average") {
3141             for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //sum all groups dists for each calculator
3142                 for (int i = 0; i < calcAverages.size(); i++) {  //initialize sums to zero.
3143                     for (int j = 0; j < calcAverages[i].size(); j++) {
3144                         calcAverages[i][j].dist += calcDistsTotals[thisIter][i][j].dist;
3145                     }
3146                 }
3147             }
3148             
3149             for (int i = 0; i < calcAverages.size(); i++) {  //finds average.
3150                 for (int j = 0; j < calcAverages[i].size(); j++) {
3151                     calcAverages[i][j].dist /= (float) calcDistsTotals.size();
3152                 }
3153             }
3154         }else { //find median
3155             for (int i = 0; i < calcAverages.size(); i++) { //for each calc
3156                 for (int j = 0; j < calcAverages[i].size(); j++) {  //for each comparison
3157                     vector<double> dists;
3158                     for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //for each subsample
3159                         dists.push_back(calcDistsTotals[thisIter][i][j].dist);
3160                     }
3161                     sort(dists.begin(), dists.end());
3162                     calcAverages[i][j].dist = dists[(calcDistsTotals.size()/2)];
3163                 }
3164             }
3165         }
3166
3167         return calcAverages;
3168     }
3169         catch(exception& e) {
3170                 errorOut(e, "MothurOut", "getAverages");                
3171                 exit(1);
3172         }
3173 }
3174 /**************************************************************************************************/
3175 vector< vector<seqDist> > MothurOut::getAverages(vector< vector< vector<seqDist> > >& calcDistsTotals) {
3176         try{
3177         
3178         vector< vector<seqDist>  > calcAverages; //calcAverages.resize(calcDistsTotals[0].size()); 
3179         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3180             //calcAverages[i].resize(calcDistsTotals[0][i].size());
3181             vector<seqDist> temp;
3182             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3183                 seqDist tempDist;
3184                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3185                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3186                 tempDist.dist = 0.0;
3187                 temp.push_back(tempDist);
3188             }
3189             calcAverages.push_back(temp);
3190         }
3191         
3192         
3193         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //sum all groups dists for each calculator
3194                 for (int i = 0; i < calcAverages.size(); i++) {  //initialize sums to zero.
3195                     for (int j = 0; j < calcAverages[i].size(); j++) {
3196                         calcAverages[i][j].dist += calcDistsTotals[thisIter][i][j].dist;
3197                     }
3198                 }
3199         }
3200             
3201         for (int i = 0; i < calcAverages.size(); i++) {  //finds average.
3202                 for (int j = 0; j < calcAverages[i].size(); j++) {
3203                     calcAverages[i][j].dist /= (float) calcDistsTotals.size();
3204                 }
3205         }
3206         
3207         return calcAverages;
3208     }
3209         catch(exception& e) {
3210                 errorOut(e, "MothurOut", "getAverages");                
3211                 exit(1);
3212         }
3213 }
3214 /**************************************************************************************************/
3215 vector< vector<seqDist> > MothurOut::getStandardDeviation(vector< vector< vector<seqDist> > >& calcDistsTotals) {
3216         try{
3217         
3218         vector< vector<seqDist> > calcAverages = getAverages(calcDistsTotals);
3219         
3220         //find standard deviation
3221         vector< vector<seqDist>  > stdDev;  
3222         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3223             vector<seqDist> temp;
3224             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3225                 seqDist tempDist;
3226                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3227                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3228                 tempDist.dist = 0.0;
3229                 temp.push_back(tempDist);
3230             }
3231             stdDev.push_back(temp);
3232         }
3233         
3234         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3235             for (int i = 0; i < stdDev.size(); i++) {  
3236                 for (int j = 0; j < stdDev[i].size(); j++) {
3237                     stdDev[i][j].dist += ((calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist) * (calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist));
3238                 }
3239             }
3240         }
3241         
3242         for (int i = 0; i < stdDev.size(); i++) {  //finds average.
3243             for (int j = 0; j < stdDev[i].size(); j++) {
3244                 stdDev[i][j].dist /= (float) calcDistsTotals.size();
3245                 stdDev[i][j].dist = sqrt(stdDev[i][j].dist);
3246             }
3247         }
3248
3249         return stdDev;
3250     }
3251         catch(exception& e) {
3252                 errorOut(e, "MothurOut", "getAverages");                
3253                 exit(1);
3254         }
3255 }
3256 /**************************************************************************************************/
3257 vector< vector<seqDist> > MothurOut::getStandardDeviation(vector< vector< vector<seqDist> > >& calcDistsTotals, vector< vector<seqDist> >& calcAverages) {
3258         try{
3259         //find standard deviation
3260         vector< vector<seqDist>  > stdDev;  
3261         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3262             vector<seqDist> temp;
3263             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3264                 seqDist tempDist;
3265                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3266                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3267                 tempDist.dist = 0.0;
3268                 temp.push_back(tempDist);
3269             }
3270             stdDev.push_back(temp);
3271         }
3272         
3273         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3274             for (int i = 0; i < stdDev.size(); i++) {  
3275                 for (int j = 0; j < stdDev[i].size(); j++) {
3276                     stdDev[i][j].dist += ((calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist) * (calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist));
3277                 }
3278             }
3279         }
3280         
3281         for (int i = 0; i < stdDev.size(); i++) {  //finds average.
3282             for (int j = 0; j < stdDev[i].size(); j++) {
3283                 stdDev[i][j].dist /= (float) calcDistsTotals.size();
3284                 stdDev[i][j].dist = sqrt(stdDev[i][j].dist);
3285             }
3286         }
3287         
3288         return stdDev;
3289     }
3290         catch(exception& e) {
3291                 errorOut(e, "MothurOut", "getAverages");                
3292                 exit(1);
3293         }
3294 }
3295
3296 /**************************************************************************************************/
3297 bool MothurOut::isContainingOnlyDigits(string input) {
3298         try{
3299                 
3300                 //are you a digit in ascii code
3301                 for (int i = 0;i < input.length(); i++){
3302                         if( input[i]>47 && input[i]<58){}
3303                         else { return false; }
3304                 }
3305                 
3306                 return true;
3307         }
3308         catch(exception& e) {
3309                 errorOut(e, "MothurOut", "isContainingOnlyDigits");             
3310                 exit(1);
3311         }
3312 }
3313 /**************************************************************************************************/
3314 int MothurOut::removeConfidences(string& tax) {
3315         try {
3316                 
3317                 string taxon;
3318                 string newTax = "";
3319                 
3320                 while (tax.find_first_of(';') != -1) {
3321                         
3322                         if (control_pressed) { return 0; }
3323                         
3324                         //get taxon
3325                         taxon = tax.substr(0,tax.find_first_of(';'));
3326         
3327                         int pos = taxon.find_last_of('(');
3328                         if (pos != -1) {
3329                                 //is it a number?
3330                                 int pos2 = taxon.find_last_of(')');
3331                                 if (pos2 != -1) {
3332                                         string confidenceScore = taxon.substr(pos+1, (pos2-(pos+1)));
3333                                         if (isNumeric1(confidenceScore)) {
3334                                                 taxon = taxon.substr(0, pos); //rip off confidence 
3335                                         }
3336                                 }
3337                         }
3338                         taxon += ";";
3339                         
3340                         tax = tax.substr(tax.find_first_of(';')+1, tax.length());
3341                         newTax += taxon;
3342                 }
3343                 
3344                 tax = newTax;
3345                 
3346                 return 0;
3347         }
3348         catch(exception& e) {
3349                 errorOut(e, "MothurOut", "removeConfidences");
3350                 exit(1);
3351         }
3352 }
3353 /**************************************************************************************************/
3354 string MothurOut::removeQuotes(string tax) {
3355         try {
3356                 
3357                 string taxon;
3358                 string newTax = "";
3359                 
3360                 for (int i = 0; i < tax.length(); i++) {
3361                         
3362                         if (control_pressed) { return newTax; }
3363             
3364             if ((tax[i] != '\'') && (tax[i] != '\"')) { newTax += tax[i]; }
3365                         
3366         }
3367                 
3368                 return newTax;
3369         }
3370         catch(exception& e) {
3371                 errorOut(e, "MothurOut", "removeQuotes");
3372                 exit(1);
3373         }
3374 }
3375 /**************************************************************************************************/
3376 // function for calculating standard deviation
3377 double MothurOut::getStandardDeviation(vector<int>& featureVector){
3378     try {
3379         //finds sum
3380         double average = 0; 
3381         for (int i = 0; i < featureVector.size(); i++) { average += featureVector[i]; }
3382         average /= (double) featureVector.size();
3383         
3384         //find standard deviation
3385         double stdDev = 0;
3386         for (int i = 0; i < featureVector.size(); i++) { //compute the difference of each dist from the mean, and square the result of each
3387             stdDev += ((featureVector[i] - average) * (featureVector[i] - average));
3388         }
3389           
3390         stdDev /= (double) featureVector.size(); 
3391         stdDev = sqrt(stdDev);
3392         
3393         return stdDev;
3394     }
3395         catch(exception& e) {
3396                 errorOut(e, "MothurOut", "getStandardDeviation");
3397                 exit(1);
3398         }
3399 }
3400 /**************************************************************************************************/
3401
3402
3403