]> git.donarmstrong.com Git - mothur.git/blobdiff - seqerrorcommand.cpp
changed added group output to indicator command. a few changes to work with the guy
[mothur.git] / seqerrorcommand.cpp
index 5efb1ce78c659577c520defc124c48e60b848dc8..5ec6cf2d1cc4778399d289ea2280c882f936b944 100644 (file)
@@ -13,6 +13,7 @@
 #include "refchimeratest.h"
 #include "filterseqscommand.h"
 
+
 //**********************************************************************************************************************
 vector<string> SeqErrorCommand::setParameters(){       
        try {
@@ -24,7 +25,7 @@ vector<string> SeqErrorCommand::setParameters(){
                CommandParameter pignorechimeras("ignorechimeras", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pignorechimeras);
                CommandParameter pthreshold("threshold", "Number", "", "1.0", "", "", "",false,false); parameters.push_back(pthreshold);
                CommandParameter pprocessors("processors", "Number", "", "1", "", "", "",false,false); parameters.push_back(pprocessors);
-               CommandParameter pfilter("filter", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pfilter);
+               CommandParameter psave("save", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(psave);
                CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
                CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
                
@@ -42,6 +43,15 @@ string SeqErrorCommand::getHelpString(){
        try {
                string helpString = "";
                helpString += "The seq.error command reads a query alignment file and a reference alignment file and creates .....\n";
+               helpString += "The fasta parameter...\n";
+               helpString += "The reference parameter...\n";
+               helpString += "The qfile parameter...\n";
+               helpString += "The report parameter...\n";
+               helpString += "The name parameter...\n";
+               helpString += "The ignorechimeras parameter...\n";
+               helpString += "The threshold parameter...\n";
+               helpString += "The processors parameter...\n";
+               helpString += "If the save parameter is set to true the reference sequences will be saved in memory, to clear them later you can use the clear.memory command. Default=f.";
                helpString += "Example seq.error(...).\n";
                helpString += "Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFasta).\n";
                helpString += "For more details please check out the wiki http://www.mothur.org/wiki/seq.error .\n";
@@ -53,19 +63,52 @@ string SeqErrorCommand::getHelpString(){
        }
 }
 //**********************************************************************************************************************
+string SeqErrorCommand::getOutputFileNameTag(string type, string inputName=""){        
+       try {
+        string outputFileName = "";
+               map<string, vector<string> >::iterator it;
+        
+        //is this a type this command creates
+        it = outputTypes.find(type);
+        if (it == outputTypes.end()) {  m->mothurOut("[ERROR]: this command doesn't create a " + type + " output file.\n"); }
+        else {
+            if (type == "errorsummary")            {   outputFileName =  "error.summary";   }
+            else if (type == "errorseq")            {   outputFileName =  "error.seq";   }
+            else if (type == "errorquality")            {   outputFileName =  "error.quality";   }
+            else if (type == "errorqualforward")            {   outputFileName =  "error.qual.forward";   }
+            else if (type == "errorqualreverse")            {   outputFileName =  "error.qual.reverse";   }
+            else if (type == "errorforward")            {   outputFileName =  "error.seq.forward";   }
+            else if (type == "errorreverse")            {   outputFileName =  "error.seq.reverse";   }
+            else if (type == "errorcount")            {   outputFileName =  "error.count";   }
+            else if (type == "errormatrix")            {   outputFileName =  "error.matrix";   }
+            else if (type == "errorchimera")            {   outputFileName =  "error.chimera";   }
+            else if (type == "errorref-query")            {   outputFileName =  "error.ref-query";   }
+            else { m->mothurOut("[ERROR]: No definition for type " + type + " output file tag.\n"); m->control_pressed = true;  }
+        }
+        return outputFileName;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "SeqErrorCommand", "getOutputFileNameTag");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
 SeqErrorCommand::SeqErrorCommand(){    
        try {
                abort = true; calledHelp = true; 
+               setParameters();
                vector<string> tempOutNames;
-               outputTypes["error.summary"] = tempOutNames;
-               outputTypes["error.seq"] = tempOutNames;
-               outputTypes["error.quality"] = tempOutNames;
-               outputTypes["error.qual.forward"] = tempOutNames;
-               outputTypes["error.qual.reverse"] = tempOutNames;
-               outputTypes["error.forward"] = tempOutNames;
-               outputTypes["error.reverse"] = tempOutNames;
-               outputTypes["error.count"] = tempOutNames;
-               outputTypes["error.matrix"] = tempOutNames;
+               outputTypes["errorsummary"] = tempOutNames;
+               outputTypes["errorseq"] = tempOutNames;
+               outputTypes["errorquality"] = tempOutNames;
+               outputTypes["errorqualforward"] = tempOutNames;
+               outputTypes["errorqualreverse"] = tempOutNames;
+               outputTypes["errorforward"] = tempOutNames;
+               outputTypes["errorreverse"] = tempOutNames;
+               outputTypes["errorcount"] = tempOutNames;
+               outputTypes["errormatrix"] = tempOutNames;
+        outputTypes["errorchimera"] = tempOutNames;
+        outputTypes["errorref-query"] = tempOutNames;
        }
        catch(exception& e) {
                m->errorOut(e, "SeqErrorCommand", "SeqErrorCommand");
@@ -78,6 +121,7 @@ SeqErrorCommand::SeqErrorCommand(string option)  {
        try {
                
                abort = false; calledHelp = false;   
+               rdb = ReferenceDB::getInstance();
                
                //allow user to run help
                if(option == "help") { help(); abort = true; calledHelp = true; }
@@ -100,15 +144,17 @@ SeqErrorCommand::SeqErrorCommand(string option)  {
                        
                        //initialize outputTypes
                        vector<string> tempOutNames;
-                       outputTypes["error.summary"] = tempOutNames;
-                       outputTypes["error.seq"] = tempOutNames;
-                       outputTypes["error.quality"] = tempOutNames;
-                       outputTypes["error.qual.forward"] = tempOutNames;
-                       outputTypes["error.qual.reverse"] = tempOutNames;
-                       outputTypes["error.forward"] = tempOutNames;
-                       outputTypes["error.reverse"] = tempOutNames;
-                       outputTypes["error.count"] = tempOutNames;
-                       outputTypes["error.matrix"] = tempOutNames;
+                       outputTypes["errorsummary"] = tempOutNames;
+                       outputTypes["errorseq"] = tempOutNames;
+                       outputTypes["errorquality"] = tempOutNames;
+                       outputTypes["errorqualforward"] = tempOutNames;
+                       outputTypes["errorqualreverse"] = tempOutNames;
+                       outputTypes["errorforward"] = tempOutNames;
+                       outputTypes["errorreverse"] = tempOutNames;
+                       outputTypes["errorcount"] = tempOutNames;
+                       outputTypes["errormatrix"] = tempOutNames;
+            outputTypes["errorchimera"] = tempOutNames;
+            outputTypes["errorref-query"] = tempOutNames;
 
                        
                        //if the user changes the input directory command factory will send this info to us in the output parameter 
@@ -164,22 +210,24 @@ SeqErrorCommand::SeqErrorCommand(string option)  {
                                if (queryFileName != "") { m->mothurOut("Using " + queryFileName + " as input file for the fasta parameter."); m->mothurOutEndLine(); }
                                else {  m->mothurOut("You have no current fasta file and the fasta parameter is required."); m->mothurOutEndLine(); abort = true; }
                        }
-                       else if (queryFileName == "not open") { abort = true; } 
+                       else if (queryFileName == "not open") { queryFileName = ""; abort = true; }     
+                       else { m->setFastaFile(queryFileName); }
                        
                        referenceFileName = validParameter.validFile(parameters, "reference", true);
                        if (referenceFileName == "not found") { m->mothurOut("reference is a required parameter for the seq.error command."); m->mothurOutEndLine(); abort = true; }
                        else if (referenceFileName == "not open") { abort = true; }     
                        
-
                        //check for optional parameters
                        namesFileName = validParameter.validFile(parameters, "name", true);
                        if(namesFileName == "not found"){       namesFileName = "";     }
                        else if (namesFileName == "not open") { namesFileName = ""; abort = true; }     
+                       else { m->setNameFile(namesFileName); }
                        
                        qualFileName = validParameter.validFile(parameters, "qfile", true);
                        if(qualFileName == "not found"){        qualFileName = "";      }
                        else if (qualFileName == "not open") { qualFileName = ""; abort = true; }       
-
+                       else { m->setQualFile(qualFileName); }
+                       
                        reportFileName = validParameter.validFile(parameters, "report", true);
                        if(reportFileName == "not found"){      reportFileName = "";    }
                        else if (reportFileName == "not open") { reportFileName = ""; abort = true; }   
@@ -199,20 +247,44 @@ SeqErrorCommand::SeqErrorCommand(string option)  {
                        //check for optional parameter and set defaults
                        // ...at some point should added some additional type checking...
                        temp = validParameter.validFile(parameters, "threshold", false);        if (temp == "not found") { temp = "1.00"; }
-                       convert(temp, threshold);  
+                       m->mothurConvert(temp, threshold);  
+                       
+                       temp = validParameter.validFile(parameters, "save", false);                     if (temp == "not found"){       temp = "f";                             }
+                       save = m->isTrue(temp); 
+                       rdb->save = save; 
+                       if (save) { //clear out old references
+                               rdb->clearMemory();     
+                       }
+                       
+                       //this has to go after save so that if the user sets save=t and provides no reference we abort
+                       referenceFileName = validParameter.validFile(parameters, "reference", true);
+                       if (referenceFileName == "not found") { 
+                               //check for saved reference sequences
+                               if (rdb->referenceSeqs.size() != 0) {
+                                       referenceFileName = "saved";
+                               }else {
+                                       m->mothurOut("[ERROR]: You don't have any saved reference sequences and the reference parameter is a required."); 
+                                       m->mothurOutEndLine();
+                                       abort = true; 
+                               }
+                       }else if (referenceFileName == "not open") { abort = true; }    
+                       else {  if (save) {     rdb->setSavedReference(referenceFileName);      }       }
+                       
                        
                        temp = validParameter.validFile(parameters, "ignorechimeras", false);   if (temp == "not found") { temp = "T"; }
                        ignoreChimeras = m->isTrue(temp);
                        
-                       temp = validParameter.validFile(parameters, "filter", false);   if (temp == "not found") { temp = "T"; }
-                       filter = m->isTrue(temp);  
-                       
                        temp = validParameter.validFile(parameters, "processors", false);       if (temp == "not found"){       temp = m->getProcessors();      }
                        m->setProcessors(temp);
-                       convert(temp, processors); 
+                       m->mothurConvert(temp, processors); 
 
                        substitutionMatrix.resize(6);
                        for(int i=0;i<6;i++){   substitutionMatrix[i].resize(6,0);      }
+                       
+                       if ((namesFileName == "") && (queryFileName != "")){
+                               vector<string> files; files.push_back(queryFileName); 
+                               parser.getNameFile(files);
+                       }
                }
        }
        catch(exception& e) {
@@ -230,42 +302,24 @@ int SeqErrorCommand::execute(){
                maxLength = 2000;
                totalBases = 0;
                totalMatches = 0;
-
-               //run vertical filter on query and reference files.
-               if (filter) {
-                       string inputString = "fasta=" + queryFileName + "-" + referenceFileName;
-                       m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
-                       m->mothurOut("Running command: filter.seqs(" + inputString + ") to improve processing time."); m->mothurOutEndLine(); 
-                       
-                       Command* filterCommand = new FilterSeqsCommand(inputString);
-                       filterCommand->execute();
-                       
-                       map<string, vector<string> > filenames = filterCommand->getOutputFiles();
-                       
-                       delete filterCommand;
-                       
-                       m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
-                       
-                       queryFileName = filenames["fasta"][0];
-                       referenceFileName = filenames["fasta"][1];
-               }
                
-               string errorSummaryFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.summary";
-               outputNames.push_back(errorSummaryFileName); outputTypes["error.summary"].push_back(errorSummaryFileName);
+        string fileNameRoot = outputDir + m->getRootName(m->getSimpleName(queryFileName));
+               string errorSummaryFileName = fileNameRoot + getOutputFileNameTag("errorsummary");
+               outputNames.push_back(errorSummaryFileName); outputTypes["errorsummary"].push_back(errorSummaryFileName);
                        
-               string errorSeqFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.seq";
-               outputNames.push_back(errorSeqFileName); outputTypes["error.seq"].push_back(errorSeqFileName);
+               string errorSeqFileName = fileNameRoot + getOutputFileNameTag("errorseq");
+               outputNames.push_back(errorSeqFileName); outputTypes["errorseq"].push_back(errorSeqFileName);
                
-               string errorChimeraFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.chimera";
-               outputNames.push_back(errorChimeraFileName); outputTypes["error.chimera"].push_back(errorChimeraFileName);
+               string errorChimeraFileName = fileNameRoot + getOutputFileNameTag("errorchimera");
+               outputNames.push_back(errorChimeraFileName); outputTypes["errorchimera"].push_back(errorChimeraFileName);
                
                getReferences();        //read in reference sequences - make sure there's no ambiguous bases
 
                if(namesFileName != ""){        weights = getWeights(); }
                
-               vector<unsigned long int> fastaFilePos;
-               vector<unsigned long int> qFilePos;
-               vector<unsigned long int> reportFilePos;
+               vector<unsigned long long> fastaFilePos;
+               vector<unsigned long long> qFilePos;
+               vector<unsigned long long> reportFilePos;
                
                setLines(queryFileName, qualFileName, reportFileName, fastaFilePos, qFilePos, reportFilePos);
                
@@ -279,7 +333,7 @@ int SeqErrorCommand::execute(){
                if(qualFileName == "")  {       qLines = lines; rLines = lines; } //fills with duds
                
                int numSeqs = 0;
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
                if(processors == 1){
                        numSeqs = driver(queryFileName, qualFileName, reportFileName, errorSummaryFileName, errorSeqFileName, errorChimeraFileName, lines[0], qLines[0], rLines[0]);
                }else{
@@ -296,12 +350,12 @@ int SeqErrorCommand::execute(){
                
                printErrorFRFile(errorForward, errorReverse);
                
-               if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; }
+               if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; }
 
-               string errorCountFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.count";
+               string errorCountFileName = fileNameRoot + getOutputFileNameTag("errorcount");
                ofstream errorCountFile;
                m->openOutputFile(errorCountFileName, errorCountFile);
-               outputNames.push_back(errorCountFileName);  outputTypes["error.count"].push_back(errorCountFileName);
+               outputNames.push_back(errorCountFileName);  outputTypes["errorcount"].push_back(errorCountFileName);
                m->mothurOut("Overall error rate:\t" + toString((double)(totalBases - totalMatches) / (double)totalBases) + "\n");
                m->mothurOut("Errors\tSequences\n");
                errorCountFile << "Errors\tSequences\n";                
@@ -311,14 +365,14 @@ int SeqErrorCommand::execute(){
                }
                errorCountFile.close();
                
-               if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; }
+               if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; }
 
                printSubMatrix();
                                
-               string megAlignmentFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.ref-query";
+               string megAlignmentFileName = fileNameRoot + getOutputFileNameTag("errorref-query");
                ofstream megAlignmentFile;
                m->openOutputFile(megAlignmentFileName, megAlignmentFile);
-               outputNames.push_back(megAlignmentFileName);  outputTypes["error.ref-query"].push_back(megAlignmentFileName);
+               outputNames.push_back(megAlignmentFileName);  outputTypes["errorref-query"].push_back(megAlignmentFileName);
                
                for(int i=0;i<numRefs;i++){
                        megAlignmentFile << referenceSeqs[i].getInlineSeq() << endl;
@@ -347,7 +401,7 @@ int SeqErrorCommand::createProcesses(string filename, string qFileName, string r
                processIDS.clear();
                map<char, vector<int> >::iterator it;
                int num = 0;
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
                
                //loop through and create all the processes you want
                while (process != processors) {
@@ -468,11 +522,11 @@ int SeqErrorCommand::createProcesses(string filename, string qFileName, string r
                        m->mothurOut("Appending files from process " + toString(processIDS[i])); m->mothurOutEndLine();
                        
                        m->appendFiles((summaryFileName + toString(processIDS[i]) + ".temp"), summaryFileName);
-                       remove((summaryFileName + toString(processIDS[i]) + ".temp").c_str());
+                       m->mothurRemove((summaryFileName + toString(processIDS[i]) + ".temp"));
                        m->appendFiles((errorOutputFileName + toString(processIDS[i]) + ".temp"), errorOutputFileName);
-                       remove((errorOutputFileName + toString(processIDS[i]) + ".temp").c_str());
+                       m->mothurRemove((errorOutputFileName + toString(processIDS[i]) + ".temp"));
                        m->appendFiles((chimeraOutputFileName + toString(processIDS[i]) + ".temp"), chimeraOutputFileName);
-                       remove((chimeraOutputFileName + toString(processIDS[i]) + ".temp").c_str());
+                       m->mothurRemove((chimeraOutputFileName + toString(processIDS[i]) + ".temp"));
                        
                        ifstream in;
                        string tempFile =  filename + toString(processIDS[i]) + ".info.temp";
@@ -567,7 +621,7 @@ int SeqErrorCommand::createProcesses(string filename, string qFileName, string r
                        }
                        m->gobble(in);
                        
-                       in.close(); remove(tempFile.c_str());
+                       in.close(); m->mothurRemove(tempFile);
                        
                }
 #endif         
@@ -663,7 +717,8 @@ int SeqErrorCommand::driver(string filename, string qFileName, string rFileName,
                        if(numParentSeqs > 1 && ignoreChimeras == 1)    {       ignoreSeq = 1;  }
                        else                                                                                    {       ignoreSeq = 0;  }
                        
-                       Compare minCompare = getErrors(query, referenceSeqs[closestRefIndex]);
+                       Compare minCompare;
+            getErrors(query, referenceSeqs[closestRefIndex], minCompare);
                        
                        if(namesFileName != ""){
                                it = weights.find(query.getName());
@@ -678,8 +733,10 @@ int SeqErrorCommand::driver(string filename, string qFileName, string rFileName,
                                for(int i=0;i<minCompare.sequence.length();i++){
                                        char letter = minCompare.sequence[i];
                                        
-                                       errorForward[letter][i] += minCompare.weight;
-                                       errorReverse[letter][minCompare.total-i-1] += minCompare.weight;                                
+                                       if(letter != 'r'){
+                                               errorForward[letter][i] += minCompare.weight;
+                                               errorReverse[letter][minCompare.total-i-1] += minCompare.weight;                                
+                                       }
                                }
                        }
                        
@@ -693,9 +750,13 @@ int SeqErrorCommand::driver(string filename, string qFileName, string rFileName,
                                quality = QualityScores(qualFile);
                                
                                if(!ignoreSeq){
+//                                     cout << query.getName() << '\t';
+                                       
                                        quality.updateQScoreErrorMap(qScoreErrorMap, minCompare.sequence, startBase, endBase, minCompare.weight);
                                        quality.updateForwardMap(qualForwardMap, startBase, endBase, minCompare.weight);
                                        quality.updateReverseMap(qualReverseMap, startBase, endBase, minCompare.weight);
+
+//                                     cout << endl;
                                }
                        }                       
                        
@@ -714,14 +775,14 @@ int SeqErrorCommand::driver(string filename, string qFileName, string rFileName,
                        
                        index++;
                        
-                       #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-                               unsigned long int pos = queryFile.tellg();
+                       #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+                               unsigned long long pos = queryFile.tellg();
                                if ((pos == -1) || (pos >= line.end)) { break; }
                        #else
                                if (queryFile.eof()) { break; }
                        #endif
                        
-                       if(index % 100 == 0){   m->mothurOut(toString(index) + '\n');   }
+                       if(index % 100 == 0){   m->mothurOut(toString(index));  m->mothurOutEndLine(); }
                }
                queryFile.close();
                if(qFileName != "" && rFileName != ""){  reportFile.close(); qualFile.close(); }
@@ -729,7 +790,7 @@ int SeqErrorCommand::driver(string filename, string qFileName, string rFileName,
                errorSeqFile.close();
                
                //report progress
-               if(index % 100 != 0){   m->mothurOut(toString(index) + '\n');   }
+               if(index % 100 != 0){   m->mothurOut(toString(index));  m->mothurOutEndLine(); }
                
                return index;
        }
@@ -742,41 +803,75 @@ int SeqErrorCommand::driver(string filename, string qFileName, string rFileName,
 
 void SeqErrorCommand::getReferences(){
        try {
-               
-               ifstream referenceFile;
-               m->openInputFile(referenceFileName, referenceFile);
-               
                int numAmbigSeqs = 0;
                
                int maxStartPos = 0;
                int minEndPos = 100000;
                
-               while(referenceFile){
-                       Sequence currentSeq(referenceFile);
-                       int numAmbigs = currentSeq.getAmbigBases();
-                       if(numAmbigs > 0){      numAmbigSeqs++; }
-                       
-//                     int startPos = currentSeq.getStartPos();
-//                     if(startPos > maxStartPos)      {       maxStartPos = startPos; }
-//
-//                     int endPos = currentSeq.getEndPos();
-//                     if(endPos < minEndPos)          {       minEndPos = endPos;             }
-                       referenceSeqs.push_back(currentSeq);
+               if (referenceFileName == "saved") {
+                       int start = time(NULL);
+                       m->mothurOutEndLine();  m->mothurOut("Using sequences from " + rdb->getSavedReference() + " that are saved in memory.");        m->mothurOutEndLine();
+                       
+                       for (int i = 0; i < rdb->referenceSeqs.size(); i++) {
+                               int numAmbigs = rdb->referenceSeqs[i].getAmbigBases();
+                               if(numAmbigs > 0){      numAmbigSeqs++; }
+                               
+                               //                      int startPos = rdb->referenceSeqs[i].getStartPos();
+                               //                      if(startPos > maxStartPos)      {       maxStartPos = startPos; }
+                               //
+                               //                      int endPos = rdb->referenceSeqs[i].getEndPos();
+                               //                      if(endPos < minEndPos)          {       minEndPos = endPos;             }                               
+                               if (rdb->referenceSeqs[i].getNumBases() == 0) {
+                    m->mothurOut("[WARNING]: " + rdb->referenceSeqs[i].getName() + " is blank, ignoring.");m->mothurOutEndLine(); 
+                }else {
+                    referenceSeqs.push_back(rdb->referenceSeqs[i]);
+                }
                                
-                       m->gobble(referenceFile);
+                       }
+                       referenceFileName = rdb->getSavedReference();
+                       
+                       m->mothurOut("It took " + toString(time(NULL) - start) + " to load " + toString(referenceSeqs.size()) + " sequences.");m->mothurOutEndLine();  
+               
+               }else {
+                       int start = time(NULL);
+
+                       ifstream referenceFile;
+                       m->openInputFile(referenceFileName, referenceFile);
+                       
+                       while(referenceFile){
+                               Sequence currentSeq(referenceFile);
+                               int numAmbigs = currentSeq.getAmbigBases();
+                               if(numAmbigs > 0){      numAmbigSeqs++; }
+                               
+       //                      int startPos = currentSeq.getStartPos();
+       //                      if(startPos > maxStartPos)      {       maxStartPos = startPos; }
+       //
+       //                      int endPos = currentSeq.getEndPos();
+       //                      if(endPos < minEndPos)          {       minEndPos = endPos;             }
+                if (currentSeq.getNumBases() == 0) {
+                    m->mothurOut("[WARNING]: " + currentSeq.getName() + " is blank, ignoring.");m->mothurOutEndLine(); 
+                }else {
+                    referenceSeqs.push_back(currentSeq);
+                    if (rdb->save) { rdb->referenceSeqs.push_back(currentSeq); }
+                }
+                                       
+                               m->gobble(referenceFile);
+                       }
+                       referenceFile.close();
+                       
+                       m->mothurOut("It took " + toString(time(NULL) - start) + " to read " + toString(referenceSeqs.size()) + " sequences.");m->mothurOutEndLine();  
                }
-               referenceFile.close();
+               
                numRefs = referenceSeqs.size();
-
                
                for(int i=0;i<numRefs;i++){
                        referenceSeqs[i].padToPos(maxStartPos);
                        referenceSeqs[i].padFromPos(minEndPos);
-               }
+        }
                
                if(numAmbigSeqs != 0){
                        m->mothurOut("Warning: " + toString(numAmbigSeqs) + " reference sequences have ambiguous bases, these bases will be ignored\n");
-               }               
+               }       
                
        }
        catch(exception& e) {
@@ -787,7 +882,7 @@ void SeqErrorCommand::getReferences(){
 
 //***************************************************************************************************************
 
-Compare SeqErrorCommand::getErrors(Sequence query, Sequence reference){
+int SeqErrorCommand::getErrors(Sequence query, Sequence reference, Compare& errors){
        try {
                if(query.getAlignLength() != reference.getAlignLength()){
                        m->mothurOut("Warning: " + toString(query.getName()) + " and " + toString(reference.getName()) + " are different lengths\n");
@@ -798,56 +893,68 @@ Compare SeqErrorCommand::getErrors(Sequence query, Sequence reference){
                string r = reference.getAligned();
 
                int started = 0;
-               Compare errors;
+               //Compare errors;
 
                for(int i=0;i<alignLength;i++){
-                       if(r[i] != 'N' && q[i] != '.' && r[i] != '.' && (q[i] != '-' || r[i] != '-')){                  //      no missing data and no double gaps
-                               started = 1;
-                               
-                               if(q[i] == 'A'){
-                                       if(r[i] == 'A'){        errors.AA++;    errors.matches++;       errors.sequence += 'm'; }
-                                       if(r[i] == 'T'){        errors.AT++;    errors.sequence += 's'; }
-                                       if(r[i] == 'G'){        errors.AG++;    errors.sequence += 's'; }
-                                       if(r[i] == 'C'){        errors.AC++;    errors.sequence += 's'; }
-                                       if(r[i] == '-'){        errors.Ai++;    errors.sequence += 'i'; }
-                               }
-                               else if(q[i] == 'T'){
-                                       if(r[i] == 'A'){        errors.TA++;    errors.sequence += 's'; }
-                                       if(r[i] == 'T'){        errors.TT++;    errors.matches++;       errors.sequence += 'm'; }
-                                       if(r[i] == 'G'){        errors.TG++;    errors.sequence += 's'; }
-                                       if(r[i] == 'C'){        errors.TC++;    errors.sequence += 's'; }
-                                       if(r[i] == '-'){        errors.Ti++;    errors.sequence += 'i'; }
-                               }
-                               else if(q[i] == 'G'){
-                                       if(r[i] == 'A'){        errors.GA++;    errors.sequence += 's'; }
-                                       if(r[i] == 'T'){        errors.GT++;    errors.sequence += 's'; }
-                                       if(r[i] == 'G'){        errors.GG++;    errors.matches++;       errors.sequence += 'm'; }
-                                       if(r[i] == 'C'){        errors.GC++;    errors.sequence += 's'; }
-                                       if(r[i] == '-'){        errors.Gi++;    errors.sequence += 'i'; }
-                               }
-                               else if(q[i] == 'C'){
-                                       if(r[i] == 'A'){        errors.CA++;    errors.sequence += 's'; }
-                                       if(r[i] == 'T'){        errors.CT++;    errors.sequence += 's'; }
-                                       if(r[i] == 'G'){        errors.CG++;    errors.sequence += 's'; }
-                                       if(r[i] == 'C'){        errors.CC++;    errors.matches++;       errors.sequence += 'm'; }
-                                       if(r[i] == '-'){        errors.Ci++;    errors.sequence += 'i'; }
-                               }
-                               else if(q[i] == 'N'){
-                                       if(r[i] == 'A'){        errors.NA++;    errors.sequence += 'a'; }
-                                       if(r[i] == 'T'){        errors.NT++;    errors.sequence += 'a'; }
-                                       if(r[i] == 'G'){        errors.NG++;    errors.sequence += 'a'; }
-                                       if(r[i] == 'C'){        errors.NC++;    errors.sequence += 'a'; }
-                                       if(r[i] == '-'){        errors.Ni++;    errors.sequence += 'a'; }
+//                     cout << r[i] << '\t' << q[i] << '\t';
+                       if(q[i] != '.' && r[i] != '.' && (q[i] != '-' || r[i] != '-')){                 //      no missing data and no double gaps
+                               if(r[i] != 'N'){
+                                       started = 1;
+                                       
+                                       if(q[i] == 'A'){
+                                               if(r[i] == 'A'){        errors.AA++;    errors.matches++;       errors.sequence += 'm'; }
+                                               if(r[i] == 'T'){        errors.AT++;    errors.sequence += 's'; }
+                                               if(r[i] == 'G'){        errors.AG++;    errors.sequence += 's'; }
+                                               if(r[i] == 'C'){        errors.AC++;    errors.sequence += 's'; }
+                                               if(r[i] == '-'){        errors.Ai++;    errors.sequence += 'i'; }
+                                       }
+                                       else if(q[i] == 'T'){
+                                               if(r[i] == 'A'){        errors.TA++;    errors.sequence += 's'; }
+                                               if(r[i] == 'T'){        errors.TT++;    errors.matches++;       errors.sequence += 'm'; }
+                                               if(r[i] == 'G'){        errors.TG++;    errors.sequence += 's'; }
+                                               if(r[i] == 'C'){        errors.TC++;    errors.sequence += 's'; }
+                                               if(r[i] == '-'){        errors.Ti++;    errors.sequence += 'i'; }
+                                       }
+                                       else if(q[i] == 'G'){
+                                               if(r[i] == 'A'){        errors.GA++;    errors.sequence += 's'; }
+                                               if(r[i] == 'T'){        errors.GT++;    errors.sequence += 's'; }
+                                               if(r[i] == 'G'){        errors.GG++;    errors.matches++;       errors.sequence += 'm'; }
+                                               if(r[i] == 'C'){        errors.GC++;    errors.sequence += 's'; }
+                                               if(r[i] == '-'){        errors.Gi++;    errors.sequence += 'i'; }
+                                       }
+                                       else if(q[i] == 'C'){
+                                               if(r[i] == 'A'){        errors.CA++;    errors.sequence += 's'; }
+                                               if(r[i] == 'T'){        errors.CT++;    errors.sequence += 's'; }
+                                               if(r[i] == 'G'){        errors.CG++;    errors.sequence += 's'; }
+                                               if(r[i] == 'C'){        errors.CC++;    errors.matches++;       errors.sequence += 'm'; }
+                                               if(r[i] == '-'){        errors.Ci++;    errors.sequence += 'i'; }
+                                       }
+                                       else if(q[i] == 'N'){
+                                               if(r[i] == 'A'){        errors.NA++;    errors.sequence += 'a'; }
+                                               if(r[i] == 'T'){        errors.NT++;    errors.sequence += 'a'; }
+                                               if(r[i] == 'G'){        errors.NG++;    errors.sequence += 'a'; }
+                                               if(r[i] == 'C'){        errors.NC++;    errors.sequence += 'a'; }
+                                               if(r[i] == '-'){        errors.Ni++;    errors.sequence += 'a'; }
+                                       }
+                                       else if(q[i] == '-' && r[i] != '-'){
+                                               if(r[i] == 'A'){        errors.dA++;    errors.sequence += 'd'; }
+                                               if(r[i] == 'T'){        errors.dT++;    errors.sequence += 'd'; }
+                                               if(r[i] == 'G'){        errors.dG++;    errors.sequence += 'd'; }
+                                               if(r[i] == 'C'){        errors.dC++;    errors.sequence += 'd'; }
+                                       }
+                                       errors.total++; 
                                }
-                               else if(q[i] == '-' && r[i] != '-'){
-                                       if(r[i] == 'A'){        errors.dA++;    errors.sequence += 'd'; }
-                                       if(r[i] == 'T'){        errors.dT++;    errors.sequence += 'd'; }
-                                       if(r[i] == 'G'){        errors.dG++;    errors.sequence += 'd'; }
-                                       if(r[i] == 'C'){        errors.dC++;    errors.sequence += 'd'; }
+                               else{
+                                       
+                                       if(q[i] == '-'){
+                                               errors.sequence += 'd'; errors.total++;
+                                       }                                               
+                                       else{
+                                               errors.sequence += 'r';
+                                       }
                                }
-                               errors.total++; 
-                               
                        }
+                               
                        else if(q[i] == '.' && r[i] != '.'){            //      reference extends beyond query
                                if(started == 1){       break;  }
                        }
@@ -857,14 +964,15 @@ Compare SeqErrorCommand::getErrors(Sequence query, Sequence reference){
                        else if(q[i] == '.' && r[i] == '.'){            //      both are missing data
                                if(started == 1){       break;  }                       
                        }
-                       
+//                     cout << errors.sequence[errors.sequence.length()-1] << endl;
                }
+//             cout << errors.sequence << endl;
                errors.mismatches = errors.total-errors.matches;
                errors.errorRate = (double)(errors.total-errors.matches) / (double)errors.total;
                errors.queryName = query.getName();
                errors.refName = reference.getName();
-               
-               return errors;
+               //return errors;
+        return 0;
        }
        catch(exception& e) {
                m->errorOut(e, "SeqErrorCommand", "getErrors");
@@ -979,10 +1087,11 @@ void SeqErrorCommand::printErrorData(Compare error, int numParentSeqs, ofstream&
 
 void SeqErrorCommand::printSubMatrix(){
        try {
-               string subMatrixFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.matrix";
+        string fileNameRoot = outputDir + m->getRootName(m->getSimpleName(queryFileName));
+               string subMatrixFileName = fileNameRoot + getOutputFileNameTag("errormatrix");
                ofstream subMatrixFile;
                m->openOutputFile(subMatrixFileName, subMatrixFile);
-               outputNames.push_back(subMatrixFileName);  outputTypes["error.matrix"].push_back(subMatrixFileName);
+               outputNames.push_back(subMatrixFileName);  outputTypes["errormatrix"].push_back(subMatrixFileName);
                vector<string> bases(6);
                bases[0] = "A";
                bases[1] = "T";
@@ -1025,10 +1134,11 @@ void SeqErrorCommand::printSubMatrix(){
 
 void SeqErrorCommand::printErrorFRFile(map<char, vector<int> > errorForward, map<char, vector<int> > errorReverse){
        try{
-               string errorForwardFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.seq.forward";
+        string fileNameRoot = outputDir + m->getRootName(m->getSimpleName(queryFileName));
+               string errorForwardFileName = fileNameRoot + getOutputFileNameTag("errorforward");
                ofstream errorForwardFile;
                m->openOutputFile(errorForwardFileName, errorForwardFile);
-               outputNames.push_back(errorForwardFileName);  outputTypes["error.forward"].push_back(errorForwardFileName);
+               outputNames.push_back(errorForwardFileName);  outputTypes["errorforward"].push_back(errorForwardFileName);
 
                errorForwardFile << "position\ttotalseqs\tmatch\tsubstitution\tinsertion\tdeletion\tambiguous" << endl;
                for(int i=0;i<maxLength;i++){
@@ -1043,10 +1153,10 @@ void SeqErrorCommand::printErrorFRFile(map<char, vector<int> > errorForward, map
                }
                errorForwardFile.close();
 
-               string errorReverseFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.seq.reverse";
+               string errorReverseFileName = fileNameRoot + getOutputFileNameTag("errorreverse");
                ofstream errorReverseFile;
                m->openOutputFile(errorReverseFileName, errorReverseFile);
-               outputNames.push_back(errorReverseFileName);  outputTypes["error.reverse"].push_back(errorReverseFileName);
+               outputNames.push_back(errorReverseFileName);  outputTypes["errorreverse"].push_back(errorReverseFileName);
 
                errorReverseFile << "position\ttotalseqs\tmatch\tsubstitution\tinsertion\tdeletion\tambiguous" << endl;
                for(int i=0;i<maxLength;i++){
@@ -1071,11 +1181,11 @@ void SeqErrorCommand::printErrorFRFile(map<char, vector<int> > errorForward, map
 
 void SeqErrorCommand::printErrorQuality(map<char, vector<int> > qScoreErrorMap){
        try{
-
-               string errorQualityFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.quality";
+        string fileNameRoot = outputDir + m->getRootName(m->getSimpleName(queryFileName));
+               string errorQualityFileName = fileNameRoot + getOutputFileNameTag("errorquality");
                ofstream errorQualityFile;
                m->openOutputFile(errorQualityFileName, errorQualityFile);
-               outputNames.push_back(errorQualityFileName);  outputTypes["error.quality"].push_back(errorQualityFileName);
+               outputNames.push_back(errorQualityFileName);  outputTypes["errorquality"].push_back(errorQualityFileName);
 
                errorQualityFile << "qscore\tmatches\tsubstitutions\tinsertions\tambiguous" << endl;
                for(int i=0;i<41;i++){
@@ -1105,11 +1215,11 @@ void SeqErrorCommand::printQualityFR(vector<vector<int> > qualForwardMap, vector
                                }
                        }
                }
-
-               string qualityForwardFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.qual.forward";
+        string fileNameRoot = outputDir + m->getRootName(m->getSimpleName(queryFileName));
+               string qualityForwardFileName = fileNameRoot + getOutputFileNameTag("errorqualforward");
                ofstream qualityForwardFile;
                m->openOutputFile(qualityForwardFileName, qualityForwardFile);
-               outputNames.push_back(qualityForwardFileName);  outputTypes["error.qual.forward"].push_back(qualityForwardFileName);
+               outputNames.push_back(qualityForwardFileName);  outputTypes["errorqualforward"].push_back(qualityForwardFileName);
 
                for(int i=0;i<numColumns;i++){  qualityForwardFile << '\t' << i;        }       qualityForwardFile << endl;
 
@@ -1124,10 +1234,10 @@ void SeqErrorCommand::printQualityFR(vector<vector<int> > qualForwardMap, vector
                qualityForwardFile.close();
 
                
-               string qualityReverseFileName = queryFileName.substr(0,queryFileName.find_last_of('.')) + ".error.qual.reverse";
+               string qualityReverseFileName = fileNameRoot + getOutputFileNameTag("errorqualreverse");
                ofstream qualityReverseFile;
                m->openOutputFile(qualityReverseFileName, qualityReverseFile);
-               outputNames.push_back(qualityReverseFileName);  outputTypes["error.qual.reverse"].push_back(qualityReverseFileName);
+               outputNames.push_back(qualityReverseFileName);  outputTypes["errorqualreverse"].push_back(qualityReverseFileName);
                
                for(int i=0;i<numColumns;i++){  qualityReverseFile << '\t' << i;        }       qualityReverseFile << endl;
                for(int i=0;i<numRows;i++){
@@ -1148,9 +1258,9 @@ void SeqErrorCommand::printQualityFR(vector<vector<int> > qualForwardMap, vector
 }
 /**************************************************************************************************/
 
-int SeqErrorCommand::setLines(string filename, string qfilename, string rfilename, vector<unsigned long int>& fastaFilePos, vector<unsigned long int>& qfileFilePos, vector<unsigned long int>& rfileFilePos) {
+int SeqErrorCommand::setLines(string filename, string qfilename, string rfilename, vector<unsigned long long>& fastaFilePos, vector<unsigned long long>& qfileFilePos, vector<unsigned long long>& rfileFilePos) {
        try {
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
                //set file positions for fasta file
                fastaFilePos = m->divideFile(filename, processors);
                
@@ -1190,7 +1300,7 @@ int SeqErrorCommand::setLines(string filename, string qfilename, string rfilenam
                                        map<string, int>::iterator it = firstSeqNames.find(sname);
                                        
                                        if(it != firstSeqNames.end()) { //this is the start of a new chunk
-                                               unsigned long int pos = inQual.tellg(); 
+                                               unsigned long long pos = inQual.tellg(); 
                                                qfileFilePos.push_back(pos - input.length() - 1);       
                                                firstSeqNames.erase(it);
                                        }
@@ -1211,7 +1321,7 @@ int SeqErrorCommand::setLines(string filename, string qfilename, string rfilenam
                
                //get last file position of qfile
                FILE * pFile;
-               unsigned long int size;
+               unsigned long long size;
                
                //get num bytes in file
                pFile = fopen (qfilename.c_str(),"rb");
@@ -1249,7 +1359,7 @@ int SeqErrorCommand::setLines(string filename, string qfilename, string rfilenam
                                map<string, int>::iterator it = firstSeqNamesReport.find(sname);
                        
                                if(it != firstSeqNamesReport.end()) { //this is the start of a new chunk
-                                       unsigned long int pos = inR.tellg(); 
+                                       unsigned long long pos = inR.tellg(); 
                                        rfileFilePos.push_back(pos - input.length() - 1);       
                                        firstSeqNamesReport.erase(it);
                                }
@@ -1270,7 +1380,7 @@ int SeqErrorCommand::setLines(string filename, string qfilename, string rfilenam
                
                //get last file position of qfile
                FILE * rFile;
-               unsigned long int sizeR;
+               unsigned long long sizeR;
                
                //get num bytes in file
                rFile = fopen (rfilename.c_str(),"rb");
@@ -1290,7 +1400,7 @@ int SeqErrorCommand::setLines(string filename, string qfilename, string rfilenam
                fastaFilePos.push_back(0); qfileFilePos.push_back(0);
                //get last file position of fastafile
                FILE * pFile;
-               unsigned long int size;
+               unsigned long long size;
                
                //get num bytes in file
                pFile = fopen (filename.c_str(),"rb");