5 * Created by Sarah Westcott on 3/30/09.
6 * Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
10 #include "venncommand.h"
14 //#include "jackknife.h"
15 #include "sharedsobscollectsummary.h"
16 #include "sharedchao1.h"
17 #include "sharedace.h"
21 //**********************************************************************************************************************
23 VennCommand::VennCommand(string option) {
25 globaldata = GlobalData::getInstance();
30 //allow user to run help
31 if(option == "help") { help(); abort = true; }
34 //valid paramters for this command
35 string AlignArray[] = {"groups","label","calc", "abund","outputdir","inputdir"};
36 vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
38 OptionParser parser(option);
39 map<string,string> parameters = parser.getParameters();
41 ValidParameters validParameter;
43 //check to make sure all parameters are valid for command
44 for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) {
45 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
48 //make sure the user has already run the read.otu command
49 if ((globaldata->getListFile() == "") && (globaldata->getSharedFile() == "")) {
50 m->mothurOut("You must read a list, or a list and a group, or a shared before you can use the venn command."); m->mothurOutEndLine(); abort = true;
53 //if the user changes the output directory command factory will send this info to us in the output parameter
54 outputDir = validParameter.validFile(parameters, "outputdir", false); if (outputDir == "not found"){
56 outputDir += m->hasPath(globaldata->inputFileName); //if user entered a file with a path then preserve it
59 //check for optional parameter and set defaults
60 // ...at some point should added some additional type checking...
61 label = validParameter.validFile(parameters, "label", false);
62 if (label == "not found") { label = ""; }
64 if(label != "all") { m->splitAtDash(label, labels); allLines = 0; }
65 else { allLines = 1; }
68 //if the user has not specified any labels use the ones from read.otu
70 allLines = globaldata->allLines;
71 labels = globaldata->labels;
74 groups = validParameter.validFile(parameters, "groups", false);
75 if (groups == "not found") { groups = ""; }
77 m->splitAtDash(groups, Groups);
78 globaldata->Groups = Groups;
81 format = globaldata->getFormat();
82 calc = validParameter.validFile(parameters, "calc", false);
83 if (calc == "not found") {
84 if(format == "list") { calc = "sobs"; }
85 else { calc = "sharedsobs"; }
88 if (calc == "default") {
89 if(format == "list") { calc = "sobs"; }
90 else { calc = "sharedsobs"; }
93 m->splitAtDash(calc, Estimators);
96 temp = validParameter.validFile(parameters, "abund", false); if (temp == "not found") { temp = "10"; }
100 validCalculator = new ValidCalculators();
104 if (format == "list") {
105 for (i=0; i<Estimators.size(); i++) {
106 if (validCalculator->isValidCalculator("vennsingle", Estimators[i]) == true) {
107 if (Estimators[i] == "sobs") {
108 vennCalculators.push_back(new Sobs());
109 }else if (Estimators[i] == "chao") {
110 vennCalculators.push_back(new Chao1());
111 }else if (Estimators[i] == "ace") {
114 vennCalculators.push_back(new Ace(abund));
115 }else if (Estimators[i] == "nseqs") {
116 vennCalculators.push_back(new NSeqs());
121 for (i=0; i<Estimators.size(); i++) {
122 if (validCalculator->isValidCalculator("vennshared", Estimators[i]) == true) {
123 if (Estimators[i] == "sharedsobs") {
124 vennCalculators.push_back(new SharedSobsCS());
125 }else if (Estimators[i] == "sharedchao") {
126 vennCalculators.push_back(new SharedChao1());
127 }else if (Estimators[i] == "sharedace") {
128 vennCalculators.push_back(new SharedAce());
129 }else if (Estimators[i] == "nseqs") {
130 vennCalculators.push_back(new NSeqs());
136 //if the users entered no valid calculators don't execute command
137 if (vennCalculators.size() == 0) { m->mothurOut("No valid calculators given, please correct."); m->mothurOutEndLine(); abort = true; }
138 else { venn = new Venn(outputDir); }
146 catch(exception& e) {
147 m->errorOut(e, "VennCommand", "VennCommand");
152 //**********************************************************************************************************************
154 void VennCommand::help(){
156 m->mothurOut("The venn command can only be executed after a successful read.otu command.\n");
157 m->mothurOut("The venn command parameters are groups, calc, abund and label. No parameters are required.\n");
158 m->mothurOut("The groups parameter allows you to specify which of the groups in your groupfile you would like included in your venn diagram, you may only use a maximum of 4 groups.\n");
159 m->mothurOut("The group names are separated by dashes. The label allows you to select what distance levels you would like a venn diagram created for, and are also separated by dashes.\n");
160 m->mothurOut("The venn command should be in the following format: venn(groups=yourGroups, calc=yourCalcs, label=yourLabels, abund=yourAbund).\n");
161 m->mothurOut("Example venn(groups=A-B-C, calc=sharedsobs-sharedchao, abund=20).\n");
162 m->mothurOut("The default value for groups is all the groups in your groupfile up to 4, and all labels in your inputfile will be used.\n");
163 m->mothurOut("The default value for calc is sobs if you have only read a list file or if you have selected only one group, and sharedsobs if you have multiple groups.\n");
164 m->mothurOut("The default available estimators for calc are sobs, chao and ace if you have only read a list file, and sharedsobs, sharedchao and sharedace if you have read a list and group file or a shared file.\n");
165 m->mothurOut("The only estmiator available four 4 groups is sharedsobs.\n");
166 m->mothurOut("The venn command outputs a .svg file for each calculator you specify at each distance you choose.\n");
167 m->mothurOut("Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n\n");
169 catch(exception& e) {
170 m->errorOut(e, "VennCommand", "help");
176 //**********************************************************************************************************************
178 VennCommand::~VennCommand(){
179 if (abort == false) {
180 delete input; globaldata->ginput = NULL;
183 globaldata->sabund = NULL;
184 delete validCalculator;
189 //**********************************************************************************************************************
191 int VennCommand::execute(){
194 if (abort == true) { return 0; }
197 vector<string> outputNames;
199 if (format == "sharedfile") {
201 read = new ReadOTUFile(globaldata->inputFileName);
202 read->read(&*globaldata);
204 input = globaldata->ginput;
205 lookup = input->getSharedRAbundVectors();
206 lastLabel = lookup[0]->getLabel();
207 }else if (format == "list") {
208 //you are using just a list file and have only one group
209 read = new ReadOTUFile(globaldata->inputFileName);
210 read->read(&*globaldata);
212 sabund = globaldata->sabund;
213 lastLabel = sabund->getLabel();
214 input = globaldata->ginput;
217 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
218 set<string> processedLabels;
219 set<string> userLabels = labels;
221 if (format != "list") {
223 //as long as you are not at the end of the file or done wih the lines you want
224 while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
226 if (m->control_pressed) {
227 for (int i = 0; i < vennCalculators.size(); i++) { delete vennCalculators[i]; }
228 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
229 globaldata->Groups.clear();
230 for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); }
234 if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){
235 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
236 processedLabels.insert(lookup[0]->getLabel());
237 userLabels.erase(lookup[0]->getLabel());
239 if (lookup.size() > 4) {
240 m->mothurOut("Error: Too many groups chosen. You may use up to 4 groups with the venn command. I will use the first four groups in your groupfile."); m->mothurOutEndLine();
241 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
244 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
245 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); } }
248 if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
249 string saveLabel = lookup[0]->getLabel();
251 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
252 lookup = input->getSharedRAbundVectors(lastLabel);
254 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
255 processedLabels.insert(lookup[0]->getLabel());
256 userLabels.erase(lookup[0]->getLabel());
258 if (lookup.size() > 4) {
259 m->mothurOut("Error: Too many groups chosen. You may use up to 4 groups with the venn command. I will use the first four groups in your groupfile."); m->mothurOutEndLine();
260 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
262 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
263 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); } }
265 //restore real lastlabel to save below
266 lookup[0]->setLabel(saveLabel);
270 lastLabel = lookup[0]->getLabel();
272 //get next line to process
273 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
274 lookup = input->getSharedRAbundVectors();
277 if (m->control_pressed) {
278 for (int i = 0; i < vennCalculators.size(); i++) { delete vennCalculators[i]; }
279 globaldata->Groups.clear();
280 for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); }
285 //output error messages about any remaining user labels
286 set<string>::iterator it;
287 bool needToRun = false;
288 for (it = userLabels.begin(); it != userLabels.end(); it++) {
289 m->mothurOut("Your file does not include the label " + *it);
290 if (processedLabels.count(lastLabel) != 1) {
291 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
294 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
298 //run last label if you need to
299 if (needToRun == true) {
300 for (int i = 0; i < lookup.size(); i++) { if (lookup[i] != NULL) { delete lookup[i]; } }
301 lookup = input->getSharedRAbundVectors(lastLabel);
303 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
304 processedLabels.insert(lookup[0]->getLabel());
305 userLabels.erase(lookup[0]->getLabel());
307 if (lookup.size() > 4) {
308 m->mothurOut("Error: Too many groups chosen. You may use up to 4 groups with the venn command. I will use the first four groups in your groupfile."); m->mothurOutEndLine();
309 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
311 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
312 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); } }
314 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
318 //reset groups parameter
319 globaldata->Groups.clear();
321 if (m->control_pressed) {
322 for (int i = 0; i < vennCalculators.size(); i++) { delete vennCalculators[i]; }
323 for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); }
330 while((sabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
332 if (m->control_pressed) {
333 for (int i = 0; i < vennCalculators.size(); i++) { delete vennCalculators[i]; }
335 for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); }
339 if(allLines == 1 || labels.count(sabund->getLabel()) == 1){
341 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
342 vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
343 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); } }
346 processedLabels.insert(sabund->getLabel());
347 userLabels.erase(sabund->getLabel());
350 if ((m->anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
351 string saveLabel = sabund->getLabel();
354 sabund = input->getSAbundVector(lastLabel);
356 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
357 vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
358 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); } }
361 processedLabels.insert(sabund->getLabel());
362 userLabels.erase(sabund->getLabel());
364 //restore real lastlabel to save below
365 sabund->setLabel(saveLabel);
368 lastLabel = sabund->getLabel();
371 sabund = input->getSAbundVector();
374 if (m->control_pressed) {
375 for (int i = 0; i < vennCalculators.size(); i++) { delete vennCalculators[i]; }
376 for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); }
380 //output error messages about any remaining user labels
381 set<string>::iterator it;
382 bool needToRun = false;
383 for (it = userLabels.begin(); it != userLabels.end(); it++) {
384 m->mothurOut("Your file does not include the label " + *it);
385 if (processedLabels.count(lastLabel) != 1) {
386 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
389 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
393 //run last label if you need to
394 if (needToRun == true) {
395 if (sabund != NULL) { delete sabund; }
396 sabund = input->getSAbundVector(lastLabel);
398 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
399 vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
400 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); } }
406 if (m->control_pressed) {
407 for (int i = 0; i < vennCalculators.size(); i++) { delete vennCalculators[i]; }
408 for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); }
413 for (int i = 0; i < vennCalculators.size(); i++) { delete vennCalculators[i]; }
415 m->mothurOutEndLine();
416 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
417 for (int i = 0; i < outputNames.size(); i++) { m->mothurOut(outputNames[i]); m->mothurOutEndLine(); }
418 m->mothurOutEndLine();
423 catch(exception& e) {
424 m->errorOut(e, "VennCommand", "execute");
429 //**********************************************************************************************************************