]> git.donarmstrong.com Git - mothur.git/blob - mothur.h
pat's edits of screen.seqs and summary.seqs
[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 inline int getNumSeqs(ifstream& file){
322         
323         int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
324         file.seekg(0);
325         return numSeqs;
326
327 }
328
329 /***********************************************************************/
330
331 //This function parses the estimator options and puts them in a vector
332 inline void splitAtDash(string& estim, vector<string>& container) {
333         try {
334                 string individual;
335                 
336                 while (estim.find_first_of('-') != -1) {
337                         individual = estim.substr(0,estim.find_first_of('-'));
338                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
339                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
340                                 container.push_back(individual);
341                         }
342                 }
343                 //get last one
344                 container.push_back(estim);
345         }
346         catch(exception& e) {
347                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
348                 exit(1);
349         }
350         catch(...) {
351                 cout << "An unknown error has occurred in the mothur class function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
352                 exit(1);
353         }
354
355 }
356
357 /***********************************************************************/
358 //This function parses the label options and puts them in a set
359 inline void splitAtDash(string& estim, set<string>& container) {
360         try {
361                 string individual;
362                 
363                 while (estim.find_first_of('-') != -1) {
364                         individual = estim.substr(0,estim.find_first_of('-'));
365                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
366                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
367                                 container.insert(individual);
368                         }
369                 }
370                 //get last one
371                 container.insert(estim);
372         }
373         catch(exception& e) {
374                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
375                 exit(1);
376         }
377         catch(...) {
378                 cout << "An unknown error has occurred in the mothur class function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
379                 exit(1);
380         }
381
382 }
383 /***********************************************************************/
384 //This function parses the line options and puts them in a set
385 inline void splitAtDash(string& estim, set<int>& container) {
386         try {
387                 string individual;
388                 int lineNum;
389                 
390                 while (estim.find_first_of('-') != -1) {
391                         individual = estim.substr(0,estim.find_first_of('-'));
392                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
393                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
394                                 convert(individual, lineNum); //convert the string to int
395                                 container.insert(lineNum);
396                         }
397                 }
398                 //get last one
399                 convert(estim, lineNum); //convert the string to int
400                 container.insert(lineNum);
401         }
402         catch(exception& e) {
403                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
404                 exit(1);
405         }
406         catch(...) {
407                 cout << "An unknown error has occurred in the mothur class function splitAtDash. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
408                 exit(1);
409         }
410
411 }
412 /***********************************************************************/
413 //This function parses the a string and puts peices in a vector
414 inline void splitAtComma(string& estim, vector<string>& container) {
415         try {
416                 string individual;
417                 
418                 while (estim.find_first_of(',') != -1) {
419                         individual = estim.substr(0,estim.find_first_of(','));
420                         if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
421                                 estim = estim.substr(estim.find_first_of(',')+1, estim.length());
422                                 container.push_back(individual);
423                         }
424                 }
425                 //get last one
426                 container.push_back(estim);
427         }
428         catch(exception& e) {
429                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
430                 exit(1);
431         }
432         catch(...) {
433                 cout << "An unknown error has occurred in the mothur class function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
434                 exit(1);
435         }
436 }
437 /***********************************************************************/
438
439 //This function splits up the various option parameters
440 inline void splitAtComma(string& prefix, string& suffix){
441         try {
442                 prefix = suffix.substr(0,suffix.find_first_of(','));
443                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
444                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
445                         string space = " ";
446                         while(suffix.at(0) == ' ')
447                                 suffix = suffix.substr(1, suffix.length());
448                 }
449
450         }
451         catch(exception& e) {
452                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
453                 exit(1);
454         }
455         catch(...) {
456                 cout << "An unknown error has occurred in the mothur class function splitAtComma. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
457                 exit(1);
458         }
459
460 }
461 /***********************************************************************/
462
463 //This function separates the key value from the option value i.e. dist=96_...
464 inline void splitAtEquals(string& key, string& value){          
465         try {
466                 if(value.find_first_of('=') != -1){
467                         key = value.substr(0,value.find_first_of('='));
468                         if ((value.find_first_of('=')+1) <= value.length()) {
469                                 value = value.substr(value.find_first_of('=')+1, value.length());
470                         }
471                 }else{
472                         key = value;
473                         value = 1;
474                 }
475         }
476         catch(exception& e) {
477                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function splitAtEquals. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
478                 exit(1);
479         }
480         catch(...) {
481                 cout << "An unknown error has occurred in the mothur class function splitAtEquals. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
482                 exit(1);
483         }
484
485 }
486 /**************************************************************************************************/
487
488 inline bool inUsersGroups(string groupname, vector<string> Groups) {
489         try {
490                 for (int i = 0; i < Groups.size(); i++) {
491                         if (groupname == Groups[i]) { return true; }
492                 }
493                 return false;
494         }
495         catch(exception& e) {
496                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function inUsersGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
497                 exit(1);
498         }
499         catch(...) {
500                 cout << "An unknown error has occurred in the mothur class function inUsersGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
501                 exit(1);
502         }
503 }
504
505 /***********************************************************************/
506 //this function determines if the user has given us labels that are smaller than the given label.
507 //if so then it returns true so that the calling function can run the previous valid distance.
508 //it's a "smart" distance function.  It also checks for invalid labels.
509 inline bool anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
510         try {
511                 set<string>::iterator it;
512                 vector<float> orderFloat;
513                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
514                 map<string, float>::iterator it2;
515                 float labelFloat;
516                 bool smaller = false;
517                 
518                 //unique is the smallest line
519                 if (label == "unique") {  return false;  }
520                 else { convert(label, labelFloat); }
521                 
522                 //go through users set and make them floats
523                 for(it = userLabels.begin(); it != userLabels.end(); ++it) {
524                         
525                         float temp;
526                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
527                                 convert(*it, temp);
528                                 orderFloat.push_back(temp);
529                                 userMap[*it] = temp;
530                         }else if (*it == "unique") { 
531                                 orderFloat.push_back(-1.0);
532                                 userMap["unique"] = -1.0;
533                         }else {
534                                 if (errorOff == "") {  cout << *it << " is not a valid label." << endl;  }
535                                 userLabels.erase(*it); 
536                                 it--;
537                         }
538                 }
539                 
540                 //sort order
541                 sort(orderFloat.begin(), orderFloat.end());
542                 
543                 /*************************************************/
544                 //is this label bigger than any of the users labels
545                 /*************************************************/
546                                 
547                 //loop through order until you find a label greater than label
548                 for (int i = 0; i < orderFloat.size(); i++) {
549                         if (orderFloat[i] < labelFloat) {
550                                 smaller = true;
551                                 if (orderFloat[i] == -1) { 
552                                         if (errorOff == "") { cout << "Your file does not include the label unique." <<  endl; }
553                                         userLabels.erase("unique");
554                                 }
555                                 else {  
556                                         if (errorOff == "") { cout << "Your file does not include the label "; }
557                                         string s = "";
558                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
559                                                 if (it2->second == orderFloat[i]) {  
560                                                         s = it2->first;  
561                                                         //remove small labels
562                                                         userLabels.erase(s);
563                                                         break;
564                                                 }
565                                         }
566                                         if (errorOff == "") { cout << s << ". I will use the next smallest distance. "  <<  endl; }
567                                 }
568                         //since they are sorted once you find a bigger one stop looking
569                         }else { break; }
570                 }
571                 
572                 return smaller;
573                                                 
574         }
575         catch(exception& e) {
576                 cout << "Standard Error: " << e.what() << " has occurred in the mothur class Function anyLabelsToProcess. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
577                 exit(1);
578         }
579         catch(...) {
580                 cout << "An unknown error has occurred in the mothur class function anyLabelsToProcess. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
581                 exit(1);
582         }
583
584 }
585
586 /**************************************************************************************************/
587 #endif
588