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