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