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