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