]> git.donarmstrong.com Git - mothur.git/blobdiff - chimerapintailcommand.cpp
fixes while testing 1.33.0
[mothur.git] / chimerapintailcommand.cpp
index 40a161036de19d7cbff03bbeb5a631a90d1caa02..fca9f176d9e66c8452a8da5c451eba71ca76d6eb 100644 (file)
 #include "chimerapintailcommand.h"
 #include "pintail.h"
 
-//***************************************************************************************************************
 
+//**********************************************************************************************************************
+vector<string> ChimeraPintailCommand::setParameters(){ 
+       try {
+               CommandParameter ptemplate("reference", "InputTypes", "", "", "none", "none", "none","",false,true,true); parameters.push_back(ptemplate);
+               CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none","chimera-accnos",false,true,true); parameters.push_back(pfasta);
+               CommandParameter pconservation("conservation", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(pconservation);
+               CommandParameter pquantile("quantile", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(pquantile);
+               CommandParameter pfilter("filter", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(pfilter);
+               CommandParameter pwindow("window", "Number", "", "0", "", "", "","","",false,false); parameters.push_back(pwindow);
+               CommandParameter pincrement("increment", "Number", "", "25", "", "", "","",false,false); parameters.push_back(pincrement);
+               CommandParameter pmask("mask", "String", "", "", "", "", "","",false,false); parameters.push_back(pmask);
+               CommandParameter pprocessors("processors", "Number", "", "1", "", "", "","",false,false,true); parameters.push_back(pprocessors);
+               CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
+               CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
+               CommandParameter psave("save", "Boolean", "", "F", "", "", "","",false,false); parameters.push_back(psave);
+
+               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, "ChimeraPintailCommand", "setParameters");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+string ChimeraPintailCommand::getHelpString(){ 
+       try {
+               string helpString = "";
+               helpString += "The chimera.pintail command reads a fastafile and referencefile and outputs potentially chimeric sequences.\n";
+               helpString += "This command was created using the algorithms described in the 'At Least 1 in 20 16S rRNA Sequence Records Currently Held in the Public Repositories is Estimated To Contain Substantial Anomalies' paper by Kevin E. Ashelford 1, Nadia A. Chuzhanova 3, John C. Fry 1, Antonia J. Jones 2 and Andrew J. Weightman 1.\n";
+               helpString += "The chimera.pintail command parameters are fasta, reference, filter, mask, processors, window, increment, conservation and quantile.\n";
+               helpString += "The fasta parameter allows you to enter the fasta file containing your potentially chimeric sequences, and is required unless you have a valid current fasta file. \n";
+               helpString += "You may enter multiple fasta files by separating their names with dashes. ie. fasta=abrecovery.fasta-amzon.fasta \n";
+               helpString += "The reference parameter allows you to enter a reference file containing known non-chimeric sequences, and is required. \n";
+               helpString += "The filter parameter allows you to specify if you would like to apply a vertical and 50% soft filter. \n";
+               helpString += "The mask parameter allows you to specify a file containing one sequence you wish to use as a mask for the your sequences, by default no mask is applied.  You can apply an ecoli mask by typing, mask=default. \n";
+               helpString += "The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n";
+#ifdef USE_MPI
+               helpString += "When using MPI, the processors parameter is set to the number of MPI processes running. \n";
+#endif
+               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 += "The window parameter allows you to specify the window size for searching for chimeras, default=300. \n";
+               helpString += "The increment parameter allows you to specify how far you move each window while finding chimeric sequences, default=25.\n";
+               helpString += "The conservation parameter allows you to enter a frequency file containing the highest bases frequency at each place in the alignment.\n";
+               helpString += "The quantile parameter allows you to enter a file containing quantiles for a template files sequences, if you use the filter the quantile file generated becomes unique to the fasta file you used.\n";
+               helpString += "The chimera.pintail command should be in the following format: \n";
+               helpString += "chimera.pintail(fasta=yourFastaFile, reference=yourTemplate) \n";
+               helpString += "Example: chimera.pintail(fasta=AD.align, reference=silva.bacteria.fasta) \n";
+               helpString += "Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n";       
+               return helpString;
+       }
+       catch(exception& e) {
+               m->errorOut(e, "ChimeraPintailCommand", "getHelpString");
+               exit(1);
+       }
+}
+//**********************************************************************************************************************
+string ChimeraPintailCommand::getOutputPattern(string type) {
+    try {
+        string pattern = "";
+        
+        if (type == "chimera") {  pattern = "[filename],[tag],pintail.chimeras-[filename],pintail.chimeras"; } 
+        else if (type == "accnos") {  pattern = "[filename],[tag],pintail.accnos-[filename],pintail.accnos"; } 
+        else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
+        
+        return pattern;
+    }
+    catch(exception& e) {
+        m->errorOut(e, "ChimeraPintailCommand", "getOutputPattern");
+        exit(1);
+    }
+}
+//**********************************************************************************************************************
+ChimeraPintailCommand::ChimeraPintailCommand(){        
+       try {
+               abort = true; calledHelp = true;
+               setParameters();
+               vector<string> tempOutNames;
+               outputTypes["chimera"] = tempOutNames;
+               outputTypes["accnos"] = tempOutNames;
+        
+       }
+       catch(exception& e) {
+               m->errorOut(e, "ChimeraPintailCommand", "ChimeraPintailCommand");
+               exit(1);
+       }
+}
+//***************************************************************************************************************
 ChimeraPintailCommand::ChimeraPintailCommand(string option)  {
        try {
-               abort = false;
+               abort = false; calledHelp = false;   
+               rdb = ReferenceDB::getInstance();
                
                //allow user to run help
-               if(option == "help") { help(); abort = true; }
+               if(option == "help") { help(); abort = true; calledHelp = true; }
+               else if(option == "citation") { citation(); abort = true; calledHelp = true;}
                
                else {
-                       //valid paramters for this command
-                       string Array[] =  {"fasta","filter","processors","window" ,"increment","template","conservation","quantile","mask","outputdir","inputdir"};
-                       vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
+                       vector<string> myArray = setParameters();
                        
                        OptionParser parser(option);
                        map<string,string> parameters = parser.getParameters();
                        
-                       ValidParameters validParameter;
+                       ValidParameters validParameter("chimera.pintail");
                        map<string,string>::iterator it;
                        
                        //check to make sure all parameters are valid for command
@@ -35,31 +123,28 @@ ChimeraPintailCommand::ChimeraPintailCommand(string option)  {
                                if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
                        }
                        
+                       vector<string> tempOutNames;
+                       outputTypes["chimera"] = tempOutNames;
+                       outputTypes["accnos"] = 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);              
+                       inputDir = validParameter.validFile(parameters, "inputdir", false);             
                        if (inputDir == "not found"){   inputDir = "";          }
                        else {
                                string path;
-                               it = parameters.find("fasta");
-                               //user has given a template file
-                               if(it != parameters.end()){ 
-                                       path = hasPath(it->second);
-                                       //if the user has not given a path then, add inputdir. else leave path alone.
-                                       if (path == "") {       parameters["fasta"] = inputDir + it->second;            }
-                               }
-                               
-                               it = parameters.find("template");
+                               it = parameters.find("reference");
                                //user has given a template file
                                if(it != parameters.end()){ 
-                                       path = hasPath(it->second);
+                                       path = m->hasPath(it->second);
                                        //if the user has not given a path then, add inputdir. else leave path alone.
-                                       if (path == "") {       parameters["template"] = inputDir + it->second;         }
+                                       if (path == "") {       parameters["reference"] = inputDir + it->second;                }
                                }
                                
                                it = parameters.find("conservation");
                                //user has given a template file
                                if(it != parameters.end()){ 
-                                       path = hasPath(it->second);
+                                       path = m->hasPath(it->second);
                                        //if the user has not given a path then, add inputdir. else leave path alone.
                                        if (path == "") {       parameters["conservation"] = inputDir + it->second;             }
                                }
@@ -67,7 +152,7 @@ ChimeraPintailCommand::ChimeraPintailCommand(string option)  {
                                it = parameters.find("quantile");
                                //user has given a template file
                                if(it != parameters.end()){ 
-                                       path = hasPath(it->second);
+                                       path = m->hasPath(it->second);
                                        //if the user has not given a path then, add inputdir. else leave path alone.
                                        if (path == "") {       parameters["quantile"] = inputDir + it->second;         }
                                }
@@ -75,55 +160,191 @@ ChimeraPintailCommand::ChimeraPintailCommand(string option)  {
 
                        
                        //check for required parameters
-                       fastafile = validParameter.validFile(parameters, "fasta", true);
-                       if (fastafile == "not open") { abort = true; }
-                       else if (fastafile == "not found") { fastafile = ""; m->mothurOut("fasta is a required parameter for the chimera.pintail command."); m->mothurOutEndLine(); abort = true;  }    
+                       fastafile = validParameter.validFile(parameters, "fasta", false);
+                       if (fastafile == "not found") {                                 
+                               //if there is a current fasta file, use it
+                               string filename = m->getFastaFile(); 
+                               if (filename != "") { fastaFileNames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the fasta parameter."); m->mothurOutEndLine(); }
+                               else {  m->mothurOut("You have no current fastafile and the fasta parameter is required."); m->mothurOutEndLine(); abort = true; }
+                       }else { 
+                               m->splitAtDash(fastafile, fastaFileNames);
+                               
+                               //go through files and make sure they are good, if not, then disregard them
+                               for (int i = 0; i < fastaFileNames.size(); i++) {
+                                       
+                                       bool ignore = false;
+                                       if (fastaFileNames[i] == "current") { 
+                                               fastaFileNames[i] = m->getFastaFile(); 
+                                               if (fastaFileNames[i] != "") {  m->mothurOut("Using " + fastaFileNames[i] + " as input file for the fasta parameter where you had given current."); m->mothurOutEndLine(); }
+                                               else {  
+                                                       m->mothurOut("You have no current fastafile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
+                                                       //erase from file list
+                                                       fastaFileNames.erase(fastaFileNames.begin()+i);
+                                                       i--;
+                                               }
+                                       }
+                                       
+                                       if (!ignore) {
+                                       
+                                               if (inputDir != "") {
+                                                       string path = m->hasPath(fastaFileNames[i]);
+                                                       //if the user has not given a path then, add inputdir. else leave path alone.
+                                                       if (path == "") {       fastaFileNames[i] = inputDir + fastaFileNames[i];               }
+                                               }
+               
+                                               int ableToOpen;
+                                               ifstream in;
+                                               
+                                               ableToOpen = m->openInputFile(fastaFileNames[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(fastaFileNames[i]);
+                                                               m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
+                                                               ifstream in2;
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");
+                                                               in2.close();
+                                                               fastaFileNames[i] = tryPath;
+                                                       }
+                                               }
+                                               
+                                               if (ableToOpen == 1) {
+                                                       if (m->getOutputDir() != "") { //default path is set
+                                                               string tryPath = m->getOutputDir() + m->getSimpleName(fastaFileNames[i]);
+                                                               m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
+                                                               ifstream in2;
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");
+                                                               in2.close();
+                                                               fastaFileNames[i] = tryPath;
+                                                       }
+                                               }
+
+                                               in.close();
+                                               
+                                               if (ableToOpen == 1) { 
+                                                       m->mothurOut("Unable to open " + fastaFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); 
+                                                       //erase from file list
+                                                       fastaFileNames.erase(fastaFileNames.begin()+i);
+                                                       i--;
+                                               }else {
+                                                       m->setFastaFile(fastaFileNames[i]);
+                                               }
+                                       }
+                               }
+                               
+                               //make sure there is at least one valid file left
+                               if (fastaFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }
+                       }
                        
-                       //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 += hasPath(fastafile); //if user entered a file with a path then preserve it  
+                       string temp;
+                       temp = validParameter.validFile(parameters, "filter", false);                   if (temp == "not found") { temp = "F"; }
+                       filter = m->isTrue(temp);
+                       
+                       temp = validParameter.validFile(parameters, "processors", false);       if (temp == "not found"){       temp = m->getProcessors();      }
+                       m->setProcessors(temp);
+                       m->mothurConvert(temp, processors);
+                       
+                       temp = validParameter.validFile(parameters, "window", false);                   if (temp == "not found") { temp = "0"; }
+                       m->mothurConvert(temp, window);
+                       
+                       temp = validParameter.validFile(parameters, "increment", false);                if (temp == "not found") { temp = "25"; }
+                       m->mothurConvert(temp, increment);
+                       
+                       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();     
                        }
-
-                       templatefile = validParameter.validFile(parameters, "template", true);
-                       if (templatefile == "not open") { abort = true; }
-                       else if (templatefile == "not found") { templatefile = "";  m->mothurOut("template is a required parameter for the chimera.pintail command."); m->mothurOutEndLine(); abort = true;  }
                        
-                       consfile = validParameter.validFile(parameters, "conservation", true);
-                       if (consfile == "not open") { abort = true; }
-                       else if (consfile == "not found") { consfile = "";  }   
+                       //this has to go after save so that if the user sets save=t and provides no reference we abort
+                       templatefile = validParameter.validFile(parameters, "reference", true);
+                       if (templatefile == "not found") { 
+                               //check for saved reference sequences
+                               if (rdb->referenceSeqs.size() != 0) {
+                                       templatefile = "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 (templatefile == "not open") { abort = true; } 
+                       else {  if (save) {     rdb->setSavedReference(templatefile);   }       }
                        
-                       quanfile = validParameter.validFile(parameters, "quantile", true);
-                       if (quanfile == "not open") { abort = true; }
-                       else if (quanfile == "not found") { quanfile = "";  }
                        
                        maskfile = validParameter.validFile(parameters, "mask", false);
                        if (maskfile == "not found") { maskfile = "";  }        
                        else if (maskfile != "default")  { 
                                if (inputDir != "") {
-                                       string path = hasPath(maskfile);
+                                       string path = m->hasPath(maskfile);
                                        //if the user has not given a path then, add inputdir. else leave path alone.
                                        if (path == "") {       maskfile = inputDir + maskfile;         }
                                }
 
                                ifstream in;
-                               int     ableToOpen = openInputFile(maskfile, in);
-                               if (ableToOpen == 1) { abort = true; }
+                               int     ableToOpen = m->openInputFile(maskfile, in, "no error");
+                               if (ableToOpen == 1) { 
+                                       if (m->getDefaultPath() != "") { //default path is set
+                                                       string tryPath = m->getDefaultPath() + m->getSimpleName(maskfile);
+                                                       m->mothurOut("Unable to open " + maskfile + ". Trying default " + tryPath); m->mothurOutEndLine();
+                                                       ifstream in2;
+                                                       ableToOpen = m->openInputFile(tryPath, in2, "noerror");
+                                                       in2.close();
+                                                       maskfile = tryPath;
+                                       }
+                               }
+                               
+                               if (ableToOpen == 1) {
+                                               if (m->getOutputDir() != "") { //default path is set
+                                                       string tryPath = m->getOutputDir() + m->getSimpleName(maskfile);
+                                                       m->mothurOut("Unable to open " + maskfile + ". Trying output directory " + tryPath); m->mothurOutEndLine();
+                                                       ifstream in2;
+                                                       ableToOpen = m->openInputFile(tryPath, in2, "noerror");
+                                                       in2.close();
+                                                       maskfile = tryPath;
+                                               }
+                               }
+                               
                                in.close();
+                                       
+                               if (ableToOpen == 1) { 
+                                               m->mothurOut("Unable to open " + maskfile + "."); m->mothurOutEndLine(); 
+                                               abort = true;
+                               }
                        }
-                                               
-                       string temp;
-                       temp = validParameter.validFile(parameters, "filter", false);                   if (temp == "not found") { temp = "F"; }
-                       filter = isTrue(temp);
-                       
-                       temp = validParameter.validFile(parameters, "processors", false);               if (temp == "not found") { temp = "1"; }
-                       convert(temp, processors);
+
                        
-                       temp = validParameter.validFile(parameters, "window", false);                   if (temp == "not found") { temp = "0"; }
-                       convert(temp, window);
+                       //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 = ""; }
+               
+                       consfile = validParameter.validFile(parameters, "conservation", true);
+                       if (consfile == "not open") { abort = true; }
+                       else if (consfile == "not found") { 
+                               consfile = "";  
+                               //check for consfile
+                               string tempConsFile = m->getRootName(inputDir + m->getSimpleName(templatefile)) + "freq";
+                               ifstream FileTest(tempConsFile.c_str());
+                               if(FileTest){   
+                                       bool GoodFile = m->checkReleaseVersion(FileTest, m->getVersion());
+                                       if (GoodFile) {  
+                                               m->mothurOut("I found " + tempConsFile + " in your input file directory. I will use it to save time."); m->mothurOutEndLine();  consfile = tempConsFile;  FileTest.close();     
+                                       }
+                               }else {
+                                       string tempConsFile = m->getDefaultPath() + m->getRootName(m->getSimpleName(templatefile)) + "freq";
+                                       ifstream FileTest2(tempConsFile.c_str());
+                                       if(FileTest2){  
+                                               bool GoodFile = m->checkReleaseVersion(FileTest2, m->getVersion());
+                                               if (GoodFile) {  
+                                                       m->mothurOut("I found " + tempConsFile + " in your input file directory. I will use it to save time."); m->mothurOutEndLine();  consfile = tempConsFile;  FileTest2.close();    
+                                               }
+                                       }
+                               }
+                       }       
                        
-                       temp = validParameter.validFile(parameters, "increment", false);                if (temp == "not found") { temp = "25"; }
-                       convert(temp, increment);
+                       quanfile = validParameter.validFile(parameters, "quantile", true);
+                       if (quanfile == "not open") { abort = true; }
+                       else if (quanfile == "not found") { quanfile = ""; }
                }
        }
        catch(exception& e) {
@@ -131,291 +352,233 @@ ChimeraPintailCommand::ChimeraPintailCommand(string option)  {
                exit(1);
        }
 }
-//**********************************************************************************************************************
-
-void ChimeraPintailCommand::help(){
-       try {
-       
-               m->mothurOut("The chimera.pintail command reads a fastafile and templatefile and outputs potentially chimeric sequences.\n");
-               m->mothurOut("This command was created using the algorythms described in the 'At Least 1 in 20 16S rRNA Sequence Records Currently Held in the Public Repositories is Estimated To Contain Substantial Anomalies' paper by Kevin E. Ashelford 1, Nadia A. Chuzhanova 3, John C. Fry 1, Antonia J. Jones 2 and Andrew J. Weightman 1.\n");
-               m->mothurOut("The chimera.pintail command parameters are fasta, template, filter, mask, processors, window, increment, conservation and quantile.\n");
-               m->mothurOut("The fasta parameter allows you to enter the fasta file containing your potentially chimeric sequences, and is required. \n");
-               m->mothurOut("The template parameter allows you to enter a template file containing known non-chimeric sequences, and is required. \n");
-               m->mothurOut("The filter parameter allows you to specify if you would like to apply a vertical and 50% soft filter. \n");
-               m->mothurOut("The mask parameter allows you to specify a file containing one sequence you wish to use as a mask for the your sequences, by default no mask is applied.  You can apply an ecoli mask by typing, mask=default. \n");
-               m->mothurOut("The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n");
-               #ifdef USE_MPI
-               m->mothurOut("When using MPI, the processors parameter is set to the number of MPI processes running. \n");
-               #endif
-               m->mothurOut("The window parameter allows you to specify the window size for searching for chimeras, default=1/4 sequence length. \n");
-               m->mothurOut("The increment parameter allows you to specify how far you move each window while finding chimeric sequences, default=25.\n");
-               m->mothurOut("The conservation parameter allows you to enter a frequency file containing the highest bases frequency at each place in the alignment.\n");
-               m->mothurOut("The quantile parameter allows you to enter a file containing quantiles for a template files sequences, if you use the filter the quantile file generated becomes unique to the fasta file you used.\n");
-               m->mothurOut("The chimera.pintail command should be in the following format: \n");
-               m->mothurOut("chimera.seqs(fasta=yourFastaFile, filter=yourFilter, correction=yourCorrection, processors=yourProcessors, method=bellerophon) \n");
-               m->mothurOut("Example: chimera.seqs(fasta=AD.align, filter=True, correction=true, method=bellerophon, window=200) \n");
-               m->mothurOut("Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n\n");     
-       }
-       catch(exception& e) {
-               m->errorOut(e, "ChimeraPintailCommand", "help");
-               exit(1);
-       }
-}
-
-//***************************************************************************************************************
-
-ChimeraPintailCommand::~ChimeraPintailCommand(){       /*      do nothing      */      }
-
 //***************************************************************************************************************
 
 int ChimeraPintailCommand::execute(){
        try{
                
-               if (abort == true) { return 0; }
-               
-               int start = time(NULL); 
-               
-               chimera = new Pintail(fastafile, templatefile, filter, processors, maskfile, consfile, quanfile, window, increment, outputDir);
-               
-               //set user options
-               if (maskfile == "default") { m->mothurOut("I am using the default 236627 EU009184.1 Shigella dysenteriae str. FBD013."); m->mothurOutEndLine();  }
+               if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
                
+               for (int s = 0; s < fastaFileNames.size(); s++) {
+                               
+                       m->mothurOut("Checking sequences from " + fastaFileNames[s] + " ..." ); m->mothurOutEndLine();
 
-               string outputFileName, accnosFileName;
-               if (maskfile != "") {
-                       outputFileName = outputDir + getRootName(getSimpleName(fastafile)) + maskfile + ".pintail.chimeras";
-                       accnosFileName = outputDir + getRootName(getSimpleName(fastafile)) + maskfile + ".pintail.accnos";
-               }else {
-                       outputFileName = outputDir + getRootName(getSimpleName(fastafile))  + "pintail.chimeras";
-                       accnosFileName = outputDir + getRootName(getSimpleName(fastafile))  + "pintail.accnos";
-               }
-               bool hasAccnos = true;
-               
-               if (m->control_pressed) { delete chimera;       return 0;       }
-               
-               if (chimera->getUnaligned()) { 
-                       m->mothurOut("Your template sequences are different lengths, please correct."); m->mothurOutEndLine(); 
-                       delete chimera;
-                       return 0; 
-               }
-               templateSeqsLength = chimera->getLength();
-       
-       #ifdef USE_MPI
-               int pid, end, numSeqsPerProcessor; 
-                       int tag = 2001;
-                       vector<long> MPIPos;
-                       MPIWroteAccnos = false;
-                       
-                       MPI_Status status; 
-                       MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
-                       MPI_Comm_size(MPI_COMM_WORLD, &processors); 
-
-                       MPI_File inMPI;
-                       MPI_File outMPI;
-                       MPI_File outMPIAccnos;
-                       
-                       int outMode=MPI_MODE_CREATE|MPI_MODE_WRONLY; 
-                       int inMode=MPI_MODE_RDONLY; 
+                       int start = time(NULL); 
                        
-                       char* outFilename = new char[outputFileName.length()];\r
-                       memcpy(outFilename, outputFileName.c_str(), outputFileName.length());
+                       //set user options
+                       if (maskfile == "default") { m->mothurOut("I am using the default 236627 EU009184.1 Shigella dysenteriae str. FBD013."); m->mothurOutEndLine();  }
                        
-                       char* outAccnosFilename = new char[accnosFileName.length()];\r
-                       memcpy(outAccnosFilename, accnosFileName.c_str(), accnosFileName.length());
-
-                       char* inFileName = new char[fastafile.length()];\r
-                       memcpy(inFileName, fastafile.c_str(), fastafile.length());
-
-                       MPI_File_open(MPI_COMM_WORLD, inFileName, inMode, MPI_INFO_NULL, &inMPI);  //comm, filename, mode, info, filepointer
-                       MPI_File_open(MPI_COMM_WORLD, outFilename, outMode, MPI_INFO_NULL, &outMPI);
-                       MPI_File_open(MPI_COMM_WORLD, outAccnosFilename, outMode, MPI_INFO_NULL, &outMPIAccnos);
+                       //check for quantile to save the time
+                       string baseName = templatefile;
+                       if (templatefile == "saved") { baseName = rdb->getSavedReference(); }
                        
-                       delete inFileName;
-                       delete outFilename;
-                       delete outAccnosFilename;
-
-                       if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  delete chimera; return 0;  }
-
-                       if (pid == 0) { //you are the root process 
-                                                       
-                               MPIPos = setFilePosFasta(fastafile, numSeqs); //fills MPIPos, returns numSeqs
-                               
-                               //send file positions to all processes
-                               MPI_Bcast(&numSeqs, 1, MPI_INT, 0, MPI_COMM_WORLD);  //send numSeqs
-                               MPI_Bcast(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, MPI_COMM_WORLD); //send file pos        
-                               
-                               //figure out how many sequences you have to align
-                               numSeqsPerProcessor = numSeqs / processors;
-                               if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
-                               int startIndex =  pid * numSeqsPerProcessor;
+                       string tempQuan = "";
+                       if ((!filter) && (maskfile == "")) {
+                               tempQuan = inputDir + m->getRootName(m->getSimpleName(baseName)) + "pintail.quan";
+                       }else if ((!filter) && (maskfile != "")) { 
+                               tempQuan = inputDir + m->getRootName(m->getSimpleName(baseName)) + "pintail.masked.quan";
+                       }else if ((filter) && (maskfile != "")) { 
+                               tempQuan = inputDir + m->getRootName(m->getSimpleName(baseName)) + "pintail.filtered." + m->getSimpleName(m->getRootName(fastaFileNames[s])) + "masked.quan";
+                       }else if ((filter) && (maskfile == "")) { 
+                               tempQuan = inputDir + m->getRootName(m->getSimpleName(baseName)) + "pintail.filtered." + m->getSimpleName(m->getRootName(fastaFileNames[s])) + "quan";
+                       }
                        
-                               //align your part
-                               driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
-                               
-                               if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  remove(outputFileName.c_str());  remove(accnosFileName.c_str());  delete chimera; return 0;  }
-                               
-                               for (int i = 1; i < processors; i++) {
-                                       bool tempResult;
-                                       MPI_Recv(&tempResult, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &status);
-                                       if (tempResult != 0) { MPIWroteAccnos = true; }
+                       ifstream FileTest(tempQuan.c_str());
+                       if(FileTest){   
+                               bool GoodFile = m->checkReleaseVersion(FileTest, m->getVersion());
+                               if (GoodFile) {  
+                                       m->mothurOut("I found " + tempQuan + " in your input file directory. I will use it to save time."); m->mothurOutEndLine();  quanfile = tempQuan;  FileTest.close();     
+                               }
+                       }else {
+                               string tryPath = m->getDefaultPath();
+                               string tempQuan = "";
+                               if ((!filter) && (maskfile == "")) {
+                                       tempQuan = tryPath + m->getRootName(m->getSimpleName(baseName)) + "pintail.quan";
+                               }else if ((!filter) && (maskfile != "")) { 
+                                       tempQuan = tryPath + m->getRootName(m->getSimpleName(baseName)) + "pintail.masked.quan";
+                               }else if ((filter) && (maskfile != "")) { 
+                                       tempQuan = tryPath + m->getRootName(m->getSimpleName(baseName)) + "pintail.filtered." + m->getSimpleName(m->getRootName(fastaFileNames[s])) + "masked.quan";
+                               }else if ((filter) && (maskfile == "")) { 
+                                       tempQuan = tryPath + m->getRootName(m->getSimpleName(baseName)) + "pintail.filtered." + m->getSimpleName(m->getRootName(fastaFileNames[s])) + "quan";
                                }
-                       }else{ //you are a child process
-                               MPI_Bcast(&numSeqs, 1, MPI_INT, 0, MPI_COMM_WORLD); //get numSeqs
-                               MPIPos.resize(numSeqs+1);
-                               MPI_Bcast(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, MPI_COMM_WORLD); //get file positions
-                               
-                               //figure out how many sequences you have to align
-                               numSeqsPerProcessor = numSeqs / processors;
-                               if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
-                               int startIndex =  pid * numSeqsPerProcessor;
-                               
-                               //align your part
-                               driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
                                
-                               if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  delete chimera; return 0;  }
-
-                               MPI_Send(&MPIWroteAccnos, 1, MPI_INT, 0, tag, MPI_COMM_WORLD); 
+                               ifstream FileTest2(tempQuan.c_str());
+                               if(FileTest2){  
+                                       bool GoodFile = m->checkReleaseVersion(FileTest2, m->getVersion());
+                                       if (GoodFile) {  
+                                               m->mothurOut("I found " + tempQuan + " in your input file directory. I will use it to save time."); m->mothurOutEndLine();  quanfile = tempQuan;  FileTest2.close();    
+                                       }
+                               }
                        }
+                       chimera = new Pintail(fastaFileNames[s], templatefile, filter, processors, maskfile, consfile, quanfile, window, increment, outputDir);
                        
-                       //close files 
-                       MPI_File_close(&inMPI);
-                       MPI_File_close(&outMPI);
-                       MPI_File_close(&outMPIAccnos);
-                       
-                       //delete accnos file if blank
-                       if (pid == 0) {
-                               if (!MPIWroteAccnos) { 
-                                       //MPI_Info info;
-                                       //MPI_File_delete(outAccnosFilename, info);
-                                       hasAccnos = false;      
-                                       remove(accnosFileName.c_str()); 
-                               }
+                       if (outputDir == "") { outputDir = m->hasPath(fastaFileNames[s]);  }//if user entered a file with a path then preserve it
+                       string outputFileName, accnosFileName;
+            map<string, string> variables;
+            variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[s]));
+                       if (maskfile != "") { variables["[tag]"] = m->getSimpleName(m->getRootName(maskfile)); }
+            outputFileName = getOutputFileName("chimera", variables);
+            accnosFileName = getOutputFileName("accnos", variables);
+                       
+                       
+                       if (m->control_pressed) { delete chimera; for (int j = 0; j < outputNames.size(); j++) {        m->mothurRemove(outputNames[j]);        }  return 0;    }
+                       
+                       if (chimera->getUnaligned()) { 
+                               m->mothurOut("Your template sequences are different lengths, please correct."); m->mothurOutEndLine(); 
+                               delete chimera;
+                               return 0; 
                        }
-
-       #else
-       
-               //break up file
-               #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
-                       if(processors == 1){
-                               ifstream inFASTA;
-                               openInputFile(fastafile, inFASTA);
-                               numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
-                               inFASTA.close();
+                       templateSeqsLength = chimera->getLength();
+               
+               #ifdef USE_MPI
+                       int pid, numSeqsPerProcessor; 
+                               int tag = 2001;
+                               vector<unsigned long long> MPIPos;
                                
-                               lines.push_back(new linePair(0, numSeqs));
+                               MPI_Status status; 
+                               MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
+                               MPI_Comm_size(MPI_COMM_WORLD, &processors); 
+
+                               MPI_File inMPI;
+                               MPI_File outMPI;
+                               MPI_File outMPIAccnos;
                                
-                               driver(lines[0], outputFileName, fastafile, accnosFileName);
+                               int outMode=MPI_MODE_CREATE|MPI_MODE_WRONLY; 
+                               int inMode=MPI_MODE_RDONLY; 
                                
-                               if (m->control_pressed) { 
-                                       remove(outputFileName.c_str()); 
-                                       remove(accnosFileName.c_str());
-                                       for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
-                                       delete chimera;
-                                       return 0;
-                               }
+                               char outFilename[1024];
+                               strcpy(outFilename, outputFileName.c_str());
                                
-                               //delete accnos file if its blank 
-                               if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
-                                                               
-                       }else{
-                               vector<int> positions;
-                               processIDS.resize(0);
+                               char outAccnosFilename[1024];
+                               strcpy(outAccnosFilename, accnosFileName.c_str());
                                
-                               ifstream inFASTA;
-                               openInputFile(fastafile, inFASTA);
+                               char inFileName[1024];
+                               strcpy(inFileName, fastaFileNames[s].c_str());
+
+                               MPI_File_open(MPI_COMM_WORLD, inFileName, inMode, MPI_INFO_NULL, &inMPI);  //comm, filename, mode, info, filepointer
+                               MPI_File_open(MPI_COMM_WORLD, outFilename, outMode, MPI_INFO_NULL, &outMPI);
+                               MPI_File_open(MPI_COMM_WORLD, outAccnosFilename, outMode, MPI_INFO_NULL, &outMPIAccnos);
                                
-                               string input;
-                               while(!inFASTA.eof()){
-                                       input = getline(inFASTA);
-                                       if (input.length() != 0) {
-                                               if(input[0] == '>'){    long int pos = inFASTA.tellg(); positions.push_back(pos - input.length() - 1);  }
+                               if (m->control_pressed) { outputTypes.clear();  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  for (int j = 0; j < outputNames.size(); j++) {      m->mothurRemove(outputNames[j]);        }  delete chimera; return 0;  }
+
+                               if (pid == 0) { //you are the root process 
+                                                               
+                                       MPIPos = m->setFilePosFasta(fastaFileNames[s], numSeqs); //fills MPIPos, returns numSeqs
+                                       
+                                       //send file positions to all processes
+                                       for(int i = 1; i < processors; i++) { 
+                                               MPI_Send(&numSeqs, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
+                                               MPI_Send(&MPIPos[0], (numSeqs+1), MPI_LONG, i, tag, MPI_COMM_WORLD);
                                        }
-                               }
-                               inFASTA.close();
-                               
-                               numSeqs = positions.size();
-                               
-                               int numSeqsPerProcessor = numSeqs / processors;
+                                       
+                                       //figure out how many sequences you have to align
+                                       numSeqsPerProcessor = numSeqs / processors;
+                                       int startIndex =  pid * numSeqsPerProcessor;
+                                       if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
                                
-                               for (int i = 0; i < processors; i++) {
-                                       long int startPos = positions[ i * numSeqsPerProcessor ];
-                                       if(i == processors - 1){
-                                               numSeqsPerProcessor = numSeqs - i * numSeqsPerProcessor;
-                                       }
-                                       lines.push_back(new linePair(startPos, numSeqsPerProcessor));
+                                       //do your part
+                                       driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
+                                       
+                                       if (m->control_pressed) { outputTypes.clear();  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  m->mothurRemove(outputFileName);  m->mothurRemove(accnosFileName);  for (int j = 0; j < outputNames.size(); j++) {  m->mothurRemove(outputNames[j]);        }  delete chimera; return 0;  }
+                                       
+                               }else{ //you are a child process
+                                       MPI_Recv(&numSeqs, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
+                                       MPIPos.resize(numSeqs+1);
+                                       MPI_Recv(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, tag, MPI_COMM_WORLD, &status);
+                                       
+                                       //figure out how many sequences you have to align
+                                       numSeqsPerProcessor = numSeqs / processors;
+                                       int startIndex =  pid * numSeqsPerProcessor;
+                                       if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
+                                       
+                                       //do your part
+                                       driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
+                                       
+                                       if (m->control_pressed) { outputTypes.clear();  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  for (int j = 0; j < outputNames.size(); j++) {      m->mothurRemove(outputNames[j]);        }  delete chimera; return 0;  }
                                }
                                
-                               
-                               createProcesses(outputFileName, fastafile, accnosFileName); 
+                               //close files 
+                               MPI_File_close(&inMPI);
+                               MPI_File_close(&outMPI);
+                               MPI_File_close(&outMPIAccnos);
+                               MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
+               #else
+                                               
+                       //break up file
+                       #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+                               vector<unsigned long long> positions = m->divideFile(fastaFileNames[s], processors);
                        
-                               rename((outputFileName + toString(processIDS[0]) + ".temp").c_str(), outputFileName.c_str());
+                               for (int i = 0; i < (positions.size()-1); i++) {
+                                       lines.push_back(new linePair(positions[i], positions[(i+1)]));
+                               }       
+                       
+                               if(processors == 1){
+               
+                                       numSeqs = driver(lines[0], outputFileName, fastaFileNames[s], accnosFileName);
                                        
-                               //append output files
-                               for(int i=1;i<processors;i++){
-                                       appendFiles((outputFileName + toString(processIDS[i]) + ".temp"), outputFileName);
-                                       remove((outputFileName + toString(processIDS[i]) + ".temp").c_str());
-                               }
-                               
-                               vector<string> nonBlankAccnosFiles;
-                               //delete blank accnos files generated with multiple processes
-                               for(int i=0;i<processors;i++){  
-                                       if (!(isBlank(accnosFileName + toString(processIDS[i]) + ".temp"))) {
-                                               nonBlankAccnosFiles.push_back(accnosFileName + toString(processIDS[i]) + ".temp");
-                                       }else { remove((accnosFileName + toString(processIDS[i]) + ".temp").c_str());  }
-                               }
+                                       if (m->control_pressed) { outputTypes.clear(); m->mothurRemove(outputFileName); m->mothurRemove(accnosFileName); for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]);        } for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear(); delete chimera; return 0; }
+                                       
+                               }else{
+                                       processIDS.resize(0);
+                                       
+                                       numSeqs = createProcesses(outputFileName, fastaFileNames[s], accnosFileName); 
                                
-                               //append accnos files
-                               if (nonBlankAccnosFiles.size() != 0) { 
-                                       rename(nonBlankAccnosFiles[0].c_str(), accnosFileName.c_str());
+                                       rename((outputFileName + toString(processIDS[0]) + ".temp").c_str(), outputFileName.c_str());
+                                       rename((accnosFileName + toString(processIDS[0]) + ".temp").c_str(), accnosFileName.c_str());
+                                               
+                                       //append output files
+                                       for(int i=1;i<processors;i++){
+                                               m->appendFiles((outputFileName + toString(processIDS[i]) + ".temp"), outputFileName);
+                                               m->mothurRemove((outputFileName + toString(processIDS[i]) + ".temp"));
+                                       }
                                        
-                                       for (int h=1; h < nonBlankAccnosFiles.size(); h++) {
-                                               appendFiles(nonBlankAccnosFiles[h], accnosFileName);
-                                               remove(nonBlankAccnosFiles[h].c_str());
+                                       //append output files
+                                       for(int i=1;i<processors;i++){
+                                               m->appendFiles((accnosFileName + toString(processIDS[i]) + ".temp"), accnosFileName);
+                                               m->mothurRemove((accnosFileName + toString(processIDS[i]) + ".temp"));
+                                       }
+                                                                               
+                                       if (m->control_pressed) { 
+                                               m->mothurRemove(outputFileName); 
+                                               m->mothurRemove(accnosFileName);
+                                               for (int j = 0; j < outputNames.size(); j++) {  m->mothurRemove(outputNames[j]);        } outputTypes.clear();
+                                               for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
+                                               delete chimera;
+                                               return 0;
                                        }
-                               }else{ hasAccnos = false;  }
-                               
-                               if (m->control_pressed) { 
-                                       remove(outputFileName.c_str()); 
-                                       remove(accnosFileName.c_str());
-                                       for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
-                                       delete chimera;
-                                       return 0;
                                }
-                       }
 
-               #else
-                       ifstream inFASTA;
-                       openInputFile(fastafile, inFASTA);
-                       numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
-                       inFASTA.close();
-                       lines.push_back(new linePair(0, numSeqs));
-                       
-                       driver(lines[0], outputFileName, fastafile, accnosFileName);
-                       
-                       if (m->control_pressed) { 
-                                       remove(outputFileName.c_str()); 
-                                       remove(accnosFileName.c_str());
-                                       for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
-                                       delete chimera;
-                                       return 0;
-                       }
+                       #else
+                               lines.push_back(new linePair(0, 1000));
+                               numSeqs = driver(lines[0], outputFileName, fastaFileNames[s], accnosFileName);
+                               
+                               if (m->control_pressed) { outputTypes.clear(); m->mothurRemove(outputFileName); m->mothurRemove(accnosFileName); for (int j = 0; j < outputNames.size(); j++) { m->mothurRemove(outputNames[j]);        } for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear(); delete chimera; return 0; }
+                       #endif
                        
-                       //delete accnos file if its blank 
-                       if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
-               #endif
+               #endif  
                
-       #endif  
-       
-               delete chimera;
-               for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
+                       delete chimera;
+                       for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
+                       
+                       outputNames.push_back(outputFileName); outputTypes["chimera"].push_back(outputFileName);
+                       outputNames.push_back(accnosFileName); outputTypes["accnos"].push_back(accnosFileName);
+                       
+                       m->mothurOutEndLine();
+                       m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine();
+               }
+               
+               //set accnos file as new current accnosfile
+               string current = "";
+               itTypes = outputTypes.find("accnos");
+               if (itTypes != outputTypes.end()) {
+                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setAccnosFile(current); }
+               }
                
                m->mothurOutEndLine();
                m->mothurOut("Output File Names: "); m->mothurOutEndLine();
-               m->mothurOut(outputFileName); m->mothurOutEndLine();    
-               if (hasAccnos) {  m->mothurOut(accnosFileName); m->mothurOutEndLine();  }
+               for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }       
                m->mothurOutEndLine();
-               m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine();
-               
+                       
                return 0;
                
        }
@@ -426,24 +589,27 @@ int ChimeraPintailCommand::execute(){
 }
 //**********************************************************************************************************************
 
-int ChimeraPintailCommand::driver(linePair* line, string outputFName, string filename, string accnos){
+int ChimeraPintailCommand::driver(linePair* filePos, string outputFName, string filename, string accnos){
        try {
                ofstream out;
-               openOutputFile(outputFName, out);
+               m->openOutputFile(outputFName, out);
                
                ofstream out2;
-               openOutputFile(accnos, out2);
+               m->openOutputFile(accnos, out2);
                
                ifstream inFASTA;
-               openInputFile(filename, inFASTA);
+               m->openInputFile(filename, inFASTA);
 
-               inFASTA.seekg(line->start);
-               
-               for(int i=0;i<line->numSeqs;i++){
-               
+               inFASTA.seekg(filePos->start);
+
+               bool done = false;
+               int count = 0;
+       
+               while (!done) {
+                               
                        if (m->control_pressed) {       return 1;       }
                
-                       Sequence* candidateSeq = new Sequence(inFASTA);  gobble(inFASTA);
+                       Sequence* candidateSeq = new Sequence(inFASTA);  m->gobble(inFASTA);
                                
                        if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
                                
@@ -458,20 +624,28 @@ int ChimeraPintailCommand::driver(linePair* line, string outputFName, string fil
                                        //print results
                                        chimera->print(out, out2);
                                }
+                               count++;
                        }
                        delete candidateSeq;
                        
+                       #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+                               unsigned long long pos = inFASTA.tellg();
+                               if ((pos == -1) || (pos >= filePos->end)) { break; }
+                       #else
+                               if (inFASTA.eof()) { break; }
+                       #endif
+                       
                        //report progress
-                       if((i+1) % 100 == 0){   m->mothurOut("Processing sequence: " + toString(i+1)); m->mothurOutEndLine();           }
+                       if((count) % 100 == 0){ m->mothurOutJustToScreen("Processing sequence: " + toString(count) + "\n");             }
                }
                //report progress
-               if((line->numSeqs) % 100 != 0){ m->mothurOut("Processing sequence: " + toString(line->numSeqs)); m->mothurOutEndLine();         }
+               if((count) % 100 != 0){ m->mothurOutJustToScreen("Processing sequence: " + toString(count) + "\n");             }
                
                out.close();
                out2.close();
                inFASTA.close();
                                
-               return 0;
+               return count;
        }
        catch(exception& e) {
                m->errorOut(e, "ChimeraPintailCommand", "driver");
@@ -480,7 +654,7 @@ int ChimeraPintailCommand::driver(linePair* line, string outputFName, string fil
 }
 //**********************************************************************************************************************
 #ifdef USE_MPI
-int ChimeraPintailCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_File& outMPI, MPI_File& outAccMPI, vector<long>& MPIPos){
+int ChimeraPintailCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_File& outMPI, MPI_File& outAccMPI, vector<unsigned long long>& MPIPos){
        try {
                                
                MPI_Status status; 
@@ -502,7 +676,7 @@ int ChimeraPintailCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_Fi
                        istringstream iss (tempBuf,istringstream::in);
                        delete buf4;
 
-                       Sequence* candidateSeq = new Sequence(iss);  gobble(iss);
+                       Sequence* candidateSeq = new Sequence(iss);  m->gobble(iss);
                                
                        if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
                                
@@ -515,17 +689,16 @@ int ChimeraPintailCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_Fi
                                        if (m->control_pressed) {       delete candidateSeq; return 1;  }
                
                                        //print results
-                                       bool isChimeric = chimera->print(outMPI, outAccMPI);
-                                       if (isChimeric) { MPIWroteAccnos = true;  }
+                                       chimera->print(outMPI, outAccMPI);
                                }
                        }
                        delete candidateSeq;
                        
                        //report progress
-                       if((i+1) % 100 == 0){  cout << "Processing sequence: " << (i+1) << endl;        m->mothurOutJustToLog("Processing sequence: " + toString(i+1) + "\n");          }
+                       if((i+1) % 100 == 0){  cout << "Processing sequence: " << (i+1) << endl;                        }
                }
                //report progress
-               if(num % 100 != 0){             cout << "Processing sequence: " << num << endl; m->mothurOutJustToLog("Processing sequence: " + toString(num) + "\n");  }
+               if(num % 100 != 0){             cout << "Processing sequence: " << num << endl;         }
                
                                
                return 0;
@@ -541,9 +714,9 @@ int ChimeraPintailCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_Fi
 
 int ChimeraPintailCommand::createProcesses(string outputFileName, string filename, string accnos) {
        try {
-#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
                int process = 0;
-               //              processIDS.resize(0);
+               int num = 0;
                
                //loop through and create all the processes you want
                while (process != processors) {
@@ -553,9 +726,21 @@ int ChimeraPintailCommand::createProcesses(string outputFileName, string filenam
                                processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
                                process++;
                        }else if (pid == 0){
-                               driver(lines[process], outputFileName + toString(getpid()) + ".temp", filename, accnos + toString(getpid()) + ".temp");
+                               num = driver(lines[process], outputFileName + toString(getpid()) + ".temp", filename, accnos + toString(getpid()) + ".temp");
+                               
+                               //pass numSeqs to parent
+                               ofstream out;
+                               string tempFile = outputFileName + toString(getpid()) + ".num.temp";
+                               m->openOutputFile(tempFile, out);
+                               out << num << endl;
+                               out.close();
+
+                               exit(0);
+                       }else { 
+                               m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
+                               for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
                                exit(0);
-                       }else { m->mothurOut("unable to spawn the necessary processes."); m->mothurOutEndLine(); exit(0); }
+                       }
                }
                
                //force parent to wait until all the processes are done
@@ -564,7 +749,15 @@ int ChimeraPintailCommand::createProcesses(string outputFileName, string filenam
                        wait(&temp);
                }
                
-               return 0;
+               for (int i = 0; i < processIDS.size(); i++) {
+                       ifstream in;
+                       string tempFile =  outputFileName + toString(processIDS[i]) + ".num.temp";
+                       m->openInputFile(tempFile, in);
+                       if (!in.eof()) { int tempNum = 0; in >> tempNum; num += tempNum; }
+                       in.close(); m->mothurRemove(tempFile);
+               }
+               
+               return num;
 #endif         
        }
        catch(exception& e) {