]> git.donarmstrong.com Git - mothur.git/blob - mothur.h
added getline function to mothur and modified places where we use getline to use...
[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 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 inline string getline(ifstream& fileHandle) {
173         try {
174         
175                 string line = "";
176                 
177                 while (!fileHandle.eof())       {
178                         //get next character
179                         char c = fileHandle.get(); 
180                         
181                         //are you at the end of the line
182                         if (c == 10 || c == 13){   break;       }       
183                         else {          line += c;              }
184                 }
185                 
186                 return line;
187                 
188         }
189         catch(exception& e) {
190                 cout << "Error in mothur function getline" << endl;
191                 exit(1);
192         }
193 }
194
195 /**************************************************************************************************/
196
197 inline void mothurOut(string message) {
198         try{
199                 ofstream out;
200                 string logFileName = "mothur.logFile";
201                 openOutputFileAppend(logFileName, out);
202                 
203                 cout << message;
204                 out << message;
205                 
206                 out.close();
207         }
208         catch(exception& e) {
209                 cout << "Error in mothur class mothurOut" << endl;
210                 exit(1);
211         }
212 }
213 /**************************************************************************************************/
214
215 inline void mothurOut(string message, string precision) {
216         try{
217                 ofstream out;
218                 string logFileName = "mothur.logFile";
219                 openOutputFileAppend(logFileName, out);
220                 
221                 cout << precision << message;
222                 out << precision << message;
223                 
224                 out.close();
225         }
226         catch(exception& e) {
227                 cout << "Error in mothur class mothurOut" << endl;
228                 exit(1);
229         }
230 }
231
232 /**************************************************************************************************/
233
234 inline void mothurOutEndLine() {
235         try {
236                 ofstream out;
237                 string logFileName = "mothur.logFile";
238                 openOutputFileAppend(logFileName, out);
239                 
240                 cout << endl;  
241                 out << endl;
242                 
243                 out.close();
244         }
245         catch(exception& e) {
246                 cout << "error in mothur mothurOutEndLine" << endl;
247                 exit(1);
248         }
249 }
250
251
252 /**************************************************************************************************/
253
254 inline void errorOut(exception& e, string object, string function) {
255         
256                 mothurOut("Error: ");
257                 mothurOut(toString(e.what()));
258                 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.");
259                 mothurOutEndLine();
260         
261 }
262
263
264
265
266 /***********************************************************************/
267
268 inline void gobble(istream& f){
269         
270         char d;
271     while(isspace(d=f.get()))           {;}
272         f.putback(d);
273         
274 }
275 /***********************************************************************/
276
277 inline bool isTrue(string f){
278         
279         if ((f == "TRUE") || (f == "T") || (f == "true") || (f == "t")) {       return true;    }
280         else {  return false;  }
281 }
282
283 /***********************************************************************/
284
285 inline float roundDist(float dist, int precision){
286         
287         return int(dist * precision + 0.5)/float(precision);
288         
289 }
290
291 /***********************************************************************/
292
293 inline int getNumNames(string names){
294         
295         int count = 0;
296         
297         if(names != ""){
298                 count = 1;
299                 for(int i=0;i<names.size();i++){
300                         if(names[i] == ','){
301                                 count++;
302                         }
303                 }
304         }
305         
306         return count;
307         
308 }
309
310 /**************************************************************************************************/
311
312 inline vector<vector<double> > binomial(int maxOrder){
313         
314         vector<vector<double> > binomial(maxOrder+1);
315         
316     for(int i=0;i<=maxOrder;i++){
317                 binomial[i].resize(maxOrder+1);
318                 binomial[i][0]=1;
319                 binomial[0][i]=0;
320     }
321     binomial[0][0]=1;
322         
323     binomial[1][0]=1;
324     binomial[1][1]=1;
325         
326     for(int i=2;i<=maxOrder;i++){
327                 binomial[1][i]=0;
328     }
329         
330     for(int i=2;i<=maxOrder;i++){
331                 for(int j=1;j<=maxOrder;j++){
332                         if(i==j){       binomial[i][j]=1;                                                                       }
333                         if(j>i) {       binomial[i][j]=0;                                                                       }
334                         else    {       binomial[i][j]=binomial[i-1][j-1]+binomial[i-1][j];     }
335                 }
336     }
337         
338         return binomial;
339 }
340
341 /***********************************************************************/
342
343 inline string getRootName(string longName){
344  
345         string rootName = longName;
346         
347         if(longName.find_last_of(".") != longName.npos){
348                 int pos = longName.find_last_of('.')+1;
349                 rootName = longName.substr(0, pos);
350         }
351
352         return rootName;
353 }
354 /***********************************************************************/
355
356 inline string getSimpleName(string longName){
357  
358         string simpleName = longName;
359         
360         if(longName.find_last_of("/") != longName.npos){
361                 int pos = longName.find_last_of('/')+1;
362                 simpleName = longName.substr(pos, longName.length());
363         }
364
365         return simpleName;
366 }
367
368 /***********************************************************************/
369
370 inline int factorial(int num){
371         int total = 1;
372         
373         for (int i = 1; i <= num; i++) {
374                 total *= i;
375         }
376         
377         return total;
378 }
379 /**************************************************************************************************
380
381 double min(double x, double y)
382 {
383     if(x<y){    return x;    }
384     else   {    return y;    }
385 }
386
387 /***********************************************************************/
388
389 inline string getPathName(string longName){
390  
391         string rootPathName = longName;
392         
393         if(longName.find_last_of('/') != longName.npos){
394                 int pos = longName.find_last_of('/')+1;
395                 rootPathName = longName.substr(0, pos);
396         }
397
398         return rootPathName;
399 }
400
401 /***********************************************************************/
402
403 inline string getExtension(string longName){
404         
405         string extension = longName;
406         
407         if(longName.find_last_of('.') != longName.npos){
408                 int pos = longName.find_last_of('.');
409                 extension = longName.substr(pos, longName.length());
410         }
411         
412         return extension;
413 }
414
415 /***********************************************************************/
416
417 inline int openInputFile(string fileName, ifstream& fileHandle){
418
419         fileHandle.open(fileName.c_str());
420         if(!fileHandle) {
421                 mothurOut("Error: Could not open " + fileName);  mothurOutEndLine();
422                 return 1;
423         }
424         else {
425                 return 0;
426         }
427         
428 }
429
430 /***********************************************************************/
431
432 inline int openOutputFile(string fileName, ofstream& fileHandle){
433         
434         fileHandle.open(fileName.c_str(), ios::trunc);
435         if(!fileHandle) {
436                 mothurOut("Error: Could not open " + fileName);  mothurOutEndLine();
437                 return 1;
438         }
439         else {
440                 return 0;
441         }
442
443 }
444
445 /***********************************************************************/
446
447 inline int getNumSeqs(ifstream& file){
448         
449         int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
450         file.seekg(0);
451         return numSeqs;
452
453 }
454
455 /***********************************************************************/
456
457 //This function parses the estimator options and puts them in a vector
458 inline void splitAtDash(string& estim, vector<string>& container) {
459         try {
460                 string individual;
461                 
462                 while (estim.find_first_of('-') != -1) {
463                         individual = estim.substr(0,estim.find_first_of('-'));
464                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
465                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
466                                 container.push_back(individual);
467                         }
468                 }
469                 //get last one
470                 container.push_back(estim);
471         }
472         catch(exception& e) {
473                 errorOut(e, "mothur", "splitAtDash");
474                 exit(1);
475         }
476 }
477
478 /***********************************************************************/
479 //This function parses the label options and puts them in a set
480 inline void splitAtDash(string& estim, set<string>& container) {
481         try {
482                 string individual;
483                 
484                 while (estim.find_first_of('-') != -1) {
485                         individual = estim.substr(0,estim.find_first_of('-'));
486                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
487                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
488                                 container.insert(individual);
489                         }
490                 }
491                 //get last one
492                 container.insert(estim);
493         }
494         catch(exception& e) {
495                 errorOut(e, "mothur", "splitAtDash");
496                 exit(1);
497         }
498 }
499 /***********************************************************************/
500 //This function parses the line options and puts them in a set
501 inline void splitAtDash(string& estim, set<int>& container) {
502         try {
503                 string individual;
504                 int lineNum;
505                 
506                 while (estim.find_first_of('-') != -1) {
507                         individual = estim.substr(0,estim.find_first_of('-'));
508                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
509                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
510                                 convert(individual, lineNum); //convert the string to int
511                                 container.insert(lineNum);
512                         }
513                 }
514                 //get last one
515                 convert(estim, lineNum); //convert the string to int
516                 container.insert(lineNum);
517         }
518         catch(exception& e) {
519                 errorOut(e, "mothur", "splitAtDash");
520                 exit(1);
521         }
522 }
523 /***********************************************************************/
524 //This function parses the a string and puts peices in a vector
525 inline void splitAtComma(string& estim, vector<string>& container) {
526         try {
527                 string individual;
528                 
529                 while (estim.find_first_of(',') != -1) {
530                         individual = estim.substr(0,estim.find_first_of(','));
531                         if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
532                                 estim = estim.substr(estim.find_first_of(',')+1, estim.length());
533                                 container.push_back(individual);
534                         }
535                 }
536                 //get last one
537                 container.push_back(estim);
538         }
539         catch(exception& e) {
540                 errorOut(e, "mothur", "splitAtComma");
541                 exit(1);
542         }
543 }
544 /***********************************************************************/
545
546 //This function splits up the various option parameters
547 inline void splitAtComma(string& prefix, string& suffix){
548         try {
549                 prefix = suffix.substr(0,suffix.find_first_of(','));
550                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
551                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
552                         string space = " ";
553                         while(suffix.at(0) == ' ')
554                                 suffix = suffix.substr(1, suffix.length());
555                 }
556
557         }
558         catch(exception& e) {
559                 errorOut(e, "mothur", "splitAtComma");
560                 exit(1);
561         }
562 }
563 /***********************************************************************/
564
565 //This function separates the key value from the option value i.e. dist=96_...
566 inline void splitAtEquals(string& key, string& value){          
567         try {
568                 if(value.find_first_of('=') != -1){
569                         key = value.substr(0,value.find_first_of('='));
570                         if ((value.find_first_of('=')+1) <= value.length()) {
571                                 value = value.substr(value.find_first_of('=')+1, value.length());
572                         }
573                 }else{
574                         key = value;
575                         value = 1;
576                 }
577         }
578         catch(exception& e) {
579                 errorOut(e, "mothur", "splitAtEquals");
580                 exit(1);
581         }
582 }
583 /**************************************************************************************************/
584
585 inline bool inUsersGroups(string groupname, vector<string> Groups) {
586         try {
587                 for (int i = 0; i < Groups.size(); i++) {
588                         if (groupname == Groups[i]) { return true; }
589                 }
590                 return false;
591         }
592         catch(exception& e) {
593                 errorOut(e, "mothur", "inUsersGroups");
594                 exit(1);
595         }
596 }
597
598 /**************************************************************************************************/
599
600 inline void mothurOutJustToLog(string message) {
601         try {
602                 ofstream out;
603                 string logFileName = "mothur.logFile";
604                 openOutputFileAppend(logFileName, out);
605                 
606                 out << message;
607                 
608                 out.close();
609         }
610         catch(exception& e) {
611                 errorOut(e, "mothur", "mothurOutJustToLog");
612                 exit(1);
613         }
614 }
615
616
617 /**************************************************************************************************/
618
619 inline void mothurOut(float num) {
620         try {
621                 ofstream out;
622                 string logFileName = "mothur.logFile";
623                 openOutputFileAppend(logFileName, out);
624                 
625                 cout << num;  
626                 out << num;
627                 
628                 out.close();
629         }
630         catch(exception& e) {
631                 cout << "Error in mothur class mothurOut float" << endl;
632                 exit(1);
633         }
634 }
635 /***********************************************************************/
636 inline void mothurOut(double value) {
637         try {
638                 ofstream out;
639                 string logFileName = "mothur.logFile";
640                 openOutputFileAppend(logFileName, out);
641                 
642                 cout << value;  
643                 out << value;
644                 
645                 out.close();
646         }
647         catch(exception& e) {
648                 cout << "Error in mothur class mothurOut double" << endl;
649                 exit(1);
650         }
651 }
652
653 /***********************************************************************/
654 //this function determines if the user has given us labels that are smaller than the given label.
655 //if so then it returns true so that the calling function can run the previous valid distance.
656 //it's a "smart" distance function.  It also checks for invalid labels.
657 inline bool anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
658         try {
659                 set<string>::iterator it;
660                 vector<float> orderFloat;
661                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
662                 map<string, float>::iterator it2;
663                 float labelFloat;
664                 bool smaller = false;
665                 
666                 //unique is the smallest line
667                 if (label == "unique") {  return false;  }
668                 else { convert(label, labelFloat); }
669                 
670                 //go through users set and make them floats
671                 for(it = userLabels.begin(); it != userLabels.end(); ++it) {
672                         
673                         float temp;
674                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
675                                 convert(*it, temp);
676                                 orderFloat.push_back(temp);
677                                 userMap[*it] = temp;
678                         }else if (*it == "unique") { 
679                                 orderFloat.push_back(-1.0);
680                                 userMap["unique"] = -1.0;
681                         }else {
682                                 if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
683                                 userLabels.erase(*it); 
684                                 it--;
685                         }
686                 }
687                 
688                 //sort order
689                 sort(orderFloat.begin(), orderFloat.end());
690                 
691                 /*************************************************/
692                 //is this label bigger than any of the users labels
693                 /*************************************************/
694                                 
695                 //loop through order until you find a label greater than label
696                 for (int i = 0; i < orderFloat.size(); i++) {
697                         if (orderFloat[i] < labelFloat) {
698                                 smaller = true;
699                                 if (orderFloat[i] == -1) { 
700                                         if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
701                                         userLabels.erase("unique");
702                                 }
703                                 else {  
704                                         if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
705                                         string s = "";
706                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
707                                                 if (it2->second == orderFloat[i]) {  
708                                                         s = it2->first;  
709                                                         //remove small labels
710                                                         userLabels.erase(s);
711                                                         break;
712                                                 }
713                                         }
714                                         if (errorOff == "") { mothurOut(s + ". I will use the next smallest distance. "); mothurOutEndLine(); }
715                                 }
716                         //since they are sorted once you find a bigger one stop looking
717                         }else { break; }
718                 }
719                 
720                 return smaller;
721                                                 
722         }
723         catch(exception& e) {
724                 errorOut(e, "mothur", "anyLabelsToProcess");
725                 exit(1);
726         }
727 }
728
729 /**************************************************************************************************/
730 #endif
731