]> git.donarmstrong.com Git - mothur.git/blobdiff - amovacommand.cpp
changes while testing
[mothur.git] / amovacommand.cpp
index 8ab08553c4969268be12230b68f0f80303da2989..492a096f76cc1de12514731f66514e8d632c0c5f 100644 (file)
 #include "amovacommand.h"
 #include "readphylipvector.h"
 #include "groupmap.h"
+#include "sharedutilities.h"
+
 
 //**********************************************************************************************************************
-vector<string> AmovaCommand::getValidParameters(){     
+vector<string> AmovaCommand::setParameters(){  
        try {
-               string Array[] =  {"outputdir","iters","phylip","design","alpha", "inputdir"};
-               vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
+               CommandParameter pdesign("design", "InputTypes", "", "", "none", "none", "none","amova",false,true,true); parameters.push_back(pdesign);
+        CommandParameter psets("sets", "String", "", "", "", "", "","",false,false); parameters.push_back(psets);
+               CommandParameter pphylip("phylip", "InputTypes", "", "", "none", "none", "none","amova",false,true,true); parameters.push_back(pphylip);
+               CommandParameter piters("iters", "Number", "", "1000", "", "", "","",false,false); parameters.push_back(piters);
+               CommandParameter palpha("alpha", "Number", "", "0.05", "", "", "","",false,false); parameters.push_back(palpha);
+               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, "AmovaCommand", "getValidParameters");
+               m->errorOut(e, "AmovaCommand", "setParameters");
                exit(1);
        }
 }
 //**********************************************************************************************************************
-AmovaCommand::AmovaCommand(){  
+string AmovaCommand::getHelpString(){  
        try {
-               abort = true; calledHelp = true; 
-               vector<string> tempOutNames;
-               outputTypes["amova"] = tempOutNames;
+               string helpString = "";
+               helpString += "Referenced: Anderson MJ (2001). A new method for non-parametric multivariate analysis of variance. Austral Ecol 26: 32-46.";
+               helpString += "The amova command outputs a .amova file.";
+               helpString += "The amova command parameters are phylip, iters, sets and alpha.  The phylip and design parameters are required, unless you have valid current files.";
+               helpString += "The design parameter allows you to assign your samples to groups when you are running amova. It is required.";
+               helpString += "The design file looks like the group file.  It is a 2 column tab delimited file, where the first column is the sample name and the second column is the group the sample belongs to.";
+        helpString += "The sets parameter allows you to specify which of the sets in your designfile you would like to analyze. The set names are separated by dashes. THe default is all sets in the designfile.\n";
+               helpString += "The iters parameter allows you to set number of randomization for the P value.  The default is 1000.";
+               helpString += "The amova command should be in the following format: amova(phylip=file.dist, design=file.design).";
+               helpString += "Note: No spaces between parameter labels (i.e. iters), '=' and parameters (i.e. 1000).";
+               return helpString;
        }
        catch(exception& e) {
-               m->errorOut(e, "AmovaCommand", "AmovaCommand");
+               m->errorOut(e, "AmovaCommand", "getHelpString");
                exit(1);
        }
 }
 //**********************************************************************************************************************
-vector<string> AmovaCommand::getRequiredParameters(){  
-       try {
-               string Array[] =  {"design"};
-               vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
-               return myArray;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "AmovaCommand", "getRequiredParameters");
-               exit(1);
-       }
+string AmovaCommand::getOutputPattern(string type) {
+    try {
+        string pattern = "";
+        
+        if (type == "amova") {  pattern = "[filename],amova"; } //makes file like: amazon.align
+        else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
+        
+        return pattern;
+    }
+    catch(exception& e) {
+        m->errorOut(e, "AmovaCommand", "getOutputPattern");
+        exit(1);
+    }
 }
 //**********************************************************************************************************************
-vector<string> AmovaCommand::getRequiredFiles(){       
+AmovaCommand::AmovaCommand(){  
        try {
-               string Array[] =  {};
-               vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
-               return myArray;
+               abort = true; calledHelp = true; 
+               setParameters();
+               vector<string> tempOutNames;
+               outputTypes["amova"] = tempOutNames;
        }
        catch(exception& e) {
-               m->errorOut(e, "AmovaCommand", "getRequiredFiles");
+               m->errorOut(e, "AmovaCommand", "AmovaCommand");
                exit(1);
        }
 }
 //**********************************************************************************************************************
-
 AmovaCommand::AmovaCommand(string option) {
        try {
                abort = false; calledHelp = false;   
                
                //allow user to run help
                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[] =  {"design","outputdir","iters","phylip","alpha", "inputdir"};
-                       vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
+                       vector<string> myArray = setParameters();
                        
                        OptionParser parser(option);
                        map<string,string> parameters = parser.getParameters();
@@ -116,23 +136,35 @@ AmovaCommand::AmovaCommand(string option) {
                        phylipFileName = validParameter.validFile(parameters, "phylip", true);
                        if (phylipFileName == "not open") { phylipFileName = ""; abort = true; }
                        else if (phylipFileName == "not found") { 
-                               phylipFileName = ""; 
-                       }       
+                               //if there is a current phylip file, use it
+                               phylipFileName = m->getPhylipFile(); 
+                               if (phylipFileName != "") { m->mothurOut("Using " + phylipFileName + " as input file for the phylip parameter."); m->mothurOutEndLine(); }
+                               else {  m->mothurOut("You have no current phylip file and the phylip parameter is required."); m->mothurOutEndLine(); abort = true; }
+                       }else { m->setPhylipFile(phylipFileName); }
                        
                        //check for required parameters
                        designFileName = validParameter.validFile(parameters, "design", true);
-                       if (designFileName == "not open") { abort = true; }
+                       if (designFileName == "not open") { designFileName = ""; abort = true; }
                        else if (designFileName == "not found") {
-                               designFileName = "";
-                       }       
+                               //if there is a current design file, use it
+                               designFileName = m->getDesignFile(); 
+                               if (designFileName != "") { m->mothurOut("Using " + designFileName + " as input file for the design parameter."); m->mothurOutEndLine(); }
+                               else {  m->mothurOut("You have no current design file and the design parameter is required."); m->mothurOutEndLine(); abort = true; }                           
+                       }else { m->setDesignFile(designFileName); }     
 
                        string temp = validParameter.validFile(parameters, "iters", false);
                        if (temp == "not found") { temp = "1000"; }
-                       convert(temp, iters); 
+                       m->mothurConvert(temp, iters); 
                        
                        temp = validParameter.validFile(parameters, "alpha", false);
                        if (temp == "not found") { temp = "0.05"; }
-                       convert(temp, experimentwiseAlpha); 
+                       m->mothurConvert(temp, experimentwiseAlpha); 
+            
+            string sets = validParameter.validFile(parameters, "sets", false);                 
+                       if (sets == "not found") { sets = ""; }
+                       else { 
+                               m->splitAtDash(sets, Sets);
+                       }
                }
        }
        catch(exception& e) {
@@ -140,30 +172,6 @@ AmovaCommand::AmovaCommand(string option) {
                exit(1);
        }
 }
-
-//**********************************************************************************************************************
-
-void AmovaCommand::help(){
-       try {
-               m->mothurOut("Referenced: Anderson MJ (2001). A new method for non-parametric multivariate analysis of variance. Austral Ecol 26: 32-46.\n");
-               m->mothurOut("The amova command outputs a .amova file. \n");
-               m->mothurOut("The amova command parameters are phylip, iters, and alpha.  The phylip and design parameters are required.\n");
-               m->mothurOut("The design parameter allows you to assign your samples to groups when you are running amova. It is required. \n");
-               m->mothurOut("The design file looks like the group file.  It is a 2 column tab delimited file, where the first column is the sample name and the second column is the group the sample belongs to.\n");
-               m->mothurOut("The iters parameter allows you to set number of randomization for the P value.  The default is 1000. \n");
-               m->mothurOut("The amova command should be in the following format: amova(phylip=file.dist, design=file.design).\n");
-               m->mothurOut("Note: No spaces between parameter labels (i.e. iters), '=' and parameters (i.e. 1000).\n\n");
-       }
-       catch(exception& e) {
-               m->errorOut(e, "AmovaCommand", "help");
-               exit(1);
-       }
-}
-
-//**********************************************************************************************************************
-
-AmovaCommand::~AmovaCommand(){}
-
 //**********************************************************************************************************************
 
 int AmovaCommand::execute(){
@@ -180,7 +188,32 @@ int AmovaCommand::execute(){
                //read in distance matrix and square it
                ReadPhylipVector readMatrix(phylipFileName);
                vector<string> sampleNames = readMatrix.read(distanceMatrix);
-               
+        
+        if (Sets.size() != 0) { //user selected sets, so we want to remove the samples not in those sets
+            SharedUtil util; 
+            vector<string> dGroups = designMap->getNamesOfGroups();
+            util.setGroups(Sets, dGroups);  
+
+            for(int i=0;i<distanceMatrix.size();i++){
+                
+                if (m->control_pressed) { delete designMap; return 0; }
+                
+                string group = designMap->getGroup(sampleNames[i]);
+                
+                if (group == "not found") {
+                    m->mothurOut("[ERROR]: " + sampleNames[i] + " is not in your design file, please correct."); m->mothurOutEndLine(); m->control_pressed = true;
+                }else if (!m->inUsersGroups(group, Sets)){  //not in set we want remove it
+                    //remove from all other rows
+                    for(int j=0;j<distanceMatrix.size();j++){
+                        distanceMatrix[j].erase(distanceMatrix[j].begin()+i);
+                    }
+                    distanceMatrix.erase(distanceMatrix.begin()+i);
+                    sampleNames.erase(sampleNames.begin()+i);
+                    i--;
+                }
+            }
+        }
+        
                for(int i=0;i<distanceMatrix.size();i++){
                        for(int j=0;j<i;j++){
                                distanceMatrix[i][j] *= distanceMatrix[i][j];   
@@ -190,13 +223,22 @@ int AmovaCommand::execute(){
                //link designMap to rows/columns in distance matrix
                map<string, vector<int> > origGroupSampleMap;
                for(int i=0;i<sampleNames.size();i++){
-                       origGroupSampleMap[designMap->getGroup(sampleNames[i])].push_back(i);
+                       string group = designMap->getGroup(sampleNames[i]);
+                       
+                       if (group == "not found") {
+                               m->mothurOut("[ERROR]: " + sampleNames[i] + " is not in your design file, please correct."); m->mothurOutEndLine(); m->control_pressed = true;
+                       }else { origGroupSampleMap[group].push_back(i); }
+                       
                }
                int numGroups = origGroupSampleMap.size();
                
+               if (m->control_pressed) { delete designMap; return 0; }
+               
                //create a new filename
                ofstream AMOVAFile;
-               string AMOVAFileName = outputDir + m->getRootName(m->getSimpleName(phylipFileName))  + "amova";                         
+        map<string, string> variables; variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(phylipFileName));
+               string AMOVAFileName = getOutputFileName("amova", variables);   
+        
                m->openOutputFile(AMOVAFileName, AMOVAFile);
                outputNames.push_back(AMOVAFileName); outputTypes["amova"].push_back(AMOVAFileName);
                
@@ -265,7 +307,7 @@ double AmovaCommand::runAMOVA(ofstream& AMOVAFile, map<string, vector<int> > gro
                for(int i=0;i<iters;i++){
                        map<string, vector<int> > randomizedGroup = getRandomizedGroups(groupSampleMap);
                        double ssWithinRand = calcSSWithin(randomizedGroup);
-                       if(ssWithinRand < ssWithinOrig){        counter++;      }
+                       if(ssWithinRand <= ssWithinOrig){       counter++;      }
                }
                
                double pValue = (double)counter / (double) iters;