]> git.donarmstrong.com Git - mothur.git/blob - mothurout.cpp
Merge remote-tracking branch 'mothur/master'
[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, using multiple processors, 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.  If you are using multiple processors, try running the command with processors=1, the more processors you use the more memory is required. 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         /*
2780                 for(int i=0;i<estimLength;i++){
2781                         if(prevEscape){
2782                                 individual += estim[i];
2783                                 prevEscape = false;
2784                         }
2785                         else{
2786                                 if(estim[i] == '\\'){
2787                                         prevEscape = true;
2788                                 }
2789                                 else if(estim[i] == '-'){
2790                                         container.insert(individual);
2791                                         individual = "";
2792                                         prevEscape = false;                             
2793                                 }
2794                                 else{
2795                                         individual += estim[i];
2796                                         prevEscape = false;
2797                                 }
2798                         }
2799                 }
2800                 */
2801         
2802         for(int i=0;i<estimLength;i++){
2803             if(estim[i] == '-'){
2804                 if (prevEscape) {  individual += estim[i]; prevEscape = false;  } //add in dash because it was escaped.
2805                 else {
2806                     container.insert(individual);
2807                     individual = "";
2808                 }
2809             }else if(estim[i] == '\\'){
2810                 if (i < estimLength-1) { 
2811                     if (estim[i+1] == '-') { prevEscape=true; }  //are you a backslash before a dash, if yes ignore
2812                     else { individual += estim[i]; prevEscape = false;  } //if no, add in
2813                 }else { individual += estim[i]; }
2814             }else {
2815                 individual += estim[i];
2816             }
2817         }
2818         container.insert(individual);
2819         
2820         }
2821         catch(exception& e) {
2822                 errorOut(e, "MothurOut", "splitAtDash");
2823                 exit(1);
2824         }       
2825 }
2826 /***********************************************************************/
2827 //This function parses the line options and puts them in a set
2828 void MothurOut::splitAtDash(string& estim, set<int>& container) {
2829         try {
2830                 string individual = "";
2831                 int lineNum;
2832                 int estimLength = estim.size();
2833                 bool prevEscape = false;
2834         /*
2835                 for(int i=0;i<estimLength;i++){
2836                         if(prevEscape){
2837                                 individual += estim[i];
2838                                 prevEscape = false;
2839                         }
2840                         else{
2841                                 if(estim[i] == '\\'){
2842                                         prevEscape = true;
2843                                 }
2844                                 else if(estim[i] == '-'){
2845                                         convert(individual, lineNum); //convert the string to int
2846                                         container.insert(lineNum);
2847                                         individual = "";
2848                                         prevEscape = false;                             
2849                                 }
2850                                 else{
2851                                         individual += estim[i];
2852                                         prevEscape = false;
2853                                 }
2854                         }
2855                 }*/
2856         
2857         for(int i=0;i<estimLength;i++){
2858             if(estim[i] == '-'){
2859                 if (prevEscape) {  individual += estim[i]; prevEscape = false;  } //add in dash because it was escaped.
2860                 else {
2861                     convert(individual, lineNum); //convert the string to int
2862                     container.insert(lineNum);
2863                     individual = "";
2864                 }
2865             }else if(estim[i] == '\\'){
2866                 if (i < estimLength-1) { 
2867                     if (estim[i+1] == '-') { prevEscape=true; }  //are you a backslash before a dash, if yes ignore
2868                     else { individual += estim[i]; prevEscape = false;  } //if no, add in
2869                 }else { individual += estim[i]; }
2870             }else {
2871                 individual += estim[i];
2872             }
2873         }
2874         
2875                 convert(individual, lineNum); //convert the string to int
2876                 container.insert(lineNum);
2877         }
2878         catch(exception& e) {
2879                 errorOut(e, "MothurOut", "splitAtDash");
2880                 exit(1);
2881         }       
2882 }
2883
2884 /***********************************************************************/
2885 string MothurOut::makeList(vector<string>& names) {
2886         try {
2887                 string list = "";
2888         
2889         if (names.size() == 0) { return list; }
2890                 
2891         for (int i = 0; i < names.size()-1; i++) { list += names[i] + ",";  }
2892         
2893         //get last name
2894         list += names[names.size()-1];
2895         
2896         return list;
2897     }
2898         catch(exception& e) {
2899                 errorOut(e, "MothurOut", "makeList");
2900                 exit(1);
2901         }       
2902 }
2903
2904 /***********************************************************************/
2905 //This function parses the a string and puts peices in a vector
2906 void MothurOut::splitAtComma(string& estim, vector<string>& container) {
2907         try {
2908                 string individual = "";
2909                 int estimLength = estim.size();
2910                 for(int i=0;i<estimLength;i++){
2911                         if(estim[i] == ','){
2912                                 container.push_back(individual);
2913                                 individual = "";                                
2914                         }
2915                         else{
2916                                 individual += estim[i];
2917                         }
2918                 }
2919                 container.push_back(individual);
2920                 
2921                 
2922                 
2923                 
2924 //              string individual;
2925 //              
2926 //              while (estim.find_first_of(',') != -1) {
2927 //                      individual = estim.substr(0,estim.find_first_of(','));
2928 //                      if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
2929 //                              estim = estim.substr(estim.find_first_of(',')+1, estim.length());
2930 //                              container.push_back(individual);
2931 //                      }
2932 //              }
2933 //              //get last one
2934 //              container.push_back(estim);
2935         }
2936         catch(exception& e) {
2937                 errorOut(e, "MothurOut", "splitAtComma");
2938                 exit(1);
2939         }       
2940 }
2941 /***********************************************************************/
2942 //This function splits up the various option parameters
2943 void MothurOut::splitAtChar(string& prefix, string& suffix, char c){
2944         try {
2945                 prefix = suffix.substr(0,suffix.find_first_of(c));
2946                 if ((suffix.find_first_of(c)+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
2947                         suffix = suffix.substr(suffix.find_first_of(c)+1, suffix.length());
2948                         string space = " ";
2949                         while(suffix.at(0) == ' ')
2950                                 suffix = suffix.substr(1, suffix.length());
2951                 }else {  suffix = "";  }
2952         
2953     }
2954         catch(exception& e) {
2955                 errorOut(e, "MothurOut", "splitAtChar");
2956                 exit(1);
2957         }       
2958 }
2959
2960 /***********************************************************************/
2961
2962 //This function splits up the various option parameters
2963 void MothurOut::splitAtComma(string& prefix, string& suffix){
2964         try {
2965                 prefix = suffix.substr(0,suffix.find_first_of(','));
2966                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
2967                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
2968                         string space = " ";
2969                         while(suffix.at(0) == ' ')
2970                                 suffix = suffix.substr(1, suffix.length());
2971                 }else {  suffix = "";  }
2972
2973         }
2974         catch(exception& e) {
2975                 errorOut(e, "MothurOut", "splitAtComma");
2976                 exit(1);
2977         }       
2978 }
2979 /***********************************************************************/
2980
2981 //This function separates the key value from the option value i.e. dist=96_...
2982 void MothurOut::splitAtEquals(string& key, string& value){              
2983         try {
2984                 if(value.find_first_of('=') != -1){
2985                         key = value.substr(0,value.find_first_of('='));
2986                         if ((value.find_first_of('=')+1) <= value.length()) {
2987                                 value = value.substr(value.find_first_of('=')+1, value.length());
2988                         }
2989                 }else{
2990                         key = value;
2991                         value = 1;
2992                 }
2993         }
2994         catch(exception& e) {
2995                 errorOut(e, "MothurOut", "splitAtEquals");
2996                 exit(1);
2997         }       
2998 }
2999
3000 /**************************************************************************************************/
3001
3002 bool MothurOut::inUsersGroups(string groupname, vector<string> Groups) {
3003         try {
3004                 for (int i = 0; i < Groups.size(); i++) {
3005                         if (groupname == Groups[i]) { return true; }
3006                 }
3007                 return false;
3008         }
3009         catch(exception& e) {
3010                 errorOut(e, "MothurOut", "inUsersGroups");
3011                 exit(1);
3012         }       
3013 }
3014 /**************************************************************************************************/
3015
3016 bool MothurOut::inUsersGroups(vector<int> set, vector< vector<int> > sets) {
3017         try {
3018                 for (int i = 0; i < sets.size(); i++) {
3019                         if (set == sets[i]) { return true; }
3020                 }
3021                 return false;
3022         }
3023         catch(exception& e) {
3024                 errorOut(e, "MothurOut", "inUsersGroups");
3025                 exit(1);
3026         }       
3027 }
3028 /**************************************************************************************************/
3029
3030 bool MothurOut::inUsersGroups(int groupname, vector<int> Groups) {
3031         try {
3032                 for (int i = 0; i < Groups.size(); i++) {
3033                         if (groupname == Groups[i]) { return true; }
3034                 }
3035                 return false;
3036         }
3037         catch(exception& e) {
3038                 errorOut(e, "MothurOut", "inUsersGroups");
3039                 exit(1);
3040         }       
3041 }
3042
3043 /**************************************************************************************************/
3044 //returns true if any of the strings in first vector are in second vector
3045 bool MothurOut::inUsersGroups(vector<string> groupnames, vector<string> Groups) {
3046         try {
3047                 
3048                 for (int i = 0; i < groupnames.size(); i++) {
3049                         if (inUsersGroups(groupnames[i], Groups)) { return true; }
3050                 }
3051                 return false;
3052         }
3053         catch(exception& e) {
3054                 errorOut(e, "MothurOut", "inUsersGroups");
3055                 exit(1);
3056         }       
3057 }
3058 /***********************************************************************/
3059 //this function determines if the user has given us labels that are smaller than the given label.
3060 //if so then it returns true so that the calling function can run the previous valid distance.
3061 //it's a "smart" distance function.  It also checks for invalid labels.
3062 bool MothurOut::anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
3063         try {
3064                 
3065                 set<string>::iterator it;
3066                 vector<float> orderFloat;
3067                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
3068                 map<string, float>::iterator it2;
3069                 float labelFloat;
3070                 bool smaller = false;
3071                 
3072                 //unique is the smallest line
3073                 if (label == "unique") {  return false;  }
3074                 else { 
3075                         if (convertTestFloat(label, labelFloat)) {
3076                                 convert(label, labelFloat); 
3077                         }else { //cant convert 
3078                                 return false;
3079                         }
3080                 }
3081                 
3082                 //go through users set and make them floats
3083                 for(it = userLabels.begin(); it != userLabels.end();) {
3084                         
3085                         float temp;
3086                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
3087                                 convert(*it, temp);
3088                                 orderFloat.push_back(temp);
3089                                 userMap[*it] = temp;
3090                                 it++;
3091                         }else if (*it == "unique") { 
3092                                 orderFloat.push_back(-1.0);
3093                                 userMap["unique"] = -1.0;
3094                                 it++;
3095                         }else {
3096                                 if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
3097                                 userLabels.erase(it++); 
3098                         }
3099                 }
3100                 
3101                 //sort order
3102                 sort(orderFloat.begin(), orderFloat.end());
3103                 
3104                 /*************************************************/
3105                 //is this label bigger than any of the users labels
3106                 /*************************************************/
3107                                 
3108                 //loop through order until you find a label greater than label
3109                 for (int i = 0; i < orderFloat.size(); i++) {
3110                         if (orderFloat[i] < labelFloat) {
3111                                 smaller = true;
3112                                 if (orderFloat[i] == -1) { 
3113                                         if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
3114                                         userLabels.erase("unique");
3115                                 }
3116                                 else {  
3117                                         if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
3118                                         string s = "";
3119                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
3120                                                 if (it2->second == orderFloat[i]) {  
3121                                                         s = it2->first;  
3122                                                         //remove small labels
3123                                                         userLabels.erase(s);
3124                                                         break;
3125                                                 }
3126                                         }
3127                                         if (errorOff == "") {mothurOut( s +  ". I will use the next smallest distance. "); mothurOutEndLine(); }
3128                                 }
3129                         //since they are sorted once you find a bigger one stop looking
3130                         }else { break; }
3131                 }
3132                 
3133                 return smaller;
3134                                                 
3135         }
3136         catch(exception& e) {
3137                 errorOut(e, "MothurOut", "anyLabelsToProcess");
3138                 exit(1);
3139         }       
3140 }
3141
3142 /**************************************************************************************************/
3143 bool MothurOut::checkReleaseVersion(ifstream& file, string version) {
3144         try {
3145                 
3146                 bool good = true;
3147                 
3148                 string line = getline(file);  
3149
3150                 //before we added this check
3151                 if (line[0] != '#') {  good = false;  }
3152                 else {
3153                         //rip off #
3154                         line = line.substr(1);
3155                         
3156                         vector<string> versionVector;
3157                         splitAtChar(version, versionVector, '.');
3158                         
3159                         //check file version
3160                         vector<string> linesVector;
3161                         splitAtChar(line, linesVector, '.');
3162                         
3163                         if (versionVector.size() != linesVector.size()) { good = false; }
3164                         else {
3165                                 for (int j = 0; j < versionVector.size(); j++) {
3166                                         int num1, num2;
3167                                         convert(versionVector[j], num1);
3168                                         convert(linesVector[j], num2);
3169                                         
3170                                         //if mothurs version is newer than this files version, then we want to remake it
3171                                         if (num1 > num2) {  good = false; break;  }
3172                                 }
3173                         }
3174                         
3175                 }
3176                 
3177                 if (!good) {  file.close();  }
3178                 else { file.seekg(0);  }
3179                 
3180                 return good;
3181         }
3182         catch(exception& e) {
3183                 errorOut(e, "MothurOut", "checkReleaseVersion");                
3184                 exit(1);
3185         }
3186 }
3187 /**************************************************************************************************/
3188 vector<double> MothurOut::getAverages(vector< vector<double> >& dists) {
3189         try{
3190         vector<double> averages; //averages.resize(numComp, 0.0);
3191         for (int i = 0; i < dists[0].size(); i++) { averages.push_back(0.0); }
3192       
3193         for (int thisIter = 0; thisIter < dists.size(); thisIter++) {
3194             for (int i = 0; i < dists[thisIter].size(); i++) {  
3195                 averages[i] += dists[thisIter][i];
3196             }
3197         }
3198         
3199         //finds average.
3200         for (int i = 0; i < averages.size(); i++) {  averages[i] /= (double) dists.size(); }
3201         
3202         return averages;
3203     }
3204         catch(exception& e) {
3205                 errorOut(e, "MothurOut", "getAverages");                
3206                 exit(1);
3207         }
3208 }
3209 /**************************************************************************************************/
3210 vector<double> MothurOut::getStandardDeviation(vector< vector<double> >& dists) {
3211         try{
3212         
3213         vector<double> averages = getAverages(dists);
3214         
3215         //find standard deviation
3216         vector<double> stdDev; //stdDev.resize(numComp, 0.0);
3217         for (int i = 0; i < dists[0].size(); i++) { stdDev.push_back(0.0); }
3218         
3219         for (int thisIter = 0; thisIter < dists.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3220             for (int j = 0; j < dists[thisIter].size(); j++) {
3221                 stdDev[j] += ((dists[thisIter][j] - averages[j]) * (dists[thisIter][j] - averages[j]));
3222             }
3223         }
3224         for (int i = 0; i < stdDev.size(); i++) {  
3225             stdDev[i] /= (double) dists.size(); 
3226             stdDev[i] = sqrt(stdDev[i]);
3227         }
3228         
3229         return stdDev;
3230     }
3231         catch(exception& e) {
3232                 errorOut(e, "MothurOut", "getAverages");                
3233                 exit(1);
3234         }
3235 }
3236 /**************************************************************************************************/
3237 vector<double> MothurOut::getStandardDeviation(vector< vector<double> >& dists, vector<double>& averages) {
3238         try{
3239         //find standard deviation
3240         vector<double> stdDev; //stdDev.resize(numComp, 0.0);
3241         for (int i = 0; i < dists[0].size(); i++) { stdDev.push_back(0.0); }
3242         
3243         for (int thisIter = 0; thisIter < dists.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3244             for (int j = 0; j < dists[thisIter].size(); j++) {
3245                 stdDev[j] += ((dists[thisIter][j] - averages[j]) * (dists[thisIter][j] - averages[j]));
3246             }
3247         }
3248         for (int i = 0; i < stdDev.size(); i++) {  
3249             stdDev[i] /= (double) dists.size(); 
3250             stdDev[i] = sqrt(stdDev[i]);
3251         }
3252         
3253         return stdDev;
3254     }
3255         catch(exception& e) {
3256                 errorOut(e, "MothurOut", "getAverages");                
3257                 exit(1);
3258         }
3259 }
3260 /**************************************************************************************************/
3261 vector< vector<seqDist> > MothurOut::getAverages(vector< vector< vector<seqDist> > >& calcDistsTotals, string mode) {
3262         try{
3263         
3264         vector< vector<seqDist>  > calcAverages; //calcAverages.resize(calcDistsTotals[0].size()); 
3265         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3266             //calcAverages[i].resize(calcDistsTotals[0][i].size());
3267             vector<seqDist> temp;
3268             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3269                 seqDist tempDist;
3270                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3271                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3272                 tempDist.dist = 0.0;
3273                 temp.push_back(tempDist);
3274             }
3275             calcAverages.push_back(temp);
3276         }
3277         
3278         if (mode == "average") {
3279             for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //sum all groups dists for each calculator
3280                 for (int i = 0; i < calcAverages.size(); i++) {  //initialize sums to zero.
3281                     for (int j = 0; j < calcAverages[i].size(); j++) {
3282                         calcAverages[i][j].dist += calcDistsTotals[thisIter][i][j].dist;
3283                     }
3284                 }
3285             }
3286             
3287             for (int i = 0; i < calcAverages.size(); i++) {  //finds average.
3288                 for (int j = 0; j < calcAverages[i].size(); j++) {
3289                     calcAverages[i][j].dist /= (float) calcDistsTotals.size();
3290                 }
3291             }
3292         }else { //find median
3293             for (int i = 0; i < calcAverages.size(); i++) { //for each calc
3294                 for (int j = 0; j < calcAverages[i].size(); j++) {  //for each comparison
3295                     vector<double> dists;
3296                     for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //for each subsample
3297                         dists.push_back(calcDistsTotals[thisIter][i][j].dist);
3298                     }
3299                     sort(dists.begin(), dists.end());
3300                     calcAverages[i][j].dist = dists[(calcDistsTotals.size()/2)];
3301                 }
3302             }
3303         }
3304
3305         return calcAverages;
3306     }
3307         catch(exception& e) {
3308                 errorOut(e, "MothurOut", "getAverages");                
3309                 exit(1);
3310         }
3311 }
3312 /**************************************************************************************************/
3313 vector< vector<seqDist> > MothurOut::getAverages(vector< vector< vector<seqDist> > >& calcDistsTotals) {
3314         try{
3315         
3316         vector< vector<seqDist>  > calcAverages; //calcAverages.resize(calcDistsTotals[0].size()); 
3317         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3318             //calcAverages[i].resize(calcDistsTotals[0][i].size());
3319             vector<seqDist> temp;
3320             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3321                 seqDist tempDist;
3322                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3323                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3324                 tempDist.dist = 0.0;
3325                 temp.push_back(tempDist);
3326             }
3327             calcAverages.push_back(temp);
3328         }
3329         
3330         
3331         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //sum all groups dists for each calculator
3332                 for (int i = 0; i < calcAverages.size(); i++) {  //initialize sums to zero.
3333                     for (int j = 0; j < calcAverages[i].size(); j++) {
3334                         calcAverages[i][j].dist += calcDistsTotals[thisIter][i][j].dist;
3335                     }
3336                 }
3337         }
3338             
3339         for (int i = 0; i < calcAverages.size(); i++) {  //finds average.
3340                 for (int j = 0; j < calcAverages[i].size(); j++) {
3341                     calcAverages[i][j].dist /= (float) calcDistsTotals.size();
3342                 }
3343         }
3344         
3345         return calcAverages;
3346     }
3347         catch(exception& e) {
3348                 errorOut(e, "MothurOut", "getAverages");                
3349                 exit(1);
3350         }
3351 }
3352 /**************************************************************************************************/
3353 vector< vector<seqDist> > MothurOut::getStandardDeviation(vector< vector< vector<seqDist> > >& calcDistsTotals) {
3354         try{
3355         
3356         vector< vector<seqDist> > calcAverages = getAverages(calcDistsTotals);
3357         
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 vector< vector<seqDist> > MothurOut::getStandardDeviation(vector< vector< vector<seqDist> > >& calcDistsTotals, vector< vector<seqDist> >& calcAverages) {
3396         try{
3397         //find standard deviation
3398         vector< vector<seqDist>  > stdDev;  
3399         for (int i = 0; i < calcDistsTotals[0].size(); i++) {  //initialize sums to zero.
3400             vector<seqDist> temp;
3401             for (int j = 0; j < calcDistsTotals[0][i].size(); j++) {
3402                 seqDist tempDist;
3403                 tempDist.seq1 = calcDistsTotals[0][i][j].seq1;
3404                 tempDist.seq2 = calcDistsTotals[0][i][j].seq2;
3405                 tempDist.dist = 0.0;
3406                 temp.push_back(tempDist);
3407             }
3408             stdDev.push_back(temp);
3409         }
3410         
3411         for (int thisIter = 0; thisIter < calcDistsTotals.size(); thisIter++) { //compute the difference of each dist from the mean, and square the result of each
3412             for (int i = 0; i < stdDev.size(); i++) {  
3413                 for (int j = 0; j < stdDev[i].size(); j++) {
3414                     stdDev[i][j].dist += ((calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist) * (calcDistsTotals[thisIter][i][j].dist - calcAverages[i][j].dist));
3415                 }
3416             }
3417         }
3418         
3419         for (int i = 0; i < stdDev.size(); i++) {  //finds average.
3420             for (int j = 0; j < stdDev[i].size(); j++) {
3421                 stdDev[i][j].dist /= (float) calcDistsTotals.size();
3422                 stdDev[i][j].dist = sqrt(stdDev[i][j].dist);
3423             }
3424         }
3425         
3426         return stdDev;
3427     }
3428         catch(exception& e) {
3429                 errorOut(e, "MothurOut", "getAverages");                
3430                 exit(1);
3431         }
3432 }
3433
3434 /**************************************************************************************************/
3435 bool MothurOut::isContainingOnlyDigits(string input) {
3436         try{
3437                 
3438                 //are you a digit in ascii code
3439                 for (int i = 0;i < input.length(); i++){
3440                         if( input[i]>47 && input[i]<58){}
3441                         else { return false; }
3442                 }
3443                 
3444                 return true;
3445         }
3446         catch(exception& e) {
3447                 errorOut(e, "MothurOut", "isContainingOnlyDigits");             
3448                 exit(1);
3449         }
3450 }
3451 /**************************************************************************************************/
3452 int MothurOut::removeConfidences(string& tax) {
3453         try {
3454                 
3455                 string taxon;
3456                 string newTax = "";
3457                 
3458                 while (tax.find_first_of(';') != -1) {
3459                         
3460                         if (control_pressed) { return 0; }
3461                         
3462                         //get taxon
3463                         taxon = tax.substr(0,tax.find_first_of(';'));
3464         
3465                         int pos = taxon.find_last_of('(');
3466                         if (pos != -1) {
3467                                 //is it a number?
3468                                 int pos2 = taxon.find_last_of(')');
3469                                 if (pos2 != -1) {
3470                                         string confidenceScore = taxon.substr(pos+1, (pos2-(pos+1)));
3471                                         if (isNumeric1(confidenceScore)) {
3472                                                 taxon = taxon.substr(0, pos); //rip off confidence 
3473                                         }
3474                                 }
3475                         }
3476                         taxon += ";";
3477                         
3478                         tax = tax.substr(tax.find_first_of(';')+1, tax.length());
3479                         newTax += taxon;
3480                 }
3481                 
3482                 tax = newTax;
3483                 
3484                 return 0;
3485         }
3486         catch(exception& e) {
3487                 errorOut(e, "MothurOut", "removeConfidences");
3488                 exit(1);
3489         }
3490 }
3491 /**************************************************************************************************/
3492 string MothurOut::removeQuotes(string tax) {
3493         try {
3494                 
3495                 string taxon;
3496                 string newTax = "";
3497                 
3498                 for (int i = 0; i < tax.length(); i++) {
3499                         
3500                         if (control_pressed) { return newTax; }
3501             
3502             if ((tax[i] != '\'') && (tax[i] != '\"')) { newTax += tax[i]; }
3503                         
3504         }
3505                 
3506                 return newTax;
3507         }
3508         catch(exception& e) {
3509                 errorOut(e, "MothurOut", "removeQuotes");
3510                 exit(1);
3511         }
3512 }
3513 /**************************************************************************************************/
3514 // function for calculating standard deviation
3515 double MothurOut::getStandardDeviation(vector<int>& featureVector){
3516     try {
3517         //finds sum
3518         double average = 0; 
3519         for (int i = 0; i < featureVector.size(); i++) { average += featureVector[i]; }
3520         average /= (double) featureVector.size();
3521         
3522         //find standard deviation
3523         double stdDev = 0;
3524         for (int i = 0; i < featureVector.size(); i++) { //compute the difference of each dist from the mean, and square the result of each
3525             stdDev += ((featureVector[i] - average) * (featureVector[i] - average));
3526         }
3527           
3528         stdDev /= (double) featureVector.size(); 
3529         stdDev = sqrt(stdDev);
3530         
3531         return stdDev;
3532     }
3533         catch(exception& e) {
3534                 errorOut(e, "MothurOut", "getStandardDeviation");
3535                 exit(1);
3536         }
3537 }
3538 /**************************************************************************************************/
3539
3540
3541