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