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