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