]> git.donarmstrong.com Git - mothur.git/blob - venncommand.cpp
Merge remote-tracking branch 'mothur/master'
[mothur.git] / venncommand.cpp
1 /*
2  *  venncommand.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 3/30/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "venncommand.h"
11 #include "ace.h"
12 #include "sobs.h"
13 #include "chao1.h"
14 //#include "jackknife.h"
15 #include "sharedsobscollectsummary.h"
16 #include "sharedchao1.h"
17 #include "sharedace.h"
18 #include "nseqs.h"
19
20 //**********************************************************************************************************************
21 vector<string> VennCommand::setParameters(){    
22         try {
23                 CommandParameter plist("list", "InputTypes", "", "", "LRSS", "LRSS", "none","svg",false,false,true); parameters.push_back(plist);
24                 CommandParameter pshared("shared", "InputTypes", "", "", "LRSS", "LRSS", "none","svg",false,false,true); parameters.push_back(pshared); 
25                 CommandParameter pgroups("groups", "String", "", "", "", "", "","",false,false); parameters.push_back(pgroups);
26                 CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
27                 CommandParameter pcalc("calc", "String", "", "", "", "", "","",false,false); parameters.push_back(pcalc);
28                 CommandParameter pabund("abund", "Number", "", "10", "", "", "","",false,false); parameters.push_back(pabund);
29                 CommandParameter pnseqs("nseqs", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(pnseqs);
30         CommandParameter psharedotus("sharedotus", "Boolean", "", "t", "", "", "","",false,false); parameters.push_back(psharedotus);
31                 CommandParameter pfontsize("fontsize", "Number", "", "24", "", "", "","",false,false); parameters.push_back(pfontsize);
32                 CommandParameter ppermute("permute", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(ppermute);
33                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
34                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
35                 
36                 vector<string> myArray;
37                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
38                 return myArray;
39         }
40         catch(exception& e) {
41                 m->errorOut(e, "VennCommand", "setParameters");
42                 exit(1);
43         }
44 }
45 //**********************************************************************************************************************
46 string VennCommand::getHelpString(){    
47         try {
48                 string helpString = "";
49                 helpString += "The venn command parameters are list, shared, groups, calc, abund, nseqs, permute, fontsize and label.   shared, relabund, list, rabund or sabund is required unless you have a valid current file.\n";
50                 helpString += "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";
51                 helpString += "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";
52                 helpString += "The fontsize parameter allows you to adjust the font size of the picture created, default=24.\n";
53                 helpString += "The venn command should be in the following format: venn(groups=yourGroups, calc=yourCalcs, label=yourLabels, abund=yourAbund).\n";
54                 helpString += "Example venn(groups=A-B-C, calc=sharedsobs-sharedchao, abund=20).\n";
55                 helpString += "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";
56                 helpString += "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";
57                 helpString += "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 shared file.\n";
58                 helpString += "The nseqs parameter will output the number of sequences represented by the otus in the picture, default=F.\n";
59                 helpString += "If you have more than 4 groups, the permute parameter will find all possible combos of 4 of your groups and create pictures for them, default=F.\n";
60                 helpString += "The only estimators available four 4 groups are sharedsobs and sharedchao.\n";
61                 helpString += "The venn command outputs a .svg file for each calculator you specify at each distance you choose.\n";
62                 helpString += "Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n";
63                 return helpString;
64         }
65         catch(exception& e) {
66                 m->errorOut(e, "VennCommand", "getHelpString");
67                 exit(1);
68         }
69 }
70 //**********************************************************************************************************************
71 string VennCommand::getOutputPattern(string type) {
72     try {
73         string pattern = "";
74         
75         if (type == "svg") {  pattern = "[filename],svg"; } 
76         else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
77         
78         return pattern;
79     }
80     catch(exception& e) {
81         m->errorOut(e, "VennCommand", "getOutputPattern");
82         exit(1);
83     }
84 }
85
86 //**********************************************************************************************************************
87 VennCommand::VennCommand(){     
88         try {
89                 abort = true; calledHelp = true; 
90                 setParameters();
91                 vector<string> tempOutNames;
92                 outputTypes["svg"] = tempOutNames;
93         }
94         catch(exception& e) {
95                 m->errorOut(e, "VennCommand", "VennCommand");
96                 exit(1);
97         }
98 }
99 //**********************************************************************************************************************
100
101 VennCommand::VennCommand(string option)  {
102         try {
103                 abort = false; calledHelp = false;   
104                 allLines = 1;
105                         
106                 //allow user to run help
107                 if(option == "help") { help(); abort = true; calledHelp = true; }
108                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
109                 
110                 else {
111                         vector<string> myArray = setParameters();
112                         
113                         OptionParser parser(option);
114                         map<string,string> parameters = parser.getParameters();
115                         map<string,string>::iterator it;
116                         
117                         ValidParameters validParameter;
118                         
119                         //check to make sure all parameters are valid for command
120                         for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) { 
121                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
122                         }
123                         
124                         //if the user changes the input directory command factory will send this info to us in the output parameter 
125                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
126                         if (inputDir == "not found"){   inputDir = "";          }
127                         else {
128                                 string path;
129                                 it = parameters.find("shared");
130                                 //user has given a template file
131                                 if(it != parameters.end()){ 
132                                         path = m->hasPath(it->second);
133                                         //if the user has not given a path then, add inputdir. else leave path alone.
134                                         if (path == "") {       parameters["shared"] = inputDir + it->second;           }
135                                 }
136                                 
137                                 it = parameters.find("list");
138                                 //user has given a template file
139                                 if(it != parameters.end()){ 
140                                         path = m->hasPath(it->second);
141                                         //if the user has not given a path then, add inputdir. else leave path alone.
142                                         if (path == "") {       parameters["list"] = inputDir + it->second;             }
143                                 }
144                         }
145                         
146                         //check for required parameters
147                         listfile = validParameter.validFile(parameters, "list", true);
148                         if (listfile == "not open") { listfile = ""; abort = true; }
149                         else if (listfile == "not found") { listfile = ""; }
150                         else {  format = "list"; inputfile = listfile; m->setListFile(listfile); }
151                         
152                         sharedfile = validParameter.validFile(parameters, "shared", true);
153                         if (sharedfile == "not open") { sharedfile = ""; abort = true; }        
154                         else if (sharedfile == "not found") { sharedfile = ""; }
155                         else {  format = "sharedfile"; inputfile = sharedfile; m->setSharedFile(sharedfile); }
156                         
157                         if ((sharedfile == "") && (listfile == "")) { 
158                                 //is there are current file available for any of these?
159                                 //give priority to shared, then list, then rabund, then sabund
160                                 //if there is a current shared file, use it
161                                 sharedfile = m->getSharedFile(); 
162                                 if (sharedfile != "") { inputfile = sharedfile; format = "sharedfile"; m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
163                                 else { 
164                                         listfile = m->getListFile(); 
165                                         if (listfile != "") { inputfile = listfile; format = "list"; m->mothurOut("Using " + listfile + " as input file for the list parameter."); m->mothurOutEndLine(); }
166                                         else { 
167                                                 m->mothurOut("No valid current files. You must provide a list or shared file."); m->mothurOutEndLine(); 
168                                                 abort = true;
169                                         }
170                                 }
171                         }
172                         
173                         //if the user changes the output directory command factory will send this info to us in the output parameter 
174                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = m->hasPath(inputfile);              }
175
176                         //check for optional parameter and set defaults
177                         // ...at some point should added some additional type checking...
178                         label = validParameter.validFile(parameters, "label", false);                   
179                         if (label == "not found") { label = ""; }
180                         else { 
181                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
182                                 else { allLines = 1;  }
183                         }
184                         
185                         groups = validParameter.validFile(parameters, "groups", false);                 
186                         if (groups == "not found") { groups = ""; }
187                         else { 
188                                 m->splitAtDash(groups, Groups);
189                                 m->setGroups(Groups);
190                         }
191                         
192                         calc = validParameter.validFile(parameters, "calc", false);                     
193                         if (calc == "not found") { 
194                                 if(format == "list") { calc = "sobs"; }
195                                 else { calc = "sharedsobs"; }
196                         }
197                         else { 
198                                  if (calc == "default")  {  
199                                         if(format == "list") { calc = "sobs"; }
200                                         else { calc = "sharedsobs"; }
201                                 }
202                         }
203                         m->splitAtDash(calc, Estimators);
204                         if (m->inUsersGroups("citation", Estimators)) { 
205                                 ValidCalculators validCalc; validCalc.printCitations(Estimators); 
206                                 //remove citation from list of calcs
207                                 for (int i = 0; i < Estimators.size(); i++) { if (Estimators[i] == "citation") {  Estimators.erase(Estimators.begin()+i); break; } }
208                         }
209                         
210                         string temp;
211                         temp = validParameter.validFile(parameters, "abund", false);            if (temp == "not found") { temp = "10"; }
212                         m->mothurConvert(temp, abund); 
213                         
214                         temp = validParameter.validFile(parameters, "nseqs", false);            if (temp == "not found"){       temp = "f";                             }
215                         nseqs = m->isTrue(temp); 
216
217                         temp = validParameter.validFile(parameters, "permute", false);          if (temp == "not found"){       temp = "f";                             }
218                         perm = m->isTrue(temp); 
219             
220             temp = validParameter.validFile(parameters, "sharedotus", false);           if (temp == "not found"){       temp = "t";                             }
221                         sharedOtus = m->isTrue(temp); 
222                         
223                         temp = validParameter.validFile(parameters, "fontsize", false);         if (temp == "not found") { temp = "24"; }
224                         m->mothurConvert(temp, fontsize);
225
226                 }
227                                 
228         }
229         catch(exception& e) {
230                 m->errorOut(e, "VennCommand", "VennCommand");
231                 exit(1);
232         }
233 }
234 //**********************************************************************************************************************
235
236 int VennCommand::execute(){
237         try {
238         
239                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
240         
241                 ValidCalculators validCalculator;
242                                         
243                 if (format == "list") {
244                         for (int i=0; i<Estimators.size(); i++) {
245                                 if (validCalculator.isValidCalculator("vennsingle", Estimators[i]) == true) { 
246                                         if (Estimators[i] == "sobs") { 
247                                                 vennCalculators.push_back(new Sobs());
248                                         }else if (Estimators[i] == "chao") { 
249                                                 vennCalculators.push_back(new Chao1());
250                                         }else if (Estimators[i] == "ace") {
251                                                 if(abund < 5) { abund = 10; }
252                                                 vennCalculators.push_back(new Ace(abund));
253                                         }
254                                 }
255                         }
256                 }else {
257                         for (int i=0; i<Estimators.size(); i++) {
258                                 if (validCalculator.isValidCalculator("vennshared", Estimators[i]) == true) { 
259                                         if (Estimators[i] == "sharedsobs") { 
260                                                 vennCalculators.push_back(new SharedSobsCS());
261                                         }else if (Estimators[i] == "sharedchao") { 
262                                                 vennCalculators.push_back(new SharedChao1());
263                                         }else if (Estimators[i] == "sharedace") { 
264                                                 vennCalculators.push_back(new SharedAce());
265                                         }
266                                 }
267                         }
268                 }
269                         
270                 //if the users entered no valid calculators don't execute command
271                 if (vennCalculators.size() == 0) { m->mothurOut("No valid calculators given, please correct."); m->mothurOutEndLine(); return 0;  }
272                 
273                 venn = new Venn(outputDir, nseqs, inputfile, fontsize, sharedOtus); 
274                 input = new InputData(inputfile, format);
275                 
276                 string lastLabel;
277                 
278                 if (format == "sharedfile") {
279                         lookup = input->getSharedRAbundVectors();
280                         lastLabel = lookup[0]->getLabel();
281                         
282                         if ((lookup.size() > 4) && (perm)) { combosOfFour = findCombinations(lookup.size()); }
283                 }else if (format == "list") {
284                         sabund = input->getSAbundVector();
285                         lastLabel = sabund->getLabel();
286                 }
287                 
288                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
289                 set<string> processedLabels;
290                 set<string> userLabels = labels;
291
292                 if (format != "list") { 
293                         
294                         //as long as you are not at the end of the file or done wih the lines you want
295                         while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
296                         
297                                 if (m->control_pressed) {
298                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
299                                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
300                                         m->clearGroups(); delete venn; delete input;
301                                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
302                                         return 0;
303                                 }
304
305                                 if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
306                                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
307                                         processedLabels.insert(lookup[0]->getLabel());
308                                         userLabels.erase(lookup[0]->getLabel());
309                                         
310                                         if ((lookup.size() > 4) && (!perm)){
311                                                 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. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
312                                                 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
313                                         
314                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
315                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  } }
316
317                                         }else if ((lookup.size() > 4) && (perm)) {
318                                                 set< set<int> >::iterator it3;
319                                                 set<int>::iterator it2;
320                                                 for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
321                         
322                                                         set<int> poss = *it3;
323                                                         vector<SharedRAbundVector*> subset;
324                                                         for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
325                                                         
326                                                         vector<string> outfilenames = venn->getPic(subset, vennCalculators);
327                                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]); }  }
328                                                 }               
329                                         }else {
330                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
331                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
332                                         }                                       
333                                 }
334                                 
335                                 if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
336                                         string saveLabel = lookup[0]->getLabel();
337                                         
338                                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
339                                         lookup = input->getSharedRAbundVectors(lastLabel);
340
341                                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
342                                         processedLabels.insert(lookup[0]->getLabel());
343                                         userLabels.erase(lookup[0]->getLabel());
344
345                                         if ((lookup.size() > 4) && (!perm)){
346                                                 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. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
347                                                 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
348                                         
349                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
350                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
351
352                                         }else if ((lookup.size() > 4) && (perm)) {
353                                                 set< set<int> >::iterator it3;
354                                                 set<int>::iterator it2;
355                                                 for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
356                         
357                                                         set<int> poss = *it3;
358                                                         vector<SharedRAbundVector*> subset;
359                                                         for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
360                                                         
361                                                         vector<string> outfilenames = venn->getPic(subset, vennCalculators);
362                                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
363                                                 }               
364                                         }else {
365                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
366                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
367                                         }
368                                                                                 
369                                         //restore real lastlabel to save below
370                                         lookup[0]->setLabel(saveLabel);
371                                 }
372                                 
373                                 
374                                 lastLabel = lookup[0]->getLabel();      
375                                                 
376                                 //get next line to process
377                                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
378                                 lookup = input->getSharedRAbundVectors();
379                         }
380                         
381                         if (m->control_pressed) {
382                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
383                                         m->clearGroups(); delete venn; delete input; 
384                                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
385                                         return 0;
386                         }
387
388                         
389                         //output error messages about any remaining user labels
390                         set<string>::iterator it;
391                         bool needToRun = false;
392                         for (it = userLabels.begin(); it != userLabels.end(); it++) {  
393                                 m->mothurOut("Your file does not include the label " + *it); 
394                                 if (processedLabels.count(lastLabel) != 1) {
395                                         m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
396                                         needToRun = true;
397                                 }else {
398                                         m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
399                                 }
400                         }
401                 
402                         //run last label if you need to
403                         if (needToRun == true)  {
404                                         for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) {     delete lookup[i]; }  } 
405                                         lookup = input->getSharedRAbundVectors(lastLabel);
406
407                                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
408                                         processedLabels.insert(lookup[0]->getLabel());
409                                         userLabels.erase(lookup[0]->getLabel());
410
411                                         if ((lookup.size() > 4) && (!perm)){
412                                                 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. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
413                                                 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
414                                         
415                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
416                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]); }  }
417
418                                         }else if ((lookup.size() > 4) && (perm)) {
419                                                 set< set<int> >::iterator it3;
420                                                 set<int>::iterator it2;
421                                                 for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
422                         
423                                                         set<int> poss = *it3;
424                                                         vector<SharedRAbundVector*> subset;
425                                                         for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
426                                                         
427                                                         vector<string> outfilenames = venn->getPic(subset, vennCalculators);
428                                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]); }  }
429                                                 }               
430                                         }else {
431                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
432                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
433                                         }
434                                         
435                                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
436                         }
437                 
438
439                         //reset groups parameter
440                         m->clearGroups();  
441                         
442                         if (m->control_pressed) {
443                                         m->clearGroups(); delete venn; delete input;
444                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
445                                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
446                                         return 0;
447                         }
448
449                         
450                 }else{
451                 
452                         while((sabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
453                         
454                                 if (m->control_pressed) {
455                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
456                                         delete sabund; delete venn; delete input;
457                                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
458                                         return 0;
459                                 }
460                 
461                                 if(allLines == 1 || labels.count(sabund->getLabel()) == 1){                     
462         
463                                         m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
464                                         vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
465                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
466
467                                         
468                                         processedLabels.insert(sabund->getLabel());
469                                         userLabels.erase(sabund->getLabel());
470                                 }
471                                 
472                                 if ((m->anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
473                                         string saveLabel = sabund->getLabel();
474                                 
475                                         delete sabund;
476                                         sabund = input->getSAbundVector(lastLabel);
477                                         
478                                         m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
479                                         vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
480                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
481
482                                         
483                                         processedLabels.insert(sabund->getLabel());
484                                         userLabels.erase(sabund->getLabel());
485                                         
486                                         //restore real lastlabel to save below
487                                         sabund->setLabel(saveLabel);
488                                 }               
489                                 
490                                 lastLabel = sabund->getLabel();         
491                                 
492                                 delete sabund;
493                                 sabund = input->getSAbundVector();
494                         }
495                         
496                         if (m->control_pressed) {
497                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
498                                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
499                                         delete venn; delete input;
500                                         return 0;
501                         }
502                         
503                         //output error messages about any remaining user labels
504                         set<string>::iterator it;
505                         bool needToRun = false;
506                         for (it = userLabels.begin(); it != userLabels.end(); it++) {  
507                                 m->mothurOut("Your file does not include the label " + *it); 
508                                 if (processedLabels.count(lastLabel) != 1) {
509                                         m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
510                                         needToRun = true;
511                                 }else {
512                                         m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
513                                 }
514                         }
515                 
516                         //run last label if you need to
517                         if (needToRun == true)  {
518                                 if (sabund != NULL) {   delete sabund;  }
519                                 sabund = input->getSAbundVector(lastLabel);
520                                         
521                                 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
522                                 vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
523                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
524
525                                 delete sabund;
526                                         
527                         }
528                         
529                         if (m->control_pressed) {
530                                         delete venn; delete input;
531                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
532                                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
533                                         return 0;
534                         }
535                 }
536                 
537                 for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
538                 delete venn; delete input;
539                 
540                 m->mothurOutEndLine();
541                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
542                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
543                 m->mothurOutEndLine();
544
545                 
546                 return 0;
547         }
548         catch(exception& e) {
549                 m->errorOut(e, "VennCommand", "execute");
550                 exit(1);
551         }
552 }
553 //**********************************************************************************************************************
554 //returns a vector of sets containing the 4 group combinations
555 set< set<int> > VennCommand::findCombinations(int lookupSize){
556         try {
557                 set< set<int> > combos;
558                 
559                 set<int> possibles;
560                 for (int i = 0; i < lookupSize; i++) {  possibles.insert(i);  }
561                 
562                 getCombos(possibles, combos);
563                 
564                 return combos;
565                 
566         }
567         catch(exception& e) {
568                 m->errorOut(e, "VennCommand", "findCombinations");
569                 exit(1);
570         }
571 }
572 //**********************************************************************************************************************
573 //recusively finds combos of 4
574 int VennCommand::getCombos(set<int> possibles, set< set<int> >& combos){
575         try {
576                 
577                 if (possibles.size() == 4) { //done
578                         if (combos.count(possibles) == 0) { //no dups
579                                 combos.insert(possibles);
580                         }
581                 }else { //we still have work to do
582                         set<int>::iterator it;
583                         set<int>::iterator it2;
584                         for (it = possibles.begin(); it != possibles.end(); it++) {  
585                                 
586                                 set<int> newPossibles;
587                                 for (it2 = possibles.begin(); it2 != possibles.end(); it2++) {  //all possible combos of one length smaller
588                                         if (*it != *it2) { 
589                                                 newPossibles.insert(*it2);
590                                         }
591                                 }
592                                 getCombos(newPossibles, combos);
593                         }
594                 }
595                 
596                 return 0;
597         }
598         catch(exception& e) {
599                 m->errorOut(e, "VennCommand", "getCombos");
600                 exit(1);
601         }
602 }
603
604 //**********************************************************************************************************************