]> git.donarmstrong.com Git - mothur.git/commitdiff
added binary file operations to mothurout class. added comment to sequence class...
authorSarah Westcott <mothur.westcott@gmail.com>
Tue, 19 Nov 2013 17:15:21 +0000 (12:15 -0500)
committerSarah Westcott <mothur.westcott@gmail.com>
Tue, 19 Nov 2013 17:15:21 +0000 (12:15 -0500)
29 files changed:
Mothur.xcodeproj/project.pbxproj
chimerauchimecommand.cpp
classifyseqscommand.h
cooccurrencecommand.h
countseqscommand.cpp
deuniqueseqscommand.cpp
deuniqueseqscommand.h
getmetacommunitycommand.h
getoturepcommand.cpp
getoturepcommand.h
makebiomcommand.cpp
makecontigscommand.cpp
mothurout.cpp
mothurout.h
nmdscommand.cpp
pcrseqscommand.h
prcseqscommand.cpp
preclustercommand.cpp
screenseqscommand.cpp
sequence.cpp
sequence.hpp
setcurrentcommand.cpp
sffinfocommand.cpp [changed mode: 0644->0755]
sffinfocommand.h
sracommand.cpp [new file with mode: 0644]
sracommand.h [new file with mode: 0644]
summarysharedcommand.cpp
venncommand.cpp
venncommand.h

index 2314b5dc1469993f1d60473d7828a4e1fda633ee..f3b6a09ea7e690a55a31fcbe6b9fc457fa59ca2a 100644 (file)
@@ -38,6 +38,7 @@
                A73DDC3813C4BF64006AAE38 /* mothurmetastats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73DDC3713C4BF64006AAE38 /* mothurmetastats.cpp */; };
                A741744C175CD9B1007DF49B /* makelefsecommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A741744A175CD9B1007DF49B /* makelefsecommand.cpp */; };
                A741FAD215D1688E0067BCC5 /* sequencecountparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A741FAD115D1688E0067BCC5 /* sequencecountparser.cpp */; };
+               A747EC71181EA0F900345732 /* sracommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A747EC70181EA0F900345732 /* sracommand.cpp */; };
                A7496D2E167B531B00CC7D7C /* kruskalwalliscommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7496D2C167B531B00CC7D7C /* kruskalwalliscommand.cpp */; };
                A74A9A9F148E881E00AB5E3E /* spline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74A9A9E148E881E00AB5E3E /* spline.cpp */; };
                A74C06E916A9C0A9008390A3 /* primerdesigncommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74C06E816A9C0A8008390A3 /* primerdesigncommand.cpp */; };
                A741744B175CD9B1007DF49B /* makelefsecommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = makelefsecommand.h; sourceTree = "<group>"; };
                A741FAD115D1688E0067BCC5 /* sequencecountparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sequencecountparser.cpp; sourceTree = "<group>"; };
                A741FAD415D168A00067BCC5 /* sequencecountparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sequencecountparser.h; sourceTree = "<group>"; };
+               A747EC6F181EA0E500345732 /* sracommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sracommand.h; sourceTree = "<group>"; };
+               A747EC70181EA0F900345732 /* sracommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sracommand.cpp; sourceTree = "<group>"; };
                A7496D2C167B531B00CC7D7C /* kruskalwalliscommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kruskalwalliscommand.cpp; sourceTree = "<group>"; };
                A7496D2D167B531B00CC7D7C /* kruskalwalliscommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kruskalwalliscommand.h; sourceTree = "<group>"; };
                A74A9A9D148E881E00AB5E3E /* spline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spline.h; sourceTree = "<group>"; };
                                A7E9B83F12D37EC400DA6239 /* splitabundcommand.cpp */,
                                A7E9B84212D37EC400DA6239 /* splitgroupscommand.h */,
                                A7E9B84112D37EC400DA6239 /* splitgroupscommand.cpp */,
+                               A747EC6F181EA0E500345732 /* sracommand.h */,
+                               A747EC70181EA0F900345732 /* sracommand.cpp */,
                                A7E9B85012D37EC400DA6239 /* subsamplecommand.h */,
                                A7E9B84F12D37EC400DA6239 /* subsamplecommand.cpp */,
                                A7E9B85812D37EC400DA6239 /* summarycommand.h */,
                                A77916E8176F7F7600EEFE18 /* designmap.cpp in Sources */,
                                A7D9378A17B146B5001E90B0 /* wilcox.cpp in Sources */,
                                A7F24FC317EA36600021DC9A /* classifyrfsharedcommand.cpp in Sources */,
+                               A747EC71181EA0F900345732 /* sracommand.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                GCC_OPTIMIZATION_LEVEL = 3;
                                GCC_PREPROCESSOR_DEFINITIONS = (
                                        "MOTHUR_FILES=\"\\\"../../release\\\"\"",
-                                       "VERSION=\"\\\"1.31.0\\\"\"",
-                                       "RELEASE_DATE=\"\\\"5/24/2013\\\"\"",
+                                       "VERSION=\"\\\"1.32.0\\\"\"",
+                                       "RELEASE_DATE=\"\\\"10/31/2013\\\"\"",
                                );
                                GCC_VERSION = "";
                                "GCC_VERSION[arch=*]" = "";
index 346afe213b12fab2baab1e4d23102e526f6ecc8c..3a9f42b22e0715ccf1f68313439342269da81bf8 100644 (file)
@@ -569,6 +569,7 @@ ChimeraUchimeCommand::ChimeraUchimeCommand(string option)  {
 
                        
                        if (hasName && (templatefile != "self")) { m->mothurOut("You have provided a namefile and the reference parameter is not set to self. I am not sure what reference you are trying to use, aborting."); m->mothurOutEndLine(); abort=true; }
+            if (hasCount && (templatefile != "self")) { m->mothurOut("You have provided a countfile and the reference parameter is not set to self. I am not sure what reference you are trying to use, aborting."); m->mothurOutEndLine(); abort=true; }
                        if (hasGroup && (templatefile != "self")) { m->mothurOut("You have provided a group file and the reference parameter is not set to self. I am not sure what reference you are trying to use, aborting."); m->mothurOutEndLine(); abort=true; }
                        
                        //look for uchime exe
index 59d9ee275800195255961639d77fb6c57d97f417..55546f2032af82f9934fb1af4b73891684904cd6 100644 (file)
@@ -166,7 +166,7 @@ static DWORD WINAPI MyClassThreadFunction(LPVOID lpParam){
                //make classify
                Classify* myclassify;
         string outputMethodTag = pDataArray->method + ".";
-               if(pDataArray->method == "bayesian"){   myclassify = new Bayesian(pDataArray->taxonomyFileName, pDataArray->templateFileName, pDataArray->search, pDataArray->kmerSize, pDataArray->cutoff, pDataArray->iters, pDataArray->threadID, pDataArray->flip, pDataArray->writeShortcuts);             }
+               if(pDataArray->method == "wang"){       myclassify = new Bayesian(pDataArray->taxonomyFileName, pDataArray->templateFileName, pDataArray->search, pDataArray->kmerSize, pDataArray->cutoff, pDataArray->iters, pDataArray->threadID, pDataArray->flip, pDataArray->writeShortcuts);             }
                else if(pDataArray->method == "knn"){   myclassify = new Knn(pDataArray->taxonomyFileName, pDataArray->templateFileName, pDataArray->search, pDataArray->kmerSize, pDataArray->gapOpen, pDataArray->gapExtend, pDataArray->match, pDataArray->misMatch, pDataArray->numWanted, pDataArray->threadID);                           }
         else if(pDataArray->method == "zap"){  
             outputMethodTag = pDataArray->search + "_" + outputMethodTag;
@@ -174,7 +174,7 @@ static DWORD WINAPI MyClassThreadFunction(LPVOID lpParam){
             else {  myclassify = new AlignTree(pDataArray->templateFileName, pDataArray->taxonomyFileName, pDataArray->cutoff);  }
         }
                else {
-                       pDataArray->m->mothurOut(pDataArray->search + " is not a valid method option. I will run the command using bayesian.");
+                       pDataArray->m->mothurOut(pDataArray->method + " is not a valid method option. I will run the command using wang.");
                        pDataArray->m->mothurOutEndLine();
                        myclassify = new Bayesian(pDataArray->taxonomyFileName, pDataArray->templateFileName, pDataArray->search, pDataArray->kmerSize, pDataArray->cutoff, pDataArray->iters, pDataArray->threadID, pDataArray->flip, pDataArray->writeShortcuts);     
                }
index 758a9fff0c155261c1efbe60e7a0992d9b215681..94930ac2db71fff68a9fb208385a6cdc2c94ade4 100644 (file)
@@ -26,7 +26,7 @@ public:
        ~CooccurrenceCommand(){}
        
        vector<string> setParameters();
-       string getCommandName()                 { return "Cooccurrence";                        }
+       string getCommandName()                 { return "cooccurrence";                        }
        string getCommandCategory()             { return "Hypothesis Testing";  }
        
        string getHelpString(); 
index 411a814d73671ebb69b43a783e36e31d6263fe45..575ffe844ed0a1134d52ecd0d6aa30531e2fc584 100644 (file)
@@ -628,7 +628,7 @@ map<int, string> CountSeqsCommand::processNameFile(string name) {
             }
                }
                in.close();
-        out.close();
+       
                
         if (rest != "") {
             vector<string> pieces = m->splitWhiteSpace(rest);
@@ -651,6 +651,7 @@ map<int, string> CountSeqsCommand::processNameFile(string name) {
             }
 
         }
+        out.close();
         
         return indexToNames;
     }
@@ -704,7 +705,7 @@ map<int, string> CountSeqsCommand::getGroupNames(string filename, set<string>& n
             }
                }
                in.close();
-        out.close();
+        
         
         if (rest != "") {
             vector<string> pieces = m->splitWhiteSpace(rest);
@@ -726,6 +727,7 @@ map<int, string> CountSeqsCommand::getGroupNames(string filename, set<string>& n
                 }
             }
         }
+        out.close();
                
         for (it = groupIndex.begin(); it != groupIndex.end(); it++) {  indexToGroups[it->second] = it->first;  }
         
index f72a7c9c7e1264265d4d28e1072e087cf501c288..a6c151c38318f4a98917e5b46f81f5b8cd7cfc27 100644 (file)
@@ -9,12 +9,14 @@
 
 #include "deuniqueseqscommand.h"
 #include "sequence.hpp"
+#include "counttable.h"
 
 //**********************************************************************************************************************
 vector<string> DeUniqueSeqsCommand::setParameters(){   
        try {
                CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none","fasta",false,true,true); parameters.push_back(pfasta);
-               CommandParameter pname("name", "InputTypes", "", "", "none", "none", "none","",false,true,true); parameters.push_back(pname);
+               CommandParameter pname("name", "InputTypes", "", "", "namecount", "namecount", "none","name",false,false,true); parameters.push_back(pname);
+        CommandParameter pcount("count", "InputTypes", "", "", "namecount", "namecount", "none","group",false,false,true); parameters.push_back(pcount);
                CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
                CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
                
@@ -31,8 +33,8 @@ vector<string> DeUniqueSeqsCommand::setParameters(){
 string DeUniqueSeqsCommand::getHelpString(){   
        try {
                string helpString = "";
-               helpString += "The deunique.seqs command reads a fastafile and namefile, and creates a fastafile containing all the sequences.\n";
-               helpString += "The deunique.seqs command parameters are fasta and name, both are required, unless you have valid current name and fasta files.\n";
+               helpString += "The deunique.seqs command reads a fastafile and namefile or countfile, and creates a fastafile containing all the sequences. It you provide a count file with group information a group file is also created.\n";
+               helpString += "The deunique.seqs command parameters are fasta, name and count. Fasta is required and you must provide either a name or count file.\n";
                helpString += "The deunique.seqs command should be in the following format: \n";
                helpString += "deunique.seqs(fasta=yourFastaFile, name=yourNameFile) \n";       
                helpString += "Example deunique.seqs(fasta=abrecovery.unique.fasta, name=abrecovery.names).\n";
@@ -49,7 +51,8 @@ string DeUniqueSeqsCommand::getOutputPattern(string type) {
     try {
         string pattern = "";
         
-        if (type == "fasta") {  pattern = "[filename],redundant.fasta"; } 
+        if (type == "fasta") {  pattern = "[filename],redundant.fasta"; }
+        else if (type == "group") {  pattern = "[filename],redundant.groups"; }
         else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
         
         return pattern;
@@ -66,6 +69,7 @@ DeUniqueSeqsCommand::DeUniqueSeqsCommand(){
                setParameters();
                vector<string> tempOutNames;
                outputTypes["fasta"] = tempOutNames;
+        outputTypes["group"] = tempOutNames;
        }
        catch(exception& e) {
                m->errorOut(e, "DeUniqueSeqsCommand", "DeconvoluteCommand");
@@ -98,6 +102,7 @@ DeUniqueSeqsCommand::DeUniqueSeqsCommand(string option)  {
                        //initialize outputTypes
                        vector<string> tempOutNames;
                        outputTypes["fasta"] = tempOutNames;
+            outputTypes["group"] = 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);              
@@ -119,6 +124,14 @@ DeUniqueSeqsCommand::DeUniqueSeqsCommand(string option)  {
                                        //if the user has not given a path then, add inputdir. else leave path alone.
                                        if (path == "") {       parameters["name"] = inputDir + it->second;             }
                                }
+                
+                it = parameters.find("count");
+                               //user has given a template file
+                               if(it != parameters.end()){
+                                       path = m->hasPath(it->second);
+                                       //if the user has not given a path then, add inputdir. else leave path alone.
+                                       if (path == "") {       parameters["count"] = inputDir + it->second;            }
+                               }
                        }
 
                        
@@ -134,16 +147,31 @@ DeUniqueSeqsCommand::DeUniqueSeqsCommand(string option)  {
                        //if the user changes the output directory command factory will send this info to us in the output parameter 
                        outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  
                                outputDir = ""; 
-                               outputDir += m->hasPath(fastaFile); //if user entered a file with a path then preserve it       
                        }
                        
                        nameFile = validParameter.validFile(parameters, "name", true);
                        if (nameFile == "not open") { abort = true; }
-                       else if (nameFile == "not found"){                                      
-                               nameFile = m->getNameFile(); 
+                       else if (nameFile == "not found"){      nameFile = ""; }
+                       else { m->setNameFile(nameFile); }
+            
+            countfile = validParameter.validFile(parameters, "count", true);
+                       if (countfile == "not open") { abort = true;  }
+                       else if (countfile == "not found") { countfile = ""; }
+                       else { m->setCountTableFile(countfile); }
+                       
+            if ((countfile != "") && (nameFile != "")) { m->mothurOut("When executing a deunique.seqs command you must enter ONLY ONE of the following: count or name."); m->mothurOutEndLine(); abort = true; }
+                       
+            
+                       if ((countfile == "") && (nameFile == "")) { //look for currents
+                nameFile = m->getNameFile();
                                if (nameFile != "") { m->mothurOut("Using " + nameFile + " as input file for the name parameter."); m->mothurOutEndLine(); }
-                               else {  m->mothurOut("You have no current namefile and the name parameter is required."); m->mothurOutEndLine(); abort = true; }
-                       }else { m->setNameFile(nameFile); }
+                               else {
+                    countfile = m->getCountTableFile();
+                    if (countfile != "") { m->mothurOut("Using " + countfile + " as input file for the count parameter."); m->mothurOutEndLine(); }
+                    else {  m->mothurOut("[ERROR]: You have no current name or count files one is required."); m->mothurOutEndLine(); abort = true; }
+                }
+            }
+
                }
 
        }
@@ -160,7 +188,9 @@ int DeUniqueSeqsCommand::execute() {
 
                //prepare filenames and open files
                ofstream out;
-               string outFastaFile = m->getRootName(m->getSimpleName(fastaFile));
+        string thisOutputDir = outputDir;
+               if (outputDir == "") {  thisOutputDir += m->hasPath(fastaFile);  }
+               string outFastaFile = thisOutputDir + m->getRootName(m->getSimpleName(fastaFile));
                int pos = outFastaFile.find("unique");
                if (pos != string::npos) { outFastaFile = outputDir + outFastaFile.substr(0, pos); }
         else { outFastaFile = outputDir + outFastaFile; }
@@ -169,55 +199,92 @@ int DeUniqueSeqsCommand::execute() {
         outFastaFile = getOutputFileName("fasta", variables);
                m->openOutputFile(outFastaFile, out);
                
-               readNamesFile();
-               if (m->control_pressed) {  out.close(); outputTypes.clear(); m->mothurRemove(outFastaFile); return 0; }
+               map<string, string> nameMap;
+        CountTable ct;
+        ofstream outGroup;
+        string outGroupFile;
+        vector<string> groups;
+        if (nameFile != "") { m->readNames(nameFile, nameMap); }
+        else {
+            ct.readTable(countfile, true, false);
+            
+            if (ct.hasGroupInfo()) {
+                thisOutputDir = outputDir;
+                if (outputDir == "") {  thisOutputDir += m->hasPath(countfile);  }
+                outGroupFile = thisOutputDir + m->getRootName(m->getSimpleName(countfile));
+                variables["[filename]"] = outGroupFile;
+                outGroupFile = getOutputFileName("group", variables);
+                m->openOutputFile(outGroupFile, outGroup);
+                groups = ct.getNamesOfGroups();
+            }
+        }
+        
+               if (m->control_pressed) {  out.close(); outputTypes.clear(); m->mothurRemove(outFastaFile); if (countfile != "") { if (ct.hasGroupInfo()) { outGroup.close(); m->mothurRemove(outGroupFile); } } return 0; }
                
                ifstream in;
                m->openInputFile(fastaFile, in);
                
                while (!in.eof()) {
                
-                       if (m->control_pressed) { in.close(); out.close(); outputTypes.clear(); m->mothurRemove(outFastaFile); return 0; }
+                       if (m->control_pressed) { in.close(); out.close(); outputTypes.clear(); m->mothurRemove(outFastaFile); if (countfile != "") { if (ct.hasGroupInfo()) { outGroup.close(); m->mothurRemove(outGroupFile); } } return 0; }
                        
                        Sequence seq(in); m->gobble(in);
                        
                        if (seq.getName() != "") {
                                
-                               //look for sequence name in nameMap
-                               map<string, string>::iterator it = nameMap.find(seq.getName());
-                               
-                               if (it == nameMap.end()) {      m->mothurOut("[ERROR]: Your namefile does not contain " + seq.getName() + ", aborting."); m->mothurOutEndLine(); m->control_pressed = true; }
-                               else {
-                                       vector<string> names;
-                                       m->splitAtComma(it->second, names);
-                                       
-                                       //output sequences
-                                       for (int i = 0; i < names.size(); i++) {
-                                               out << ">" << names[i] << endl;
-                                               out << seq.getAligned() << endl;
-                                       }
-                                       
-                                       //remove seq from name map so we can check for seqs in namefile not in fastafile later
-                                       nameMap.erase(it);
-                               }
+                if (nameFile != "") {
+                    //look for sequence name in nameMap
+                    map<string, string>::iterator it = nameMap.find(seq.getName());
+                    
+                    if (it == nameMap.end()) { m->mothurOut("[ERROR]: Your namefile does not contain " + seq.getName() + ", aborting."); m->mothurOutEndLine(); m->control_pressed = true; }
+                    else {
+                        vector<string> names;
+                        m->splitAtComma(it->second, names);
+                        
+                        //output sequences
+                        for (int i = 0; i < names.size(); i++) {
+                            out << ">" << names[i] << endl;
+                            out << seq.getAligned() << endl;
+                        }
+                        
+                        //remove seq from name map so we can check for seqs in namefile not in fastafile later
+                        nameMap.erase(it);
+                    }
+                }else {
+                    if (ct.hasGroupInfo()) {
+                        vector<int> groupCounts = ct.getGroupCounts(seq.getName());
+                        int count = 1;
+                        for (int i = 0; i < groups.size(); i++) {
+                            for (int j = 0; j < groupCounts[i]; j++) {
+                                outGroup << seq.getName()+"_"+toString(count) << '\t' << groups[i] << endl; count++;
+                            }
+                        }
+                        
+                    }
+                    
+                    int numReps = ct.getNumSeqs(seq.getName()); //will report error and set m->control_pressed if not found
+                    for (int i = 0; i < numReps; i++) {
+                        out << ">" << seq.getName()+"_"+toString(i+1) << endl;
+                        out << seq.getAligned() << endl;
+                    }
+                }
                        }
                }
                in.close();
-               out.close(); 
+               out.close();
+        if (countfile != "") { if (ct.hasGroupInfo()) { outGroup.close(); } }
                
-               if (nameMap.size() != 0) { //then there are names in the namefile not in the fastafile
-                       for (map<string, string>::iterator it = nameMap.begin(); it != nameMap.end(); it++) {  
-                               m->mothurOut(it->first + " is not in your fasta file, but is in your name file. Please correct."); m->mothurOutEndLine();
-                       }
-               }
-                               
-               if (m->control_pressed) { outputTypes.clear(); m->mothurRemove(outFastaFile); return 0; }
+                                               
+               if (m->control_pressed) { outputTypes.clear(); m->mothurRemove(outFastaFile); if (countfile != "") { if (ct.hasGroupInfo()) {  m->mothurRemove(outGroupFile); } }return 0; }
                
+        outputNames.push_back(outFastaFile);  outputTypes["fasta"].push_back(outFastaFile);
+        if (countfile != "") { if (ct.hasGroupInfo()) { outputNames.push_back(outGroupFile);  outputTypes["group"].push_back(outGroupFile); } }
+        
                m->mothurOutEndLine();
                m->mothurOut("Output File Names: "); m->mothurOutEndLine();
-               m->mothurOut(outFastaFile); m->mothurOutEndLine();      
-               outputNames.push_back(outFastaFile);  outputTypes["fasta"].push_back(outFastaFile);  
-               m->mothurOutEndLine();
+               for(int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();      }
+        m->mothurOutEndLine();
+               
                
                //set fasta file as new current fastafile
                string current = "";
@@ -225,47 +292,18 @@ int DeUniqueSeqsCommand::execute() {
                if (itTypes != outputTypes.end()) {
                        if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); }
                }
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "DeUniqueSeqsCommand", "execute");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int DeUniqueSeqsCommand::readNamesFile() {
-       try {
-               
-               ifstream inNames;
-               m->openInputFile(nameFile, inNames);
-               
-               string name, names;
-               map<string, string>::iterator it;
-       
-               while(inNames){
-                       
-                       if(m->control_pressed) { break; }
-                       
-                       inNames >> name;        m->gobble(inNames);             
-                       inNames >> names;               
-                       
-                       it = nameMap.find(name);
-                       
-                       if (it == nameMap.end()) {      nameMap[name] = names; }
-                       else { m->mothurOut("[ERROR]: Your namefile already contains " + name + ", aborting."); m->mothurOutEndLine(); m->control_pressed = true; }
-                                       
-                       m->gobble(inNames);
+        
+        itTypes = outputTypes.find("group");
+               if (itTypes != outputTypes.end()) {
+                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setGroupFile(current); }
                }
-               inNames.close();
+
                
                return 0;
-
        }
        catch(exception& e) {
-               m->errorOut(e, "DeUniqueSeqsCommand", "readNamesFile");
+               m->errorOut(e, "DeUniqueSeqsCommand", "execute");
                exit(1);
        }
 }
-
 /**************************************************************************************/
index a6d467a16a96c56ca3f1282d7c7fbbdfbdf02ca7..042ff498fce19a60cd51d7b1393ec2cd4074123c 100644 (file)
@@ -36,13 +36,10 @@ public:
        
 private:
 
-       string fastaFile, nameFile, outputDir;
+       string fastaFile, nameFile, outputDir, countfile;
        vector<string> outputNames;
        bool abort;
-       
-       map<string, string> nameMap;
-       
-       int readNamesFile();
+
        
 };
 
index d7b163e93f1003fdb0dcd73bdb5984de2eee208b..7697430cca6164b695ed92526dd190926ec1eb5e 100644 (file)
@@ -146,7 +146,7 @@ static DWORD WINAPI MyMetaCommunityThreadFunction(LPVOID lpParam){
             pDataArray->outputNames.push_back(pDataArray->matrix[i]);
             
             findQ->printZMatrix(pDataArray->matrix[i], pDataArray->m->getGroups());
-            findQ->printRelAbund(pDataArray->relabunds[i], pDataArray->m->currentBinLabels);
+            findQ->printRelAbund(pDataArray->relabunds[i], pDataArray->m->currentSharedBinLabels);
             
             if(pDataArray->optimizegap != -1 && (numPartitions - pDataArray->minPartition) >= pDataArray->optimizegap && numPartitions >= pDataArray->minpartitions){ break; }
             
index 7e71a1a836b2e6306b40d67f5cdce0d7f35dbcdc..61092372b18ae196a652d0b0f66c6b04d22d0266 100644 (file)
@@ -23,7 +23,7 @@ inline bool compareName(repStruct left, repStruct right){
 //********************************************************************************************************************
 //sorts lowest to highest
 inline bool compareBin(repStruct left, repStruct right){
-       return (left.bin < right.bin);  
+       return (left.simpleBin < right.simpleBin);
 }
 //********************************************************************************************************************
 //sorts lowest to highest
@@ -979,6 +979,7 @@ int GetOTURepCommand::process(ListVector* processList) {
                }
                
                //for each bin in the list vector
+        vector<string> binLabels = processList->getLabels();
                for (int i = 0; i < processList->size(); i++) {
                        if (m->control_pressed) { 
                                out.close();  
@@ -999,7 +1000,7 @@ int GetOTURepCommand::process(ListVector* processList) {
                        
                        if (Groups.size() == 0) {
                                nameRep = findRep(namesInBin, "");
-                               newNamesOutput << i << '\t' << nameRep << '\t';
+                               newNamesOutput << binLabels[i] << '\t' << nameRep << '\t';
                 
                 //put rep at first position in names line
                 string outputString = nameRep + ",";
@@ -1042,7 +1043,7 @@ int GetOTURepCommand::process(ListVector* processList) {
                                                nameRep = findRep(NamesInGroup[Groups[j]], Groups[j]);
                                                
                                                //output group rep and other members of this group
-                                               (*(filehandles[Groups[j]])) << i << '\t' << nameRep << '\t';
+                                               (*(filehandles[Groups[j]])) << binLabels[i] << '\t' << nameRep << '\t';
                                                
                         //put rep at first position in names line
                         string outputString = nameRep + ",";
@@ -1100,7 +1101,6 @@ int GetOTURepCommand::processFastaNames(string filename, string label, FastaMap*
                ifstream in;
                m->openInputFile(filename, in);
                
-               int i = 0;
         string tempGroup = "";
         in >> tempGroup; m->gobble(in);
         
@@ -1112,8 +1112,8 @@ int GetOTURepCommand::processFastaNames(string filename, string label, FastaMap*
     
         int thistotal = 0;
                while (!in.eof()) {
-                       string rep, binnames;
-                       in >> i >> rep >> binnames; m->gobble(in);
+                       string rep, binnames, binLabel;
+                       in >> binLabel >> rep >> binnames; m->gobble(in);
                        
                        vector<string> names;
                        m->splitAtComma(binnames, names);
@@ -1178,7 +1178,7 @@ int GetOTURepCommand::processFastaNames(string filename, string label, FastaMap*
 
                        if (sequence != "not found") {
                                if (sorted == "") { //print them out
-                                       rep = rep + "\t" + toString(i+1);
+                                       rep = rep + "\t" + binLabel;
                                        rep = rep + "|" + toString(binsize);
                                        if (group != "") {
                                                rep = rep + "|" + group;
@@ -1186,7 +1186,9 @@ int GetOTURepCommand::processFastaNames(string filename, string label, FastaMap*
                                        out << ">" << rep << endl;
                                        out << sequence << endl;
                                }else { //save them
-                                       repStruct newRep(rep, i+1, binsize, group);
+                    int simpleLabel;
+                    m->mothurConvert(m->getSimpleLabel(binLabel), simpleLabel);
+                                       repStruct newRep(rep, binLabel, simpleLabel, binsize, group);
                                        reps.push_back(newRep);
                                }
                        }else { 
@@ -1204,7 +1206,7 @@ int GetOTURepCommand::processFastaNames(string filename, string label, FastaMap*
                        //print them
                        for (int i = 0; i < reps.size(); i++) {
                                string sequence = fasta->getSequence(reps[i].name);
-                               string outputName = reps[i].name + "\t" + toString(reps[i].bin);
+                               string outputName = reps[i].name + "\t" + reps[i].bin;
                                outputName = outputName + "|" + toString(reps[i].size);
                                if (reps[i].group != "") {
                                        outputName = outputName + "|" + reps[i].group;
@@ -1245,7 +1247,6 @@ int GetOTURepCommand::processNames(string filename, string label) {
                ifstream in;
                m->openInputFile(filename, in);
                
-               int i = 0;
                string rep, binnames;
         
         string tempGroup = "";
@@ -1259,7 +1260,8 @@ int GetOTURepCommand::processNames(string filename, string label) {
         
                while (!in.eof()) {
                        if (m->control_pressed) { break; }
-                       in >> i >> rep >> binnames; m->gobble(in);
+            string binLabel;
+                       in >> binLabel >> rep >> binnames; m->gobble(in);
             
                        if (countfile == "") { out2 << rep << '\t' << binnames << endl; }
             else {
index ca3439d809f96f6eff93dcf3948abd1a8274a7f5..daf5bc16cbd3640093502d315af1f35008300ef0 100644 (file)
@@ -24,12 +24,13 @@ typedef map<int, float> SeqMap;
 
 struct repStruct {
                string name;
-               int     bin;
+               string bin;
+        int simpleBin;
                int size;
                string group;
                
                repStruct(){}
-               repStruct(string n, int b, int s, string g) : name(n), bin(b), size(s), group(g) {}
+               repStruct(string n, string b, int sb, int s, string g) : name(n), bin(b), size(s), group(g), simpleBin(sb) { }
                ~repStruct() {}
 };
 
index 826cf372c7b4ae52f5e230e839a576adb2ec58b5..4c350922608489b89156c01244c170d8688d930d 100644 (file)
@@ -824,7 +824,7 @@ map<string, string> MakeBiomCommand::readGGOtuMap(){
             vector<string> pieces = m->splitWhiteSpace(line);
             
             if (pieces.size() != 0) {
-                string otuID = pieces[0];
+                string otuID = pieces[1];
                 for (int i = 1; i < pieces.size(); i++) {  otuMap[pieces[i]] = otuID; }
             }
         }
index 87027f4df5e0166f25852fec44cd6cfa120c90a7..bf27d264ec5f06f15a3d25b7ac8c5952cd03e17a 100644 (file)
@@ -1298,9 +1298,11 @@ vector< vector<string> > MakeContigsCommand::readFastqFiles(unsigned long int& c
         
         if (uniques.size() != 0) {
             for (itUniques = uniques.begin(); itUniques != uniques.end(); itUniques++) {
+                if (m->control_pressed) { break; }
                 m->mothurOut("[WARNING]: did not find paired read for " + itUniques->first + ", ignoring.\n");
             }
             for (map<string, pairFastqRead>:: iterator it = pairUniques.begin(); it != pairUniques.end(); it++) {
+                if (m->control_pressed) { break; }
                 m->mothurOut("[WARNING]: did not find paired read for " + (it->first).substr(1) + ", ignoring.\n");
             }
             m->mothurOutEndLine();
@@ -1660,6 +1662,7 @@ fastqRead MakeContigsCommand::readFastq(ifstream& in, bool& ignore){
         
         vector<int> qualScores = convertQual(quality);
         
+        m->checkName(name);
         read.name = name;
         read.sequence = sequence;
         read.scores = qualScores;
index e7f0c8e3b764c66362f0004b7dbabc4f4c6fdaa3..0f24cb2dc362c679dd16ed0eb7c50444f07e7a6e 100644 (file)
@@ -779,6 +779,8 @@ string MothurOut::getPathName(string longName){
 bool MothurOut::dirCheck(string& dirName){
        try {
         
+        if (dirName == "") { return false; }
+        
         string tag = "";
         #ifdef USE_MPI
             int pid; 
@@ -1140,6 +1142,105 @@ int MothurOut::openInputFile(string fileName, ifstream& fileHandle){
                exit(1);
        }       
 }
+/***********************************************************************/
+int MothurOut::openInputFileBinary(string fileName, ifstream& fileHandle){
+       try {
+        
+               //get full path name
+               string completeFileName = getFullPathName(fileName);
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+#ifdef USE_COMPRESSION
+        // check for gzipped or bzipped file
+        if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
+            string tempName = string(tmpnam(0));
+            mkfifo(tempName.c_str(), 0666);
+            int fork_result = fork();
+            if (fork_result < 0) {
+                cerr << "Error forking.\n";
+                exit(1);
+            } else if (fork_result == 0) {
+                string command = (endsWith(completeFileName, ".gz") ? "zcat " : "bzcat ") + completeFileName + string(" > ") + tempName;
+                cerr << "Decompressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
+                system(command.c_str());
+                cerr << "Done decompressing " << completeFileName << "\n";
+                mothurRemove(tempName);
+                exit(EXIT_SUCCESS);
+            } else {
+                cerr << "waiting on child process " << fork_result << "\n";
+                completeFileName = tempName;
+            }
+        }
+#endif
+#endif
+        
+               fileHandle.open(completeFileName.c_str(), ios::binary);
+               if(!fileHandle) {
+                       mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
+                       return 1;
+               }
+               else {
+                       //check for blank file
+                       gobble(fileHandle);
+                       if (fileHandle.eof()) { mothurOut("[ERROR]: " + completeFileName + " is blank. Please correct."); mothurOutEndLine();  }
+                       
+                       return 0;
+               }
+       }
+       catch(exception& e) {
+               errorOut(e, "MothurOut", "openInputFileBinary");
+               exit(1);
+       }       
+}
+/***********************************************************************/
+int MothurOut::openInputFileBinary(string fileName, ifstream& fileHandle, string noerror){
+       try {
+        
+               //get full path name
+               string completeFileName = getFullPathName(fileName);
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+#ifdef USE_COMPRESSION
+        // check for gzipped or bzipped file
+        if (endsWith(completeFileName, ".gz") || endsWith(completeFileName, ".bz2")) {
+            string tempName = string(tmpnam(0));
+            mkfifo(tempName.c_str(), 0666);
+            int fork_result = fork();
+            if (fork_result < 0) {
+                cerr << "Error forking.\n";
+                exit(1);
+            } else if (fork_result == 0) {
+                string command = (endsWith(completeFileName, ".gz") ? "zcat " : "bzcat ") + completeFileName + string(" > ") + tempName;
+                cerr << "Decompressing " << completeFileName << " via temporary named pipe " << tempName << "\n";
+                system(command.c_str());
+                cerr << "Done decompressing " << completeFileName << "\n";
+                mothurRemove(tempName);
+                exit(EXIT_SUCCESS);
+            } else {
+                cerr << "waiting on child process " << fork_result << "\n";
+                completeFileName = tempName;
+            }
+        }
+#endif
+#endif
+        
+               fileHandle.open(completeFileName.c_str(), ios::binary);
+               if(!fileHandle) {
+                       //mothurOut("[ERROR]: Could not open " + completeFileName); mothurOutEndLine();
+                       return 1;
+               }
+               else {
+                       //check for blank file
+                       gobble(fileHandle);
+                       //if (fileHandle.eof()) { mothurOut("[ERROR]: " + completeFileName + " is blank. Please correct."); mothurOutEndLine();  }
+                       
+                       return 0;
+               }
+       }
+       catch(exception& e) {
+               errorOut(e, "MothurOut", "openInputFileBinary - no error");
+               exit(1);
+       }
+}
+
 /***********************************************************************/
 
 int MothurOut::renameFile(string oldName, string newName){
@@ -1289,6 +1390,36 @@ int MothurOut::appendFiles(string temp, string filename) {
                exit(1);
        }       
 }
+/**************************************************************************************************/
+int MothurOut::appendBinaryFiles(string temp, string filename) {
+       try{
+               ofstream output;
+               ifstream input;
+        
+               //open output file in append mode
+               openOutputFileBinaryAppend(filename, output);
+               int ableToOpen = openInputFileBinary(temp, input, "no error");
+               
+               if (ableToOpen == 0) { //you opened it
+            
+            char buffer[4096];
+            while (!input.eof()) {
+                input.read(buffer, 4096);
+                output.write(buffer, input.gcount());
+            }
+                       input.close();
+               }
+               
+               output.close();
+               
+               return ableToOpen;
+       }
+       catch(exception& e) {
+               errorOut(e, "MothurOut", "appendBinaryFiles");
+               exit(1);
+       }       
+}
+
 /**************************************************************************************************/
 int MothurOut::appendFilesWithoutHeaders(string temp, string filename) {
        try{
index 1caa1fe5814679a86e8026f1ec7a54d228dee44e..1747b1480c732ae42f361940ff57dcbe151bbc7b 100644 (file)
@@ -82,6 +82,7 @@ class MothurOut {
                vector<unsigned long long> setFilePosFasta(string, int&);
                string sortFile(string, string);
                int appendFiles(string, string);
+        int appendBinaryFiles(string, string);
         int appendFilesWithoutHeaders(string, string);
                int renameFile(string, string); //oldname, newname
                string getFullPathName(string);
@@ -97,6 +98,8 @@ class MothurOut {
                int openOutputFileAppend(string, ofstream&);
         int openOutputFileBinaryAppend(string, ofstream&);
                int openInputFile(string, ifstream&);
+        int openInputFileBinary(string, ifstream&);
+        int openInputFileBinary(string, ifstream&, string);
                int openInputFile(string, ifstream&, string); //no error given
     
         bool checkLocations(string&, string);  //filename, inputDir. checks for file in ./, inputdir, default and mothur's exe location.  Returns false if cant be found. If found completes name with location
index a90ed2965888928f4a90049fe04fe888d773c450..82d2d7f2c2c4335f76b3b8909031359e014e8963 100644 (file)
@@ -288,7 +288,7 @@ int NMDSCommand::execute(){
                outBest.setf(ios::fixed, ios::floatfield);
                outBest.setf(ios::showpoint);
                
-               outBest << '\t';
+               outBest << "group" << '\t';
                for (int k = 0; k < bestConfig.size(); k++) { outBest << "axis" << (k+1) << '\t'; }
                outBest << endl;
                
index f4481ab9402f5a5362b6d864980bbc9b6e1e101f..ba9062437d78df8aa337bc5948b603b1acf8e351 100644 (file)
@@ -60,7 +60,7 @@ private:
     int readCount(set<string>);
     bool readOligos();
     bool readEcoli();
-       int driverPcr(string, string, string, string, set<string>&, linePair, int&, int&, bool&);
+       int driverPcr(string, string, string, string, set<string>&, linePair, int&, bool&);
        int createProcesses(string, string, string, set<string>&);
     bool isAligned(string, map<int, int>&);
     string reverseOligo(string);
@@ -98,8 +98,8 @@ struct pcrData {
         nomatch = nm;
         keepprimer = kp;
         keepdots = kd;
+        end = en;
                start = st;
-               end = en;
         length = l;
                fstart = fst;
         fend = fen;
@@ -142,8 +142,8 @@ static DWORD WINAPI MyPcrThreadFunction(LPVOID lpParam){
         set<int> lengths;
         //pdiffs, bdiffs, primers, barcodes, revPrimers
         map<string, int> faked;
-        vector< set<int> > locations; //locations[0] = beginning locations, locations[1] = ending locations
-        locations.resize(2);
+        set<int> locations; //locations = beginning locations
+        
         TrimOligos trim(pDataArray->pdiffs, 0, pDataArray->primers, faked, pDataArray->revPrimer);
                
                for(int i = 0; i < pDataArray->fend; i++){ //end is the number of sequences to process
@@ -192,7 +192,7 @@ static DWORD WINAPI MyPcrThreadFunction(LPVOID lpParam){
                                     else            {
                                         currSeq.setAligned(currSeq.getAligned().substr(mapAligned[primerEnd-1]+1));
                                         if (pDataArray->fileAligned) {
-                                            thisPStart = mapAligned[primerEnd-1]+1; //locations[0].insert(mapAligned[primerEnd-1]+1);
+                                            thisPStart = mapAligned[primerEnd-1]+1; //locations.insert(mapAligned[primerEnd-1]+1);
                                             locationsString += currSeq.getName() + "\t" + toString(mapAligned[primerEnd-1]+1) + "\n";
                                         }
 }
@@ -202,7 +202,7 @@ static DWORD WINAPI MyPcrThreadFunction(LPVOID lpParam){
                                     else            {
                                         currSeq.setAligned(currSeq.getAligned().substr(mapAligned[primerStart]));
                                         if (pDataArray->fileAligned) {
-                                            thisPStart = mapAligned[primerStart]; //locations[0].insert(mapAligned[primerStart]);
+                                            thisPStart = mapAligned[primerStart]; //locations.insert(mapAligned[primerStart]);
                                             locationsString += currSeq.getName() + "\t" + toString(mapAligned[primerStart]) + "\n";
                                         }
                                     }
@@ -237,7 +237,7 @@ static DWORD WINAPI MyPcrThreadFunction(LPVOID lpParam){
                                     else            {
                                         currSeq.setAligned(currSeq.getAligned().substr(0, mapAligned[primerStart]));
                                         if (pDataArray->fileAligned) {
-                                            thisPEnd = mapAligned[primerStart]; //locations[1].insert(mapAligned[primerStart]);
+                                            thisPEnd = mapAligned[primerStart]; //locations.insert(mapAligned[primerStart]);
                                             locationsString += currSeq.getName() + "\t" + toString(mapAligned[primerStart]) + "\n";
                                         }
 
@@ -248,7 +248,7 @@ static DWORD WINAPI MyPcrThreadFunction(LPVOID lpParam){
                                     else            {
                                         currSeq.setAligned(currSeq.getAligned().substr(0, mapAligned[primerEnd-1]+1));
                                         if (pDataArray->fileAligned) {
-                                            thisPEnd = mapAligned[primerEnd-1]+1; //locations[1].insert(mapAligned[primerEnd-1]+1);
+                                            thisPEnd = mapAligned[primerEnd-1]+1; //locations.insert(mapAligned[primerEnd-1]+1);
                                             locationsString += currSeq.getName() + "\t" + toString(mapAligned[primerEnd-1]+1) + "\n";
                                         }
 
@@ -303,8 +303,7 @@ static DWORD WINAPI MyPcrThreadFunction(LPVOID lpParam){
                                if(goodSeq == 1)    {
                     currSeq.printSequence(goodFile);
                     if (locationsString != "") { locationsFile << locationsString; }
-                    if (thisPStart != -1)   { locations[0].insert(thisPStart);  }
-                    if (thisPEnd != -1)     { locations[1].insert(thisPEnd);    }
+                    if (thisPStart != -1)   { locations.insert(thisPStart);  }
                 }
                                else {  
                     pDataArray->badSeqNames.insert(currSeq.getName()); 
@@ -327,9 +326,8 @@ static DWORD WINAPI MyPcrThreadFunction(LPVOID lpParam){
         if (pDataArray->m->debug) { pDataArray->m->mothurOut("[DEBUG]: fileAligned = " + toString(pDataArray->fileAligned) +'\n'); }
         
         if (pDataArray->fileAligned && !pDataArray->keepdots) { //print out smallest start value and largest end value
-            if ((locations[0].size() > 1) || (locations[1].size() > 1)) { pDataArray->adjustNeeded = true; }
-            if (pDataArray->primers.size() != 0)    {   set<int>::iterator it = locations[0].begin();  pDataArray->pstart = *it;  }
-            if (pDataArray->revPrimer.size() != 0)  {   set<int>::reverse_iterator it2 = locations[1].rbegin();  pDataArray->pend = *it2; }
+            if (locations.size() > 1) { pDataArray->adjustNeeded = true; }
+            if (pDataArray->primers.size() != 0)    {   set<int>::iterator it = locations.begin();  pDataArray->pstart = *it;  }
         }
         
         return 0;
index cb8dd490e3a53a40edce7d1d52fffada445fac13..a1eae4687c4d49b2ce8e0f90895a36a994aec689 100644 (file)
@@ -443,13 +443,13 @@ int PcrSeqsCommand::createProcesses(string filename, string goodFileName, string
                                process++;
                        }else if (pid == 0){
                 string locationsFile = toString(getpid()) + ".temp";
-                               num = driverPcr(filename, goodFileName + toString(getpid()) + ".temp", badFileName + toString(getpid()) + ".temp", locationsFile, badSeqNames, lines[process], pstart, pend, adjustNeeded);
+                               num = driverPcr(filename, goodFileName + toString(getpid()) + ".temp", badFileName + toString(getpid()) + ".temp", locationsFile, badSeqNames, lines[process], pstart, adjustNeeded);
                                
                                //pass numSeqs to parent
                                ofstream out;
                                string tempFile = filename + toString(getpid()) + ".num.temp";
                                m->openOutputFile(tempFile, out);
-                out << pstart << '\t' << pend << '\t' << adjustNeeded << endl;
+                out << pstart << '\t' << adjustNeeded << endl;
                                out << num << '\t' << badSeqNames.size() << endl;
                 for (set<string>::iterator it = badSeqNames.begin(); it != badSeqNames.end(); it++) {
                     out << (*it) << endl;
@@ -465,7 +465,7 @@ int PcrSeqsCommand::createProcesses(string filename, string goodFileName, string
                }
                
         string locationsFile = toString(getpid()) + ".temp";
-        num = driverPcr(filename, goodFileName, badFileName, locationsFile, badSeqNames, lines[0], pstart, pend, adjustNeeded);
+        num = driverPcr(filename, goodFileName, badFileName, locationsFile, badSeqNames, lines[0], pstart, adjustNeeded);
         
                //force parent to wait until all the processes are done
                for (int i=0;i<processIDS.size();i++) { 
@@ -478,20 +478,16 @@ int PcrSeqsCommand::createProcesses(string filename, string goodFileName, string
                        string tempFile =  filename + toString(processIDS[i]) + ".num.temp";
                        m->openInputFile(tempFile, in);
             int numBadNames = 0; string name = "";
-            int tpstart = -1; int tpend = -1; bool tempAdjust = false;
+            int tpstart = -1; bool tempAdjust = false;
             
                        if (!in.eof()) {
-                in >> tpstart >> tpend >> tempAdjust; m->gobble(in);
+                in >> tpstart >> tempAdjust; m->gobble(in);
                 
                 if (tempAdjust) { adjustNeeded = true; }
                 if (tpstart != -1)   {
                     if (tpstart != pstart) { adjustNeeded = true; }
                     if (tpstart < pstart) { pstart = tpstart; } //smallest start
                 } 
-                if (tpend != -1)     {
-                    if (tpend != pend) { adjustNeeded = true; }
-                    if (tpend > pend) { pend = tpend; } //largest end
-                } 
                 int tempNum = 0; in >> tempNum >> numBadNames; num += tempNum; m->gobble(in);
             }
             for (int j = 0; j < numBadNames; j++) {
@@ -541,7 +537,7 @@ int PcrSeqsCommand::createProcesses(string filename, string goodFileName, string
                }
                
         //do your part
-        num = driverPcr(filename, (goodFileName+toString(processors-1)+".temp"), (badFileName+toString(processors-1)+".temp"), (locationsFile+toString(processors-1)+".temp"), badSeqNames, lines[processors-1], pstart, pend, adjustNeeded);
+        num = driverPcr(filename, (goodFileName+toString(processors-1)+".temp"), (badFileName+toString(processors-1)+".temp"), (locationsFile+toString(processors-1)+".temp"), badSeqNames, lines[processors-1], pstart, adjustNeeded);
         processIDS.push_back(processors-1);
         
                //Wait until all threads have terminated.
@@ -558,11 +554,7 @@ int PcrSeqsCommand::createProcesses(string filename, string goodFileName, string
                 if (pDataArray[i]->pstart != pstart) { adjustNeeded = true; }
                 if (pDataArray[i]->pstart < pstart) { pstart = pDataArray[i]->pstart; }
             } //smallest start
-            if (pDataArray[i]->pend != -1)     {
-                if (pDataArray[i]->pend != pend) { adjustNeeded = true; }
-                if (pDataArray[i]->pend > pend) { pend = pDataArray[i]->pend; }
-            } //largest end
-
+            
             for (set<string>::iterator it = pDataArray[i]->badSeqNames.begin(); it != pDataArray[i]->badSeqNames.end(); it++) {        badSeqNames.insert(*it);       }
                        CloseHandle(hThreadArray[i]);
                        delete pDataArray[i];
@@ -580,7 +572,43 @@ int PcrSeqsCommand::createProcesses(string filename, string goodFileName, string
                }
         
 #endif 
-        if (fileAligned && adjustNeeded) { adjustDots(goodFileName, locationsFile, pstart, pend); }
+        
+        
+
+        if (fileAligned) {
+            //find pend - pend is the biggest ending value, but we must account for when we adjust the start.  That adjustment may make the "new" end larger then the largest end. So lets find out what that "new" end will be.
+            ifstream inLocations;
+            m->openInputFile(locationsFile, inLocations);
+            
+            while(!inLocations.eof()) {
+                
+                if (m->control_pressed) { break; }
+                
+                string name = "";
+                int thisStart = -1; int thisEnd = -1;
+                if (primers.size() != 0)    { inLocations >> name >> thisStart; m->gobble(inLocations); }
+                if (revPrimer.size() != 0)  { inLocations >> name >> thisEnd;   m->gobble(inLocations); }
+                else { pend = -1; break; }
+                
+                int myDiff = 0;
+                if (pstart != -1) {
+                    if (thisStart != -1) {
+                        if (thisStart != pstart) { myDiff += (thisStart - pstart); }
+                    }
+                }
+                
+                int myEnd = thisEnd + myDiff;
+                //cout << name << '\t' << thisStart << '\t' << thisEnd << " diff = " << myDiff << '\t' << myEnd << endl;
+                
+                if (thisEnd != -1) {
+                    if (myEnd > pend) { pend = myEnd; }
+                }
+                
+            }
+            inLocations.close();
+            
+            adjustDots(goodFileName, locationsFile, pstart, pend);
+        }
         
         return num;
         
@@ -592,7 +620,7 @@ int PcrSeqsCommand::createProcesses(string filename, string goodFileName, string
 }
 
 //**********************************************************************************************************************
-int PcrSeqsCommand::driverPcr(string filename, string goodFasta, string badFasta, string locationsName, set<string>& badSeqNames, linePair filePos, int& pstart, int& pend, bool& adjustNeeded){
+int PcrSeqsCommand::driverPcr(string filename, string goodFasta, string badFasta, string locationsName, set<string>& badSeqNames, linePair filePos, int& pstart, bool& adjustNeeded){
        try {
                ofstream goodFile;
                m->openOutputFile(goodFasta, goodFile);
@@ -611,8 +639,7 @@ int PcrSeqsCommand::driverPcr(string filename, string goodFasta, string badFasta
                bool done = false;
                int count = 0;
         set<int> lengths;
-        vector< set<int> > locations; //locations[0] = beginning locations, locations[1] = ending locations
-        locations.resize(2);
+        set<int> locations; //locations[0] = beginning locations, 
         
         //pdiffs, bdiffs, primers, barcodes, revPrimers
         map<string, int> faked;
@@ -759,9 +786,8 @@ int PcrSeqsCommand::driverPcr(string filename, string goodFasta, string badFasta
                                if(goodSeq == 1)    {
                     currSeq.printSequence(goodFile);
                     if (m->debug) { m->mothurOut("[DEBUG]: " + locationsString + "\n"); }
+                    if (thisPStart != -1)   { locations.insert(thisPStart);  }
                     if (locationsString != "") { locationsFile << locationsString; }
-                    if (thisPStart != -1)   { locations[0].insert(thisPStart);  }
-                    if (thisPEnd != -1)     { locations[1].insert(thisPEnd);    }
                 }
                                else {  
                     badSeqNames.insert(currSeq.getName()); 
@@ -792,9 +818,8 @@ int PcrSeqsCommand::driverPcr(string filename, string goodFasta, string badFasta
         if (m->debug) { m->mothurOut("[DEBUG]: fileAligned = " + toString(fileAligned) +'\n'); }
     
         if (fileAligned && !keepdots) { //print out smallest start value and largest end value
-            if ((locations[0].size() > 1) || (locations[1].size() > 1)) { adjustNeeded = true; }
-            if (primers.size() != 0)    {   set<int>::iterator it = locations[0].begin();  pstart = *it;  }
-            if (revPrimer.size() != 0)  {   set<int>::reverse_iterator it2 = locations[1].rbegin();  pend = *it2; }
+            if (locations.size() > 1) { adjustNeeded = true; }
+            if (primers.size() != 0)    {   set<int>::iterator it = locations.begin();  pstart = *it;  }
         }
 
                return count;
@@ -837,6 +862,7 @@ int PcrSeqsCommand::adjustDots(string goodFasta, string locations, int pstart, i
         
         set<int> lengths;
         //cout << pstart << '\t' << pend << endl;
+        //if (pstart > pend) { //swap them
         
         while(!inFasta.eof()) {
             if(m->control_pressed) { break; }
@@ -847,6 +873,8 @@ int PcrSeqsCommand::adjustDots(string goodFasta, string locations, int pstart, i
             int thisStart = -1; int thisEnd = -1;
             if (primers.size() != 0)    { inLocations >> name >> thisStart; m->gobble(inLocations); }
             if (revPrimer.size() != 0)  { inLocations >> name >> thisEnd;   m->gobble(inLocations); }
+            
+            
             //cout << seq.getName() << '\t' << thisStart << '\t' << thisEnd << '\t' << seq.getAligned().length() << endl;
             //cout << seq.getName() << '\t' << pstart << '\t' << pend << endl;
             
@@ -887,7 +915,8 @@ int PcrSeqsCommand::adjustDots(string goodFasta, string locations, int pstart, i
         
         //cout << "final lengths = \n";
         //for (set<int>::iterator it = lengths.begin(); it != lengths.end(); it++) {
-           // cout << *it << endl;
+           //cout << *it << endl;
+           // cout << lengths.count(*it) << endl;
        // }
         
         return 0;
index fbbe4bb3a2fc5c99f77875292849e0a0e95f1043..fe722a669f2c0ca983c94ef21cc73dc95f5719bc 100644 (file)
@@ -300,6 +300,7 @@ int PreClusterCommand::execute(){
                        m->mothurOut("It took " + toString(time(NULL) - start) + " secs to run pre.cluster."); m->mothurOutEndLine(); 
                                
                }else {
+            if (processors != 1) { m->mothurOut("When using running without group information mothur can only use 1 processor, continuing."); m->mothurOutEndLine(); processors = 1; }
                        if (namefile != "") { readNameFile(); }
                
                        //reads fasta file and return number of seqs
index a56b0ebb73d1f6188ecd09430e70ed0128abaf31..bf702e13534f507576bee7c24bcf6462aacb7ca3 100644 (file)
@@ -2119,7 +2119,7 @@ int ScreenSeqsCommand::screenGroupFile(map<string, string> badSeqNames){
                while(!inputGroups.eof()){
                        if (m->control_pressed) { goodGroupOut.close(); inputGroups.close(); m->mothurRemove(goodGroupFile); return 0; }
 
-                       inputGroups >> seqName; m->gobble(inputGroups); inputGroups >> group;
+                       inputGroups >> seqName; m->gobble(inputGroups); inputGroups >> group; m->gobble(inputGroups);
                        it = badSeqNames.find(seqName);
                        
                        if(it != badSeqNames.end()){
@@ -2128,7 +2128,6 @@ int ScreenSeqsCommand::screenGroupFile(map<string, string> badSeqNames){
                        else{
                                goodGroupOut << seqName << '\t' << group << endl;
                        }
-                       m->gobble(inputGroups);
                }
                
                if (m->control_pressed) { goodGroupOut.close();  inputGroups.close(); m->mothurRemove(goodGroupFile);  return 0; }
index d6073d75da3ed630b27b626bbba8615d79b58858..efeb88ce65183135c2a0aaef36d8d3a1c8f432cc 100644 (file)
@@ -76,7 +76,8 @@ Sequence::Sequence(istringstream& fastaString){
                                }
                        }
                        
-                       while (!fastaString.eof())      {       char c = fastaString.get();  if (c == 10 || c == 13){ break;    }       } // get rest of line if there's any crap there
+                       //while (!fastaString.eof())    {       char c = fastaString.get();  if (c == 10 || c == 13){ break;    }       } // get rest of line if there's any crap there
+            comment = getCommentString(fastaString);
                        
                        int numAmbig = 0;
                        sequence = getSequenceString(fastaString, numAmbig);
@@ -120,7 +121,8 @@ Sequence::Sequence(istringstream& fastaString, string JustUnaligned){
                                }
                        }
                        
-                       while (!fastaString.eof())      {       char c = fastaString.get();  if (c == 10 || c == 13){ break;    }       } // get rest of line if there's any crap there
+                       //while (!fastaString.eof())    {       char c = fastaString.get();  if (c == 10 || c == 13){ break;    }       } // get rest of line if there's any crap there
+            comment = getCommentString(fastaString);
                        
                        int numAmbig = 0;
                        sequence = getSequenceString(fastaString, numAmbig);
@@ -166,8 +168,8 @@ Sequence::Sequence(ifstream& fastaFile){
                                }
                        }
                        
-                       //read real sequence
-                       while (!fastaFile.eof())        {       char c = fastaFile.get(); if (c == 10 || c == 13){  break;      }       } // get rest of line if there's any crap there
+                       //while (!fastaFile.eof())      {       char c = fastaFile.get(); if (c == 10 || c == 13){  break;      }       } // get rest of line if there's any crap there
+            comment = getCommentString(fastaFile);
                        
                        int numAmbig = 0;
                        sequence = getSequenceString(fastaFile, numAmbig);
@@ -216,9 +218,11 @@ Sequence::Sequence(ifstream& fastaFile, string& extraInfo, bool getInfo){
                        //read info after sequence name
                        while (!fastaFile.eof())        {       
                 char c = fastaFile.get(); 
-                if (c == 10 || c == 13 || c == -1){  break;    }
+                if (c == 10 || c == 13 || c == -1){   break;   }
                 extraInfo += c;
-            } 
+            }
+            
+            comment = extraInfo;
                        
                        int numAmbig = 0;
                        sequence = getSequenceString(fastaFile, numAmbig);
@@ -261,8 +265,8 @@ Sequence::Sequence(ifstream& fastaFile, string JustUnaligned){
                                }
                        }
                        
-                       //read real sequence
-                       while (!fastaFile.eof())        {       char c = fastaFile.get(); if (c == 10 || c == 13){       break; }       } // get rest of line if there's any crap there
+                       //while (!fastaFile.eof())      {       char c = fastaFile.get(); if (c == 10 || c == 13){       break; }       } // get rest of line if there's any crap there
+            comment = getCommentString(fastaFile);
                        
                        int numAmbig = 0;
                        sequence = getSequenceString(fastaFile, numAmbig);
@@ -360,17 +364,19 @@ string Sequence::getSequenceString(ifstream& fastaFile, int& numAmbig) {
 string Sequence::getCommentString(ifstream& fastaFile) {
        try {
                char letter;
-               string sequence = "";
+               string temp = "";
                
                while(fastaFile){
                        letter=fastaFile.get();
-                       if((letter == '\r') || (letter == '\n')){  
+                       if((letter == '\r') || (letter == '\n') || letter == -1){
                                m->gobble(fastaFile);  //in case its a \r\n situation
                                break;
-                       }
+                       }else {
+                temp += letter;
+            }
                }
                
-               return sequence;
+               return temp;
        }
        catch(exception& e) {
                m->errorOut(e, "Sequence", "getCommentString");
@@ -414,17 +420,19 @@ string Sequence::getSequenceString(istringstream& fastaFile, int& numAmbig) {
 string Sequence::getCommentString(istringstream& fastaFile) {
        try {
                char letter;
-               string sequence = "";
+               string temp = "";
                
                while(fastaFile){
                        letter=fastaFile.get();
-                       if((letter == '\r') || (letter == '\n')){  
+                       if((letter == '\r') || (letter == '\n') || letter == -1){  
                                m->gobble(fastaFile);  //in case its a \r\n situation
                                break;
-                       }
+                       }else {
+                temp += letter;
+            }
                }
                
-               return sequence;
+               return temp;
        }
        catch(exception& e) {
                m->errorOut(e, "Sequence", "getCommentString");
@@ -439,6 +447,7 @@ void Sequence::initialize(){
        unaligned = "";
        aligned = "";
        pairwise = "";
+    comment = "";
        
        numBases = 0;
        alignmentLength = 0;
@@ -581,7 +590,7 @@ int Sequence::getNumNs(){
 
 void Sequence::printSequence(ostream& out){
 
-       out << ">" << name << endl;
+       out << ">" << name << comment << endl;
        if(isAligned){
                out << aligned << endl;
        }
index ad3a4b40c238c4260d36f7afea027b903539c8a0..c49899411f2dd7919d96ce9b9840c30b2b0dfcac 100644 (file)
@@ -76,6 +76,7 @@ private:
        string unaligned;
        string aligned;
        string pairwise;
+    string comment;
        int numBases;
        int alignmentLength;
        bool isAligned;
index 9d59696ba2f47157dd059c066af108d6bb76e731..98ae223818bd67b290dfbdf0450fa2a33b9b49b2 100644 (file)
@@ -417,10 +417,9 @@ SetCurrentCommand::SetCurrentCommand(string option)  {
                        else if (summaryfile == "not found") {  summaryfile = "";  }
                        if (summaryfile != "") { m->setSummaryFile(summaryfile); }
 
-                       
-                       processors = validParameter.validFile(parameters, "processors", false);
-                       if (processors == "not found") {  processors = "1";  }  
-                       if (processors != "") { m->setProcessors(processors); }
+                       string temp = validParameter.validFile(parameters, "processors", false);
+                       if (temp == "not found"){       temp = m->getProcessors();      }
+                       m->setProcessors(temp);
                        
                        clearTypes = validParameter.validFile(parameters, "clear", false);                      
                        if (clearTypes == "not found") { clearTypes = ""; }
old mode 100644 (file)
new mode 100755 (executable)
index 399f253..bccb751
-/*
- *  sffinfocommand.cpp
- *  Mothur
- *
- *  Created by westcott on 7/7/10.
- *  Copyright 2010 Schloss Lab. All rights reserved.
- *
- */
-
-#include "sffinfocommand.h"
-#include "endiannessmacros.h"
-#include "trimoligos.h"
-#include "sequence.hpp"
-#include "qualityscores.h"
-
-//**********************************************************************************************************************
-vector<string> SffInfoCommand::setParameters(){        
-       try {           
-               CommandParameter psff("sff", "InputTypes", "", "", "none", "none", "none","",false,false,true); parameters.push_back(psff);
-        CommandParameter poligos("oligos", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(poligos);
-               CommandParameter paccnos("accnos", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(paccnos);
-               CommandParameter psfftxt("sfftxt", "String", "", "", "", "", "","",false,false); parameters.push_back(psfftxt);
-               CommandParameter pflow("flow", "Boolean", "", "T", "", "", "","flow",false,false); parameters.push_back(pflow);
-               CommandParameter ptrim("trim", "Boolean", "", "T", "", "", "","",false,false); parameters.push_back(ptrim);
-               CommandParameter pfasta("fasta", "Boolean", "", "T", "", "", "","fasta",false,false); parameters.push_back(pfasta);
-               CommandParameter pqfile("qfile", "Boolean", "", "T", "", "", "","qfile",false,false); parameters.push_back(pqfile);
-        CommandParameter ppdiffs("pdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(ppdiffs);
-               CommandParameter pbdiffs("bdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pbdiffs);
-        CommandParameter pldiffs("ldiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pldiffs);
-               CommandParameter psdiffs("sdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(psdiffs);
-        CommandParameter ptdiffs("tdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(ptdiffs);
-               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, "SffInfoCommand", "setParameters");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-string SffInfoCommand::getHelpString(){        
-       try {
-               string helpString = "";
-               helpString += "The sffinfo command reads a sff file and extracts the sequence data, or you can use it to parse a sfftxt file.\n";
-               helpString += "The sffinfo command parameters are sff, fasta, qfile, accnos, flow, sfftxt, oligos, bdiffs, tdiffs, ldiffs, sdiffs, pdiffs and trim. sff is required. \n";
-               helpString += "The sff parameter allows you to enter the sff file you would like to extract data from.  You may enter multiple files by separating them by -'s.\n";
-               helpString += "The fasta parameter allows you to indicate if you would like a fasta formatted file generated.  Default=True. \n";
-               helpString += "The qfile parameter allows you to indicate if you would like a quality file generated.  Default=True. \n";
-        helpString += "The oligos parameter allows you to provide an oligos file to split your sff file into separate sff files by barcode. \n";
-        helpString += "The tdiffs parameter is used to specify the total number of differences allowed in the sequence. The default is pdiffs + bdiffs + sdiffs + ldiffs.\n";
-               helpString += "The bdiffs parameter is used to specify the number of differences allowed in the barcode. The default is 0.\n";
-               helpString += "The pdiffs parameter is used to specify the number of differences allowed in the primer. The default is 0.\n";
-        helpString += "The ldiffs parameter is used to specify the number of differences allowed in the linker. The default is 0.\n";
-               helpString += "The sdiffs parameter is used to specify the number of differences allowed in the spacer. The default is 0.\n";
-               helpString += "The flow parameter allows you to indicate if you would like a flowgram file generated.  Default=True. \n";
-               helpString += "The sfftxt parameter allows you to indicate if you would like a sff.txt file generated.  Default=False. \n";
-               helpString += "If you want to parse an existing sfftxt file into flow, fasta and quality file, enter the file name using the sfftxt parameter. \n";
-               helpString += "The trim parameter allows you to indicate if you would like a sequences and quality scores trimmed to the clipQualLeft and clipQualRight values.  Default=True. \n";
-               helpString += "The accnos parameter allows you to provide a accnos file containing the names of the sequences you would like extracted. You may enter multiple files by separating them by -'s. \n";
-               helpString += "Example sffinfo(sff=mySffFile.sff, trim=F).\n";
-               helpString += "Note: No spaces between parameter labels (i.e. sff), '=' and parameters (i.e.yourSffFileName).\n";
-               return helpString;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "getHelpString");
-               exit(1);
-       }
-}
-
-//**********************************************************************************************************************
-string SffInfoCommand::getOutputPattern(string type) {
-    try {
-        string pattern = "";
-        
-        if (type == "fasta")            {   pattern =  "[filename],fasta-[filename],[tag],fasta";   }
-        else if (type == "flow")    {   pattern =  "[filename],flow";   }
-        else if (type == "sfftxt")        {   pattern =  "[filename],sff.txt";   }
-        else if (type == "sff")        {   pattern =  "[filename],[group],sff";   }
-        else if (type == "qfile")       {   pattern =  "[filename],qual-[filename],[tag],qual";   }
-        else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
-        
-        return pattern;
-    }
-    catch(exception& e) {
-        m->errorOut(e, "SffInfoCommand", "getOutputPattern");
-        exit(1);
-    }
-}
-//**********************************************************************************************************************
-SffInfoCommand::SffInfoCommand(){      
-       try {
-               abort = true; calledHelp = true; 
-               setParameters();
-               vector<string> tempOutNames;
-               outputTypes["fasta"] = tempOutNames;
-               outputTypes["flow"] = tempOutNames;
-               outputTypes["sfftxt"] = tempOutNames;
-               outputTypes["qfile"] = tempOutNames;
-        outputTypes["sff"] = tempOutNames;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "SffInfoCommand");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-
-SffInfoCommand::SffInfoCommand(string option)  {
-       try {
-               abort = false; calledHelp = false;   
-               hasAccnos = false; hasOligos = false;
-        split = 1;
-               
-               //allow user to run help
-               if(option == "help") { help(); abort = true; calledHelp = true; }
-               else if(option == "citation") { citation(); abort = true; calledHelp = true;}
-               
-               else {
-                       //valid paramters for this command
-                       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["fasta"] = tempOutNames;
-                       outputTypes["flow"] = tempOutNames;
-                       outputTypes["sfftxt"] = tempOutNames;
-                       outputTypes["qfile"] = tempOutNames;
-            outputTypes["sff"] = tempOutNames;
-                       
-                       //if the user changes the output directory command factory will send this info to us in the output parameter 
-                       outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
-                       
-                       //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 = "";          }
-
-                       sffFilename = validParameter.validFile(parameters, "sff", false);
-                       if (sffFilename == "not found") { sffFilename = "";  }
-                       else { 
-                               m->splitAtDash(sffFilename, filenames);
-                               
-                               //go through files and make sure they are good, if not, then disregard them
-                               for (int i = 0; i < filenames.size(); i++) {
-                                       bool ignore = false;
-                                       if (filenames[i] == "current") { 
-                                               filenames[i] = m->getSFFFile(); 
-                                               if (filenames[i] != "") {  m->mothurOut("Using " + filenames[i] + " as input file for the sff parameter where you had given current."); m->mothurOutEndLine(); }
-                                               else {  
-                                                       m->mothurOut("You have no current sfffile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
-                                                       //erase from file list
-                                                       filenames.erase(filenames.begin()+i);
-                                                       i--;
-                                               }
-                                       }
-                                       
-                                       if (!ignore) {
-                                               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];         }
-                                               }
-               
-                                               ifstream in;
-                                               int ableToOpen = m->openInputFile(filenames[i], in, "noerror");
-                                       
-                                               //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 default 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;
-                                                       }
-                                               }
-                                               
-                                               in.close();
-                                               
-                                               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--;
-                                               }else { m->setSFFFile(filenames[i]); }
-                                       }
-                               }
-                               
-                               //make sure there is at least one valid file left
-                               if (filenames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }
-                       }
-                       
-                       accnosName = validParameter.validFile(parameters, "accnos", false);
-                       if (accnosName == "not found") { accnosName = "";  }
-                       else { 
-                               hasAccnos = true;
-                               m->splitAtDash(accnosName, accnosFileNames);
-                               
-                               //go through files and make sure they are good, if not, then disregard them
-                               for (int i = 0; i < accnosFileNames.size(); i++) {
-                                       bool ignore = false;
-                                       if (accnosFileNames[i] == "current") { 
-                                               accnosFileNames[i] = m->getAccnosFile(); 
-                                               if (accnosFileNames[i] != "") {  m->mothurOut("Using " + accnosFileNames[i] + " as input file for the accnos parameter where you had given current."); m->mothurOutEndLine(); }
-                                               else {  
-                                                       m->mothurOut("You have no current accnosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
-                                                       //erase from file list
-                                                       accnosFileNames.erase(accnosFileNames.begin()+i);
-                                                       i--;
-                                               }
-                                       }
-                                       
-                                       if (!ignore) {
-                                       
-                                               if (inputDir != "") {
-                                                       string path = m->hasPath(accnosFileNames[i]);
-                                                       //if the user has not given a path then, add inputdir. else leave path alone.
-                                                       if (path == "") {       accnosFileNames[i] = inputDir + accnosFileNames[i];             }
-                                               }
-               
-                                               ifstream in;
-                                               int ableToOpen = m->openInputFile(accnosFileNames[i], in, "noerror");
-                                       
-                                               //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(accnosFileNames[i]);
-                                                               m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
-                                                               ifstream in2;
-                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");
-                                                               in2.close();
-                                                               accnosFileNames[i] = tryPath;
-                                                       }
-                                               }
-                                               //if you can't open it, try default location
-                                               if (ableToOpen == 1) {
-                                                       if (m->getOutputDir() != "") { //default path is set
-                                                               string tryPath = m->getOutputDir() + m->getSimpleName(accnosFileNames[i]);
-                                                               m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
-                                                               ifstream in2;
-                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");
-                                                               in2.close();
-                                                               accnosFileNames[i] = tryPath;
-                                                       }
-                                               }
-                                               in.close();
-                                               
-                                               if (ableToOpen == 1) { 
-                                                       m->mothurOut("Unable to open " + accnosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();
-                                                       //erase from file list
-                                                       accnosFileNames.erase(accnosFileNames.begin()+i);
-                                                       i--;
-                                               }
-                                       }
-                               }
-                               
-                               //make sure there is at least one valid file left
-                               if (accnosFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }
-                       }
-            
-            oligosfile = validParameter.validFile(parameters, "oligos", false);
-                       if (oligosfile == "not found") { oligosfile = "";  }
-                       else { 
-                               hasOligos = true;
-                               m->splitAtDash(oligosfile, oligosFileNames);
-                               
-                               //go through files and make sure they are good, if not, then disregard them
-                               for (int i = 0; i < oligosFileNames.size(); i++) {
-                                       bool ignore = false;
-                                       if (oligosFileNames[i] == "current") { 
-                                               oligosFileNames[i] = m->getOligosFile(); 
-                                               if (oligosFileNames[i] != "") {  m->mothurOut("Using " + oligosFileNames[i] + " as input file for the accnos parameter where you had given current."); m->mothurOutEndLine(); }
-                                               else {  
-                                                       m->mothurOut("You have no current oligosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
-                                                       //erase from file list
-                                                       oligosFileNames.erase(oligosFileNames.begin()+i);
-                                                       i--;
-                                               }
-                                       }
-                                       
-                                       if (!ignore) {
-                        
-                                               if (inputDir != "") {
-                                                       string path = m->hasPath(oligosFileNames[i]);
-                                                       //if the user has not given a path then, add inputdir. else leave path alone.
-                                                       if (path == "") {       oligosFileNames[i] = inputDir + oligosFileNames[i];             }
-                                               }
-                        
-                                               ifstream in;
-                                               int ableToOpen = m->openInputFile(oligosFileNames[i], in, "noerror");
-                        
-                                               //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(oligosFileNames[i]);
-                                                               m->mothurOut("Unable to open " + oligosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
-                                                               ifstream in2;
-                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");
-                                                               in2.close();
-                                                               oligosFileNames[i] = tryPath;
-                                                       }
-                                               }
-                                               //if you can't open it, try default location
-                                               if (ableToOpen == 1) {
-                                                       if (m->getOutputDir() != "") { //default path is set
-                                                               string tryPath = m->getOutputDir() + m->getSimpleName(oligosFileNames[i]);
-                                                               m->mothurOut("Unable to open " + oligosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
-                                                               ifstream in2;
-                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");
-                                                               in2.close();
-                                                               oligosFileNames[i] = tryPath;
-                                                       }
-                                               }
-                                               in.close();
-                                               
-                                               if (ableToOpen == 1) { 
-                                                       m->mothurOut("Unable to open " + oligosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();
-                                                       //erase from file list
-                                                       oligosFileNames.erase(oligosFileNames.begin()+i);
-                                                       i--;
-                                               }
-                                       }
-                               }
-                               
-                               //make sure there is at least one valid file left
-                               if (oligosFileNames.size() == 0) { m->mothurOut("no valid oligos files."); m->mothurOutEndLine(); abort = true; }
-                       }
-
-                       if (hasOligos) {
-                split = 2;
-                               if (oligosFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide a oligos file, you must have one for each sff file."); m->mothurOutEndLine(); }
-                       }
-            
-                       if (hasAccnos) {
-                               if (accnosFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide a accnos file, you must have one for each sff file."); m->mothurOutEndLine(); }
-                       }
-                       
-                       string temp = validParameter.validFile(parameters, "qfile", false);                     if (temp == "not found"){       temp = "T";                             }
-                       qual = m->isTrue(temp); 
-                       
-                       temp = validParameter.validFile(parameters, "fasta", false);                            if (temp == "not found"){       temp = "T";                             }
-                       fasta = m->isTrue(temp); 
-                       
-                       temp = validParameter.validFile(parameters, "flow", false);                                     if (temp == "not found"){       temp = "T";                             }
-                       flow = m->isTrue(temp); 
-                       
-                       temp = validParameter.validFile(parameters, "trim", false);                                     if (temp == "not found"){       temp = "T";                             }
-                       trim = m->isTrue(temp); 
-            
-            temp = validParameter.validFile(parameters, "bdiffs", false);              if (temp == "not found") { temp = "0"; }
-                       m->mothurConvert(temp, bdiffs);
-                       
-                       temp = validParameter.validFile(parameters, "pdiffs", false);           if (temp == "not found") { temp = "0"; }
-                       m->mothurConvert(temp, pdiffs);
-            
-            temp = validParameter.validFile(parameters, "ldiffs", false);              if (temp == "not found") { temp = "0"; }
-                       m->mothurConvert(temp, ldiffs);
-            
-            temp = validParameter.validFile(parameters, "sdiffs", false);              if (temp == "not found") { temp = "0"; }
-                       m->mothurConvert(temp, sdiffs);
-                       
-                       temp = validParameter.validFile(parameters, "tdiffs", false);           if (temp == "not found") { int tempTotal = pdiffs + bdiffs + ldiffs + sdiffs;  temp = toString(tempTotal); }
-                       m->mothurConvert(temp, tdiffs);
-                       
-                       if(tdiffs == 0){        tdiffs = bdiffs + pdiffs + ldiffs + sdiffs;     }
-            
-                       temp = validParameter.validFile(parameters, "sfftxt", false);                           
-                       if (temp == "not found")        {       temp = "F";      sfftxt = false; sfftxtFilename = "";           }
-                       else if (m->isTrue(temp))       {       sfftxt = true;          sfftxtFilename = "";                            }
-                       else {
-                               //you are a filename
-                               if (inputDir != "") {
-                                       map<string,string>::iterator it = parameters.find("sfftxt");
-                                       //user has given a template file
-                                       if(it != parameters.end()){ 
-                                               string path = m->hasPath(it->second);
-                                               //if the user has not given a path then, add inputdir. else leave path alone.
-                                               if (path == "") {       parameters["sfftxt"] = inputDir + it->second;           }
-                                       }
-                               }
-                               
-                               sfftxtFilename = validParameter.validFile(parameters, "sfftxt", true);
-                               if (sfftxtFilename == "not found") { sfftxtFilename = "";  }
-                               else if (sfftxtFilename == "not open") { sfftxtFilename = "";  }
-                       }
-                       
-                       if ((sfftxtFilename == "") && (filenames.size() == 0)) {  
-                               //if there is a current sff file, use it
-                               string filename = m->getSFFFile(); 
-                               if (filename != "") { filenames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the sff parameter."); m->mothurOutEndLine(); }
-                               else {  m->mothurOut("[ERROR]: you must provide a valid sff or sfftxt file."); m->mothurOutEndLine(); abort=true;  }
-                       }
-            
-            
-               }
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "SffInfoCommand");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::execute(){
-       try {
-               if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
-               
-               for (int s = 0; s < filenames.size(); s++) {
-                       
-                       if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]);        } return 0; }
-                       
-                       int start = time(NULL);
-                       
-            filenames[s] = m->getFullPathName(filenames[s]);
-                       m->mothurOut("Extracting info from " + filenames[s] + " ..." ); m->mothurOutEndLine();
-                       
-                       string accnos = "";
-                       if (hasAccnos) { accnos = accnosFileNames[s]; }
-            
-            string oligos = "";
-            if (hasOligos) { oligos = oligosFileNames[s]; }
-                       
-                       int numReads = extractSffInfo(filenames[s], accnos, oligos);
-
-                       m->mothurOut("It took " + toString(time(NULL) - start) + " secs to extract " + toString(numReads) + ".");
-               }
-               
-               if (sfftxtFilename != "") {  parseSffTxt(); }
-               
-               if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]);        } return 0; }
-               
-               //set fasta file as new current fastafile
-               string current = "";
-               itTypes = outputTypes.find("fasta");
-               if (itTypes != outputTypes.end()) {
-                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); }
-               }
-               
-               itTypes = outputTypes.find("qfile");
-               if (itTypes != outputTypes.end()) {
-                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setQualFile(current); }
-               }
-               
-               itTypes = outputTypes.find("flow");
-               if (itTypes != outputTypes.end()) {
-                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFlowFile(current); }
-               }
-               
-               //report output filenames
-               m->mothurOutEndLine();
-               m->mothurOut("Output File Names: "); m->mothurOutEndLine();
-               for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
-               m->mothurOutEndLine();
-
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "execute");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){
-       try {
-               currentFileName = input;
-               if (outputDir == "") {  outputDir += m->hasPath(input); }
-               
-               if (accnos != "")       {  readAccnosFile(accnos);  }
-               else                            {       seqNames.clear();               }
-         
-        if (oligos != "")   {   readOligos(oligos);  split = 2;   }
-
-               ofstream outSfftxt, outFasta, outQual, outFlow;
-               string outFastaFileName, outQualFileName;
-        string rootName = outputDir + m->getRootName(m->getSimpleName(input));
-        if(rootName.find_last_of(".") == rootName.npos){ rootName += "."; }
-        
-        map<string, string> variables; 
-               variables["[filename]"] = rootName;
-               string sfftxtFileName = getOutputFileName("sfftxt",variables);
-               string outFlowFileName = getOutputFileName("flow",variables);
-               if (!trim) { variables["[tag]"] = "raw"; }
-               outFastaFileName = getOutputFileName("fasta",variables);
-        outQualFileName = getOutputFileName("qfile",variables);
-        
-               if (sfftxt) { m->openOutputFile(sfftxtFileName, outSfftxt); outSfftxt.setf(ios::fixed, ios::floatfield); outSfftxt.setf(ios::showpoint);  outputNames.push_back(sfftxtFileName);  outputTypes["sfftxt"].push_back(sfftxtFileName); }
-               if (fasta)      { m->openOutputFile(outFastaFileName, outFasta);        outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); }
-               if (qual)       { m->openOutputFile(outQualFileName, outQual);          outputNames.push_back(outQualFileName); outputTypes["qfile"].push_back(outQualFileName);  }
-               if (flow)       { m->openOutputFile(outFlowFileName, outFlow);          outputNames.push_back(outFlowFileName);  outFlow.setf(ios::fixed, ios::floatfield); outFlow.setf(ios::showpoint); outputTypes["flow"].push_back(outFlowFileName);  }
-               
-               ifstream in;
-               in.open(input.c_str(), ios::binary);
-               
-               CommonHeader header; 
-               readCommonHeader(in, header);
-       
-               int count = 0;
-               mycount = 0;
-               
-               //check magic number and version
-               if (header.magicNumber != 779314790) { m->mothurOut("Magic Number is not correct, not a valid .sff file"); m->mothurOutEndLine(); return count; }
-               if (header.version != "0001") { m->mothurOut("Version is not supported, only support version 0001."); m->mothurOutEndLine(); return count; }
-       
-               //print common header
-               if (sfftxt) {   printCommonHeader(outSfftxt, header);           }
-               if (flow)       {       outFlow << header.numFlowsPerRead << endl;      }
-                       
-               //read through the sff file
-               while (!in.eof()) {
-                       
-                       bool print = true;
-                                               
-                       //read data
-                       seqRead read;  Header readheader;
-                       readSeqData(in, read, header.numFlowsPerRead, readheader);
-            bool okay = sanityCheck(readheader, read);
-            if (!okay) { break; }
-            
-                       //if you have provided an accosfile and this seq is not in it, then dont print
-                       if (seqNames.size() != 0) {   if (seqNames.count(readheader.name) == 0) { print = false; }  }
-                       
-                       //print 
-                       if (print) {
-                               if (sfftxt) { printHeader(outSfftxt, readheader); printSffTxtSeqData(outSfftxt, read, readheader); }
-                               if (fasta)      {       printFastaSeqData(outFasta, read, readheader);  }
-                               if (qual)       {       printQualSeqData(outQual, read, readheader);    }
-                               if (flow)       {       printFlowSeqData(outFlow, read, readheader);    }
-                       }
-                       
-                       count++;
-                       mycount++;
-        
-                       //report progress
-                       if((count+1) % 10000 == 0){     m->mothurOut(toString(count+1)); m->mothurOutEndLine();         }
-               
-                       if (m->control_pressed) { count = 0; break;   }
-                       
-                       if (count >= header.numReads) { break; }
-            //if (count >= 100) { break; }
-               }
-               
-               //report progress
-               if (!m->control_pressed) {   if((count) % 10000 != 0){  m->mothurOut(toString(count)); m->mothurOutEndLine();           }  }
-               
-               in.close();
-               
-               if (sfftxt) {  outSfftxt.close();       }
-               if (fasta)      {  outFasta.close();    }
-               if (qual)       {  outQual.close();             }
-               if (flow)       {  outFlow.close();             }
-               
-        if (split > 1) {
-            //create new common headers for each file with the correct number of reads
-            adjustCommonHeader(header);
-            
-                       map<string, string>::iterator it;
-                       set<string> namesToRemove;
-                       for(int i=0;i<filehandles.size();i++){
-                               for(int j=0;j<filehandles[0].size();j++){
-                                       if (filehandles[i][j] != "") {
-                                               if (namesToRemove.count(filehandles[i][j]) == 0) {
-                                                       if(m->isBlank(filehandles[i][j])){
-                                                               m->mothurRemove(filehandles[i][j]);
-                                m->mothurRemove(filehandlesHeaders[i][j]);
-                                                               namesToRemove.insert(filehandles[i][j]);
-                            }
-                                               }
-                                       }
-                               }
-                       }
-            
-            //append new header to reads
-            for (int i = 0; i < filehandles.size(); i++) {
-                for (int j = 0; j < filehandles[i].size(); j++) {
-                    m->appendFiles(filehandles[i][j], filehandlesHeaders[i][j]);
-                    m->renameFile(filehandlesHeaders[i][j], filehandles[i][j]);
-                    m->mothurRemove(filehandlesHeaders[i][j]);
-                    if (numSplitReads[i][j] == 0) { m->mothurRemove(filehandles[i][j]); }
-                }
-            }
-                       
-                       //remove names for outputFileNames, just cleans up the output
-                       for(int i = 0; i < outputNames.size(); i++) { 
-                if (namesToRemove.count(outputNames[i]) != 0) { 
-                    outputNames.erase(outputNames.begin()+i);
-                    i--;
-                } 
-            }
-            
-            if(m->isBlank(noMatchFile)){  m->mothurRemove(noMatchFile); }
-            else { outputNames.push_back(noMatchFile); outputTypes["sff"].push_back(noMatchFile); }
-        }
-        
-               return count;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "extractSffInfo");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::readCommonHeader(ifstream& in, CommonHeader& header){
-       try {
-        
-               if (!in.eof()) {
-
-                       //read magic number
-                       char buffer[4];
-                       in.read(buffer, 4);
-                       header.magicNumber = be_int4(*(unsigned int *)(&buffer));
-            
-                       //read version
-                       char buffer9[4];
-                       in.read(buffer9, 4);
-                       header.version = "";
-                       for (int i = 0; i < 4; i++) {  header.version += toString((int)(buffer9[i]));  }
-    
-                       //read offset
-                       char buffer2 [8];
-                       in.read(buffer2, 8);
-                       header.indexOffset =  be_int8(*(unsigned long long *)(&buffer2));
-                       
-                       //read index length
-                       char buffer3 [4];
-                       in.read(buffer3, 4);
-                       header.indexLength =  be_int4(*(unsigned int *)(&buffer3));
-            
-                       //read num reads
-                       char buffer4 [4];
-                       in.read(buffer4, 4);
-                       header.numReads =  be_int4(*(unsigned int *)(&buffer4));
-            
-            if (m->debug) { m->mothurOut("[DEBUG]: numReads = " + toString(header.numReads) + "\n"); }
-                               
-                       //read header length
-                       char buffer5 [2];
-                       in.read(buffer5, 2);
-                       header.headerLength =  be_int2(*(unsigned short *)(&buffer5));
-                                       
-                       //read key length
-                       char buffer6 [2];
-                       in.read(buffer6, 2);
-                       header.keyLength = be_int2(*(unsigned short *)(&buffer6));
-                       
-                       //read number of flow reads
-                       char buffer7 [2];
-                       in.read(buffer7, 2);
-                       header.numFlowsPerRead =  be_int2(*(unsigned short *)(&buffer7));
-                               
-                       //read format code
-                       char buffer8 [1];
-                       in.read(buffer8, 1);
-                       header.flogramFormatCode = (int)(buffer8[0]);
-                       
-                       //read flow chars
-                       char* tempBuffer = new char[header.numFlowsPerRead];
-                       in.read(&(*tempBuffer), header.numFlowsPerRead); 
-                       header.flowChars = tempBuffer;
-                       if (header.flowChars.length() > header.numFlowsPerRead) { header.flowChars = header.flowChars.substr(0, header.numFlowsPerRead);  }
-                       delete[] tempBuffer;
-                       
-                       //read key
-                       char* tempBuffer2 = new char[header.keyLength];
-                       in.read(&(*tempBuffer2), header.keyLength);
-                       header.keySequence = tempBuffer2;
-                       if (header.keySequence.length() > header.keyLength) { header.keySequence = header.keySequence.substr(0, header.keyLength);  }
-                       delete[] tempBuffer2;
-                       
-                       /* Pad to 8 chars */
-                       unsigned long long spotInFile = in.tellg();
-                       unsigned long long spot = (spotInFile + 7)& ~7;  // ~ inverts
-                       in.seekg(spot);
-            
-        }else{
-                       m->mothurOut("Error reading sff common header."); m->mothurOutEndLine();
-               }
-        
-               return 0;
-        
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "readCommonHeader");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::adjustCommonHeader(CommonHeader header){
-       try {
-
-        char* mybuffer = new char[4];
-        ifstream in;
-        in.open(currentFileName.c_str(), ios::binary);
-        
-        //magic number
-        in.read(mybuffer,4);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-        
-        //version
-        mybuffer = new char[4];
-        in.read(mybuffer,4);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-        
-        //offset
-        mybuffer = new char[8];
-        in.read(mybuffer,8);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                unsigned long long offset = 0;
-                char* thisbuffer = new char[8];
-                thisbuffer[0] = (offset >> 56) & 0xFF;
-                thisbuffer[1] = (offset >> 48) & 0xFF;
-                thisbuffer[2] = (offset >> 40) & 0xFF;
-                thisbuffer[3] = (offset >> 32) & 0xFF;
-                thisbuffer[4] = (offset >> 24) & 0xFF;
-                thisbuffer[5] = (offset >> 16) & 0xFF;
-                thisbuffer[6] = (offset >> 8) & 0xFF;
-                thisbuffer[7] = offset & 0xFF;
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(thisbuffer, 8);
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-            
-                       
-        //read index length
-               mybuffer = new char[4];
-        in.read(mybuffer,4);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                unsigned int offset = 0;
-                char* thisbuffer = new char[4];
-                thisbuffer[0] = (offset >> 24) & 0xFF;
-                thisbuffer[1] = (offset >> 16) & 0xFF;
-                thisbuffer[2] = (offset >> 8) & 0xFF;
-                thisbuffer[3] = offset & 0xFF;
-                out.write(thisbuffer, 4);
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-               
-        //change num reads
-        mybuffer = new char[4];
-        in.read(mybuffer,4);
-        delete[] mybuffer;
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                //convert number of reads to 4 byte char*
-                char* thisbuffer = new char[4];
-                if ((m->findEdianness()) == "BIG_ENDIAN") {
-                    thisbuffer[0] = (numSplitReads[i][j] >> 24) & 0xFF;
-                    thisbuffer[1] = (numSplitReads[i][j] >> 16) & 0xFF;
-                    thisbuffer[2] = (numSplitReads[i][j] >> 8) & 0xFF;
-                    thisbuffer[3] = numSplitReads[i][j] & 0xFF;
-                }else {
-                    thisbuffer[0] = numSplitReads[i][j] & 0xFF;
-                    thisbuffer[1] = (numSplitReads[i][j] >> 8) & 0xFF;
-                    thisbuffer[2] = (numSplitReads[i][j] >> 16) & 0xFF;
-                    thisbuffer[3] = (numSplitReads[i][j] >> 24) & 0xFF;
-                 }
-                out.write(thisbuffer, 4);
-                out.close();
-                delete[] thisbuffer;
-            }
-        }
-            
-        //read header length
-        mybuffer = new char[2];
-        in.read(mybuffer,2);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-            
-        //read key length
-        mybuffer = new char[2];
-        in.read(mybuffer,2);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-                       
-        //read number of flow reads
-        mybuffer = new char[2];
-        in.read(mybuffer,2);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-            
-        //read format code
-        mybuffer = new char[1];
-        in.read(mybuffer,1);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-                       
-        //read flow chars
-        mybuffer = new char[header.numFlowsPerRead];
-        in.read(mybuffer,header.numFlowsPerRead);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-                       
-        //read key
-        mybuffer = new char[header.keyLength];
-        in.read(mybuffer,header.keyLength);
-        for (int i = 0; i < filehandlesHeaders.size(); i++) {  
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, in.gcount()); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-        
-                       
-        /* Pad to 8 chars */
-        unsigned long long spotInFile = in.tellg();
-        unsigned long long spot = (spotInFile + 7)& ~7;  // ~ inverts
-        in.seekg(spot);
-        
-        mybuffer = new char[spot-spotInFile];
-        for (int i = 0; i < filehandlesHeaders.size(); i++) { 
-            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {
-                ofstream out;
-                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);
-                out.write(mybuffer, spot-spotInFile); 
-                out.close();
-            }
-        }
-        delete[] mybuffer;
-        in.close();
-               return 0;
-        
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "adjustCommonHeader");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads, Header& header){
-       try {
-        unsigned long long startSpotInFile = in.tellg();
-               if (!in.eof()) {
-            
-            /*****************************************/
-            //read header
-            
-            //read header length
-                       char buffer [2];
-                       in.read(buffer, 2); 
-                       header.headerLength = be_int2(*(unsigned short *)(&buffer));
-            
-                       //read name length
-                       char buffer2 [2];
-                       in.read(buffer2, 2);
-                       header.nameLength = be_int2(*(unsigned short *)(&buffer2));
-            
-                       //read num bases
-                       char buffer3 [4];
-                       in.read(buffer3, 4);
-                       header.numBases =  be_int4(*(unsigned int *)(&buffer3));
-            
-                       
-                       //read clip qual left
-                       char buffer4 [2];
-                       in.read(buffer4, 2);
-                       header.clipQualLeft =  be_int2(*(unsigned short *)(&buffer4));
-                       header.clipQualLeft = 5;
-            
-                       
-                       //read clip qual right
-                       char buffer5 [2];
-                       in.read(buffer5, 2);
-                       header.clipQualRight =  be_int2(*(unsigned short *)(&buffer5));
-           
-            
-                       //read clipAdapterLeft
-                       char buffer6 [2];
-                       in.read(buffer6, 2);
-                       header.clipAdapterLeft = be_int2(*(unsigned short *)(&buffer6));
-            
-            
-                       //read clipAdapterRight
-                       char buffer7 [2];
-                       in.read(buffer7, 2);
-                       header.clipAdapterRight = be_int2(*(unsigned short *)(&buffer7));
-            
-            
-                       //read name
-                       char* tempBuffer = new char[header.nameLength];
-                       in.read(&(*tempBuffer), header.nameLength);
-                       header.name = tempBuffer;
-                       if (header.name.length() > header.nameLength) { header.name = header.name.substr(0, header.nameLength);  }
-            
-                       delete[] tempBuffer;
-                       
-                       //extract info from name
-                       decodeName(header.timestamp, header.region, header.xy, header.name);
-                       
-                       /* Pad to 8 chars */
-                       unsigned long long spotInFile = in.tellg();
-                       unsigned long long spot = (spotInFile + 7)& ~7;
-                       in.seekg(spot);
-
-            /*****************************************/
-            //sequence read 
-            
-                       //read flowgram
-                       read.flowgram.resize(numFlowReads);
-                       for (int i = 0; i < numFlowReads; i++) {  
-                               char buffer [2];
-                               in.read(buffer, 2);
-                               read.flowgram[i] = be_int2(*(unsigned short *)(&buffer));
-                       }
-            
-                       //read flowIndex
-                       read.flowIndex.resize(header.numBases);
-                       for (int i = 0; i < header.numBases; i++) {  
-                               char temp[1];
-                               in.read(temp, 1);
-                               read.flowIndex[i] = be_int1(*(unsigned char *)(&temp));
-                       }
-       
-                       //read bases
-                       char* tempBuffer6 = new char[header.numBases];
-                       in.read(&(*tempBuffer6), header.numBases);
-                       read.bases = tempBuffer6;
-                       if (read.bases.length() > header.numBases) { read.bases = read.bases.substr(0, header.numBases);  }
-                       delete[] tempBuffer6;
-
-                       //read qual scores
-                       read.qualScores.resize(header.numBases);
-                       for (int i = 0; i < header.numBases; i++) {  
-                               char temp[1];
-                               in.read(temp, 1);
-                               read.qualScores[i] = be_int1(*(unsigned char *)(&temp));
-                       }
-       
-                       /* Pad to 8 chars */
-                       spotInFile = in.tellg();
-                       spot = (spotInFile + 7)& ~7;
-                       in.seekg(spot);
-            
-            if (split > 1) {
-                char * mybuffer;
-                mybuffer = new char [spot-startSpotInFile];
-                ifstream in2;
-                in2.open(currentFileName.c_str(), ios::binary);
-                in2.seekg(startSpotInFile);
-                in2.read(mybuffer,spot-startSpotInFile);
-                in2.close();
-                
-                int barcodeIndex, primerIndex;
-                int trashCodeLength = findGroup(header, read, barcodeIndex, primerIndex);
-                                
-                if(trashCodeLength == 0){
-                    //cout << header.name << " length = " << spot << '\t' << startSpotInFile << '\t' << in2.gcount() << endl;
-                    
-                    ofstream out;
-                    m->openOutputFileBinaryAppend(filehandles[barcodeIndex][primerIndex], out);
-                    out.write(mybuffer, in2.gcount()); 
-                    out.close();
-                    numSplitReads[barcodeIndex][primerIndex]++;
-                               }
-                               else{
-                                       ofstream out;
-                    m->openOutputFileBinaryAppend(noMatchFile, out);
-                    out.write(mybuffer, in2.gcount()); 
-                    out.close();
-                               }
-                               delete[] mybuffer;
-                       }
-               }else{
-                       m->mothurOut("Error reading."); m->mothurOutEndLine();
-               }
-
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "readSeqData");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::findGroup(Header header, seqRead read, int& barcode, int& primer) {
-       try {
-        //find group read belongs to
-        TrimOligos trimOligos(pdiffs, bdiffs, ldiffs, sdiffs, primers, barcodes, revPrimer, linker, spacer);
-        
-        int success = 1;
-        string trashCode = "";
-        int currentSeqsDiffs = 0;
-        
-        string seq = read.bases;
-        
-        if (trim) {
-            if(header.clipQualRight < header.clipQualLeft){
-                if (header.clipQualRight == 0) { //don't trim right
-                    seq = seq.substr(header.clipQualLeft-1);
-                }else {
-                    seq = "NNNN";
-                }
-            }
-            else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){
-                seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft));
-            }
-            else {
-                seq = seq.substr(header.clipQualLeft-1);
-            }
-        }else{
-            //if you wanted the sfftxt then you already converted the bases to the right case
-            if (!sfftxt) {
-                int endValue = header.clipQualRight;
-                //make the bases you want to clip lowercase and the bases you want to keep upper case
-                if(endValue == 0){     endValue = seq.length();        }
-                for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]);  }
-                for (int i = (header.clipQualLeft-1); i < (endValue-1); i++)  {   seq[i] = toupper(seq[i]);  }
-                for (int i = (endValue-1); i < seq.length(); i++) {   seq[i] = tolower(seq[i]);  }
-            }
-        }
-        
-        Sequence currSeq(header.name, seq);
-        QualityScores currQual;
-        
-        if(numLinkers != 0){
-            success = trimOligos.stripLinker(currSeq, currQual);
-            if(success > ldiffs)               {       trashCode += 'k';       }
-            else{ currentSeqsDiffs += success;  }
-            
-        }
-        
-        if(barcodes.size() != 0){
-            success = trimOligos.stripBarcode(currSeq, currQual, barcode);
-            if(success > bdiffs)               {       trashCode += 'b';       }
-            else{ currentSeqsDiffs += success;  }
-        }
-        
-        if(numSpacers != 0){
-            success = trimOligos.stripSpacer(currSeq, currQual);
-            if(success > sdiffs)               {       trashCode += 's';       }
-            else{ currentSeqsDiffs += success;  }
-            
-        }
-        
-        if(numFPrimers != 0){
-            success = trimOligos.stripForward(currSeq, currQual, primer, true);
-            if(success > pdiffs)               {       trashCode += 'f';       }
-            else{ currentSeqsDiffs += success;  }
-        }
-        
-        if (currentSeqsDiffs > tdiffs) {       trashCode += 't';   }
-        
-        if(revPrimer.size() != 0){
-            success = trimOligos.stripReverse(currSeq, currQual);
-            if(!success)                               {       trashCode += 'r';       }
-        }
-
-        
-        return trashCode.length();
-    }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "findGroup");
-               exit(1);
-       }
-}     
-//**********************************************************************************************************************
-int SffInfoCommand::decodeName(string& timestamp, string& region, string& xy, string name) {
-       try {
-               
-               if (name.length() >= 6) {
-                       string time = name.substr(0, 6);
-                       unsigned int timeNum = m->fromBase36(time);
-                       
-                       int q1 = timeNum / 60;
-                       int sec = timeNum - 60 * q1;
-                       int q2 = q1 / 60;
-                       int minute = q1 - 60 * q2;
-                       int q3 = q2 / 24;
-                       int hr = q2 - 24 * q3;
-                       int q4 = q3 / 32;
-                       int day = q3 - 32 * q4;
-                       int q5 = q4 / 13;
-                       int mon = q4 - 13 * q5;
-                       int year = 2000 + q5;
-               
-                       timestamp = toString(year) + "_" + toString(mon) + "_" + toString(day) + "_" + toString(hr) + "_" + toString(minute) + "_" + toString(sec);
-               }
-               
-               if (name.length() >= 9) {
-                       region = name.substr(7, 2);
-               
-                       string xyNum = name.substr(9);
-                       unsigned int myXy = m->fromBase36(xyNum);
-                       int x = myXy >> 12;
-                       int y = myXy & 4095;
-               
-                       xy = toString(x) + "_" + toString(y);
-               }
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "decodeName");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::printCommonHeader(ofstream& out, CommonHeader& header) {
-       try {
-       
-               out << "Common Header:\nMagic Number: " << header.magicNumber << endl;
-               out << "Version: " << header.version << endl;
-               out << "Index Offset: " << header.indexOffset << endl;
-               out << "Index Length: " << header.indexLength << endl;
-               out << "Number of Reads: " << header.numReads << endl;
-               out << "Header Length: " << header.headerLength << endl;
-               out << "Key Length: " << header.keyLength << endl;
-               out << "Number of Flows: " << header.numFlowsPerRead << endl;
-               out << "Format Code: " << header.flogramFormatCode << endl;
-               out << "Flow Chars: " << header.flowChars << endl;
-               out << "Key Sequence: " << header.keySequence << endl << endl;
-                       
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "printCommonHeader");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::printHeader(ofstream& out, Header& header) {
-       try {
-               
-               out << ">" << header.name << endl;
-               out << "Run Prefix: " << header.timestamp << endl;
-               out << "Region #:  " << header.region << endl;
-               out << "XY Location: " << header.xy << endl << endl;
-               
-               out << "Run Name:  " << endl;
-               out << "Analysis Name:  " << endl;
-               out << "Full Path: " << endl << endl;
-               
-               out << "Read Header Len: " << header.headerLength << endl;
-               out << "Name Length: " << header.nameLength << endl;
-               out << "# of Bases: " << header.numBases << endl;
-               out << "Clip Qual Left: " << header.clipQualLeft << endl;
-               out << "Clip Qual Right: " << header.clipQualRight << endl;
-               out << "Clip Adap Left: " << header.clipAdapterLeft << endl;
-               out << "Clip Adap Right: " << header.clipAdapterRight << endl << endl;
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "printHeader");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-bool SffInfoCommand::sanityCheck(Header& header, seqRead& read) {
-       try {
-        bool okay = true;
-        string message = "[WARNING]: Your sff file may be corrupted! Sequence: " + header.name + "\n";
-        
-        if (header.clipQualLeft > read.bases.length()) {
-            okay = false; message += "Clip Qual Left = " + toString(header.clipQualLeft) + ", but we only read " + toString(read.bases.length()) + " bases.\n";
-        }
-        if (header.clipQualRight > read.bases.length()) {
-            okay = false; message += "Clip Qual Right = " + toString(header.clipQualRight) + ", but we only read " + toString(read.bases.length()) + " bases.\n";
-        }
-        if (header.clipQualLeft > read.qualScores.size()) {
-            okay = false; message += "Clip Qual Left = " + toString(header.clipQualLeft) + ", but we only read " + toString(read.qualScores.size()) + " quality scores.\n";
-        }
-        if (header.clipQualRight > read.qualScores.size()) {
-            okay = false; message += "Clip Qual Right = " + toString(header.clipQualRight) + ", but we only read " + toString(read.qualScores.size()) + " quality scores.\n";
-        }
-        
-        if (okay == false) {
-            m->mothurOut(message); m->mothurOutEndLine();
-        }
-        
-               return okay;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "sanityCheck");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::printSffTxtSeqData(ofstream& out, seqRead& read, Header& header) {
-       try {
-               out << "Flowgram: ";
-               for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << (read.flowgram[i]/(float)100) << '\t';  }
-               
-               out << endl <<  "Flow Indexes: ";
-               int sum = 0;
-               for (int i = 0; i < read.flowIndex.size(); i++) {  sum +=  read.flowIndex[i];  out << sum << '\t'; }
-               
-               //make the bases you want to clip lowercase and the bases you want to keep upper case
-        int endValue = header.clipQualRight;
-               if(endValue == 0){      endValue = read.bases.length(); }
-               for (int i = 0; i < (header.clipQualLeft-1); i++) { read.bases[i] = tolower(read.bases[i]); }
-               for (int i = (header.clipQualLeft-1); i < (endValue-1); i++) {   read.bases[i] = toupper(read.bases[i]);  }
-               for (int i = (endValue-1); i < read.bases.length(); i++) {   read.bases[i] = tolower(read.bases[i]);  }
-               
-               out << endl <<  "Bases: " << read.bases << endl << "Quality Scores: ";
-               for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }
-       
-               
-               out << endl << endl;
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "printSffTxtSeqData");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::printFastaSeqData(ofstream& out, seqRead& read, Header& header) {
-       try {
-               string seq = read.bases;
-               
-        if (trim) {
-                       if(header.clipQualRight < header.clipQualLeft){
-                               if (header.clipQualRight == 0) { //don't trim right
-                    seq = seq.substr(header.clipQualLeft-1);
-                }else {
-                    seq = "NNNN";
-                }
-                       }
-                       else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){
-                               seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft));
-                       }
-                       else {
-                               seq = seq.substr(header.clipQualLeft-1);
-                       }
-               }else{
-                       //if you wanted the sfftxt then you already converted the bases to the right case
-                       if (!sfftxt) {
-                int endValue = header.clipQualRight;
-                               //make the bases you want to clip lowercase and the bases you want to keep upper case
-                               if(endValue == 0){      endValue = seq.length();        }
-                               for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]);  }
-                               for (int i = (header.clipQualLeft-1); i < (endValue-1); i++)  {   seq[i] = toupper(seq[i]);  }
-                               for (int i = (endValue-1); i < seq.length(); i++) {   seq[i] = tolower(seq[i]);  }
-                       }
-               }
-               
-               out << ">" << header.name  << " xy=" << header.xy << endl;
-               out << seq << endl;
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "printFastaSeqData");
-               exit(1);
-       }
-}
-
-//**********************************************************************************************************************
-int SffInfoCommand::printQualSeqData(ofstream& out, seqRead& read, Header& header) {
-       try {
-               
-               if (trim) {
-                       if(header.clipQualRight < header.clipQualLeft){
-                if (header.clipQualRight == 0) { //don't trim right
-                    out << ">" << header.name << " xy=" << header.xy << " length=" << (read.qualScores.size()-header.clipQualLeft) << endl;
-                    for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';      }       
-                }else {
-                    out << ">" << header.name << " xy=" << header.xy << endl;
-                    out << "0\t0\t0\t0";
-                }
-                       }
-                       else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){
-                               out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;
-                               for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) {   out << read.qualScores[i] << '\t'; }
-                       }
-                       else{
-                               out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;
-                               for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';   }                       
-                       }
-               }else{
-                       out << ">" << header.name << " xy=" << header.xy << " length=" << read.qualScores.size() << endl;
-                       for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }
-               }
-               
-               out << endl;
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "printQualSeqData");
-               exit(1);
-       }
-}
-
-//**********************************************************************************************************************
-int SffInfoCommand::printFlowSeqData(ofstream& out, seqRead& read, Header& header) {
-       try {
-        
-        int endValue = header.clipQualRight;
-        if (header.clipQualRight == 0) {
-            endValue = read.flowIndex.size();
-            if (m->debug) { m->mothurOut("[DEBUG]: " + header.name + " has clipQualRight=0.\n"); }
-        }
-        if(endValue > header.clipQualLeft){
-            
-            int rightIndex = 0;
-            for (int i = 0; i < endValue; i++) {  rightIndex +=  read.flowIndex[i];     }
-            
-            out << header.name << ' ' << rightIndex;
-            for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << ' ' << (read.flowgram[i]/(float)100);  }
-            out << endl;
-        }
-               
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "printFlowSeqData");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::readAccnosFile(string filename) {
-       try {
-               //remove old names
-               seqNames.clear();
-               
-               ifstream in;
-               m->openInputFile(filename, in);
-               string name;
-               
-               while(!in.eof()){
-                       in >> name; m->gobble(in);
-                                               
-                       seqNames.insert(name);
-                       
-                       if (m->control_pressed) { seqNames.clear(); break; }
-               }
-               in.close();             
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "readAccnosFile");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-int SffInfoCommand::parseSffTxt() {
-       try {
-               
-               ifstream inSFF;
-               m->openInputFile(sfftxtFilename, inSFF);
-               
-               if (outputDir == "") {  outputDir += m->hasPath(sfftxtFilename); }
-               
-               //output file names
-               ofstream outFasta, outQual, outFlow;
-               string outFastaFileName, outQualFileName;
-               string fileRoot = m->getRootName(m->getSimpleName(sfftxtFilename));
-               if (fileRoot.length() > 0) {
-                       //rip off last .
-                       fileRoot = fileRoot.substr(0, fileRoot.length()-1);
-                       fileRoot = m->getRootName(fileRoot);
-               }
-               
-        map<string, string> variables; 
-               variables["[filename]"] = fileRoot;
-               string sfftxtFileName = getOutputFileName("sfftxt",variables);
-               string outFlowFileName = getOutputFileName("flow",variables);
-               if (!trim) { variables["[tag]"] = "raw"; }
-               outFastaFileName = getOutputFileName("fasta",variables);
-        outQualFileName = getOutputFileName("qfile",variables);
-               
-               if (fasta)      { m->openOutputFile(outFastaFileName, outFasta);        outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); }
-               if (qual)       { m->openOutputFile(outQualFileName, outQual);          outputNames.push_back(outQualFileName); outputTypes["qfile"].push_back(outQualFileName);  }
-               if (flow)       { m->openOutputFile(outFlowFileName, outFlow);          outputNames.push_back(outFlowFileName);  outFlow.setf(ios::fixed, ios::floatfield); outFlow.setf(ios::showpoint); outputTypes["flow"].push_back(outFlowFileName);  }
-               
-               //read common header
-               string commonHeader = m->getline(inSFF);
-               string magicNumber = m->getline(inSFF); 
-               string version = m->getline(inSFF);
-               string indexOffset = m->getline(inSFF);
-               string indexLength = m->getline(inSFF);
-               int numReads = parseHeaderLineToInt(inSFF);
-               string headerLength = m->getline(inSFF);
-               string keyLength = m->getline(inSFF);
-               int numFlows = parseHeaderLineToInt(inSFF);
-               string flowgramCode = m->getline(inSFF);
-               string flowChars = m->getline(inSFF);
-               string keySequence = m->getline(inSFF);
-               m->gobble(inSFF);
-               
-               string seqName;
-               
-               if (flow)       {       outFlow << numFlows << endl;    }
-               
-               for(int i=0;i<numReads;i++){
-                       
-                       //sanity check
-                       if (inSFF.eof()) { m->mothurOut("[ERROR]: Expected " + toString(numReads) + " but reached end of file at " + toString(i+1) + "."); m->mothurOutEndLine(); break; }
-                       
-                       Header header;
-                       
-                       //parse read header
-                       inSFF >> seqName;
-                       seqName = seqName.substr(1);
-                       m->gobble(inSFF);
-                       header.name = seqName;
-                       
-                       string runPrefix = parseHeaderLineToString(inSFF);              header.timestamp = runPrefix;
-                       string regionNumber = parseHeaderLineToString(inSFF);   header.region = regionNumber;
-                       string xyLocation = parseHeaderLineToString(inSFF);             header.xy = xyLocation;
-                       m->gobble(inSFF);
-                               
-                       string runName = parseHeaderLineToString(inSFF);
-                       string analysisName = parseHeaderLineToString(inSFF);
-                       string fullPath = parseHeaderLineToString(inSFF);
-                       m->gobble(inSFF);
-                       
-                       string readHeaderLen = parseHeaderLineToString(inSFF);  convert(readHeaderLen, header.headerLength);
-                       string nameLength = parseHeaderLineToString(inSFF);             convert(nameLength, header.nameLength);
-                       int numBases = parseHeaderLineToInt(inSFF);                             header.numBases = numBases;
-                       string clipQualLeft = parseHeaderLineToString(inSFF);   convert(clipQualLeft, header.clipQualLeft);
-                       int clipQualRight = parseHeaderLineToInt(inSFF);                header.clipQualRight = clipQualRight;
-                       string clipAdapLeft = parseHeaderLineToString(inSFF);   convert(clipAdapLeft, header.clipAdapterLeft);
-                       string clipAdapRight = parseHeaderLineToString(inSFF);  convert(clipAdapRight, header.clipAdapterRight);
-                       m->gobble(inSFF);
-                               
-                       seqRead read;
-                       
-                       //parse read
-                       vector<unsigned short> flowVector = parseHeaderLineToFloatVector(inSFF, numFlows);      read.flowgram = flowVector;
-                       vector<unsigned int> flowIndices = parseHeaderLineToIntVector(inSFF, numBases); 
-                       
-                       //adjust for print
-                       vector<unsigned int> flowIndicesAdjusted; flowIndicesAdjusted.push_back(flowIndices[0]);
-                       for (int j = 1; j < flowIndices.size(); j++) {   flowIndicesAdjusted.push_back(flowIndices[j] - flowIndices[j-1]);   }
-                       read.flowIndex = flowIndicesAdjusted;
-                       
-                       string bases = parseHeaderLineToString(inSFF);                                                                          read.bases = bases;
-                       vector<unsigned int> qualityScores = parseHeaderLineToIntVector(inSFF, numBases);       read.qualScores = qualityScores;
-                       m->gobble(inSFF);
-                                       
-                       //if you have provided an accosfile and this seq is not in it, then dont print
-                       bool print = true;
-                       if (seqNames.size() != 0) {   if (seqNames.count(header.name) == 0) { print = false; }  }
-                       
-                       //print 
-                       if (print) {
-                               if (fasta)      {       printFastaSeqData(outFasta, read, header);      }
-                               if (qual)       {       printQualSeqData(outQual, read, header);        }
-                               if (flow)       {       printFlowSeqData(outFlow, read, header);        }
-                       }
-                       
-                       //report progress
-                       if((i+1) % 10000 == 0){ m->mothurOut(toString(i+1)); m->mothurOutEndLine();             }
-                       
-                       if (m->control_pressed) {  break;  }
-               }
-               
-               //report progress
-               if (!m->control_pressed) {   if((numReads) % 10000 != 0){       m->mothurOut(toString(numReads)); m->mothurOutEndLine();                }  }
-               
-               inSFF.close();
-               
-               if (fasta)      {  outFasta.close();    }
-               if (qual)       {  outQual.close();             }
-               if (flow)       {  outFlow.close();             }
-               
-               return 0;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "parseSffTxt");
-               exit(1);
-       }
-}
-//**********************************************************************************************************************
-
-int SffInfoCommand::parseHeaderLineToInt(ifstream& file){
-       try {
-               int number;
-               
-               while (!file.eof())     {
-                       
-                       char c = file.get(); 
-                       if (c == ':'){
-                               file >> number;
-                               break;
-                       }
-                       
-               }
-               m->gobble(file);
-               return number;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToInt");
-               exit(1);
-       }
-       
-}
-
-//**********************************************************************************************************************
-
-string SffInfoCommand::parseHeaderLineToString(ifstream& file){
-       try {
-               string text;
-               
-               while (!file.eof())     {
-                       char c = file.get(); 
-                       
-                       if (c == ':'){
-                               //m->gobble(file);
-                               //text = m->getline(file);      
-                               file >> text;
-                               break;
-                       }
-               }
-               m->gobble(file);
-               
-               return text;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToString");
-               exit(1);
-       }
-}
-
-//**********************************************************************************************************************
-
-vector<unsigned short> SffInfoCommand::parseHeaderLineToFloatVector(ifstream& file, int length){
-       try {
-               vector<unsigned short> floatVector(length);
-               
-               while (!file.eof())     {
-                       char c = file.get(); 
-                       if (c == ':'){
-                               float temp;
-                               for(int i=0;i<length;i++){
-                                       file >> temp;
-                                       floatVector[i] = temp * 100;
-                               }
-                               break;
-                       }
-               }
-               m->gobble(file);        
-               return floatVector;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToFloatVector");
-               exit(1);
-       }
-}
-
-//**********************************************************************************************************************
-
-vector<unsigned int> SffInfoCommand::parseHeaderLineToIntVector(ifstream& file, int length){
-       try {
-               vector<unsigned int> intVector(length);
-               
-               while (!file.eof())     {
-                       char c = file.get(); 
-                       if (c == ':'){
-                               for(int i=0;i<length;i++){
-                                       file >> intVector[i];
-                               }
-                               break;
-                       }
-               }
-               m->gobble(file);        
-               return intVector;
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToIntVector");
-               exit(1);
-       }
-}
-//***************************************************************************************************************
-
-bool SffInfoCommand::readOligos(string oligoFile){
-       try {
-        filehandles.clear();
-        numSplitReads.clear();
-        filehandlesHeaders.clear();
-        
-               ifstream inOligos;
-               m->openInputFile(oligoFile, inOligos);
-               
-               string type, oligo, group;
-        
-               int indexPrimer = 0;
-               int indexBarcode = 0;
-               
-               while(!inOligos.eof()){
-            
-                       inOligos >> type; 
-            
-                       if(type[0] == '#'){
-                               while (!inOligos.eof()) {       char c = inOligos.get();  if (c == 10 || c == 13){      break;  }       } // get rest of line if there's any crap there
-                               m->gobble(inOligos);
-                       }
-                       else{
-                               m->gobble(inOligos);
-                               //make type case insensitive
-                               for(int i=0;i<type.length();i++){       type[i] = toupper(type[i]);  }
-                               
-                               inOligos >> oligo;
-                               
-                               for(int i=0;i<oligo.length();i++){
-                                       oligo[i] = toupper(oligo[i]);
-                                       if(oligo[i] == 'U')     {       oligo[i] = 'T'; }
-                               }
-                               
-                               if(type == "FORWARD"){
-                                       group = "";
-                                       
-                                       // get rest of line in case there is a primer name
-                                       while (!inOligos.eof()) {       
-                                               char c = inOligos.get(); 
-                                               if (c == 10 || c == 13 || c == -1){     break;  }
-                                               else if (c == 32 || c == 9){;} //space or tab
-                                               else {  group += c;  }
-                                       } 
-                                       
-                                       //check for repeat barcodes
-                                       map<string, int>::iterator itPrime = primers.find(oligo);
-                                       if (itPrime != primers.end()) { m->mothurOut("primer " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }
-                                       
-                                       primers[oligo]=indexPrimer; indexPrimer++;              
-                                       primerNameVector.push_back(group);
-                               }else if(type == "REVERSE"){
-                                       //Sequence oligoRC("reverse", oligo);
-                                       //oligoRC.reverseComplement();
-                    string oligoRC = reverseOligo(oligo);
-                                       revPrimer.push_back(oligoRC);
-                               }
-                               else if(type == "BARCODE"){
-                                       inOligos >> group;
-                                       
-                                       //check for repeat barcodes
-                                       map<string, int>::iterator itBar = barcodes.find(oligo);
-                                       if (itBar != barcodes.end()) { m->mothurOut("barcode " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }
-                    
-                                       barcodes[oligo]=indexBarcode; indexBarcode++;
-                                       barcodeNameVector.push_back(group);
-                               }else if(type == "LINKER"){
-                                       linker.push_back(oligo);
-                               }else if(type == "SPACER"){
-                                       spacer.push_back(oligo);
-                               }
-                               else{   m->mothurOut("[WARNING]: " + type + " is not recognized as a valid type. Choices are forward, reverse, and barcode. Ignoring " + oligo + "."); m->mothurOutEndLine(); }
-                       }
-                       m->gobble(inOligos);
-               }       
-               inOligos.close();
-               
-               if(barcodeNameVector.size() == 0 && primerNameVector[0] == ""){ split = 1;      }
-               
-               //add in potential combos
-               if(barcodeNameVector.size() == 0){
-                       barcodes[""] = 0;
-                       barcodeNameVector.push_back("");                        
-               }
-               
-               if(primerNameVector.size() == 0){
-                       primers[""] = 0;
-                       primerNameVector.push_back("");                 
-               }
-               
-               filehandles.resize(barcodeNameVector.size());
-               for(int i=0;i<filehandles.size();i++){
-                       filehandles[i].assign(primerNameVector.size(), "");
-               }
-                       
-               if(split > 1){
-                       set<string> uniqueNames; //used to cleanup outputFileNames
-                       for(map<string, int>::iterator itBar = barcodes.begin();itBar != barcodes.end();itBar++){
-                               for(map<string, int>::iterator itPrimer = primers.begin();itPrimer != primers.end(); itPrimer++){
-                                       
-                                       string primerName = primerNameVector[itPrimer->second];
-                                       string barcodeName = barcodeNameVector[itBar->second];
-                                       
-                                       string comboGroupName = "";
-                                       string fastaFileName = "";
-                                       string qualFileName = "";
-                                       string nameFileName = "";
-                                       
-                                       if(primerName == ""){
-                                               comboGroupName = barcodeNameVector[itBar->second];
-                                       }
-                                       else{
-                                               if(barcodeName == ""){
-                                                       comboGroupName = primerNameVector[itPrimer->second];
-                                               }
-                                               else{
-                                                       comboGroupName = barcodeNameVector[itBar->second] + "." + primerNameVector[itPrimer->second];
-                                               }
-                                       }
-                                       
-                                       ofstream temp;
-                    map<string, string> variables; 
-                    variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));
-                    variables["[group]"] = comboGroupName;
-                                       string thisFilename = getOutputFileName("sff",variables);
-                                       if (uniqueNames.count(thisFilename) == 0) {
-                                               outputNames.push_back(thisFilename);
-                                               outputTypes["sff"].push_back(thisFilename);
-                                               uniqueNames.insert(thisFilename);
-                                       }
-                                       
-                                       filehandles[itBar->second][itPrimer->second] = thisFilename;
-                                       temp.open(thisFilename.c_str(), ios::binary);           temp.close();
-                               }
-                       }
-               }
-               numFPrimers = primers.size();
-        numLinkers = linker.size();
-        numSpacers = spacer.size();
-        map<string, string> variables; 
-        variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));
-        variables["[group]"] = "scrap";
-               noMatchFile = getOutputFileName("sff",variables);
-        m->mothurRemove(noMatchFile);
-        
-               bool allBlank = true;
-               for (int i = 0; i < barcodeNameVector.size(); i++) {
-                       if (barcodeNameVector[i] != "") {
-                               allBlank = false;
-                               break;
-                       }
-               }
-               for (int i = 0; i < primerNameVector.size(); i++) {
-                       if (primerNameVector[i] != "") {
-                               allBlank = false;
-                               break;
-                       }
-               }
-               
-        filehandlesHeaders.resize(filehandles.size());
-        numSplitReads.resize(filehandles.size());
-        for (int i = 0; i < filehandles.size(); i++) { 
-            numSplitReads[i].resize(filehandles[i].size(), 0); 
-            for (int j = 0; j < filehandles[i].size(); j++) {
-                filehandlesHeaders[i].push_back(filehandles[i][j]+"headers");
-            }
-        }
-                             
-               if (allBlank) {
-                       m->mothurOut("[WARNING]: your oligos file does not contain any group names.  mothur will not create a split the sff file."); m->mothurOutEndLine();
-                       split = 1;
-                       return false;
-               }
-               
-               return true;
-               
-       }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "readOligos");
-               exit(1);
-       }
-}
-//********************************************************************/
-string SffInfoCommand::reverseOligo(string oligo){
-       try {
-        string reverse = "";
-        
-        for(int i=oligo.length()-1;i>=0;i--){
-            
-            if(oligo[i] == 'A')                {       reverse += 'T'; }
-            else if(oligo[i] == 'T'){  reverse += 'A'; }
-            else if(oligo[i] == 'U'){  reverse += 'A'; }
-            
-            else if(oligo[i] == 'G'){  reverse += 'C'; }
-            else if(oligo[i] == 'C'){  reverse += 'G'; }
-            
-            else if(oligo[i] == 'R'){  reverse += 'Y'; }
-            else if(oligo[i] == 'Y'){  reverse += 'R'; }
-            
-            else if(oligo[i] == 'M'){  reverse += 'K'; }
-            else if(oligo[i] == 'K'){  reverse += 'M'; }
-            
-            else if(oligo[i] == 'W'){  reverse += 'W'; }
-            else if(oligo[i] == 'S'){  reverse += 'S'; }
-            
-            else if(oligo[i] == 'B'){  reverse += 'V'; }
-            else if(oligo[i] == 'V'){  reverse += 'B'; }
-            
-            else if(oligo[i] == 'D'){  reverse += 'H'; }
-            else if(oligo[i] == 'H'){  reverse += 'D'; }
-            
-            else                                               {       reverse += 'N'; }
-        }
-        
-        
-        return reverse;
-    }
-       catch(exception& e) {
-               m->errorOut(e, "SffInfoCommand", "reverseOligo");
-               exit(1);
-       }
-}
-
-//**********************************************************************************************************************
-
-
-                               
-                               
+/*\r
+ *  sffinfocommand.cpp\r
+ *  Mothur\r
+ *\r
+ *  Created by westcott on 7/7/10.\r
+ *  Copyright 2010 Schloss Lab. All rights reserved.\r
+ *\r
+ */\r
+\r
+#include "sffinfocommand.h"\r
+#include "endiannessmacros.h"\r
+#include "trimoligos.h"\r
+#include "sequence.hpp"\r
+#include "qualityscores.h"\r
+\r
+//**********************************************************************************************************************\r
+vector<string> SffInfoCommand::setParameters(){        \r
+       try {           \r
+               CommandParameter psff("sff", "InputTypes", "", "", "none", "none", "none","",false,false,true); parameters.push_back(psff);\r
+        CommandParameter poligos("oligos", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(poligos);\r
+               CommandParameter paccnos("accnos", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(paccnos);\r
+               CommandParameter psfftxt("sfftxt", "String", "", "", "", "", "","",false,false); parameters.push_back(psfftxt);\r
+               CommandParameter pflow("flow", "Boolean", "", "T", "", "", "","flow",false,false); parameters.push_back(pflow);\r
+               CommandParameter ptrim("trim", "Boolean", "", "T", "", "", "","",false,false); parameters.push_back(ptrim);\r
+               CommandParameter pfasta("fasta", "Boolean", "", "T", "", "", "","fasta",false,false); parameters.push_back(pfasta);\r
+               CommandParameter pqfile("qfile", "Boolean", "", "T", "", "", "","qfile",false,false); parameters.push_back(pqfile);\r
+        CommandParameter ppdiffs("pdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(ppdiffs);\r
+               CommandParameter pbdiffs("bdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pbdiffs);\r
+        CommandParameter pldiffs("ldiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pldiffs);\r
+               CommandParameter psdiffs("sdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(psdiffs);\r
+        CommandParameter ptdiffs("tdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(ptdiffs);\r
+               CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);\r
+               CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);\r
+               \r
+               vector<string> myArray;\r
+               for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }\r
+               return myArray;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "setParameters");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+string SffInfoCommand::getHelpString(){        \r
+       try {\r
+               string helpString = "";\r
+               helpString += "The sffinfo command reads a sff file and extracts the sequence data, or you can use it to parse a sfftxt file.\n";\r
+               helpString += "The sffinfo command parameters are sff, fasta, qfile, accnos, flow, sfftxt, oligos, bdiffs, tdiffs, ldiffs, sdiffs, pdiffs and trim. sff is required. \n";\r
+               helpString += "The sff parameter allows you to enter the sff file you would like to extract data from.  You may enter multiple files by separating them by -'s.\n";\r
+               helpString += "The fasta parameter allows you to indicate if you would like a fasta formatted file generated.  Default=True. \n";\r
+               helpString += "The qfile parameter allows you to indicate if you would like a quality file generated.  Default=True. \n";\r
+        helpString += "The oligos parameter allows you to provide an oligos file to split your sff file into separate sff files by barcode. \n";\r
+        helpString += "The tdiffs parameter is used to specify the total number of differences allowed in the sequence. The default is pdiffs + bdiffs + sdiffs + ldiffs.\n";\r
+               helpString += "The bdiffs parameter is used to specify the number of differences allowed in the barcode. The default is 0.\n";\r
+               helpString += "The pdiffs parameter is used to specify the number of differences allowed in the primer. The default is 0.\n";\r
+        helpString += "The ldiffs parameter is used to specify the number of differences allowed in the linker. The default is 0.\n";\r
+               helpString += "The sdiffs parameter is used to specify the number of differences allowed in the spacer. The default is 0.\n";\r
+               helpString += "The flow parameter allows you to indicate if you would like a flowgram file generated.  Default=True. \n";\r
+               helpString += "The sfftxt parameter allows you to indicate if you would like a sff.txt file generated.  Default=False. \n";\r
+               helpString += "If you want to parse an existing sfftxt file into flow, fasta and quality file, enter the file name using the sfftxt parameter. \n";\r
+               helpString += "The trim parameter allows you to indicate if you would like a sequences and quality scores trimmed to the clipQualLeft and clipQualRight values.  Default=True. \n";\r
+               helpString += "The accnos parameter allows you to provide a accnos file containing the names of the sequences you would like extracted. You may enter multiple files by separating them by -'s. \n";\r
+               helpString += "Example sffinfo(sff=mySffFile.sff, trim=F).\n";\r
+               helpString += "Note: No spaces between parameter labels (i.e. sff), '=' and parameters (i.e.yourSffFileName).\n";\r
+               return helpString;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "getHelpString");\r
+               exit(1);\r
+       }\r
+}\r
+\r
+//**********************************************************************************************************************\r
+string SffInfoCommand::getOutputPattern(string type) {\r
+    try {\r
+        string pattern = "";\r
+        \r
+        if (type == "fasta")            {   pattern =  "[filename],fasta-[filename],[tag],fasta";   }\r
+        else if (type == "flow")    {   pattern =  "[filename],flow";   }\r
+        else if (type == "sfftxt")        {   pattern =  "[filename],sff.txt";   }\r
+        else if (type == "sff")        {   pattern =  "[filename],[group],sff";   }\r
+        else if (type == "qfile")       {   pattern =  "[filename],qual-[filename],[tag],qual";   }\r
+        else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }\r
+        \r
+        return pattern;\r
+    }\r
+    catch(exception& e) {\r
+        m->errorOut(e, "SffInfoCommand", "getOutputPattern");\r
+        exit(1);\r
+    }\r
+}\r
+//**********************************************************************************************************************\r
+SffInfoCommand::SffInfoCommand(){      \r
+       try {\r
+               abort = true; calledHelp = true; \r
+               setParameters();\r
+               vector<string> tempOutNames;\r
+               outputTypes["fasta"] = tempOutNames;\r
+               outputTypes["flow"] = tempOutNames;\r
+               outputTypes["sfftxt"] = tempOutNames;\r
+               outputTypes["qfile"] = tempOutNames;\r
+        outputTypes["sff"] = tempOutNames;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "SffInfoCommand");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+\r
+SffInfoCommand::SffInfoCommand(string option)  {\r
+       try {\r
+               abort = false; calledHelp = false;   \r
+               hasAccnos = false; hasOligos = false;\r
+        split = 1;\r
+               \r
+               //allow user to run help\r
+               if(option == "help") { help(); abort = true; calledHelp = true; }\r
+               else if(option == "citation") { citation(); abort = true; calledHelp = true;}\r
+               \r
+               else {\r
+                       //valid paramters for this command\r
+                       vector<string> myArray = setParameters();\r
+                       \r
+                       OptionParser parser(option);\r
+                       map<string, string> parameters = parser.getParameters();\r
+                       \r
+                       ValidParameters validParameter;\r
+                       //check to make sure all parameters are valid for command\r
+                       for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) { \r
+                               if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }\r
+                       }\r
+                       \r
+                       //initialize outputTypes\r
+                       vector<string> tempOutNames;\r
+                       outputTypes["fasta"] = tempOutNames;\r
+                       outputTypes["flow"] = tempOutNames;\r
+                       outputTypes["sfftxt"] = tempOutNames;\r
+                       outputTypes["qfile"] = tempOutNames;\r
+            outputTypes["sff"] = tempOutNames;\r
+                       \r
+                       //if the user changes the output directory command factory will send this info to us in the output parameter \r
+                       outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }\r
+                       \r
+                       //if the user changes the input directory command factory will send this info to us in the output parameter \r
+                       string inputDir = validParameter.validFile(parameters, "inputdir", false);        if (inputDir == "not found"){ inputDir = "";          }\r
+\r
+                       sffFilename = validParameter.validFile(parameters, "sff", false);\r
+                       if (sffFilename == "not found") { sffFilename = "";  }\r
+                       else { \r
+                               m->splitAtDash(sffFilename, filenames);\r
+                               \r
+                               //go through files and make sure they are good, if not, then disregard them\r
+                               for (int i = 0; i < filenames.size(); i++) {\r
+                                       bool ignore = false;\r
+                                       if (filenames[i] == "current") { \r
+                                               filenames[i] = m->getSFFFile(); \r
+                                               if (filenames[i] != "") {  m->mothurOut("Using " + filenames[i] + " as input file for the sff parameter where you had given current."); m->mothurOutEndLine(); }\r
+                                               else {  \r
+                                                       m->mothurOut("You have no current sfffile, ignoring current."); m->mothurOutEndLine(); ignore=true; \r
+                                                       //erase from file list\r
+                                                       filenames.erase(filenames.begin()+i);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       if (!ignore) {\r
+                                               if (inputDir != "") {\r
+                                                       string path = m->hasPath(filenames[i]);\r
+                                                       //if the user has not given a path then, add inputdir. else leave path alone.\r
+                                                       if (path == "") {       filenames[i] = inputDir + filenames[i];         }\r
+                                               }\r
+               \r
+                                               ifstream in;\r
+                                               int ableToOpen = m->openInputFile(filenames[i], in, "noerror");\r
+                                       \r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getDefaultPath() != "") { //default path is set\r
+                                                               string tryPath = m->getDefaultPath() + m->getSimpleName(filenames[i]);\r
+                                                               m->mothurOut("Unable to open " + filenames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               filenames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               \r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getOutputDir() != "") { //default path is set\r
+                                                               string tryPath = m->getOutputDir() + m->getSimpleName(filenames[i]);\r
+                                                               m->mothurOut("Unable to open " + filenames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               filenames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               \r
+                                               in.close();\r
+                                               \r
+                                               if (ableToOpen == 1) { \r
+                                                       m->mothurOut("Unable to open " + filenames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
+                                                       //erase from file list\r
+                                                       filenames.erase(filenames.begin()+i);\r
+                                                       i--;\r
+                                               }else { m->setSFFFile(filenames[i]); }\r
+                                       }\r
+                               }\r
+                               \r
+                               //make sure there is at least one valid file left\r
+                               if (filenames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }\r
+                       }\r
+                       \r
+                       accnosName = validParameter.validFile(parameters, "accnos", false);\r
+                       if (accnosName == "not found") { accnosName = "";  }\r
+                       else { \r
+                               hasAccnos = true;\r
+                               m->splitAtDash(accnosName, accnosFileNames);\r
+                               \r
+                               //go through files and make sure they are good, if not, then disregard them\r
+                               for (int i = 0; i < accnosFileNames.size(); i++) {\r
+                                       bool ignore = false;\r
+                                       if (accnosFileNames[i] == "current") { \r
+                                               accnosFileNames[i] = m->getAccnosFile(); \r
+                                               if (accnosFileNames[i] != "") {  m->mothurOut("Using " + accnosFileNames[i] + " as input file for the accnos parameter where you had given current."); m->mothurOutEndLine(); }\r
+                                               else {  \r
+                                                       m->mothurOut("You have no current accnosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; \r
+                                                       //erase from file list\r
+                                                       accnosFileNames.erase(accnosFileNames.begin()+i);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       if (!ignore) {\r
+                                       \r
+                                               if (inputDir != "") {\r
+                                                       string path = m->hasPath(accnosFileNames[i]);\r
+                                                       //if the user has not given a path then, add inputdir. else leave path alone.\r
+                                                       if (path == "") {       accnosFileNames[i] = inputDir + accnosFileNames[i];             }\r
+                                               }\r
+               \r
+                                               ifstream in;\r
+                                               int ableToOpen = m->openInputFile(accnosFileNames[i], in, "noerror");\r
+                                       \r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getDefaultPath() != "") { //default path is set\r
+                                                               string tryPath = m->getDefaultPath() + m->getSimpleName(accnosFileNames[i]);\r
+                                                               m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               accnosFileNames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getOutputDir() != "") { //default path is set\r
+                                                               string tryPath = m->getOutputDir() + m->getSimpleName(accnosFileNames[i]);\r
+                                                               m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               accnosFileNames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               in.close();\r
+                                               \r
+                                               if (ableToOpen == 1) { \r
+                                                       m->mothurOut("Unable to open " + accnosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
+                                                       //erase from file list\r
+                                                       accnosFileNames.erase(accnosFileNames.begin()+i);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               \r
+                               //make sure there is at least one valid file left\r
+                               if (accnosFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }\r
+                       }\r
+            \r
+            oligosfile = validParameter.validFile(parameters, "oligos", false);\r
+                       if (oligosfile == "not found") { oligosfile = "";  }\r
+                       else { \r
+                               hasOligos = true;\r
+                               m->splitAtDash(oligosfile, oligosFileNames);\r
+                               \r
+                               //go through files and make sure they are good, if not, then disregard them\r
+                               for (int i = 0; i < oligosFileNames.size(); i++) {\r
+                                       bool ignore = false;\r
+                                       if (oligosFileNames[i] == "current") { \r
+                                               oligosFileNames[i] = m->getOligosFile(); \r
+                                               if (oligosFileNames[i] != "") {  m->mothurOut("Using " + oligosFileNames[i] + " as input file for the accnos parameter where you had given current."); m->mothurOutEndLine(); }\r
+                                               else {  \r
+                                                       m->mothurOut("You have no current oligosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; \r
+                                                       //erase from file list\r
+                                                       oligosFileNames.erase(oligosFileNames.begin()+i);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       if (!ignore) {\r
+                        \r
+                                               if (inputDir != "") {\r
+                                                       string path = m->hasPath(oligosFileNames[i]);\r
+                                                       //if the user has not given a path then, add inputdir. else leave path alone.\r
+                                                       if (path == "") {       oligosFileNames[i] = inputDir + oligosFileNames[i];             }\r
+                                               }\r
+                        \r
+                                               ifstream in;\r
+                                               int ableToOpen = m->openInputFile(oligosFileNames[i], in, "noerror");\r
+                        \r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getDefaultPath() != "") { //default path is set\r
+                                                               string tryPath = m->getDefaultPath() + m->getSimpleName(oligosFileNames[i]);\r
+                                                               m->mothurOut("Unable to open " + oligosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               oligosFileNames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getOutputDir() != "") { //default path is set\r
+                                                               string tryPath = m->getOutputDir() + m->getSimpleName(oligosFileNames[i]);\r
+                                                               m->mothurOut("Unable to open " + oligosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               oligosFileNames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               in.close();\r
+                                               \r
+                                               if (ableToOpen == 1) { \r
+                                                       m->mothurOut("Unable to open " + oligosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
+                                                       //erase from file list\r
+                                                       oligosFileNames.erase(oligosFileNames.begin()+i);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               \r
+                               //make sure there is at least one valid file left\r
+                               if (oligosFileNames.size() == 0) { m->mothurOut("no valid oligos files."); m->mothurOutEndLine(); abort = true; }\r
+                       }\r
+\r
+                       if (hasOligos) {\r
+                split = 2;\r
+                               if (oligosFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide a oligos file, you must have one for each sff file."); m->mothurOutEndLine(); }\r
+                       }\r
+            \r
+                       if (hasAccnos) {\r
+                               if (accnosFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide a accnos file, you must have one for each sff file."); m->mothurOutEndLine(); }\r
+                       }\r
+                       \r
+                       string temp = validParameter.validFile(parameters, "qfile", false);                     if (temp == "not found"){       temp = "T";                             }\r
+                       qual = m->isTrue(temp); \r
+                       \r
+                       temp = validParameter.validFile(parameters, "fasta", false);                            if (temp == "not found"){       temp = "T";                             }\r
+                       fasta = m->isTrue(temp); \r
+                       \r
+                       temp = validParameter.validFile(parameters, "flow", false);                                     if (temp == "not found"){       temp = "T";                             }\r
+                       flow = m->isTrue(temp); \r
+                       \r
+                       temp = validParameter.validFile(parameters, "trim", false);                                     if (temp == "not found"){       temp = "T";                             }\r
+                       trim = m->isTrue(temp); \r
+            \r
+            temp = validParameter.validFile(parameters, "bdiffs", false);              if (temp == "not found") { temp = "0"; }\r
+                       m->mothurConvert(temp, bdiffs);\r
+                       \r
+                       temp = validParameter.validFile(parameters, "pdiffs", false);           if (temp == "not found") { temp = "0"; }\r
+                       m->mothurConvert(temp, pdiffs);\r
+            \r
+            temp = validParameter.validFile(parameters, "ldiffs", false);              if (temp == "not found") { temp = "0"; }\r
+                       m->mothurConvert(temp, ldiffs);\r
+            \r
+            temp = validParameter.validFile(parameters, "sdiffs", false);              if (temp == "not found") { temp = "0"; }\r
+                       m->mothurConvert(temp, sdiffs);\r
+                       \r
+                       temp = validParameter.validFile(parameters, "tdiffs", false);           if (temp == "not found") { int tempTotal = pdiffs + bdiffs + ldiffs + sdiffs;  temp = toString(tempTotal); }\r
+                       m->mothurConvert(temp, tdiffs);\r
+                       \r
+                       if(tdiffs == 0){        tdiffs = bdiffs + pdiffs + ldiffs + sdiffs;     }\r
+            \r
+                       temp = validParameter.validFile(parameters, "sfftxt", false);                           \r
+                       if (temp == "not found")        {       temp = "F";      sfftxt = false; sfftxtFilename = "";           }\r
+                       else if (m->isTrue(temp))       {       sfftxt = true;          sfftxtFilename = "";                            }\r
+                       else {\r
+                               //you are a filename\r
+                               if (inputDir != "") {\r
+                                       map<string,string>::iterator it = parameters.find("sfftxt");\r
+                                       //user has given a template file\r
+                                       if(it != parameters.end()){ \r
+                                               string path = m->hasPath(it->second);\r
+                                               //if the user has not given a path then, add inputdir. else leave path alone.\r
+                                               if (path == "") {       parameters["sfftxt"] = inputDir + it->second;           }\r
+                                       }\r
+                               }\r
+                               \r
+                               sfftxtFilename = validParameter.validFile(parameters, "sfftxt", true);\r
+                               if (sfftxtFilename == "not found") { sfftxtFilename = "";  }\r
+                               else if (sfftxtFilename == "not open") { sfftxtFilename = "";  }\r
+                       }\r
+                       \r
+                       if ((sfftxtFilename == "") && (filenames.size() == 0)) {  \r
+                               //if there is a current sff file, use it\r
+                               string filename = m->getSFFFile(); \r
+                               if (filename != "") { filenames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the sff parameter."); m->mothurOutEndLine(); }\r
+                               else {  m->mothurOut("[ERROR]: you must provide a valid sff or sfftxt file."); m->mothurOutEndLine(); abort=true;  }\r
+                       }\r
+            \r
+            \r
+               }\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "SffInfoCommand");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::execute(){\r
+       try {\r
+               if (abort == true) { if (calledHelp) { return 0; }  return 2;   }\r
+               \r
+               for (int s = 0; s < filenames.size(); s++) {\r
+                       \r
+                       if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]);        } return 0; }\r
+                       \r
+                       int start = time(NULL);\r
+                       \r
+            filenames[s] = m->getFullPathName(filenames[s]);\r
+                       m->mothurOut("Extracting info from " + filenames[s] + " ..." ); m->mothurOutEndLine();\r
+                       \r
+                       string accnos = "";\r
+                       if (hasAccnos) { accnos = accnosFileNames[s]; }\r
+            \r
+            string oligos = "";\r
+            if (hasOligos) { oligos = oligosFileNames[s]; }\r
+                       \r
+                       int numReads = extractSffInfo(filenames[s], accnos, oligos);\r
+\r
+                       m->mothurOut("It took " + toString(time(NULL) - start) + " secs to extract " + toString(numReads) + ".");\r
+               }\r
+               \r
+               if (sfftxtFilename != "") {  parseSffTxt(); }\r
+               \r
+               if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]);        } return 0; }\r
+               \r
+               //set fasta file as new current fastafile\r
+               string current = "";\r
+               itTypes = outputTypes.find("fasta");\r
+               if (itTypes != outputTypes.end()) {\r
+                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); }\r
+               }\r
+               \r
+               itTypes = outputTypes.find("qfile");\r
+               if (itTypes != outputTypes.end()) {\r
+                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setQualFile(current); }\r
+               }\r
+               \r
+               itTypes = outputTypes.find("flow");\r
+               if (itTypes != outputTypes.end()) {\r
+                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFlowFile(current); }\r
+               }\r
+               \r
+               //report output filenames\r
+               m->mothurOutEndLine();\r
+               m->mothurOut("Output File Names: "); m->mothurOutEndLine();\r
+               for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }\r
+               m->mothurOutEndLine();\r
+\r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "execute");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){\r
+       try {\r
+               currentFileName = input;\r
+               if (outputDir == "") {  outputDir += m->hasPath(input); }\r
+               \r
+               if (accnos != "")       {  readAccnosFile(accnos);  }\r
+               else                            {       seqNames.clear();               }\r
+         \r
+        if (oligos != "")   {   readOligos(oligos);  split = 2;   }\r
+\r
+               ofstream outSfftxt, outFasta, outQual, outFlow;\r
+               string outFastaFileName, outQualFileName;\r
+        string rootName = outputDir + m->getRootName(m->getSimpleName(input));\r
+        if(rootName.find_last_of(".") == rootName.npos){ rootName += "."; }\r
+        \r
+        map<string, string> variables; \r
+               variables["[filename]"] = rootName;\r
+               string sfftxtFileName = getOutputFileName("sfftxt",variables);\r
+               string outFlowFileName = getOutputFileName("flow",variables);\r
+               if (!trim) { variables["[tag]"] = "raw"; }\r
+               outFastaFileName = getOutputFileName("fasta",variables);\r
+        outQualFileName = getOutputFileName("qfile",variables);\r
+        \r
+               if (sfftxt) { m->openOutputFile(sfftxtFileName, outSfftxt); outSfftxt.setf(ios::fixed, ios::floatfield); outSfftxt.setf(ios::showpoint);  outputNames.push_back(sfftxtFileName);  outputTypes["sfftxt"].push_back(sfftxtFileName); }\r
+               if (fasta)      { m->openOutputFile(outFastaFileName, outFasta);        outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); }\r
+               if (qual)       { m->openOutputFile(outQualFileName, outQual);          outputNames.push_back(outQualFileName); outputTypes["qfile"].push_back(outQualFileName);  }\r
+               if (flow)       { m->openOutputFile(outFlowFileName, outFlow);          outputNames.push_back(outFlowFileName);  outFlow.setf(ios::fixed, ios::floatfield); outFlow.setf(ios::showpoint); outputTypes["flow"].push_back(outFlowFileName);  }\r
+               \r
+               ifstream in;\r
+               m->openInputFileBinary(input, in);\r
+               \r
+               CommonHeader header;\r
+               readCommonHeader(in, header);\r
+        \r
+               int count = 0;\r
+               \r
+               //check magic number and version\r
+               if (header.magicNumber != 779314790) { m->mothurOut("Magic Number is not correct, not a valid .sff file"); m->mothurOutEndLine(); return count; }\r
+               if (header.version != "0001") { m->mothurOut("Version is not supported, only support version 0001."); m->mothurOutEndLine(); return count; }\r
+       \r
+               //print common header\r
+               if (sfftxt) {   printCommonHeader(outSfftxt, header);           }\r
+               if (flow)       {       outFlow << header.numFlowsPerRead << endl;      }\r
+                       \r
+               //read through the sff file\r
+               while (!in.eof()) {\r
+                       \r
+                       bool print = true;\r
+                                               \r
+                       //read data\r
+                       seqRead read;  Header readheader;\r
+            readSeqData(in, read, header.numFlowsPerRead, readheader);\r
+            \r
+            bool okay = sanityCheck(readheader, read);\r
+            if (!okay) { break; }\r
+            \r
+                       //if you have provided an accosfile and this seq is not in it, then dont print\r
+                       if (seqNames.size() != 0) {   if (seqNames.count(readheader.name) == 0) { print = false; }  }\r
+                       \r
+                       //print \r
+                       if (print) {\r
+                               if (sfftxt) { printHeader(outSfftxt, readheader); printSffTxtSeqData(outSfftxt, read, readheader); }\r
+                               if (fasta)      {       printFastaSeqData(outFasta, read, readheader);  }\r
+                               if (qual)       {       printQualSeqData(outQual, read, readheader);    }\r
+                               if (flow)       {       printFlowSeqData(outFlow, read, readheader);    }\r
+                       }\r
+                       \r
+                       count++;\r
+        \r
+                       //report progress\r
+                       if((count+1) % 10000 == 0){     m->mothurOut(toString(count+1)); m->mothurOutEndLine();         }\r
+               \r
+                       if (m->control_pressed) { count = 0; break;   }\r
+                       \r
+                       if (count >= header.numReads) { break; }\r
+               }\r
+               \r
+               //report progress\r
+               if (!m->control_pressed) {   if((count) % 10000 != 0){  m->mothurOut(toString(count)); m->mothurOutEndLine();           }  }\r
+               \r
+               in.close();\r
+               \r
+               if (sfftxt) {  outSfftxt.close();       }\r
+               if (fasta)      {  outFasta.close();    }\r
+               if (qual)       {  outQual.close();             }\r
+               if (flow)       {  outFlow.close();             }\r
+               \r
+        if (split > 1) {\r
+            //create new common headers for each file with the correct number of reads\r
+            adjustCommonHeader(header);\r
+            \r
+            //close files and delete ofstreams\r
+            for(int i=0;i<filehandles.size();i++){\r
+                               for(int j=0;j<filehandles[0].size();j++){\r
+                    (filehandles[i][j].begin()->second)->close(); delete (filehandles[i][j].begin()->second);\r
+                    (filehandlesHeaders[i][j].begin()->second)->close(); delete (filehandlesHeaders[i][j].begin()->second);\r
+                }\r
+            }\r
+            \r
+            //cout << "here" << endl;\r
+                       map<string, string>::iterator it;\r
+                       set<string> namesToRemove;\r
+                       for(int i=0;i<filehandles.size();i++){\r
+                               for(int j=0;j<filehandles[0].size();j++){\r
+                    //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << endl;\r
+                                       if (filehandles[i][j].begin()->first != "") {\r
+                                               if (namesToRemove.count(filehandles[i][j].begin()->first) == 0) {\r
+                                                       if(m->isBlank(filehandles[i][j].begin()->first)){\r
+                                //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << " is blank removing" << endl;\r
+                                                               m->mothurRemove(filehandles[i][j].begin()->first);\r
+                                m->mothurRemove(filehandlesHeaders[i][j].begin()->first);\r
+                                                               namesToRemove.insert(filehandles[i][j].begin()->first);\r
+                            }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+            //cout << "here2" << endl;\r
+            //append new header to reads\r
+            for (int i = 0; i < filehandles.size(); i++) {\r
+                for (int j = 0; j < filehandles[i].size(); j++) {\r
+                    m->appendBinaryFiles(filehandles[i][j].begin()->first, filehandlesHeaders[i][j].begin()->first);\r
+                    m->renameFile(filehandlesHeaders[i][j].begin()->first, filehandles[i][j].begin()->first);\r
+                    m->mothurRemove(filehandlesHeaders[i][j].begin()->first);\r
+                    //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << " done appending headers and removing " << filehandlesHeaders[i][j] << endl;\r
+                    if (numSplitReads[i][j] == 0) { m->mothurRemove(filehandles[i][j].begin()->first); }\r
+                }\r
+            }\r
+                       //cout << "here3" << endl;\r
+                       //remove names for outputFileNames, just cleans up the output\r
+                       for(int i = 0; i < outputNames.size(); i++) { \r
+                if (namesToRemove.count(outputNames[i]) != 0) {\r
+                    //cout << "erasing " << i << '\t' << outputNames[i] << endl;\r
+                    outputNames.erase(outputNames.begin()+i);\r
+                    i--;\r
+                } \r
+            }\r
+            //cout << "here4" << endl;\r
+            if(m->isBlank(noMatchFile)){  m->mothurRemove(noMatchFile); }\r
+            else { outputNames.push_back(noMatchFile); outputTypes["sff"].push_back(noMatchFile); }\r
+        }\r
+        \r
+               return count;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "extractSffInfo");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::readCommonHeader(ifstream& in, CommonHeader& header){\r
+       try {\r
+        \r
+               if (!in.eof()) {\r
+\r
+                       //read magic number\r
+                       char buffer[4];\r
+                       in.read(buffer, 4);\r
+                       header.magicNumber = be_int4(*(unsigned int *)(&buffer));\r
+            \r
+                       //read version\r
+                       char buffer9[4];\r
+                       in.read(buffer9, 4);\r
+                       header.version = "";\r
+                       for (int i = 0; i < 4; i++) {  header.version += toString((int)(buffer9[i]));  }\r
+    \r
+                       //read offset\r
+                       char buffer2 [8];\r
+                       in.read(buffer2, 8);\r
+                       header.indexOffset =  be_int8(*(unsigned long long *)(&buffer2));\r
+                       \r
+                       //read index length\r
+                       char buffer3 [4];\r
+                       in.read(buffer3, 4);\r
+                       header.indexLength =  be_int4(*(unsigned int *)(&buffer3));\r
+            \r
+                       //read num reads\r
+                       char buffer4 [4];\r
+                       in.read(buffer4, 4);\r
+                       header.numReads =  be_int4(*(unsigned int *)(&buffer4));\r
+            \r
+            if (m->debug) { m->mothurOut("[DEBUG]: numReads = " + toString(header.numReads) + "\n"); }\r
+                               \r
+                       //read header length\r
+                       char buffer5 [2];\r
+                       in.read(buffer5, 2);\r
+                       header.headerLength =  be_int2(*(unsigned short *)(&buffer5));\r
+                                       \r
+                       //read key length\r
+                       char buffer6 [2];\r
+                       in.read(buffer6, 2);\r
+                       header.keyLength = be_int2(*(unsigned short *)(&buffer6));\r
+                       \r
+                       //read number of flow reads\r
+                       char buffer7 [2];\r
+                       in.read(buffer7, 2);\r
+                       header.numFlowsPerRead =  be_int2(*(unsigned short *)(&buffer7));\r
+                               \r
+                       //read format code\r
+                       char buffer8 [1];\r
+                       in.read(buffer8, 1);\r
+                       header.flogramFormatCode = (int)(buffer8[0]);\r
+                       \r
+                       //read flow chars\r
+                       char* tempBuffer = new char[header.numFlowsPerRead];\r
+                       in.read(&(*tempBuffer), header.numFlowsPerRead); \r
+                       header.flowChars = tempBuffer;\r
+                       if (header.flowChars.length() > header.numFlowsPerRead) { header.flowChars = header.flowChars.substr(0, header.numFlowsPerRead);  }\r
+                       delete[] tempBuffer;\r
+                       \r
+                       //read key\r
+                       char* tempBuffer2 = new char[header.keyLength];\r
+                       in.read(&(*tempBuffer2), header.keyLength);\r
+                       header.keySequence = tempBuffer2;\r
+                       if (header.keySequence.length() > header.keyLength) { header.keySequence = header.keySequence.substr(0, header.keyLength);  }\r
+                       delete[] tempBuffer2;\r
+                       \r
+                       /* Pad to 8 chars */\r
+                       unsigned long long spotInFile = in.tellg();\r
+                       unsigned long long spot = (spotInFile + 7)& ~7;  // ~ inverts\r
+                       in.seekg(spot);\r
+            \r
+        }else{\r
+                       m->mothurOut("Error reading sff common header."); m->mothurOutEndLine();\r
+               }\r
+        \r
+               return 0;\r
+        \r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "readCommonHeader");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::adjustCommonHeader(CommonHeader header){\r
+       try {\r
+        string endian = m->findEdianness();\r
+        char* mybuffer = new char[4];\r
+        ifstream in;\r
+        m->openInputFileBinary(currentFileName, in);\r
+        \r
+        ofstream outNoMatchHeader;\r
+        string tempNoHeader = "tempNoMatchHeader";\r
+        m->openOutputFileBinary(tempNoHeader, outNoMatchHeader);\r
+        \r
+        //magic number\r
+        in.read(mybuffer,4);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+        \r
+        //version\r
+        mybuffer = new char[4];\r
+        in.read(mybuffer,4);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+               (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+        \r
+        //offset\r
+        mybuffer = new char[8];\r
+        in.read(mybuffer,8);\r
+        unsigned long long offset = 0;\r
+        char* thisbuffer = new char[8];\r
+        thisbuffer[0] = (offset >> 56) & 0xFF;\r
+        thisbuffer[1] = (offset >> 48) & 0xFF;\r
+        thisbuffer[2] = (offset >> 40) & 0xFF;\r
+        thisbuffer[3] = (offset >> 32) & 0xFF;\r
+        thisbuffer[4] = (offset >> 24) & 0xFF;\r
+        thisbuffer[5] = (offset >> 16) & 0xFF;\r
+        thisbuffer[6] = (offset >> 8) & 0xFF;\r
+        thisbuffer[7] = offset & 0xFF;\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {\r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(thisbuffer, 8);\r
+            }\r
+        }\r
+        outNoMatchHeader.write(thisbuffer, 8);\r
+        delete[] thisbuffer;\r
+        delete[] mybuffer;\r
+            \r
+                       \r
+        //read index length\r
+               mybuffer = new char[4];\r
+        in.read(mybuffer,4);\r
+        offset = 0;\r
+        char* thisbuffer2 = new char[4];\r
+        thisbuffer2[0] = (offset >> 24) & 0xFF;\r
+        thisbuffer2[1] = (offset >> 16) & 0xFF;\r
+        thisbuffer2[2] = (offset >> 8) & 0xFF;\r
+        thisbuffer2[3] = offset & 0xFF;\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {\r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(thisbuffer2, 4);\r
+            }\r
+        }\r
+        outNoMatchHeader.write(thisbuffer2, 4);\r
+        delete[] thisbuffer2;\r
+        delete[] mybuffer;\r
+               \r
+        //change num reads\r
+        mybuffer = new char[4];\r
+        in.read(mybuffer,4);\r
+        delete[] mybuffer;\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                char* thisbuffer = new char[4];\r
+                if (endian == "BIG_ENDIAN") {\r
+                    thisbuffer[0] = (numSplitReads[i][j] >> 24) & 0xFF;\r
+                    thisbuffer[1] = (numSplitReads[i][j] >> 16) & 0xFF;\r
+                    thisbuffer[2] = (numSplitReads[i][j] >> 8) & 0xFF;\r
+                    thisbuffer[3] = numSplitReads[i][j] & 0xFF;\r
+                }else {\r
+                    thisbuffer[0] = numSplitReads[i][j] & 0xFF;\r
+                    thisbuffer[1] = (numSplitReads[i][j] >> 8) & 0xFF;\r
+                    thisbuffer[2] = (numSplitReads[i][j] >> 16) & 0xFF;\r
+                    thisbuffer[3] = (numSplitReads[i][j] >> 24) & 0xFF;\r
+                 }\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(thisbuffer, 4);\r
+                delete[] thisbuffer;\r
+            }\r
+        }\r
+        char* thisbuffer3 = new char[4];\r
+        if (endian == "BIG_ENDIAN") {\r
+            thisbuffer3[0] = (numNoMatch >> 24) & 0xFF;\r
+            thisbuffer3[1] = (numNoMatch >> 16) & 0xFF;\r
+            thisbuffer3[2] = (numNoMatch >> 8) & 0xFF;\r
+            thisbuffer3[3] = numNoMatch & 0xFF;\r
+        }else {\r
+            thisbuffer3[0] = numNoMatch & 0xFF;\r
+            thisbuffer3[1] = (numNoMatch >> 8) & 0xFF;\r
+            thisbuffer3[2] = (numNoMatch >> 16) & 0xFF;\r
+            thisbuffer3[3] = (numNoMatch >> 24) & 0xFF;\r
+        }\r
+        outNoMatchHeader.write(thisbuffer3, 4);\r
+        delete[] thisbuffer3;\r
+        \r
+        \r
+        //read header length\r
+        mybuffer = new char[2];\r
+        in.read(mybuffer,2);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+            \r
+        //read key length\r
+        mybuffer = new char[2];\r
+        in.read(mybuffer,2);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+                       \r
+        //read number of flow reads\r
+        mybuffer = new char[2];\r
+        in.read(mybuffer,2);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+            \r
+        //read format code\r
+        mybuffer = new char[1];\r
+        in.read(mybuffer,1);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+                       \r
+        //read flow chars\r
+        mybuffer = new char[header.numFlowsPerRead];\r
+        in.read(mybuffer,header.numFlowsPerRead);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+                       \r
+        //read key\r
+        mybuffer = new char[header.keyLength];\r
+        in.read(mybuffer,header.keyLength);\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, in.gcount());\r
+        delete[] mybuffer;\r
+        \r
+                       \r
+        /* Pad to 8 chars */\r
+        unsigned long long spotInFile = in.tellg();\r
+        unsigned long long spot = (spotInFile + 7)& ~7;  // ~ inverts\r
+        in.seekg(spot);\r
+        \r
+        mybuffer = new char[spot-spotInFile];\r
+        for (int i = 0; i < filehandlesHeaders.size(); i++) { \r
+            for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
+                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, spot-spotInFile);\r
+            }\r
+        }\r
+        outNoMatchHeader.write(mybuffer, spot-spotInFile);\r
+        outNoMatchHeader.close();\r
+        delete[] mybuffer;\r
+        in.close();\r
+        \r
+        m->appendBinaryFiles(noMatchFile, tempNoHeader);\r
+        m->renameFile(tempNoHeader, noMatchFile);\r
+        m->mothurRemove(tempNoHeader);\r
+        \r
+               return 0;\r
+        \r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "adjustCommonHeader");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+bool SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads, Header& header){\r
+       try {\r
+        unsigned long long startSpotInFile = in.tellg();\r
+               if (!in.eof()) {\r
+            \r
+            /*****************************************/\r
+            //read header\r
+            \r
+            //read header length\r
+                       char buffer [2];\r
+                       in.read(buffer, 2); \r
+                       header.headerLength = be_int2(*(unsigned short *)(&buffer));\r
+            \r
+                       //read name length\r
+                       char buffer2 [2];\r
+                       in.read(buffer2, 2);\r
+                       header.nameLength = be_int2(*(unsigned short *)(&buffer2));\r
+            \r
+                       //read num bases\r
+                       char buffer3 [4];\r
+                       in.read(buffer3, 4);\r
+                       header.numBases =  be_int4(*(unsigned int *)(&buffer3));\r
+            \r
+                       \r
+                       //read clip qual left\r
+                       char buffer4 [2];\r
+                       in.read(buffer4, 2);\r
+                       header.clipQualLeft =  be_int2(*(unsigned short *)(&buffer4));\r
+                       header.clipQualLeft = 5;\r
+            \r
+                       \r
+                       //read clip qual right\r
+                       char buffer5 [2];\r
+                       in.read(buffer5, 2);\r
+                       header.clipQualRight =  be_int2(*(unsigned short *)(&buffer5));\r
+           \r
+            \r
+                       //read clipAdapterLeft\r
+                       char buffer6 [2];\r
+                       in.read(buffer6, 2);\r
+                       header.clipAdapterLeft = be_int2(*(unsigned short *)(&buffer6));\r
+            \r
+            \r
+                       //read clipAdapterRight\r
+                       char buffer7 [2];\r
+                       in.read(buffer7, 2);\r
+                       header.clipAdapterRight = be_int2(*(unsigned short *)(&buffer7));\r
+            \r
+            \r
+                       //read name\r
+                       char* tempBuffer = new char[header.nameLength];\r
+                       in.read(&(*tempBuffer), header.nameLength);\r
+                       header.name = tempBuffer;\r
+                       if (header.name.length() > header.nameLength) { header.name = header.name.substr(0, header.nameLength);  }\r
+            \r
+                       delete[] tempBuffer;\r
+                       \r
+                       //extract info from name\r
+                       decodeName(header.timestamp, header.region, header.xy, header.name);\r
+                       \r
+                       /* Pad to 8 chars */\r
+                       unsigned long long spotInFile = in.tellg();\r
+                       unsigned long long spot = (spotInFile + 7)& ~7;\r
+                       in.seekg(spot);\r
+\r
+            /*****************************************/\r
+            //sequence read \r
+            \r
+                       //read flowgram\r
+                       read.flowgram.resize(numFlowReads);\r
+                       for (int i = 0; i < numFlowReads; i++) {  \r
+                               char buffer [2];\r
+                               in.read(buffer, 2);\r
+                               read.flowgram[i] = be_int2(*(unsigned short *)(&buffer));\r
+                       }\r
+            \r
+                       //read flowIndex\r
+                       read.flowIndex.resize(header.numBases);\r
+                       for (int i = 0; i < header.numBases; i++) {  \r
+                               char temp[1];\r
+                               in.read(temp, 1);\r
+                               read.flowIndex[i] = be_int1(*(unsigned char *)(&temp));\r
+                       }\r
+       \r
+                       //read bases\r
+                       char* tempBuffer6 = new char[header.numBases];\r
+                       in.read(&(*tempBuffer6), header.numBases);\r
+                       read.bases = tempBuffer6;\r
+                       if (read.bases.length() > header.numBases) { read.bases = read.bases.substr(0, header.numBases);  }\r
+                       delete[] tempBuffer6;\r
+\r
+                       //read qual scores\r
+                       read.qualScores.resize(header.numBases);\r
+                       for (int i = 0; i < header.numBases; i++) {  \r
+                               char temp[1];\r
+                               in.read(temp, 1);\r
+                               read.qualScores[i] = be_int1(*(unsigned char *)(&temp));\r
+                       }\r
+       \r
+                       /* Pad to 8 chars */\r
+                       spotInFile = in.tellg();\r
+                       spot = (spotInFile + 7)& ~7;\r
+                       in.seekg(spot);\r
+            \r
+            if (split > 1) { \r
+               \r
+                int barcodeIndex, primerIndex;\r
+                int trashCodeLength = findGroup(header, read, barcodeIndex, primerIndex);\r
+                                \r
+                char * mybuffer;\r
+                mybuffer = new char [spot-startSpotInFile];\r
+                \r
+                ifstream in2;\r
+                m->openInputFileBinary(currentFileName, in2);\r
+                in2.seekg(startSpotInFile);\r
+                in2.read(mybuffer,spot-startSpotInFile);\r
+                \r
+                \r
+                if(trashCodeLength == 0){\r
+                    (*(filehandles[barcodeIndex][primerIndex].begin()->second)).write(mybuffer, in2.gcount());\r
+                    numSplitReads[barcodeIndex][primerIndex]++;\r
+                               }\r
+                               else{\r
+                                       ofstream out;\r
+                    m->openOutputFileBinaryAppend(noMatchFile, out);\r
+                    out.write(mybuffer, in2.gcount());\r
+                    out.close();\r
+                    numNoMatch++;\r
+                               }\r
+                               delete[] mybuffer;\r
+                in2.close();\r
+        }    \r
+            \r
+               }else{\r
+                       m->mothurOut("Error reading."); m->mothurOutEndLine();\r
+               }\r
+        \r
+        if (in.eof()) {  return true; }\r
+        \r
+               return false;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "readSeqData");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::findGroup(Header header, seqRead read, int& barcode, int& primer) {\r
+       try {\r
+        //find group read belongs to\r
+        TrimOligos trimOligos(pdiffs, bdiffs, ldiffs, sdiffs, primers, barcodes, revPrimer, linker, spacer);\r
+        \r
+        int success = 1;\r
+        string trashCode = "";\r
+        int currentSeqsDiffs = 0;\r
+        \r
+        string seq = read.bases;\r
+        \r
+        if (trim) {\r
+            if(header.clipQualRight < header.clipQualLeft){\r
+                if (header.clipQualRight == 0) { //don't trim right\r
+                    seq = seq.substr(header.clipQualLeft-1);\r
+                }else {\r
+                    seq = "NNNN";\r
+                }\r
+            }\r
+            else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){\r
+                seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft));\r
+            }\r
+            else {\r
+                seq = seq.substr(header.clipQualLeft-1);\r
+            }\r
+        }else{\r
+            //if you wanted the sfftxt then you already converted the bases to the right case\r
+            if (!sfftxt) {\r
+                int endValue = header.clipQualRight;\r
+                //make the bases you want to clip lowercase and the bases you want to keep upper case\r
+                if(endValue == 0){     endValue = seq.length();        }\r
+                for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]);  }\r
+                for (int i = (header.clipQualLeft-1); i < (endValue-1); i++)  {   seq[i] = toupper(seq[i]);  }\r
+                for (int i = (endValue-1); i < seq.length(); i++) {   seq[i] = tolower(seq[i]);  }\r
+            }\r
+        }\r
+        \r
+        Sequence currSeq(header.name, seq);\r
+        QualityScores currQual;\r
+        \r
+        if(numLinkers != 0){\r
+            success = trimOligos.stripLinker(currSeq, currQual);\r
+            if(success > ldiffs)               {       trashCode += 'k';       }\r
+            else{ currentSeqsDiffs += success;  }\r
+            \r
+        }\r
+        \r
+        if(barcodes.size() != 0){\r
+            success = trimOligos.stripBarcode(currSeq, currQual, barcode);\r
+            if(success > bdiffs)               {       trashCode += 'b';       }\r
+            else{ currentSeqsDiffs += success;  }\r
+        }\r
+        \r
+        if(numSpacers != 0){\r
+            success = trimOligos.stripSpacer(currSeq, currQual);\r
+            if(success > sdiffs)               {       trashCode += 's';       }\r
+            else{ currentSeqsDiffs += success;  }\r
+            \r
+        }\r
+        \r
+        if(numFPrimers != 0){\r
+            success = trimOligos.stripForward(currSeq, currQual, primer, true);\r
+            if(success > pdiffs)               {       trashCode += 'f';       }\r
+            else{ currentSeqsDiffs += success;  }\r
+        }\r
+        \r
+        if (currentSeqsDiffs > tdiffs) {       trashCode += 't';   }\r
+        \r
+        if(revPrimer.size() != 0){\r
+            success = trimOligos.stripReverse(currSeq, currQual);\r
+            if(!success)                               {       trashCode += 'r';       }\r
+        }\r
+\r
+        \r
+        return trashCode.length();\r
+    }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "findGroup");\r
+               exit(1);\r
+       }\r
+}     \r
+//**********************************************************************************************************************\r
+int SffInfoCommand::decodeName(string& timestamp, string& region, string& xy, string name) {\r
+       try {\r
+               \r
+               if (name.length() >= 6) {\r
+                       string time = name.substr(0, 6);\r
+                       unsigned int timeNum = m->fromBase36(time);\r
+                       \r
+                       int q1 = timeNum / 60;\r
+                       int sec = timeNum - 60 * q1;\r
+                       int q2 = q1 / 60;\r
+                       int minute = q1 - 60 * q2;\r
+                       int q3 = q2 / 24;\r
+                       int hr = q2 - 24 * q3;\r
+                       int q4 = q3 / 32;\r
+                       int day = q3 - 32 * q4;\r
+                       int q5 = q4 / 13;\r
+                       int mon = q4 - 13 * q5;\r
+                       int year = 2000 + q5;\r
+               \r
+                       timestamp = toString(year) + "_" + toString(mon) + "_" + toString(day) + "_" + toString(hr) + "_" + toString(minute) + "_" + toString(sec);\r
+               }\r
+               \r
+               if (name.length() >= 9) {\r
+                       region = name.substr(7, 2);\r
+               \r
+                       string xyNum = name.substr(9);\r
+                       unsigned int myXy = m->fromBase36(xyNum);\r
+                       int x = myXy >> 12;\r
+                       int y = myXy & 4095;\r
+               \r
+                       xy = toString(x) + "_" + toString(y);\r
+               }\r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "decodeName");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::printCommonHeader(ofstream& out, CommonHeader& header) {\r
+       try {\r
+       \r
+               out << "Common Header:\nMagic Number: " << header.magicNumber << endl;\r
+               out << "Version: " << header.version << endl;\r
+               out << "Index Offset: " << header.indexOffset << endl;\r
+               out << "Index Length: " << header.indexLength << endl;\r
+               out << "Number of Reads: " << header.numReads << endl;\r
+               out << "Header Length: " << header.headerLength << endl;\r
+               out << "Key Length: " << header.keyLength << endl;\r
+               out << "Number of Flows: " << header.numFlowsPerRead << endl;\r
+               out << "Format Code: " << header.flogramFormatCode << endl;\r
+               out << "Flow Chars: " << header.flowChars << endl;\r
+               out << "Key Sequence: " << header.keySequence << endl << endl;\r
+                       \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "printCommonHeader");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::printHeader(ofstream& out, Header& header) {\r
+       try {\r
+               \r
+               out << ">" << header.name << endl;\r
+               out << "Run Prefix: " << header.timestamp << endl;\r
+               out << "Region #:  " << header.region << endl;\r
+               out << "XY Location: " << header.xy << endl << endl;\r
+               \r
+               out << "Run Name:  " << endl;\r
+               out << "Analysis Name:  " << endl;\r
+               out << "Full Path: " << endl << endl;\r
+               \r
+               out << "Read Header Len: " << header.headerLength << endl;\r
+               out << "Name Length: " << header.nameLength << endl;\r
+               out << "# of Bases: " << header.numBases << endl;\r
+               out << "Clip Qual Left: " << header.clipQualLeft << endl;\r
+               out << "Clip Qual Right: " << header.clipQualRight << endl;\r
+               out << "Clip Adap Left: " << header.clipAdapterLeft << endl;\r
+               out << "Clip Adap Right: " << header.clipAdapterRight << endl << endl;\r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "printHeader");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+bool SffInfoCommand::sanityCheck(Header& header, seqRead& read) {\r
+       try {\r
+        bool okay = true;\r
+        string message = "[WARNING]: Your sff file may be corrupted! Sequence: " + header.name + "\n";\r
+        \r
+        if (header.clipQualLeft > read.bases.length()) {\r
+            okay = false; message += "Clip Qual Left = " + toString(header.clipQualLeft) + ", but we only read " + toString(read.bases.length()) + " bases.\n";\r
+        }\r
+        if (header.clipQualRight > read.bases.length()) {\r
+            okay = false; message += "Clip Qual Right = " + toString(header.clipQualRight) + ", but we only read " + toString(read.bases.length()) + " bases.\n";\r
+        }\r
+        if (header.clipQualLeft > read.qualScores.size()) {\r
+            okay = false; message += "Clip Qual Left = " + toString(header.clipQualLeft) + ", but we only read " + toString(read.qualScores.size()) + " quality scores.\n";\r
+        }\r
+        if (header.clipQualRight > read.qualScores.size()) {\r
+            okay = false; message += "Clip Qual Right = " + toString(header.clipQualRight) + ", but we only read " + toString(read.qualScores.size()) + " quality scores.\n";\r
+        }\r
+        \r
+        if (okay == false) {\r
+            m->mothurOut(message); m->mothurOutEndLine();\r
+        }\r
+        \r
+               return okay;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "sanityCheck");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::printSffTxtSeqData(ofstream& out, seqRead& read, Header& header) {\r
+       try {\r
+               out << "Flowgram: ";\r
+               for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << (read.flowgram[i]/(float)100) << '\t';  }\r
+               \r
+               out << endl <<  "Flow Indexes: ";\r
+               int sum = 0;\r
+               for (int i = 0; i < read.flowIndex.size(); i++) {  sum +=  read.flowIndex[i];  out << sum << '\t'; }\r
+               \r
+               //make the bases you want to clip lowercase and the bases you want to keep upper case\r
+        int endValue = header.clipQualRight;\r
+               if(endValue == 0){      endValue = read.bases.length(); }\r
+               for (int i = 0; i < (header.clipQualLeft-1); i++) { read.bases[i] = tolower(read.bases[i]); }\r
+               for (int i = (header.clipQualLeft-1); i < (endValue-1); i++) {   read.bases[i] = toupper(read.bases[i]);  }\r
+               for (int i = (endValue-1); i < read.bases.length(); i++) {   read.bases[i] = tolower(read.bases[i]);  }\r
+               \r
+               out << endl <<  "Bases: " << read.bases << endl << "Quality Scores: ";\r
+               for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }\r
+       \r
+               \r
+               out << endl << endl;\r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "printSffTxtSeqData");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::printFastaSeqData(ofstream& out, seqRead& read, Header& header) {\r
+       try {\r
+               string seq = read.bases;\r
+               \r
+        if (trim) {\r
+                       if(header.clipQualRight < header.clipQualLeft){\r
+                               if (header.clipQualRight == 0) { //don't trim right\r
+                    seq = seq.substr(header.clipQualLeft-1);\r
+                }else {\r
+                    seq = "NNNN";\r
+                }\r
+                       }\r
+                       else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){\r
+                               seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft));\r
+                       }\r
+                       else {\r
+                               seq = seq.substr(header.clipQualLeft-1);\r
+                       }\r
+               }else{\r
+                       //if you wanted the sfftxt then you already converted the bases to the right case\r
+                       if (!sfftxt) {\r
+                int endValue = header.clipQualRight;\r
+                               //make the bases you want to clip lowercase and the bases you want to keep upper case\r
+                               if(endValue == 0){      endValue = seq.length();        }\r
+                               for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]);  }\r
+                               for (int i = (header.clipQualLeft-1); i < (endValue-1); i++)  {   seq[i] = toupper(seq[i]);  }\r
+                               for (int i = (endValue-1); i < seq.length(); i++) {   seq[i] = tolower(seq[i]);  }\r
+                       }\r
+               }\r
+               \r
+               out << ">" << header.name  << " xy=" << header.xy << endl;\r
+               out << seq << endl;\r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "printFastaSeqData");\r
+               exit(1);\r
+       }\r
+}\r
+\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::printQualSeqData(ofstream& out, seqRead& read, Header& header) {\r
+       try {\r
+               \r
+               if (trim) {\r
+                       if(header.clipQualRight < header.clipQualLeft){\r
+                if (header.clipQualRight == 0) { //don't trim right\r
+                    out << ">" << header.name << " xy=" << header.xy << " length=" << (read.qualScores.size()-header.clipQualLeft) << endl;\r
+                    for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';      }       \r
+                }else {\r
+                    out << ">" << header.name << " xy=" << header.xy << endl;\r
+                    out << "0\t0\t0\t0";\r
+                }\r
+                       }\r
+                       else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){\r
+                               out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;\r
+                               for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) {   out << read.qualScores[i] << '\t'; }\r
+                       }\r
+                       else{\r
+                               out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;\r
+                               for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';   }                       \r
+                       }\r
+               }else{\r
+                       out << ">" << header.name << " xy=" << header.xy << " length=" << read.qualScores.size() << endl;\r
+                       for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }\r
+               }\r
+               \r
+               out << endl;\r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "printQualSeqData");\r
+               exit(1);\r
+       }\r
+}\r
+\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::printFlowSeqData(ofstream& out, seqRead& read, Header& header) {\r
+       try {\r
+        \r
+        int endValue = header.clipQualRight;\r
+        if (header.clipQualRight == 0) {\r
+            endValue = read.flowIndex.size();\r
+            if (m->debug) { m->mothurOut("[DEBUG]: " + header.name + " has clipQualRight=0.\n"); }\r
+        }\r
+        if(endValue > header.clipQualLeft){\r
+            \r
+            int rightIndex = 0;\r
+            for (int i = 0; i < endValue; i++) {  rightIndex +=  read.flowIndex[i];     }\r
+            \r
+            out << header.name << ' ' << rightIndex;\r
+            for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << ' ' << (read.flowgram[i]/(float)100);  }\r
+            out << endl;\r
+        }\r
+               \r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "printFlowSeqData");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::readAccnosFile(string filename) {\r
+       try {\r
+               //remove old names\r
+               seqNames.clear();\r
+               \r
+               ifstream in;\r
+               m->openInputFile(filename, in);\r
+               string name;\r
+               \r
+               while(!in.eof()){\r
+                       in >> name; m->gobble(in);\r
+                                               \r
+                       seqNames.insert(name);\r
+                       \r
+                       if (m->control_pressed) { seqNames.clear(); break; }\r
+               }\r
+               in.close();             \r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "readAccnosFile");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::parseSffTxt() {\r
+       try {\r
+               \r
+               ifstream inSFF;\r
+               m->openInputFile(sfftxtFilename, inSFF);\r
+               \r
+               if (outputDir == "") {  outputDir += m->hasPath(sfftxtFilename); }\r
+               \r
+               //output file names\r
+               ofstream outFasta, outQual, outFlow;\r
+               string outFastaFileName, outQualFileName;\r
+               string fileRoot = m->getRootName(m->getSimpleName(sfftxtFilename));\r
+               if (fileRoot.length() > 0) {\r
+                       //rip off last .\r
+                       fileRoot = fileRoot.substr(0, fileRoot.length()-1);\r
+                       fileRoot = m->getRootName(fileRoot);\r
+               }\r
+               \r
+        map<string, string> variables; \r
+               variables["[filename]"] = fileRoot;\r
+               string sfftxtFileName = getOutputFileName("sfftxt",variables);\r
+               string outFlowFileName = getOutputFileName("flow",variables);\r
+               if (!trim) { variables["[tag]"] = "raw"; }\r
+               outFastaFileName = getOutputFileName("fasta",variables);\r
+        outQualFileName = getOutputFileName("qfile",variables);\r
+               \r
+               if (fasta)      { m->openOutputFile(outFastaFileName, outFasta);        outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); }\r
+               if (qual)       { m->openOutputFile(outQualFileName, outQual);          outputNames.push_back(outQualFileName); outputTypes["qfile"].push_back(outQualFileName);  }\r
+               if (flow)       { m->openOutputFile(outFlowFileName, outFlow);          outputNames.push_back(outFlowFileName);  outFlow.setf(ios::fixed, ios::floatfield); outFlow.setf(ios::showpoint); outputTypes["flow"].push_back(outFlowFileName);  }\r
+               \r
+               //read common header\r
+               string commonHeader = m->getline(inSFF);\r
+               string magicNumber = m->getline(inSFF); \r
+               string version = m->getline(inSFF);\r
+               string indexOffset = m->getline(inSFF);\r
+               string indexLength = m->getline(inSFF);\r
+               int numReads = parseHeaderLineToInt(inSFF);\r
+               string headerLength = m->getline(inSFF);\r
+               string keyLength = m->getline(inSFF);\r
+               int numFlows = parseHeaderLineToInt(inSFF);\r
+               string flowgramCode = m->getline(inSFF);\r
+               string flowChars = m->getline(inSFF);\r
+               string keySequence = m->getline(inSFF);\r
+               m->gobble(inSFF);\r
+               \r
+               string seqName;\r
+               \r
+               if (flow)       {       outFlow << numFlows << endl;    }\r
+               \r
+               for(int i=0;i<numReads;i++){\r
+                       \r
+                       //sanity check\r
+                       if (inSFF.eof()) { m->mothurOut("[ERROR]: Expected " + toString(numReads) + " but reached end of file at " + toString(i+1) + "."); m->mothurOutEndLine(); break; }\r
+                       \r
+                       Header header;\r
+                       \r
+                       //parse read header\r
+                       inSFF >> seqName;\r
+                       seqName = seqName.substr(1);\r
+                       m->gobble(inSFF);\r
+                       header.name = seqName;\r
+                       \r
+                       string runPrefix = parseHeaderLineToString(inSFF);              header.timestamp = runPrefix;\r
+                       string regionNumber = parseHeaderLineToString(inSFF);   header.region = regionNumber;\r
+                       string xyLocation = parseHeaderLineToString(inSFF);             header.xy = xyLocation;\r
+                       m->gobble(inSFF);\r
+                               \r
+                       string runName = parseHeaderLineToString(inSFF);\r
+                       string analysisName = parseHeaderLineToString(inSFF);\r
+                       string fullPath = parseHeaderLineToString(inSFF);\r
+                       m->gobble(inSFF);\r
+                       \r
+                       string readHeaderLen = parseHeaderLineToString(inSFF);  convert(readHeaderLen, header.headerLength);\r
+                       string nameLength = parseHeaderLineToString(inSFF);             convert(nameLength, header.nameLength);\r
+                       int numBases = parseHeaderLineToInt(inSFF);                             header.numBases = numBases;\r
+                       string clipQualLeft = parseHeaderLineToString(inSFF);   convert(clipQualLeft, header.clipQualLeft);\r
+                       int clipQualRight = parseHeaderLineToInt(inSFF);                header.clipQualRight = clipQualRight;\r
+                       string clipAdapLeft = parseHeaderLineToString(inSFF);   convert(clipAdapLeft, header.clipAdapterLeft);\r
+                       string clipAdapRight = parseHeaderLineToString(inSFF);  convert(clipAdapRight, header.clipAdapterRight);\r
+                       m->gobble(inSFF);\r
+                               \r
+                       seqRead read;\r
+                       \r
+                       //parse read\r
+                       vector<unsigned short> flowVector = parseHeaderLineToFloatVector(inSFF, numFlows);      read.flowgram = flowVector;\r
+                       vector<unsigned int> flowIndices = parseHeaderLineToIntVector(inSFF, numBases); \r
+                       \r
+                       //adjust for print\r
+                       vector<unsigned int> flowIndicesAdjusted; flowIndicesAdjusted.push_back(flowIndices[0]);\r
+                       for (int j = 1; j < flowIndices.size(); j++) {   flowIndicesAdjusted.push_back(flowIndices[j] - flowIndices[j-1]);   }\r
+                       read.flowIndex = flowIndicesAdjusted;\r
+                       \r
+                       string bases = parseHeaderLineToString(inSFF);                                                                          read.bases = bases;\r
+                       vector<unsigned int> qualityScores = parseHeaderLineToIntVector(inSFF, numBases);       read.qualScores = qualityScores;\r
+                       m->gobble(inSFF);\r
+                                       \r
+                       //if you have provided an accosfile and this seq is not in it, then dont print\r
+                       bool print = true;\r
+                       if (seqNames.size() != 0) {   if (seqNames.count(header.name) == 0) { print = false; }  }\r
+                       \r
+                       //print \r
+                       if (print) {\r
+                               if (fasta)      {       printFastaSeqData(outFasta, read, header);      }\r
+                               if (qual)       {       printQualSeqData(outQual, read, header);        }\r
+                               if (flow)       {       printFlowSeqData(outFlow, read, header);        }\r
+                       }\r
+                       \r
+                       //report progress\r
+                       if((i+1) % 10000 == 0){ m->mothurOut(toString(i+1)); m->mothurOutEndLine();             }\r
+                       \r
+                       if (m->control_pressed) {  break;  }\r
+               }\r
+               \r
+               //report progress\r
+               if (!m->control_pressed) {   if((numReads) % 10000 != 0){       m->mothurOut(toString(numReads)); m->mothurOutEndLine();                }  }\r
+               \r
+               inSFF.close();\r
+               \r
+               if (fasta)      {  outFasta.close();    }\r
+               if (qual)       {  outQual.close();             }\r
+               if (flow)       {  outFlow.close();             }\r
+               \r
+               return 0;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "parseSffTxt");\r
+               exit(1);\r
+       }\r
+}\r
+//**********************************************************************************************************************\r
+\r
+int SffInfoCommand::parseHeaderLineToInt(ifstream& file){\r
+       try {\r
+               int number;\r
+               \r
+               while (!file.eof())     {\r
+                       \r
+                       char c = file.get(); \r
+                       if (c == ':'){\r
+                               file >> number;\r
+                               break;\r
+                       }\r
+                       \r
+               }\r
+               m->gobble(file);\r
+               return number;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToInt");\r
+               exit(1);\r
+       }\r
+       \r
+}\r
+\r
+//**********************************************************************************************************************\r
+\r
+string SffInfoCommand::parseHeaderLineToString(ifstream& file){\r
+       try {\r
+               string text;\r
+               \r
+               while (!file.eof())     {\r
+                       char c = file.get(); \r
+                       \r
+                       if (c == ':'){\r
+                               //m->gobble(file);\r
+                               //text = m->getline(file);      \r
+                               file >> text;\r
+                               break;\r
+                       }\r
+               }\r
+               m->gobble(file);\r
+               \r
+               return text;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToString");\r
+               exit(1);\r
+       }\r
+}\r
+\r
+//**********************************************************************************************************************\r
+\r
+vector<unsigned short> SffInfoCommand::parseHeaderLineToFloatVector(ifstream& file, int length){\r
+       try {\r
+               vector<unsigned short> floatVector(length);\r
+               \r
+               while (!file.eof())     {\r
+                       char c = file.get(); \r
+                       if (c == ':'){\r
+                               float temp;\r
+                               for(int i=0;i<length;i++){\r
+                                       file >> temp;\r
+                                       floatVector[i] = temp * 100;\r
+                               }\r
+                               break;\r
+                       }\r
+               }\r
+               m->gobble(file);        \r
+               return floatVector;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToFloatVector");\r
+               exit(1);\r
+       }\r
+}\r
+\r
+//**********************************************************************************************************************\r
+\r
+vector<unsigned int> SffInfoCommand::parseHeaderLineToIntVector(ifstream& file, int length){\r
+       try {\r
+               vector<unsigned int> intVector(length);\r
+               \r
+               while (!file.eof())     {\r
+                       char c = file.get(); \r
+                       if (c == ':'){\r
+                               for(int i=0;i<length;i++){\r
+                                       file >> intVector[i];\r
+                               }\r
+                               break;\r
+                       }\r
+               }\r
+               m->gobble(file);        \r
+               return intVector;\r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "parseHeaderLineToIntVector");\r
+               exit(1);\r
+       }\r
+}\r
+//***************************************************************************************************************\r
+\r
+bool SffInfoCommand::readOligos(string oligoFile){\r
+       try {\r
+        filehandles.clear();\r
+        numSplitReads.clear();\r
+        filehandlesHeaders.clear();\r
+        \r
+               ifstream inOligos;\r
+               m->openInputFile(oligoFile, inOligos);\r
+               \r
+               string type, oligo, group;\r
+        \r
+               int indexPrimer = 0;\r
+               int indexBarcode = 0;\r
+               \r
+               while(!inOligos.eof()){\r
+            \r
+                       inOligos >> type; \r
+            \r
+                       if(type[0] == '#'){\r
+                               while (!inOligos.eof()) {       char c = inOligos.get();  if (c == 10 || c == 13){      break;  }       } // get rest of line if there's any crap there\r
+                               m->gobble(inOligos);\r
+                       }\r
+                       else{\r
+                               m->gobble(inOligos);\r
+                               //make type case insensitive\r
+                               for(int i=0;i<type.length();i++){       type[i] = toupper(type[i]);  }\r
+                               \r
+                               inOligos >> oligo;\r
+                               \r
+                               for(int i=0;i<oligo.length();i++){\r
+                                       oligo[i] = toupper(oligo[i]);\r
+                                       if(oligo[i] == 'U')     {       oligo[i] = 'T'; }\r
+                               }\r
+                               \r
+                               if(type == "FORWARD"){\r
+                                       group = "";\r
+                                       \r
+                                       // get rest of line in case there is a primer name\r
+                                       while (!inOligos.eof()) {       \r
+                                               char c = inOligos.get(); \r
+                                               if (c == 10 || c == 13 || c == -1){     break;  }\r
+                                               else if (c == 32 || c == 9){;} //space or tab\r
+                                               else {  group += c;  }\r
+                                       } \r
+                                       \r
+                                       //check for repeat barcodes\r
+                                       map<string, int>::iterator itPrime = primers.find(oligo);\r
+                                       if (itPrime != primers.end()) { m->mothurOut("primer " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }\r
+                                       \r
+                                       primers[oligo]=indexPrimer; indexPrimer++;              \r
+                                       primerNameVector.push_back(group);\r
+                               }else if(type == "REVERSE"){\r
+                                       //Sequence oligoRC("reverse", oligo);\r
+                                       //oligoRC.reverseComplement();\r
+                    string oligoRC = reverseOligo(oligo);\r
+                                       revPrimer.push_back(oligoRC);\r
+                               }\r
+                               else if(type == "BARCODE"){\r
+                                       inOligos >> group;\r
+                                       \r
+                                       //check for repeat barcodes\r
+                                       map<string, int>::iterator itBar = barcodes.find(oligo);\r
+                                       if (itBar != barcodes.end()) { m->mothurOut("barcode " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }\r
+                    \r
+                                       barcodes[oligo]=indexBarcode; indexBarcode++;\r
+                                       barcodeNameVector.push_back(group);\r
+                               }else if(type == "LINKER"){\r
+                                       linker.push_back(oligo);\r
+                               }else if(type == "SPACER"){\r
+                                       spacer.push_back(oligo);\r
+                               }\r
+                               else{   m->mothurOut("[WARNING]: " + type + " is not recognized as a valid type. Choices are forward, reverse, and barcode. Ignoring " + oligo + "."); m->mothurOutEndLine(); }\r
+                       }\r
+                       m->gobble(inOligos);\r
+               }       \r
+               inOligos.close();\r
+               \r
+               if(barcodeNameVector.size() == 0 && primerNameVector[0] == ""){ split = 1;      }\r
+               \r
+               //add in potential combos\r
+               if(barcodeNameVector.size() == 0){\r
+                       barcodes[""] = 0;\r
+                       barcodeNameVector.push_back("");                        \r
+               }\r
+               \r
+               if(primerNameVector.size() == 0){\r
+                       primers[""] = 0;\r
+                       primerNameVector.push_back("");                 \r
+               }\r
+               \r
+               filehandles.resize(barcodeNameVector.size());\r
+        for (int i = 0; i < filehandles.size(); i++) {\r
+            for (int j = 0; j < primerNameVector.size(); j++) {\r
+                ofstream* temp;\r
+                map<string, ofstream*> myMap; myMap[""] = temp;\r
+                filehandles[i].push_back(myMap);\r
+            }\r
+        }\r
+                       \r
+               if(split > 1){\r
+                       set<string> uniqueNames; //used to cleanup outputFileNames\r
+                       for(map<string, int>::iterator itBar = barcodes.begin();itBar != barcodes.end();itBar++){\r
+                               for(map<string, int>::iterator itPrimer = primers.begin();itPrimer != primers.end(); itPrimer++){\r
+                                       \r
+                                       string primerName = primerNameVector[itPrimer->second];\r
+                                       string barcodeName = barcodeNameVector[itBar->second];\r
+                                       \r
+                                       string comboGroupName = "";\r
+                                       string fastaFileName = "";\r
+                                       string qualFileName = "";\r
+                                       string nameFileName = "";\r
+                                       \r
+                                       if(primerName == ""){\r
+                                               comboGroupName = barcodeNameVector[itBar->second];\r
+                                       }\r
+                                       else{\r
+                                               if(barcodeName == ""){\r
+                                                       comboGroupName = primerNameVector[itPrimer->second];\r
+                                               }\r
+                                               else{\r
+                                                       comboGroupName = barcodeNameVector[itBar->second] + "." + primerNameVector[itPrimer->second];\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       ofstream* temp = new ofstream;\r
+                    map<string, string> variables; \r
+                    variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
+                    variables["[group]"] = comboGroupName;\r
+                                       string thisFilename = getOutputFileName("sff",variables);\r
+                                       if (uniqueNames.count(thisFilename) == 0) {\r
+                                               outputNames.push_back(thisFilename);\r
+                                               outputTypes["sff"].push_back(thisFilename);\r
+                                               uniqueNames.insert(thisFilename);\r
+                                       }\r
+                                       \r
+                    map<string, ofstream*> myMap; myMap[thisFilename] = temp;\r
+                    m->openOutputFileBinary(thisFilename, *(temp));\r
+                                       filehandles[itBar->second][itPrimer->second] = myMap;\r
+                    map<string, ofstream*>::iterator itOfstream = filehandles[itBar->second][itPrimer->second].find("");\r
+                    if (itOfstream != filehandles[itBar->second][itPrimer->second].end()) { filehandles[itBar->second][itPrimer->second].erase(itOfstream); } //remove blank entry so we dont mess with .begin() above. code above assumes only 1 file name in the map\r
+                               }\r
+                       }\r
+               }\r
+               numFPrimers = primers.size();\r
+        numLinkers = linker.size();\r
+        numSpacers = spacer.size();\r
+        map<string, string> variables; \r
+        variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
+        variables["[group]"] = "scrap";\r
+               noMatchFile = getOutputFileName("sff",variables);\r
+        m->mothurRemove(noMatchFile);\r
+        numNoMatch = 0;\r
+        \r
+               bool allBlank = true;\r
+               for (int i = 0; i < barcodeNameVector.size(); i++) {\r
+                       if (barcodeNameVector[i] != "") {\r
+                               allBlank = false;\r
+                               break;\r
+                       }\r
+               }\r
+               for (int i = 0; i < primerNameVector.size(); i++) {\r
+                       if (primerNameVector[i] != "") {\r
+                               allBlank = false;\r
+                               break;\r
+                       }\r
+               }\r
+               \r
+        filehandlesHeaders.resize(filehandles.size());\r
+        numSplitReads.resize(filehandles.size());\r
+        for (int i = 0; i < filehandles.size(); i++) { \r
+            numSplitReads[i].resize(filehandles[i].size(), 0); \r
+            for (int j = 0; j < filehandles[i].size(); j++) {\r
+                ofstream* temp = new ofstream;\r
+                map<string, ofstream* > myMap;\r
+                string thisHeader = (filehandles[i][j].begin())->first+"headers";\r
+                myMap[thisHeader] = temp;\r
+                m->openOutputFileBinary(thisHeader, *(temp));\r
+                filehandlesHeaders[i].push_back(myMap);\r
+            }\r
+        }\r
+        \r
+               if (allBlank) {\r
+                       m->mothurOut("[WARNING]: your oligos file does not contain any group names.  mothur will not create a split the sff file."); m->mothurOutEndLine();\r
+                       split = 1;\r
+                       return false;\r
+               }\r
+               \r
+               return true;\r
+               \r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "readOligos");\r
+               exit(1);\r
+       }\r
+}\r
+//********************************************************************/\r
+string SffInfoCommand::reverseOligo(string oligo){\r
+       try {\r
+        string reverse = "";\r
+        \r
+        for(int i=oligo.length()-1;i>=0;i--){\r
+            \r
+            if(oligo[i] == 'A')                {       reverse += 'T'; }\r
+            else if(oligo[i] == 'T'){  reverse += 'A'; }\r
+            else if(oligo[i] == 'U'){  reverse += 'A'; }\r
+            \r
+            else if(oligo[i] == 'G'){  reverse += 'C'; }\r
+            else if(oligo[i] == 'C'){  reverse += 'G'; }\r
+            \r
+            else if(oligo[i] == 'R'){  reverse += 'Y'; }\r
+            else if(oligo[i] == 'Y'){  reverse += 'R'; }\r
+            \r
+            else if(oligo[i] == 'M'){  reverse += 'K'; }\r
+            else if(oligo[i] == 'K'){  reverse += 'M'; }\r
+            \r
+            else if(oligo[i] == 'W'){  reverse += 'W'; }\r
+            else if(oligo[i] == 'S'){  reverse += 'S'; }\r
+            \r
+            else if(oligo[i] == 'B'){  reverse += 'V'; }\r
+            else if(oligo[i] == 'V'){  reverse += 'B'; }\r
+            \r
+            else if(oligo[i] == 'D'){  reverse += 'H'; }\r
+            else if(oligo[i] == 'H'){  reverse += 'D'; }\r
+            \r
+            else                                               {       reverse += 'N'; }\r
+        }\r
+        \r
+        \r
+        return reverse;\r
+    }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "reverseOligo");\r
+               exit(1);\r
+       }\r
+}\r
+\r
+//**********************************************************************************************************************\r
+\r
+\r
+                               \r
+                               \r
index 5ec6e72239d0772548ce10f584ebccb435230d25..541c8bad0b262af72b7637629806643bf6991b78 100644 (file)
@@ -82,19 +82,20 @@ private:
        string sffFilename, sfftxtFilename, outputDir, accnosName, currentFileName, oligosfile, noMatchFile;
        vector<string> filenames, outputNames, accnosFileNames, oligosFileNames;
        bool abort, fasta, qual, trim, flow, sfftxt, hasAccnos, hasOligos;
-       int mycount, split, numFPrimers, numLinkers, numSpacers, pdiffs, bdiffs, ldiffs, sdiffs, tdiffs;
+       int mycount, split, numFPrimers, numLinkers, numSpacers, pdiffs, bdiffs, ldiffs, sdiffs, tdiffs, numNoMatch;
        set<string> seqNames;
     map<string, int> barcodes;
     map<string, int> primers;
     vector<string> linker, spacer, primerNameVector, barcodeNameVector, revPrimer;
     vector<vector<int> > numSplitReads;
-    vector<vector<string> > filehandles, filehandlesHeaders;
+    vector<vector<map<string, ofstream*> > > filehandles;
+    vector<vector<map<string, ofstream*> > > filehandlesHeaders;
     
        //extract sff file functions
        int extractSffInfo(string, string, string);
        int readCommonHeader(ifstream&, CommonHeader&);
-       //int readHeader(ifstream&, Header&);
-       int readSeqData(ifstream&, seqRead&, int, Header&);
+       int readHeader(ifstream&, Header&);
+       bool readSeqData(ifstream&, seqRead&, int, Header&);
        int decodeName(string&, string&, string&, string);
     bool readOligos(string oligosFile);
        
diff --git a/sracommand.cpp b/sracommand.cpp
new file mode 100644 (file)
index 0000000..c291ddd
--- /dev/null
@@ -0,0 +1,175 @@
+//
+//  sracommand.cpp
+//  Mothur
+//
+//  Created by SarahsWork on 10/28/13.
+//  Copyright (c) 2013 Schloss Lab. All rights reserved.
+//
+
+#include "sracommand.h"
+
+//**********************************************************************************************************************
+vector<string> SRACommand::setParameters(){
+       try {
+        CommandParameter psff("sff", "InputTypes", "", "", "none", "none", "none","sra",false,false); parameters.push_back(psff);
+               CommandParameter pfastqfile("fastqfile", "InputTypes", "", "", "none", "none", "none","sra",false,false); parameters.push_back(pfastqfile);
+        //choose only one multiple options
+        CommandParameter pplatform("platform", "Multiple", "454-???-???", "454", "", "", "","",false,false); parameters.push_back(pplatform);
+         //every command must have inputdir and outputdir.  This allows mothur users to redirect input and output files.
+               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, "SRACommand", "setParameters");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+string SRACommand::getHelpString(){
+       try {
+               string helpString = "";
+               helpString += "The sra command creates a sequence read archive from sff or fastq files.\n";
+               helpString += "The sra command parameters are: sff, fastqfiles, oligos, platform....\n";
+               helpString += "The sffiles parameter is used to provide a file containing a \n";
+               helpString += "The new command should be in the following format: \n";
+               helpString += "new(...)\n";
+               return helpString;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "SRACommand", "getHelpString");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+string SRACommand::getOutputPattern(string type) {
+    try {
+        string pattern = "";
+        
+        if (type == "sra") {  pattern = "[filename],sra"; }
+        else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
+        
+        return pattern;
+    }
+    catch(exception& e) {
+        m->errorOut(e, "SRACommand", "getOutputPattern");
+        exit(1);
+    }
+}
+//**********************************************************************************************************************
+SRACommand::SRACommand(){
+       try {
+               abort = true; calledHelp = true;
+               setParameters();
+        vector<string> tempOutNames;
+               outputTypes["sra"] = tempOutNames; 
+       }
+       catch(exception& e) {
+               m->errorOut(e, "SRACommand", "SRACommand");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+SRACommand::SRACommand(string option)  {
+       try {
+               abort = false; calledHelp = false;
+               
+               //allow user to run help
+               if(option == "help") { help(); abort = true; calledHelp = true; }
+               else if(option == "citation") { citation(); abort = true; calledHelp = true;}
+               
+               else {
+                       //valid paramters for this command
+                       vector<string> myArray = setParameters();
+                       
+                       OptionParser parser(option);
+                       map<string,string> parameters = parser.getParameters();
+                       
+                       ValidParameters validParameter;
+                       map<string,string>::iterator it;
+                       //check to make sure all parameters are valid for command
+                       for (it = parameters.begin(); it != parameters.end(); it++) {
+                               if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
+                       }
+                       
+                       
+                       //if the user changes the input directory command factory will send this info to us in the output parameter
+                       string inputDir = validParameter.validFile(parameters, "inputdir", false);
+                       if (inputDir == "not found"){   inputDir = "";          }
+                       else {
+            
+                string path;
+                               it = parameters.find("sfffiles");
+                               //user has given a template file
+                               if(it != parameters.end()){
+                                       path = m->hasPath(it->second);
+                                       //if the user has not given a path then, add inputdir. else leave path alone.
+                                       if (path == "") {       parameters["sfffiles"] = inputDir + it->second;         }
+                               }
+                               
+                               it = parameters.find("fastqfiles");
+                               //user has given a template file
+                               if(it != parameters.end()){
+                                       path = m->hasPath(it->second);
+                                       //if the user has not given a path then, add inputdir. else leave path alone.
+                                       if (path == "") {       parameters["fastqfiles"] = inputDir + it->second;               }
+                               }
+            }
+            
+                       //check for parameters
+            fastqfiles = validParameter.validFile(parameters, "fastqfiles", true);
+                       if (fastqfiles == "not open") { fastqfiles = "";  abort = true; }
+                       else if (fastqfiles == "not found") { fastqfiles = ""; }
+                       
+                       sfffiles = validParameter.validFile(parameters, "sfffiles", true);
+                       if (sfffiles == "not open") {  sfffiles = "";  abort = true; }
+                       else if (sfffiles == "not found") { sfffiles = ""; }
+                       
+                       if ((fastqfiles == "") && (sfffiles == "")) {
+                m->mothurOut("No valid current files. You must provide a sfffiles or fastqfiles file before you can use the sra command."); m->mothurOutEndLine(); abort = true;
+            }
+                                   
+            //use only one Mutliple type
+                       platform = validParameter.validFile(parameters, "platform", false);
+                       if (platform == "not found") { platform = "454"; }
+                       
+                       if ((platform == "454") || (platform == "????") || (platform == "????") || (platform == "????")) { }
+                       else { m->mothurOut("Not a valid platform option.  Valid platform options are 454, ...."); m->mothurOutEndLine(); abort = true; }
+            
+                               
+               }
+               
+       }
+       catch(exception& e) {
+               m->errorOut(e, "SRACommand", "SRACommand");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+
+int SRACommand::execute(){
+       try {
+               
+               if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
+        
+
+               
+        //output files created by command
+               m->mothurOutEndLine();
+               m->mothurOut("Output File Names: "); m->mothurOutEndLine();
+               for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
+               m->mothurOutEndLine();
+        return 0;
+               
+    }
+       catch(exception& e) {
+               m->errorOut(e, "SRACommand", "SRACommand");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+
+
diff --git a/sracommand.h b/sracommand.h
new file mode 100644 (file)
index 0000000..0f0a945
--- /dev/null
@@ -0,0 +1,46 @@
+//
+//  sracommand.h
+//  Mothur
+//
+//  Created by SarahsWork on 10/28/13.
+//  Copyright (c) 2013 Schloss Lab. All rights reserved.
+//
+
+#ifndef Mothur_sracommand_h
+#define Mothur_sracommand_h
+
+#include "command.hpp"
+
+
+/**************************************************************************************************/
+
+class SRACommand : public Command {
+public:
+    SRACommand(string);
+    SRACommand();
+    ~SRACommand(){}
+    
+    vector<string> setParameters();
+    string getCommandName()                    { return "sra";                 }
+    string getCommandCategory()                { return "Sequence Processing";         }
+    
+    string getOutputPattern(string);
+    
+       string getHelpString();
+    string getCitation() { return "http://www.mothur.org/wiki/sra"; }
+    string getDescription()            { return "create a Sequence Read Archive / SRA"; }
+    
+    int execute();
+    void help() { m->mothurOut(getHelpString()); }
+    
+private:
+    bool abort;
+    string sfffiles, fastqfiles, platform, outputDir;
+    vector<string> outputNames;
+};
+
+/**************************************************************************************************/
+
+
+
+#endif
index d93fb6e775392b5436b6dadbb99c88761e862de8..2c9399bda1dd363d04c1fed89ff9b12ea8c3aace 100644 (file)
@@ -184,9 +184,6 @@ SummarySharedCommand::SummarySharedCommand(string option)  {
                        string temp = validParameter.validFile(parameters, "all", false);                               if (temp == "not found") { temp = "false"; }
                        all = m->isTrue(temp);
                        
-                       temp = validParameter.validFile(parameters, "distance", false);                                 if (temp == "not found") { temp = "false"; }
-                       createPhylip = m->isTrue(temp);
-                       
             temp = validParameter.validFile(parameters, "iters", false);                       if (temp == "not found") { temp = "1000"; }
                        m->mothurConvert(temp, iters); 
             
@@ -204,6 +201,10 @@ SummarySharedCommand::SummarySharedCommand(string option)  {
             
             if (subsample == false) { iters = 0; }
             
+            temp = validParameter.validFile(parameters, "distance", false);                                    if (temp == "not found") { temp = "false"; }
+                       createPhylip = m->isTrue(temp);
+            if (subsample) { createPhylip = true; }
+            
                        temp = validParameter.validFile(parameters, "processors", false);       if (temp == "not found"){       temp = m->getProcessors();      }
                        m->setProcessors(temp);
                        m->mothurConvert(temp, processors); 
index 98796b3466fcc344b5e4c990015316a5ae2a0582..3767687bff20dd66f754d8e55920135d7609fe68 100644 (file)
@@ -29,8 +29,7 @@ vector<string> VennCommand::setParameters(){
                CommandParameter pnseqs("nseqs", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(pnseqs);
         CommandParameter psharedotus("sharedotus", "Boolean", "", "t", "", "", "","",false,false); parameters.push_back(psharedotus);
                CommandParameter pfontsize("fontsize", "Number", "", "24", "", "", "","",false,false); parameters.push_back(pfontsize);
-               CommandParameter ppermute("permute", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(ppermute);
-               CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
+        CommandParameter ppermute("permute", "Multiple", "1-2-3-4", "4", "", "", "","",false,false); parameters.push_back(ppermute);           CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
                CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
                
                vector<string> myArray;
@@ -56,7 +55,7 @@ string VennCommand::getHelpString(){
                helpString += "The default value for calc is sobs if you have only read a list file or if you have selected only one group, and sharedsobs if you have multiple groups.\n";
                helpString += "The default available estimators for calc are sobs, chao and ace if you have only read a list file, and sharedsobs, sharedchao and sharedace if you have read a shared file.\n";
                helpString += "The nseqs parameter will output the number of sequences represented by the otus in the picture, default=F.\n";
-               helpString += "If you have more than 4 groups, the permute parameter will find all possible combos of 4 of your groups and create pictures for them, default=F.\n";
+               helpString += "If you have more than 4 groups, you can use the permute parameter to set the number of groups you would like mothur to divide the samples into to draw the venn diagrams for all possible combos. Default=4.\n";
                helpString += "The only estimators available four 4 groups are sharedsobs and sharedchao.\n";
         helpString += "The sharedotus parameter can be used with the sharedsobs calculator to get the names of the OTUs in each section of the venn diagram. Default=t.\n";
                helpString += "The venn command outputs a .svg file for each calculator you specify at each distance you choose.\n";
@@ -215,8 +214,10 @@ VennCommand::VennCommand(string option)  {
                        temp = validParameter.validFile(parameters, "nseqs", false);            if (temp == "not found"){       temp = "f";                             }
                        nseqs = m->isTrue(temp); 
 
-                       temp = validParameter.validFile(parameters, "permute", false);          if (temp == "not found"){       temp = "f";                             }
-                       perm = m->isTrue(temp); 
+                       temp = validParameter.validFile(parameters, "permute", false);          if (temp == "not found"){       temp = "4";                             }
+                       m->mothurConvert(temp, perm);
+            if ((perm == 1) || (perm == 2) || (perm == 3) || (perm == 4)) { }
+            else { m->mothurOut("[ERROR]: Not a valid permute value.  Valid values are 1, 2, 3, and 4."); m->mothurOutEndLine(); abort = true;  }
             
             temp = validParameter.validFile(parameters, "sharedotus", false);          if (temp == "not found"){       temp = "t";                             }
                        sharedOtus = m->isTrue(temp); 
@@ -280,7 +281,7 @@ int VennCommand::execute(){
                        lookup = input->getSharedRAbundVectors();
                        lastLabel = lookup[0]->getLabel();
                        
-                       if ((lookup.size() > 4) && (perm)) { combosOfFour = findCombinations(lookup.size()); }
+                       if ((lookup.size() > 4)) { combos = findCombinations(lookup.size()); }
                }else if (format == "list") {
                        sabund = input->getSAbundVector();
                        lastLabel = sabund->getLabel();
@@ -308,17 +309,12 @@ int VennCommand::execute(){
                                        processedLabels.insert(lookup[0]->getLabel());
                                        userLabels.erase(lookup[0]->getLabel());
                                        
-                                       if ((lookup.size() > 4) && (!perm)){
-                                               m->mothurOut("Error: Too many groups chosen.  You may use up to 4 groups with the venn command.  I will use the first four groups in your groupfile. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
-                                               for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
                                        
-                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
-                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  } }
 
-                                       }else if ((lookup.size() > 4) && (perm)) {
+                                       if (lookup.size() > 4) {
                                                set< set<int> >::iterator it3;
                                                set<int>::iterator it2;
-                                               for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
+                                               for (it3 = combos.begin(); it3 != combos.end(); it3++) {  
                        
                                                        set<int> poss = *it3;
                                                        vector<SharedRAbundVector*> subset;
@@ -343,17 +339,10 @@ int VennCommand::execute(){
                                        processedLabels.insert(lookup[0]->getLabel());
                                        userLabels.erase(lookup[0]->getLabel());
 
-                                       if ((lookup.size() > 4) && (!perm)){
-                                               m->mothurOut("Error: Too many groups chosen.  You may use up to 4 groups with the venn command.  I will use the first four groups in your groupfile. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
-                                               for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
-                                       
-                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
-                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]);  }  }
-
-                                       }else if ((lookup.size() > 4) && (perm)) {
+                                       if (lookup.size() > 4) {
                                                set< set<int> >::iterator it3;
                                                set<int>::iterator it2;
-                                               for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
+                                               for (it3 = combos.begin(); it3 != combos.end(); it3++) {  
                        
                                                        set<int> poss = *it3;
                                                        vector<SharedRAbundVector*> subset;
@@ -409,17 +398,10 @@ int VennCommand::execute(){
                                        processedLabels.insert(lookup[0]->getLabel());
                                        userLabels.erase(lookup[0]->getLabel());
 
-                                       if ((lookup.size() > 4) && (!perm)){
-                                               m->mothurOut("Error: Too many groups chosen.  You may use up to 4 groups with the venn command.  I will use the first four groups in your groupfile. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
-                                               for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
-                                       
-                                               vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
-                                               for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]);  outputTypes["svg"].push_back(outfilenames[i]); }  }
-
-                                       }else if ((lookup.size() > 4) && (perm)) {
+                                       if (lookup.size() > 4) {
                                                set< set<int> >::iterator it3;
                                                set<int>::iterator it2;
-                                               for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
+                                               for (it3 = combos.begin(); it3 != combos.end(); it3++) {  
                        
                                                        set<int> poss = *it3;
                                                        vector<SharedRAbundVector*> subset;
@@ -552,7 +534,7 @@ int VennCommand::execute(){
        }
 }
 //**********************************************************************************************************************
-//returns a vector of sets containing the group combinations
+//returns a vector of sets containing the group combinations
 set< set<int> > VennCommand::findCombinations(int lookupSize){
        try {
                set< set<int> > combos;
@@ -561,7 +543,7 @@ set< set<int> > VennCommand::findCombinations(int lookupSize){
                for (int i = 0; i < lookupSize; i++) {  possibles.insert(i);  }
                
                getCombos(possibles, combos);
-               
+        
                return combos;
                
        }
@@ -571,11 +553,11 @@ set< set<int> > VennCommand::findCombinations(int lookupSize){
        }
 }
 //**********************************************************************************************************************
-//recusively finds combos of 4
+//recusively finds combos of length perm
 int VennCommand::getCombos(set<int> possibles, set< set<int> >& combos){
        try {
                
-               if (possibles.size() == 4) { //done
+               if (possibles.size() == perm) { //done
                        if (combos.count(possibles) == 0) { //no dups
                                combos.insert(possibles);
                        }
index 98a59d404099dcb32052e07e93644be9f01e2869..4762902c51d4f1195e8f3fc604b1781ddb1df39f 100644 (file)
@@ -40,11 +40,11 @@ private:
        Venn* venn;
        vector<Calculator*> vennCalculators;    
        vector<SharedRAbundVector*> lookup;
-       set< set<int> > combosOfFour;
+       set< set<int> > combos;
        SAbundVector* sabund;
-       int abund, fontsize;
+       int abund, fontsize, perm;
        
-       bool abort, allLines, nseqs, perm, sharedOtus;
+       bool abort, allLines, nseqs, sharedOtus;
        set<string> labels; //holds labels to be used
        string format, groups, calc, label, outputDir, sharedfile, listfile, inputfile;
        vector<string> Estimators, Groups, outputNames;