From: westcott <westcott>
Date: Mon, 9 Mar 2009 12:00:21 +0000 (+0000)
Subject: fixed valid parameters to include shared parameter for read.shared command.
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=9651e8e7172d86707b34af15e95ec60ad4c3c3f9;p=mothur.git

fixed valid parameters to include shared parameter for read.shared command.
---

diff --git a/fullmatrix.cpp b/fullmatrix.cpp
index 3f1344c..c61109c 100644
--- a/fullmatrix.cpp
+++ b/fullmatrix.cpp
@@ -9,18 +9,60 @@
 
 #include "fullmatrix.h"
 
-
 /**************************************************************************/
 //This constructor reads a distance matrix file and stores the data in the matrix.
-FullMatrix::FullMatrix(ifstream& f) {
+FullMatrix::FullMatrix(ifstream& filehandle) {
 	try{
-		string name;
-		f >> numSeqs >> name;
+		globaldata = GlobalData::getInstance();
+		groupmap = globaldata->gGroupmap;
 		
-		matrix.resize(numSeqs);  
+		string name, group;
+		filehandle >> numSeqs >> name;
 		
+		//make the matrix filled with zeros
+		matrix.resize(numSeqs); 
+		for(int i = 0; i < numSeqs; i++) {
+			matrix[i].resize(numSeqs, 0);
+		}
+		
+		group = groupmap->getGroup(name);
+		if(group == "not found") {	cout << "Error: Sequence '" << name << "' was not found in the group file, please correct." << endl; exit(1); }
+		index[0] = group; 
+		
+		//determine if matrix is square or lower triangle
+		//if it is square read the distances for the first sequence
+		char d;
+		while((d=filehandle.get()) != EOF){
+			
+			//is d a number meaning its square
+			if(isalnum(d)){ 
+				square = true;
+				filehandle.putback(d);
+				for(int i=0;i<numSeqs;i++){
+					filehandle >> matrix[0][i];
+				}
+				break;
+			}
+			
+			//is d a line return meaning its lower triangle
+			if(d == '\n'){
+				square = false;
+				break;
+			}
+		}
+		
+		//read rest of matrix
+		if (square == true) { readSquareMatrix(filehandle); }
+		else { readLTMatrix(filehandle); }
+		
+		
+		
+	printMatrix(cout);
+		//sort sequences so they are gathered in groups for processing
+		sortGroups();
+		cout << "after sort" << endl;
+	printMatrix(cout);
 		
-	
 	}
 	catch(exception& e) {
 		cout << "Standard Error: " << e.what() << " has occurred in the FullMatrix class Function FullMatrix. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
@@ -31,6 +73,188 @@ FullMatrix::FullMatrix(ifstream& f) {
 		exit(1);
 	}
 }
+/**************************************************************************/
+void FullMatrix::readSquareMatrix(ifstream& filehandle) {
+	try {
+	
+		Progress* reading;
+		reading = new Progress("Reading matrix:    ", numSeqs * numSeqs);
+		
+		int count = 0;
+		float distance;
+		string group, name;
+		
+		for(int i=1;i<numSeqs;i++){
+			filehandle >> name;		
+			
+			group = groupmap->getGroup(name);
+			index[i] = group;
+			
+			if(group == "not found") {	cout << "Error: Sequence '" << name << "' was not found in the group file, please correct." << endl; exit(1); }
+				
+			for(int j=0;j<numSeqs;j++){
+				filehandle >> distance;
+					
+				matrix[i][j] = distance;
+				count++;
+				reading->update(count);
+			}
+		}
+		reading->finish();
+		delete reading;
+	}
+	catch(exception& e) {
+		cout << "Standard Error: " << e.what() << " has occurred in the FullMatrix class Function readSquareMatrix. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+	catch(...) {
+		cout << "An unknown error has occurred in the FullMatrix class function readSquareMatrix. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+
+} 
+/**************************************************************************/
+void FullMatrix::readLTMatrix(ifstream& filehandle) {
+	try {
+		Progress* reading;
+		reading = new Progress("Reading matrix:    ", numSeqs * (numSeqs - 1) / 2);
+		
+		int count = 0;
+		float distance;
+		string group, name;
+		
+		for(int i=1;i<numSeqs;i++){
+			filehandle >> name;		
+						
+			group = groupmap->getGroup(name);
+			index[i] = group;
+	
+			if(group == "not found") {	cout << "Error: Sequence '" << name << "' was not found in the group file, please correct." << endl;  exit(1); }
+				
+			for(int j=0;j<i;j++){
+				filehandle >> distance;
+					
+				matrix[i][j] = distance;  matrix[j][i] = distance;
+				count++;
+				reading->update(count);
+			}
+		}
+		reading->finish();
+		delete reading;
+	}
+	catch(exception& e) {
+		cout << "Standard Error: " << e.what() << " has occurred in the FullMatrix class Function readLTMatrix. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+	catch(...) {
+		cout << "An unknown error has occurred in the FullMatrix class function readLTMatrix. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+
+}
+
+/**************************************************************************/
+void FullMatrix::sortGroups(){
+	try{
+		//sort each row by group and when you do, swap rows too.
+		for (int i = 0; i < numSeqs; i++) {
+			quicksort(0, numSeqs-1, i);
+		}
+	}
+	catch(exception& e) {
+		cout << "Standard Error: " << e.what() << " has occurred in the FullMatrix class Function sortGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+	catch(...) {
+		cout << "An unknown error has occurred in the FullMatrix class function sortGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+
+}
+/**************************************************************************/
+//this is a version of quicksort taken from http://www.c.happycodings.com/Sorting_Searching/code13.html
+/* sort everything inbetween `low' <-> `high' */
+void FullMatrix::quicksort(int low, int high, int row) {
+	try {
+		int i = low;
+		int j = high;
+		int y = 0;
+		
+		/* compare value */
+		//what group does this row belong to
+		string z = index[(low + high) / 2];
+
+		/* partition */
+		do {
+			/* find member above ... */
+			while(index[i] < z) i++;
+
+			/* find element below ... */
+			while(index[j] > z) j--;
+			
+			if(i <= j) {
+				/* swap two elements in row*/
+				y = matrix[row][i];
+				matrix[row][i] = matrix[row][j]; 
+				matrix[row][j] = y;
+				
+				/* swap two elements in column*/
+				y = matrix[i][row];
+				matrix[i][row] = matrix[j][row]; 
+				matrix[j][row] = y;
+				
+				//swap map elements
+				z = index[i];
+				index[i] = index[j];
+				index[j] = z;
+				
+				i++; 
+				j--;
+//cout << "swapping elements " << i << " " << j << endl;
+//printMatrix(cout); cout << endl;
+			}
+		} while(i <= j);
+
+		/* recurse */
+		if(low < j) 
+		quicksort(low, j, row);
+
+		if(i < high) 
+		quicksort(i, high, row); 
+	}
+	catch(exception& e) {
+		cout << "Standard Error: " << e.what() << " has occurred in the FullMatrix class Function quicksort. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+	catch(...) {
+		cout << "An unknown error has occurred in the FullMatrix class function quicksort. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+}
+
 /**************************************************************************/	
 int FullMatrix::getNumSeqs(){ return numSeqs; }
-/**************************************************************************/
\ No newline at end of file
+/**************************************************************************/
+//print out matrix
+void FullMatrix::printMatrix(ostream& out) {
+	try{
+		for (int i = 0; i < numSeqs; i++) {
+			out << "row " << i << " group = " << index[i] << endl;
+			for (int j = 0; j < numSeqs; j++) {
+				out << matrix[i][j] << " ";
+			}
+			out << endl;
+		}
+	}
+	catch(exception& e) {
+		cout << "Standard Error: " << e.what() << " has occurred in the FullMatrix class Function printMatrix. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+	catch(...) {
+		cout << "An unknown error has occurred in the FullMatrix class function printMatrix. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
+		exit(1);
+	}
+
+}
+/**************************************************************************/
+
diff --git a/fullmatrix.h b/fullmatrix.h
index 389816a..f3ad0e7 100644
--- a/fullmatrix.h
+++ b/fullmatrix.h
@@ -11,21 +11,32 @@
 
 #include "mothur.h"
 #include "groupmap.h"
+#include "globaldata.hpp"
+#include "progress.hpp"
+
+using namespace std;
 
 class FullMatrix {
 	
-public:
-	FullMatrix(){};
-	FullMatrix(ifstream&);
-	~FullMatrix(){};
+	public:
+		FullMatrix(){};
+		FullMatrix(ifstream&);
+		~FullMatrix(){};
 	
-	int getNumSeqs();
+		int getNumSeqs();
+		void printMatrix(ostream&);
 	
-private:
-	void sortGroups();  //this function sorts the sequences within the matrix.  
-	vector< vector<float> > matrix;  //a 2D distance matrix of all the sequences and their distances to eachother.
-	GroupMap* groupmap;  //maps sequences to groups they belong to.
-	int numSeqs;
+	private:
+		void sortGroups();  //this function sorts the sequences within the matrix.
+		void quicksort(int, int, int);//row of matrix, low, high and row number
+		void readSquareMatrix(ifstream&);  
+		void readLTMatrix(ifstream&);
+		vector< vector<float> > matrix;  //a 2D distance matrix of all the sequences and their distances to eachother.
+		map<int, string> index; // row in vector, sequence group.  need to know this so when we sort it can be updated.
+		GroupMap* groupmap;  //maps sequences to groups they belong to.
+		GlobalData* globaldata;
+		int numSeqs;
+		bool square;
 
 };
 
diff --git a/globaldata.cpp b/globaldata.cpp
index 015293d..b1ac4e8 100644
--- a/globaldata.cpp
+++ b/globaldata.cpp
@@ -185,6 +185,7 @@ void GlobalData::parseGlobalData(string commandString, string optionText){
 		
 		//set format for shared
 		if ((listfile != "") && (groupfile != "")) { format = "shared"; }
+		if ((phylipfile != "") && (groupfile != "")) { format = "matrix"; }
 				
 		//input defaults for calculators
 		if (commandName == "collect.single") {
diff --git a/globaldata.hpp b/globaldata.hpp
index 309ab4a..0dc4c34 100644
--- a/globaldata.hpp
+++ b/globaldata.hpp
@@ -10,6 +10,7 @@ using namespace std;
 class ListVector;
 class SharedListVector;
 class SparseMatrix;
+class FullMatrix;
 class Tree;
 class OrderVector;
 class InputData;
@@ -29,6 +30,7 @@ public:
 	SharedListVector* gSharedList;
 	SAbundVector* sabund;
 	GroupMap* gGroupmap;
+	FullMatrix* gMatrix;
 	TreeMap* gTreemap;
 	string inputFileName, helpRequest, commandName;
 	bool allLines;
diff --git a/helpcommand.cpp b/helpcommand.cpp
index 206df13..9fb5ad7 100644
--- a/helpcommand.cpp
+++ b/helpcommand.cpp
@@ -153,7 +153,7 @@ int HelpCommand::execute(){
 		cout << "The parsimony command should be in the following format: parsimony(random=yourOutputFilename, groups=yourGroups, iters=yourIters)." << "\n";
 		cout << "Example parsimony(random=out, iters=500)." << "\n";
 		cout << "The default value for random is "" (meaning you want to use the trees in your inputfile, randomtree=out means you just want the random distribution of trees outputted to out.rd_parsimony)," << "\n";
-		cout << "and iters is 1000.  The parsimony command output three files: .parsimony, .psummary and .pdistrib, their descriptions are in the manual." << "\n";
+		cout << "and iters is 1000.  The parsimony command output two files: .parsimony and .psummary their descriptions are in the manual." << "\n";
 		cout << "Note: No spaces between parameter labels (i.e. random), '=' and parameters (i.e.yourOutputFilename)." << "\n" << "\n";
 	}else if (globaldata->helpRequest == "unifrac.weighted") { 
 		cout << "The unifrac.weighted command can only be executed after a successful read.tree command." << "\n";
@@ -163,7 +163,7 @@ int HelpCommand::execute(){
 		cout << "The unifrac.weighted command should be in the following format: unifrac.weighted(groups=yourGroups, iters=yourIters)." << "\n";
 		cout << "Example unifrac.weighted(groups=A-B-C, iters=500)." << "\n";
 		cout << "The default value for groups is all the groups in your groupfile, and iters is 1000." << "\n";
-		cout << "The unifrac.weighted command output three files: .weighted, .wsummary and .wdistrib, their descriptions are in the manual." << "\n";
+		cout << "The unifrac.weighted command output two files: .weighted and .wsummary their descriptions are in the manual." << "\n";
 		cout << "Note: No spaces between parameter labels (i.e. list), '=' and parameters (i.e.yourListfile)." << "\n" << "\n";
 	}else if (globaldata->helpRequest == "unifrac.unweighted") { 
 		cout << "The unifrac.unweighted command can only be executed after a successful read.tree command." << "\n";
@@ -173,7 +173,7 @@ int HelpCommand::execute(){
 		cout << "The unifrac.unweighted command should be in the following format: unifrac.unweighted(groups=yourGroups, iters=yourIters)." << "\n";
 		cout << "Example unifrac.unweighted(groups=A-B-C, iters=500)." << "\n";
 		cout << "The default value for groups is all the groups in your groupfile, and iters is 1000." << "\n";
-		cout << "The unifrac.unweighted command output three files: .unweighted, .uwsummary and .uwdistrib, their descriptions are in the manual." << "\n";
+		cout << "The unifrac.unweighted command output two files: .unweighted and .uwsummary their descriptions are in the manual." << "\n";
 		cout << "Note: No spaces between parameter labels (i.e. list), '=' and parameters (i.e.yourListfile)." << "\n" << "\n";
 	}else if (globaldata->helpRequest == "quit") {
 		cout << "The quit command will terminate Dotur and should be in the following format: " << "\n";
diff --git a/parsimonycommand.cpp b/parsimonycommand.cpp
index f718653..c7340c7 100644
--- a/parsimonycommand.cpp
+++ b/parsimonycommand.cpp
@@ -237,11 +237,11 @@ void ParsimonyCommand::printUSummaryFile() {
 		for (int i = 0; i< T.size(); i++) {
 			for(int a = 0; a < numComp; a++) {
 				if (UScoreSig[a][i] > (1/(float)iters)) {
-					outSum << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << userTreeScores[a][i] << '\t' << UScoreSig[a][i] << endl;
-					cout << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << userTreeScores[a][i] << '\t' << UScoreSig[a][i] << endl;
+					outSum << setprecision(6) << i+1 << '\t' << groupComb[a] << '\t' << '\t' << userTreeScores[a][i] << setprecision(globaldata->getIters().length()) << '\t' << UScoreSig[a][i] << endl;
+					cout << setprecision(6) << i+1 << '\t' << groupComb[a] << '\t' << '\t' << userTreeScores[a][i] << setprecision(globaldata->getIters().length()) << '\t' << UScoreSig[a][i] << endl;
 				}else {
-					outSum << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << userTreeScores[a][i] << '\t' << "<" << (1/float(iters)) << endl;
-					cout << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << userTreeScores[a][i] << '\t' << "<" << (1/float(iters)) << endl;
+					outSum << setprecision(6) << i+1 << '\t' << groupComb[a] << '\t' << userTreeScores[a][i] << setprecision(globaldata->getIters().length())  << '\t' << "<" << (1/float(iters)) << endl;
+					cout << setprecision(6) << i+1 << '\t' << groupComb[a] << '\t' << userTreeScores[a][i] << setprecision(globaldata->getIters().length()) << '\t' << "<" << (1/float(iters)) << endl;
 				}
 			}
 		}
@@ -431,16 +431,16 @@ void ParsimonyCommand::output(vector<double> data){
 			getline(inFile, inputBuffer);
 		
 			if (randomtree == "") {
-				out << inputBuffer << '\t' << setprecision(globaldata->getIters().length()) << data[0] << '\t' << data[1] << '\t' << data[2] << '\t' << data[3] << '\t' << data[4] << endl;
+				out << inputBuffer << '\t' << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << '\t' << data[3] << '\t' << data[4] << endl;
 			}else{
-				out << inputBuffer << '\t' << setprecision(globaldata->getIters().length()) << data[0] << '\t' << data[1] << '\t' << data[2] << endl;
+				out << inputBuffer << '\t' << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << endl;
 			}
 		}
 		else{
 			if (randomtree == "") {
-				out << setprecision(globaldata->getIters().length()) << data[0] << '\t' << data[1] << '\t' << data[2] << '\t' << data[3] << '\t' << data[4] << endl;
+				out << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << '\t' << data[3] << '\t' << data[4] << endl;
 			}else{
-				out << setprecision(globaldata->getIters().length()) << data[0] << '\t' << data[1] << '\t' << data[2] << endl;
+				out << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << endl;
 			}
 		}
 
diff --git a/readdistcommand.cpp b/readdistcommand.cpp
index 4cf5c4e..116e670 100644
--- a/readdistcommand.cpp
+++ b/readdistcommand.cpp
@@ -17,24 +17,31 @@ ReadDistCommand::ReadDistCommand(){
 		format = globaldata->getFormat();	
 		
 		if (format == "column") { read = new ReadColumnMatrix(filename); }	
-		else if (format == "phylip") { read = new ReadPhylipMatrix(filename); }	
-			
-		if(globaldata->getPrecision() != ""){
-			convert(globaldata->getPrecision(), precision);	
+		else if (format == "phylip") { read = new ReadPhylipMatrix(filename); }
+		else if (format == "matrix") { 
+				groupMap = new GroupMap(globaldata->getGroupFile());
+				groupMap->readMap();
+				globaldata->gGroupmap = groupMap;
 		}
 		
-		if(globaldata->getCutOff() != ""){
-			convert(globaldata->getCutOff(), cutoff);	
-			cutoff += (5 / (precision * 10.0));
-		}
-		read->setCutoff(cutoff);
+		if (format != "matrix" ) {
+			if(globaldata->getPrecision() != ""){
+				convert(globaldata->getPrecision(), precision);	
+			}
+		
+			if(globaldata->getCutOff() != ""){
+				convert(globaldata->getCutOff(), cutoff);	
+				cutoff += (5 / (precision * 10.0));
+			}
+			read->setCutoff(cutoff);
 	
-		if(globaldata->getNameFile() != ""){	
-			nameMap = new NameAssignment(globaldata->getNameFile());
-			nameMap->readMap(1,2);
-		}
-		else{
-			nameMap = NULL;
+			if(globaldata->getNameFile() != ""){	
+				nameMap = new NameAssignment(globaldata->getNameFile());
+				nameMap->readMap(1,2);
+			}
+			else{
+				nameMap = NULL;
+			}
 		}
 			
 	}
@@ -57,9 +64,17 @@ ReadDistCommand::~ReadDistCommand(){
 //**********************************************************************************************************************
 int ReadDistCommand::execute(){
 	try {
-		read->read(nameMap);
-		globaldata->setListVector(read->getListVector());
-		globaldata->setSparseMatrix(read->getMatrix());
+		
+		if (format == "matrix") {
+			ifstream in;
+			openInputFile(filename, in);
+			matrix = new FullMatrix(in); //reads the matrix file
+			globaldata->gMatrix = matrix; //save matrix for coverage commands
+		}else {
+			read->read(nameMap);
+			globaldata->setListVector(read->getListVector());
+			globaldata->setSparseMatrix(read->getMatrix());
+		}
 		return 0;
 	}
 	catch(exception& e) {
diff --git a/readdistcommand.h b/readdistcommand.h
index bd4a913..981afa3 100644
--- a/readdistcommand.h
+++ b/readdistcommand.h
@@ -11,6 +11,8 @@
 
 #include "command.hpp"
 #include "readmatrix.hpp"
+#include "fullmatrix.h"
+#include "groupmap.h"
 
 /* The read.dist command is used to read a distance matrix file.  
 The read.dist command parameter options are phylipfile, columnfile, namefile, cutoff and precision. 
@@ -33,6 +35,8 @@ private:
 	double cutoff;
 	int precision;
 	ReadMatrix* read;
+	FullMatrix* matrix;
+	GroupMap* groupMap;
 	string filename, format, method;
 	NameAssignment* nameMap;
 };
diff --git a/readtree.cpp b/readtree.cpp
index a253741..c33617f 100644
--- a/readtree.cpp
+++ b/readtree.cpp
@@ -32,12 +32,12 @@ int ReadTree::readSpecialChar(istream& f, char c, string name) {
 		char d = f.get();
 	
 		if(d == EOF){
-			cerr << "Error: Input file ends prematurely, expecting a " << name << "\n";
-			exit(1);
+			cerr << "Error: Input file ends prematurely, expecting a " << name << "\n";  return -1;
+			//exit(1);
 		}
 		if(d != c){
-			cerr << "Error: Expected " << name << " in input file.  Found " << d << ".\n";
-			exit(1);
+			cerr << "Error: Expected " << name << " in input file.  Found " << d << ".\n";  return -1;
+			//exit(1);
 		}
 		if(d == ')' && f.peek() == '\n'){
 			gobble(f);
@@ -62,8 +62,8 @@ int ReadTree::readNodeChar(istream& f) {
 		char d = f.get();
 
 		if(d == EOF){
-			cerr << "Error: Input file ends prematurely, expecting a left parenthesis\n";
-			exit(1);
+			cerr << "Error: Input file ends prematurely, expecting a left parenthesis\n";  return -1;
+			//exit(1);
 		}
 		return d;
 	}
@@ -84,8 +84,8 @@ float ReadTree::readBranchLength(istream& f) {
 		float b;
 	
 		if(!(f >> b)){
-			cerr << "Error: Missing branch length in input tree.\n";
-			exit(1);
+			cerr << "Error: Missing branch length in input tree.\n";  return -1;
+			//exit(1);
 		}
 		gobble(f);
 		return b;
@@ -111,9 +111,9 @@ float ReadTree::readBranchLength(istream& f) {
 /***********************************************************************/
 //This class reads a file in Newick form and stores it in a tree.
 
-void ReadNewickTree::read() {
+int ReadNewickTree::read() {
 	try {
-		int c;
+		int c, error;
 		int comment = 0;
 		
 		//if you are not a nexus file 
@@ -124,7 +124,7 @@ void ReadNewickTree::read() {
 				numNodes = T->getNumNodes();
 				numLeaves = T->getNumLeaves();
 				
-				readTreeString(); 
+				error = readTreeString(); 
 				
 				//save trees for later commands
 				globaldata->gTree.push_back(T); 
@@ -158,12 +158,13 @@ void ReadNewickTree::read() {
 				numLeaves = T->getNumLeaves();
 				
 				//read tree info
-				readTreeString(); 
+				error = readTreeString(); 
 				 
 				//save trees for later commands
 				globaldata->gTree.push_back(T); 
 			}
 		}
+		return readOk;
 	}
 	catch(exception& e) {
 		cout << "Standard Error: " << e.what() << " has occurred in the ReadNewickTree class Function read. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
@@ -221,11 +222,11 @@ void ReadNewickTree::nexusTranslation() {
 }
 
 /**************************************************************************************************/
-void ReadNewickTree::readTreeString() {
+int ReadNewickTree::readTreeString() {
 	try {
 		
 		int n = 0;
-		int lc, rc; 
+		int lc, rc, error; 
 		
 		int rooted = 0;
 	
@@ -235,9 +236,11 @@ void ReadNewickTree::readTreeString() {
 			n = numLeaves;  //number of leaves / sequences, we want node 1 to start where the leaves left off
 
 			lc = readNewickInt(filehandle, n, T);
+			if (lc == -1) { return -1; } //reports an error in reading
 		
 			if(filehandle.peek()==','){							
-				readSpecialChar(filehandle,',',"comma");
+				error = readSpecialChar(filehandle,',',"comma");
+				if (error == -1) { readOk = -1; return -1; }
 			}
 			// ';' means end of tree.												
 			else if((ch=filehandle.peek())==';' || ch=='['){		
@@ -245,8 +248,10 @@ void ReadNewickTree::readTreeString() {
 			}												
 			if(rooted != 1){								
 				rc = readNewickInt(filehandle, n, T);
+				if (rc == -1) { return -1; } //reports an error in reading
 				if(filehandle.peek() == ')'){					
-					readSpecialChar(filehandle,')',"right parenthesis");
+					error = readSpecialChar(filehandle,')',"right parenthesis");
+					if (error == -1) { readOk = -1; return -1; }
 				}											
 			}												
 		}
@@ -261,7 +266,8 @@ void ReadNewickTree::readTreeString() {
 
 			if(n!=0){
 				cerr << "Internal error: The only taxon is not taxon 0.\n";
-				exit(1);
+				//exit(1);
+				readOk = -1; return -1;
 			}
 			lc = rc = -1;
 		} 
@@ -274,6 +280,7 @@ void ReadNewickTree::readTreeString() {
 			if(lc!=-1){		T->tree[lc].setParent(n);		}
 			if(rc!=-1){		T->tree[rc].setParent(n);		}
 		}
+		return 0;
 	
 	}
 	catch(exception& e) {
@@ -290,21 +297,31 @@ void ReadNewickTree::readTreeString() {
 
 int ReadNewickTree::readNewickInt(istream& f, int& n, Tree* T) {
 	try {
+		int error;
+		
 		int c = readNodeChar(f);
+		if (c == -1) { readOk = -1; return -1; }
     
 		if(c == '('){
 			int lc = readNewickInt(f, n, T);
-			readSpecialChar(f,',',"comma");
+			if (lc == -1) { return -1; } //reports an error in reading
+			error = readSpecialChar(f,',',"comma");
+			if (error == -1) { readOk = -1; return -1; }
 
-			int rc = readNewickInt(f, n, T);		
+			int rc = readNewickInt(f, n, T);
+			if (rc == -1) { return -1; }  //reports an error in reading	
 			if(f.peek()==')'){	
-				readSpecialChar(f,')',"right parenthesis");					
+				error = readSpecialChar(f,')',"right parenthesis");	
+				if (error == -1) { readOk = -1; return -1; }				
 			}			
 		
 			if(f.peek() == ':'){									      
-				readSpecialChar(f,':',"colon");							
-				if(n >= numNodes){	cerr << "Error: Too many nodes in input tree\n";  exit(1); }
-				T->tree[n].setBranchLength(readBranchLength(f));
+				error = readSpecialChar(f,':',"colon");	
+				if (error == -1) { readOk = -1; return -1; }						
+				if(n >= numNodes){	cerr << "Error: Too many nodes in input tree\n";  readOk = -1; return -1; }
+				error = readBranchLength(f);
+				if (error == -1) { readOk = -1; return -1; }
+				T->tree[n].setBranchLength(error);
 			}else{T->tree[n].setBranchLength(0.0); }						
 		
 			T->tree[n].setChildren(lc,rc);
@@ -334,7 +351,7 @@ int ReadNewickTree::readNewickInt(istream& f, int& n, Tree* T) {
 			
 			//adds sequence names that are not in group file to the "xxx" group
 			if(n1 == -1) {
-				cerr << "Name: " << name << " not found in your groupfile.. \n"; exit(1);
+				cerr << "Name: " << name << " not found in your groupfile. \n"; readOk = -1; return n1;
 				
 				//globaldata->gTreemap->namesOfSeqs.push_back(name);
 				//globaldata->gTreemap->treemap[name].groupname = "xxx";
@@ -360,8 +377,10 @@ int ReadNewickTree::readNewickInt(istream& f, int& n, Tree* T) {
 			T->tree[n1].setChildren(-1,-1);
 		
 			if(blen == 1){	
-				f.get();		
-				T->tree[n1].setBranchLength(readBranchLength(f));
+				f.get();
+				error = readBranchLength(f);	
+				if (error == -1) { readOk = -1; return -1; }	
+				T->tree[n1].setBranchLength(error);
 			}else{
 				T->tree[n1].setBranchLength(0.0);
 			}
diff --git a/readtree.h b/readtree.h
index 250b1db..15597ba 100644
--- a/readtree.h
+++ b/readtree.h
@@ -27,7 +27,7 @@ class ReadTree {
 		ReadTree(); 
 		~ReadTree() {};
 		
-		virtual void read() {};
+		virtual int read() = 0;
 		int readSpecialChar(istream&, char, string);
 		int readNodeChar(istream& f);
 		float readBranchLength(istream& f);
@@ -36,6 +36,7 @@ class ReadTree {
 		GlobalData* globaldata;
 		int numNodes, numLeaves;
 		
+		
 };
 
 /****************************************************************************/
@@ -43,18 +44,20 @@ class ReadTree {
 class ReadNewickTree : public ReadTree {
 	
 public:
-	ReadNewickTree(string file) : treeFile(file) { openInputFile(file, filehandle); } 
+	ReadNewickTree(string file) : treeFile(file) { openInputFile(file, filehandle); readOk = 0; } 
 	~ReadNewickTree() {};
-	void read();
+	int read();
 	
 private:
 	Tree* T;
 	int readNewickInt(istream&, int&, Tree*);
-	void readTreeString();
+	int readTreeString();
 	void nexusTranslation();
 	ifstream filehandle;
 	string treeFile;
 	string holder;
+	int readOk;  // readOk = 0 means success, readOk = 1 means errors.
+	
 };
 
 /****************************************************************************/
diff --git a/readtreecommand.cpp b/readtreecommand.cpp
index 63c6226..405de84 100644
--- a/readtreecommand.cpp
+++ b/readtreecommand.cpp
@@ -43,8 +43,11 @@ ReadTreeCommand::~ReadTreeCommand(){
 
 int ReadTreeCommand::execute(){
 	try {
-	
-		read->read(); 
+		int readOk;
+		
+		readOk = read->read(); 
+		
+		if (readOk != 0) { cout << "Read Terminated." << endl; globaldata->gTree.clear(); delete globaldata->gTreemap; return 0; }
 		
 		vector<Tree*> T = globaldata->gTree;
 		
@@ -52,6 +55,7 @@ int ReadTreeCommand::execute(){
 		for (int i = 0; i < T.size(); i++) {
 			T[i]->assembleTree();
 		}
+
 		return 0;
 	}
 	catch(exception& e) {
diff --git a/unifracunweightedcommand.cpp b/unifracunweightedcommand.cpp
index 6fd986f..dd1a3f9 100644
--- a/unifracunweightedcommand.cpp
+++ b/unifracunweightedcommand.cpp
@@ -165,15 +165,14 @@ void UnifracUnweightedCommand::printUWSummaryFile() {
 		outSum.setf(ios::fixed, ios::floatfield); outSum.setf(ios::showpoint);
 			
 		//print each line
-		for (int i = 0; i< T.size(); i++) {
-			for(int a = 0; a < numComp; a++) {
-				if (UWScoreSig[a][i] > (1/(float)iters)) {
-					outSum << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << utreeScores[a][i] << '\t' << UWScoreSig[a][i] << endl;
-					cout << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << utreeScores[a][i] << '\t' << UWScoreSig[a][i] << endl;
-				}else {
-					outSum << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << utreeScores[a][i] << '\t' << "<" << (1/float(iters)) << endl;
-					cout << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[a] << '\t' << utreeScores[a][i] << '\t' << "<" << (1/float(iters)) << endl;
-				}
+
+		for(int a = 0; a < numComp; a++) {
+			if (UWScoreSig[a][0] > (1/(float)iters)) {
+				outSum << setprecision(6) << groupComb[a] << '\t' << '\t' << utreeScores[a][0] << '\t' << setprecision(globaldata->getIters().length()) << UWScoreSig[a][0] << endl;
+				cout << setprecision(6)  << groupComb[a] << '\t' << '\t' << utreeScores[a][0] << '\t' << setprecision(globaldata->getIters().length()) << UWScoreSig[a][0] << endl; 
+			}else {
+				outSum << setprecision(6) << groupComb[a] << '\t' << '\t' << utreeScores[a][0] << '\t' << setprecision(globaldata->getIters().length()) << "<" << (1/float(iters)) << endl;
+				cout << setprecision(6)  << groupComb[a] << '\t' << '\t' << utreeScores[a][0] << '\t' << setprecision(globaldata->getIters().length()) << "<" << (1/float(iters)) << endl; 
 			}
 		}
 		
@@ -303,10 +302,10 @@ void UnifracUnweightedCommand::output(vector<double> data){
 			getline(inFile, inputBuffer);
 //			out	<<  inputBuffer << setprecision(6) << '\t' << data[0] << setprecision(globaldata->getIters().length()) << '\t' << data[1] << '\t' << data[2] << endl;
 		
-			out	<<  inputBuffer << setprecision(globaldata->getIters().length()-1) << '\t' << data[1] << '\t' << data[2] << endl;
+			out << inputBuffer << '\t' << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << endl;
 		}
 		else{
-			out << setprecision(6) << data[0] << setprecision(globaldata->getIters().length()-1) << '\t' << data[1] << '\t' << data[2] << endl;
+			out << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << endl;
 		}
 
 	}
diff --git a/unifracweightedcommand.cpp b/unifracweightedcommand.cpp
index 49f6631..2652f8f 100644
--- a/unifracweightedcommand.cpp
+++ b/unifracweightedcommand.cpp
@@ -175,11 +175,11 @@ void UnifracWeightedCommand::printWSummaryFile() {
 		for (int i = 0; i < T.size(); i++) { 
 			for (int j = 0; j < numComp; j++) {
 				if (WScoreSig[count] > (1/(float)iters)) {
-					outSum << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[j] << '\t' << utreeScores[count] << '\t' << WScoreSig[count] << endl; 
-					cout << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[j] << '\t' << utreeScores[count] << '\t' << WScoreSig[count] << endl; 
+					outSum << setprecision(6) << i+1 << '\t' << '\t' << groupComb[j] << '\t' << '\t'  << utreeScores[count] << '\t' << setprecision(globaldata->getIters().length()) << WScoreSig[count] << endl; 
+					cout << setprecision(6) << i+1 << '\t' << '\t' << groupComb[j] << '\t' << '\t'  << utreeScores[count] << '\t' << setprecision(globaldata->getIters().length()) << WScoreSig[count] << endl; 
 				}else{
-					outSum << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[j] << '\t' << utreeScores[count] << '\t' << "<" << (1/float(iters)) << endl; 
-					cout << setprecision(globaldata->getIters().length()) << i+1 << '\t' << groupComb[j] << '\t' << utreeScores[count] << '\t' << "<" << (1/float(iters)) << endl; 
+					outSum << setprecision(6) << i+1 << '\t' << groupComb[j] << '\t' << utreeScores[count] << '\t' << setprecision(globaldata->getIters().length()) << "<" << (1/float(iters)) << endl; 
+					cout << setprecision(6) << i+1 << '\t' << groupComb[j] << '\t' << utreeScores[count] << '\t' << setprecision(globaldata->getIters().length()) << "<" << (1/float(iters)) << endl; 
 				}
 				count++;
 			}
@@ -366,11 +366,12 @@ void UnifracWeightedCommand::output(vector<double> data){
 		if(counter != 0){		
 			string inputBuffer;
 			getline(inFile, inputBuffer);
-			
-			out	<<  inputBuffer << setprecision(globaldata->getIters().length()-1) << '\t' << data[1] << '\t' << data[2] << endl;
+
+			out << inputBuffer << '\t' << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << endl;
 		}
 		else{
-			out << setprecision(6) << data[0] << setprecision(globaldata->getIters().length()-1) << '\t' << data[1] << '\t' << data[2] << endl;
+			out << setprecision(6) << data[0] << setprecision(globaldata->getIters().length())  << '\t' << data[1] << '\t' << data[2] << endl;
+
 		}
 		
 	}
diff --git a/validparameter.cpp b/validparameter.cpp
index 590946e..3a96cc6 100644
--- a/validparameter.cpp
+++ b/validparameter.cpp
@@ -18,7 +18,8 @@ ValidParameters::ValidParameters() {
 		parameters["column"]		= "column";
 		parameters["list"]			= "list"; 
 		parameters["rabund"]		= "rabund"; 
-		parameters["sabund"]		= "sabund"; 
+		parameters["sabund"]		= "sabund";
+		parameters["shared"]		= "shared";
 		parameters["name"]			= "name"; 
 		parameters["group"]			= "group"; 
 		parameters["order"]			= "order";