]> git.donarmstrong.com Git - mothur.git/blobdiff - venncommand.cpp
sffinfo bug with flow grams right index when clipQualRight=0
[mothur.git] / venncommand.cpp
index 57228ad4c789124126d71781357f4328bfd143a5..98796b3466fcc344b5e4c990015316a5ae2a0582 100644 (file)
 #include "sharedsobscollectsummary.h"
 #include "sharedchao1.h"
 #include "sharedace.h"
+#include "nseqs.h"
 
+//**********************************************************************************************************************
+vector<string> VennCommand::setParameters(){   
+       try {
+               CommandParameter plist("list", "InputTypes", "", "", "LRSS", "LRSS", "none","svg",false,false,true); parameters.push_back(plist);
+               CommandParameter pshared("shared", "InputTypes", "", "", "LRSS", "LRSS", "none","svg",false,false,true); parameters.push_back(pshared); 
+               CommandParameter pgroups("groups", "String", "", "", "", "", "","",false,false); parameters.push_back(pgroups);
+               CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
+               CommandParameter pcalc("calc", "String", "", "", "", "", "","",false,false); parameters.push_back(pcalc);
+               CommandParameter pabund("abund", "Number", "", "10", "", "", "","",false,false); parameters.push_back(pabund);
+               CommandParameter pnseqs("nseqs", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(pnseqs);
+        CommandParameter psharedotus("sharedotus", "Boolean", "", "t", "", "", "","",false,false); parameters.push_back(psharedotus);
+               CommandParameter pfontsize("fontsize", "Number", "", "24", "", "", "","",false,false); parameters.push_back(pfontsize);
+               CommandParameter ppermute("permute", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(ppermute);
+               CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
+               CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
+               
+               vector<string> myArray;
+               for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
+               return myArray;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "VennCommand", "setParameters");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+string VennCommand::getHelpString(){   
+       try {
+               string helpString = "";
+               helpString += "The venn command parameters are list, shared, groups, calc, abund, nseqs, permute, sharedotus, fontsize and label.   shared, relabund, list, rabund or sabund is required unless you have a valid current file.\n";
+               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";
+               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";
+               helpString += "The fontsize parameter allows you to adjust the font size of the picture created, default=24.\n";
+               helpString += "The venn command should be in the following format: venn(groups=yourGroups, calc=yourCalcs, label=yourLabels, abund=yourAbund).\n";
+               helpString += "Example venn(groups=A-B-C, calc=sharedsobs-sharedchao, abund=20).\n";
+               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";
+               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";
+               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";
+               helpString += "The nseqs parameter will output the number of sequences represented by the otus in the picture, default=F.\n";
+               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";
+               helpString += "The only estimators available four 4 groups are sharedsobs and sharedchao.\n";
+        helpString += "The sharedotus parameter can be used with the sharedsobs calculator to get the names of the OTUs in each section of the venn diagram. Default=t.\n";
+               helpString += "The venn command outputs a .svg file for each calculator you specify at each distance you choose.\n";
+               helpString += "Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n";
+               return helpString;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "VennCommand", "getHelpString");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+string VennCommand::getOutputPattern(string type) {
+    try {
+        string pattern = "";
+        
+        if (type == "svg") {  pattern = "[filename],svg"; } 
+        else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
+        
+        return pattern;
+    }
+    catch(exception& e) {
+        m->errorOut(e, "VennCommand", "getOutputPattern");
+        exit(1);
+    }
+}
 
+//**********************************************************************************************************************
+VennCommand::VennCommand(){    
+       try {
+               abort = true; calledHelp = true; 
+               setParameters();
+               vector<string> tempOutNames;
+               outputTypes["svg"] = tempOutNames;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "VennCommand", "VennCommand");
+               exit(1);
+       }
+}
 //**********************************************************************************************************************
 
 VennCommand::VennCommand(string option)  {
        try {
-               globaldata = GlobalData::getInstance();
-               abort = false;
+               abort = false; calledHelp = false;   
                allLines = 1;
-               labels.clear();
                        
                //allow user to run help
-               if(option == "help") { help(); abort = true; }
+               if(option == "help") { help(); abort = true; calledHelp = true; }
+               else if(option == "citation") { citation(); abort = true; calledHelp = true;}
                
                else {
-                       //valid paramters for this command
-                       string AlignArray[] =  {"groups","label","calc", "abund","outputdir","inputdir"};
-                       vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
+                       vector<string> myArray = setParameters();
                        
                        OptionParser parser(option);
                        map<string,string> parameters = parser.getParameters();
+                       map<string,string>::iterator it;
                        
                        ValidParameters validParameter;
                        
@@ -44,40 +122,74 @@ VennCommand::VennCommand(string option)  {
                                if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
                        }
                        
-                       //make sure the user has already run the read.otu command
-                       if ((globaldata->getListFile() == "") && (globaldata->getSharedFile() == "")) {
-                               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; 
+                       //if the user changes the input directory command factory will send this info to us in the output parameter 
+                       string inputDir = validParameter.validFile(parameters, "inputdir", false);              
+                       if (inputDir == "not found"){   inputDir = "";          }
+                       else {
+                               string path;
+                               it = parameters.find("shared");
+                               //user has given a template file
+                               if(it != parameters.end()){ 
+                                       path = m->hasPath(it->second);
+                                       //if the user has not given a path then, add inputdir. else leave path alone.
+                                       if (path == "") {       parameters["shared"] = inputDir + it->second;           }
+                               }
+                               
+                               it = parameters.find("list");
+                               //user has given a template file
+                               if(it != parameters.end()){ 
+                                       path = m->hasPath(it->second);
+                                       //if the user has not given a path then, add inputdir. else leave path alone.
+                                       if (path == "") {       parameters["list"] = inputDir + it->second;             }
+                               }
                        }
                        
-                       //if the user changes the output directory command factory will send this info to us in the output parameter 
-                       outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  
-                               outputDir = ""; 
-                               outputDir += hasPath(globaldata->inputFileName); //if user entered a file with a path then preserve it  
+                       //check for required parameters
+                       listfile = validParameter.validFile(parameters, "list", true);
+                       if (listfile == "not open") { listfile = ""; abort = true; }
+                       else if (listfile == "not found") { listfile = ""; }
+                       else {  format = "list"; inputfile = listfile; m->setListFile(listfile); }
+                       
+                       sharedfile = validParameter.validFile(parameters, "shared", true);
+                       if (sharedfile == "not open") { sharedfile = ""; abort = true; }        
+                       else if (sharedfile == "not found") { sharedfile = ""; }
+                       else {  format = "sharedfile"; inputfile = sharedfile; m->setSharedFile(sharedfile); }
+                       
+                       if ((sharedfile == "") && (listfile == "")) { 
+                               //is there are current file available for any of these?
+                               //give priority to shared, then list, then rabund, then sabund
+                               //if there is a current shared file, use it
+                               sharedfile = m->getSharedFile(); 
+                               if (sharedfile != "") { inputfile = sharedfile; format = "sharedfile"; m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
+                               else { 
+                                       listfile = m->getListFile(); 
+                                       if (listfile != "") { inputfile = listfile; format = "list"; m->mothurOut("Using " + listfile + " as input file for the list parameter."); m->mothurOutEndLine(); }
+                                       else { 
+                                               m->mothurOut("No valid current files. You must provide a list or shared file."); m->mothurOutEndLine(); 
+                                               abort = true;
+                                       }
+                               }
                        }
+                       
+                       //if the user changes the output directory command factory will send this info to us in the output parameter 
+                       outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = m->hasPath(inputfile);              }
 
                        //check for optional parameter and set defaults
                        // ...at some point should added some additional type checking...
                        label = validParameter.validFile(parameters, "label", false);                   
                        if (label == "not found") { label = ""; }
                        else { 
-                               if(label != "all") {  splitAtDash(label, labels);  allLines = 0;  }
+                               if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
                                else { allLines = 1;  }
                        }
                        
-                       //if the user has not specified any labels use the ones from read.otu
-                       if (label == "") {  
-                               allLines = globaldata->allLines; 
-                               labels = globaldata->labels; 
-                       }
-                       
                        groups = validParameter.validFile(parameters, "groups", false);                 
                        if (groups == "not found") { groups = ""; }
                        else { 
-                               splitAtDash(groups, Groups);
-                               globaldata->Groups = Groups;
+                               m->splitAtDash(groups, Groups);
+                               m->setGroups(Groups);
                        }
                        
-                       format = globaldata->getFormat();
                        calc = validParameter.validFile(parameters, "calc", false);                     
                        if (calc == "not found") { 
                                if(format == "list") { calc = "sobs"; }
@@ -89,50 +201,30 @@ VennCommand::VennCommand(string option)  {
                                        else { calc = "sharedsobs"; }
                                }
                        }
-                       splitAtDash(calc, Estimators);
+                       m->splitAtDash(calc, Estimators);
+                       if (m->inUsersGroups("citation", Estimators)) { 
+                               ValidCalculators validCalc; validCalc.printCitations(Estimators); 
+                               //remove citation from list of calcs
+                               for (int i = 0; i < Estimators.size(); i++) { if (Estimators[i] == "citation") {  Estimators.erase(Estimators.begin()+i); break; } }
+                       }
                        
                        string temp;
                        temp = validParameter.validFile(parameters, "abund", false);            if (temp == "not found") { temp = "10"; }
-                       convert(temp, abund); 
+                       m->mothurConvert(temp, abund); 
+                       
+                       temp = validParameter.validFile(parameters, "nseqs", false);            if (temp == "not found"){       temp = "f";                             }
+                       nseqs = m->isTrue(temp); 
 
-                       if (abort == false) {
-                               validCalculator = new ValidCalculators();
-               
-                               int i;
-                               
-                               if (format == "list") {
-                                       for (i=0; i<Estimators.size(); i++) {
-                                               if (validCalculator->isValidCalculator("vennsingle", Estimators[i]) == true) { 
-                                                       if (Estimators[i] == "sobs") { 
-                                                               vennCalculators.push_back(new Sobs());
-                                                       }else if (Estimators[i] == "chao") { 
-                                                               vennCalculators.push_back(new Chao1());
-                                                       }else if (Estimators[i] == "ace") {
-                                                               if(abund < 5)
-                                                                       abund = 10;
-                                                               vennCalculators.push_back(new Ace(abund));
-                                                       }
-                                               }
-                                       }
-                               }else {
-                                       for (i=0; i<Estimators.size(); i++) {
-                                               if (validCalculator->isValidCalculator("vennshared", Estimators[i]) == true) { 
-                                                       if (Estimators[i] == "sharedsobs") { 
-                                                               vennCalculators.push_back(new SharedSobsCS());
-                                                       }else if (Estimators[i] == "sharedchao") { 
-                                                               vennCalculators.push_back(new SharedChao1());
-                                                       }else if (Estimators[i] == "sharedace") { 
-                                                               vennCalculators.push_back(new SharedAce());
-                                                       }
-                                               }
-                                       }
-                               }
-                               
-                               venn = new Venn(outputDir);
-                       }
-               }
+                       temp = validParameter.validFile(parameters, "permute", false);          if (temp == "not found"){       temp = "f";                             }
+                       perm = m->isTrue(temp); 
+            
+            temp = validParameter.validFile(parameters, "sharedotus", false);          if (temp == "not found"){       temp = "t";                             }
+                       sharedOtus = m->isTrue(temp); 
+                       
+                       temp = validParameter.validFile(parameters, "fontsize", false);         if (temp == "not found") { temp = "24"; }
+                       m->mothurConvert(temp, fontsize);
 
-               
+               }
                                
        }
        catch(exception& e) {
@@ -140,98 +232,108 @@ VennCommand::VennCommand(string option)  {
                exit(1);
        }
 }
-
-//**********************************************************************************************************************
-
-void VennCommand::help(){
-       try {
-               m->mothurOut("The venn command can only be executed after a successful read.otu command.\n");
-               m->mothurOut("The venn command parameters are groups, calc, abund and label.  No parameters are required.\n");
-               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");
-               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");
-               m->mothurOut("The venn command should be in the following format: venn(groups=yourGroups, calc=yourCalcs, label=yourLabels, abund=yourAbund).\n");
-               m->mothurOut("Example venn(groups=A-B-C, calc=sharedsobs-sharedchao, abund=20).\n");
-               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");
-               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");
-               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");
-               m->mothurOut("The only estmiator available four 4 groups is sharedsobs.\n");
-               m->mothurOut("The venn command outputs a .svg file for each calculator you specify at each distance you choose.\n");
-               m->mothurOut("Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n\n");
-       }
-       catch(exception& e) {
-               m->errorOut(e, "VennCommand", "help");
-               exit(1);
-       }
-}
-
-
-//**********************************************************************************************************************
-
-VennCommand::~VennCommand(){
-       if (abort == false) {
-               delete input; globaldata->ginput = NULL;
-               delete read;
-               delete venn;
-               globaldata->sabund = NULL;
-       }
-       
-}
-
 //**********************************************************************************************************************
 
 int VennCommand::execute(){
        try {
        
-               if (abort == true) { return 0; }
+               if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
+       
+               ValidCalculators validCalculator;
+                                       
+               if (format == "list") {
+                       for (int i=0; i<Estimators.size(); i++) {
+                               if (validCalculator.isValidCalculator("vennsingle", Estimators[i]) == true) { 
+                                       if (Estimators[i] == "sobs") { 
+                                               vennCalculators.push_back(new Sobs());
+                                       }else if (Estimators[i] == "chao") { 
+                                               vennCalculators.push_back(new Chao1());
+                                       }else if (Estimators[i] == "ace") {
+                                               if(abund < 5) { abund = 10; }
+                                               vennCalculators.push_back(new Ace(abund));
+                                       }
+                               }
+                       }
+               }else {
+                       for (int i=0; i<Estimators.size(); i++) {
+                               if (validCalculator.isValidCalculator("vennshared", Estimators[i]) == true) { 
+                                       if (Estimators[i] == "sharedsobs") { 
+                                               vennCalculators.push_back(new SharedSobsCS());
+                                       }else if (Estimators[i] == "sharedchao") { 
+                                               vennCalculators.push_back(new SharedChao1());
+                                       }else if (Estimators[i] == "sharedace") { 
+                                               vennCalculators.push_back(new SharedAce());
+                                       }
+                               }
+                       }
+               }
+                       
+               //if the users entered no valid calculators don't execute command
+               if (vennCalculators.size() == 0) { m->mothurOut("No valid calculators given, please correct."); m->mothurOutEndLine(); return 0;  }
                
-               string lastLabel;
-               vector<string> outputNames;
+               venn = new Venn(outputDir, nseqs, inputfile, fontsize, sharedOtus); 
+               input = new InputData(inputfile, format);
                
-               //if the users entered no valid calculators don't execute command
-               if (vennCalculators.size() == 0) { return 0; }
+               string lastLabel;
                
                if (format == "sharedfile") {
-                       //you have groups
-                       read = new ReadOTUFile(globaldata->inputFileName);      
-                       read->read(&*globaldata); 
-                       
-                       input = globaldata->ginput;
                        lookup = input->getSharedRAbundVectors();
                        lastLabel = lookup[0]->getLabel();
+                       
+                       if ((lookup.size() > 4) && (perm)) { combosOfFour = findCombinations(lookup.size()); }
                }else if (format == "list") {
-                       //you are using just a list file and have only one group
-                       read = new ReadOTUFile(globaldata->inputFileName);      
-                       read->read(&*globaldata); 
-               
-                       sabund = globaldata->sabund;
+                       sabund = input->getSAbundVector();
                        lastLabel = sabund->getLabel();
-                       input = globaldata->ginput;
                }
                
                //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
                set<string> processedLabels;
                set<string> userLabels = labels;
-               
+
                if (format != "list") { 
                        
                        //as long as you are not at the end of the file or done wih the lines you want
                        while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
+                       
+                               if (m->control_pressed) {
+                                       for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
+                                       for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
+                                       m->clearGroups(); delete venn; delete input;
+                                       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
+                                       return 0;
+                               }
 
                                if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
                                        m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
                                        processedLabels.insert(lookup[0]->getLabel());
                                        userLabels.erase(lookup[0]->getLabel());
                                        
-                                       if (lookup.size() > 4) {
-                                               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();
+                                       if ((lookup.size() > 4) && (!perm)){
+                                               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();
                                                for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
-                                       }
                                        
-                                       vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
-                                       for(int i = 0; i < outfilenames.size(); i++) { outputNames.push_back(outfilenames[i]); } 
+                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
+                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  } }
+
+                                       }else if ((lookup.size() > 4) && (perm)) {
+                                               set< set<int> >::iterator it3;
+                                               set<int>::iterator it2;
+                                               for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
+                       
+                                                       set<int> poss = *it3;
+                                                       vector<SharedRAbundVector*> subset;
+                                                       for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
+                                                       
+                                                       vector<string> outfilenames = venn->getPic(subset, vennCalculators);
+                                                       for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]); }  }
+                                               }               
+                                       }else {
+                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
+                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
+                                       }                                       
                                }
                                
-                               if ((anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
+                               if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
                                        string saveLabel = lookup[0]->getLabel();
                                        
                                        for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
@@ -241,13 +343,30 @@ int VennCommand::execute(){
                                        processedLabels.insert(lookup[0]->getLabel());
                                        userLabels.erase(lookup[0]->getLabel());
 
-                                       if (lookup.size() > 4) {
-                                               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();
+                                       if ((lookup.size() > 4) && (!perm)){
+                                               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();
                                                for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
-                                       }                               
-                                       vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
-                                       for(int i = 0; i < outfilenames.size(); i++) { outputNames.push_back(outfilenames[i]); } 
                                        
+                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
+                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
+
+                                       }else if ((lookup.size() > 4) && (perm)) {
+                                               set< set<int> >::iterator it3;
+                                               set<int>::iterator it2;
+                                               for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
+                       
+                                                       set<int> poss = *it3;
+                                                       vector<SharedRAbundVector*> subset;
+                                                       for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
+                                                       
+                                                       vector<string> outfilenames = venn->getPic(subset, vennCalculators);
+                                                       for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
+                                               }               
+                                       }else {
+                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
+                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
+                                       }
+                                                                               
                                        //restore real lastlabel to save below
                                        lookup[0]->setLabel(saveLabel);
                                }
@@ -260,6 +379,14 @@ int VennCommand::execute(){
                                lookup = input->getSharedRAbundVectors();
                        }
                        
+                       if (m->control_pressed) {
+                                       for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
+                                       m->clearGroups(); delete venn; delete input; 
+                                       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
+                                       return 0;
+                       }
+
+                       
                        //output error messages about any remaining user labels
                        set<string>::iterator it;
                        bool needToRun = false;
@@ -282,36 +409,68 @@ int VennCommand::execute(){
                                        processedLabels.insert(lookup[0]->getLabel());
                                        userLabels.erase(lookup[0]->getLabel());
 
-                                       if (lookup.size() > 4) {
-                                               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();
+                                       if ((lookup.size() > 4) && (!perm)){
+                                               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();
                                                for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
-                                       }                               
-                                       vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
-                                       for(int i = 0; i < outfilenames.size(); i++) { outputNames.push_back(outfilenames[i]); } 
+                                       
+                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
+                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]); }  }
 
+                                       }else if ((lookup.size() > 4) && (perm)) {
+                                               set< set<int> >::iterator it3;
+                                               set<int>::iterator it2;
+                                               for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
+                       
+                                                       set<int> poss = *it3;
+                                                       vector<SharedRAbundVector*> subset;
+                                                       for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
+                                                       
+                                                       vector<string> outfilenames = venn->getPic(subset, vennCalculators);
+                                                       for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]); }  }
+                                               }               
+                                       }else {
+                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
+                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
+                                       }
+                                       
                                        for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
                        }
                
 
                        //reset groups parameter
-                       globaldata->Groups.clear();  
+                       m->clearGroups();  
+                       
+                       if (m->control_pressed) {
+                                       m->clearGroups(); delete venn; delete input;
+                                       for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
+                                       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
+                                       return 0;
+                       }
+
                        
                }else{
                
                        while((sabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
+                       
+                               if (m->control_pressed) {
+                                       for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
+                                       delete sabund; delete venn; delete input;
+                                       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
+                                       return 0;
+                               }
                
                                if(allLines == 1 || labels.count(sabund->getLabel()) == 1){                     
        
                                        m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
                                        vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
-                                       for(int i = 0; i < outfilenames.size(); i++) { outputNames.push_back(outfilenames[i]); } 
+                                       for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
 
                                        
                                        processedLabels.insert(sabund->getLabel());
                                        userLabels.erase(sabund->getLabel());
                                }
                                
-                               if ((anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
+                               if ((m->anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
                                        string saveLabel = sabund->getLabel();
                                
                                        delete sabund;
@@ -319,7 +478,7 @@ int VennCommand::execute(){
                                        
                                        m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
                                        vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
-                                       for(int i = 0; i < outfilenames.size(); i++) { outputNames.push_back(outfilenames[i]); } 
+                                       for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
 
                                        
                                        processedLabels.insert(sabund->getLabel());
@@ -335,6 +494,13 @@ int VennCommand::execute(){
                                sabund = input->getSAbundVector();
                        }
                        
+                       if (m->control_pressed) {
+                                       for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
+                                       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
+                                       delete venn; delete input;
+                                       return 0;
+                       }
+                       
                        //output error messages about any remaining user labels
                        set<string>::iterator it;
                        bool needToRun = false;
@@ -355,15 +521,22 @@ int VennCommand::execute(){
                                        
                                m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
                                vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
-                               for(int i = 0; i < outfilenames.size(); i++) { outputNames.push_back(outfilenames[i]); } 
+                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
 
                                delete sabund;
                                        
                        }
                        
+                       if (m->control_pressed) {
+                                       delete venn; delete input;
+                                       for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
+                                       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]);  }
+                                       return 0;
+                       }
                }
                
                for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
+               delete venn; delete input;
                
                m->mothurOutEndLine();
                m->mothurOut("Output File Names: "); m->mothurOutEndLine();
@@ -378,5 +551,55 @@ int VennCommand::execute(){
                exit(1);
        }
 }
+//**********************************************************************************************************************
+//returns a vector of sets containing the 4 group combinations
+set< set<int> > VennCommand::findCombinations(int lookupSize){
+       try {
+               set< set<int> > combos;
+               
+               set<int> possibles;
+               for (int i = 0; i < lookupSize; i++) {  possibles.insert(i);  }
+               
+               getCombos(possibles, combos);
+               
+               return combos;
+               
+       }
+       catch(exception& e) {
+               m->errorOut(e, "VennCommand", "findCombinations");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+//recusively finds combos of 4
+int VennCommand::getCombos(set<int> possibles, set< set<int> >& combos){
+       try {
+               
+               if (possibles.size() == 4) { //done
+                       if (combos.count(possibles) == 0) { //no dups
+                               combos.insert(possibles);
+                       }
+               }else { //we still have work to do
+                       set<int>::iterator it;
+                       set<int>::iterator it2;
+                       for (it = possibles.begin(); it != possibles.end(); it++) {  
+                               
+                               set<int> newPossibles;
+                               for (it2 = possibles.begin(); it2 != possibles.end(); it2++) {  //all possible combos of one length smaller
+                                       if (*it != *it2) { 
+                                               newPossibles.insert(*it2);
+                                       }
+                               }
+                               getCombos(newPossibles, combos);
+                       }
+               }
+               
+               return 0;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "VennCommand", "getCombos");
+               exit(1);
+       }
+}
 
 //**********************************************************************************************************************