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