2 * matrixoutputcommand.cpp
5 * Created by Sarah Westcott on 5/20/09.
6 * Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
10 #include "matrixoutputcommand.h"
11 #include "sharedjabund.h"
12 #include "sharedsorabund.h"
13 #include "sharedjclass.h"
14 #include "sharedsorclass.h"
15 #include "sharedjest.h"
16 #include "sharedsorest.h"
17 #include "sharedthetayc.h"
18 #include "sharedthetan.h"
19 #include "sharedmorisitahorn.h"
20 #include "sharedbraycurtis.h"
23 //**********************************************************************************************************************
25 MatrixOutputCommand::MatrixOutputCommand(string option){
27 globaldata = GlobalData::getInstance();
35 //allow user to run help
36 if(option == "help") { validCalculator = new ValidCalculators(); help(); abort = true; }
39 //valid paramters for this command
40 string Array[] = {"line","label","calc","groups"};
41 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
43 OptionParser parser(option);
44 map<string,string> parameters = parser.getParameters();
46 ValidParameters validParameter;
48 //check to make sure all parameters are valid for command
49 for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) {
50 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
53 //make sure the user has already run the read.otu command
54 if (globaldata->getSharedFile() == "") {
55 if (globaldata->getListFile() == "") { cout << "You must read a list and a group, or a shared before you can use the dist.shared command." << endl; abort = true; }
56 else if (globaldata->getGroupFile() == "") { cout << "You must read a list and a group, or a shared before you can use the dist.shared command." << endl; abort = true; }
59 //check for optional parameter and set defaults
60 // ...at some point should added some additional type checking...
61 line = validParameter.validFile(parameters, "line", false);
62 if (line == "not found") { line = ""; }
64 if(line != "all") { splitAtDash(line, lines); allLines = 0; }
65 else { allLines = 1; }
68 label = validParameter.validFile(parameters, "label", false);
69 if (label == "not found") { label = ""; }
71 if(label != "all") { splitAtDash(label, labels); allLines = 0; }
72 else { allLines = 1; }
75 //make sure user did not use both the line and label parameters
76 if ((line != "") && (label != "")) { cout << "You cannot use both the line and label parameters at the same time. " << endl; abort = true; }
77 //if the user has not specified any line or labels use the ones from read.otu
78 else if((line == "") && (label == "")) {
79 allLines = globaldata->allLines;
80 labels = globaldata->labels;
81 lines = globaldata->lines;
84 groups = validParameter.validFile(parameters, "groups", false);
85 if (groups == "not found") { groups = ""; }
87 splitAtDash(groups, Groups);
88 globaldata->Groups = Groups;
91 calc = validParameter.validFile(parameters, "calc", false);
92 if (calc == "not found") { calc = "jclass-thetayc"; }
94 if (calc == "default") { calc = "jclass-thetayc"; }
96 splitAtDash(calc, Estimators);
100 validCalculator = new ValidCalculators();
103 for (i=0; i<Estimators.size(); i++) {
104 if (validCalculator->isValidCalculator("matrix", Estimators[i]) == true) {
105 if (Estimators[i] == "jabund") {
106 matrixCalculators.push_back(new JAbund());
107 }else if (Estimators[i] == "sorabund") {
108 matrixCalculators.push_back(new SorAbund());
109 }else if (Estimators[i] == "jclass") {
110 matrixCalculators.push_back(new Jclass());
111 }else if (Estimators[i] == "sorclass") {
112 matrixCalculators.push_back(new SorClass());
113 }else if (Estimators[i] == "jest") {
114 matrixCalculators.push_back(new Jest());
115 }else if (Estimators[i] == "sorest") {
116 matrixCalculators.push_back(new SorEst());
117 }else if (Estimators[i] == "thetayc") {
118 matrixCalculators.push_back(new ThetaYC());
119 }else if (Estimators[i] == "thetan") {
120 matrixCalculators.push_back(new ThetaN());
121 }else if (Estimators[i] == "morisitahorn") {
122 matrixCalculators.push_back(new MorHorn());
123 }else if (Estimators[i] == "braycurtis") {
124 matrixCalculators.push_back(new BrayCurtis());
133 catch(exception& e) {
134 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function MatrixOutputCommand. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
138 cout << "An unknown error has occurred in the MatrixOutputCommand class function MatrixOutputCommand. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
143 //**********************************************************************************************************************
145 void MatrixOutputCommand::help(){
147 cout << "The dist.shared command can only be executed after a successful read.otu command." << "\n";
148 cout << "The dist.shared command parameters are groups, calc, line and label. The calc parameter is required, and you may not use line and label at the same time." << "\n";
149 cout << "The groups parameter allows you to specify which of the groups in your groupfile you would like included used." << "\n";
150 cout << "The group names are separated by dashes. The line and label allow you to select what distance levels you would like distance matrices created for, and are also separated by dashes." << "\n";
151 cout << "The dist.shared command should be in the following format: dist.shared(groups=yourGroups, calc=yourCalcs, line=yourLines, label=yourLabels)." << "\n";
152 cout << "Example dist.shared(groups=A-B-C, line=1-3-5, calc=jabund-sorabund)." << "\n";
153 cout << "The default value for groups is all the groups in your groupfile." << "\n";
154 cout << "The default value for calc is jclass and thetayc." << "\n";
155 validCalculator->printCalc("matrix", cout);
156 cout << "The dist.shared command outputs a .dist file for each calculator you specify at each distance you choose." << "\n";
157 cout << "Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups)." << "\n" << "\n";
159 catch(exception& e) {
160 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function help. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
164 cout << "An unknown error has occurred in the MatrixOutputCommand class function help. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
170 //**********************************************************************************************************************
172 MatrixOutputCommand::~MatrixOutputCommand(){
173 if (abort == false) {
174 delete input; globaldata->ginput = NULL;
176 delete validCalculator;
180 //**********************************************************************************************************************
182 int MatrixOutputCommand::execute(){
185 if (abort == true) { return 0; }
189 //if the users entered no valid calculators don't execute command
190 if (matrixCalculators.size() == 0) { cout << "No valid calculators." << endl; return 0; }
193 read = new ReadOTUFile(globaldata->inputFileName);
194 read->read(&*globaldata);
196 input = globaldata->ginput;
197 lookup = input->getSharedRAbundVectors();
198 vector<SharedRAbundVector*> lastLookup = lookup;
200 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
201 set<string> processedLabels;
202 set<string> userLabels = labels;
203 set<int> userLines = lines;
205 if (lookup.size() < 2) { cout << "You have not provided enough valid groups. I cannot run the command." << endl; return 0;}
207 numGroups = lookup.size();
209 //as long as you are not at the end of the file or done wih the lines you want
210 while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0) || (userLines.size() != 0))) {
212 if(allLines == 1 || lines.count(count) == 1 || labels.count(lookup[0]->getLabel()) == 1){
213 cout << lookup[0]->getLabel() << '\t' << count << endl;
216 processedLabels.insert(lookup[0]->getLabel());
217 userLabels.erase(lookup[0]->getLabel());
218 userLines.erase(count);
221 if ((anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLookup[0]->getLabel()) != 1)) {
222 cout << lastLookup[0]->getLabel() << '\t' << count << endl;
225 processedLabels.insert(lastLookup[0]->getLabel());
226 userLabels.erase(lastLookup[0]->getLabel());
229 //prevent memory leak
230 if (count != 1) { for (int i = 0; i < lastLookup.size(); i++) { delete lastLookup[i]; } }
233 //get next line to process
234 lookup = input->getSharedRAbundVectors();
238 //output error messages about any remaining user labels
239 set<string>::iterator it;
240 bool needToRun = false;
241 for (it = userLabels.begin(); it != userLabels.end(); it++) {
242 cout << "Your file does not include the label "<< *it;
243 if (processedLabels.count(lastLookup[0]->getLabel()) != 1) {
244 cout << ". I will use " << lastLookup[0]->getLabel() << "." << endl;
247 cout << ". Please refer to " << lastLookup[0]->getLabel() << "." << endl;
251 //run last line if you need to
252 if (needToRun == true) {
253 cout << lastLookup[0]->getLabel() << '\t' << count << endl;
257 for (int i = 0; i < lastLookup.size(); i++) { delete lastLookup[i]; }
260 //reset groups parameter
261 globaldata->Groups.clear();
265 catch(exception& e) {
266 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function execute. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
270 cout << "An unknown error has occurred in the MatrixOutputCommand class function execute. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
274 /***********************************************************/
275 void MatrixOutputCommand::printSims(ostream& out) {
278 //output column headers
279 out << simMatrix.size() << endl;
281 for (int m = 0; m < simMatrix.size(); m++) {
282 out << lookup[m]->getGroup() << '\t';
283 for (int n = 0; n < m; n++) {
284 out << simMatrix[m][n] << '\t';
290 catch(exception& e) {
291 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function printSims. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
295 cout << "An unknown error has occurred in the MatrixOutputCommand class function printSims. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
299 /***********************************************************/
300 void MatrixOutputCommand::process(vector<SharedRAbundVector*> thisLookup){
304 vector<SharedRAbundVector*> subset;
306 //for each calculator
307 for(int i = 0 ; i < matrixCalculators.size(); i++) {
309 //initialize simMatrix
311 simMatrix.resize(numGroups);
312 for (int m = 0; m < simMatrix.size(); m++) {
313 for (int j = 0; j < simMatrix.size(); j++) {
314 simMatrix[m].push_back(0.0);
318 for (int k = 0; k < thisLookup.size(); k++) {
319 for (int l = k; l < thisLookup.size(); l++) {
320 if (k != l) { //we dont need to similiarity of a groups to itself
321 //get estimated similarity between 2 groups
323 subset.clear(); //clear out old pair of sharedrabunds
324 //add new pair of sharedrabunds
325 subset.push_back(thisLookup[k]); subset.push_back(thisLookup[l]);
327 data = matrixCalculators[i]->getValues(subset); //saves the calculator outputs
328 //save values in similarity matrix
329 simMatrix[k][l] = 1.0 - data[0]; //convert similiarity to distance
330 simMatrix[l][k] = 1.0 - data[0]; //convert similiarity to distance
335 exportFileName = getRootName(globaldata->inputFileName) + matrixCalculators[i]->getName() + "." + thisLookup[0]->getLabel() + ".dist";
336 openOutputFile(exportFileName, out);
345 catch(exception& e) {
346 cout << "Standard Error: " << e.what() << " has occurred in the MatrixOutputCommand class Function process. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
350 cout << "An unknown error has occurred in the MatrixOutputCommand class function process. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
354 /***********************************************************/