]> git.donarmstrong.com Git - mothur.git/commitdiff
reworked amova / homova / anosim
authorpschloss <pschloss>
Mon, 21 Feb 2011 21:14:58 +0000 (21:14 +0000)
committerpschloss <pschloss>
Mon, 21 Feb 2011 21:14:58 +0000 (21:14 +0000)
Mothur.xcodeproj/project.pbxproj
amovacommand.cpp
amovacommand.h
anosimcommand.cpp
anosimcommand.h
homovacommand.cpp
homovacommand.h
readphylipvector.cpp
venn.cpp

index e4797253008a0057cc5562ddef17f0c4b4a8efa2..902e927e15ac79e725a1277fa67e891c237e7576 100644 (file)
                        attributes = {
                                ORGANIZATIONNAME = "Schloss Lab";
                        };
-                       buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "mothur" */;
+                       buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "Mothur" */;
                        compatibilityVersion = "Xcode 3.1";
                        developmentRegion = English;
                        hasScannedForEncodings = 1;
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
-               1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "mothur" */ = {
+               1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "Mothur" */ = {
                        isa = XCConfigurationList;
                        buildConfigurations = (
                                1DEB928A08733DD80010E9CD /* Debug */,
index 4dfe43be296698299adb1adc870f634ef5a6d769..b9b5deeb5e670ef2f119eb09bded37ab870efe4d 100644 (file)
@@ -8,55 +8,13 @@
  */
 
 #include "amovacommand.h"
-#include "sharedutilities.h"
-//#include "sharedsobscollectsummary.h"
-//#include "sharedchao1.h"
-//#include "sharedace.h"
-//#include "sharednseqs.h"
-//#include "sharedjabund.h"
-//#include "sharedsorabund.h"
-//#include "sharedjclass.h"
-//#include "sharedsorclass.h"
-//#include "sharedjest.h"
-//#include "sharedsorest.h"
-//#include "sharedthetayc.h"
-//#include "sharedthetan.h"
-//#include "sharedkstest.h"
-//#include "whittaker.h"
-//#include "sharedochiai.h"
-//#include "sharedanderbergs.h"
-//#include "sharedkulczynski.h"
-//#include "sharedkulczynskicody.h"
-//#include "sharedlennon.h"
-//#include "sharedmorisitahorn.h"
-//#include "sharedbraycurtis.h"
-//#include "sharedjackknife.h"
-//#include "whittaker.h"
-//#include "odum.h"
-//#include "canberra.h"
-//#include "structeuclidean.h"
-//#include "structchord.h"
-//#include "hellinger.h"
-//#include "manhattan.h"
-//#include "structpearson.h"
-//#include "soergel.h"
-//#include "spearman.h"
-//#include "structkulczynski.h"
-//#include "structchi2.h"
-//#include "speciesprofile.h"
-//#include "hamming.h"
-//#include "gower.h"
-//#include "memchi2.h"
-//#include "memchord.h"
-//#include "memeuclidean.h"
-//#include "mempearson.h"
+#include "readphylipvector.h"
+#include "groupmap.h"
 
 //**********************************************************************************************************************
 vector<string> AmovaCommand::getValidParameters(){     
        try {
-               string Array[] =  {"groups","label","outputdir","iters","phylip","design","alpha", 
-                       //"sets","processors"
-                       "inputdir"};
+               string Array[] =  {"outputdir","iters","phylip","design","alpha", "inputdir"};
                vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
                return myArray;
        }
@@ -105,19 +63,14 @@ vector<string> AmovaCommand::getRequiredFiles(){
 
 AmovaCommand::AmovaCommand(string option) {
        try {
-               globaldata = GlobalData::getInstance();
                abort = false; calledHelp = false;   
-//             allLines = 1;
-//             labels.clear();
                
                //allow user to run help
                if(option == "help") { help(); abort = true; calledHelp = true; }
                
                else {
                        //valid paramters for this command
-                       string AlignArray[] =  {"groups","label","outputdir","iters","phylip","alpha",
-//                             "design","sets","processors",
-                               "inputdir"};
+                       string AlignArray[] =  {"design","outputdir","iters","phylip","alpha", "inputdir"};
                        vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
                        
                        OptionParser parser(option);
@@ -163,10 +116,12 @@ AmovaCommand::AmovaCommand(string option) {
                        phylipFileName = validParameter.validFile(parameters, "phylip", true);
                        if (phylipFileName == "not open") { phylipFileName = ""; abort = true; }
                        else if (phylipFileName == "not found") { phylipFileName = ""; }        
-                       else {
-                               globaldata->newRead();
-                               globaldata->setPhylipFile(phylipFileName);
-                       }
+                       else if (designFileName == "not found") {
+                               designFileName = "";
+                               m->mothurOut("You must provide an phylip file.");
+                               m->mothurOutEndLine();
+                               abort = true;
+                       }       
                        
                        //check for required parameters
                        designFileName = validParameter.validFile(parameters, "design", true);
@@ -178,151 +133,14 @@ AmovaCommand::AmovaCommand(string option) {
                                abort = true;
                        }       
 
-                       string temp = validParameter.validFile(parameters, "iters", false);                     if (temp == "not found") { temp = "1000"; }
+                       string temp = validParameter.validFile(parameters, "iters", false);
+                       if (temp == "not found") { temp = "1000"; }
                        convert(temp, iters); 
                        
-                       temp = validParameter.validFile(parameters, "alpha", false);                    if (temp == "not found") { temp = "0.05"; }
+                       temp = validParameter.validFile(parameters, "alpha", false);
+                       if (temp == "not found") { temp = "0.05"; }
                        convert(temp, experimentwiseAlpha); 
-                       
-//                     make sure the user has already run the read.otu command
-//                     if ((globaldata->getSharedFile() == "")) {
-//                             if ((phylipfile == "")) {
-//                                     m->mothurOut("You must read a list and a group, a shared file or provide a distance matrix before you can use the amova command.");
-//                                     m->mothurOutEndLine();
-//                                     abort = true; 
-//                             }
-//                     }else { sharedfile = globaldata->getSharedFile(); } 
-//                             
-//                     //use distance matrix if one is provided
-//                     if ((sharedfile != "") && (phylipfile != "")) { sharedfile = ""; }
-//                     
-//                     //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") {  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 { 
-//                             m->splitAtDash(groups, Groups);
-//                             globaldata->Groups = Groups;
-//                     }
-//                     
-//                     sets = validParameter.validFile(parameters, "sets", false);                     
-//                     if (sets == "not found") { sets = ""; pickedGroups = false; }
-//                     else { 
-//                             pickedGroups = true;
-//                             m->splitAtDash(sets, Sets);
-//                     }
-//             
-//                     temp = validParameter.validFile(parameters, "processors", false);                       if (temp == "not found"){       temp = "1";     }
-//                     convert(temp, processors); 
-//                     
-//                     vector<string> Estimators;
-//                     calc = validParameter.validFile(parameters, "calc", false);                     
-//                     if (calc == "not found") { calc = "morisitahorn";  }
-//                     m->splitAtDash(calc, Estimators);
-//                             
-//                     if (abort == false) {
-//                             
-//                             ValidCalculators* validCalculator = new ValidCalculators();
-//                             
-//                             for (int i=0; i<Estimators.size(); i++) {
-//                                     if (validCalculator->isValidCalculator("treegroup", Estimators[i]) == true) { 
-//                                             if (Estimators[i] == "sharedsobs") { 
-//                                                     calculators.push_back(new SharedSobsCS());
-//                                             }else if (Estimators[i] == "sharedchao") { 
-//                                                     calculators.push_back(new SharedChao1());
-//                                             }else if (Estimators[i] == "sharedace") { 
-//                                                     calculators.push_back(new SharedAce());
-//                                             }else if (Estimators[i] == "jabund") {  
-//                                                     calculators.push_back(new JAbund());
-//                                             }else if (Estimators[i] == "sorabund") { 
-//                                                     calculators.push_back(new SorAbund());
-//                                             }else if (Estimators[i] == "jclass") { 
-//                                                     calculators.push_back(new Jclass());
-//                                             }else if (Estimators[i] == "sorclass") { 
-//                                                     calculators.push_back(new SorClass());
-//                                             }else if (Estimators[i] == "jest") { 
-//                                                     calculators.push_back(new Jest());
-//                                             }else if (Estimators[i] == "sorest") { 
-//                                                     calculators.push_back(new SorEst());
-//                                             }else if (Estimators[i] == "thetayc") { 
-//                                                     calculators.push_back(new ThetaYC());
-//                                             }else if (Estimators[i] == "thetan") { 
-//                                                     calculators.push_back(new ThetaN());
-//                                             }else if (Estimators[i] == "kstest") { 
-//                                                     calculators.push_back(new KSTest());
-//                                             }else if (Estimators[i] == "sharednseqs") { 
-//                                                     calculators.push_back(new SharedNSeqs());
-//                                             }else if (Estimators[i] == "ochiai") { 
-//                                                     calculators.push_back(new Ochiai());
-//                                             }else if (Estimators[i] == "anderberg") { 
-//                                                     calculators.push_back(new Anderberg());
-//                                             }else if (Estimators[i] == "kulczynski") { 
-//                                                     calculators.push_back(new Kulczynski());
-//                                             }else if (Estimators[i] == "kulczynskicody") { 
-//                                                     calculators.push_back(new KulczynskiCody());
-//                                             }else if (Estimators[i] == "lennon") { 
-//                                                     calculators.push_back(new Lennon());
-//                                             }else if (Estimators[i] == "morisitahorn") { 
-//                                                     calculators.push_back(new MorHorn());
-//                                             }else if (Estimators[i] == "braycurtis") { 
-//                                                     calculators.push_back(new BrayCurtis());
-//                                             }else if (Estimators[i] == "whittaker") { 
-//                                                     calculators.push_back(new Whittaker());
-//                                             }else if (Estimators[i] == "odum") { 
-//                                                     calculators.push_back(new Odum());
-//                                             }else if (Estimators[i] == "canberra") { 
-//                                                     calculators.push_back(new Canberra());
-//                                             }else if (Estimators[i] == "structeuclidean") { 
-//                                                     calculators.push_back(new StructEuclidean());
-//                                             }else if (Estimators[i] == "structchord") { 
-//                                                     calculators.push_back(new StructChord());
-//                                             }else if (Estimators[i] == "hellinger") { 
-//                                                     calculators.push_back(new Hellinger());
-//                                             }else if (Estimators[i] == "manhattan") { 
-//                                                     calculators.push_back(new Manhattan());
-//                                             }else if (Estimators[i] == "structpearson") { 
-//                                                     calculators.push_back(new StructPearson());
-//                                             }else if (Estimators[i] == "soergel") { 
-//                                                     calculators.push_back(new Soergel());
-//                                             }else if (Estimators[i] == "spearman") { 
-//                                                     calculators.push_back(new Spearman());
-//                                             }else if (Estimators[i] == "structkulczynski") { 
-//                                                     calculators.push_back(new StructKulczynski());
-//                                             }else if (Estimators[i] == "speciesprofile") { 
-//                                                     calculators.push_back(new SpeciesProfile());
-//                                             }else if (Estimators[i] == "hamming") { 
-//                                                     calculators.push_back(new Hamming());
-//                                             }else if (Estimators[i] == "structchi2") { 
-//                                                     calculators.push_back(new StructChi2());
-//                                             }else if (Estimators[i] == "gower") { 
-//                                                     calculators.push_back(new Gower());
-//                                             }else if (Estimators[i] == "memchi2") { 
-//                                                     calculators.push_back(new MemChi2());
-//                                             }else if (Estimators[i] == "memchord") { 
-//                                                     calculators.push_back(new MemChord());
-//                                             }else if (Estimators[i] == "memeuclidean") { 
-//                                                     calculators.push_back(new MemEuclidean());
-//                                             }else if (Estimators[i] == "mempearson") { 
-//                                                     calculators.push_back(new MemPearson());
-//                                             }
-//                                     }
-//                             }
-//                     }
                }
-               
        }
        catch(exception& e) {
                m->errorOut(e, "AmovaCommand", "AmovaCommand");
@@ -335,19 +153,13 @@ AmovaCommand::AmovaCommand(string option) {
 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 can only be executed after a successful read.otu command of a list and group or shared file, or by providing a phylip formatted distance matrix.\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 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. To run the pairwise comparisons of all sets use sets=all.\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 groups parameter allows you to specify which of the groups you would like included. The group names are separated by dashes. groups=all will find all pairwise comparisons. \n");
-//             m->mothurOut("The label parameter allows you to select what distance levels you would like, and are also separated by dashes.\n");
-//             m->mothurOut("The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \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");
@@ -375,7 +187,6 @@ int AmovaCommand::execute(){
                //read in distance matrix and square it
                ReadPhylipVector readMatrix(phylipFileName);
                vector<string> sampleNames = readMatrix.read(distanceMatrix);
-               int numSamples = sampleNames.size();
                
                for(int i=0;i<distanceMatrix.size();i++){
                        for(int j=0;j<i;j++){
@@ -385,7 +196,7 @@ int AmovaCommand::execute(){
                
                //link designMap to rows/columns in distance matrix
                map<string, vector<int> > origGroupSampleMap;
-               for(int i=0;i<numSamples;i++){
+               for(int i=0;i<sampleNames.size();i++){
                        origGroupSampleMap[designMap->getGroup(sampleNames[i])].push_back(i);
                }
                int numGroups = origGroupSampleMap.size();
@@ -395,8 +206,6 @@ int AmovaCommand::execute(){
                string AMOVAFileName = outputDir + m->getRootName(m->getSimpleName(phylipFileName))  + "amova";                         
                m->openOutputFile(AMOVAFileName, AMOVAFile);
                outputNames.push_back(AMOVAFileName); outputTypes["amova"].push_back(AMOVAFileName);
-
-               experimentwiseAlpha = 0.05;
                
                double fullANOVAPValue = runAMOVA(AMOVAFile, origGroupSampleMap, experimentwiseAlpha);
                if(fullANOVAPValue <= experimentwiseAlpha && numGroups > 2){
@@ -418,232 +227,17 @@ int AmovaCommand::execute(){
                                        runAMOVA(AMOVAFile, pairwiseGroupSampleMap, pairwiseAlpha);
                                }                       
                        }
-                       cout << "Experiment-wise error rate: " << experimentwiseAlpha << endl;
-                       cout << "Pair-wise error rate (Bonferroni): " << pairwiseAlpha << endl;
+                       m->mothurOut("Experiment-wise error rate: " + toString(experimentwiseAlpha) + '\n');
+                       m->mothurOut("Pair-wise error rate (Bonferroni): " + toString(pairwiseAlpha) + '\n');
                }
                else{
-                       cout << "Experiment-wise error rate: " << experimentwiseAlpha << endl;
+                       m->mothurOut("Experiment-wise error rate: " + toString(experimentwiseAlpha) + '\n');
                }
-
-               cout << "If you have borderline P-values, you should try increasing the number of iterations" << endl;
-
-               
-//             //make sure sets are all in designMap
-//             SharedUtil* util = new SharedUtil();  
-//             util->setGroups(Sets, designMap->namesOfGroups);  
-//             delete util;
-//             
-//             //if the user pickedGroups or set sets=all, then we want to figure out how to split the pairwise comparison between processors
-//             if (pickedGroups) {
-//                     for (int a=0; a<numGroups; a++) { 
-//                             for (int l = 0; l < a; l++) {   
-//                                     vector<string> groups; groups.push_back(Sets[a]); groups.push_back(Sets[l]);
-//                                     namesOfGroupCombos.push_back(groups);
-//                             }
-//                     }
-//             }else { //one giant compare
-//                     vector<string> groups;
-//                     for (int a=0; a<numGroups; a++) { groups.push_back(Sets[a]); }
-//                     namesOfGroupCombos.push_back(groups);
-//             }
-//             
-//             //only 1 combo
-//             if (numGroups == 2) { processors = 1; }
-//             else if (numGroups < 2) {
-//                     m->mothurOut("Not enough sets, I need at least 2 valid sets. Unable to complete command.");
-//                     m->mothurOutEndLine(); m->control_pressed = true;
-//             }
-//             
-//             #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-//                     if(processors != 1){
-//                             int numPairs = namesOfGroupCombos.size();
-//                             int numPairsPerProcessor = numPairs / processors;
-//                     
-//                             for (int i = 0; i < processors; i++) {
-//                                     int startPos = i * numPairsPerProcessor;
-//                                     if(i == processors - 1){
-//                                             numPairsPerProcessor = numPairs - i * numPairsPerProcessor;
-//                                     }
-//                                     lines.push_back(linePair(startPos, numPairsPerProcessor));
-//                             }
-//                     }
-//             #endif
-//             
-//             if (sharedfile != "") { //create distance matrix for each label
-//                     
-//                     if (outputDir == "") { outputDir = m->hasPath(sharedfile); }
-//                     
-//                     //for each calculator
-//                     for(int i = 0 ; i < calculators.size(); i++) {
-//                             
-//                             //create a new filename
-//                             ofstream out;
-//                             string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".amova";
-//                             m->openOutputFile(outputFile, out);
-//                             outputNames.push_back(outputFile); outputTypes["amova"].push_back(outputFile);
-//                             
-//                             //print headers
-//                             out << "label\tgroupsCompared\tMeanSquaredWithin\tMeanSquaredAmong\tFstatistic\tpValue" << endl;  
-//                             out.close();
-//                             m->mothurOut("label\tgroupsCompared\tMeanSquaredWithin\tMeanSquaredAmong\tFstatistic\tpValue\n");  
-//                     }
-//                     
-//                     InputData input(sharedfile, "sharedfile");
-//                     vector<SharedRAbundVector*> lookup = input.getSharedRAbundVectors();
-//                     string lastLabel = lookup[0]->getLabel();
-//                     
-//                     //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;
-//                     
-//                     //sanity check between shared file groups and design file groups
-//                     for (int i = 0; i < lookup.size(); i++) { 
-//                             string group = designMap->getGroup(lookup[i]->getGroup());
-//                             
-//                             if (group == "not found") { m->control_pressed = true;  m->mothurOut("[ERROR]: " + lookup[i]->getGroup() + " is not in your design file, please correct."); m->mothurOutEndLine();  }
-//                     }
-//                     
-//                     //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 < lookup.size(); i++) {  delete lookup[i];  } globaldata->Groups.clear();  delete designMap;  for (int i = 0; i < outputNames.size(); i++) {       remove(outputNames[i].c_str()); } return 0; }
-//                             
-//                             if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
-//                                     
-//                                     m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-//                                     process(lookup);
-//                                     
-//                                     processedLabels.insert(lookup[0]->getLabel());
-//                                     userLabels.erase(lookup[0]->getLabel());
-//                             }
-//                             
-//                             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];  }  
-//                                     lookup = input.getSharedRAbundVectors(lastLabel);
-//                                     m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-//                                     
-//                                     process(lookup);
-//                                     
-//                                     processedLabels.insert(lookup[0]->getLabel());
-//                                     userLabels.erase(lookup[0]->getLabel());
-//                                     
-//                                     //restore real lastlabel to save below
-//                                     lookup[0]->setLabel(saveLabel);
-//                             }
-//                             
-//                             lastLabel = lookup[0]->getLabel();
-//                             //prevent memory leak
-//                             for (int i = 0; i < lookup.size(); i++) {  delete lookup[i]; lookup[i] = NULL; }
-//                             
-//                             if (m->control_pressed) {  globaldata->Groups.clear();   delete designMap;  for (int i = 0; i < outputNames.size(); i++) {      remove(outputNames[i].c_str()); } return 0; }
-//                             
-//                             //get next line to process
-//                             lookup = input.getSharedRAbundVectors();                                
-//                     }
-//                     
-//                     if (m->control_pressed) { globaldata->Groups.clear();  delete designMap;  for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); }  return 0; }
-//                     
-//                     //output error messages about any remaining user labels
-//                     set<string>::iterator it;
-//                     bool needToRun = false;
-//                     for (it = userLabels.begin(); it != userLabels.end(); it++) {  
-//                             m->mothurOut("Your file does not include the label " + *it); 
-//                             if (processedLabels.count(lastLabel) != 1) {
-//                                     m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
-//                                     needToRun = true;
-//                             }else {
-//                                     m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
-//                             }
-//                     }
-//                     
-//                     //run last label if you need to
-//                     if (needToRun == true)  {
-//                             for (int i = 0; i < lookup.size(); i++) { if (lookup[i] != NULL) { delete lookup[i]; } }  
-//                             lookup = input.getSharedRAbundVectors(lastLabel);
-//                             
-//                             m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-//                             
-//                             process(lookup);
-//                             
-//                             for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
-//                     }
-//                     
-//                     //reset groups parameter
-//                     globaldata->Groups.clear();  
-//                     
-//                     
-//             }else { //user provided distance matrix
-//                     
-//                     if (outputDir == "") { outputDir = m->hasPath(phylipFile); }
-//                                     
-//                     //create a new filename
-//                     ofstream out;
-//                     string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipFile))  + "amova";                                
-//                     m->openOutputFile(outputFile, out);
-//                     outputNames.push_back(outputFile); outputTypes["amova"].push_back(outputFile);
-//                     
-//                     //print headers
-//                     out << "groupsCompared\tMeanSquaredWithin\tMeanSquaredAmong\tFstatistic\tpValue" << endl;  
-//                     out.close();
-//                     m->mothurOut("groupsCompared\tMeanSquaredWithin\tMeanSquaredAmong\tFstatistic\tpValue\n");  
-//                     
-//                     ReadPhylipVector readMatrix(phylipFile);
-//                     vector< vector<double> > completeMatrix;
-//                     vector<string> names = readMatrix.read(completeMatrix);
-//                     
-//                     #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-//                             if(processors == 1){
-//                                     driver(0, namesOfGroupCombos.size(), names, "", completeMatrix);
-//                             }else{
-//                                     int process = 1;
-//                                     vector<int> processIDS;
-//                                     
-//                                     //loop through and create all the processes you want
-//                                     while (process != processors) {
-//                                             int pid = fork();
-//                                             
-//                                             if (pid > 0) {
-//                                                     processIDS.push_back(pid);  
-//                                                     process++;
-//                                             }else if (pid == 0){
-//                                                     driver(lines[process].start, lines[process].num, names, toString(getpid()), completeMatrix);
-//                                                     exit(0);
-//                                             }else { 
-//                                                     m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
-//                                                     for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
-//                                                     exit(0);
-//                                             }
-//                                     }
-//                                     
-//                                     //do my part
-//                                     driver(lines[0].start, lines[0].num, names, "", completeMatrix);
-//                                     
-//                                     //force parent to wait until all the processes are done
-//                                     for (int i=0;i<(processors-1);i++) { 
-//                                             int temp = processIDS[i];
-//                                             wait(&temp);
-//                                     }
-//                                     
-//                                     //append files
-//                                     string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipFile)) + "amova";                         
-//                                     for (int j = 0; j < processIDS.size(); j++) {
-//                                             m->appendFiles((outputFile + toString(processIDS[j])), outputFile);
-//                                             remove((outputFile + toString(processIDS[j])).c_str());
-//                                     }
-//                                     
-//                             }
-//                     #else
-//                             driver(0, namesOfGroupCombos.size(), names, "", completeMatrix);
-//                     #endif
-//                     
-//             }
+               m->mothurOut("If you have borderline P-values, you should try increasing the number of iterations\n");
+               AMOVAFile.close();
                
                delete designMap;
         
-               if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); } return 0; }
-
                m->mothurOutEndLine();
                m->mothurOut("Output File Names: "); m->mothurOutEndLine();
                for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
@@ -664,10 +258,10 @@ double AmovaCommand::runAMOVA(ofstream& AMOVAFile, map<string, vector<int> > gro
                map<string, vector<int> >::iterator it;
 
                int numGroups = groupSampleMap.size();
-               int numSamples = 0;
+               int totalNumSamples = 0;
 
                for(it = groupSampleMap.begin();it!=groupSampleMap.end();it++){
-                       numSamples += it->second.size();                        
+                       totalNumSamples += it->second.size();                   
                }
 
                double ssTotalOrig = calcSSTotal(groupSampleMap);
@@ -689,29 +283,47 @@ double AmovaCommand::runAMOVA(ofstream& AMOVAFile, map<string, vector<int> > gro
                
                //print anova table
                it = groupSampleMap.begin();
-               cout << it->first;
+               AMOVAFile << it->first;
+               m->mothurOut(it->first);
                it++;
                for(it;it!=groupSampleMap.end();it++){
-                       cout << " vs. " << it->first;
-               }cout << endl;
-               cout << "ANOVA\tAmong\tWithin\tTotal" << endl;
-               cout << "SS\t" << ssAmongOrig << '\t' << ssWithinOrig << '\t' << ssTotalOrig << endl;
+                       AMOVAFile << '-' << it->first;
+                       m->mothurOut('-' + it->first);
+               }
+               
+               AMOVAFile << "\tAmong\tWithin\tTotal" << endl;
+               m->mothurOut("\tAmong\tWithin\tTotal\n");
+               
+               AMOVAFile << "SS\t" << ssAmongOrig << '\t' << ssWithinOrig << '\t' << ssTotalOrig << endl;
+               m->mothurOut("SS\t" + toString(ssAmongOrig) + '\t' + toString(ssWithinOrig) + '\t' + toString(ssTotalOrig) + '\n');
+               
+               int dfAmong = numGroups - 1;                            double MSAmong = ssAmongOrig / (double) dfAmong;
+               int dfWithin = totalNumSamples - numGroups;     double MSWithin = ssWithinOrig / (double) dfWithin;
+               int dfTotal = totalNumSamples - 1;                      double Fs = MSAmong / MSWithin;
                
-               int dfAmong = numGroups - 1;                    double MSAmong = ssAmongOrig / (double) dfAmong;
-               int dfWithin = numSamples - numGroups;  double MSWithin = ssWithinOrig / (double) dfWithin;
-               int dfTotal = numSamples - 1;                   double Fs = MSAmong / MSWithin;
+               AMOVAFile << "df\t" << dfAmong << '\t' << dfWithin << '\t' << dfTotal << endl;
+               m->mothurOut("df\t" + toString(dfAmong) + '\t' + toString(dfWithin) + '\t' + toString(dfTotal) + '\n');
+
+               AMOVAFile << "MS\t" << MSAmong << '\t' << MSWithin << endl << endl;
+               m->mothurOut("MS\t" + toString(MSAmong) + '\t' + toString(MSWithin) + "\n\n");
+
+               AMOVAFile << "Fs:\t" << Fs << endl;
+               m->mothurOut("Fs:\t" + toString(Fs) + '\n');
                
-               cout << "df\t" << dfAmong << '\t' << dfWithin << '\t' << dfTotal << endl;
-               cout << "MS\t" << MSAmong << '\t' << MSWithin << endl << endl;
-               cout << "Fs:\t" << Fs << endl;
-               cout << "p-value: " << pString;
-               if(pValue < alpha){     cout << " ***"; }
-               cout << endl << endl;
+               AMOVAFile << "p-value: " << pString;
+               m->mothurOut("p-value: " + pString);
+
+               if(pValue < alpha){
+                       AMOVAFile << "*";
+                       m->mothurOut("*");
+               }
+               AMOVAFile << endl << endl;
+               m->mothurOutEndLine();m->mothurOutEndLine();
 
                return pValue;
        }
        catch(exception& e) {
-               m->errorOut(e, "AmovaCommand", "calcAmova");
+               m->errorOut(e, "AmovaCommand", "runAMOVA");
                exit(1);
        }
 }
@@ -743,7 +355,7 @@ map<string, vector<int> > AmovaCommand::getRandomizedGroups(map<string, vector<i
                return randomizedGroups;                
        }
        catch (exception& e) {
-               m->errorOut(e, "AmovaCommand", "randomizeGroups");
+               m->errorOut(e, "AmovaCommand", "getRandomizedGroups");
                exit(1);
        }
 }
@@ -813,261 +425,9 @@ double AmovaCommand::calcSSWithin(map<string, vector<int> >& groupSampleMap) {
                return ssWithin;
        }
        catch(exception& e) {
-               m->errorOut(e, "AmovaCommand", "calcWithin");
+               m->errorOut(e, "AmovaCommand", "calcSSWithin");
                exit(1);
        }
 }
 
 //**********************************************************************************************************************
-
-//int AmovaCommand::process(vector<SharedRAbundVector*> thisLookup) {
-//     try{
-//             
-//#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-//             if(processors == 1){
-//                     driver(0, namesOfGroupCombos.size(), thisLookup, "");
-//             }else{
-//                     int process = 1;
-//                     vector<int> processIDS;
-//                     
-//                     //loop through and create all the processes you want
-//                     while (process != processors) {
-//                             int pid = fork();
-//                             
-//                             if (pid > 0) {
-//                                     processIDS.push_back(pid);  
-//                                     process++;
-//                             }else if (pid == 0){
-//                                     driver(lines[process].start, lines[process].num, thisLookup, toString(getpid()));
-//                                     exit(0);
-//                             }else { 
-//                                     m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
-//                                     for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
-//                                     exit(0);
-//                             }
-//                     }
-//                     
-//                     //do my part
-//                     driver(lines[0].start, lines[0].num, thisLookup, "");
-//                     
-//                     //force parent to wait until all the processes are done
-//                     for (int i=0;i<(processors-1);i++) { 
-//                             int temp = processIDS[i];
-//                             wait(&temp);
-//                     }
-//                     
-//                     //append files
-//                     for(int i = 0 ; i < calculators.size(); i++) {
-//                             string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".amova";                            
-//
-//                             for (int j = 0; j < processIDS.size(); j++) {
-//                                     m->appendFiles((outputFile + toString(processIDS[j])), outputFile);
-//                                     remove((outputFile + toString(processIDS[j])).c_str());
-//                             }
-//                     }
-//             }
-//#else
-//             driver(0, namesOfGroupCombos.size(), thisLookUp, "");
-//#endif
-//                     
-//             return 0;
-//     }
-//     catch(exception& e) {
-//             m->errorOut(e, "AmovaCommand", "process");
-//             exit(1);
-//     }
-//}
-
-//**********************************************************************************************************************
-
-//int AmovaCommand::driver(int start, int num, vector<SharedRAbundVector*> thisLookup, string pidValue) {
-//     try {
-//             vector<SharedRAbundVector*> subset;
-//             EstOutput data;
-//             
-//             //for each calculator
-//             for(int i = 0 ; i < calculators.size(); i++) {
-//                     
-//                     //create a new filename
-//                     ofstream out;
-//                     string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".amova" + pidValue;                         
-//                     m->openOutputFileAppend(outputFile, out);
-//                     out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
-//                     
-//                     //for each combo
-//                     for (int c = start; c < (start+num); c++) {
-//                             
-//                             if (m->control_pressed) { out.close(); return 0; }
-//                             
-//                             //get set names
-//                             vector<string> setNames;
-//                             for (int j = 0; j < namesOfGroupCombos[c].size(); j++) { setNames.push_back(namesOfGroupCombos[c][j]); }
-//                             
-//                             vector<SharedRAbundVector*> thisCombosLookup;
-//                             vector<string> thisCombosLookupSets; //what set each sharedRabund is from to be used when calculating SSWithin
-//                             for (int k = 0; k < thisLookup.size(); k++) {
-//                                     string thisGroup = thisLookup[k]->getGroup();
-//                                     
-//                                     //is this group for a set we want to compare??
-//                                     if (m->inUsersGroups(designMap->getGroup(thisGroup), setNames)) {  
-//                                             thisCombosLookup.push_back(thisLookup[k]);
-//                                             thisCombosLookupSets.push_back(designMap->getGroup(thisGroup));
-//                                     }
-//                                     
-//                             }
-//                             
-//                             int numGroups = thisCombosLookup.size();
-//                     
-//                             //calc the distance matrix
-//                             matrix.clear();
-//                             matrix.resize(numGroups);
-//                             for (int k = 0; k < matrix.size(); k++) {       for (int j = 0; j < matrix.size(); j++) {       matrix[k].push_back(1.0);       }       }
-//                             
-//                             if (thisCombosLookup.size() == 0)  { 
-//                                     m->mothurOut("[ERROR]: Missing shared info for sets. Skipping comparison."); m->mothurOutEndLine(); 
-//                             }else{
-//                                     
-//                                     m->mothurOut(thisLookup[0]->getLabel() + '\t');
-//                                     out << thisLookup[0]->getLabel() << '\t';
-//                                     if (setNames.size() == 2) {
-//                                             m->mothurOut(setNames[0] + '-' + setNames[1] + '\t');
-//                                             out << setNames[0] << "-" << setNames[1] << '\t'; 
-//                                     }
-//                                     else {
-//                                             out << "all" << '\t'; 
-//                                             m->mothurOut("all\t");
-//                                     }
-//                                     
-//                                     for (int k = 0; k < thisCombosLookup.size(); k++) { 
-//                                             for (int l = k; l < thisCombosLookup.size(); l++) {
-//                                                     
-//                                                     if (m->control_pressed) { out.close(); return 0; }
-//                                                     
-//                                                     if (k != l) { //we dont need to similiarity of a groups to itself
-//                                                             //get estimated similarity between 2 groups
-//                                                             subset.clear(); //clear out old pair of sharedrabunds
-//                                                             //add new pair of sharedrabunds
-//                                                             subset.push_back(thisCombosLookup[k]); subset.push_back(thisCombosLookup[l]); 
-//                                                             
-//                                                             //if this calc needs all groups to calculate the pair load all groups
-//                                                             if (calculators[i]->getNeedsAll()) { 
-//                                                                     //load subset with rest of lookup for those calcs that need everyone to calc for a pair
-//                                                                     for (int w = 0; w < thisCombosLookup.size(); w++) {
-//                                                                             if ((w != k) && (w != l)) { subset.push_back(thisCombosLookup[w]); }
-//                                                                     }
-//                                                             }
-//                                                             
-//                                                             data = calculators[i]->getValues(subset); //saves the calculator outputs
-//                                                             
-//                                                             //save values in similarity matrix
-//                                                             matrix[k][l] = 1.0 - data[0];
-//                                                             matrix[l][k] = 1.0 - data[0];
-//                                                     }
-//                                             }
-//                                     }
-//                                     
-//                                     //calc amova
-//                                     calcAmova(out, setNames.size(), thisCombosLookupSets);
-//                             }
-//                     }
-//                     
-//                     out.close();
-//             }               
-//             
-//             return 0;
-//             
-//     }
-//     catch(exception& e) {
-//             m->errorOut(e, "AmovaCommand", "driver");
-//             exit(1);
-//     }
-//}
-//
-//**********************************************************************************************************************
-//
-//int AmovaCommand::driver(int start, int num, vector<string> names, string pidValue, vector< vector<double> >& completeMatrix) {
-//     try {
-//             
-//             //create a new filename
-//             ofstream out;
-//             string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipFile)) + "amova" + pidValue;                              
-//             m->openOutputFileAppend(outputFile, out);
-//             out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
-//             
-//             //for each combo
-//             for (int c = start; c < (start+num); c++) {
-//                     
-//                     if (m->control_pressed) { out.close(); return 0; }
-//                     
-//                     //get set names
-//                     vector<string> setNames;
-//                     for (int j = 0; j < namesOfGroupCombos[c].size(); j++) { setNames.push_back(namesOfGroupCombos[c][j]); }
-//                     
-//                     vector<string> thisCombosSets; //what set each line in the distance matrix is from to be used when calculating SSWithin
-//                     set<int> indexes;
-//                     for (int k = 0; k < names.size(); k++) {
-//                             //is this group for a set we want to compare??
-//                             if (m->inUsersGroups(designMap->getGroup(names[k]), setNames)) {  
-//                                     thisCombosSets.push_back(designMap->getGroup(names[k]));        
-//                                     indexes.insert(k); //save indexes of valid rows in matrix for submatrix
-//                             }
-//                     }
-//                     
-//                     int numGroups = thisCombosSets.size();
-//                     
-//                     //calc the distance matrix
-//                     matrix.clear();
-//                     matrix.resize(numGroups);
-//                     
-//                     for (int k = 0; k < matrix.size(); k++) {       for (int j = 0; j < matrix.size(); j++) {       matrix[k].push_back(1.0);       }       }
-//                     
-//                     if (thisCombosSets.size() == 0)  { 
-//                             m->mothurOut("[ERROR]: Missing distance info for sets. Skipping comparison."); m->mothurOutEndLine(); 
-//                     }else{
-//                             
-//                             if (setNames.size() == 2) { 
-//                                     out << setNames[0] << "-" << setNames[1] << '\t'; 
-//                                     m->mothurOut(setNames[0] + '-' + setNames[1] + '\t');
-//                             }
-//                             else {
-//                                     out << "all" << '\t'; 
-//                                     m->mothurOut("all\t");
-//                             }
-//                             
-//                             //fill submatrix
-//                             int rowCount = 0;
-//                             for (int j = 0; j < completeMatrix.size(); j++) {
-//                                     
-//                                     if (indexes.count(j) != 0) { //we want at least part of this row
-//                                             int columnCount = 0;
-//                                             for (int k = 0; k < completeMatrix[j].size(); k++) {
-//                                                     
-//                                                     if (indexes.count(k) != 0) { //we want this distance
-//                                                             matrix[rowCount][columnCount] = completeMatrix[j][k];
-//                                                             matrix[columnCount][rowCount] = completeMatrix[j][k];
-//                                                             columnCount++;
-//                                                     }
-//                                             }
-//                                             rowCount++;
-//                                     }
-//                             }
-//                             
-//                             //calc amova
-//                             calcAmova(out, setNames.size(), thisCombosSets);
-//                     }
-//             }
-//             
-//             out.close();
-//             
-//     
-//             return 0;
-//             
-//     }
-//     catch(exception& e) {
-//             m->errorOut(e, "AmovaCommand", "driver");
-//             exit(1);
-//     }
-//}
-//
-//**********************************************************************************************************************
-
index d9fe1e6fe7e941c89ed65ffafce0f0ad2cc72c61..51a420064fc0e560cebb291035b1d9245febce5c 100644 (file)
  */
 
 #include "command.hpp"
-#include "inputdata.h"
-#include "sharedrabundvector.h"
-#include "validcalculator.h"
-#include "readphylipvector.h"
 
-class GlobalData;
+//class GlobalData;
+class GroupMap;
 
 class AmovaCommand : public Command {
        
@@ -39,7 +36,6 @@ private:
 
        
        bool abort;
-       GlobalData* globaldata;
        map<string, vector<string> > outputTypes;
        vector<string> outputNames;
 
@@ -48,23 +44,6 @@ private:
        vector< vector<double> > distanceMatrix;
        int iters;
        double experimentwiseAlpha;
-       
-//     struct linePair {
-//             int start;
-//             int num;
-//             linePair(int i, int j) : start(i), num(j) {}
-//     };
-//     vector<linePair> lines;
-//
-//     vector< vector<string> > namesOfGroupCombos;
-//     vector<string> Groups, outputNames, Sets;
-//     int processors;
-//     string groups, sets, calc, sharedfile, label, allLines, pickedGroups;
-//     vector<Calculator*> calculators;
-//     set<string> labels; //holds labels to be used
-//     int driver(int, int, vector<SharedRAbundVector*>, string);
-//     int driver(int, int, vector<string>, string, vector< vector<double> >&);
-//     int process(vector<SharedRAbundVector*>);       
 };
 
 #endif
index 9f537b8f6d15c115558a196996b48b58bda7fbb6..bb0f495a0ac81d6ce72c358b0c02d13592f8dbb2 100644 (file)
@@ -8,53 +8,13 @@
  */
 
 #include "anosimcommand.h"
-#include "sharedutilities.h"
-#include "sharedsobscollectsummary.h"
-#include "sharedchao1.h"
-#include "sharedace.h"
-#include "sharednseqs.h"
-#include "sharedjabund.h"
-#include "sharedsorabund.h"
-#include "sharedjclass.h"
-#include "sharedsorclass.h"
-#include "sharedjest.h"
-#include "sharedsorest.h"
-#include "sharedthetayc.h"
-#include "sharedthetan.h"
-#include "sharedkstest.h"
-#include "whittaker.h"
-#include "sharedochiai.h"
-#include "sharedanderbergs.h"
-#include "sharedkulczynski.h"
-#include "sharedkulczynskicody.h"
-#include "sharedlennon.h"
-#include "sharedmorisitahorn.h"
-#include "sharedbraycurtis.h"
-#include "sharedjackknife.h"
-#include "whittaker.h"
-#include "odum.h"
-#include "canberra.h"
-#include "structeuclidean.h"
-#include "structchord.h"
-#include "hellinger.h"
-#include "manhattan.h"
-#include "structpearson.h"
-#include "soergel.h"
-#include "spearman.h"
-#include "structkulczynski.h"
-#include "structchi2.h"
-#include "speciesprofile.h"
-#include "hamming.h"
-#include "gower.h"
-#include "memchi2.h"
-#include "memchord.h"
-#include "memeuclidean.h"
-#include "mempearson.h"
+#include "inputdata.h"
+#include "readphylipvector.h"
 
 //**********************************************************************************************************************
 vector<string> AnosimCommand::getValidParameters(){    
        try {
-               string Array[] =  {"groups","label","outputdir","iters","phylip","design","sets","processors","inputdir"};
+               string Array[] =  {"outputdir","iters","phylip","design", "alpha","inputdir"};
                vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
                return myArray;
        }
@@ -103,17 +63,14 @@ vector<string> AnosimCommand::getRequiredFiles(){
 
 AnosimCommand::AnosimCommand(string option) {
        try {
-               globaldata = GlobalData::getInstance();
                abort = false; calledHelp = false;   
-               allLines = 1;
-               labels.clear();
                
                //allow user to run help
                if(option == "help") { help(); abort = true; calledHelp = true; }
                
                else {
                        //valid paramters for this command
-                       string AlignArray[] =  {"groups","label","outputdir","iters","phylip","design","sets","processors","inputdir"};
+                       string AlignArray[] =  {"outputdir","iters","phylip","design", "alpha","inputdir"};
                        vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
                        
                        OptionParser parser(option);
@@ -156,155 +113,33 @@ AnosimCommand::AnosimCommand(string option) {
                                }
                        }
                        
-                       phylipfile = validParameter.validFile(parameters, "phylip", true);
-                       if (phylipfile == "not open") { phylipfile = ""; abort = true; }
-                       else if (phylipfile == "not found") { phylipfile = ""; }        
-                       else {  globaldata->newRead(); format = "phylip";  globaldata->setPhylipFile(phylipfile);       }
+                       phylipFileName = validParameter.validFile(parameters, "phylip", true);
+                       if (phylipFileName == "not open") { phylipFileName = ""; abort = true; }
+                       else if (phylipFileName == "not found") { phylipFileName = ""; }        
+                       else if (designFileName == "not found") {
+                               designFileName = "";
+                               m->mothurOut("You must provide an phylip file.");
+                               m->mothurOutEndLine();
+                               abort = true;
+                       }       
                        
                        //check for required parameters
-                       designfile = validParameter.validFile(parameters, "design", true);
-                       if (designfile == "not open") { abort = true; }
-                       else if (designfile == "not found") {  designfile = "";  m->mothurOut("You must provide an design file."); m->mothurOutEndLine(); abort = true; }       
-                       
-                       //make sure the user has already run the read.otu command
-                       if ((globaldata->getSharedFile() == "")) {
-                               if ((phylipfile == "")) {
-                                       m->mothurOut("You must read a list and a group, a shared file or provide a distance matrix before you can use the anosim command."); m->mothurOutEndLine(); abort = true; 
-                               }
-                       }else { sharedfile = globaldata->getSharedFile(); } 
-                       
-                       //use distance matrix if one is provided
-                       if ((sharedfile != "") && (phylipfile != "")) { sharedfile = ""; }
-                       
-                       //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") {  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 { 
-                               m->splitAtDash(groups, Groups);
-                               globaldata->Groups = Groups;
-                       }
-                       
-                       sets = validParameter.validFile(parameters, "sets", false);                     
-                       if (sets == "not found") { sets = ""; pickedGroups = false; }
-                       else { 
-                               pickedGroups = true;
-                               m->splitAtDash(sets, Sets);
-                       }
-                       
-                       
-                       string temp = validParameter.validFile(parameters, "iters", false);                     if (temp == "not found") { temp = "1000"; }
+                       designFileName = validParameter.validFile(parameters, "design", true);
+                       if (designFileName == "not open") { abort = true; }
+                       else if (designFileName == "not found") {
+                               designFileName = "";
+                               m->mothurOut("You must provide an design file.");
+                               m->mothurOutEndLine();
+                               abort = true;
+                       }       
+                       
+                       string temp = validParameter.validFile(parameters, "iters", false);
+                       if (temp == "not found") { temp = "1000"; }
                        convert(temp, iters); 
                        
-                       temp = validParameter.validFile(parameters, "processors", false);                       if (temp == "not found"){       temp = "1";     }
-                       convert(temp, processors); 
-                       
-                       vector<string> Estimators;
-                       calc = validParameter.validFile(parameters, "calc", false);                     
-                       if (calc == "not found") { calc = "morisitahorn";  }
-                       m->splitAtDash(calc, Estimators);
-                       
-                       if (abort == false) {
-                               
-                               ValidCalculators* validCalculator = new ValidCalculators();
-                               
-                               for (int i=0; i<Estimators.size(); i++) {
-                                       if (validCalculator->isValidCalculator("treegroup", Estimators[i]) == true) { 
-                                               if (Estimators[i] == "sharedsobs") { 
-                                                       calculators.push_back(new SharedSobsCS());
-                                               }else if (Estimators[i] == "sharedchao") { 
-                                                       calculators.push_back(new SharedChao1());
-                                               }else if (Estimators[i] == "sharedace") { 
-                                                       calculators.push_back(new SharedAce());
-                                               }else if (Estimators[i] == "jabund") {  
-                                                       calculators.push_back(new JAbund());
-                                               }else if (Estimators[i] == "sorabund") { 
-                                                       calculators.push_back(new SorAbund());
-                                               }else if (Estimators[i] == "jclass") { 
-                                                       calculators.push_back(new Jclass());
-                                               }else if (Estimators[i] == "sorclass") { 
-                                                       calculators.push_back(new SorClass());
-                                               }else if (Estimators[i] == "jest") { 
-                                                       calculators.push_back(new Jest());
-                                               }else if (Estimators[i] == "sorest") { 
-                                                       calculators.push_back(new SorEst());
-                                               }else if (Estimators[i] == "thetayc") { 
-                                                       calculators.push_back(new ThetaYC());
-                                               }else if (Estimators[i] == "thetan") { 
-                                                       calculators.push_back(new ThetaN());
-                                               }else if (Estimators[i] == "kstest") { 
-                                                       calculators.push_back(new KSTest());
-                                               }else if (Estimators[i] == "sharednseqs") { 
-                                                       calculators.push_back(new SharedNSeqs());
-                                               }else if (Estimators[i] == "ochiai") { 
-                                                       calculators.push_back(new Ochiai());
-                                               }else if (Estimators[i] == "anderberg") { 
-                                                       calculators.push_back(new Anderberg());
-                                               }else if (Estimators[i] == "kulczynski") { 
-                                                       calculators.push_back(new Kulczynski());
-                                               }else if (Estimators[i] == "kulczynskicody") { 
-                                                       calculators.push_back(new KulczynskiCody());
-                                               }else if (Estimators[i] == "lennon") { 
-                                                       calculators.push_back(new Lennon());
-                                               }else if (Estimators[i] == "morisitahorn") { 
-                                                       calculators.push_back(new MorHorn());
-                                               }else if (Estimators[i] == "braycurtis") { 
-                                                       calculators.push_back(new BrayCurtis());
-                                               }else if (Estimators[i] == "whittaker") { 
-                                                       calculators.push_back(new Whittaker());
-                                               }else if (Estimators[i] == "odum") { 
-                                                       calculators.push_back(new Odum());
-                                               }else if (Estimators[i] == "canberra") { 
-                                                       calculators.push_back(new Canberra());
-                                               }else if (Estimators[i] == "structeuclidean") { 
-                                                       calculators.push_back(new StructEuclidean());
-                                               }else if (Estimators[i] == "structchord") { 
-                                                       calculators.push_back(new StructChord());
-                                               }else if (Estimators[i] == "hellinger") { 
-                                                       calculators.push_back(new Hellinger());
-                                               }else if (Estimators[i] == "manhattan") { 
-                                                       calculators.push_back(new Manhattan());
-                                               }else if (Estimators[i] == "structpearson") { 
-                                                       calculators.push_back(new StructPearson());
-                                               }else if (Estimators[i] == "soergel") { 
-                                                       calculators.push_back(new Soergel());
-                                               }else if (Estimators[i] == "spearman") { 
-                                                       calculators.push_back(new Spearman());
-                                               }else if (Estimators[i] == "structkulczynski") { 
-                                                       calculators.push_back(new StructKulczynski());
-                                               }else if (Estimators[i] == "speciesprofile") { 
-                                                       calculators.push_back(new SpeciesProfile());
-                                               }else if (Estimators[i] == "hamming") { 
-                                                       calculators.push_back(new Hamming());
-                                               }else if (Estimators[i] == "structchi2") { 
-                                                       calculators.push_back(new StructChi2());
-                                               }else if (Estimators[i] == "gower") { 
-                                                       calculators.push_back(new Gower());
-                                               }else if (Estimators[i] == "memchi2") { 
-                                                       calculators.push_back(new MemChi2());
-                                               }else if (Estimators[i] == "memchord") { 
-                                                       calculators.push_back(new MemChord());
-                                               }else if (Estimators[i] == "memeuclidean") { 
-                                                       calculators.push_back(new MemEuclidean());
-                                               }else if (Estimators[i] == "mempearson") { 
-                                                       calculators.push_back(new MemPearson());
-                                               }
-                                       }
-                               }
-                       }
+                       temp = validParameter.validFile(parameters, "alpha", false);
+                       if (temp == "not found") { temp = "0.05"; }
+                       convert(temp, experimentwiseAlpha); 
                }
                
        }
@@ -318,19 +153,14 @@ AnosimCommand::AnosimCommand(string option) {
 
 void AnosimCommand::help(){
        try {
-               m->mothurOut("The anosim command can only be executed after a successful read.otu command of a list and group or shared file, or by providing a phylip formatted distance matrix.\n");
+               m->mothurOut("Referenced: Clarke, K. R. (1993). Non-parametric multivariate analysis of changes in community structure.   _Australian Journal of Ecology_ 18, 117-143.\n");
                m->mothurOut("The anosim command outputs a .anosim file. \n");
-               m->mothurOut("The anosim command parameters are phylip, iters, groups, label, design, sets and processors.  The design parameter is required.\n");
-               m->mothurOut("The design parameter allows you to assign your groups to sets when you are running anosim. 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 group name and the second column is the set the group belongs to.\n");
-               m->mothurOut("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. To run the pairwise comparisons of all sets use sets=all.\n");
+               m->mothurOut("The anosim 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 anosim. 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 groups parameter allows you to specify which of the groups you would like included. The group names are separated by dashes. groups=all will find all pairwise comparisons. \n");
-               m->mothurOut("The label parameter allows you to select what distance levels you would like, and are also separated by dashes.\n");
-               m->mothurOut("The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n");
-               m->mothurOut("The anosim command should be in the following format: anosim(design=yourDesignFile).\n");
-               m->mothurOut("Example anosim(design=temp.design, groups=A-B-C).\n");
-               m->mothurOut("Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n\n");
+               m->mothurOut("The anosim command should be in the following format: anosim(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) {
@@ -351,223 +181,91 @@ int AnosimCommand::execute(){
                if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
                
                //read design file
-               designMap = new GroupMap(designfile);
+               designMap = new GroupMap(designFileName);
                designMap->readDesignMap();
                
-               //make sure sets are all in designMap
-               SharedUtil* util = new SharedUtil();  
-               util->setGroups(Sets, designMap->namesOfGroups);  
-               delete util;
-               
-               //if the user pickedGroups or set sets=all, then we want to figure out how to split the pairwise comparison between processors
-               int numGroups = Sets.size();
-               if (pickedGroups) {
-                       for (int a=0; a<numGroups; a++) { 
-                               for (int l = 0; l < a; l++) {   
-                                       vector<string> groups; groups.push_back(Sets[a]); groups.push_back(Sets[l]);
-                                       namesOfGroupCombos.push_back(groups);
-                               }
-                       }
-               }else { //one giant compare
-                       vector<string> groups;
-                       for (int a=0; a<numGroups; a++) { groups.push_back(Sets[a]); }
-                       namesOfGroupCombos.push_back(groups);
-               }
+               if (outputDir == "") { outputDir = m->hasPath(phylipFileName); }
                
-               //only 1 combo
-               if (numGroups == 2) { processors = 1; }
-               else if (numGroups < 2) { m->mothurOut("Not enough sets, I need at least 2 valid sets. Unable to complete command."); m->mothurOutEndLine(); m->control_pressed = true; }
+               //read in distance matrix and square it
+               ReadPhylipVector readMatrix(phylipFileName);
+               vector<string> sampleNames = readMatrix.read(distanceMatrix);
                
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-               if(processors != 1){
-                       int numPairs = namesOfGroupCombos.size();
-                       int numPairsPerProcessor = numPairs / processors;
-                       
-                       for (int i = 0; i < processors; i++) {
-                               int startPos = i * numPairsPerProcessor;
-                               if(i == processors - 1){
-                                       numPairsPerProcessor = numPairs - i * numPairsPerProcessor;
-                               }
-                               lines.push_back(linePair(startPos, numPairsPerProcessor));
+               for(int i=0;i<distanceMatrix.size();i++){
+                       for(int j=0;j<i;j++){
+                               distanceMatrix[i][j] *= distanceMatrix[i][j];   
                        }
                }
-#endif
                
-               if (sharedfile != "") { //create distance matrix for each label
-                       
-                       if (outputDir == "") { outputDir = m->hasPath(sharedfile); }
-                       
-                       //for each calculator
-                       for(int i = 0 ; i < calculators.size(); i++) {
-                               
-                               //create a new filename
-                               ofstream out;
-                               string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".anosim";                           
-                               m->openOutputFile(outputFile, out);
-                               outputNames.push_back(outputFile); outputTypes["anosim"].push_back(outputFile);
-                               
-                               //print headers
-                               out << "label\tgroupsCompared\tRValue\tpValue" << endl;  
-                               m->mothurOut("\nlabel\tgroupsCompared\tRValue\tpValue"); m->mothurOutEndLine();  
-                               out.close();
-                       }
-                       
-                       InputData input(sharedfile, "sharedfile");
-                       vector<SharedRAbundVector*> lookup = input.getSharedRAbundVectors();
-                       string lastLabel = lookup[0]->getLabel();
-                       
-                       //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;
-                       
-                       //sanity check between shared file groups and design file groups
-                       for (int i = 0; i < lookup.size(); i++) { 
-                               string group = designMap->getGroup(lookup[i]->getGroup());
-                               
-                               if (group == "not found") { m->control_pressed = true;  m->mothurOut("[ERROR]: " + lookup[i]->getGroup() + " is not in your design file, please correct."); m->mothurOutEndLine();  }
-                       }
-                       
-                       //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 < lookup.size(); i++) {  delete lookup[i];  } globaldata->Groups.clear();  delete designMap;  for (int i = 0; i < outputNames.size(); i++) {       remove(outputNames[i].c_str()); } return 0; }
-                               
-                               if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
-                                       
-                                       m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-                                       process(lookup);
-                                       
-                                       processedLabels.insert(lookup[0]->getLabel());
-                                       userLabels.erase(lookup[0]->getLabel());
-                               }
-                               
-                               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];  }  
-                                       lookup = input.getSharedRAbundVectors(lastLabel);
-                                       m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-                                       
-                                       process(lookup);
+               //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);
+               }
+               int numGroups = origGroupSampleMap.size();
+               
+               //create a new filename
+               ofstream ANOSIMFile;
+               string ANOSIMFileName = outputDir + m->getRootName(m->getSimpleName(phylipFileName))  + "anosim";                               
+               m->openOutputFile(ANOSIMFileName, ANOSIMFile);
+               outputNames.push_back(ANOSIMFileName); outputTypes["anosim"].push_back(ANOSIMFileName);
+               m->mothurOut("\ncomparison\tR-value\tP-value\n");
+               ANOSIMFile << "comparison\tR-value\tP-value\n";
+               
+               
+               double fullANOSIMPValue = runANOSIM(ANOSIMFile, distanceMatrix, origGroupSampleMap, experimentwiseAlpha);
+               
+               
+               if(fullANOSIMPValue <= experimentwiseAlpha && numGroups > 2){
+
+                       int numCombos = numGroups * (numGroups-1) / 2;
+                       double pairwiseAlpha = experimentwiseAlpha / (double) numCombos;
+
+                       for(map<string, vector<int> >::iterator itA=origGroupSampleMap.begin();itA!=origGroupSampleMap.end();itA++){
+                               map<string, vector<int> >::iterator itB = itA;
+                               itB++;
+                               for(itB;itB!=origGroupSampleMap.end();itB++){
                                        
-                                       processedLabels.insert(lookup[0]->getLabel());
-                                       userLabels.erase(lookup[0]->getLabel());
+                                       map<string, vector<int> > subGroupSampleMap;
                                        
-                                       //restore real lastlabel to save below
-                                       lookup[0]->setLabel(saveLabel);
-                               }
-                               
-                               lastLabel = lookup[0]->getLabel();
-                               //prevent memory leak
-                               for (int i = 0; i < lookup.size(); i++) {  delete lookup[i]; lookup[i] = NULL; }
-                               
-                               if (m->control_pressed) {  globaldata->Groups.clear();   delete designMap;  for (int i = 0; i < outputNames.size(); i++) {      remove(outputNames[i].c_str()); } return 0; }
-                               
-                               //get next line to process
-                               lookup = input.getSharedRAbundVectors();                                
-                       }
-                       
-                       if (m->control_pressed) { globaldata->Groups.clear();  delete designMap;  for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); }  return 0; }
-                       
-                       //output error messages about any remaining user labels
-                       set<string>::iterator it;
-                       bool needToRun = false;
-                       for (it = userLabels.begin(); it != userLabels.end(); it++) {  
-                               m->mothurOut("Your file does not include the label " + *it); 
-                               if (processedLabels.count(lastLabel) != 1) {
-                                       m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
-                                       needToRun = true;
-                               }else {
-                                       m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
-                               }
-                       }
-                       
-                       //run last label if you need to
-                       if (needToRun == true)  {
-                               for (int i = 0; i < lookup.size(); i++) { if (lookup[i] != NULL) { delete lookup[i]; } }  
-                               lookup = input.getSharedRAbundVectors(lastLabel);
-                               
-                               m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-                               
-                               process(lookup);
-                               
-                               for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
-                       }
-                       
-                       //reset groups parameter
-                       globaldata->Groups.clear();  
-                       
-                       
-               }else { //user provided distance matrix
-                       
-                       if (outputDir == "") { outputDir = m->hasPath(phylipfile); }
+                                       subGroupSampleMap[itA->first] = itA->second;    string groupA = itA->first;
+                                       subGroupSampleMap[itB->first] = itB->second;    string groupB = itB->first;
                        
-                       //create a new filename
-                       ofstream out;
-                       string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipfile))  + "anosim";                               
-                       m->openOutputFile(outputFile, out);
-                       outputNames.push_back(outputFile); outputTypes["anosim"].push_back(outputFile);
-                       
-                       //print headers
-                       out << "groupsCompared\tRValue\tpValue" << endl; 
-                       m->mothurOut("\ngroupsCompared\tRValue\tpValue"); m->mothurOutEndLine();  
-                       out.close();
-                       
-                       ReadPhylipVector readMatrix(phylipfile);
-                       vector< vector<double> > completeMatrix;
-                       vector<string> names = readMatrix.read(completeMatrix);
-                       
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-                       if(processors == 1){
-                               driver(0, namesOfGroupCombos.size(), names, "", completeMatrix);
-                       }else{
-                               int process = 1;
-                               vector<int> processIDS;
-                               
-                               //loop through and create all the processes you want
-                               while (process != processors) {
-                                       int pid = fork();
+                                       vector<int> subIndices;
+                                       for(map<string, vector<int> >::iterator it=subGroupSampleMap.begin();it!=subGroupSampleMap.end();it++){
+                                               subIndices.insert(subIndices.end(), it->second.begin(), it->second.end());
+                                       }
+                                       int subNumSamples = subIndices.size();
+
+                                       sort(subIndices.begin(), subIndices.end());             
                                        
-                                       if (pid > 0) {
-                                               processIDS.push_back(pid);  
-                                               process++;
-                                       }else if (pid == 0){
-                                               driver(lines[process].start, lines[process].num, names, toString(getpid()), completeMatrix);
-                                               exit(0);
-                                       }else { 
-                                               m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
-                                               for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
-                                               exit(0);
+                                       vector<vector<double> > subDistMatrix(distanceMatrix.size());
+                                       for(int i=0;i<distanceMatrix.size();i++){
+                                               subDistMatrix[i].assign(distanceMatrix.size(), -1);
                                        }
+
+                                       for(int i=0;i<subNumSamples;i++){
+                                               for(int j=0;j<i;j++){
+                                                       subDistMatrix[subIndices[i]][subIndices[j]] = distanceMatrix[subIndices[i]][subIndices[j]];
+                                               }
+                                       }
+
+                                       runANOSIM(ANOSIMFile, subDistMatrix, subGroupSampleMap, pairwiseAlpha);
+
                                }
-                               
-                               //do my part
-                               driver(lines[0].start, lines[0].num, names, "", completeMatrix);
-                               
-                               //force parent to wait until all the processes are done
-                               for (int i=0;i<(processors-1);i++) { 
-                                       int temp = processIDS[i];
-                                       wait(&temp);
-                               }
-                               
-                               //append files
-                               string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipfile)) + "anosim";                                
-                               for (int j = 0; j < processIDS.size(); j++) {
-                                       m->appendFiles((outputFile + toString(processIDS[j])), outputFile);
-                                       remove((outputFile + toString(processIDS[j])).c_str());
-                               }
-                               
                        }
-#else
-                       driver(0, namesOfGroupCombos.size(), names, "", completeMatrix);
-#endif
                        
+                       m->mothurOut("\nExperiment-wise error rate: " + toString(experimentwiseAlpha) + '\n');
+                       m->mothurOut("Pair-wise error rate (Bonferroni): " + toString(pairwiseAlpha) + '\n');
+               }
+               else{
+                       m->mothurOut("\nExperiment-wise error rate: " + toString(experimentwiseAlpha) + '\n');
                }
+               m->mothurOut("If you have borderline P-values, you should try increasing the number of iterations\n");
+               ANOSIMFile.close();
                
+                       
                delete designMap;
-               
-               if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); } return 0; }
-               
+                               
                m->mothurOutEndLine();
                m->mothurOut("Output File Names: "); m->mothurOutEndLine();
                for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
@@ -582,366 +280,204 @@ int AnosimCommand::execute(){
 }
 //**********************************************************************************************************************
 
-int AnosimCommand::process(vector<SharedRAbundVector*> thisLookup) {
-       try{
+double AnosimCommand::runANOSIM(ofstream& ANOSIMFile, vector<vector<double> > dMatrix, map<string, vector<int> > groupSampleMap, double alpha) {
+       try {
+
                
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-               if(processors == 1){
-                       driver(0, namesOfGroupCombos.size(), thisLookup, "");
-               }else{
-                       int process = 1;
-                       vector<int> processIDS;
-                       
-                       //loop through and create all the processes you want
-                       while (process != processors) {
-                               int pid = fork();
-                               
-                               if (pid > 0) {
-                                       processIDS.push_back(pid);  
-                                       process++;
-                               }else if (pid == 0){
-                                       driver(lines[process].start, lines[process].num, thisLookup, toString(getpid()));
-                                       exit(0);
-                               }else { 
-                                       m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
-                                       for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
-                                       exit(0);
-                               }
-                       }
-                       
-                       //do my part
-                       driver(lines[0].start, lines[0].num, thisLookup, "");
-                       
-                       //force parent to wait until all the processes are done
-                       for (int i=0;i<(processors-1);i++) { 
-                               int temp = processIDS[i];
-                               wait(&temp);
-                       }
-                       
-                       //append files
-                       for(int i = 0 ; i < calculators.size(); i++) {
-                               string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".anosim";                           
-                               
-                               for (int j = 0; j < processIDS.size(); j++) {
-                                       m->appendFiles((outputFile + toString(processIDS[j])), outputFile);
-                                       remove((outputFile + toString(processIDS[j])).c_str());
-                               }
-                       }
+               vector<vector<double> > rankMatrix = convertToRanks(dMatrix);
+               double RValue = calcR(rankMatrix, groupSampleMap);
+               
+               int pCount = 0;
+               for(int i=0;i<iters;i++){
+                       map<string, vector<int> > randGroupSampleMap = getRandomizedGroups(groupSampleMap);
+                       double RValueRand = calcR(rankMatrix, randGroupSampleMap);
+                       if(RValue <= RValueRand){       pCount++;       }
                }
-#else
-               driver(0, namesOfGroupCombos.size(), thisLookUp, "");
-#endif
+
+               double pValue = (double)pCount / (double) iters;
+               string pString = "";
+               if(pValue < 1/(double)iters){   pString = '<' + toString(1/(double)iters);      }
+               else                                            {       pString = toString(pValue);                                     }
                
-               return 0;
+               
+               map<string, vector<int> >::iterator it=groupSampleMap.begin();
+               m->mothurOut(it->first);
+               ANOSIMFile << it->first;
+               it++;
+               for(it;it!=groupSampleMap.end();it++){
+                       m->mothurOut('-' + it->first);
+                       ANOSIMFile << '-' << it->first;
+               
+               }
+               m->mothurOut('\t' + toString(RValue) + '\t' + pString);
+               ANOSIMFile << '\t' << RValue << '\t' << pString;
+
+               if(pValue < alpha){
+                       ANOSIMFile << "*";
+                       m->mothurOut("*");
+               }
+               ANOSIMFile << endl;
+               m->mothurOutEndLine();
+               
+               return pValue;
        }
        catch(exception& e) {
-               m->errorOut(e, "AnosimCommand", "process");
+               m->errorOut(e, "AnosimCommand", "calcAnisom");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
 
-int AnosimCommand::driver(int start, int num, vector<SharedRAbundVector*> thisLookup, string pidValue) {
+double AnosimCommand::calcR(vector<vector<double> > rankMatrix, map<string, vector<int> > groupSampleMap){
        try {
-               vector<SharedRAbundVector*> subset;
-               EstOutput data;
+
+               int numSamples = 0;
+               for(map<string, vector<int> >::iterator it=groupSampleMap.begin();it!=groupSampleMap.end();it++){
+                       numSamples += it->second.size();
+               }
                
-               //for each calculator
-               for(int i = 0 ; i < calculators.size(); i++) {
-                       
-                       //create a new filename
-                       ofstream out;
-                       string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".anosim" + pidValue;                                
-                       m->openOutputFileAppend(outputFile, out);
-                       out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
-                       cout.setf(ios::fixed, ios::floatfield); cout.setf(ios::showpoint);
-                       
-                       //for each combo
-                       for (int c = start; c < (start+num); c++) {
-                               
-                               if (m->control_pressed) { out.close(); return 0; }
-                               
-                               //get set names
-                               vector<string> setNames;
-                               for (int j = 0; j < namesOfGroupCombos[c].size(); j++) { setNames.push_back(namesOfGroupCombos[c][j]); }
-                               
-                               vector<SharedRAbundVector*> thisCombosLookup;
-                               vector<string> thisCombosLookupSets; //what set each sharedRabund is from to be used when calculating SSWithin
-                               for (int k = 0; k < thisLookup.size(); k++) {
-                                       string thisGroup = thisLookup[k]->getGroup();
-                                       
-                                       //is this group for a set we want to compare??
-                                       if (m->inUsersGroups(designMap->getGroup(thisGroup), setNames)) {  
-                                               thisCombosLookup.push_back(thisLookup[k]);
-                                               thisCombosLookupSets.push_back(designMap->getGroup(thisGroup));
-                                       }
-                                       
-                               }
-                               
-                               int numGroups = thisCombosLookup.size();
-                               
-                               //calc the distance matrix
-                               matrix.clear();
-                               matrix.resize(numGroups);
-                               for (int k = 0; k < matrix.size(); k++) {       for (int j = 0; j < matrix.size(); j++) {       matrix[k].push_back(1.0);       }       }
-                               
-                               if (thisCombosLookup.size() == 0)  { 
-                                       m->mothurOut("[ERROR]: Missing shared info for sets. Skipping comparison."); m->mothurOutEndLine(); 
-                               }else{
-                                       
-                                       out << thisLookup[0]->getLabel() << '\t';
-                                       m->mothurOut(thisLookup[0]->getLabel() + "\t");
-                                       if (setNames.size() == 2) { out << setNames[0] << "-" << setNames[1] << '\t'; m->mothurOut(setNames[0] + "-" + setNames[1] + "\t");  }
-                                       else { out << "all" << '\t'; m->mothurOut("all\t"); }
-                                       
-                                       for (int k = 0; k < thisCombosLookup.size(); k++) { 
-                                               for (int l = k; l < thisCombosLookup.size(); l++) {
-                                                       
-                                                       if (m->control_pressed) { out.close(); return 0; }
-                                                       
-                                                       if (k != l) { //we dont need to similiarity of a groups to itself
-                                                               //get estimated similarity between 2 groups
-                                                               subset.clear(); //clear out old pair of sharedrabunds
-                                                               //add new pair of sharedrabunds
-                                                               subset.push_back(thisCombosLookup[k]); subset.push_back(thisCombosLookup[l]); 
-                                                               
-                                                               //if this calc needs all groups to calculate the pair load all groups
-                                                               if (calculators[i]->getNeedsAll()) { 
-                                                                       //load subset with rest of lookup for those calcs that need everyone to calc for a pair
-                                                                       for (int w = 0; w < thisCombosLookup.size(); w++) {
-                                                                               if ((w != k) && (w != l)) { subset.push_back(thisCombosLookup[w]); }
-                                                                       }
-                                                               }
-                                                               
-                                                               data = calculators[i]->getValues(subset); //saves the calculator outputs
-                                                               
-                                                               //save values in similarity matrix
-                                                               matrix[k][l] = 1.0 - data[0];
-                                                               matrix[l][k] = 1.0 - data[0];
-                                                       }
-                                               }
-                                       }
-                                       
-                                       //calc anosim
-                                       calcAnosim(out, setNames.size(), thisCombosLookupSets);
+               
+               double within = 0.0;
+               int numWithinComps = 0;         
+               
+               for(map<string, vector<int> >::iterator it=groupSampleMap.begin();it!=groupSampleMap.end();it++){
+                       vector<int> indices = it->second;
+                       for(int i=0;i<indices.size();i++){
+                               for(int j=0;j<i;j++){
+                                       if(indices[i] > indices[j])     {       within += rankMatrix[indices[i]][indices[j]];   }
+                                       else                                            {       within += rankMatrix[indices[j]][indices[i]];   }
+                                       numWithinComps++;
                                }
                        }
-                       
-                       out.close();
-               }               
+               }
                
-               return 0;
+               within /= (float) numWithinComps;
                
-       }
-       catch(exception& e) {
-               m->errorOut(e, "AnosimCommand", "driver");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
+               double between = 0.0;
+               int numBetweenComps = 0;
 
-int AnosimCommand::driver(int start, int num, vector<string> names, string pidValue, vector< vector<double> >& completeMatrix) {
-       try {
+               map<string, vector<int> >::iterator itB;
                
-               //create a new filename
-               ofstream out;
-               string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipfile)) + "anosim" + pidValue;                             
-               m->openOutputFileAppend(outputFile, out);
-               out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
-               cout.setf(ios::fixed, ios::floatfield); cout.setf(ios::showpoint);
-               
-               //for each combo
-               for (int c = start; c < (start+num); c++) {
-                       
-                       if (m->control_pressed) { out.close(); return 0; }
-                       
-                       //get set names
-                       vector<string> setNames;
-                       for (int j = 0; j < namesOfGroupCombos[c].size(); j++) { setNames.push_back(namesOfGroupCombos[c][j]); }
-                       
-                       vector<string> thisCombosSets; //what set each line in the distance matrix is from to be used when calculating SSWithin
-                       set<int> indexes;
-                       for (int k = 0; k < names.size(); k++) {
-                               //is this group for a set we want to compare??
-                               if (m->inUsersGroups(designMap->getGroup(names[k]), setNames)) {  
-                                       thisCombosSets.push_back(designMap->getGroup(names[k]));        
-                                       indexes.insert(k); //save indexes of valid rows in matrix for submatrix
-                               }
-                       }
-                       
-                       int numGroups = thisCombosSets.size();
-                       
-                       //calc the distance matrix
-                       matrix.clear();
-                       matrix.resize(numGroups);
-                       
-                       for (int k = 0; k < matrix.size(); k++) {       for (int j = 0; j < matrix.size(); j++) {       matrix[k].push_back(1.0);       }       }
-                       
-                       if (thisCombosSets.size() == 0)  { 
-                               m->mothurOut("[ERROR]: Missing distance info for sets. Skipping comparison."); m->mothurOutEndLine(); 
-                       }else{
-                               
-                               if (setNames.size() == 2) { out << setNames[0] << "-" << setNames[1] << '\t'; m->mothurOut(setNames[0] + "-" + setNames[1] + "\t");  }
-                               else { out << "all" << '\t'; m->mothurOut("all\t"); }
-                               
-                               //fill submatrix
-                               int rowCount = 0;
-                               for (int j = 0; j < completeMatrix.size(); j++) {
-                                       
-                                       if (indexes.count(j) != 0) { //we want at least part of this row
-                                               int columnCount = 0;
-                                               for (int k = 0; k < completeMatrix[j].size(); k++) {
-                                                       
-                                                       if (indexes.count(k) != 0) { //we want this distance
-                                                               matrix[rowCount][columnCount] = completeMatrix[j][k];
-                                                               matrix[columnCount][rowCount] = completeMatrix[j][k];
-                                                               columnCount++;
-                                                       }
-                                               }
-                                               rowCount++;
-                                       }
+               for(map<string, vector<int> >::iterator itA=groupSampleMap.begin();itA!=groupSampleMap.end();itA++){
+
+                       for(int i=0;i<itA->second.size();i++){
+                               int A = itA->second[i];
+                               map<string, vector<int> >::iterator itB = itA;
+                               itB++;
+                               for(itB;itB!=groupSampleMap.end();itB++){
+                                       for(int j=0;j<itB->second.size();j++){
+                                               int B = itB->second[j];
+                                               if(A>B) {       between += rankMatrix[A][B];    }
+                                               else    {       between += rankMatrix[B][A];    }
+                                               numBetweenComps++;
+                                       }                                       
                                }
                                
-                               
-                               //calc anosim
-                               calcAnosim(out, setNames.size(), thisCombosSets);
                        }
                }
                
-               out.close();
                
+               between /= (float) numBetweenComps;
                
-               return 0;
-               
+               double Rvalue = (between - within)/(numSamples * (numSamples-1) / 4.0);
+                               
+               return Rvalue;
        }
        catch(exception& e) {
-               m->errorOut(e, "AnosimCommand", "driver");
+               m->errorOut(e, "AnosimCommand", "calcWithinBetween");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
-int AnosimCommand::calcAnosim(ofstream& out, int numTreatments, vector<string> thisCombosLookupSets) {
+
+vector<vector<double> > AnosimCommand::convertToRanks(vector<vector<double> > dist) {
        try {
-               //rank distances
-               vector<seqDist> rankMatrix = convertToRanks();
-               
-               double meanBetween, meanWithin, RValue, pValue;
+               vector<seqDist> cells;
+               vector<vector<double> > ranks = dist;
                
-               meanWithin = calcWithinBetween(rankMatrix, thisCombosLookupSets, meanBetween);
-               
-               int N = matrix.size();
-               int div = (N * (N-1) / 4);
-       
-               //calc RValue
-               RValue = (meanBetween - meanWithin) / (double) div;
-               
-               //calc Pvalue
-               int count = 0;
-               for (int i = 0; i < iters; i++) {
-                       if (m->control_pressed) { break; }
-                       
-                       //randomly shuffle names to randomize the matrix
-                       vector<string> copyNames = thisCombosLookupSets;
-                       random_shuffle(copyNames.begin(), copyNames.end());
-                       
-                       meanWithin = calcWithinBetween(rankMatrix, copyNames, meanBetween);
-                       
-                       //calc RValue
-                       double randomRValue = (meanBetween - meanWithin) / (double) div;        
-                       
-                       if (randomRValue >= RValue) { count++; }
+               for (int i = 0; i < dist.size(); i++) {
+                       for (int j = 0; j < i; j++) {
+                               if(dist[i][j] != -1){
+                                       seqDist member(i, j, dist[i][j]);
+                                       cells.push_back(member);
+                               }
+                       }
                }
                
-               pValue = count / (float) iters;
-               
-               out << RValue << '\t' << pValue << endl;
-               cout << RValue << '\t' << pValue << endl;
-               m->mothurOutJustToLog(toString(RValue) + "\t" + toString(pValue) + "\n");
                
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "AnosimCommand", "calcAnisom");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-double AnosimCommand::calcWithinBetween(vector<seqDist>& thisMatrix, vector<string> thisCombosLookupSets, double& between) {
-       try {
-               double within = 0.0;
-               int count = 0;
-               int count2 = 0;
-               between = 0.0;
-               
-               for (int l = 0; l < thisMatrix.size(); l++) {
-                       //if you are from the same treatment 
-                       if (thisCombosLookupSets[thisMatrix[l].seq1] == thisCombosLookupSets[thisMatrix[l].seq2]) { 
-                               within += thisMatrix[l].dist; //rank of this distance
-                               count++;
-                       }else { //different treatments
-                               between += thisMatrix[l].dist; //rank of this distance
-                               count2++;
+               //sort distances
+               sort(cells.begin(), cells.end(), compareSequenceDistance);      
+
+               //find ranks of distances
+               int index = 0;
+               int indexSum = 0;
+               for(int i=0;i<cells.size()-1;i++){
+
+                       index = i;
+                       indexSum = i + 1;
+                       while(dist[cells[index].seq1][cells[index].seq2] == dist[cells[index+1].seq1][cells[index+1].seq2]){
+                               index++;                                
+                               indexSum += index + 1;
+                       }
+                       
+                       if(index == i){
+                               ranks[cells[i].seq1][cells[i].seq2] = i+1;
+                       }
+                       else{
+                               double aveIndex = (double)indexSum / (double)(index - i + 1);
+                               for(int j=i;j<=index;j++){
+                                       ranks[cells[j].seq1][cells[j].seq2] = aveIndex;
+                               }                                       
+                               i = index;
                        }
                }
                
-               within /= (float) count;
-               between /= (float) count2;
-               
-               return within;
+               if(indexSum == cells.size() - 1){
+                       ranks[cells[cells.size()-1].seq1][cells[cells.size()-1].seq2] = indexSum + 1;
+               }
+
+               return ranks;
        }
        catch(exception& e) {
-               m->errorOut(e, "AnosimCommand", "calcWithinBetween");
+               m->errorOut(e, "AnosimCommand", "convertToRanks");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
-vector<seqDist> AnosimCommand::convertToRanks() {
-       try {
-               vector<seqDist> ranks;
-               
-               for (int i = 0; i < matrix.size(); i++) {
-                       for (int j = 0; j < i; j++) {
-                               seqDist member(i, j, matrix[i][j]);
-                               ranks.push_back(member);
-                       }
+
+map<string, vector<int> > AnosimCommand::getRandomizedGroups(map<string, vector<int> > origMapping){
+       try{
+               vector<int> sampleIndices;
+               vector<int> samplesPerGroup;
+               
+               map<string, vector<int> >::iterator it;
+               for(it=origMapping.begin();it!=origMapping.end();it++){
+                       vector<int> indices = it->second;
+                       samplesPerGroup.push_back(indices.size());
+                       sampleIndices.insert(sampleIndices.end(), indices.begin(), indices.end());
                }
                
-               //sort distances
-               sort(ranks.begin(), ranks.end(), compareSequenceDistance);      
+               random_shuffle(sampleIndices.begin(), sampleIndices.end());
                
-               //find ranks of distances
-               vector<seqDist*> ties;
-               int rankTotal = 0;
-               for (int j = 0; j < ranks.size(); j++) {
-                       rankTotal += (j+1);
-                       ties.push_back(&ranks[j]);
-                       
-                       if (j != (ranks.size()-1)) { // you are not the last so you can look ahead
-                               if (ranks[j].dist != ranks[j+1].dist) { // you are done with ties, rank them and continue
-                                       
-                                       for (int k = 0; k < ties.size(); k++) {
-                                               float thisrank = rankTotal / (float) ties.size();
-                                               (*ties[k]).dist = thisrank;
-                                       }
-                                       ties.clear();
-                                       rankTotal = 0;
-                               }
-                       }else { // you are the last one
-                               
-                               for (int k = 0; k < ties.size(); k++) {
-                                       float thisrank = rankTotal / (float) ties.size();
-                                       (*ties[k]).dist = thisrank;
-                               }
+               int index = 0;
+               map<string, vector<int> > randomizedGroups = origMapping;
+               for(it=randomizedGroups.begin();it!=randomizedGroups.end();it++){
+                       for(int i=0;i<it->second.size();i++){
+                               it->second[i] = sampleIndices[index++];                         
                        }
                }
                
-               return ranks;
+               return randomizedGroups;                
        }
-       catch(exception& e) {
-               m->errorOut(e, "AnosimCommand", "convertToRanks");
+       catch (exception& e) {
+               m->errorOut(e, "AnosimCommand", "randomizeGroups");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
 
 
index 0b145639d8b0f8551988e67d29ee4a2612efa809..ab724007237d508e1b2dabf1bba521c5c38f7497 100644 (file)
 
 
 #include "command.hpp"
-#include "inputdata.h"
-#include "sharedrabundvector.h"
-#include "validcalculator.h"
-#include "readphylipvector.h"
 
-class GlobalData;
+class GroupMap;
 
 class AnosimCommand : public Command {
        
@@ -33,32 +29,23 @@ public:
        void help();
        
 private:
-       struct linePair {
-               int start;
-               int num;
-               linePair(int i, int j) : start(i), num(j) {}
-       };
-       vector<linePair> lines;
-       
-       GlobalData* globaldata;
+       bool abort;
        GroupMap* designMap;
        map<string, vector<string> > outputTypes;
+       string outputDir, inputDir, designFileName, phylipFileName;
+       
+       vector<vector<double> > convertToRanks(vector<vector<double> >);
+       double calcR(vector<vector<double> >, map<string, vector<int> >);
+       map<string, vector<int> > getRandomizedGroups(map<string, vector<int> >);
+       double runANOSIM(ofstream&, vector<vector<double> >, map<string, vector<int> >, double);
        
-       vector< vector<double> > matrix;
-       bool abort, allLines, pickedGroups;
-       set<string> labels; //holds labels to be used
-       string format, groups, label, outputDir, inputDir, designfile, sets, phylipfile, calc, sharedfile;
-       vector<string> Groups, outputNames, Sets;
+       vector< vector<double> > distanceMatrix;
+       vector<string> outputNames;
+       int iters;
+       double experimentwiseAlpha;
        vector< vector<string> > namesOfGroupCombos;
-       int iters, processors;
-       vector<Calculator*> calculators;
        
-       int driver(int, int, vector<SharedRAbundVector*>, string);
-       int driver(int, int, vector<string>, string, vector< vector<double> >&);
-       int process(vector<SharedRAbundVector*>);
-       int calcAnosim(ofstream&, int, vector<string>);
-       double calcWithinBetween(vector<seqDist>&, vector<string>, double&);
-       vector<seqDist> convertToRanks();
+       
 };
 
 #endif
index 28f560f75ccd2b56613b0a79253dc1f462f20194..52456b4ddedcd7b1db62a4fa8d03c5082eedf932 100644 (file)
@@ -8,53 +8,14 @@
  */
 
 #include "homovacommand.h"
-#include "sharedutilities.h"
-#include "sharedsobscollectsummary.h"
-#include "sharedchao1.h"
-#include "sharedace.h"
-#include "sharednseqs.h"
-#include "sharedjabund.h"
-#include "sharedsorabund.h"
-#include "sharedjclass.h"
-#include "sharedsorclass.h"
-#include "sharedjest.h"
-#include "sharedsorest.h"
-#include "sharedthetayc.h"
-#include "sharedthetan.h"
-#include "sharedkstest.h"
-#include "whittaker.h"
-#include "sharedochiai.h"
-#include "sharedanderbergs.h"
-#include "sharedkulczynski.h"
-#include "sharedkulczynskicody.h"
-#include "sharedlennon.h"
-#include "sharedmorisitahorn.h"
-#include "sharedbraycurtis.h"
-#include "sharedjackknife.h"
-#include "whittaker.h"
-#include "odum.h"
-#include "canberra.h"
-#include "structeuclidean.h"
-#include "structchord.h"
-#include "hellinger.h"
-#include "manhattan.h"
-#include "structpearson.h"
-#include "soergel.h"
-#include "spearman.h"
-#include "structkulczynski.h"
-#include "structchi2.h"
-#include "speciesprofile.h"
-#include "hamming.h"
-#include "gower.h"
-#include "memchi2.h"
-#include "memchord.h"
-#include "memeuclidean.h"
-#include "mempearson.h"
+#include "groupmap.h"
+#include "readphylipvector.h"
 
 //**********************************************************************************************************************
+
 vector<string> HomovaCommand::getValidParameters(){    
        try {
-               string Array[] =  {"groups","label","outputdir","iters","phylip","design","sets","processors","inputdir"};
+               string Array[] =  {"outputdir","iters","phylip","design","alpha", "inputdir"};
                vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
                return myArray;
        }
@@ -63,7 +24,9 @@ vector<string> HomovaCommand::getValidParameters(){
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
+
 HomovaCommand::HomovaCommand(){        
        try {
                abort = true; calledHelp = true; 
@@ -75,7 +38,9 @@ HomovaCommand::HomovaCommand(){
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
+
 vector<string> HomovaCommand::getRequiredParameters(){ 
        try {
                string Array[] =  {"design"};
@@ -87,7 +52,9 @@ vector<string> HomovaCommand::getRequiredParameters(){
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
+
 vector<string> HomovaCommand::getRequiredFiles(){      
        try {
                string Array[] =  {};
@@ -99,21 +66,19 @@ vector<string> HomovaCommand::getRequiredFiles(){
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
 
 HomovaCommand::HomovaCommand(string option) {
        try {
-               globaldata = GlobalData::getInstance();
                abort = false; calledHelp = false;   
-               allLines = 1;
-               labels.clear();
                
                //allow user to run help
                if(option == "help") { help(); abort = true; calledHelp = true; }
                
                else {
                        //valid paramters for this command
-                       string AlignArray[] =  {"groups","label","outputdir","iters","phylip","design","sets","processors","inputdir"};
+                       string AlignArray[] =  {"design","outputdir","iters","phylip","alpha", "inputdir"};
                        vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
                        
                        OptionParser parser(option);
@@ -156,155 +121,33 @@ HomovaCommand::HomovaCommand(string option) {
                                }
                        }
                        
-                       phylipfile = validParameter.validFile(parameters, "phylip", true);
-                       if (phylipfile == "not open") { phylipfile = ""; abort = true; }
-                       else if (phylipfile == "not found") { phylipfile = ""; }        
-                       else {  globaldata->newRead(); format = "phylip";  globaldata->setPhylipFile(phylipfile);       }
+                       phylipFileName = validParameter.validFile(parameters, "phylip", true);
+                       if (phylipFileName == "not open") { phylipFileName = ""; abort = true; }
+                       else if (phylipFileName == "not found") { phylipFileName = ""; }        
+                       else if (designFileName == "not found") {
+                               designFileName = "";
+                               m->mothurOut("You must provide an phylip file.");
+                               m->mothurOutEndLine();
+                               abort = true;
+                       }       
                        
                        //check for required parameters
-                       designfile = validParameter.validFile(parameters, "design", true);
-                       if (designfile == "not open") { abort = true; }
-                       else if (designfile == "not found") {  designfile = "";  m->mothurOut("You must provide an design file."); m->mothurOutEndLine(); abort = true; }       
-                       
-                       //make sure the user has already run the read.otu command
-                       if ((globaldata->getSharedFile() == "")) {
-                               if ((phylipfile == "")) {
-                                       m->mothurOut("You must read a list and a group, a shared file or provide a distance matrix before you can use the homova command."); m->mothurOutEndLine(); abort = true; 
-                               }
-                       }else { sharedfile = globaldata->getSharedFile(); } 
-                       
-                       //use distance matrix if one is provided
-                       if ((sharedfile != "") && (phylipfile != "")) { sharedfile = ""; }
-                       
-                       //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") {  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 { 
-                               m->splitAtDash(groups, Groups);
-                               globaldata->Groups = Groups;
-                       }
-                       
-                       sets = validParameter.validFile(parameters, "sets", false);                     
-                       if (sets == "not found") { sets = ""; pickedGroups = false; }
-                       else { 
-                               pickedGroups = true;
-                               m->splitAtDash(sets, Sets);
-                       }
-                       
-                       
-                       string temp = validParameter.validFile(parameters, "iters", false);                     if (temp == "not found") { temp = "1000"; }
+                       designFileName = validParameter.validFile(parameters, "design", true);
+                       if (designFileName == "not open") { abort = true; }
+                       else if (designFileName == "not found") {
+                               designFileName = "";
+                               m->mothurOut("You must provide an design file.");
+                               m->mothurOutEndLine();
+                               abort = true;
+                       }       
+                       
+                       string temp = validParameter.validFile(parameters, "iters", false);
+                       if (temp == "not found") { temp = "1000"; }
                        convert(temp, iters); 
                        
-                       temp = validParameter.validFile(parameters, "processors", false);                       if (temp == "not found"){       temp = "1";     }
-                       convert(temp, processors); 
-                       
-                       vector<string> Estimators;
-                       calc = validParameter.validFile(parameters, "calc", false);                     
-                       if (calc == "not found") { calc = "morisitahorn";  }
-                       m->splitAtDash(calc, Estimators);
-                       
-                       if (abort == false) {
-                               
-                               ValidCalculators* validCalculator = new ValidCalculators();
-                               
-                               for (int i=0; i<Estimators.size(); i++) {
-                                       if (validCalculator->isValidCalculator("treegroup", Estimators[i]) == true) { 
-                                               if (Estimators[i] == "sharedsobs") { 
-                                                       calculators.push_back(new SharedSobsCS());
-                                               }else if (Estimators[i] == "sharedchao") { 
-                                                       calculators.push_back(new SharedChao1());
-                                               }else if (Estimators[i] == "sharedace") { 
-                                                       calculators.push_back(new SharedAce());
-                                               }else if (Estimators[i] == "jabund") {  
-                                                       calculators.push_back(new JAbund());
-                                               }else if (Estimators[i] == "sorabund") { 
-                                                       calculators.push_back(new SorAbund());
-                                               }else if (Estimators[i] == "jclass") { 
-                                                       calculators.push_back(new Jclass());
-                                               }else if (Estimators[i] == "sorclass") { 
-                                                       calculators.push_back(new SorClass());
-                                               }else if (Estimators[i] == "jest") { 
-                                                       calculators.push_back(new Jest());
-                                               }else if (Estimators[i] == "sorest") { 
-                                                       calculators.push_back(new SorEst());
-                                               }else if (Estimators[i] == "thetayc") { 
-                                                       calculators.push_back(new ThetaYC());
-                                               }else if (Estimators[i] == "thetan") { 
-                                                       calculators.push_back(new ThetaN());
-                                               }else if (Estimators[i] == "kstest") { 
-                                                       calculators.push_back(new KSTest());
-                                               }else if (Estimators[i] == "sharednseqs") { 
-                                                       calculators.push_back(new SharedNSeqs());
-                                               }else if (Estimators[i] == "ochiai") { 
-                                                       calculators.push_back(new Ochiai());
-                                               }else if (Estimators[i] == "anderberg") { 
-                                                       calculators.push_back(new Anderberg());
-                                               }else if (Estimators[i] == "kulczynski") { 
-                                                       calculators.push_back(new Kulczynski());
-                                               }else if (Estimators[i] == "kulczynskicody") { 
-                                                       calculators.push_back(new KulczynskiCody());
-                                               }else if (Estimators[i] == "lennon") { 
-                                                       calculators.push_back(new Lennon());
-                                               }else if (Estimators[i] == "morisitahorn") { 
-                                                       calculators.push_back(new MorHorn());
-                                               }else if (Estimators[i] == "braycurtis") { 
-                                                       calculators.push_back(new BrayCurtis());
-                                               }else if (Estimators[i] == "whittaker") { 
-                                                       calculators.push_back(new Whittaker());
-                                               }else if (Estimators[i] == "odum") { 
-                                                       calculators.push_back(new Odum());
-                                               }else if (Estimators[i] == "canberra") { 
-                                                       calculators.push_back(new Canberra());
-                                               }else if (Estimators[i] == "structeuclidean") { 
-                                                       calculators.push_back(new StructEuclidean());
-                                               }else if (Estimators[i] == "structchord") { 
-                                                       calculators.push_back(new StructChord());
-                                               }else if (Estimators[i] == "hellinger") { 
-                                                       calculators.push_back(new Hellinger());
-                                               }else if (Estimators[i] == "manhattan") { 
-                                                       calculators.push_back(new Manhattan());
-                                               }else if (Estimators[i] == "structpearson") { 
-                                                       calculators.push_back(new StructPearson());
-                                               }else if (Estimators[i] == "soergel") { 
-                                                       calculators.push_back(new Soergel());
-                                               }else if (Estimators[i] == "spearman") { 
-                                                       calculators.push_back(new Spearman());
-                                               }else if (Estimators[i] == "structkulczynski") { 
-                                                       calculators.push_back(new StructKulczynski());
-                                               }else if (Estimators[i] == "speciesprofile") { 
-                                                       calculators.push_back(new SpeciesProfile());
-                                               }else if (Estimators[i] == "hamming") { 
-                                                       calculators.push_back(new Hamming());
-                                               }else if (Estimators[i] == "structchi2") { 
-                                                       calculators.push_back(new StructChi2());
-                                               }else if (Estimators[i] == "gower") { 
-                                                       calculators.push_back(new Gower());
-                                               }else if (Estimators[i] == "memchi2") { 
-                                                       calculators.push_back(new MemChi2());
-                                               }else if (Estimators[i] == "memchord") { 
-                                                       calculators.push_back(new MemChord());
-                                               }else if (Estimators[i] == "memeuclidean") { 
-                                                       calculators.push_back(new MemEuclidean());
-                                               }else if (Estimators[i] == "mempearson") { 
-                                                       calculators.push_back(new MemPearson());
-                                               }
-                                       }
-                               }
-                       }
+                       temp = validParameter.validFile(parameters, "alpha", false);
+                       if (temp == "not found") { temp = "0.05"; }
+                       convert(temp, experimentwiseAlpha); 
                }
                
        }
@@ -319,20 +162,13 @@ HomovaCommand::HomovaCommand(string option) {
 void HomovaCommand::help(){
        try {
                m->mothurOut("Referenced: Stewart CN, Excoffier L (1996). Assessing population genetic structure and variability with RAPD data: Application to Vaccinium macrocarpon (American Cranberry). J Evol Biol 9: 153-71.\n");
-               m->mothurOut("The homova command can only be executed after a successful read.otu command of a list and group or shared file, or by providing a phylip formatted distance matrix.\n");
                m->mothurOut("The homova command outputs a .homova file. \n");
-               m->mothurOut("The homova command parameters are phylip, iters, groups, label, design, sets and processors.  The design parameter is required.\n");
-               m->mothurOut("The design parameter allows you to assign your groups to sets when you are running homova. 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 group name and the second column is the set the group belongs to.\n");
-               m->mothurOut("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. To run the pairwise comparisons of all sets use sets=all.\n");
+               m->mothurOut("The homova 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 homova. 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 groups parameter allows you to specify which of the groups you would like included. The group names are separated by dashes. groups=all will find all pairwise comparisons. \n");
-               m->mothurOut("The label parameter allows you to select what distance levels you would like, and are also separated by dashes.\n");
-               m->mothurOut("The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n");
-               m->mothurOut("The homova command should be in the following format: homova(design=yourDesignFile).\n");
-               m->mothurOut("Example amova(design=temp.design, groups=A-B-C).\n");
-               m->mothurOut("Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n\n");
-               
+               m->mothurOut("The homova command should be in the following format: homova(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, "HomovaCommand", "help");
@@ -352,220 +188,71 @@ int HomovaCommand::execute(){
                if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
                
                //read design file
-               designMap = new GroupMap(designfile);
+               designMap = new GroupMap(designFileName);
                designMap->readDesignMap();
                
-               //make sure sets are all in designMap
-               SharedUtil* util = new SharedUtil();  
-               util->setGroups(Sets, designMap->namesOfGroups);  
-               delete util;
-               
-               //if the user pickedGroups or set sets=all, then we want to figure out how to split the pairwise comparison between processors
-               int numGroups = Sets.size();
-               if (pickedGroups) {
-                       for (int a=0; a<numGroups; a++) { 
-                               for (int l = 0; l < a; l++) {   
-                                       vector<string> groups; groups.push_back(Sets[a]); groups.push_back(Sets[l]);
-                                       namesOfGroupCombos.push_back(groups);
-                               }
-                       }
-               }else { //one giant compare
-                       vector<string> groups;
-                       for (int a=0; a<numGroups; a++) { groups.push_back(Sets[a]); }
-                       namesOfGroupCombos.push_back(groups);
-               }
+               if (outputDir == "") { outputDir = m->hasPath(phylipFileName); }
                
-               //only 1 combo
-               if (numGroups == 2) { processors = 1; }
-               else if (numGroups < 2) { m->mothurOut("Not enough sets, I need at least 2 valid sets. Unable to complete command."); m->mothurOutEndLine(); m->control_pressed = true; }
+               //read in distance matrix and square it
+               ReadPhylipVector readMatrix(phylipFileName);
+               vector<string> sampleNames = readMatrix.read(distanceMatrix);
                
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-               if(processors != 1){
-                       int numPairs = namesOfGroupCombos.size();
-                       int numPairsPerProcessor = numPairs / processors;
-                       
-                       for (int i = 0; i < processors; i++) {
-                               int startPos = i * numPairsPerProcessor;
-                               if(i == processors - 1){
-                                       numPairsPerProcessor = numPairs - i * numPairsPerProcessor;
-                               }
-                               lines.push_back(linePair(startPos, numPairsPerProcessor));
+               for(int i=0;i<distanceMatrix.size();i++){
+                       for(int j=0;j<i;j++){
+                               distanceMatrix[i][j] *= distanceMatrix[i][j];   
                        }
                }
-#endif
                
-               if (sharedfile != "") { //create distance matrix for each label
-                       
-                       if (outputDir == "") { outputDir = m->hasPath(sharedfile); }
-                       
-                       //for each calculator
-                       for(int i = 0 ; i < calculators.size(); i++) {
-                               
-                               //create a new filename
-                               ofstream out;
-                               string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".homova";                           
-                               m->openOutputFile(outputFile, out);
-                               outputNames.push_back(outputFile); outputTypes["homova"].push_back(outputFile);
-                               
-                               //print headers
-                               out << "label\tgroupsCompared\tBValue\tpValue" << endl;  
-                               out.close();
-                       }
-                       
-                       InputData input(sharedfile, "sharedfile");
-                       vector<SharedRAbundVector*> lookup = input.getSharedRAbundVectors();
-                       string lastLabel = lookup[0]->getLabel();
+               //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);
+               }
+               int numGroups = origGroupSampleMap.size();
+               
+               //create a new filename
+               ofstream HOMOVAFile;
+               string HOMOVAFileName = outputDir + m->getRootName(m->getSimpleName(phylipFileName))  + "homova";                               
+               m->openOutputFile(HOMOVAFileName, HOMOVAFile);
+               outputNames.push_back(HOMOVAFileName); outputTypes["homova"].push_back(HOMOVAFileName);
+               
+               HOMOVAFile << "HOMOVA\tBValue\tP-value\tSSwithin_values" << endl;
+               m->mothurOut("HOMOVA\tBValue\tP-value\tSSwithin_values\n");
+               
+               double fullHOMOVAPValue = runHOMOVA(HOMOVAFile, origGroupSampleMap, experimentwiseAlpha);
+
+               if(fullHOMOVAPValue <= experimentwiseAlpha && numGroups > 2){
                        
-                       //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;
+                       int numCombos = numGroups * (numGroups-1) / 2;
+                       double pairwiseAlpha = experimentwiseAlpha / (double) numCombos;
                        
-                       //sanity check between shared file groups and design file groups
-                       for (int i = 0; i < lookup.size(); i++) { 
-                               string group = designMap->getGroup(lookup[i]->getGroup());
-                               
-                               if (group == "not found") { m->control_pressed = true;  m->mothurOut("[ERROR]: " + lookup[i]->getGroup() + " is not in your design file, please correct."); m->mothurOutEndLine();  }
-                       }
+                       map<string, vector<int> >::iterator itA;
+                       map<string, vector<int> >::iterator itB;
                        
-                       //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 < lookup.size(); i++) {  delete lookup[i];  } globaldata->Groups.clear();  delete designMap;  for (int i = 0; i < outputNames.size(); i++) {       remove(outputNames[i].c_str()); } return 0; }
-                               
-                               if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
+                       for(itA=origGroupSampleMap.begin();itA!=origGroupSampleMap.end();itA++){
+                               itB = itA;itB++;
+                               for(itB;itB!=origGroupSampleMap.end();itB++){
                                        
-                                       m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-                                       process(lookup);
+                                       map<string, vector<int> > pairwiseGroupSampleMap;
+                                       pairwiseGroupSampleMap[itA->first] = itA->second;
+                                       pairwiseGroupSampleMap[itB->first] = itB->second;
                                        
-                                       processedLabels.insert(lookup[0]->getLabel());
-                                       userLabels.erase(lookup[0]->getLabel());
-                               }
-                               
-                               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];  }  
-                                       lookup = input.getSharedRAbundVectors(lastLabel);
-                                       m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-                                       
-                                       process(lookup);
-                                       
-                                       processedLabels.insert(lookup[0]->getLabel());
-                                       userLabels.erase(lookup[0]->getLabel());
-                                       
-                                       //restore real lastlabel to save below
-                                       lookup[0]->setLabel(saveLabel);
-                               }
-                               
-                               lastLabel = lookup[0]->getLabel();
-                               //prevent memory leak
-                               for (int i = 0; i < lookup.size(); i++) {  delete lookup[i]; lookup[i] = NULL; }
-                               
-                               if (m->control_pressed) {  globaldata->Groups.clear();   delete designMap;  for (int i = 0; i < outputNames.size(); i++) {      remove(outputNames[i].c_str()); } return 0; }
-                               
-                               //get next line to process
-                               lookup = input.getSharedRAbundVectors();                                
-                       }
-                       
-                       if (m->control_pressed) { globaldata->Groups.clear();  delete designMap;  for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); }  return 0; }
-                       
-                       //output error messages about any remaining user labels
-                       set<string>::iterator it;
-                       bool needToRun = false;
-                       for (it = userLabels.begin(); it != userLabels.end(); it++) {  
-                               m->mothurOut("Your file does not include the label " + *it); 
-                               if (processedLabels.count(lastLabel) != 1) {
-                                       m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
-                                       needToRun = true;
-                               }else {
-                                       m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
-                               }
-                       }
-                       
-                       //run last label if you need to
-                       if (needToRun == true)  {
-                               for (int i = 0; i < lookup.size(); i++) { if (lookup[i] != NULL) { delete lookup[i]; } }  
-                               lookup = input.getSharedRAbundVectors(lastLabel);
-                               
-                               m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
-                               
-                               process(lookup);
-                               
-                               for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
-                       }
-                       
-                       //reset groups parameter
-                       globaldata->Groups.clear();  
-                       
-                       
-               }else { //user provided distance matrix
-                       
-                       if (outputDir == "") { outputDir = m->hasPath(phylipfile); }
-                       
-                       //create a new filename
-                       ofstream out;
-                       string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipfile))  + "homova";                               
-                       m->openOutputFile(outputFile, out);
-                       outputNames.push_back(outputFile); outputTypes["homova"].push_back(outputFile);
-                       
-                       //print headers
-                       out << "groupsCompared\tBValue\tpValue" << endl;  
-                       out.close();
-                       
-                       ReadPhylipVector readMatrix(phylipfile);
-                       vector< vector<double> > completeMatrix;
-                       vector<string> names = readMatrix.read(completeMatrix);
-                       
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-                       if(processors == 1){
-                               driver(0, namesOfGroupCombos.size(), names, "", completeMatrix);
-                       }else{
-                               int process = 1;
-                               vector<int> processIDS;
-                               
-                               //loop through and create all the processes you want
-                               while (process != processors) {
-                                       int pid = fork();
-                                       
-                                       if (pid > 0) {
-                                               processIDS.push_back(pid);  
-                                               process++;
-                                       }else if (pid == 0){
-                                               driver(lines[process].start, lines[process].num, names, toString(getpid()), completeMatrix);
-                                               exit(0);
-                                       }else { 
-                                               m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
-                                               for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
-                                               exit(0);
-                                       }
-                               }
-                               
-                               //do my part
-                               driver(lines[0].start, lines[0].num, names, "", completeMatrix);
-                               
-                               //force parent to wait until all the processes are done
-                               for (int i=0;i<(processors-1);i++) { 
-                                       int temp = processIDS[i];
-                                       wait(&temp);
-                               }
-                               
-                               //append files
-                               string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipfile)) + "homova";                                
-                               for (int j = 0; j < processIDS.size(); j++) {
-                                       m->appendFiles((outputFile + toString(processIDS[j])), outputFile);
-                                       remove((outputFile + toString(processIDS[j])).c_str());
-                               }
-                               
+                                       runHOMOVA(HOMOVAFile, pairwiseGroupSampleMap, pairwiseAlpha);
+                               }                       
                        }
-#else
-                       driver(0, namesOfGroupCombos.size(), names, "", completeMatrix);
-#endif
+                       HOMOVAFile << endl;
+                       m->mothurOutEndLine();
                        
+                       m->mothurOut("Experiment-wise error rate: " + toString(experimentwiseAlpha) + '\n');
+                       m->mothurOut("Pair-wise error rate (Bonferroni): " + toString(pairwiseAlpha) + '\n');
+               }
+               else{
+                       m->mothurOut("Experiment-wise error rate: " + toString(experimentwiseAlpha) + '\n');
                }
                
-               delete designMap;
+               m->mothurOut("If you have borderline P-values, you should try increasing the number of iterations\n");
                
-               if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); } return 0; }
+               delete designMap;
                
                m->mothurOutEndLine();
                m->mothurOut("Output File Names: "); m->mothurOutEndLine();
@@ -579,384 +266,167 @@ int HomovaCommand::execute(){
                exit(1);
        }
 }
-//**********************************************************************************************************************
 
-int HomovaCommand::process(vector<SharedRAbundVector*> thisLookup) {
-       try{
-               
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-               if(processors == 1){
-                       driver(0, namesOfGroupCombos.size(), thisLookup, "");
-               }else{
-                       int process = 1;
-                       vector<int> processIDS;
-                       
-                       //loop through and create all the processes you want
-                       while (process != processors) {
-                               int pid = fork();
-                               
-                               if (pid > 0) {
-                                       processIDS.push_back(pid);  
-                                       process++;
-                               }else if (pid == 0){
-                                       driver(lines[process].start, lines[process].num, thisLookup, toString(getpid()));
-                                       exit(0);
-                               }else { 
-                                       m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
-                                       for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
-                                       exit(0);
-                               }
-                       }
-                       
-                       //do my part
-                       driver(lines[0].start, lines[0].num, thisLookup, "");
-                       
-                       //force parent to wait until all the processes are done
-                       for (int i=0;i<(processors-1);i++) { 
-                               int temp = processIDS[i];
-                               wait(&temp);
-                       }
-                       
-                       //append files
-                       for(int i = 0 ; i < calculators.size(); i++) {
-                               string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".homova";                           
-                               
-                               for (int j = 0; j < processIDS.size(); j++) {
-                                       m->appendFiles((outputFile + toString(processIDS[j])), outputFile);
-                                       remove((outputFile + toString(processIDS[j])).c_str());
-                               }
-                       }
-               }
-#else
-               driver(0, namesOfGroupCombos.size(), thisLookUp, "");
-#endif
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "HomovaCommand", "process");
-               exit(1);
-       }
-}
 //**********************************************************************************************************************
 
-int HomovaCommand::driver(int start, int num, vector<SharedRAbundVector*> thisLookup, string pidValue) {
+double HomovaCommand::runHOMOVA(ofstream& HOMOVAFile, map<string, vector<int> > groupSampleMap, double alpha){
        try {
-               vector<SharedRAbundVector*> subset;
-               EstOutput data;
+               map<string, vector<int> >::iterator it;
+               int numGroups = groupSampleMap.size();
+               
+               vector<double> ssWithinOrigVector;
+               double bValueOrig = calcBValue(groupSampleMap, ssWithinOrigVector);
+               
+               double counter = 0;
+               for(int i=0;i<iters;i++){
+                       vector<double> ssWithinRandVector;
+                       map<string, vector<int> > randomizedGroup = getRandomizedGroups(groupSampleMap);
+                       double bValueRand = calcBValue(randomizedGroup, ssWithinRandVector);
+                       if(bValueRand > bValueOrig){    counter++;      }
+               }
                
-               //for each calculator
-               for(int i = 0 ; i < calculators.size(); i++) {
-                       
-                       //create a new filename
-                       ofstream out;
-                       string outputFile = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + calculators[i]->getName() + ".homova" + pidValue;                                
-                       m->openOutputFileAppend(outputFile, out);
-                       out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
-                       
-                       //for each combo
-                       for (int c = start; c < (start+num); c++) {
-                               
-                               if (m->control_pressed) { out.close(); return 0; }
-                               
-                               //get set names
-                               vector<string> setNames;
-                               for (int j = 0; j < namesOfGroupCombos[c].size(); j++) { setNames.push_back(namesOfGroupCombos[c][j]); }
-                               
-                               vector<SharedRAbundVector*> thisCombosLookup;
-                               vector<string> thisCombosLookupSets; //what set each sharedRabund is from to be used when calculating SSWithin
-                               for (int k = 0; k < thisLookup.size(); k++) {
-                                       string thisGroup = thisLookup[k]->getGroup();
-                                       
-                                       //is this group for a set we want to compare??
-                                       if (m->inUsersGroups(designMap->getGroup(thisGroup), setNames)) {  
-                                               thisCombosLookup.push_back(thisLookup[k]);
-                                               thisCombosLookupSets.push_back(designMap->getGroup(thisGroup));
-                                       }
-                                       
-                               }
-                               
-                               int numGroups = thisCombosLookup.size();
-                               
-                               //calc the distance matrix
-                               matrix.clear();
-                               matrix.resize(numGroups);
-                               for (int k = 0; k < matrix.size(); k++) {       for (int j = 0; j < matrix.size(); j++) {       matrix[k].push_back(1.0);       }       }
-                               
-                               if (thisCombosLookup.size() == 0)  { 
-                                       m->mothurOut("[ERROR]: Missing shared info for sets. Skipping comparison."); m->mothurOutEndLine(); 
-                               }else{
-                                       
-                                       out << thisLookup[0]->getLabel() << '\t';
-                                       if (setNames.size() == 2) { out << setNames[0] << "-" << setNames[1] << '\t'; }
-                                       else { out << "all" << '\t'; }
-                                       
-                                       for (int k = 0; k < thisCombosLookup.size(); k++) { 
-                                               for (int l = k; l < thisCombosLookup.size(); l++) {
-                                                       
-                                                       if (m->control_pressed) { out.close(); return 0; }
-                                                       
-                                                       if (k != l) { //we dont need to similiarity of a groups to itself
-                                                               //get estimated similarity between 2 groups
-                                                               subset.clear(); //clear out old pair of sharedrabunds
-                                                               //add new pair of sharedrabunds
-                                                               subset.push_back(thisCombosLookup[k]); subset.push_back(thisCombosLookup[l]); 
-                                                               
-                                                               //if this calc needs all groups to calculate the pair load all groups
-                                                               if (calculators[i]->getNeedsAll()) { 
-                                                                       //load subset with rest of lookup for those calcs that need everyone to calc for a pair
-                                                                       for (int w = 0; w < thisCombosLookup.size(); w++) {
-                                                                               if ((w != k) && (w != l)) { subset.push_back(thisCombosLookup[w]); }
-                                                                       }
-                                                               }
-                                                               
-                                                               data = calculators[i]->getValues(subset); //saves the calculator outputs
-                                                               
-                                                               //save values in similarity matrix
-                                                               matrix[k][l] = 1.0 - data[0];
-                                                               matrix[l][k] = 1.0 - data[0];
-                                                       }
-                                               }
-                                       }
-                                       
-                                       //calc homova
-                                       calcHomova(out, setNames.size(), thisCombosLookupSets);
-                               }
-                       }
-                       
-                       out.close();
-               }               
+               double pValue = (double) counter / (double) iters;
+               string pString = "";
+               if(pValue < 1/(double)iters){   pString = '<' + toString(1/(double)iters);      }
+               else                                            {       pString = toString(pValue);                                     }
                
-               return 0;
                
+               //print homova table
+               it = groupSampleMap.begin();
+               HOMOVAFile << it->first;
+               m->mothurOut(it->first);
+               it++;
+               for(it;it!=groupSampleMap.end();it++){
+                       HOMOVAFile << '-' << it->first;
+                       m->mothurOut('-' + it->first);
+               }
+
+               HOMOVAFile << '\t' << bValueOrig << '\t' << pString;
+               m->mothurOut('\t' + toString(bValueOrig) + '\t' + pString);
+               
+               if(pValue < alpha){
+                       HOMOVAFile << "*";
+                       m->mothurOut("*");
+               }
+
+               for(int i=0;i<numGroups;i++){
+                       HOMOVAFile << '\t' << ssWithinOrigVector[i];
+                       m->mothurOut('\t' + toString(ssWithinOrigVector[i]));
+               }
+               HOMOVAFile << endl;
+               m->mothurOutEndLine();
+               
+               return pValue;  
        }
        catch(exception& e) {
-               m->errorOut(e, "HomovaCommand", "driver");
+               m->errorOut(e, "HomovaCommand", "runHOMOVA");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
 
-int HomovaCommand::driver(int start, int num, vector<string> names, string pidValue, vector< vector<double> >& completeMatrix) {
+double HomovaCommand::calcSigleSSWithin(vector<int> sampleIndices) {
        try {
+               double ssWithin = 0.0;
+               int numSamplesInGroup = sampleIndices.size();
                
-               //create a new filename
-               ofstream out;
-               string outputFile = outputDir + m->getRootName(m->getSimpleName(phylipfile)) + "homova" + pidValue;                             
-               m->openOutputFileAppend(outputFile, out);
-               out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
-               
-               //for each combo
-               for (int c = start; c < (start+num); c++) {
-                       
-                       if (m->control_pressed) { out.close(); return 0; }
-                       
-                       //get set names
-                       vector<string> setNames;
-                       for (int j = 0; j < namesOfGroupCombos[c].size(); j++) { setNames.push_back(namesOfGroupCombos[c][j]); }
-                       
-                       vector<string> thisCombosSets; //what set each line in the distance matrix is from to be used when calculating SSWithin
-                       set<int> indexes;
-                       for (int k = 0; k < names.size(); k++) {
-                               //is this group for a set we want to compare??
-                               if (m->inUsersGroups(designMap->getGroup(names[k]), setNames)) {  
-                                       thisCombosSets.push_back(designMap->getGroup(names[k]));        
-                                       indexes.insert(k); //save indexes of valid rows in matrix for submatrix
-                               }
-                       }
+               for(int i=0;i<numSamplesInGroup;i++){
+                       int row = sampleIndices[i];
                        
-                       int numGroups = thisCombosSets.size();
-                       
-                       //calc the distance matrix
-                       matrix.clear();
-                       matrix.resize(numGroups);
-                       
-                       for (int k = 0; k < matrix.size(); k++) {       for (int j = 0; j < matrix.size(); j++) {       matrix[k].push_back(1.0);       }       }
-                       
-                       if (thisCombosSets.size() == 0)  { 
-                               m->mothurOut("[ERROR]: Missing distance info for sets. Skipping comparison."); m->mothurOutEndLine(); 
-                       }else{
+                       for(int j=0;j<numSamplesInGroup;j++){
+                               int col = sampleIndices[j];
                                
-                               if (setNames.size() == 2) { out << setNames[0] << "-" << setNames[1] << '\t'; }
-                               else { out << "all" << '\t'; }
-                               
-                               //fill submatrix
-                               int rowCount = 0;
-                               for (int j = 0; j < completeMatrix.size(); j++) {
-                                       
-                                       if (indexes.count(j) != 0) { //we want at least part of this row
-                                               int columnCount = 0;
-                                               for (int k = 0; k < completeMatrix[j].size(); k++) {
-                                                       
-                                                       if (indexes.count(k) != 0) { //we want this distance
-                                                               matrix[rowCount][columnCount] = completeMatrix[j][k];
-                                                               matrix[columnCount][rowCount] = completeMatrix[j][k];
-                                                               columnCount++;
-                                                       }
-                                               }
-                                               rowCount++;
-                                       }
+                               if(col < row){
+                                       ssWithin += distanceMatrix[row][col];
                                }
                                
-                               //calc homova
-                               calcHomova(out, setNames.size(), thisCombosSets);
                        }
                }
                
-               out.close();
-               
-               
-               return 0;
-               
+               ssWithin /= numSamplesInGroup;
+               return ssWithin;
        }
        catch(exception& e) {
-               m->errorOut(e, "HomovaCommand", "driver");
+               m->errorOut(e, "HomovaCommand", "calcSigleSSWithin");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
-int HomovaCommand::calcHomova(ofstream& out, int numTreatments, vector<string> thisCombosLookupSets) {
+
+double HomovaCommand::calcBValue(map<string, vector<int> > groupSampleMap, vector<double>& ssWithinVector) {
        try {
+
+               map<string, vector<int> >::iterator it;
                
-               double SSTotal, BValue, pValue;
-               map<string, double> SSWithin;
-               map<string, double>::iterator it;
-               
-               SSTotal = calcWithin(matrix, numTreatments, thisCombosLookupSets);
-               int numSamples = matrix.size();
-               
-               //calc BValue
-               map<string, int> counts;
-               SSWithin = calcWithinEach(matrix, numTreatments, thisCombosLookupSets, counts);
-                               
-               double sum = 0.0;
-               double sumDenom = 0.0;
-               for (it = SSWithin.begin(); it != SSWithin.end(); it++) {
-                       double temp2 = (it->second) / (double) (counts[it->first] - 1);
-                       sum += ((counts[it->first] - 1) * log(temp2));
-                       sumDenom += ((1 / (double) (counts[it->first] - 1)) - ( 1 / (double) (numSamples - numTreatments) ));
-               }
-               
-               double temp = SSTotal / (double) (numSamples - numTreatments);
-               double numeratorTerm1 = (numSamples - numTreatments) * log(temp);
-               double numerator = numeratorTerm1 - sum;
-               double denom = 1 + ((1 / (double) (3 * (numTreatments - 1))) * sumDenom);
-               
-               BValue = numerator / denom;
+               double numGroups = (double)groupSampleMap.size();
+               ssWithinVector.resize(numGroups, 0);
                
-               //calc Pvalue
-               int count = 0;
-               for (int i = 0; i < iters; i++) {
-                       if (m->control_pressed) { break; }
-                       
-                       //randomly shuffle names to randomize the matrix
-                       vector<string> copyNames = thisCombosLookupSets;
-                       random_shuffle(copyNames.begin(), copyNames.end());
-                       
-                       SSTotal = calcWithin(matrix, numTreatments, copyNames);
-                       
-                       counts.clear();
-                       map<string, double> randomSSWithin = calcWithinEach(matrix, numTreatments, copyNames, counts);
-                       
-                       sum = 0.0;
-                       sumDenom = 0.0;
-                       for (it = randomSSWithin.begin(); it != randomSSWithin.end(); it++) {
-                               double temp2 = (it->second) / (double) (counts[it->first] - numTreatments);
-                               sum += ((counts[it->first] - 1) * log(temp2));
-                               sumDenom += ((1 / (double) (counts[it->first] - 1)) - ( 1 / (double) (numSamples - numTreatments) ));
-                       }
-                       
-                       temp = SSTotal / (double) (numSamples - numTreatments);
-                       numeratorTerm1 = (numSamples - numTreatments) * log(temp);
-                       numerator = numeratorTerm1 - sum;
-                       denom = 1 + ((1 / (double) (3 * (numTreatments - 1))) * sumDenom);
-                       
-                       double randomBValue = numerator / denom;
-                       
-                       if (randomBValue <= BValue) { count++; }
-               }
-                               
-               pValue = count / (float) iters;
-               
-               out << BValue << '\t' << pValue << endl;
-
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "HomovaCommand", "calcHomova");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-map<string, double> HomovaCommand::calcWithinEach(vector< vector<double> >& thisMatrix, int numTreatments, vector<string> thisCombosLookupSets, map<string, int>& count) {
-       try {
-               map<string, double> within; //maps treatment to within value
-               map<string, double>::iterator it;
-               map<string, int>::iterator itCount;
+               double totalNumSamples = 0;
+               double ssWithinFull;
+               double secondTermSum = 0;
+               double inverseOneMinusSum = 0;
+               int index = 0;
                
-               for (int i = 0; i < thisCombosLookupSets.size(); i++) {
-                       itCount = count.find(thisCombosLookupSets[i]);
+               ssWithinVector.resize(numGroups, 0);
+               for(it = groupSampleMap.begin();it!=groupSampleMap.end();it++){
+                       int numSamplesInGroup = it->second.size();
+                       totalNumSamples += numSamplesInGroup;
                        
-                       if (itCount == count.end()) { //first time we have seen this treatment
-                               count[thisCombosLookupSets[i]] = 1; 
-                       }else {
-                               count[thisCombosLookupSets[i]]++;
-                       }
+                       ssWithinVector[index] = calcSigleSSWithin(it->second);
+                       ssWithinFull += ssWithinVector[index];
                        
-                       //initialize within
-                       within[thisCombosLookupSets[i]] = 0.0;
+                       secondTermSum += (numSamplesInGroup - 1) * log(ssWithinVector[index] / (double)(numSamplesInGroup - 1));
+                       inverseOneMinusSum += 1.0 / (double)(numSamplesInGroup - 1);
+                       index++;
                }
-                       
                
-               //traverse lower triangle
-               for (int k = 0; k < thisMatrix.size(); k++) { 
-                       for (int l = k; l < thisMatrix[k].size(); l++) {
-                               
-                               //if you are from the same treatment then eij is 1 so add, else eij = 0
-                               if (thisCombosLookupSets[k] == thisCombosLookupSets[l]) { 
-                                       within[thisCombosLookupSets[k]] += (thisMatrix[k][l] * thisMatrix[k][l]); //dij^2
-                               }
-                       }
-               }
+               double B = (totalNumSamples - numGroups) * log(ssWithinFull/(totalNumSamples-numGroups)) - secondTermSum;
+               double denomintor = 1 + 1.0/(3.0 * (numGroups - 1.0)) * (inverseOneMinusSum - 1.0 / (double) (totalNumSamples - numGroups));
+               B /= denomintor;
                
-               //1 / (numSamples in this treatment)
-               for (it = within.begin(); it != within.end(); it++) {
-                       (it->second) *= (1.0 / (float) count[it->first]);
-               }
+               return B;
                
-               return within;
        }
        catch(exception& e) {
-               m->errorOut(e, "HomovaCommand", "calcWithinEach");
+               m->errorOut(e, "HomovaCommand", "calcBValue");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
-double HomovaCommand::calcWithin(vector< vector<double> >& thisMatrix, int numTreatments, vector<string> thisCombosLookupSets) {
-       try {
-               double total = 0.0;
+
+map<string, vector<int> > HomovaCommand::getRandomizedGroups(map<string, vector<int> > origMapping){
+       try{
+               vector<int> sampleIndices;
+               vector<int> samplesPerGroup;
+               
+               map<string, vector<int> >::iterator it;
+               for(it=origMapping.begin();it!=origMapping.end();it++){
+                       vector<int> indices = it->second;
+                       samplesPerGroup.push_back(indices.size());
+                       sampleIndices.insert(sampleIndices.end(), indices.begin(), indices.end());
+               }
                
-               //traverse lower triangle
-               for (int k = 0; k < thisMatrix.size(); k++) { 
-                       for (int l = k; l < thisMatrix[k].size(); l++) {
-                               
-                               //if you are from the same treatment then eij is 1 so add, else eij = 0
-                               if (thisCombosLookupSets[k] == thisCombosLookupSets[l]) { 
-                                       total += (thisMatrix[k][l] * thisMatrix[k][l]); //dij^2
-                               }
+               random_shuffle(sampleIndices.begin(), sampleIndices.end());
+               
+               int index = 0;
+               map<string, vector<int> > randomizedGroups = origMapping;
+               for(it=randomizedGroups.begin();it!=randomizedGroups.end();it++){
+                       for(int i=0;i<it->second.size();i++){
+                               it->second[i] = sampleIndices[index++];                         
                        }
                }
                
-               //1 / (numSamples / numTreatments)
-               total *= (1.0 / (float) (thisMatrix.size() / (float) numTreatments));
-               
-               return total;
+               return randomizedGroups;                
        }
-       catch(exception& e) {
-               m->errorOut(e, "HomovaCommand", "calcWithin");
+       catch (exception& e) {
+               m->errorOut(e, "AmovaCommand", "randomizeGroups");
                exit(1);
        }
 }
+
 //**********************************************************************************************************************
 
 
index 55e4eac7b1a1efc7bac263186fd827bd72d19ad6..11f3c07fcebb96ddfe7a473aac8ccb0f234e167d 100644 (file)
 
 
 #include "command.hpp"
-#include "inputdata.h"
-#include "sharedrabundvector.h"
-#include "validcalculator.h"
-#include "readphylipvector.h"
 
-class GlobalData;
+//class GlobalData;
+class GroupMap;
 
 class HomovaCommand : public Command {
        
@@ -33,35 +30,20 @@ public:
        void help();
        
 private:
-       struct linePair {
-               int start;
-               int num;
-               linePair(int i, int j) : start(i), num(j) {}
-       };
-       vector<linePair> lines;
-       
-       GlobalData* globaldata;
-       GroupMap* designMap;
+       double runHOMOVA(ofstream& , map<string, vector<int> >, double);
+       double calcSigleSSWithin(vector<int>);
+       double calcBValue(map<string, vector<int> >, vector<double>&);
+       map<string, vector<int> > getRandomizedGroups(map<string, vector<int> >);
+
+       bool abort;
        map<string, vector<string> > outputTypes;
-       
-       vector< vector<double> > matrix;
-       bool abort, allLines, pickedGroups;
-       set<string> labels; //holds labels to be used
-       string format, groups, label, outputDir, inputDir, designfile, sets, phylipfile, calc, sharedfile;
-       vector<string> Groups, outputNames, Sets;
-       vector< vector<string> > namesOfGroupCombos;
-       int iters, processors;
-       vector<Calculator*> calculators;
-       
-       int driver(int, int, vector<SharedRAbundVector*>, string);
-       int driver(int, int, vector<string>, string, vector< vector<double> >&);
-       int process(vector<SharedRAbundVector*>);
-       int calcHomova(ofstream&, int, vector<string>);
-       map<string, double> calcWithinEach(vector< vector<double> >&, int, vector<string>, map<string, int>&);
-       double calcWithin(vector< vector<double> >&, int, vector<string>);
-       double calcTotal(int);
+       vector<string> outputNames;
+
+       string outputDir, inputDir, designFileName, phylipFileName;
+       GroupMap* designMap;
+       vector< vector<double> > distanceMatrix;
+       int iters;
+       double experimentwiseAlpha;
 };
 
 #endif
-
-
index f8907ccb0c88b15a3f8a943d4895b75b18bf8323..c3ffccef2aa6c73ef8922a2265d131d52ce40f29 100644 (file)
@@ -94,6 +94,7 @@ vector<string> ReadPhylipVector::read(vector< vector<double> >& matrix) {
                                }
                        }
                }
+               f.close();
                
                return names;
        }
@@ -171,6 +172,7 @@ vector<string> ReadPhylipVector::read(vector<seqDist>& matrix) {
                                }
                        }
                }
+               f.close();
                
                return names;
        }
index 378e004ac4524d78088b054a91947d604ca32768..cf77a921e3c58cb6c6db8fbd6c38d5a0a369bff6 100644 (file)
--- a/venn.cpp
+++ b/venn.cpp
@@ -33,7 +33,7 @@ vector<string> Venn::getPic(SAbundVector* sabund, vector<Calculator*> vCalcs) {
        try {
                
                vector<string> outputNames;
-               
+
                for(int i=0;i<vCalcs.size();i++){
                        string filenamesvg = outputDir + m->getRootName(m->getSimpleName(globaldata->inputFileName)) + "." + sabund->getLabel() + "." + vCalcs[i]->getName() + ".svg";
                        outputNames.push_back(filenamesvg);
@@ -78,7 +78,7 @@ vector<string> Venn::getPic(SAbundVector* sabund, vector<Calculator*> vCalcs) {
 //**********************************************************************************************************************
 vector<string> Venn::getPic(vector<SharedRAbundVector*> lookup, vector<Calculator*> vCalcs) {
        try {
-               
+
                vector<SharedRAbundVector*> subset;
                vector<string> outputNames;
                
@@ -168,14 +168,16 @@ vector<string> Venn::getPic(vector<SharedRAbundVector*> lookup, vector<Calculato
                                        //singleCalc = new Ace(10);
                                //}
                                
-                               int sharedVal, numSeqsA, numSeqsB;
+                               int sharedVal, numSeqsA, numSeqsB, uniqSeqsToA, uniqSeqsToB;
                                if (nseqs) {
                                        NSeqs* nseqsCalc = new NSeqs();
                                        vector<double> data = nseqsCalc->getValues(lookup);
-                                       
+                                       cout << data[0] << '\t' << data[1] << endl;
                                        sharedVal = data[0] + data[1];
                                        numSeqsA = sabundA->getNumSeqs();
                                        numSeqsB = sabundB->getNumSeqs();
+                                       uniqSeqsToA = numSeqsA-data[0];
+                                       uniqSeqsToB = numSeqsB-data[1];
                                        
                                        delete nseqsCalc;
                                }
@@ -205,21 +207,22 @@ vector<string> Venn::getPic(vector<SharedRAbundVector*> lookup, vector<Calculato
                                if (numA.size() == 3) { 
                                        outsvg << " the lci is " + toString(numA[1]) + " and the hci is " + toString(numA[2]);
                                }
-                               if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsA);  }  
+                               if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsA) + "; " + toString(uniqSeqsToA) + " sequences are not shared";  }  
                                outsvg << "</text>\n";
                
                                outsvg << "<text fill=\"black\" class=\"seri\"   font-size=\"24\" x=\"" +  toString(int(0.25 * width)) +  "\" y=\"" +  toString(int(0.69 * height)) +  "\">The number of species in group " + lookup[1]->getGroup() + " is " + toString(numB[0]);
                                if (numB.size() == 3) { 
                                        outsvg << " the lci is " + toString(numB[1]) + " and the hci is " + toString(numB[2]);
                                }
-                               if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsB);  }  
+                               if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsB) + "; " + toString(uniqSeqsToB) + " sequences are not shared";  }  
                                outsvg << "</text>\n";
 
                                outsvg << "<text fill=\"black\" class=\"seri\"  font-size=\"24\" x=\"" +  toString(int(0.25 * width)) +  "\" y=\"" +  toString(int(0.72 * height)) +  "\">The number of sepecies shared between groups " + lookup[0]->getGroup() + " and " + lookup[1]->getGroup() + " is " + toString(shared[0]);
-                               if (nseqs) {  outsvg << ", and the number of squences is " + toString(sharedVal);  }  
+                               if (nseqs) {  outsvg << ", and the number of squences is " + toString(sharedVal) + "; " + toString((sharedVal / (float)(numSeqsA + numSeqsB))*100) + "% of these sequences are shared";  }  
                                outsvg << "</text>\n";
                                
                                outsvg << "<text fill=\"black\" class=\"seri\"  font-size=\"24\" x=\"" +  toString(int(0.25 * width)) +  "\" y=\"" +  toString(int(0.75 * height)) +  "\">Percentage of species that are shared in groups " + lookup[0]->getGroup() + " and " + lookup[1]->getGroup() + " is " + toString((shared[0] / (float)(numA[0] + numB[0] - shared[0]))*100) + "</text>\n";
+                               
                                outsvg << "<text fill=\"black\" class=\"seri\"  font-size=\"24\" x=\"" +  toString(int(0.25 * width)) +  "\" y=\"" +  toString(int(0.78 * height)) +  "\">The total richness for all groups is " + toString((float)(numA[0] + numB[0] - shared[0]))+ "</text>\n";;
                                
                                
@@ -254,7 +257,7 @@ vector<string> Venn::getPic(vector<SharedRAbundVector*> lookup, vector<Calculato
                                
                                if (m->control_pressed) { outsvg.close(); return outputNames; }
                                
-                               int sharedVal, sharedABVal, sharedACVal, sharedBCVal, numSeqsA, numSeqsB, numSeqsC;
+                               int sharedVal, sharedABVal, sharedACVal, sharedBCVal, numSeqsA, numSeqsB, numSeqsC, uniqSeqsToA, uniqSeqsToB, uniqSeqsToC;
                                
                                if (nseqs) {
                                        NSeqs* nseqsCalc = new NSeqs();
@@ -276,6 +279,9 @@ vector<string> Venn::getPic(vector<SharedRAbundVector*> lookup, vector<Calculato
                                        numSeqsA = sabundA->getNumSeqs();
                                        numSeqsB = sabundB->getNumSeqs();
                                        numSeqsC = sabundC->getNumSeqs();
+                                       uniqSeqsToA = numSeqsA-sharedData[0];
+                                       uniqSeqsToB = numSeqsC-sharedData[1];
+                                       uniqSeqsToC = numSeqsB-sharedData[1];
 
                                        delete nseqsCalc;
                                }
@@ -409,21 +415,21 @@ vector<string> Venn::getPic(vector<SharedRAbundVector*> lookup, vector<Calculato
                                        if (numA.size() == 3) { 
                                                outsvg << " the lci is " + toString(numA[1]) + " and the hci is " + toString(numA[2]);
                                        } 
-                                       if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsA);  }  
+                                       if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsA) + "; " + toString(uniqSeqsToA) + " sequences are not shared";  }  
                                        outsvg << "</text>\n";
                        
                                        outsvg << "<text fill=\"black\" class=\"seri\"  font-size=\"24\" x=\"" +  toString(int(0.25 * width)) +  "\" y=\"" +  toString(int(0.75 * height)) +  "\">The number of species in group " + lookup[1]->getGroup() + " is " + toString(numB[0]);
                                        if (numB.size() == 3) { 
                                                outsvg << " the lci is " + toString(numB[1]) + " and the hci is " + toString(numB[2]);
                                        }
-                                       if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsB);  }  
+                                       if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsB) + "; " + toString(uniqSeqsToB) + " sequences are not shared";  }  
                                        outsvg << "</text>\n";
                                        
                                        outsvg << "<text fill=\"black\" class=\"seri\"  font-size=\"24\" x=\"" +  toString(int(0.25 * width)) +  "\" y=\"" +  toString(int(0.775 * height)) +  "\">The number of species in group " + lookup[2]->getGroup() + " is " + toString(numC[0]);
                                        if (numC.size() == 3) { 
                                                outsvg << " the lci is " + toString(numC[1]) + " and the hci is " + toString(numC[2]);
                                        }
-                                       if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsC);  }  
+                                       if (nseqs) {  outsvg << ", and the number of squences is " + toString(numSeqsC) + "; " + toString(uniqSeqsToC) + " sequences are not shared";  }  
                                        outsvg << "</text>\n";
 
                                        outsvg << "<text fill=\"black\" class=\"seri\"  font-size=\"24\" x=\"" +  toString(int(0.25 * width)) +  "\" y=\"" +  toString(int(0.80 * height)) +  "\">The total richness of all the groups is " + toString(numA[0] + numB[0] + numC[0] - sharedAB[0] - sharedAC[0] - sharedBC[0] + sharedABC) + "</text>\n";