]> git.donarmstrong.com Git - mothur.git/blob - mothurout.cpp
added *.count.summary file to count.groups command. added deltaq and insert parameter...
[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
1434 vector<unsigned long long> MothurOut::divideFilePerLine(string filename, int& proc) {
1435         try{
1436                 vector<unsigned long long> filePos;
1437                 filePos.push_back(0);
1438                 
1439                 FILE * pFile;
1440                 unsigned long long size;
1441                 
1442                 filename = getFullPathName(filename);
1443         
1444                 //get num bytes in file
1445                 pFile = fopen (filename.c_str(),"rb");
1446                 if (pFile==NULL) perror ("Error opening file");
1447                 else{
1448                         fseek (pFile, 0, SEEK_END);
1449                         size=ftell (pFile);
1450                         fclose (pFile);
1451                 }
1452                 
1453 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
1454         
1455                 //estimate file breaks
1456                 unsigned long long chunkSize = 0;
1457                 chunkSize = size / proc;
1458         
1459                 //file to small to divide by processors
1460                 if (chunkSize == 0)  {  proc = 1;       filePos.push_back(size); return filePos;        }
1461         
1462                 //for each process seekg to closest file break and search for next '>' char. make that the filebreak
1463                 for (int i = 0; i < proc; i++) {
1464                         unsigned long long spot = (i+1) * chunkSize;
1465                         
1466                         ifstream in;
1467                         openInputFile(filename, in);
1468                         in.seekg(spot);
1469                         
1470                         //look for next line break
1471                         unsigned long long newSpot = spot;
1472                         while (!in.eof()) {
1473                 char c = in.get();
1474                                 
1475                                 if ((c == '\n') || (c == '\r') || (c == '\f'))  { gobble(in); newSpot = in.tellg(); break; }
1476                 else if (int(c) == -1) { break; }
1477             }
1478             
1479                         //there was not another line before the end of the file
1480                         unsigned long long sanityPos = in.tellg();
1481             
1482                         if (sanityPos == -1) {  break;  }
1483                         else {  filePos.push_back(newSpot);  }
1484                         
1485                         in.close();
1486                 }
1487                 
1488                 //save end pos
1489                 filePos.push_back(size);
1490                 
1491                 //sanity check filePos
1492                 for (int i = 0; i < (filePos.size()-1); i++) {
1493                         if (filePos[(i+1)] <= filePos[i]) {  filePos.erase(filePos.begin()+(i+1)); i--; }
1494                 }
1495         
1496                 proc = (filePos.size() - 1);
1497 #else
1498                 mothurOut("[ERROR]: Windows version should not be calling the divideFile function."); mothurOutEndLine();
1499                 proc=1;
1500                 filePos.push_back(size);
1501 #endif
1502                 return filePos;
1503         }
1504         catch(exception& e) {
1505                 errorOut(e, "MothurOut", "divideFile");
1506                 exit(1);
1507         }
1508 }
1509 /**************************************************************************************************/
1510 int MothurOut::divideFile(string filename, int& proc, vector<string>& files) {
1511         try{
1512                 
1513                 vector<unsigned long long> filePos = divideFile(filename, proc);
1514                 
1515                 for (int i = 0; i < (filePos.size()-1); i++) {
1516                         
1517                         //read file chunk
1518                         ifstream in;
1519                         openInputFile(filename, in);
1520                         in.seekg(filePos[i]);
1521                         unsigned long long size = filePos[(i+1)] - filePos[i];
1522                         char* chunk = new char[size];
1523                         in.read(chunk, size);
1524                         in.close();
1525                         
1526                         //open new file
1527                         string fileChunkName = filename + "." + toString(i) + ".tmp";
1528                         ofstream out; 
1529                         openOutputFile(fileChunkName, out);
1530                         
1531                         out << chunk << endl;
1532                         out.close();
1533                         delete[] chunk;
1534                         
1535                         //save name
1536                         files.push_back(fileChunkName);
1537                 }
1538                                 
1539                 return 0;
1540         }
1541         catch(exception& e) {
1542                 errorOut(e, "MothurOut", "divideFile");
1543                 exit(1);
1544         }
1545 }
1546 /***********************************************************************/
1547
1548 bool MothurOut::isTrue(string f){
1549         try {
1550                 
1551                 for (int i = 0; i < f.length(); i++) { f[i] = toupper(f[i]); }
1552                 
1553                 if ((f == "TRUE") || (f == "T")) {      return true;    }
1554                 else {  return false;  }
1555         }
1556         catch(exception& e) {
1557                 errorOut(e, "MothurOut", "isTrue");
1558                 exit(1);
1559         }
1560 }
1561
1562 /***********************************************************************/
1563
1564 float MothurOut::roundDist(float dist, int precision){
1565         try {
1566                 return int(dist * precision + 0.5)/float(precision);
1567         }
1568         catch(exception& e) {
1569                 errorOut(e, "MothurOut", "roundDist");
1570                 exit(1);
1571         }
1572 }
1573 /***********************************************************************/
1574
1575 float MothurOut::ceilDist(float dist, int precision){
1576         try {
1577                 return int(ceil(dist * precision))/float(precision);
1578         }
1579         catch(exception& e) {
1580                 errorOut(e, "MothurOut", "ceilDist");
1581                 exit(1);
1582         }
1583 }
1584 /***********************************************************************/
1585
1586 vector<string> MothurOut::splitWhiteSpace(string& rest, char buffer[], int size){
1587         try {
1588         vector<string> pieces;
1589         
1590         for (int i = 0; i < size; i++) {
1591             if (!isspace(buffer[i]))  { rest += buffer[i];  }
1592             else {
1593                 if (rest != "") { pieces.push_back(rest);  rest = ""; }
1594                 while (i < size) {  //gobble white space
1595                     if (isspace(buffer[i])) { i++; }
1596                     else { rest = buffer[i];  break; } //cout << "next piece buffer = " << nextPiece << endl;
1597                 } 
1598             }
1599         }
1600         
1601         return pieces;
1602         }
1603         catch(exception& e) {
1604                 errorOut(e, "MothurOut", "splitWhiteSpace");
1605                 exit(1);
1606         }
1607 }
1608 /***********************************************************************/
1609 vector<string> MothurOut::splitWhiteSpace(string input){
1610         try {
1611         vector<string> pieces;
1612         string rest = "";
1613         
1614         for (int i = 0; i < input.length(); i++) {
1615             if (!isspace(input[i]))  { rest += input[i];  }
1616             else {
1617                 if (rest != "") { pieces.push_back(rest);  rest = ""; }
1618                 while (i < input.length()) {  //gobble white space
1619                     if (isspace(input[i])) { i++; }
1620                     else { rest = input[i];  break; } //cout << "next piece buffer = " << nextPiece << endl;
1621                 } 
1622             }
1623         }
1624         
1625         if (rest != "") { pieces.push_back(rest); }
1626         
1627         return pieces;
1628         }
1629         catch(exception& e) {
1630                 errorOut(e, "MothurOut", "splitWhiteSpace");
1631                 exit(1);
1632         }
1633 }
1634 /***********************************************************************/
1635 vector<string> MothurOut::splitWhiteSpaceWithQuotes(string input){
1636         try {
1637         vector<string> pieces;
1638         string rest = "";
1639         
1640         int pos = input.find('\'');
1641         int pos2 = input.find('\"');
1642         
1643         if ((pos == string::npos) && (pos2 == string::npos)) { return splitWhiteSpace(input); } //no quotes to worry about
1644         else {
1645             for (int i = 0; i < input.length(); i++) {
1646                 if ((input[i] == '\'') || (input[i] == '\"') || (rest == "\'") || (rest == "\"")) { //grab everything til end or next ' or "
1647                     rest += input[i];
1648                     for (int j = i+1; j < input.length(); j++) {
1649                         if ((input[j] == '\'') || (input[j] == '\"')) {  //then quit
1650                             rest += input[j];
1651                             i = j+1;
1652                             j+=input.length();
1653                         }else { rest += input[j]; }
1654                     }
1655                 }else if (!isspace(input[i]))  { rest += input[i];  }
1656                 else {
1657                     if (rest != "") { pieces.push_back(rest);  rest = ""; }
1658                     while (i < input.length()) {  //gobble white space
1659                         if (isspace(input[i])) { i++; }
1660                         else { rest = input[i];  break; } //cout << "next piece buffer = " << nextPiece << endl;
1661                     } 
1662                 }
1663             }
1664             
1665             if (rest != "") { pieces.push_back(rest); }
1666         }
1667         return pieces;
1668         }
1669         catch(exception& e) {
1670                 errorOut(e, "MothurOut", "splitWhiteSpace");
1671                 exit(1);
1672         }
1673 }
1674 //**********************************************************************************************************************
1675 int MothurOut::readTax(string namefile, map<string, string>& taxMap) {
1676         try {
1677         //open input file
1678                 ifstream in;
1679                 openInputFile(namefile, in);
1680         
1681         string rest = "";
1682         char buffer[4096];
1683         bool pairDone = false;
1684         bool columnOne = true;
1685         string firstCol, secondCol;
1686         
1687                 while (!in.eof()) {
1688                         if (control_pressed) { break; }
1689                         
1690             in.read(buffer, 4096);
1691             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1692             
1693             for (int i = 0; i < pieces.size(); i++) {
1694                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1695                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1696                 
1697                 if (pairDone) { 
1698                     checkName(firstCol);
1699                     //are there confidence scores, if so remove them
1700                     if (secondCol.find_first_of('(') != -1) {  removeConfidences(secondCol);    }
1701                     map<string, string>::iterator itTax = taxMap.find(firstCol);
1702                     
1703                     if(itTax == taxMap.end()) {
1704                         bool ignore = false;
1705                         if (secondCol != "") { if (secondCol[secondCol.length()-1] != ';') { mothurOut("[ERROR]: " + firstCol + " is missing the final ';', ignoring.\n"); ignore=true; }
1706                         }
1707                         if (!ignore) { taxMap[firstCol] = secondCol; }
1708                         if (debug) {  mothurOut("[DEBUG]: name = '" + firstCol + "' tax = '" + secondCol + "'\n");  }
1709                     }else {
1710                         mothurOut("[ERROR]: " + firstCol + " is already in your taxonomy file, names must be unique./n"); control_pressed = true;
1711                     }
1712                     pairDone = false; 
1713                 }
1714             }
1715                 }
1716                 in.close();
1717         
1718         if (rest != "") {
1719             vector<string> pieces = splitWhiteSpace(rest);
1720             
1721             for (int i = 0; i < pieces.size(); i++) {
1722                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1723                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1724                 
1725                 if (pairDone) { 
1726                     checkName(firstCol);
1727                     //are there confidence scores, if so remove them
1728                     if (secondCol.find_first_of('(') != -1) {  removeConfidences(secondCol);    }
1729                     map<string, string>::iterator itTax = taxMap.find(firstCol);
1730                     
1731                     if(itTax == taxMap.end()) {
1732                         bool ignore = false;
1733                         if (secondCol != "") { if (secondCol[secondCol.length()-1] != ';') { mothurOut("[ERROR]: " + firstCol + " is missing the final ';', ignoring.\n"); ignore=true; }
1734                         }
1735                         if (!ignore) { taxMap[firstCol] = secondCol; }
1736                         if (debug) {  mothurOut("[DEBUG]: name = '" + firstCol + "' tax = '" + secondCol + "'\n");  }
1737                     }else {
1738                         mothurOut("[ERROR]: " + firstCol + " is already in your taxonomy file, names must be unique./n"); control_pressed = true;
1739                     }
1740
1741                     pairDone = false; 
1742                 }
1743             } 
1744         }
1745                 
1746                 return taxMap.size();
1747
1748         }
1749         catch(exception& e) {
1750                 errorOut(e, "MothurOut", "readTax");
1751                 exit(1);
1752         }
1753 }
1754 /**********************************************************************************************************************/
1755 int MothurOut::readNames(string namefile, map<string, string>& nameMap, bool redund) { 
1756         try {
1757                 //open input file
1758                 ifstream in;
1759                 openInputFile(namefile, in);
1760         
1761         string rest = "";
1762         char buffer[4096];
1763         bool pairDone = false;
1764         bool columnOne = true;
1765         string firstCol, secondCol;
1766         
1767                 while (!in.eof()) {
1768                         if (control_pressed) { break; }
1769                         
1770             in.read(buffer, 4096);
1771             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1772             
1773             for (int i = 0; i < pieces.size(); i++) {
1774                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1775                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1776                 
1777                 if (pairDone) { 
1778                     checkName(firstCol);
1779                     checkName(secondCol);
1780                     
1781                     //parse names into vector
1782                     vector<string> theseNames;
1783                     splitAtComma(secondCol, theseNames);
1784                     for (int i = 0; i < theseNames.size(); i++) {  nameMap[theseNames[i]] = firstCol;  }
1785                     pairDone = false; 
1786                 }
1787             }
1788                 }
1789                 in.close();
1790         
1791         if (rest != "") {
1792             vector<string> pieces = splitWhiteSpace(rest);
1793             
1794             for (int i = 0; i < pieces.size(); i++) {
1795                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1796                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1797                 
1798                 if (pairDone) { 
1799                     checkName(firstCol);
1800                     checkName(secondCol);
1801                     
1802                     //parse names into vector
1803                     vector<string> theseNames;
1804                     splitAtComma(secondCol, theseNames);
1805                     for (int i = 0; i < theseNames.size(); i++) {   nameMap[theseNames[i]] = firstCol;  }
1806                     pairDone = false; 
1807                 }
1808             }  
1809         }
1810                 
1811                 return nameMap.size();
1812                 
1813         }
1814         catch(exception& e) {
1815                 errorOut(e, "MothurOut", "readNames");
1816                 exit(1);
1817         }
1818 }
1819 /**********************************************************************************************************************/
1820 int MothurOut::readNames(string namefile, map<string, string>& nameMap, int flip) { 
1821         try {
1822                 //open input file
1823                 ifstream in;
1824                 openInputFile(namefile, in);
1825         
1826         string rest = "";
1827         char buffer[4096];
1828         bool pairDone = false;
1829         bool columnOne = true;
1830         string firstCol, secondCol;
1831         
1832                 while (!in.eof()) {
1833                         if (control_pressed) { break; }
1834                         
1835             in.read(buffer, 4096);
1836             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1837             
1838             for (int i = 0; i < pieces.size(); i++) {
1839                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1840                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1841                 
1842                 if (pairDone) { 
1843                     checkName(firstCol);
1844                     checkName(secondCol);
1845                     nameMap[secondCol] = firstCol;
1846                     pairDone = false; 
1847                 }
1848             }
1849                 }
1850                 in.close();
1851         
1852         if (rest != "") {
1853             vector<string> pieces = splitWhiteSpace(rest);
1854             
1855             for (int i = 0; i < pieces.size(); i++) {
1856                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1857                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1858                 
1859                 if (pairDone) { 
1860                     checkName(firstCol);
1861                     checkName(secondCol);
1862                     nameMap[secondCol] = firstCol;
1863                     pairDone = false; 
1864                 }
1865             } 
1866         }
1867                 
1868                 return nameMap.size();
1869                 
1870         }
1871         catch(exception& e) {
1872                 errorOut(e, "MothurOut", "readNames");
1873                 exit(1);
1874         }
1875 }
1876 /**********************************************************************************************************************/
1877 int MothurOut::readNames(string namefile, map<string, string>& nameMap, map<string, int>& nameCount) { 
1878         try {
1879                 nameMap.clear(); nameCount.clear();
1880                 //open input file
1881                 ifstream in;
1882                 openInputFile(namefile, in);
1883         
1884         string rest = "";
1885         char buffer[4096];
1886         bool pairDone = false;
1887         bool columnOne = true;
1888         string firstCol, secondCol;
1889         
1890                 while (!in.eof()) {
1891                         if (control_pressed) { break; }
1892                         
1893             in.read(buffer, 4096);
1894             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1895             
1896             for (int i = 0; i < pieces.size(); i++) {
1897                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1898                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1899                 
1900                 if (pairDone) { 
1901                     checkName(firstCol);
1902                     checkName(secondCol);
1903                     //parse names into vector
1904                     vector<string> theseNames;
1905                     splitAtComma(secondCol, theseNames);
1906                     for (int i = 0; i < theseNames.size(); i++) {  nameMap[theseNames[i]] = firstCol;  }
1907                     nameCount[firstCol] = theseNames.size();
1908                     pairDone = false; 
1909                 }
1910             }
1911                 }
1912                 in.close();
1913                 
1914         if (rest != "") {
1915             vector<string> pieces = splitWhiteSpace(rest);
1916             
1917             for (int i = 0; i < pieces.size(); i++) {
1918                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1919                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1920                 
1921                 if (pairDone) { 
1922                     checkName(firstCol);
1923                     checkName(secondCol);
1924                     //parse names into vector
1925                     vector<string> theseNames;
1926                     splitAtComma(secondCol, theseNames);
1927                     for (int i = 0; i < theseNames.size(); i++) {  nameMap[theseNames[i]] = firstCol;  }
1928                     nameCount[firstCol] = theseNames.size();
1929                     pairDone = false; 
1930                 }
1931             }
1932
1933         }
1934                 return nameMap.size();
1935                 
1936         }
1937         catch(exception& e) {
1938                 errorOut(e, "MothurOut", "readNames");
1939                 exit(1);
1940         }
1941 }
1942 /**********************************************************************************************************************/
1943 int MothurOut::readNames(string namefile, map<string, string>& nameMap) { 
1944         try {
1945                 //open input file
1946                 ifstream in;
1947                 openInputFile(namefile, in);
1948
1949         string rest = "";
1950         char buffer[4096];
1951         bool pairDone = false;
1952         bool columnOne = true;
1953         string firstCol, secondCol;
1954         
1955                 while (!in.eof()) {
1956                         if (control_pressed) { break; }
1957                         
1958             in.read(buffer, 4096);
1959             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
1960              
1961             for (int i = 0; i < pieces.size(); i++) {
1962                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1963                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1964                 
1965                 if (pairDone) { 
1966                     checkName(firstCol);
1967                     checkName(secondCol);
1968                     nameMap[firstCol] = secondCol; pairDone = false; }
1969             }
1970                 }
1971                 in.close();
1972         
1973         if (rest != "") {
1974             vector<string> pieces = splitWhiteSpace(rest);
1975             
1976             for (int i = 0; i < pieces.size(); i++) {
1977                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
1978                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
1979                 
1980                 if (pairDone) { 
1981                     checkName(firstCol);
1982                     checkName(secondCol);
1983                     nameMap[firstCol] = secondCol; pairDone = false; }
1984             }
1985         }
1986                 
1987                 return nameMap.size();
1988                 
1989         }
1990         catch(exception& e) {
1991                 errorOut(e, "MothurOut", "readNames");
1992                 exit(1);
1993         }
1994 }
1995 /**********************************************************************************************************************/
1996 int MothurOut::readNames(string namefile, map<string, vector<string> >& nameMap) { 
1997         try {        
1998                 //open input file
1999                 ifstream in;
2000                 openInputFile(namefile, in);
2001                 
2002         string rest = "";
2003         char buffer[4096];
2004         bool pairDone = false;
2005         bool columnOne = true;
2006         string firstCol, secondCol;
2007         
2008                 while (!in.eof()) {
2009                         if (control_pressed) { break; }
2010                         
2011             in.read(buffer, 4096);
2012             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2013             
2014             for (int i = 0; i < pieces.size(); i++) {
2015                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2016                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2017                 
2018                 if (pairDone) { 
2019                     checkName(firstCol);
2020                     checkName(secondCol);
2021                     vector<string> temp;
2022                     splitAtComma(secondCol, temp);
2023                     nameMap[firstCol] = temp;
2024                     pairDone = false;  
2025                 } 
2026             }
2027                 }
2028                 in.close();
2029         
2030         if (rest != "") {
2031             vector<string> pieces = splitWhiteSpace(rest);
2032             
2033             for (int i = 0; i < pieces.size(); i++) {
2034                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2035                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2036                 
2037                 if (pairDone) { 
2038                     checkName(firstCol);
2039                     checkName(secondCol);
2040                     vector<string> temp;
2041                     splitAtComma(secondCol, temp);
2042                     nameMap[firstCol] = temp;
2043                     pairDone = false;  
2044                 } 
2045             }
2046         }
2047         
2048                 return nameMap.size();
2049         }
2050         catch(exception& e) {
2051                 errorOut(e, "MothurOut", "readNames");
2052                 exit(1);
2053         }
2054 }
2055 /**********************************************************************************************************************/
2056 map<string, int> MothurOut::readNames(string namefile) { 
2057         try {
2058                 map<string, int> nameMap;
2059                 
2060                 //open input file
2061                 ifstream in;
2062                 openInputFile(namefile, in);
2063                 
2064         string rest = "";
2065         char buffer[4096];
2066         bool pairDone = false;
2067         bool columnOne = true;
2068         string firstCol, secondCol;
2069         
2070                 while (!in.eof()) {
2071                         if (control_pressed) { break; }
2072                         
2073             in.read(buffer, 4096);
2074             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2075             
2076             for (int i = 0; i < pieces.size(); i++) {
2077                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2078                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2079                 
2080                 if (pairDone) { 
2081                     checkName(firstCol);
2082                     checkName(secondCol);
2083                     int num = getNumNames(secondCol);
2084                     nameMap[firstCol] = num;
2085                     pairDone = false;  
2086                 } 
2087             }
2088                 }
2089         in.close();
2090         
2091         if (rest != "") {
2092             vector<string> pieces = splitWhiteSpace(rest);
2093             for (int i = 0; i < pieces.size(); i++) {
2094                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2095                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2096                 
2097                 if (pairDone) { 
2098                     checkName(firstCol);
2099                     checkName(secondCol);
2100                     int num = getNumNames(secondCol);
2101                     nameMap[firstCol] = num;
2102                     pairDone = false;  
2103                 } 
2104             }
2105         }
2106                 
2107                 return nameMap;
2108                 
2109         }
2110         catch(exception& e) {
2111                 errorOut(e, "MothurOut", "readNames");
2112                 exit(1);
2113         }
2114 }
2115 /**********************************************************************************************************************/
2116 map<string, int> MothurOut::readNames(string namefile, unsigned long int& numSeqs) { 
2117         try {
2118                 map<string, int> nameMap;
2119         numSeqs = 0;
2120                 
2121                 //open input file
2122                 ifstream in;
2123                 openInputFile(namefile, in);
2124                 
2125         string rest = "";
2126         char buffer[4096];
2127         bool pairDone = false;
2128         bool columnOne = true;
2129         string firstCol, secondCol;
2130         
2131                 while (!in.eof()) {
2132                         if (control_pressed) { break; }
2133                         
2134             in.read(buffer, 4096);
2135             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2136             
2137             for (int i = 0; i < pieces.size(); i++) {
2138                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2139                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2140                 
2141                 if (pairDone) { 
2142                     checkName(firstCol);
2143                     checkName(secondCol);
2144                     int num = getNumNames(secondCol);
2145                     nameMap[firstCol] = num;
2146                     pairDone = false;  
2147                     numSeqs += num;
2148                 } 
2149             }
2150                 }
2151         in.close();
2152         
2153         if (rest != "") {
2154             vector<string> pieces = splitWhiteSpace(rest);
2155             for (int i = 0; i < pieces.size(); i++) {
2156                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2157                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2158                 
2159                 if (pairDone) { 
2160                     checkName(firstCol);
2161                     checkName(secondCol);
2162                     int num = getNumNames(secondCol);
2163                     nameMap[firstCol] = num;
2164                     pairDone = false;  
2165                     numSeqs += num;
2166                 } 
2167             }
2168         }
2169                 
2170                 return nameMap;
2171                 
2172         }
2173         catch(exception& e) {
2174                 errorOut(e, "MothurOut", "readNames");
2175                 exit(1);
2176         }
2177 }
2178 /************************************************************/
2179 int MothurOut::checkName(string& name) {
2180     try {
2181         for (int i = 0; i < name.length(); i++) {
2182             if (name[i] == ':') { name[i] = '_'; changedSeqNames = true; }
2183         }        
2184         return 0;
2185     }
2186         catch(exception& e) {
2187                 errorOut(e, "MothurOut", "checkName");
2188                 exit(1);
2189         }
2190 }
2191 /**********************************************************************************************************************/
2192 int MothurOut::readNames(string namefile, vector<seqPriorityNode>& nameVector, map<string, string>& fastamap) { 
2193         try {
2194                 int error = 0;
2195                 
2196                 //open input file
2197                 ifstream in;
2198                 openInputFile(namefile, in);
2199                 
2200         string rest = "";
2201         char buffer[4096];
2202         bool pairDone = false;
2203         bool columnOne = true;
2204         string firstCol, secondCol;
2205         
2206                 while (!in.eof()) {
2207                         if (control_pressed) { break; }
2208                         
2209             in.read(buffer, 4096);
2210             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2211             
2212             for (int i = 0; i < pieces.size(); i++) {
2213                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2214                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2215                 
2216                 if (pairDone) { 
2217                     checkName(firstCol);
2218                     checkName(secondCol);
2219                     int num = getNumNames(secondCol);
2220                     
2221                     map<string, string>::iterator it = fastamap.find(firstCol);
2222                     if (it == fastamap.end()) {
2223                         error = 1;
2224                         mothurOut("[ERROR]: " + firstCol + " is not in your fastafile, but is in your namesfile, please correct."); mothurOutEndLine();
2225                     }else {
2226                         seqPriorityNode temp(num, it->second, firstCol);
2227                         nameVector.push_back(temp);
2228                     }
2229                     
2230                     pairDone = false;  
2231                 } 
2232             }
2233                 }
2234         in.close();
2235         
2236         if (rest != "") {
2237             vector<string> pieces = splitWhiteSpace(rest);
2238             
2239             for (int i = 0; i < pieces.size(); i++) {
2240                 if (columnOne) {  firstCol = pieces[i]; columnOne=false; }
2241                 else  { secondCol = pieces[i]; pairDone = true; columnOne=true; }
2242                 
2243                 if (pairDone) { 
2244                     checkName(firstCol);
2245                     checkName(secondCol);
2246                     int num = getNumNames(secondCol);
2247                     
2248                     map<string, string>::iterator it = fastamap.find(firstCol);
2249                     if (it == fastamap.end()) {
2250                         error = 1;
2251                         mothurOut("[ERROR]: " + firstCol + " is not in your fastafile, but is in your namesfile, please correct."); mothurOutEndLine();
2252                     }else {
2253                         seqPriorityNode temp(num, it->second, firstCol);
2254                         nameVector.push_back(temp);
2255                     }
2256                     
2257                     pairDone = false;  
2258                 } 
2259             }
2260         }
2261                 return error;
2262         }
2263         catch(exception& e) {
2264                 errorOut(e, "MothurOut", "readNames");
2265                 exit(1);
2266         }
2267 }
2268 //**********************************************************************************************************************
2269 set<string> MothurOut::readAccnos(string accnosfile){
2270         try {
2271                 set<string> names;
2272                 ifstream in;
2273                 openInputFile(accnosfile, in);
2274                 string name;
2275                 
2276         string rest = "";
2277         char buffer[4096];
2278         
2279                 while (!in.eof()) {
2280                         if (control_pressed) { break; }
2281                         
2282             in.read(buffer, 4096);
2283             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2284             
2285             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.insert(pieces[i]);  }
2286         }
2287                 in.close();     
2288                 
2289         if (rest != "") {
2290             vector<string> pieces = splitWhiteSpace(rest);
2291             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.insert(pieces[i]);  } 
2292         }
2293                 return names;
2294         }
2295         catch(exception& e) {
2296                 errorOut(e, "MothurOut", "readAccnos");
2297                 exit(1);
2298         }
2299 }
2300 //**********************************************************************************************************************
2301 int MothurOut::readAccnos(string accnosfile, vector<string>& names){
2302         try {
2303         names.clear();
2304                 ifstream in;
2305                 openInputFile(accnosfile, in);
2306                 string name;
2307                 
2308         string rest = "";
2309         char buffer[4096];
2310         
2311                 while (!in.eof()) {
2312                         if (control_pressed) { break; }
2313                         
2314             in.read(buffer, 4096);
2315             vector<string> pieces = splitWhiteSpace(rest, buffer, in.gcount());
2316             
2317             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.push_back(pieces[i]);  }
2318         }
2319                 in.close();     
2320         
2321         if (rest != "") {
2322             vector<string> pieces = splitWhiteSpace(rest);
2323             for (int i = 0; i < pieces.size(); i++) {  checkName(pieces[i]); names.push_back(pieces[i]);  }
2324         }
2325                 
2326                 return 0;
2327         }
2328         catch(exception& e) {
2329                 errorOut(e, "MothurOut", "readAccnos");
2330                 exit(1);
2331         }
2332 }
2333 /***********************************************************************/
2334
2335 int MothurOut::getNumNames(string names){
2336         try {
2337                 int count = 0;
2338                 
2339                 if(names != ""){
2340                         count = 1;
2341                         for(int i=0;i<names.size();i++){
2342                                 if(names[i] == ','){
2343                                         count++;
2344                                 }
2345                         }
2346                 }
2347                 
2348                 return count;
2349         }
2350         catch(exception& e) {
2351                 errorOut(e, "MothurOut", "getNumNames");
2352                 exit(1);
2353         }
2354 }
2355 /***********************************************************************/
2356
2357 int MothurOut::getNumChar(string line, char c){
2358         try {
2359                 int count = 0;
2360                 
2361                 if(line != ""){
2362                         for(int i=0;i<line.size();i++){
2363                                 if(line[i] == c){
2364                                         count++;
2365                                 }
2366                         }
2367                 }
2368                 
2369                 return count;
2370         }
2371         catch(exception& e) {
2372                 errorOut(e, "MothurOut", "getNumChar");
2373                 exit(1);
2374         }
2375 }
2376 //**********************************************************************************************************************
2377 bool MothurOut::isSubset(vector<string> bigset, vector<string> subset) {
2378         try {
2379                 
2380         
2381                 if (subset.size() > bigset.size()) { return false;  }
2382                 
2383                 //check if each guy in suset is also in bigset
2384                 for (int i = 0; i < subset.size(); i++) {
2385                         bool match = false;
2386                         for (int j = 0; j < bigset.size(); j++) {
2387                                 if (subset[i] == bigset[j]) { match = true; break; }
2388                         }
2389                         
2390                         //you have a guy in subset that had no match in bigset
2391                         if (match == false) { return false; }
2392                 }
2393                 
2394                 return true;
2395         
2396         }
2397         catch(exception& e) {
2398                 errorOut(e, "MothurOut", "isSubset");
2399                 exit(1);
2400         }
2401 }
2402 /***********************************************************************/
2403 int MothurOut::mothurRemove(string filename){
2404         try {
2405                 filename = getFullPathName(filename);
2406                 int error = remove(filename.c_str());
2407                 //if (error != 0) { 
2408                 //      if (errno != ENOENT) { //ENOENT == file does not exist
2409                 //              string message = "Error deleting file " + filename;
2410                 //              perror(message.c_str()); 
2411                 //      }
2412                 //}
2413                 return error;
2414         }
2415         catch(exception& e) {
2416                 errorOut(e, "MothurOut", "mothurRemove");
2417                 exit(1);
2418         }
2419 }
2420 /***********************************************************************/
2421 bool MothurOut::mothurConvert(string item, int& num){
2422         try {
2423                 bool error = false;
2424                 
2425                 if (isNumeric1(item)) {
2426                         convert(item, num);
2427                 }else {
2428                         num = 0;
2429                         error = true;
2430                         mothurOut("[ERROR]: cannot convert " + item + " to an integer."); mothurOutEndLine();
2431                         commandInputsConvertError = true;
2432                 }
2433                 
2434                 return error;
2435         }
2436         catch(exception& e) {
2437                 errorOut(e, "MothurOut", "mothurConvert");
2438                 exit(1);
2439         }
2440 }
2441 /***********************************************************************/
2442 bool MothurOut::mothurConvert(string item, intDist& num){
2443         try {
2444                 bool error = false;
2445                 
2446                 if (isNumeric1(item)) {
2447                         convert(item, num);
2448                 }else {
2449                         num = 0;
2450                         error = true;
2451                         mothurOut("[ERROR]: cannot convert " + item + " to an integer."); mothurOutEndLine();
2452                         commandInputsConvertError = true;
2453                 }
2454                 
2455                 return error;
2456         }
2457         catch(exception& e) {
2458                 errorOut(e, "MothurOut", "mothurConvert");
2459                 exit(1);
2460         }
2461 }
2462
2463 /***********************************************************************/
2464 bool MothurOut::isNumeric1(string stringToCheck){
2465         try {
2466                 bool numeric = false;
2467                 
2468                 if(stringToCheck.find_first_not_of("0123456789.-") == string::npos) { numeric = true; }
2469                         
2470                 return numeric;
2471         }
2472         catch(exception& e) {
2473                 errorOut(e, "MothurOut", "isNumeric1");
2474                 exit(1);
2475         }
2476         
2477 }
2478 /***********************************************************************/
2479 bool MothurOut::mothurConvert(string item, float& num){
2480         try {
2481                 bool error = false;
2482                 
2483                 if (isNumeric1(item)) {
2484                         convert(item, num);
2485                 }else {
2486                         num = 0;
2487                         error = true;
2488                         mothurOut("[ERROR]: cannot convert " + item + " to a float."); mothurOutEndLine();
2489                         commandInputsConvertError = true;
2490                 }
2491                 
2492                 return error;
2493         }
2494         catch(exception& e) {
2495                 errorOut(e, "MothurOut", "mothurConvert");
2496                 exit(1);
2497         }
2498 }
2499 /***********************************************************************/
2500 bool MothurOut::mothurConvert(string item, double& num){
2501         try {
2502                 bool error = false;
2503                 
2504                 if (isNumeric1(item)) {
2505                         convert(item, num);
2506                 }else {
2507                         num = 0;
2508                         error = true;
2509                         mothurOut("[ERROR]: cannot convert " + item + " to a double."); mothurOutEndLine();
2510                         commandInputsConvertError = true;
2511                 }
2512                 
2513                 return error;
2514         }
2515         catch(exception& e) {
2516                 errorOut(e, "MothurOut", "mothurConvert");
2517                 exit(1);
2518         }
2519 }
2520 /**************************************************************************************************/
2521
2522 vector<vector<double> > MothurOut::binomial(int maxOrder){
2523         try {
2524         vector<vector<double> > binomial(maxOrder+1);
2525         
2526     for(int i=0;i<=maxOrder;i++){
2527                 binomial[i].resize(maxOrder+1);
2528                 binomial[i][0]=1;
2529                 binomial[0][i]=0;
2530     }
2531     binomial[0][0]=1;
2532         
2533     binomial[1][0]=1;
2534     binomial[1][1]=1;
2535         
2536     for(int i=2;i<=maxOrder;i++){
2537                 binomial[1][i]=0;
2538     }
2539         
2540     for(int i=2;i<=maxOrder;i++){
2541                 for(int j=1;j<=maxOrder;j++){
2542                         if(i==j){       binomial[i][j]=1;                                                                       }
2543                         if(j>i) {       binomial[i][j]=0;                                                                       }
2544                         else    {       binomial[i][j]=binomial[i-1][j-1]+binomial[i-1][j];     }
2545                 }
2546     }
2547         
2548         return binomial;
2549         
2550         }
2551         catch(exception& e) {
2552                 errorOut(e, "MothurOut", "binomial");
2553                 exit(1);
2554         }
2555 }
2556 /**************************************************************************************************/
2557 unsigned int MothurOut::fromBase36(string base36){
2558         try {
2559                 unsigned int num = 0;
2560                 
2561                 map<char, int> converts;
2562                 converts['A'] = 0;
2563                 converts['a'] = 0;
2564                 converts['B'] = 1;
2565                 converts['b'] = 1;
2566                 converts['C'] = 2;
2567                 converts['c'] = 2;
2568                 converts['D'] = 3;
2569                 converts['d'] = 3;
2570                 converts['E'] = 4;
2571                 converts['e'] = 4;
2572                 converts['F'] = 5;
2573                 converts['f'] = 5;
2574                 converts['G'] = 6;
2575                 converts['g'] = 6;
2576                 converts['H'] = 7;
2577                 converts['h'] = 7;
2578                 converts['I'] = 8;
2579                 converts['i'] = 8;
2580                 converts['J'] = 9;
2581                 converts['j'] = 9;
2582                 converts['K'] = 10;
2583                 converts['k'] = 10;
2584                 converts['L'] = 11;
2585                 converts['l'] = 11;
2586                 converts['M'] = 12;
2587                 converts['m'] = 12;
2588                 converts['N'] = 13;
2589                 converts['n'] = 13;
2590                 converts['O'] = 14;
2591                 converts['o'] = 14;
2592                 converts['P'] = 15;
2593                 converts['p'] = 15;
2594                 converts['Q'] = 16;
2595                 converts['q'] = 16;
2596                 converts['R'] = 17;
2597                 converts['r'] = 17;
2598                 converts['S'] = 18;
2599                 converts['s'] = 18;
2600                 converts['T'] = 19;
2601                 converts['t'] = 19;
2602                 converts['U'] = 20;
2603                 converts['u'] = 20;
2604                 converts['V'] = 21;
2605                 converts['v'] = 21;
2606                 converts['W'] = 22;
2607                 converts['w'] = 22;
2608                 converts['X'] = 23;
2609                 converts['x'] = 23;
2610                 converts['Y'] = 24;
2611                 converts['y'] = 24;
2612                 converts['Z'] = 25;
2613                 converts['z'] = 25;
2614                 converts['0'] = 26;
2615                 converts['1'] = 27;
2616                 converts['2'] = 28;
2617                 converts['3'] = 29;
2618                 converts['4'] = 30;
2619                 converts['5'] = 31;
2620                 converts['6'] = 32;
2621                 converts['7'] = 33;
2622                 converts['8'] = 34;
2623                 converts['9'] = 35;             
2624                 
2625                 int i = 0;
2626                 while (i < base36.length()) {
2627                         char c = base36[i];
2628                         num = 36 * num + converts[c];
2629                         i++;
2630                 }
2631                 
2632                 return num;
2633                 
2634         }
2635         catch(exception& e) {
2636                 errorOut(e, "MothurOut", "fromBase36");
2637                 exit(1);
2638         }
2639 }
2640 /***********************************************************************/
2641
2642 int MothurOut::factorial(int num){
2643         try {
2644                 int total = 1;
2645                 
2646                 for (int i = 1; i <= num; i++) {
2647                         total *= i;
2648                 }
2649                 
2650                 return total;
2651         }
2652         catch(exception& e) {
2653                 errorOut(e, "MothurOut", "factorial");
2654                 exit(1);
2655         }
2656 }
2657 /***********************************************************************/
2658
2659 int MothurOut::getNumSeqs(ifstream& file){
2660         try {
2661                 int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
2662                 file.seekg(0);
2663                 return numSeqs;
2664         }
2665         catch(exception& e) {
2666                 errorOut(e, "MothurOut", "getNumSeqs");
2667                 exit(1);
2668         }       
2669 }
2670 /***********************************************************************/
2671 void MothurOut::getNumSeqs(ifstream& file, int& numSeqs){
2672         try {
2673                 string input;
2674                 numSeqs = 0;
2675                 while(!file.eof()){
2676                         input = getline(file);
2677                         if (input.length() != 0) {
2678                                 if(input[0] == '>'){ numSeqs++; }
2679                         }
2680                 }
2681         }
2682         catch(exception& e) {
2683                 errorOut(e, "MothurOut", "getNumSeqs");
2684                 exit(1);
2685         }       
2686 }
2687 /***********************************************************************/
2688
2689 //This function parses the estimator options and puts them in a vector
2690 void MothurOut::splitAtChar(string& estim, vector<string>& container, char symbol) {
2691         try {
2692         
2693         if (symbol == '-') { splitAtDash(estim, container); return; }
2694         
2695                 string individual = "";
2696                 int estimLength = estim.size();
2697                 for(int i=0;i<estimLength;i++){
2698                         if(estim[i] == symbol){
2699                                 container.push_back(individual);
2700                                 individual = "";                                
2701                         }
2702                         else{
2703                                 individual += estim[i];
2704                         }
2705                 }
2706                 container.push_back(individual);
2707
2708         }
2709         catch(exception& e) {
2710                 errorOut(e, "MothurOut", "splitAtChar");
2711                 exit(1);
2712         }       
2713 }
2714
2715 /***********************************************************************/
2716
2717 //This function parses the estimator options and puts them in a vector
2718 void MothurOut::splitAtDash(string& estim, vector<string>& container) {
2719         try {
2720                 string individual = "";
2721                 int estimLength = estim.size();
2722                 bool prevEscape = false;
2723                 /*for(int i=0;i<estimLength;i++){
2724                         if(prevEscape){
2725                                 individual += estim[i];
2726                                 prevEscape = false;
2727                         }
2728                         else{
2729                                 if(estim[i] == '\\'){
2730                                         prevEscape = true;
2731                                 }
2732                                 else if(estim[i] == '-'){
2733                                         container.push_back(individual);
2734                                         individual = "";
2735                                         prevEscape = false;                             
2736                                 }
2737                                 else{
2738                                         individual += estim[i];
2739                                         prevEscape = false;
2740                                 }
2741                         }
2742                 }*/
2743         
2744         
2745         for(int i=0;i<estimLength;i++){
2746             if(estim[i] == '-'){
2747                 if (prevEscape) {  individual += estim[i]; prevEscape = false;  } //add in dash because it was escaped.
2748                 else {
2749                     container.push_back(individual);
2750                     individual = "";
2751                 }
2752             }else if(estim[i] == '\\'){
2753                 if (i < estimLength-1) { 
2754                     if (estim[i+1] == '-') { prevEscape=true; }  //are you a backslash before a dash, if yes ignore
2755                     else { individual += estim[i]; prevEscape = false;  } //if no, add in
2756                 }else { individual += estim[i]; }
2757             }else {
2758                 individual += estim[i];
2759             }
2760         }
2761         
2762
2763         
2764                 container.push_back(individual);
2765         }
2766         catch(exception& e) {
2767                 errorOut(e, "MothurOut", "splitAtDash");
2768                 exit(1);
2769         }       
2770 }
2771
2772 /***********************************************************************/
2773 //This function parses the label options and puts them in a set
2774 void MothurOut::splitAtDash(string& estim, set<string>& container) {
2775         try {
2776                 string individual = "";
2777                 int estimLength = estim.size();
2778                 bool prevEscape = false;
2779                 for(int i=0;i<estimLength;i++){
2780                         if(prevEscape){
2781                                 individual += estim[i];
2782                                 prevEscape = false;
2783                         }
2784                         else{
2785                                 if(estim[i] == '\\'){
2786                                         prevEscape = true;
2787                                 }
2788                                 else if(estim[i] == '-'){
2789                                         container.insert(individual);
2790                                         individual = "";
2791                                         prevEscape = false;                             
2792                                 }
2793                                 else{
2794                                         individual += estim[i];
2795                                         prevEscape = false;
2796                                 }
2797                         }
2798                 }
2799                 container.insert(individual);
2800         
2801         }
2802         catch(exception& e) {
2803                 errorOut(e, "MothurOut", "splitAtDash");
2804                 exit(1);
2805         }       
2806 }
2807 /***********************************************************************/
2808 //This function parses the line options and puts them in a set
2809 void MothurOut::splitAtDash(string& estim, set<int>& container) {
2810         try {
2811                 string individual = "";
2812                 int lineNum;
2813                 int estimLength = estim.size();
2814                 bool prevEscape = false;
2815                 for(int i=0;i<estimLength;i++){
2816                         if(prevEscape){
2817                                 individual += estim[i];
2818                                 prevEscape = false;
2819                         }
2820                         else{
2821                                 if(estim[i] == '\\'){
2822                                         prevEscape = true;
2823                                 }
2824                                 else if(estim[i] == '-'){
2825                                         convert(individual, lineNum); //convert the string to int
2826                                         container.insert(lineNum);
2827                                         individual = "";
2828                                         prevEscape = false;                             
2829                                 }
2830                                 else{
2831                                         individual += estim[i];
2832                                         prevEscape = false;
2833                                 }
2834                         }
2835                 }
2836                 convert(individual, lineNum); //convert the string to int
2837                 container.insert(lineNum);
2838         }
2839         catch(exception& e) {
2840                 errorOut(e, "MothurOut", "splitAtDash");
2841                 exit(1);
2842         }       
2843 }
2844
2845 /***********************************************************************/
2846 string MothurOut::makeList(vector<string>& names) {
2847         try {
2848                 string list = "";
2849         
2850         if (names.size() == 0) { return list; }
2851                 
2852         for (int i = 0; i < names.size()-1; i++) { list += names[i] + ",";  }
2853         
2854         //get last name
2855         list += names[names.size()-1];
2856         
2857         return list;
2858     }
2859         catch(exception& e) {
2860                 errorOut(e, "MothurOut", "makeList");
2861                 exit(1);
2862         }       
2863 }
2864
2865 /***********************************************************************/
2866 //This function parses the a string and puts peices in a vector
2867 void MothurOut::splitAtComma(string& estim, vector<string>& container) {
2868         try {
2869                 string individual = "";
2870                 int estimLength = estim.size();
2871                 for(int i=0;i<estimLength;i++){
2872                         if(estim[i] == ','){
2873                                 container.push_back(individual);
2874                                 individual = "";                                
2875                         }
2876                         else{
2877                                 individual += estim[i];
2878                         }
2879                 }
2880                 container.push_back(individual);
2881                 
2882                 
2883                 
2884                 
2885 //              string individual;
2886 //              
2887 //              while (estim.find_first_of(',') != -1) {
2888 //                      individual = estim.substr(0,estim.find_first_of(','));
2889 //                      if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
2890 //                              estim = estim.substr(estim.find_first_of(',')+1, estim.length());
2891 //                              container.push_back(individual);
2892 //                      }
2893 //              }
2894 //              //get last one
2895 //              container.push_back(estim);
2896         }
2897         catch(exception& e) {
2898                 errorOut(e, "MothurOut", "splitAtComma");
2899                 exit(1);
2900         }       
2901 }
2902 /***********************************************************************/
2903 //This function splits up the various option parameters
2904 void MothurOut::splitAtChar(string& prefix, string& suffix, char c){
2905         try {
2906                 prefix = suffix.substr(0,suffix.find_first_of(c));
2907                 if ((suffix.find_first_of(c)+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
2908                         suffix = suffix.substr(suffix.find_first_of(c)+1, suffix.length());
2909                         string space = " ";
2910                         while(suffix.at(0) == ' ')
2911                                 suffix = suffix.substr(1, suffix.length());
2912                 }else {  suffix = "";  }
2913         
2914     }
2915         catch(exception& e) {
2916                 errorOut(e, "MothurOut", "splitAtChar");
2917                 exit(1);
2918         }       
2919 }
2920
2921 /***********************************************************************/
2922
2923 //This function splits up the various option parameters
2924 void MothurOut::splitAtComma(string& prefix, string& suffix){
2925         try {
2926                 prefix = suffix.substr(0,suffix.find_first_of(','));
2927                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
2928                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
2929                         string space = " ";
2930                         while(suffix.at(0) == ' ')
2931                                 suffix = suffix.substr(1, suffix.length());
2932                 }else {  suffix = "";  }
2933
2934         }
2935         catch(exception& e) {
2936                 errorOut(e, "MothurOut", "splitAtComma");
2937                 exit(1);
2938         }       
2939 }
2940 /***********************************************************************/
2941
2942 //This function separates the key value from the option value i.e. dist=96_...
2943 void MothurOut::splitAtEquals(string& key, string& value){              
2944         try {
2945                 if(value.find_first_of('=') != -1){
2946                         key = value.substr(0,value.find_first_of('='));
2947                         if ((value.find_first_of('=')+1) <= value.length()) {
2948                                 value = value.substr(value.find_first_of('=')+1, value.length());
2949                         }
2950                 }else{
2951                         key = value;
2952                         value = 1;
2953                 }
2954         }
2955         catch(exception& e) {
2956                 errorOut(e, "MothurOut", "splitAtEquals");
2957                 exit(1);
2958         }       
2959 }
2960
2961 /**************************************************************************************************/
2962
2963 bool MothurOut::inUsersGroups(string groupname, vector<string> Groups) {
2964         try {
2965                 for (int i = 0; i < Groups.size(); i++) {
2966                         if (groupname == Groups[i]) { return true; }
2967                 }
2968                 return false;
2969         }
2970         catch(exception& e) {
2971                 errorOut(e, "MothurOut", "inUsersGroups");
2972                 exit(1);
2973         }       
2974 }
2975 /**************************************************************************************************/
2976
2977 bool MothurOut::inUsersGroups(vector<int> set, vector< vector<int> > sets) {
2978         try {
2979                 for (int i = 0; i < sets.size(); i++) {
2980                         if (set == sets[i]) { return true; }
2981                 }
2982                 return false;
2983         }
2984         catch(exception& e) {
2985                 errorOut(e, "MothurOut", "inUsersGroups");
2986                 exit(1);
2987         }       
2988 }
2989 /**************************************************************************************************/
2990
2991 bool MothurOut::inUsersGroups(int groupname, vector<int> Groups) {
2992         try {
2993                 for (int i = 0; i < Groups.size(); i++) {
2994                         if (groupname == Groups[i]) { return true; }
2995                 }
2996                 return false;
2997         }
2998         catch(exception& e) {
2999                 errorOut(e, "MothurOut", "inUsersGroups");
3000                 exit(1);
3001         }       
3002 }
3003
3004 /**************************************************************************************************/
3005 //returns true if any of the strings in first vector are in second vector
3006 bool MothurOut::inUsersGroups(vector<string> groupnames, vector<string> Groups) {
3007         try {
3008                 
3009                 for (int i = 0; i < groupnames.size(); i++) {
3010                         if (inUsersGroups(groupnames[i], Groups)) { return true; }
3011                 }
3012                 return false;
3013         }
3014         catch(exception& e) {
3015                 errorOut(e, "MothurOut", "inUsersGroups");
3016                 exit(1);
3017         }       
3018 }
3019 /***********************************************************************/
3020 //this function determines if the user has given us labels that are smaller than the given label.
3021 //if so then it returns true so that the calling function can run the previous valid distance.
3022 //it's a "smart" distance function.  It also checks for invalid labels.
3023 bool MothurOut::anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
3024         try {
3025                 
3026                 set<string>::iterator it;
3027                 vector<float> orderFloat;
3028                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
3029                 map<string, float>::iterator it2;
3030                 float labelFloat;
3031                 bool smaller = false;
3032                 
3033                 //unique is the smallest line
3034                 if (label == "unique") {  return false;  }
3035                 else { 
3036                         if (convertTestFloat(label, labelFloat)) {
3037                                 convert(label, labelFloat); 
3038                         }else { //cant convert 
3039                                 return false;
3040                         }
3041                 }
3042                 
3043                 //go through users set and make them floats
3044                 for(it = userLabels.begin(); it != userLabels.end();) {
3045                         
3046                         float temp;
3047                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
3048                                 convert(*it, temp);
3049                                 orderFloat.push_back(temp);
3050                                 userMap[*it] = temp;
3051                                 it++;
3052                         }else if (*it == "unique") { 
3053                                 orderFloat.push_back(-1.0);
3054                                 userMap["unique"] = -1.0;
3055                                 it++;
3056                         }else {
3057                                 if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
3058                                 userLabels.erase(it++); 
3059                         }
3060                 }
3061                 
3062                 //sort order
3063                 sort(orderFloat.begin(), orderFloat.end());
3064                 
3065                 /*************************************************/
3066                 //is this label bigger than any of the users labels
3067                 /*************************************************/
3068                                 
3069                 //loop through order until you find a label greater than label
3070                 for (int i = 0; i < orderFloat.size(); i++) {
3071                         if (orderFloat[i] < labelFloat) {
3072                                 smaller = true;
3073                                 if (orderFloat[i] == -1) { 
3074                                         if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
3075                                         userLabels.erase("unique");
3076                                 }
3077                                 else {  
3078                                         if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
3079                                         string s = "";
3080                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
3081                                                 if (it2->second == orderFloat[i]) {  
3082                                                         s = it2->first;  
3083                                                         //remove small labels
3084                                                         userLabels.erase(s);
3085                                                         break;
3086                                                 }
3087                                         }
3088                                         if (errorOff == "") {mothurOut( s +  ". I will use the next smallest distance. "); mothurOutEndLine(); }
3089                                 }
3090                         //since they are sorted once you find a bigger one stop looking
3091                         }else { break; }
3092                 }
3093                 
3094                 return smaller;
3095                                                 
3096         }
3097         catch(exception& e) {
3098                 errorOut(e, "MothurOut", "anyLabelsToProcess");
3099                 exit(1);
3100         }       
3101 }
3102
3103 /**************************************************************************************************/
3104 bool MothurOut::checkReleaseVersion(ifstream& file, string version) {
3105         try {
3106                 
3107                 bool good = true;
3108                 
3109                 string line = getline(file);  
3110
3111                 //before we added this check
3112                 if (line[0] != '#') {  good = false;  }
3113                 else {
3114                         //rip off #
3115                         line = line.substr(1);
3116                         
3117                         vector<string> versionVector;
3118                         splitAtChar(version, versionVector, '.');
3119                         
3120                         //check file version
3121                         vector<string> linesVector;
3122                         splitAtChar(line, linesVector, '.');
3123                         
3124                         if (versionVector.size() != linesVector.size()) { good = false; }
3125                         else {
3126                                 for (int j = 0; j < versionVector.size(); j++) {
3127                                         int num1, num2;
3128                                         convert(versionVector[j], num1);
3129                                         convert(linesVector[j], num2);
3130                                         
3131                                         //if mothurs version is newer than this files version, then we want to remake it
3132                                         if (num1 > num2) {  good = false; break;  }
3133                                 }
3134                         }
3135                         
3136                 }
3137                 
3138                 if (!good) {  file.close();  }
3139                 else { file.seekg(0);  }
3140                 
3141                 return good;
3142         }
3143         catch(exception& e) {
3144                 errorOut(e, "MothurOut", "checkReleaseVersion");                
3145                 exit(1);
3146         }
3147 }
3148 /**************************************************************************************************/
3149 vector<double> MothurOut::getAverages(vector< vector<double> >& dists) {
3150         try{
3151         vector<double> averages; //averages.resize(numComp, 0.0);
3152         for (int i = 0; i < dists[0].size(); i++) { averages.push_back(0.0); }
3153       
3154         for (int thisIter = 0; thisIter < dists.size(); thisIter++) {
3155             for (int i = 0; i < dists[thisIter].size(); i++) {  
3156                 averages[i] += dists[thisIter][i];
3157             }
3158         }
3159         
3160         //finds average.
3161         for (int i = 0; i < averages.size(); i++) {  averages[i] /= (double) dists.size(); }
3162         
3163         return averages;
3164     }
3165         catch(exception& e) {
3166                 errorOut(e, "MothurOut", "getAverages");                
3167                 exit(1);
3168         }
3169 }
3170 /**************************************************************************************************/
3171 vector<double> MothurOut::getStandardDeviation(vector< vector<double> >& dists) {
3172         try{
3173         
3174         vector<double> averages = getAverages(dists);
3175         
3176         //find standard deviation
3177         vector<double> stdDev; //stdDev.resize(numComp, 0.0);
3178         for (int i = 0; i < dists[0].size(); i++) { stdDev.push_back(0.0); }
3179         
3180         for (int thisIter = 0; thisIter < dists.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3181             for (int j = 0; j < dists[thisIter].size(); j++) {
3182                 stdDev[j] += ((dists[thisIter][j] - averages[j]) * (dists[thisIter][j] - averages[j]));
3183             }
3184         }
3185         for (int i = 0; i < stdDev.size(); i++) {  
3186             stdDev[i] /= (double) dists.size(); 
3187             stdDev[i] = sqrt(stdDev[i]);
3188         }
3189         
3190         return stdDev;
3191     }
3192         catch(exception& e) {
3193                 errorOut(e, "MothurOut", "getAverages");                
3194                 exit(1);
3195         }
3196 }
3197 /**************************************************************************************************/
3198 vector<double> MothurOut::getStandardDeviation(vector< vector<double> >& dists, vector<double>& averages) {
3199         try{
3200         //find standard deviation
3201         vector<double> stdDev; //stdDev.resize(numComp, 0.0);
3202         for (int i = 0; i < dists[0].size(); i++) { stdDev.push_back(0.0); }
3203         
3204         for (int thisIter = 0; thisIter < dists.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3205             for (int j = 0; j < dists[thisIter].size(); j++) {
3206                 stdDev[j] += ((dists[thisIter][j] - averages[j]) * (dists[thisIter][j] - averages[j]));
3207             }
3208         }
3209         for (int i = 0; i < stdDev.size(); i++) {  
3210             stdDev[i] /= (double) dists.size(); 
3211             stdDev[i] = sqrt(stdDev[i]);
3212         }
3213         
3214         return stdDev;
3215     }
3216         catch(exception& e) {
3217                 errorOut(e, "MothurOut", "getAverages");                
3218                 exit(1);
3219         }
3220 }
3221 /**************************************************************************************************/
3222 vector< vector<seqDist> > MothurOut::getAverages(vector< vector< vector<seqDist> > >& calcDistsTotals, string mode) {
3223         try{
3224         
3225         vector< vector<seqDist>  > calcAverages; //calcAverages.resize(calcDistsTotals[0].size()); 
3226         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3227             //calcAverages[i].resize(calcDistsTotals[0][i].size());
3228             vector<seqDist> temp;
3229             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3230                 seqDist tempDist;
3231                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3232                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3233                 tempDist.dist = 0.0;
3234                 temp.push_back(tempDist);
3235             }
3236             calcAverages.push_back(temp);
3237         }
3238         
3239         if (mode == "average") {
3240             for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //sum all groups dists for each calculator
3241                 for (int i = 0; i < calcAverages.size(); i++) {  //initialize sums to zero.
3242                     for (int j = 0; j < calcAverages[i].size(); j++) {
3243                         calcAverages[i][j].dist += calcDistsTotals[thisIter][i][j].dist;
3244                     }
3245                 }
3246             }
3247             
3248             for (int i = 0; i < calcAverages.size(); i++) {  //finds average.
3249                 for (int j = 0; j < calcAverages[i].size(); j++) {
3250                     calcAverages[i][j].dist /= (float) calcDistsTotals.size();
3251                 }
3252             }
3253         }else { //find median
3254             for (int i = 0; i < calcAverages.size(); i++) { //for each calc
3255                 for (int j = 0; j < calcAverages[i].size(); j++) {  //for each comparison
3256                     vector<double> dists;
3257                     for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //for each subsample
3258                         dists.push_back(calcDistsTotals[thisIter][i][j].dist);
3259                     }
3260                     sort(dists.begin(), dists.end());
3261                     calcAverages[i][j].dist = dists[(calcDistsTotals.size()/2)];
3262                 }
3263             }
3264         }
3265
3266         return calcAverages;
3267     }
3268         catch(exception& e) {
3269                 errorOut(e, "MothurOut", "getAverages");                
3270                 exit(1);
3271         }
3272 }
3273 /**************************************************************************************************/
3274 vector< vector<seqDist> > MothurOut::getAverages(vector< vector< vector<seqDist> > >& calcDistsTotals) {
3275         try{
3276         
3277         vector< vector<seqDist>  > calcAverages; //calcAverages.resize(calcDistsTotals[0].size()); 
3278         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3279             //calcAverages[i].resize(calcDistsTotals[0][i].size());
3280             vector<seqDist> temp;
3281             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3282                 seqDist tempDist;
3283                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3284                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3285                 tempDist.dist = 0.0;
3286                 temp.push_back(tempDist);
3287             }
3288             calcAverages.push_back(temp);
3289         }
3290         
3291         
3292         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //sum all groups dists for each calculator
3293                 for (int i = 0; i < calcAverages.size(); i++) {  //initialize sums to zero.
3294                     for (int j = 0; j < calcAverages[i].size(); j++) {
3295                         calcAverages[i][j].dist += calcDistsTotals[thisIter][i][j].dist;
3296                     }
3297                 }
3298         }
3299             
3300         for (int i = 0; i < calcAverages.size(); i++) {  //finds average.
3301                 for (int j = 0; j < calcAverages[i].size(); j++) {
3302                     calcAverages[i][j].dist /= (float) calcDistsTotals.size();
3303                 }
3304         }
3305         
3306         return calcAverages;
3307     }
3308         catch(exception& e) {
3309                 errorOut(e, "MothurOut", "getAverages");                
3310                 exit(1);
3311         }
3312 }
3313 /**************************************************************************************************/
3314 vector< vector<seqDist> > MothurOut::getStandardDeviation(vector< vector< vector<seqDist> > >& calcDistsTotals) {
3315         try{
3316         
3317         vector< vector<seqDist> > calcAverages = getAverages(calcDistsTotals);
3318         
3319         //find standard deviation
3320         vector< vector<seqDist>  > stdDev;  
3321         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3322             vector<seqDist> temp;
3323             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3324                 seqDist tempDist;
3325                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3326                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3327                 tempDist.dist = 0.0;
3328                 temp.push_back(tempDist);
3329             }
3330             stdDev.push_back(temp);
3331         }
3332         
3333         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3334             for (int i = 0; i < stdDev.size(); i++) {  
3335                 for (int j = 0; j < stdDev[i].size(); j++) {
3336                     stdDev[i][j].dist += ((calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist) * (calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist));
3337                 }
3338             }
3339         }
3340         
3341         for (int i = 0; i < stdDev.size(); i++) {  //finds average.
3342             for (int j = 0; j < stdDev[i].size(); j++) {
3343                 stdDev[i][j].dist /= (float) calcDistsTotals.size();
3344                 stdDev[i][j].dist = sqrt(stdDev[i][j].dist);
3345             }
3346         }
3347
3348         return stdDev;
3349     }
3350         catch(exception& e) {
3351                 errorOut(e, "MothurOut", "getAverages");                
3352                 exit(1);
3353         }
3354 }
3355 /**************************************************************************************************/
3356 vector< vector<seqDist> > MothurOut::getStandardDeviation(vector< vector< vector<seqDist> > >& calcDistsTotals, vector< vector<seqDist> >& calcAverages) {
3357         try{
3358         //find standard deviation
3359         vector< vector<seqDist>  > stdDev;  
3360         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3361             vector<seqDist> temp;
3362             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3363                 seqDist tempDist;
3364                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3365                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3366                 tempDist.dist = 0.0;
3367                 temp.push_back(tempDist);
3368             }
3369             stdDev.push_back(temp);
3370         }
3371         
3372         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3373             for (int i = 0; i < stdDev.size(); i++) {  
3374                 for (int j = 0; j < stdDev[i].size(); j++) {
3375                     stdDev[i][j].dist += ((calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist) * (calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist));
3376                 }
3377             }
3378         }
3379         
3380         for (int i = 0; i < stdDev.size(); i++) {  //finds average.
3381             for (int j = 0; j < stdDev[i].size(); j++) {
3382                 stdDev[i][j].dist /= (float) calcDistsTotals.size();
3383                 stdDev[i][j].dist = sqrt(stdDev[i][j].dist);
3384             }
3385         }
3386         
3387         return stdDev;
3388     }
3389         catch(exception& e) {
3390                 errorOut(e, "MothurOut", "getAverages");                
3391                 exit(1);
3392         }
3393 }
3394
3395 /**************************************************************************************************/
3396 bool MothurOut::isContainingOnlyDigits(string input) {
3397         try{
3398                 
3399                 //are you a digit in ascii code
3400                 for (int i = 0;i < input.length(); i++){
3401                         if( input[i]>47 && input[i]<58){}
3402                         else { return false; }
3403                 }
3404                 
3405                 return true;
3406         }
3407         catch(exception& e) {
3408                 errorOut(e, "MothurOut", "isContainingOnlyDigits");             
3409                 exit(1);
3410         }
3411 }
3412 /**************************************************************************************************/
3413 int MothurOut::removeConfidences(string& tax) {
3414         try {
3415                 
3416                 string taxon;
3417                 string newTax = "";
3418                 
3419                 while (tax.find_first_of(';') != -1) {
3420                         
3421                         if (control_pressed) { return 0; }
3422                         
3423                         //get taxon
3424                         taxon = tax.substr(0,tax.find_first_of(';'));
3425         
3426                         int pos = taxon.find_last_of('(');
3427                         if (pos != -1) {
3428                                 //is it a number?
3429                                 int pos2 = taxon.find_last_of(')');
3430                                 if (pos2 != -1) {
3431                                         string confidenceScore = taxon.substr(pos+1, (pos2-(pos+1)));
3432                                         if (isNumeric1(confidenceScore)) {
3433                                                 taxon = taxon.substr(0, pos); //rip off confidence 
3434                                         }
3435                                 }
3436                         }
3437                         taxon += ";";
3438                         
3439                         tax = tax.substr(tax.find_first_of(';')+1, tax.length());
3440                         newTax += taxon;
3441                 }
3442                 
3443                 tax = newTax;
3444                 
3445                 return 0;
3446         }
3447         catch(exception& e) {
3448                 errorOut(e, "MothurOut", "removeConfidences");
3449                 exit(1);
3450         }
3451 }
3452 /**************************************************************************************************/
3453 string MothurOut::removeQuotes(string tax) {
3454         try {
3455                 
3456                 string taxon;
3457                 string newTax = "";
3458                 
3459                 for (int i = 0; i < tax.length(); i++) {
3460                         
3461                         if (control_pressed) { return newTax; }
3462             
3463             if ((tax[i] != '\'') && (tax[i] != '\"')) { newTax += tax[i]; }
3464                         
3465         }
3466                 
3467                 return newTax;
3468         }
3469         catch(exception& e) {
3470                 errorOut(e, "MothurOut", "removeQuotes");
3471                 exit(1);
3472         }
3473 }
3474 /**************************************************************************************************/
3475 // function for calculating standard deviation
3476 double MothurOut::getStandardDeviation(vector<int>& featureVector){
3477     try {
3478         //finds sum
3479         double average = 0; 
3480         for (int i = 0; i < featureVector.size(); i++) { average += featureVector[i]; }
3481         average /= (double) featureVector.size();
3482         
3483         //find standard deviation
3484         double stdDev = 0;
3485         for (int i = 0; i < featureVector.size(); i++) { //compute the difference of each dist from the mean, and square the result of each
3486             stdDev += ((featureVector[i] - average) * (featureVector[i] - average));
3487         }
3488           
3489         stdDev /= (double) featureVector.size(); 
3490         stdDev = sqrt(stdDev);
3491         
3492         return stdDev;
3493     }
3494         catch(exception& e) {
3495                 errorOut(e, "MothurOut", "getStandardDeviation");
3496                 exit(1);
3497         }
3498 }
3499 /**************************************************************************************************/
3500
3501
3502