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