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