]> git.donarmstrong.com Git - mothur.git/blobdiff - mothur.h
updated pats contact and mothur header info
[mothur.git] / mothur.h
index c1d93ed197fe2990c24ca2ba0d89f52f8fe8320e..c5afe86a79a9e92c789735ea3b1be3d33accf66a 100644 (file)
--- a/mothur.h
+++ b/mothur.h
@@ -1,7 +1,6 @@
 #ifndef MOTHUR_H
 #define MOTHUR_H
 
-using namespace std;
 
 
 /*
@@ -41,7 +40,28 @@ using namespace std;
 #include <math.h>
 #include <algorithm>
 
-typedef unsigned long long ull;
+//misc
+#include <cerrno>
+#include <ctime>
+#include <limits>
+
+
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+       #include <sys/wait.h>
+       #include <unistd.h>
+#endif
+
+using namespace std;
+
+#define exp(x) (exp((double) x))
+#define sqrt(x) (sqrt((double) x))
+#define log10(x) (log10((double) x))
+#define log2(x) (log10(x)/log10(2))
+#define isnan(x) ((x) != (x))
+#define isinf(x) (fabs(x) == std::numeric_limits<double>::infinity())
+
+
+typedef unsigned long ull;
 
 struct IntNode {
        int lvalue;
@@ -51,7 +71,13 @@ struct IntNode {
        IntNode* left;
        IntNode* right;
 };
-       
+
+struct ThreadNode {
+       int* pid;
+       IntNode* left;
+       IntNode* right;
+};
+
 /***********************************************************************/
 
 // snagged from http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2
@@ -71,6 +97,20 @@ inline void convert(const string& s, T& x, bool failIfLeftoverChars = true){
        if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
                throw BadConversion(s);
 }
+
+//**********************************************************************************************************************
+
+template<typename T>
+inline bool convertTestFloat(const string& s, T& x, bool failIfLeftoverChars = true){
+       istringstream i(s);
+       char c;
+       if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
+       {
+               return false;
+       } 
+       return true;
+}
+
 //**********************************************************************************************************************
 
 template<typename T>
@@ -79,7 +119,7 @@ inline bool convertTest(const string& s, T& x, bool failIfLeftoverChars = true){
        char c;
        if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
        {
-               cout << "'" << s << "' is unable to be converted into an integer.\n";
+               cout << "unable to be converted into an integer.\n" << endl;
                return false;
        } 
        return true;
@@ -115,6 +155,114 @@ string toString(const T&x, int i){
        
     return output.str();
 }
+/***********************************************************************/
+
+inline int openOutputFileAppend(string fileName, ofstream& fileHandle){
+       
+       fileHandle.open(fileName.c_str(), ios::app);
+       if(!fileHandle) {
+               cout << "Error: Could not open " <<  fileName << endl; 
+               return 1;
+       }
+       else {
+               return 0;
+       }
+
+}
+/***********************************************************************/
+
+inline string getline(ifstream& fileHandle) {
+       try {
+       
+               string line = "";
+               
+               while (!fileHandle.eof())       {
+                       //get next character
+                       char c = fileHandle.get(); 
+                       
+                       //are you at the end of the line
+                       if ((c == '\n') || (c == '\r') || (c == '\f')){   break;        }       
+                       else {          line += c;              }
+               }
+               
+               return line;
+               
+       }
+       catch(exception& e) {
+               cout << "Error in mothur function getline" << endl;
+               exit(1);
+       }
+}
+
+/**************************************************************************************************/
+
+inline void mothurOut(string message) {
+       try{
+               ofstream out;
+               string logFileName = "mothur.logFile";
+               openOutputFileAppend(logFileName, out);
+               
+               cout << message;
+               out << message;
+               
+               out.close();
+       }
+       catch(exception& e) {
+               cout << "Error in mothur class mothurOut" << endl;
+               exit(1);
+       }
+}
+/**************************************************************************************************/
+
+inline void mothurOut(string message, string precision) {
+       try{
+               ofstream out;
+               string logFileName = "mothur.logFile";
+               openOutputFileAppend(logFileName, out);
+               
+               cout << precision << message;
+               out << precision << message;
+               
+               out.close();
+       }
+       catch(exception& e) {
+               cout << "Error in mothur class mothurOut" << endl;
+               exit(1);
+       }
+}
+
+/**************************************************************************************************/
+
+inline void mothurOutEndLine() {
+       try {
+               ofstream out;
+               string logFileName = "mothur.logFile";
+               openOutputFileAppend(logFileName, out);
+               
+               cout << endl;  
+               out << endl;
+               
+               out.close();
+       }
+       catch(exception& e) {
+               cout << "error in mothur mothurOutEndLine" << endl;
+               exit(1);
+       }
+}
+
+
+/**************************************************************************************************/
+
+inline void errorOut(exception& e, string object, string function) {
+       
+               mothurOut("Error: ");
+               mothurOut(toString(e.what()));
+               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.");
+               mothurOutEndLine();
+       
+}
+
+
 
 
 /***********************************************************************/
@@ -126,6 +274,13 @@ inline void gobble(istream& f){
        f.putback(d);
        
 }
+/***********************************************************************/
+
+inline bool isTrue(string f){
+       
+       if ((f == "TRUE") || (f == "T") || (f == "true") || (f == "t")) {       return true;    }
+       else {  return false;  }
+}
 
 /***********************************************************************/
 
@@ -211,6 +366,7 @@ inline string getSimpleName(string longName){
 
        return simpleName;
 }
+
 /***********************************************************************/
 
 inline int factorial(int num){
@@ -222,6 +378,13 @@ inline int factorial(int num){
        
        return total;
 }
+/**************************************************************************************************
+
+double min(double x, double y)
+{
+    if(x<y){   return x;    }
+    else   {   return y;    }
+}
 
 /***********************************************************************/
 
@@ -229,7 +392,7 @@ inline string getPathName(string longName){
  
        string rootPathName = longName;
        
-       if(longName.find_last_of("/") != longName.npos){
+       if(longName.find_last_of('/') != longName.npos){
                int pos = longName.find_last_of('/')+1;
                rootPathName = longName.substr(0, pos);
        }
@@ -239,11 +402,25 @@ inline string getPathName(string longName){
 
 /***********************************************************************/
 
+inline string getExtension(string longName){
+       
+       string extension = longName;
+       
+       if(longName.find_last_of('.') != longName.npos){
+               int pos = longName.find_last_of('.');
+               extension = longName.substr(pos, longName.length());
+       }
+       
+       return extension;
+}
+
+/***********************************************************************/
+
 inline int openInputFile(string fileName, ifstream& fileHandle){
 
        fileHandle.open(fileName.c_str());
        if(!fileHandle) {
-               cerr << "Error: Could not open " << fileName << endl;
+               mothurOut("Error: Could not open " + fileName);  mothurOutEndLine();
                return 1;
        }
        else {
@@ -258,7 +435,7 @@ inline int openOutputFile(string fileName, ofstream& fileHandle){
        
        fileHandle.open(fileName.c_str(), ios::trunc);
        if(!fileHandle) {
-               cerr << "Error: Could not open " << fileName << endl;
+               mothurOut("Error: Could not open " + fileName);  mothurOutEndLine();
                return 1;
        }
        else {
@@ -269,6 +446,16 @@ inline int openOutputFile(string fileName, ofstream& fileHandle){
 
 /***********************************************************************/
 
+inline int getNumSeqs(ifstream& file){
+       
+       int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
+       file.seekg(0);
+       return numSeqs;
+
+}
+
+/***********************************************************************/
+
 //This function parses the estimator options and puts them in a vector
 inline void splitAtDash(string& estim, vector<string>& container) {
        try {
@@ -285,14 +472,9 @@ inline void splitAtDash(string& estim, vector<string>& container) {
                container.push_back(estim);
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
-               exit(1);
-       }
-       catch(...) {
-               cout << "An unknown error has occurred in the mothur class function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               errorOut(e, "mothur", "splitAtDash");
                exit(1);
        }
-
 }
 
 /***********************************************************************/
@@ -312,14 +494,9 @@ inline void splitAtDash(string& estim, set<string>& container) {
                container.insert(estim);
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
-               exit(1);
-       }
-       catch(...) {
-               cout << "An unknown error has occurred in the mothur class function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               errorOut(e, "mothur", "splitAtDash");
                exit(1);
        }
-
 }
 /***********************************************************************/
 //This function parses the line options and puts them in a set
@@ -341,14 +518,9 @@ inline void splitAtDash(string& estim, set<int>& container) {
                container.insert(lineNum);
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
-               exit(1);
-       }
-       catch(...) {
-               cout << "An unknown error has occurred in the mothur class function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               errorOut(e, "mothur", "splitAtDash");
                exit(1);
        }
-
 }
 /***********************************************************************/
 //This function parses the a string and puts peices in a vector
@@ -367,11 +539,7 @@ inline void splitAtComma(string& estim, vector<string>& container) {
                container.push_back(estim);
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
-               exit(1);
-       }
-       catch(...) {
-               cout << "An unknown error has occurred in the mothur class function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               errorOut(e, "mothur", "splitAtComma");
                exit(1);
        }
 }
@@ -390,14 +558,9 @@ inline void splitAtComma(string& prefix, string& suffix){
 
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
-               exit(1);
-       }
-       catch(...) {
-               cout << "An unknown error has occurred in the mothur class function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               errorOut(e, "mothur", "splitAtComma");
                exit(1);
        }
-
 }
 /***********************************************************************/
 
@@ -415,14 +578,9 @@ inline void splitAtEquals(string& key, string& value){
                }
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtEquals. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
-               exit(1);
-       }
-       catch(...) {
-               cout << "An unknown error has occurred in the mothur class function splitAtEquals. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               errorOut(e, "mothur", "splitAtEquals");
                exit(1);
        }
-
 }
 /**************************************************************************************************/
 
@@ -434,17 +592,142 @@ inline bool inUsersGroups(string groupname, vector<string> Groups) {
                return false;
        }
        catch(exception& e) {
-               cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function inUsersGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+               errorOut(e, "mothur", "inUsersGroups");
                exit(1);
        }
-       catch(...) {
-               cout << "An unknown error has occurred in the mothur class function inUsersGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+}
+
+/**************************************************************************************************/
+
+inline void mothurOutJustToLog(string message) {
+       try {
+               ofstream out;
+               string logFileName = "mothur.logFile";
+               openOutputFileAppend(logFileName, out);
+               
+               out << message;
+               
+               out.close();
+       }
+       catch(exception& e) {
+               errorOut(e, "mothur", "mothurOutJustToLog");
                exit(1);
        }
 }
 
+
 /**************************************************************************************************/
 
+inline void mothurOut(float num) {
+       try {
+               ofstream out;
+               string logFileName = "mothur.logFile";
+               openOutputFileAppend(logFileName, out);
+               
+               cout << num;  
+               out << num;
+               
+               out.close();
+       }
+       catch(exception& e) {
+               cout << "Error in mothur class mothurOut float" << endl;
+               exit(1);
+       }
+}
+/***********************************************************************/
+inline void mothurOut(double value) {
+       try {
+               ofstream out;
+               string logFileName = "mothur.logFile";
+               openOutputFileAppend(logFileName, out);
+               
+               cout << value;  
+               out << value;
+               
+               out.close();
+       }
+       catch(exception& e) {
+               cout << "Error in mothur class mothurOut double" << endl;
+               exit(1);
+       }
+}
 
+/***********************************************************************/
+//this function determines if the user has given us labels that are smaller than the given label.
+//if so then it returns true so that the calling function can run the previous valid distance.
+//it's a "smart" distance function.  It also checks for invalid labels.
+inline bool anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
+       try {
+               set<string>::iterator it;
+               vector<float> orderFloat;
+               map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
+               map<string, float>::iterator it2;
+               float labelFloat;
+               bool smaller = false;
+               
+               //unique is the smallest line
+               if (label == "unique") {  return false;  }
+               else { convert(label, labelFloat); }
+               
+               //go through users set and make them floats
+               for(it = userLabels.begin(); it != userLabels.end(); ++it) {
+                       
+                       float temp;
+                       if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
+                               convert(*it, temp);
+                               orderFloat.push_back(temp);
+                               userMap[*it] = temp;
+                       }else if (*it == "unique") { 
+                               orderFloat.push_back(-1.0);
+                               userMap["unique"] = -1.0;
+                       }else {
+                               if (errorOff == "") {  mothurOut(*it + " is not a valid label."); mothurOutEndLine();  }
+                               userLabels.erase(*it); 
+                               it--;
+                       }
+               }
+               
+               //sort order
+               sort(orderFloat.begin(), orderFloat.end());
+               
+               /*************************************************/
+               //is this label bigger than any of the users labels
+               /*************************************************/
+                               
+               //loop through order until you find a label greater than label
+               for (int i = 0; i < orderFloat.size(); i++) {
+                       if (orderFloat[i] < labelFloat) {
+                               smaller = true;
+                               if (orderFloat[i] == -1) { 
+                                       if (errorOff == "") { mothurOut("Your file does not include the label unique."); mothurOutEndLine(); }
+                                       userLabels.erase("unique");
+                               }
+                               else {  
+                                       if (errorOff == "") { mothurOut("Your file does not include the label "); mothurOutEndLine(); }
+                                       string s = "";
+                                       for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
+                                               if (it2->second == orderFloat[i]) {  
+                                                       s = it2->first;  
+                                                       //remove small labels
+                                                       userLabels.erase(s);
+                                                       break;
+                                               }
+                                       }
+                                       if (errorOff == "") { mothurOut(s + ". I will use the next smallest distance. "); mothurOutEndLine(); }
+                               }
+                       //since they are sorted once you find a bigger one stop looking
+                       }else { break; }
+               }
+               
+               return smaller;
+                                               
+       }
+       catch(exception& e) {
+               errorOut(e, "mothur", "anyLabelsToProcess");
+               exit(1);
+       }
+}
+
+/**************************************************************************************************/
 #endif