]> git.donarmstrong.com Git - mothur.git/blob - mothur.h
adding mothurout.h and .cpp to repo
[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 #include <signal.h>
25
26
27 //exception
28 #include <stdexcept>
29 #include <exception>
30 #include <cstdlib> 
31
32
33 //containers
34 #include <vector>
35 #include <set>
36 #include <map>
37 #include <string>
38 #include <list>
39
40 //math
41 #include <cmath>
42 #include <math.h>
43 #include <algorithm>
44
45 //misc
46 #include <cerrno>
47 #include <ctime>
48 #include <limits>
49
50 /***********************************************************************/
51
52 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
53         #include <sys/wait.h>
54         #include <unistd.h>
55         
56         #ifdef USE_READLINE
57                 #include <readline/readline.h>
58                 #include <readline/history.h>
59         #endif
60
61         //#include <readline/readline.h>
62         //#include <readline/history.h>
63 #else
64         #include <conio.h> //allows unbuffered screen capture from stdin
65         #include <direct.h> //get cwd
66 #endif
67
68 using namespace std;
69
70 #define exp(x) (exp((double) x))
71 #define sqrt(x) (sqrt((double) x))
72 #define log10(x) (log10((double) x))
73 #define log2(x) (log10(x)/log10(2))
74 #define isnan(x) ((x) != (x))
75 #define isinf(x) (fabs(x) == std::numeric_limits<double>::infinity())
76
77 typedef unsigned long ull;
78
79 struct IntNode {
80         int lvalue;
81         int rvalue;
82         int lcoef;
83         int rcoef;
84         IntNode* left;
85         IntNode* right;
86         
87         IntNode(int lv, int rv, IntNode* l, IntNode* r) : lvalue(lv), rvalue(rv), left(l), right(r) {};
88         IntNode() {};
89 };
90
91 struct ThreadNode {
92         int* pid;
93         IntNode* left;
94         IntNode* right;
95 };
96
97 /************************************************************/
98 struct clusterNode {
99         int numSeq;
100         int parent;
101         int smallChild; //used to make linkTable work with list and rabund. represents bin number of this cluster node
102         clusterNode(int num, int par, int kid) : numSeq(num), parent(par), smallChild(kid) {};
103 };
104 /************************************************************/
105 struct seqDist {
106         int seq1;
107         int seq2;
108         float dist;
109         seqDist() {}
110         seqDist(int s1, int s2, float d) : seq1(s1), seq2(s2), dist(d) {}
111         ~seqDist() {}
112 };
113 //********************************************************************************************************************
114 //sorts lowest to highest
115 inline bool compareSequenceDistance(seqDist left, seqDist right){
116         return (left.dist < right.dist);        
117
118 /***********************************************************************/
119
120 // snagged from http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2
121 // works for now, but there should be a way to do it without killing the whole program
122
123 class BadConversion : public runtime_error {
124 public:
125         BadConversion(const string& s) : runtime_error(s){ }
126 };
127
128 //**********************************************************************************************************************
129
130 template<typename T>
131 inline void convert(const string& s, T& x, bool failIfLeftoverChars = true){
132         istringstream i(s);
133         char c;
134         if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
135                 throw BadConversion(s);
136 }
137
138 //**********************************************************************************************************************
139
140 template<typename T>
141 inline bool convertTestFloat(const string& s, T& x, bool failIfLeftoverChars = true){
142         istringstream i(s);
143         char c;
144         if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
145         {
146                 return false;
147         } 
148         return true;
149 }
150
151 //**********************************************************************************************************************
152
153 template<typename T>
154 inline bool convertTest(const string& s, T& x, bool failIfLeftoverChars = true){
155         istringstream i(s);
156         char c;
157         if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
158         {
159                 cout << "unable to be converted into an integer.\n" << endl;
160                 return false;
161         } 
162         return true;
163 }
164
165 //**********************************************************************************************************************
166
167 template<typename T>
168 string toString(const T&x){
169     stringstream output;
170     output << x;
171     return output.str();
172 }
173
174 //**********************************************************************************************************************
175
176 template<typename T>
177 string toHex(const T&x){
178         stringstream output;
179         
180         output << hex << x;
181
182     return output.str();
183 }
184 //**********************************************************************************************************************
185
186 template<typename T>
187 string toString(const T&x, int i){
188         stringstream output;
189         
190         output.precision(i);
191     output << fixed << x;
192         
193     return output.str();
194 }
195 /***********************************************************************/
196 inline int openOutputFileAppend(string fileName, ofstream& fileHandle){
197         
198         fileHandle.open(fileName.c_str(), ios::app);
199         if(!fileHandle) {
200                 cout << "Error: Could not open " << fileName << endl;
201                 return 1;
202         }
203         else {
204                 return 0;
205         }
206
207 }
208 /***********************************************************************/
209
210 inline void gobble(istream& f){
211         
212         char d;
213     while(isspace(d=f.get()))           {;}
214         f.putback(d);
215         
216 }
217 /***********************************************************************/
218
219 inline string getline(ifstream& fileHandle) {
220         try {
221         
222                 string line = "";
223                 
224                 while (!fileHandle.eof())       {
225                         //get next character
226                         char c = fileHandle.get(); 
227                         
228                         //are you at the end of the line
229                         if ((c == '\n') || (c == '\r') || (c == '\f')){  break; }       
230                         else {          line += c;              }
231                 }
232                 
233                 return line;
234                 
235         }
236         catch(exception& e) {
237                 cout << "Error in mothur function getline" << endl;
238                 exit(1);
239         }
240 }
241
242 /***********************************************************************/
243
244 inline bool isTrue(string f){
245         
246         if ((f == "TRUE") || (f == "T") || (f == "true") || (f == "t")) {       return true;    }
247         else {  return false;  }
248 }
249
250 /***********************************************************************/
251
252 inline float roundDist(float dist, int precision){
253         
254         return int(dist * precision + 0.5)/float(precision);
255         
256 }
257
258 /***********************************************************************/
259
260 inline int getNumNames(string names){
261         
262         int count = 0;
263         
264         if(names != ""){
265                 count = 1;
266                 for(int i=0;i<names.size();i++){
267                         if(names[i] == ','){
268                                 count++;
269                         }
270                 }
271         }
272         
273         return count;
274         
275 }
276
277 /**************************************************************************************************/
278
279 inline vector<vector<double> > binomial(int maxOrder){
280         
281         vector<vector<double> > binomial(maxOrder+1);
282         
283     for(int i=0;i<=maxOrder;i++){
284                 binomial[i].resize(maxOrder+1);
285                 binomial[i][0]=1;
286                 binomial[0][i]=0;
287     }
288     binomial[0][0]=1;
289         
290     binomial[1][0]=1;
291     binomial[1][1]=1;
292         
293     for(int i=2;i<=maxOrder;i++){
294                 binomial[1][i]=0;
295     }
296         
297     for(int i=2;i<=maxOrder;i++){
298                 for(int j=1;j<=maxOrder;j++){
299                         if(i==j){       binomial[i][j]=1;                                                                       }
300                         if(j>i) {       binomial[i][j]=0;                                                                       }
301                         else    {       binomial[i][j]=binomial[i-1][j-1]+binomial[i-1][j];     }
302                 }
303     }
304         
305         return binomial;
306 }
307
308 /***********************************************************************/
309
310 inline string getRootName(string longName){
311  
312         string rootName = longName;
313         
314         if(longName.find_last_of(".") != longName.npos){
315                 int pos = longName.find_last_of('.')+1;
316                 rootName = longName.substr(0, pos);
317         }
318
319         return rootName;
320 }
321 /***********************************************************************/
322
323 inline string getSimpleName(string longName){
324  
325         string simpleName = longName;
326         
327         size_t found;
328         found=longName.find_last_of("/\\");
329
330         if(found != longName.npos){
331                 simpleName = longName.substr(found+1);
332         }
333         
334                 //if(longName.find_last_of("/") != longName.npos){
335                 //      int pos = longName.find_last_of('/')+1;
336                 //      simpleName = longName.substr(pos, longName.length());
337                 //}
338         
339         return simpleName;
340 }
341
342 /***********************************************************************/
343
344 inline int factorial(int num){
345         int total = 1;
346         
347         for (int i = 1; i <= num; i++) {
348                 total *= i;
349         }
350         
351         return total;
352 }
353 /**************************************************************************************************
354
355 double min(double x, double y)
356 {
357     if(x<y){    return x;    }
358     else   {    return y;    }
359 }
360
361 /***********************************************************************/
362
363 inline string getPathName(string longName){
364  
365         string rootPathName = longName;
366         
367         if(longName.find_last_of("/\\") != longName.npos){
368                 int pos = longName.find_last_of("/\\")+1;
369                 rootPathName = longName.substr(0, pos);
370         }
371         
372         return rootPathName;
373 }
374 /***********************************************************************/
375
376 inline string hasPath(string longName){
377         
378         string path = "";
379         
380         size_t found;
381         found=longName.find_last_of("/\\");
382
383         if(found != longName.npos){
384                 path = longName.substr(0, found+1);
385         }
386         
387         return path;
388 }
389
390 /***********************************************************************/
391
392 inline string getExtension(string longName){
393         
394         string extension = longName;
395         
396         if(longName.find_last_of('.') != longName.npos){
397                 int pos = longName.find_last_of('.');
398                 extension = longName.substr(pos, longName.length());
399         }
400         
401         return extension;
402 }
403 /***********************************************************************/
404 inline bool isBlank(string fileName){
405         
406         ifstream fileHandle;
407         fileHandle.open(fileName.c_str());
408         if(!fileHandle) {
409                 cout << "Error: Could not open " << fileName << endl;
410                 return false;
411         }else {
412                 //check for blank file
413                 gobble(fileHandle);
414                 if (fileHandle.eof()) { fileHandle.close(); return true;  }
415         }
416         return false;
417 }
418 /***********************************************************************/
419
420 inline string getFullPathName(string fileName){
421         try{
422         
423         string path = hasPath(fileName);
424         string newFileName;
425         int pos;
426         
427         if (path == "") { return fileName; } //its a simple name
428         else { //we need to complete the pathname
429                 // ex. ../../../filename 
430                 // cwd = /user/work/desktop
431                                 
432                 string cwd;
433                 //get current working directory 
434                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)   
435                         if (path.rfind("./") == -1) { return fileName; } //already complete name
436                         else { newFileName = fileName.substr(fileName.rfind("./")+2); } //save the complete part of the name
437                         
438                         char* cwdpath = new char[1024];
439
440                         size_t size;
441                         cwdpath=getcwd(cwdpath,size);
442                 
443                         cwd = cwdpath;
444                         
445                         //rip off first '/'
446                         string simpleCWD;
447                         if (cwd.length() > 0) { simpleCWD = cwd.substr(1); }
448                         
449                         //break apart the current working directory
450                         vector<string> dirs;
451                         while (simpleCWD.find_first_of('/') != -1) {
452                                 string dir = simpleCWD.substr(0,simpleCWD.find_first_of('/'));
453                                 simpleCWD = simpleCWD.substr(simpleCWD.find_first_of('/')+1, simpleCWD.length());
454                                 dirs.push_back(dir);
455                         }
456                         //get last one              // ex. ../../../filename = /user/work/desktop/filename
457                         dirs.push_back(simpleCWD);  //ex. dirs[0] = user, dirs[1] = work, dirs[2] = desktop
458                         
459                 
460                         int index = dirs.size()-1;
461                 
462                         while((pos = path.rfind("./")) != -1) { //while you don't have a complete path
463                                 if (path[(pos-1)] == '.') { //you want your parent directory ../
464                                         path = path.substr(0, pos-1);
465                                         index--;
466                                         if (index == 0) {  break; }
467                                 }else if (path[(pos-1)] == '/') { //you want the current working dir ./
468                                         path = path.substr(0, pos);
469                                 }else if (pos == 1) { break; 
470                                 }else { cout << "cannot resolve path for " <<  fileName << endl; return fileName; }
471                         }
472                 
473                         for (int i = index; i >= 0; i--) {
474                                 newFileName = dirs[i] +  "/" + newFileName;             
475                         }
476                         
477                         newFileName =  "/" +  newFileName;
478                         return newFileName;
479                                 
480                 #else
481                         if (path.rfind(".\\") == -1) { return fileName; } //already complete name
482                         else { newFileName = fileName.substr(fileName.rfind(".\\")+2); } //save the complete part of the name
483                                                 
484                         char *cwdpath = NULL;
485                         cwdpath = getcwd(NULL, 0); // or _getcwd
486                         if ( cwdpath != NULL) { cwd = cwdpath; }
487                         else { cwd = "";  }
488                         
489                         //break apart the current working directory
490                         vector<string> dirs;
491                         while (cwd.find_first_of('\\') != -1) {
492                                 string dir = cwd.substr(0,cwd.find_first_of('\\'));
493                                 cwd = cwd.substr(cwd.find_first_of('\\')+1, cwd.length());
494                                 dirs.push_back(dir);
495         
496                         }
497                         //get last one
498                         dirs.push_back(cwd);  //ex. dirs[0] = user, dirs[1] = work, dirs[2] = desktop
499                                 
500                         int index = dirs.size()-1;
501                                 
502                         while((pos = path.rfind(".\\")) != -1) { //while you don't have a complete path
503                                 if (path[(pos-1)] == '.') { //you want your parent directory ../
504                                         path = path.substr(0, pos-1);
505                                         index--;
506                                         if (index == 0) {  break; }
507                                 }else if (path[(pos-1)] == '\\') { //you want the current working dir ./
508                                         path = path.substr(0, pos);
509                                 }else if (pos == 1) { break; 
510                                 }else {  cout << "cannot resolve path for " <<  fileName << endl;  return fileName; }
511                         }
512                 
513                         for (int i = index; i >= 0; i--) {
514                                 newFileName = dirs[i] +  "\\" + newFileName;            
515                         }
516                         
517                         return newFileName;
518                         
519                 #endif
520         }
521         }
522         catch(exception& e) {
523                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function getFullPathName. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
524                 exit(1);
525         }       
526 }
527 /***********************************************************************/
528
529 inline int openInputFile(string fileName, ifstream& fileHandle, string m){
530         
531         //get full path name
532         string completeFileName = getFullPathName(fileName);
533
534         fileHandle.open(completeFileName.c_str());
535         if(!fileHandle) {
536                 return 1;
537         }else {
538                 //check for blank file
539                 gobble(fileHandle);
540                 return 0;
541         }       
542 }
543 /***********************************************************************/
544
545 inline int openInputFile(string fileName, ifstream& fileHandle){
546         
547         //get full path name
548         string completeFileName = getFullPathName(fileName);
549
550         fileHandle.open(completeFileName.c_str());
551         if(!fileHandle) {
552                 cout << "Error: Could not open " << completeFileName << endl;
553                 return 1;
554         }
555         else {
556                 //check for blank file
557                 gobble(fileHandle);
558                 if (fileHandle.eof()) { cout << completeFileName << " is blank. Please correct." << endl;  return 1;  }
559                 
560                 return 0;
561         }
562         
563 }
564 /***********************************************************************/
565
566 inline int renameFile(string oldName, string newName){
567         
568         ifstream inTest;
569         int exist = openInputFile(newName, inTest, "");
570         
571 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)           
572         if (exist == 0) { //you could open it so you want to delete it
573                 inTest.close();
574                 string command = "rm " + newName;
575                 system(command.c_str());
576         }
577                         
578         string command = "mv " + oldName + " " + newName;
579         system(command.c_str());
580 #else
581         remove(newName.c_str());
582         int renameOk = rename(oldName.c_str(), newName.c_str());
583 #endif
584         return 0;
585 }
586
587 /***********************************************************************/
588
589 inline int openOutputFile(string fileName, ofstream& fileHandle){
590         
591         string completeFileName = getFullPathName(fileName);
592         
593         fileHandle.open(completeFileName.c_str(), ios::trunc);
594         if(!fileHandle) {
595                 cout << "Error: Could not open " << completeFileName << endl;
596                 return 1;
597         }
598         else {
599                 return 0;
600         }
601
602 }
603
604 /***********************************************************************/
605
606 inline int getNumSeqs(ifstream& file){
607         
608         int numSeqs = count(istreambuf_iterator<char>(file),istreambuf_iterator<char>(), '>');
609         file.seekg(0);
610         return numSeqs;
611
612 }
613 /***********************************************************************/
614
615 inline bool inVector(string member, vector<string> group){
616         
617         for (int i = 0; i < group.size(); i++) {
618                 if (group[i] == member) {  return true;         }
619         }
620         
621         return false;
622 }
623 /***********************************************************************/
624
625 //This function parses the estimator options and puts them in a vector
626 inline void splitAtDash(string& estim, vector<string>& container) {
627         try {
628                 string individual;
629                 
630                 while (estim.find_first_of('-') != -1) {
631                         individual = estim.substr(0,estim.find_first_of('-'));
632                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
633                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
634                                 container.push_back(individual);
635                         }
636                 }
637                 //get last one
638                 container.push_back(estim);
639         }
640         catch(exception& e) {
641                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function splitAtDash. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
642                 exit(1);
643         }       
644 }
645
646 /***********************************************************************/
647 //This function parses the label options and puts them in a set
648 inline void splitAtDash(string& estim, set<string>& container) {
649         try {
650                 string individual;
651                 
652                 while (estim.find_first_of('-') != -1) {
653                         individual = estim.substr(0,estim.find_first_of('-'));
654                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
655                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
656                                 container.insert(individual);
657                         }
658                 }
659                 //get last one
660                 container.insert(estim);
661         }
662         catch(exception& e) {
663                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function splitAtDash. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
664                 exit(1);
665         }       
666 }
667 /***********************************************************************/
668 //This function parses the line options and puts them in a set
669 inline void splitAtDash(string& estim, set<int>& container) {
670         try {
671                 string individual;
672                 int lineNum;
673                 
674                 while (estim.find_first_of('-') != -1) {
675                         individual = estim.substr(0,estim.find_first_of('-'));
676                         if ((estim.find_first_of('-')+1) <= estim.length()) { //checks to make sure you don't have dash at end of string
677                                 estim = estim.substr(estim.find_first_of('-')+1, estim.length());
678                                 convert(individual, lineNum); //convert the string to int
679                                 container.insert(lineNum);
680                         }
681                 }
682                 //get last one
683                 convert(estim, lineNum); //convert the string to int
684                 container.insert(lineNum);
685         }
686         catch(exception& e) {
687                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function splitAtDash. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
688                 exit(1);
689         }       
690 }
691 /***********************************************************************/
692 //This function parses the a string and puts peices in a vector
693 inline void splitAtComma(string& estim, vector<string>& container) {
694         try {
695                 string individual;
696                 
697                 while (estim.find_first_of(',') != -1) {
698                         individual = estim.substr(0,estim.find_first_of(','));
699                         if ((estim.find_first_of(',')+1) <= estim.length()) { //checks to make sure you don't have comma at end of string
700                                 estim = estim.substr(estim.find_first_of(',')+1, estim.length());
701                                 container.push_back(individual);
702                         }
703                 }
704                 //get last one
705                 container.push_back(estim);
706         }
707         catch(exception& e) {
708                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function splitAtComma. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
709                 exit(1);
710         }       
711 }
712 /***********************************************************************/
713
714 //This function splits up the various option parameters
715 inline void splitAtComma(string& prefix, string& suffix){
716         try {
717                 prefix = suffix.substr(0,suffix.find_first_of(','));
718                 if ((suffix.find_first_of(',')+2) <= suffix.length()) {  //checks to make sure you don't have comma at end of string
719                         suffix = suffix.substr(suffix.find_first_of(',')+1, suffix.length());
720                         string space = " ";
721                         while(suffix.at(0) == ' ')
722                                 suffix = suffix.substr(1, suffix.length());
723                 }
724
725         }
726         catch(exception& e) {
727                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function splitAtComma. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
728                 exit(1);
729         }       
730 }
731 /***********************************************************************/
732
733 //This function separates the key value from the option value i.e. dist=96_...
734 inline void splitAtEquals(string& key, string& value){          
735         try {
736                 if(value.find_first_of('=') != -1){
737                         key = value.substr(0,value.find_first_of('='));
738                         if ((value.find_first_of('=')+1) <= value.length()) {
739                                 value = value.substr(value.find_first_of('=')+1, value.length());
740                         }
741                 }else{
742                         key = value;
743                         value = 1;
744                 }
745         }
746         catch(exception& e) {
747                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function splitAtEquals. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
748                 exit(1);
749         }       
750 }
751 /**************************************************************************************************/
752
753 inline bool inUsersGroups(string groupname, vector<string> Groups) {
754         try {
755                 for (int i = 0; i < Groups.size(); i++) {
756                         if (groupname == Groups[i]) { return true; }
757                 }
758                 return false;
759         }
760         catch(exception& e) {
761                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function inUsersGroups. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
762                 exit(1);
763         }       
764 }
765 /**************************************************************************************************/
766 //returns true if any of the strings in first vector are in second vector
767 inline bool inUsersGroups(vector<string> groupnames, vector<string> Groups) {
768         try {
769                 
770                 for (int i = 0; i < groupnames.size(); i++) {
771                         if (inUsersGroups(groupnames[i], Groups)) { return true; }
772                 }
773                 return false;
774         }
775         catch(exception& e) {
776                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function inUsersGroups. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
777                 exit(1);
778         }       
779 }
780 /***********************************************************************/
781 //this function determines if the user has given us labels that are smaller than the given label.
782 //if so then it returns true so that the calling function can run the previous valid distance.
783 //it's a "smart" distance function.  It also checks for invalid labels.
784 inline bool anyLabelsToProcess(string label, set<string>& userLabels, string errorOff) {
785         try {
786                 
787                 set<string>::iterator it;
788                 vector<float> orderFloat;
789                 map<string, float> userMap;  //the conversion process removes trailing 0's which we need to put back
790                 map<string, float>::iterator it2;
791                 float labelFloat;
792                 bool smaller = false;
793                 
794                 //unique is the smallest line
795                 if (label == "unique") {  return false;  }
796                 else { convert(label, labelFloat); }
797                 
798                 //go through users set and make them floats
799                 for(it = userLabels.begin(); it != userLabels.end(); ++it) {
800                         
801                         float temp;
802                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
803                                 convert(*it, temp);
804                                 orderFloat.push_back(temp);
805                                 userMap[*it] = temp;
806                         }else if (*it == "unique") { 
807                                 orderFloat.push_back(-1.0);
808                                 userMap["unique"] = -1.0;
809                         }else {
810                                 if (errorOff == "") {  cout << *it << " is not a valid label." << endl;  }
811                                 userLabels.erase(*it); 
812                                 it--;
813                         }
814                 }
815                 
816                 //sort order
817                 sort(orderFloat.begin(), orderFloat.end());
818                 
819                 /*************************************************/
820                 //is this label bigger than any of the users labels
821                 /*************************************************/
822                                 
823                 //loop through order until you find a label greater than label
824                 for (int i = 0; i < orderFloat.size(); i++) {
825                         if (orderFloat[i] < labelFloat) {
826                                 smaller = true;
827                                 if (orderFloat[i] == -1) { 
828                                         if (errorOff == "") { cout << "Your file does not include the label unique." << endl; }
829                                         userLabels.erase("unique");
830                                 }
831                                 else {  
832                                         if (errorOff == "") { cout << "Your file does not include the label " << endl; }
833                                         string s = "";
834                                         for (it2 = userMap.begin(); it2!= userMap.end(); it2++) {  
835                                                 if (it2->second == orderFloat[i]) {  
836                                                         s = it2->first;  
837                                                         //remove small labels
838                                                         userLabels.erase(s);
839                                                         break;
840                                                 }
841                                         }
842                                         if (errorOff == "") {cout << s <<  ". I will use the next smallest distance. " << endl; }
843                                 }
844                         //since they are sorted once you find a bigger one stop looking
845                         }else { break; }
846                 }
847                 
848                 return smaller;
849                                                 
850         }
851         catch(exception& e) {
852                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function anyLabelsToProcess. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
853                 exit(1);
854         }       
855 }
856
857 /**************************************************************************************************/
858 inline void appendFiles(string temp, string filename) {
859         try{
860                 ofstream output;
861                 ifstream input;
862         
863                 //open output file in append mode
864                 openOutputFileAppend(filename, output);
865                 openInputFile(temp, input);
866                 
867                 while(char c = input.get()){
868                         if(input.eof())         {       break;                  }
869                         else                            {       output << c;    }
870                 }
871                 
872                 input.close();
873                 output.close();
874         }
875         catch(exception& e) {
876                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function appendFiles. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
877                 exit(1);
878         }       
879 }
880
881 /**************************************************************************************************/
882 inline string sortFile(string distFile){
883         try {   
884                 string outfile = getRootName(distFile) + "sorted.dist";
885                 
886                 //if you can, use the unix sort since its been optimized for years
887                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
888                         string command = "sort -n -k +3 " + distFile + " -o " + outfile;
889                         system(command.c_str());
890                 #else //you are stuck with my best attempt...
891                         //windows sort does not have a way to specify a column, only a character in the line
892                         //since we cannot assume that the distance will always be at the the same character location on each line
893                         //due to variable sequence name lengths, I chose to force the distance into first position, then sort and then put it back.
894                 
895                         //read in file line by file and put distance first
896                         string tempDistFile = distFile + ".temp";
897                         ifstream input;
898                         ofstream output;
899                         openInputFile(distFile, input);
900                         openOutputFile(tempDistFile, output);
901
902                         string firstName, secondName;
903                         float dist;
904                         while (input) {
905                                 input >> firstName >> secondName >> dist;
906                                 output << dist << '\t' << firstName << '\t' << secondName << endl;
907                                 gobble(input);
908                         }
909                         input.close();
910                         output.close();
911                 
912         
913                         //sort using windows sort
914                         string tempOutfile = outfile + ".temp";
915                         string command = "sort " + tempDistFile + " /O " + tempOutfile;
916                         system(command.c_str());
917                 
918                         //read in sorted file and put distance at end again
919                         ifstream input2;
920                         openInputFile(tempOutfile, input2);
921                         openOutputFile(outfile, output);
922                 
923                         while (input2) {
924                                 input2 >> dist >> firstName >> secondName;
925                                 output << firstName << '\t' << secondName << '\t' << dist << endl;
926                                 gobble(input2);
927                         }
928                         input2.close();
929                         output.close();
930                 
931                         //remove temp files
932                         remove(tempDistFile.c_str());
933                         remove(tempOutfile.c_str());
934                 #endif
935                 
936                 return outfile;
937         }
938         catch(exception& e) {
939                 cout << "Standard Error: " << e.what() << " has occurred in the mothur.h function sortfile. Please contact Pat Schloss at mothur.bugs@gmail.com." << "\n";
940                 exit(1);
941         }       
942 }
943 /**************************************************************************************************/
944 #endif
945