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();
34 //allow user to run help
35 if(option == "help") { validCalculator = new ValidCalculators(); help(); abort = true; }
38 //valid paramters for this command
39 string Array[] = {"label","calc","groups","outputdir","inputdir"};
40 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
42 OptionParser parser(option);
43 map<string,string> parameters = parser.getParameters();
45 ValidParameters validParameter;
47 //check to make sure all parameters are valid for command
48 for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) {
49 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
52 //if the user changes the output directory command factory will send this info to us in the output parameter
53 outputDir = validParameter.validFile(parameters, "outputdir", false); if (outputDir == "not found"){
55 outputDir += hasPath(globaldata->inputFileName); //if user entered a file with a path then preserve it
58 //make sure the user has already run the read.otu command
59 if (globaldata->getSharedFile() == "") {
60 if (globaldata->getListFile() == "") { mothurOut("You must read a list and a group, or a shared before you can use the dist.shared command."); mothurOutEndLine(); abort = true; }
61 else if (globaldata->getGroupFile() == "") { mothurOut("You must read a list and a group, or a shared before you can use the dist.shared command."); mothurOutEndLine(); abort = true; }
64 //check for optional parameter and set defaults
65 // ...at some point should added some additional type checking...
66 label = validParameter.validFile(parameters, "label", false);
67 if (label == "not found") { label = ""; }
69 if(label != "all") { splitAtDash(label, labels); allLines = 0; }
70 else { allLines = 1; }
73 //if the user has not specified any labels use the ones from read.otu
75 allLines = globaldata->allLines;
76 labels = globaldata->labels;
79 groups = validParameter.validFile(parameters, "groups", false);
80 if (groups == "not found") { groups = ""; }
82 splitAtDash(groups, Groups);
83 globaldata->Groups = Groups;
86 calc = validParameter.validFile(parameters, "calc", false);
87 if (calc == "not found") { calc = "jclass-thetayc"; }
89 if (calc == "default") { calc = "jclass-thetayc"; }
91 splitAtDash(calc, Estimators);
95 validCalculator = new ValidCalculators();
98 for (i=0; i<Estimators.size(); i++) {
99 if (validCalculator->isValidCalculator("matrix", Estimators[i]) == true) {
100 if (Estimators[i] == "jabund") {
101 matrixCalculators.push_back(new JAbund());
102 }else if (Estimators[i] == "sorabund") {
103 matrixCalculators.push_back(new SorAbund());
104 }else if (Estimators[i] == "jclass") {
105 matrixCalculators.push_back(new Jclass());
106 }else if (Estimators[i] == "sorclass") {
107 matrixCalculators.push_back(new SorClass());
108 }else if (Estimators[i] == "jest") {
109 matrixCalculators.push_back(new Jest());
110 }else if (Estimators[i] == "sorest") {
111 matrixCalculators.push_back(new SorEst());
112 }else if (Estimators[i] == "thetayc") {
113 matrixCalculators.push_back(new ThetaYC());
114 }else if (Estimators[i] == "thetan") {
115 matrixCalculators.push_back(new ThetaN());
116 }else if (Estimators[i] == "morisitahorn") {
117 matrixCalculators.push_back(new MorHorn());
118 }else if (Estimators[i] == "braycurtis") {
119 matrixCalculators.push_back(new BrayCurtis());
128 catch(exception& e) {
129 errorOut(e, "MatrixOutputCommand", "MatrixOutputCommand");
134 //**********************************************************************************************************************
136 void MatrixOutputCommand::help(){
138 mothurOut("The dist.shared command can only be executed after a successful read.otu command.\n");
139 mothurOut("The dist.shared command parameters are groups, calc and label. No parameters are required.\n");
140 mothurOut("The groups parameter allows you to specify which of the groups in your groupfile you would like included used.\n");
141 mothurOut("The group names are separated by dashes. The label parameter allows you to select what distance levels you would like distance matrices created for, and is also separated by dashes.\n");
142 mothurOut("The dist.shared command should be in the following format: dist.shared(groups=yourGroups, calc=yourCalcs, label=yourLabels).\n");
143 mothurOut("Example dist.shared(groups=A-B-C, calc=jabund-sorabund).\n");
144 mothurOut("The default value for groups is all the groups in your groupfile.\n");
145 mothurOut("The default value for calc is jclass and thetayc.\n");
146 validCalculator->printCalc("matrix", cout);
147 mothurOut("The dist.shared command outputs a .dist file for each calculator you specify at each distance you choose.\n");
148 mothurOut("Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n\n");
150 catch(exception& e) {
151 errorOut(e, "MatrixOutputCommand", "help");
157 //**********************************************************************************************************************
159 MatrixOutputCommand::~MatrixOutputCommand(){
160 if (abort == false) {
161 delete input; globaldata->ginput = NULL;
163 delete validCalculator;
167 //**********************************************************************************************************************
169 int MatrixOutputCommand::execute(){
172 if (abort == true) { return 0; }
174 //if the users entered no valid calculators don't execute command
175 if (matrixCalculators.size() == 0) { mothurOut("No valid calculators."); mothurOutEndLine(); return 0; }
178 read = new ReadOTUFile(globaldata->inputFileName);
179 read->read(&*globaldata);
181 input = globaldata->ginput;
182 lookup = input->getSharedRAbundVectors();
183 string lastLabel = lookup[0]->getLabel();
185 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
186 set<string> processedLabels;
187 set<string> userLabels = labels;
189 if (lookup.size() < 2) { mothurOut("You have not provided enough valid groups. I cannot run the command."); mothurOutEndLine(); return 0;}
191 numGroups = lookup.size();
193 //as long as you are not at the end of the file or done wih the lines you want
194 while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
196 if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){
197 mothurOut(lookup[0]->getLabel()); mothurOutEndLine();
200 processedLabels.insert(lookup[0]->getLabel());
201 userLabels.erase(lookup[0]->getLabel());
204 if ((anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
205 string saveLabel = lookup[0]->getLabel();
207 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
208 lookup = input->getSharedRAbundVectors(lastLabel);
210 mothurOut(lookup[0]->getLabel()); mothurOutEndLine();
213 processedLabels.insert(lookup[0]->getLabel());
214 userLabels.erase(lookup[0]->getLabel());
216 //restore real lastlabel to save below
217 lookup[0]->setLabel(saveLabel);
220 lastLabel = lookup[0]->getLabel();
222 //get next line to process
223 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
224 lookup = input->getSharedRAbundVectors();
227 //output error messages about any remaining user labels
228 set<string>::iterator it;
229 bool needToRun = false;
230 for (it = userLabels.begin(); it != userLabels.end(); it++) {
231 mothurOut("Your file does not include the label " + *it);
232 if (processedLabels.count(lastLabel) != 1) {
233 mothurOut(". I will use " + lastLabel + "."); mothurOutEndLine();
236 mothurOut(". Please refer to " + lastLabel + "."); mothurOutEndLine();
240 //run last label if you need to
241 if (needToRun == true) {
242 for (int i = 0; i < lookup.size(); i++) { if (lookup[i] != NULL) { delete lookup[i]; } }
243 lookup = input->getSharedRAbundVectors(lastLabel);
245 mothurOut(lookup[0]->getLabel()); mothurOutEndLine();
247 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
251 //reset groups parameter
252 globaldata->Groups.clear();
256 catch(exception& e) {
257 errorOut(e, "MatrixOutputCommand", "execute");
261 /***********************************************************/
262 void MatrixOutputCommand::printSims(ostream& out) {
265 //output column headers
266 out << simMatrix.size() << endl;
268 for (int m = 0; m < simMatrix.size(); m++) {
269 out << lookup[m]->getGroup() << '\t';
270 for (int n = 0; n < m; n++) {
271 out << simMatrix[m][n] << '\t';
277 catch(exception& e) {
278 errorOut(e, "MatrixOutputCommand", "printSims");
282 /***********************************************************/
283 void MatrixOutputCommand::process(vector<SharedRAbundVector*> thisLookup){
287 vector<SharedRAbundVector*> subset;
289 //for each calculator
290 for(int i = 0 ; i < matrixCalculators.size(); i++) {
292 //initialize simMatrix
294 simMatrix.resize(numGroups);
295 for (int m = 0; m < simMatrix.size(); m++) {
296 for (int j = 0; j < simMatrix.size(); j++) {
297 simMatrix[m].push_back(0.0);
301 for (int k = 0; k < thisLookup.size(); k++) {
302 for (int l = k; l < thisLookup.size(); l++) {
303 if (k != l) { //we dont need to similiarity of a groups to itself
304 //get estimated similarity between 2 groups
306 subset.clear(); //clear out old pair of sharedrabunds
307 //add new pair of sharedrabunds
308 subset.push_back(thisLookup[k]); subset.push_back(thisLookup[l]);
310 data = matrixCalculators[i]->getValues(subset); //saves the calculator outputs
311 //save values in similarity matrix
312 simMatrix[k][l] = 1.0 - data[0]; //convert similiarity to distance
313 simMatrix[l][k] = 1.0 - data[0]; //convert similiarity to distance
318 exportFileName = outputDir + getRootName(getSimpleName(globaldata->inputFileName)) + matrixCalculators[i]->getName() + "." + thisLookup[0]->getLabel() + ".dist";
319 openOutputFile(exportFileName, out);
328 catch(exception& e) {
329 errorOut(e, "MatrixOutputCommand", "process");
333 /***********************************************************/