]> git.donarmstrong.com Git - mothur.git/blob - mothur.h
fixed bug in bootstrap command that was caused by globaldata's breakup, and made...
[mothur.git] / mothur.h
1 #ifndef MOTHUR_H
2 #define MOTHUR_H
3
4
5
6 /*
7  *  mothur.h
8  *  Mothur
9  *
10  *  Created by Sarah Westcott on 2/19/09.
11  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
12  *
13  */
14
15 /* This file contains all the standard incudes we use in the project as well as some common utilities. */
16
17 //#include <cstddef>
18
19 //io libraries
20 #include <iostream>
21 #include <iomanip>
22 #include <fstream>
23 #include <sstream>
24
25 //exception
26 #include <stdexcept>
27 #include <exception>
28 #include <cstdlib> 
29
30
31 //containers
32 #include <vector>
33 #include <set>
34 #include <map>
35 #include <string>
36 #include <list>
37
38 //math
39 #include <cmath>
40 #include <math.h>
41 #include <algorithm>
42
43 //misc
44 #include <cerrno>
45 #include <ctime>
46 #include <limits>
47
48 using namespace std;
49
50 #ifdef _WIN32
51         #define exp(x) (exp((double) x))
52         #define sqrt(x) (sqrt((double) x))
53         #define log10(x) (log10((double) x))
54         #define log2(x) (log10(x)/log10(2))
55         #define isnan(x) ((x) != (x))
56         #define isinf(x) (fabs(x) == std::numeric_limits<double>::infinity())
57 #else
58         #include <sys/wait.h>
59         #include <unistd.h>
60 #endif
61
62
63 typedef unsigned long long ull;
64
65 struct IntNode {
66         int lvalue;
67         int rvalue;
68         int lcoef;
69         int rcoef;
70         IntNode* left;
71         IntNode* right;
72 };
73
74 struct ThreadNode {
75         int* pid;
76         IntNode* left;
77         IntNode* right;
78 };
79
80 /***********************************************************************/
81
82 // snagged from http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2
83 // works for now, but there should be a way to do it without killing the whole program
84
85 class BadConversion : public runtime_error {
86 public:
87         BadConversion(const string& s) : runtime_error(s){ }
88 };
89
90 //**********************************************************************************************************************
91
92 template<typename T>
93 inline void convert(const string& s, T& x, bool failIfLeftoverChars = true){
94         istringstream i(s);
95         char c;
96         if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
97                 throw BadConversion(s);
98 }
99 //**********************************************************************************************************************
100
101 template<typename T>
102 inline bool convertTestFloat(const string& s, T& x, bool failIfLeftoverChars = true){
103         istringstream i(s);
104         char c;
105         if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
106         {
107                 return false;
108         } 
109         return true;
110 }
111
112 //**********************************************************************************************************************
113
114 template<typename T>
115 inline bool convertTest(const string& s, T& x, bool failIfLeftoverChars = true){
116         istringstream i(s);
117         char c;
118         if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
119         {
120                 cout << "unable to be converted into an integer.\n" << endl;
121                 return false;
122         } 
123         return true;
124 }
125
126 //**********************************************************************************************************************
127
128 template<typename T>
129 string toString(const T&x){
130     stringstream output;
131     output << x;
132     return output.str();
133 }
134
135 //**********************************************************************************************************************
136
137 template<typename T>
138 string toHex(const T&x){
139         stringstream output;
140         
141         output << hex << x;
142
143     return output.str();
144 }
145 //**********************************************************************************************************************
146
147 template<typename T>
148 string toString(const T&x, int i){
149         stringstream output;
150         
151         output.precision(i);
152     output << fixed << x;
153         
154     return output.str();
155 }
156 /***********************************************************************/
157
158 inline int openOutputFileAppend(string fileName, ofstream& fileHandle){
159         
160         fileHandle.open(fileName.c_str(), ios::app);
161         if(!fileHandle) {
162                 cout << "Error: Could not open " <<  fileName << endl; 
163                 return 1;
164         }
165         else {
166                 return 0;
167         }
168
169 }
170
171 /**************************************************************************************************/
172
173 inline void mothurOut(string message) {
174         try{
175                 ofstream out;
176                 string logFileName = "mothur.logFile";
177                 openOutputFileAppend(logFileName, out);
178                 
179                 cout << message;
180                 out << message;
181                 
182                 out.close();
183         }
184         catch(exception& e) {
185                 cout << "Error in mothur class mothurOut" << endl;
186                 exit(1);
187         }
188 }
189 /**************************************************************************************************/
190
191 inline void mothurOut(string message, string precision) {
192         try{
193                 ofstream out;
194                 string logFileName = "mothur.logFile";
195                 openOutputFileAppend(logFileName, out);
196                 
197                 cout << precision << message;
198                 out << precision << message;
199                 
200                 out.close();
201         }
202         catch(exception& e) {
203                 cout << "Error in mothur class mothurOut" << endl;
204                 exit(1);
205         }
206 }
207
208 /**************************************************************************************************/
209
210 inline void mothurOutEndLine() {
211         try {
212                 ofstream out;
213                 string logFileName = "mothur.logFile";
214                 openOutputFileAppend(logFileName, out);
215                 
216                 cout << endl;  
217                 out << endl;
218                 
219                 out.close();
220         }
221         catch(exception& e) {
222                 cout << "error in mothur mothurOutEndLine" << endl;
223                 exit(1);
224         }
225 }
226
227
228 /**************************************************************************************************/
229
230 inline void errorOut(exception& e, string object, string function) {
231         
232                 mothurOut("Error: ");
233                 mothurOut(toString(e.what()));
234                 mothurOut(" has occurred in the " + object + " class function " + function + "Please contact Pat Schloss at pschloss@microbio.umass.edu, and be sure to include the mothur.logFile with your inquiry.");
235                 mothurOutEndLine();
236         
237 }
238
239
240
241
242 /***********************************************************************/
243
244 inline void gobble(istream& f){
245         
246         char d;
247     while(isspace(d=f.get()))           {;}
248         f.putback(d);
249         
250 }
251 /***********************************************************************/
252
253 inline bool isTrue(string f){
254         
255         if ((f == "TRUE") || (f == "T") || (f == "true") || (f == "t")) {       return true;    }
256         else {  return false;  }
257 }
258
259 /***********************************************************************/
260
261 inline float roundDist(float dist, int precision){
262         
263         return int(dist * precision + 0.5)/float(precision);
264         
265 }
266
267 /***********************************************************************/
268
269 inline int getNumNames(string names){
270         
271         int count = 0;
272         
273         if(names != ""){
274                 count = 1;
275                 for(int i=0;i<names.size();i++){
276                         if(names[i] == ','){
277                                 count++;
278                         }
279                 }
280         }
281         
282         return count;
283         
284 }
285
286 /**************************************************************************************************/
287
288 inline vector<vector<double> > binomial(int maxOrder){
289         
290         vector<vector<double> > binomial(maxOrder+1);
291         
292     for(int i=0;i<=maxOrder;i++){
293                 binomial[i].resize(maxOrder+1);
294                 binomial[i][0]=1;
295                 binomial[0][i]=0;
296     }
297     binomial[0][0]=1;
298         
299     binomial[1][0]=1;
300     binomial[1][1]=1;
301         
302     for(int i=2;i<=maxOrder;i++){
303                 binomial[1][i]=0;
304     }
305         
306     for(int i=2;i<=maxOrder;i++){
307                 for(int j=1;j<=maxOrder;j++){
308                         if(i==j){       binomial[i][j]=1;                                                                       }
309                         if(j>i) {       binomial[i][j]=0;                                                                       }
310                         else    {       binomial[i][j]=binomial[i-1][j-1]+binomial[i-1][j];     }
311                 }
312     }
313         
314         return binomial;
315 }
316
317 /***********************************************************************/
318
319 inline string getRootName(string longName){
320  
321         string rootName = longName;
322         
323         if(longName.find_last_of(".") != longName.npos){
324                 int pos = longName.find_last_of('.')+1;
325                 rootName = longName.substr(0, pos);
326         }
327
328         return rootName;
329 }
330 /***********************************************************************/
331
332 inline string getSimpleName(string longName){
333  
334         string simpleName = longName;
335         
336         if(longName.find_last_of("/") != longName.npos){
337                 int pos = longName.find_last_of('/')+1;
338                 simpleName = longName.substr(pos, longName.length());
339         }
340
341         return simpleName;
342 }
343
344 /***********************************************************************/
345
346 inline int factorial(int num){
347         int total = 1;
348         
349         for (int i = 1; i <= num; i++) {
350                 total *= i;
351         }
352         
353         return total;
354 }
355 /**************************************************************************************************
356
357 double min(double x, double y)
358 {
359     if(x<y){    return x;    }
360     else   {    return y;    }
361 }
362
363 /***********************************************************************/
364
365 inline string getPathName(string longName){
366  
367         string rootPathName = longName;
368         
369         if(longName.find_last_of('/') != longName.npos){
370                 int pos = longName.find_last_of('/')+1;
371                 rootPathName = longName.substr(0, pos);
372         }
373
374         return rootPathName;
375 }
376
377 /***********************************************************************/
378
379 inline string getExtension(string longName){
380         
381         string extension = longName;
382         
383         if(longName.find_last_of('.') != longName.npos){
384                 int pos = longName.find_last_of('.');
385                 extension = longName.substr(pos, longName.length());
386         }
387         
388         return extension;
389 }
390
391 /***********************************************************************/
392
393 inline int openInputFile(string fileName, ifstream& fileHandle){
394
395         fileHandle.open(fileName.c_str());
396         if(!fileHandle) {
397                 mothurOut("Error: Could not open " + fileName);  mothurOutEndLine();
398                 return 1;
399         }
400         else {
401                 return 0;
402         }
403         
404 }
405
406 /***********************************************************************/
407
408 inline int openOutputFile(string fileName, ofstream& fileHandle){
409         
410         fileHandle.open(fileName.c_str(), ios::trunc);
411         if(!fileHandle) {
412                 mothurOut("Error: Could not open " + fileName);  mothurOutEndLine();
413                 return 1;
414         }
415         else {
416                 return 0;
417         }
418
419 }
420
421 /***********************************************************************/
422
423 inline int getNumSeqs(ifstream& file){
424         
425         int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
426         file.seekg(0);
427         return numSeqs;
428
429 }
430
431 /***********************************************************************/
432
433 //This function parses the estimator options and puts them in a vector
434 inline void splitAtDash(string& estim, vector<string>& container) {
435         try {
436                 string individual;
437                 
438                 while (estim.find_first_of('-') != -1) {
439                         individual = estim.substr(0,estim.find_first_of('-'));
440                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
441                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
442                                 container.push_back(individual);
443                         }
444                 }
445                 //get last one
446                 container.push_back(estim);
447         }
448         catch(exception& e) {
449                 errorOut(e, "mothur", "splitAtDash");
450                 exit(1);
451         }
452 }
453
454 /***********************************************************************/
455 //This function parses the label options and puts them in a set
456 inline void splitAtDash(string& estim, set<string>& container) {
457         try {
458                 string individual;
459                 
460                 while (estim.find_first_of('-') != -1) {
461                         individual = estim.substr(0,estim.find_first_of('-'));
462                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
463                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
464                                 container.insert(individual);
465                         }
466                 }
467                 //get last one
468                 container.insert(estim);
469         }
470         catch(exception& e) {
471                 errorOut(e, "mothur", "splitAtDash");
472                 exit(1);
473         }
474 }
475 /***********************************************************************/
476 //This function parses the line options and puts them in a set
477 inline void splitAtDash(string& estim, set<int>& container) {
478         try {
479                 string individual;
480                 int lineNum;
481                 
482                 while (estim.find_first_of('-') != -1) {
483                         individual = estim.substr(0,estim.find_first_of('-'));
484                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
485                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
486                                 convert(individual, lineNum); //convert the string to int
487                                 container.insert(lineNum);
488                         }
489                 }
490                 //get last one
491                 convert(estim, lineNum); //convert the string to int
492                 container.insert(lineNum);
493         }
494         catch(exception& e) {
495                 errorOut(e, "mothur", "splitAtDash");
496                 exit(1);
497         }
498 }
499 /***********************************************************************/
500 //This function parses the a string and puts peices in a vector
501 inline void splitAtComma(string& estim, vector<string>& container) {
502         try {
503                 string individual;
504                 
505                 while (estim.find_first_of(',') != -1) {
506                         individual = estim.substr(0,estim.find_first_of(','));
507                         if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
508                                 estim = estim.substr(estim.find_first_of(',')+1, estim.length());
509                                 container.push_back(individual);
510                         }
511                 }
512                 //get last one
513                 container.push_back(estim);
514         }
515         catch(exception& e) {
516                 errorOut(e, "mothur", "splitAtComma");
517                 exit(1);
518         }
519 }
520 /***********************************************************************/
521
522 //This function splits up the various option parameters
523 inline void splitAtComma(string& prefix, string& suffix){
524         try {
525                 prefix = suffix.substr(0,suffix.find_first_of(','));
526                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
527                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
528                         string space = " ";
529                         while(suffix.at(0) == ' ')
530                                 suffix = suffix.substr(1, suffix.length());
531                 }
532
533         }
534         catch(exception& e) {
535                 errorOut(e, "mothur", "splitAtComma");
536                 exit(1);
537         }
538 }
539 /***********************************************************************/
540
541 //This function separates the key value from the option value i.e. dist=96_...
542 inline void splitAtEquals(string& key, string& value){          
543         try {
544                 if(value.find_first_of('=') != -1){
545                         key = value.substr(0,value.find_first_of('='));
546                         if ((value.find_first_of('=')+1) <= value.length()) {
547                                 value = value.substr(value.find_first_of('=')+1, value.length());
548                         }
549                 }else{
550                         key = value;
551                         value = 1;
552                 }
553         }
554         catch(exception& e) {
555                 errorOut(e, "mothur", "splitAtEquals");
556                 exit(1);
557         }
558 }
559 /**************************************************************************************************/
560
561 inline bool inUsersGroups(string groupname, vector<string> Groups) {
562         try {
563                 for (int i = 0; i < Groups.size(); i++) {
564                         if (groupname == Groups[i]) { return true; }
565                 }
566                 return false;
567         }
568         catch(exception& e) {
569                 errorOut(e, "mothur", "inUsersGroups");
570                 exit(1);
571         }
572 }
573
574 /**************************************************************************************************/
575
576 inline void mothurOutJustToLog(string message) {
577         try {
578                 ofstream out;
579                 string logFileName = "mothur.logFile";
580                 openOutputFileAppend(logFileName, out);
581                 
582                 out << message;
583                 
584                 out.close();
585         }
586         catch(exception& e) {
587                 errorOut(e, "mothur", "mothurOutJustToLog");
588                 exit(1);
589         }
590 }
591
592
593 /**************************************************************************************************/
594
595 inline void mothurOut(float num) {
596         try {
597                 ofstream out;
598                 string logFileName = "mothur.logFile";
599                 openOutputFileAppend(logFileName, out);
600                 
601                 cout << num;  
602                 out << num;
603                 
604                 out.close();
605         }
606         catch(exception& e) {
607                 cout << "Error in mothur class mothurOut float" << endl;
608                 exit(1);
609         }
610 }
611 /***********************************************************************/
612 inline void mothurOut(double value) {
613         try {
614                 ofstream out;
615                 string logFileName = "mothur.logFile";
616                 openOutputFileAppend(logFileName, out);
617                 
618                 cout << value;  
619                 out << value;
620                 
621                 out.close();
622         }
623         catch(exception& e) {
624                 cout << "Error in mothur class mothurOut double" << endl;
625                 exit(1);
626         }
627 }
628
629 /***********************************************************************/
630 //this function determines if the user has given us labels that are smaller than the given label.
631 //if so then it returns true so that the calling function can run the previous valid distance.
632 //it's a "smart" distance function.  It also checks for invalid labels.
633 inline bool anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
634         try {
635                 set<string>::iterator it;
636                 vector<float> orderFloat;
637                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
638                 map<string, float>::iterator it2;
639                 float labelFloat;
640                 bool smaller = false;
641                 
642                 //unique is the smallest line
643                 if (label == "unique") {  return false;  }
644                 else { convert(label, labelFloat); }
645                 
646                 //go through users set and make them floats
647                 for(it = userLabels.begin(); it != userLabels.end(); ++it) {
648                         
649                         float temp;
650                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
651                                 convert(*it, temp);
652                                 orderFloat.push_back(temp);
653                                 userMap[*it] = temp;
654                         }else if (*it == "unique") { 
655                                 orderFloat.push_back(-1.0);
656                                 userMap["unique"] = -1.0;
657                         }else {
658                                 if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
659                                 userLabels.erase(*it); 
660                                 it--;
661                         }
662                 }
663                 
664                 //sort order
665                 sort(orderFloat.begin(), orderFloat.end());
666                 
667                 /*************************************************/
668                 //is this label bigger than any of the users labels
669                 /*************************************************/
670                                 
671                 //loop through order until you find a label greater than label
672                 for (int i = 0; i < orderFloat.size(); i++) {
673                         if (orderFloat[i] < labelFloat) {
674                                 smaller = true;
675                                 if (orderFloat[i] == -1) { 
676                                         if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
677                                         userLabels.erase("unique");
678                                 }
679                                 else {  
680                                         if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
681                                         string s = "";
682                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
683                                                 if (it2->second == orderFloat[i]) {  
684                                                         s = it2->first;  
685                                                         //remove small labels
686                                                         userLabels.erase(s);
687                                                         break;
688                                                 }
689                                         }
690                                         if (errorOff == "") { mothurOut(s + ". I will use the next smallest distance. "); mothurOutEndLine(); }
691                                 }
692                         //since they are sorted once you find a bigger one stop looking
693                         }else { break; }
694                 }
695                 
696                 return smaller;
697                                                 
698         }
699         catch(exception& e) {
700                 errorOut(e, "mothur", "anyLabelsToProcess");
701                 exit(1);
702         }
703 }
704
705 /**************************************************************************************************/
706 #endif
707