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