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