]> git.donarmstrong.com Git - mothur.git/commitdiff
added merge.taxsummary command. added column format to dist.shared.
authorSarah Westcott <mothur.westcott@gmail.com>
Wed, 13 Feb 2013 19:02:49 +0000 (14:02 -0500)
committerSarah Westcott <mothur.westcott@gmail.com>
Wed, 13 Feb 2013 19:02:49 +0000 (14:02 -0500)
Mothur.xcodeproj/project.pbxproj
commandfactory.cpp
matrixoutputcommand.cpp
mergetaxsummarycommand.cpp [new file with mode: 0644]
mergetaxsummarycommand.h [new file with mode: 0644]

index 15a5cff06d869482c252cdc50e82c5ec0a75abdf..33c768c343a36a119d058414cece3ec193b228e1 100644 (file)
@@ -58,6 +58,7 @@
                A7876A26152A017C00A0AE86 /* subsample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7876A25152A017C00A0AE86 /* subsample.cpp */; };
                A79234D713C74BF6002B08E2 /* mothurfisher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A79234D613C74BF6002B08E2 /* mothurfisher.cpp */; };
                A795840D13F13CD900F201D5 /* countgroupscommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A795840C13F13CD900F201D5 /* countgroupscommand.cpp */; };
+               A799314B16CBD0CD0017E888 /* mergetaxsummarycommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A799314A16CBD0CD0017E888 /* mergetaxsummarycommand.cpp */; };
                A799F5B91309A3E000AEEFA0 /* makefastqcommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A799F5B81309A3E000AEEFA0 /* makefastqcommand.cpp */; };
                A79EEF8616971D4A0006DEC1 /* filtersharedcommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A79EEF8516971D4A0006DEC1 /* filtersharedcommand.cpp */; };
                A7A0671A1562946F0095C8C5 /* listotulabelscommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A067191562946F0095C8C5 /* listotulabelscommand.cpp */; };
                A79234D613C74BF6002B08E2 /* mothurfisher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mothurfisher.cpp; sourceTree = "<group>"; };
                A795840B13F13CD900F201D5 /* countgroupscommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = countgroupscommand.h; sourceTree = "<group>"; };
                A795840C13F13CD900F201D5 /* countgroupscommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = countgroupscommand.cpp; sourceTree = "<group>"; };
+               A799314816CBD0BC0017E888 /* mergetaxsummarycommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mergetaxsummarycommand.h; sourceTree = "<group>"; };
+               A799314A16CBD0CD0017E888 /* mergetaxsummarycommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mergetaxsummarycommand.cpp; sourceTree = "<group>"; };
                A799F5B71309A3E000AEEFA0 /* makefastqcommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = makefastqcommand.h; sourceTree = "<group>"; };
                A799F5B81309A3E000AEEFA0 /* makefastqcommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = makefastqcommand.cpp; sourceTree = "<group>"; };
                A79EEF8516971D4A0006DEC1 /* filtersharedcommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = filtersharedcommand.cpp; sourceTree = "<group>"; };
                                A7E9B75312D37EC400DA6239 /* mergefilecommand.cpp */,
                                A71FE12A12EDF72400963CA7 /* mergegroupscommand.h */,
                                A71FE12B12EDF72400963CA7 /* mergegroupscommand.cpp */,
+                               A799314816CBD0BC0017E888 /* mergetaxsummarycommand.h */,
+                               A799314A16CBD0CD0017E888 /* mergetaxsummarycommand.cpp */,
                                A7E9B75812D37EC400DA6239 /* metastatscommand.h */,
                                A7E9B75712D37EC400DA6239 /* metastatscommand.cpp */,
                                A7E9B75A12D37EC400DA6239 /* mgclustercommand.h */,
                                A74C06E916A9C0A9008390A3 /* primerdesigncommand.cpp in Sources */,
                                A7128B1D16B7002A00723BE4 /* getdistscommand.cpp in Sources */,
                                A7B0231516B8244C006BA09E /* removedistscommand.cpp in Sources */,
+                               A799314B16CBD0CD0017E888 /* mergetaxsummarycommand.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 42e99d1331b3694792eed47e94ab9d21b33f9545..193c53c4d610111cf369084f1a153400bfbe38e5 100644 (file)
 #include "primerdesigncommand.h"
 #include "getdistscommand.h"
 #include "removedistscommand.h"
+#include "mergetaxsummarycommand.h"
 
 /*******************************************************/
 
@@ -303,6 +304,7 @@ CommandFactory::CommandFactory(){
     commands["primer.design"]          = "primer.design";
     commands["get.dists"]           = "get.dists";
     commands["remove.dists"]        = "remove.dists";
+    commands["merge.taxsummary"]    = "merge.taxsummary";
     
 
 }
@@ -522,6 +524,7 @@ Command* CommandFactory::getCommand(string commandName, string optionString){
         else if(commandName == "primer.design")         {      command = new PrimerDesignCommand(optionString);            }
         else if(commandName == "get.dists")             {      command = new GetDistsCommand(optionString);                }
         else if(commandName == "remove.dists")          {      command = new RemoveDistsCommand(optionString);             }
+        else if(commandName == "merge.taxsummary")      {      command = new MergeTaxSummaryCommand(optionString);         }
                else                                                                                    {       command = new NoCommand(optionString);                                          }
 
                return command;
@@ -682,6 +685,7 @@ Command* CommandFactory::getCommand(string commandName, string optionString, str
         else if(commandName == "primer.design")         {      pipecommand = new PrimerDesignCommand(optionString);            }
         else if(commandName == "get.dists")             {      pipecommand = new GetDistsCommand(optionString);                }
         else if(commandName == "remove.dists")          {      pipecommand = new RemoveDistsCommand(optionString);             }
+        else if(commandName == "merge.taxsummary")      {      pipecommand = new MergeTaxSummaryCommand(optionString);         }
                else                                                                                    {       pipecommand = new NoCommand(optionString);                                              }
 
                return pipecommand;
@@ -828,6 +832,7 @@ Command* CommandFactory::getCommand(string commandName){
         else if(commandName == "primer.design")         {      shellcommand = new PrimerDesignCommand();           }
         else if(commandName == "get.dists")             {      shellcommand = new GetDistsCommand();               }
         else if(commandName == "remove.dists")          {      shellcommand = new RemoveDistsCommand();            }
+        else if(commandName == "merge.taxsummary")      {      shellcommand = new MergeTaxSummaryCommand();        }
                else                                                                                    {       shellcommand = new NoCommand();                                         }
 
                return shellcommand;
index 95b881190d085135539601c17836ce7d123592da..310e32bf23e048c73ae37579ac2e8e2d1cb8b0ff 100644 (file)
@@ -18,7 +18,7 @@ vector<string> MatrixOutputCommand::setParameters(){
         CommandParameter psubsample("subsample", "String", "", "", "", "", "","",false,false); parameters.push_back(psubsample);
                CommandParameter pgroups("groups", "String", "", "", "", "", "","",false,false); parameters.push_back(pgroups);
                CommandParameter pcalc("calc", "Multiple", "sharedsobs-sharedchao-sharedace-jabund-sorabund-jclass-sorclass-jest-sorest-thetayc-thetan-kstest-sharednseqs-ochiai-anderberg-kulczynski-kulczynskicody-lennon-morisitahorn-braycurtis-whittaker-odum-canberra-structeuclidean-structchord-hellinger-manhattan-structpearson-soergel-spearman-structkulczynski-speciesprofile-hamming-structchi2-gower-memchi2-memchord-memeuclidean-mempearson", "jclass-thetayc", "", "", "","",true,false,true); parameters.push_back(pcalc);
-               CommandParameter poutput("output", "Multiple", "lt-square", "lt", "", "", "","",false,false); parameters.push_back(poutput);
+               CommandParameter poutput("output", "Multiple", "lt-square-column", "lt", "", "", "","",false,false); parameters.push_back(poutput);
         CommandParameter pmode("mode", "Multiple", "average-median", "average", "", "", "","",false,false); parameters.push_back(pmode);
                CommandParameter pprocessors("processors", "Number", "", "1", "", "", "","",false,false,true); parameters.push_back(pprocessors);
         CommandParameter piters("iters", "Number", "", "1000", "", "", "","",false,false); parameters.push_back(piters);
@@ -45,7 +45,7 @@ string MatrixOutputCommand::getHelpString(){
         helpString += "The iters parameter allows you to choose the number of times you would like to run the subsample.\n";
         helpString += "The subsample parameter allows you to enter the size pergroup of the sample or you can set subsample=T and mothur will use the size of your smallest group.\n";
                helpString += "The dist.shared command should be in the following format: dist.shared(groups=yourGroups, calc=yourCalcs, label=yourLabels).\n";
-               helpString += "The output parameter allows you to specify format of your distance matrix. Options are lt, and square. The default is lt.\n";
+               helpString += "The output parameter allows you to specify format of your distance matrix. Options are lt, column and square. The default is lt.\n";
         helpString += "The mode parameter allows you to specify if you want the average or the median values reported when subsampling. Options are average, and median. The default is average.\n";
                helpString += "Example dist.shared(groups=A-B-C, calc=jabund-sorabund).\n";
                helpString += "The default value for groups is all the groups in your groupfile.\n";
@@ -156,7 +156,7 @@ MatrixOutputCommand::MatrixOutputCommand(string option)  {
                        }
                        
                        output = validParameter.validFile(parameters, "output", false);         if(output == "not found"){      output = "lt"; }
-                       if ((output != "lt") && (output != "square")) { m->mothurOut(output + " is not a valid output form. Options are lt and square. I will use lt."); m->mothurOutEndLine(); output = "lt"; }
+                       if ((output != "lt") && (output != "square") && (output != "column")) { m->mothurOut(output + " is not a valid output form. Options are lt, column and square. I will use lt."); m->mothurOutEndLine(); output = "lt"; }
             
             mode = validParameter.validFile(parameters, "mode", false);                if(mode == "not found"){        mode = "average"; }
                        if ((mode != "average") && (mode != "median")) { m->mothurOut(mode + " is not a valid mode. Options are average and medina. I will use average."); m->mothurOutEndLine(); output = "average"; }
@@ -449,11 +449,9 @@ void MatrixOutputCommand::printSims(ostream& out, vector< vector<double> >& simM
        try {
                
                out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
-               
-               //output num seqs
-               out << simMatrix.size() << endl;
-               
+                               
                if (output == "lt") {
+            out << simMatrix.size() << endl;
                        for (int b = 0; b < simMatrix.size(); b++)      {
                                out << lookup[b]->getGroup() << '\t';
                                for (int n = 0; n < b; n++)     {
@@ -461,7 +459,14 @@ void MatrixOutputCommand::printSims(ostream& out, vector< vector<double> >& simM
                                }
                                out << endl;
                        }
+        }else if (output == "column") {
+            for (int b = 0; b < simMatrix.size(); b++) {
+                for (int n = 0; n < b; n++)    {
+                    out << lookup[b]->getGroup() << '\t' << lookup[n]->getGroup() << '\t' << simMatrix[b][n] << endl;
+                }
+            }
                }else{
+            out << simMatrix.size() << endl;
                        for (int b = 0; b < simMatrix.size(); b++)      {
                                out << lookup[b]->getGroup() << '\t';
                                for (int n = 0; n < simMatrix[b].size(); n++)   {
diff --git a/mergetaxsummarycommand.cpp b/mergetaxsummarycommand.cpp
new file mode 100644 (file)
index 0000000..852e0e0
--- /dev/null
@@ -0,0 +1,373 @@
+//
+//  mergetaxsummarycommand.cpp
+//  Mothur
+//
+//  Created by Sarah Westcott on 2/13/13.
+//  Copyright (c) 2013 Schloss Lab. All rights reserved.
+//
+
+#include "mergetaxsummarycommand.h"
+
+
+//**********************************************************************************************************************
+vector<string> MergeTaxSummaryCommand::setParameters(){        
+       try {
+               CommandParameter pinput("input", "String", "", "", "", "", "","",false,true,true); parameters.push_back(pinput);
+               CommandParameter poutput("output", "String", "", "", "", "", "","",false,true,true); parameters.push_back(poutput);
+               CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
+               CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
+               
+               vector<string> myArray;
+               for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
+               return myArray;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "setParameters");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+string MergeTaxSummaryCommand::getHelpString(){        
+       try {
+               string helpString = "";
+               helpString += "The merge.taxsummary command takes a list of tax.summary files separated by dashes and merges them into one file."; 
+               helpString += "The merge.taxsummary command parameters are input and output."; 
+               helpString += "Example merge.taxsummary(input=small.tax.summary-large.tax.summary, output=all.tax.summary).";
+               helpString += "Note: No spaces between parameter labels (i.e. output), '=' and parameters (i.e.yourOutputFileName).\n";
+               return helpString;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "getHelpString");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+MergeTaxSummaryCommand::MergeTaxSummaryCommand(){      
+       try {
+               abort = true; calledHelp = true; 
+               setParameters();
+               vector<string> tempOutNames;
+               outputTypes["taxsummary"] = tempOutNames;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "MergeTaxSummaryCommand");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+
+MergeTaxSummaryCommand::MergeTaxSummaryCommand(string option)  {
+       try {
+               abort = false; calledHelp = false;   
+               
+               if(option == "help") { help();  abort = true; calledHelp = true;    }
+               else if(option == "citation") { citation(); abort = true; calledHelp = true;   }
+               else {
+                       vector<string> myArray = setParameters();
+                       
+                       OptionParser parser(option);
+                       map<string,string> parameters = parser.getParameters();
+                       
+                       ValidParameters validParameter;
+                       
+                       //check to make sure all parameters are valid for command
+                       for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) { 
+                               if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
+                       }
+                       
+                       //initialize outputTypes
+                       vector<string> tempOutNames;
+                       outputTypes["taxsummary"] = tempOutNames;
+                       
+                       //if the user changes the input directory command factory will send this info to us in the output parameter 
+                       string inputDir = validParameter.validFile(parameters, "inputdir", false);              
+                       if (inputDir == "not found"){   inputDir = "";          }
+                       
+                       string fileList = validParameter.validFile(parameters, "input", false);                 
+                       if(fileList == "not found") { m->mothurOut("you must enter two or more file names"); m->mothurOutEndLine();  abort=true;  }
+                       else{   m->splitAtDash(fileList, fileNames);    }
+                       
+                       //if the user changes the output directory command factory will send this info to us in the output parameter 
+                       string outputDir = validParameter.validFile(parameters, "outputdir", false);            if (outputDir == "not found")   {       outputDir = "";         }
+                       
+                       
+                       numInputFiles = fileNames.size();
+                       ifstream testFile;
+                       if(numInputFiles == 0){
+                               m->mothurOut("you must enter two or more file names and you entered " + toString(fileNames.size()) +  " file names"); m->mothurOutEndLine();
+                               abort=true;  
+                       }
+                       else{
+                               for(int i=0;i<numInputFiles;i++){
+                                       if (inputDir != "") {
+                        string path = m->hasPath(fileNames[i]);
+                        //if the user has not given a path then, add inputdir. else leave path alone.
+                        if (path == "") {      fileNames[i] = inputDir + fileNames[i];         }
+                    }
+                    
+                    int ableToOpen;
+                    ifstream in;
+                    ableToOpen = m->openInputFile(fileNames[i], in, "noerror");
+                    in.close();        
+                    
+                    //if you can't open it, try default location
+                    if (ableToOpen == 1) {
+                        if (m->getDefaultPath() != "") { //default path is set
+                            string tryPath = m->getDefaultPath() + m->getSimpleName(fileNames[i]);
+                            m->mothurOut("Unable to open " + fileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
+                            ifstream in2;
+                            ableToOpen = m->openInputFile(tryPath, in2, "noerror");
+                            in2.close();
+                            fileNames[i] = tryPath;
+                        }
+                    }
+                    
+                    //if you can't open it, try output location
+                    if (ableToOpen == 1) {
+                        if (m->getOutputDir() != "") { //default path is set
+                            string tryPath = m->getOutputDir() + m->getSimpleName(fileNames[i]);
+                            m->mothurOut("Unable to open " + fileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
+                            ifstream in2;
+                            ableToOpen = m->openInputFile(tryPath, in2, "noerror");
+                            in2.close();
+                            fileNames[i] = tryPath;
+                        }
+                    }
+                    
+                    
+                    
+                    if (ableToOpen == 1) { 
+                        m->mothurOut("Unable to open " + fileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); 
+                        //erase from file list
+                        fileNames.erase(fileNames.begin()+i);
+                        i--;
+                    }
+                               }
+                       }   
+                       
+                       outputFileName = validParameter.validFile(parameters, "output", false);                 
+                       if (outputFileName == "not found") { m->mothurOut("you must enter an output file name"); m->mothurOutEndLine();  abort=true;  }
+                       else if (outputDir != "") { outputFileName = outputDir + m->getSimpleName(outputFileName);   }
+            
+               }
+        
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "MergeTaxSummaryCommand");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+
+int MergeTaxSummaryCommand::execute(){
+       try {
+               if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
+               
+        outputFileName = m->getFullPathName(outputFileName);
+               m->mothurRemove(outputFileName);
+        
+        vector<rawTaxNode> tree;
+        tree.push_back(rawTaxNode("Root"));
+               tree[0].rank = "0";
+        bool hasGroups = true;
+        set<string> groups;
+       
+        for (int i = 0; i < fileNames.size(); i++) {
+            
+            ifstream in;
+            m->openInputFile(fileNames[i], in);
+            string temp = m->getline(in);
+            vector<string> headers = m->splitWhiteSpace(temp);
+            
+            vector<string> thisFilesGroups;
+            if (headers.size() == 5) { hasGroups = false; }
+            else {  for (int j = 5; j < headers.size(); j++) { groups.insert(headers[j]); thisFilesGroups.push_back(headers[j]); } }
+            
+            int level, daugterLevels, total;
+            string rankId, tax; 
+            map<int, int> levelToCurrentNode;
+            levelToCurrentNode[0] = 0;
+            while (!in.eof()) {
+                
+                if (m->control_pressed) {   return 0;  }
+                
+                in >> level >> rankId >> tax >> daugterLevels >> total; m->gobble(in);
+                map<string, int> groupCounts;
+                if (thisFilesGroups.size() != 0) {  
+                    for (int j = 0; j < thisFilesGroups.size(); j++) {  
+                        int tempNum; in >> tempNum; m->gobble(in);
+                        groupCounts[thisFilesGroups[j]] = tempNum; 
+                    } 
+                }
+                
+                if (level == 0) {}
+                else { 
+                    map<int, int>::iterator itParent = levelToCurrentNode.find(level-1);
+                    int parent = 0;
+                    if (itParent == levelToCurrentNode.end()) { m->mothurOut("[ERROR]: situation I didnt expect.\n"); }
+                    else { parent = itParent->second; }
+                    
+                    levelToCurrentNode[level] = addTaxToTree(tree, level, parent, tax, total, groupCounts);
+                } 
+            }
+            in.close();
+        }
+        
+        if (!hasGroups && (groups.size() != 0)) { groups.clear();  m->mothurOut("[WARNING]: not all files contain group breakdown, ignoring group counts.\n");  }
+        
+        ofstream out;
+        m->openOutputFile(outputFileName, out);
+        print(out, tree, groups);
+                       
+               if (m->control_pressed) {  m->mothurRemove(outputFileName); return 0;  }
+               
+               m->mothurOutEndLine();
+               m->mothurOut("Output File Names: "); m->mothurOutEndLine();
+               m->mothurOut(outputFileName); m->mothurOutEndLine();    outputNames.push_back(outputFileName); outputTypes["taxsummary"].push_back(outputFileName);
+               m->mothurOutEndLine();
+        
+               return 0;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "execute");
+               exit(1);
+       }
+}
+/**************************************************************************************************/
+
+int MergeTaxSummaryCommand::addTaxToTree(vector<rawTaxNode>& tree, int level, int currentNode, string taxon, int total, map<string, int> groups){
+       try {
+               map<string, int>::iterator childPointer;
+               
+        childPointer = tree[currentNode].children.find(taxon);
+        int nodeToIncrement = 0;
+                       
+        if(childPointer != tree[currentNode].children.end()){  //if the node already exists, increment counts
+            nodeToIncrement = childPointer->second;
+            tree[nodeToIncrement].total += total;
+            
+            for (map<string, int>::iterator itGroups = groups.begin(); itGroups != groups.end(); itGroups++) {
+                map<string, int>::iterator it = tree[nodeToIncrement].groupCount.find(itGroups->first);
+                if (it == tree[nodeToIncrement].groupCount.end()) { tree[nodeToIncrement].groupCount[itGroups->first] = itGroups->second; }
+                else {   it->second += itGroups->second;  }
+            }
+        }
+        else{                                                                                  //otherwise, create it
+            tree.push_back(rawTaxNode(taxon));
+            tree[currentNode].children[taxon] = tree.size()-1;
+            tree[tree.size()-1].parent = currentNode;
+            nodeToIncrement = tree.size()-1;
+            tree[nodeToIncrement].total = total;
+            tree[nodeToIncrement].level = level;
+            for (map<string, int>::iterator itGroups = groups.begin(); itGroups != groups.end(); itGroups++) {
+                 tree[nodeToIncrement].groupCount[itGroups->first] = itGroups->second; 
+            }
+        }
+        
+               return nodeToIncrement;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "addSeqToTree");
+               exit(1);
+       }
+}
+/**************************************************************************************************/
+
+int MergeTaxSummaryCommand::assignRank(int index, vector<rawTaxNode>& tree){
+       try {
+               map<string,int>::iterator it;
+               int counter = 1;
+               
+               for(it=tree[index].children.begin();it!=tree[index].children.end();it++){
+            if (m->control_pressed) { return 0; }
+                       tree[it->second].rank = tree[index].rank + '.' + toString(counter);
+                       counter++;
+            
+                       assignRank(it->second, tree);
+               }
+        
+        return 0;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "assignRank");
+               exit(1);
+       }
+}
+/**************************************************************************************************/
+
+int MergeTaxSummaryCommand::print(ofstream& out, vector<rawTaxNode>& tree, set<string> groups){
+       try {
+               
+               assignRank(0, tree); 
+        vector<string> mGroups;
+               //print labels
+               out << "taxlevel\t rankID\t taxon\t daughterlevels\t total\t";
+               for (set<string>::iterator it = groups.begin(); it != groups.end(); it++) { out << (*it) << '\t'; }             
+               out << endl;
+        
+        for (set<string>::iterator it2 = groups.begin(); it2 != groups.end(); it2++) {  tree[0].groupCount[*it2] = 0;  }
+            
+        map<string,int>::iterator it;
+               for(it=tree[0].children.begin();it!=tree[0].children.end();it++){   
+            tree[0].total += tree[it->second].total;
+                       for (set<string>::iterator it2 = groups.begin(); it2 != groups.end(); it2++) { 
+                map<string, int>:: iterator itGroups = tree[it->second].groupCount.find(*it2);
+                if (itGroups != tree[it->second].groupCount.end()) { 
+                    tree[0].groupCount[*it2] += itGroups->second;
+                }
+            }
+               }
+
+               
+               //print root
+               out << tree[0].level << "\t" << tree[0].rank << "\t" << tree[0].name << "\t" << tree[0].children.size() << "\t" << tree[0].total << "\t";
+               
+        for (set<string>::iterator it = groups.begin(); it != groups.end(); it++) { 
+            map<string, int>:: iterator itGroups = tree[0].groupCount.find(*it);
+            int num = 0;
+            if (itGroups != tree[0].groupCount.end()) { num = itGroups->second; }
+            out << num << '\t';
+        }
+        out << endl;
+               
+               //print rest
+               print(0, out, tree, groups);
+        
+        return 0;
+               
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "print");
+               exit(1);
+       }
+}
+/**************************************************************************************************/
+int MergeTaxSummaryCommand::print(int i, ofstream& out, vector<rawTaxNode>& tree, set<string> groups){
+       try {
+               map<string,int>::iterator it;
+               for(it=tree[i].children.begin();it!=tree[i].children.end();it++){
+                       
+            //print root
+            out << tree[it->second].level << "\t" << tree[it->second].rank << "\t" << tree[it->second].name << "\t" << tree[it->second].children.size() << "\t" << tree[it->second].total << "\t";
+            
+            for (set<string>::iterator it2 = groups.begin(); it2 != groups.end(); it2++) { 
+                map<string, int>:: iterator itGroups = tree[it->second].groupCount.find(*it2);
+                int num = 0;
+                if (itGroups != tree[it->second].groupCount.end()) { num = itGroups->second; }
+                out << num << '\t';
+            }
+            out << endl;
+
+                       print(it->second, out, tree, groups);
+               }
+        
+        return 0;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "MergeTaxSummaryCommand", "print");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+
+
diff --git a/mergetaxsummarycommand.h b/mergetaxsummarycommand.h
new file mode 100644 (file)
index 0000000..d39617a
--- /dev/null
@@ -0,0 +1,47 @@
+//
+//  mergetaxsummarycommand.h
+//  Mothur
+//
+//  Created by Sarah Westcott on 2/13/13.
+//  Copyright (c) 2013 Schloss Lab. All rights reserved.
+//
+
+#ifndef Mothur_mergetaxsummarycommand_h
+#define Mothur_mergetaxsummarycommand_h
+
+#include "mothur.h"
+#include "command.hpp"
+#include "phylosummary.h"
+
+class MergeTaxSummaryCommand : public Command {
+public:
+       MergeTaxSummaryCommand(string);
+       MergeTaxSummaryCommand();
+       ~MergeTaxSummaryCommand(){}
+       
+       vector<string> setParameters();
+       string getCommandName()                 { return "merge.taxsummary";    }
+       string getCommandCategory()             { return "Phylotype Analysis";          }
+       string getHelpString(); 
+    string getOutputPattern(string){ return "";  }     
+       string getCitation() { return "http://www.mothur.org/wiki/Merge.taxsummary"; }
+       string getDescription()         { return "merges tax summary files creating one file"; }
+    
+       
+       int execute(); 
+       void help() { m->mothurOut(getHelpString()); }  
+       
+private:
+       vector<string> fileNames, outputNames;
+       string outputFileName;
+       int numInputFiles;
+       bool abort;
+       
+    int addTaxToTree(vector<rawTaxNode>&, int, int, string, int, map<string, int>);
+    int assignRank(int index, vector<rawTaxNode>& tree);
+    int print(ofstream& out, vector<rawTaxNode>& tree, set<string> groups);
+    int print(int, ofstream& out, vector<rawTaxNode>& tree, set<string> groups);
+};
+
+
+#endif