]> git.donarmstrong.com Git - mothur.git/blobdiff - trimseqscommand.cpp
fixed bug in unifrac commands with unrooted trees
[mothur.git] / trimseqscommand.cpp
index 7267b91da4d2ec193508579e8226c33d6758e9c7..dd5bf3460debcc3e2fd5b6af736b0e123c7890ae 100644 (file)
@@ -14,7 +14,7 @@
 
 vector<string> TrimSeqsCommand::getValidParameters(){  
        try {
-               string Array[] =  {"fasta", "flip", "oligos", "maxambig", "maxhomop", "group","minlength", "maxlength", "qfile", 
+               string Array[] =  {"fasta", "flip", "oligos", "maxambig", "maxhomop","minlength", "maxlength", "qfile", 
                                                                        "qthreshold", "qwindowaverage", "qstepsize", "qwindowsize", "qaverage", "rollaverage",
                                                                        "keepfirst", "removelast",
                                                                        "allfiles", "qtrim","tdiffs", "pdiffs", "bdiffs", "processors", "outputdir","inputdir"};
@@ -31,12 +31,10 @@ vector<string> TrimSeqsCommand::getValidParameters(){
 
 TrimSeqsCommand::TrimSeqsCommand(){    
        try {
-               abort = true;
-               //initialize outputTypes
+               abort = true; calledHelp = true; 
                vector<string> tempOutNames;
                outputTypes["fasta"] = tempOutNames;
                outputTypes["qual"] = tempOutNames;
-               outputTypes["group"] = tempOutNames;
        }
        catch(exception& e) {
                m->errorOut(e, "TrimSeqsCommand", "TrimSeqsCommand");
@@ -76,15 +74,15 @@ vector<string> TrimSeqsCommand::getRequiredFiles(){
 TrimSeqsCommand::TrimSeqsCommand(string option)  {
        try {
                
-               abort = false;
+               abort = false; calledHelp = false;   
                comboStarts = 0;
                
                //allow user to run help
-               if(option == "help") { help(); abort = true; }
+               if(option == "help") { help(); abort = true; calledHelp = true; }
                
                else {
                        //valid paramters for this command
-                       string AlignArray[] =  {        "fasta", "flip", "oligos", "maxambig", "maxhomop", "group","minlength", "maxlength", "qfile", 
+                       string AlignArray[] =  {        "fasta", "flip", "oligos", "maxambig", "maxhomop", "minlength", "maxlength", "qfile", 
                                                                "qthreshold", "qwindowaverage", "qstepsize", "qwindowsize", "qaverage", "rollaverage",
                                                                "keepfirst", "removelast",
                                                                "allfiles", "qtrim","tdiffs", "pdiffs", "bdiffs", "processors", "outputdir","inputdir"};
@@ -106,7 +104,6 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                        vector<string> tempOutNames;
                        outputTypes["fasta"] = tempOutNames;
                        outputTypes["qual"] = tempOutNames;
-                       outputTypes["group"] = tempOutNames;
                        
                        //if the user changes the input directory command factory will send this info to us in the output parameter 
                        string inputDir = validParameter.validFile(parameters, "inputdir", false);              
@@ -137,13 +134,6 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                                        if (path == "") {       parameters["qfile"] = inputDir + it->second;            }
                                }
                                
-                               it = parameters.find("group");
-                               //user has given a template file
-                               if(it != parameters.end()){ 
-                                       path = m->hasPath(it->second);
-                                       //if the user has not given a path then, add inputdir. else leave path alone.
-                                       if (path == "") {       parameters["group"] = inputDir + it->second;            }
-                               }
                        }
 
                        
@@ -171,10 +161,6 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                        else if(temp == "not open"){    abort = true;   } 
                        else                                    {       oligoFile = temp;               }
                        
-                       temp = validParameter.validFile(parameters, "group", true);
-                       if (temp == "not found"){       groupfile = "";         }
-                       else if(temp == "not open"){    abort = true;   } 
-                       else                                    {       groupfile = temp;               }
                        
                        temp = validParameter.validFile(parameters, "maxambig", false);         if (temp == "not found") { temp = "-1"; }
                        convert(temp, maxAmbig);  
@@ -269,9 +255,8 @@ void TrimSeqsCommand::help(){
        try {
                m->mothurOut("The trim.seqs command reads a fastaFile and creates 2 new fasta files, .trim.fasta and scrap.fasta, as well as group files if you provide and oligos file.\n");
                m->mothurOut("The .trim.fasta contains sequences that meet your requirements, and the .scrap.fasta contains those which don't.\n");
-               m->mothurOut("The trim.seqs command parameters are fasta, flip, oligos, group, maxambig, maxhomop, minlength, maxlength, qfile, qthreshold, qaverage, diffs, qtrim, keepfirst, removelast and allfiles.\n");
+               m->mothurOut("The trim.seqs command parameters are fasta, flip, oligos, maxambig, maxhomop, minlength, maxlength, qfile, qthreshold, qaverage, diffs, qtrim, keepfirst, removelast and allfiles.\n");
                m->mothurOut("The fasta parameter is required.\n");
-               m->mothurOut("The group parameter allows you to enter a group file for your fasta file.\n");
                m->mothurOut("The flip parameter will output the reverse compliment of your trimmed sequence. The default is false.\n");
                m->mothurOut("The oligos parameter allows you to provide an oligos file.\n");
                m->mothurOut("The maxambig parameter allows you to set the maximum number of ambigious bases allowed. The default is -1.\n");
@@ -316,51 +301,33 @@ TrimSeqsCommand::~TrimSeqsCommand(){      /*      do nothing      */      }
 int TrimSeqsCommand::execute(){
        try{
        
-               if (abort == true) { return 0; }
+               if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
                
                numFPrimers = 0;  //this needs to be initialized
                numRPrimers = 0;
-               vector<string> fastaFileNames;
-               vector<string> qualFileNames;
+               vector<vector<string> > fastaFileNames;
+               vector<vector<string> > qualFileNames;
                
                string trimSeqFile = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "trim.fasta";
                outputNames.push_back(trimSeqFile); outputTypes["fasta"].push_back(trimSeqFile);
+               
                string scrapSeqFile = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "scrap.fasta";
                outputNames.push_back(scrapSeqFile); outputTypes["fasta"].push_back(scrapSeqFile);
+               
                string trimQualFile = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "trim.qual";
                string scrapQualFile = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "scrap.qual";
-               if (qFileName != "") {  outputNames.push_back(trimQualFile); outputNames.push_back(scrapQualFile);  outputTypes["qual"].push_back(trimQualFile); outputTypes["qual"].push_back(scrapQualFile); }
-               string groupFile = "";
-               if (groupfile == "") { groupFile = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "groups"; }
-               else{
-                       groupFile = outputDir + m->getRootName(m->getSimpleName(groupfile)) + "trim.groups";
-                       outputNames.push_back(groupFile); outputTypes["group"].push_back(groupFile);
-                       groupMap = new GroupMap(groupfile);
-                       groupMap->readMap();
-                       
-                       if(allFiles){
-                               for (int i = 0; i < groupMap->namesOfGroups.size(); i++) {
-                                       groupToIndex[groupMap->namesOfGroups[i]] = i;
-                                       groupVector.push_back(groupMap->namesOfGroups[i]);
-                                       fastaFileNames.push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) +  groupMap->namesOfGroups[i] + ".fasta"));
-                                       
-                                       //we append later, so we want to clear file
-                                       ofstream outRemove;
-                                       m->openOutputFile(fastaFileNames[i], outRemove);
-                                       outRemove.close();
-                                       if(qFileName != ""){
-                                               qualFileNames.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) +  groupMap->namesOfGroups[i] + ".qual"));
-                                               ofstream outRemove2;
-                                               m->openOutputFile(qualFileNames[i], outRemove2);
-                                               outRemove2.close();
-                                       }
-                               }
-                       }
-                       comboStarts = fastaFileNames.size()-1;
+               if (qFileName != "") {
+                       outputNames.push_back(trimQualFile);
+                       outputNames.push_back(scrapQualFile);
+                       outputTypes["qual"].push_back(trimQualFile);
+                       outputTypes["qual"].push_back(scrapQualFile); 
                }
                
+               string outputGroupFileName;
+
                if(oligoFile != ""){
-                       outputNames.push_back(groupFile); outputTypes["group"].push_back(groupFile);
+                       outputGroupFileName = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "groups";
+                       outputNames.push_back(outputGroupFileName); outputTypes["groups"].push_back(outputGroupFileName);
                        getOligos(fastaFileNames, qualFileNames);
                }
 
@@ -377,64 +344,33 @@ int TrimSeqsCommand::execute(){
                
                #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
                                if(processors == 1){
-                                       driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, groupFile, fastaFileNames, qualFileNames, lines[0], qLines[0]);
+                                       driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, outputGroupFileName, fastaFileNames, qualFileNames, lines[0], qLines[0]);
                                }else{
-                                       createProcessesCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, groupFile, fastaFileNames, qualFileNames); 
+                                       createProcessesCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, outputGroupFileName, fastaFileNames, qualFileNames); 
                                }       
                #else
-                               driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, groupFile, fastaFileNames, qualFileNames, lines[0], qLines[0]);
+                               driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, outputGroupFileName, fastaFileNames, qualFileNames, lines[0], qLines[0]);
                #endif
                
                if (m->control_pressed) {  return 0; }                  
                        
-               set<string> blanks;
-               for(int i=0;i<fastaFileNames.size();i++){
-                       if (m->isBlank(fastaFileNames[i])) {   blanks.insert(fastaFileNames[i]);        }
-                       else if (filesToRemove.count(fastaFileNames[i]) > 0) {  remove(fastaFileNames[i].c_str()); }
-                       else {
-                               ifstream inFASTA;
-                               string seqName;
-                               m->openInputFile(fastaFileNames[i], inFASTA);
-                               ofstream outGroups;
-                               string outGroupFilename = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[i])) + "groups";
-                               
-                               //if the fastafile is on the blanks list then the groups file should be as well
-                               if (blanks.count(fastaFileNames[i]) != 0) { blanks.insert(outGroupFilename); }
-                               
-                               m->openOutputFile(outGroupFilename, outGroups);
-                               outputNames.push_back(outGroupFilename); outputTypes["group"].push_back(outGroupFilename);  
                                
-                               string thisGroup = "";
-                               if (i > comboStarts) {
-                                       map<string, int>::iterator itCombo;
-                                       for(itCombo=combos.begin();itCombo!=combos.end(); itCombo++){
-                                               if(itCombo->second == i){       thisGroup = itCombo->first;     combos.erase(itCombo);  break;  }
-                                       }
-                               }else{ thisGroup = groupVector[i]; }
-                                       
-                               while(!inFASTA.eof()){
-                                       if(inFASTA.get() == '>'){
-                                               inFASTA >> seqName;
-                                               outGroups << seqName << '\t' << thisGroup << endl;
+               if(allFiles){
+                       for(int i=0;i<fastaFileNames.size();i++){
+                               for(int j=0;j<fastaFileNames[0].size();j++){
+                                       if(m->isBlank(fastaFileNames[i][j])){
+                                               remove(fastaFileNames[i][j].c_str());
+
+                                               if(qFileName != ""){
+                                                       remove(fastaFileNames[i][j].c_str());
+                                               }
+
                                        }
-                                       while (!inFASTA.eof())  {       char c = inFASTA.get(); if (c == 10 || c == 13){        break;  }       }
                                }
-                               outGroups.close();
-                               inFASTA.close();
                        }
                }
                
-               for (set<string>::iterator itBlanks = blanks.begin(); itBlanks != blanks.end(); itBlanks++) {  remove((*(itBlanks)).c_str()); }
-               
-               blanks.clear();
-               if(qFileName != ""){
-                       for(int i=0;i<qualFileNames.size();i++){
-                               if (m->isBlank(qualFileNames[i])) {  blanks.insert(qualFileNames[i]);   }
-                               else if (filesToRemove.count(qualFileNames[i]) > 0) {  remove(qualFileNames[i].c_str()); }
-                       }
-               }
                
-               for (set<string>::iterator itBlanks = blanks.begin(); itBlanks != blanks.end(); itBlanks++) {  remove((*(itBlanks)).c_str()); }
                
                if (m->control_pressed) { 
                        for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); }
@@ -457,27 +393,36 @@ int TrimSeqsCommand::execute(){
                
 /**************************************************************************************/
 
-int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string trimFile, string scrapFile, string trimQFile, string scrapQFile, string groupFile, vector<string> fastaNames, vector<string> qualNames, linePair* line, linePair* qline) {     
+int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string trimFileName, string scrapFileName, string trimQFileName, string scrapQFileName, string groupFileName, vector<vector<string> > fastaFileNames, vector<vector<string> > qualFileNames, linePair* line, linePair* qline) {       
                
        try {
                
-               ofstream outFASTA;
-               m->openOutputFile(trimFile, outFASTA);
+               ofstream trimFASTAFile;
+               m->openOutputFile(trimFileName, trimFASTAFile);
                
-               ofstream scrapFASTA;
-               m->openOutputFile(scrapFile, scrapFASTA);
+               ofstream scrapFASTAFile;
+               m->openOutputFile(scrapFileName, scrapFASTAFile);
                
-               ofstream outQual;
-               ofstream scrapQual;
+               ofstream trimQualFile;
+               ofstream scrapQualFile;
                if(qFileName != ""){
-                       m->openOutputFile(trimQFile, outQual);
-                       m->openOutputFile(scrapQFile, scrapQual);
+                       m->openOutputFile(trimQFileName, trimQualFile);
+                       m->openOutputFile(scrapQFileName, scrapQualFile);
                }
                
-               ofstream outGroups;
+               ofstream outGroupsFile;
+               if (oligoFile != ""){   m->openOutputFile(groupFileName, outGroupsFile);   }
                
-               if (oligoFile != "") {          
-                       m->openOutputFile(groupFile, outGroups);   
+               if(allFiles){
+                       for (int i = 0; i < fastaFileNames.size(); i++) { //clears old file
+                               for (int j = 0; j < fastaFileNames[i].size(); j++) { //clears old file
+                                       ofstream temp;
+                                       m->openOutputFile(fastaFileNames[i][j], temp);                  temp.close();
+                                       if(qFileName != ""){
+                                               m->openOutputFile(qualFileNames[i][j], temp);                   temp.close();
+                                       }
+                               }
+                       }
                }
                
                ifstream inFASTA;
@@ -485,29 +430,19 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                inFASTA.seekg(line->start);
                
                ifstream qFile;
-               if(qFileName != "")     {       m->openInputFile(qFileName, qFile);     qFile.seekg(qline->start);  }
-               
-               
-               for (int i = 0; i < fastaNames.size(); i++) { //clears old file
-                       ofstream temp;
-                       m->openOutputFile(fastaNames[i], temp);
-                       temp.close();
-               }
-               for (int i = 0; i < qualNames.size(); i++) { //clears old file
-                       ofstream temp;
-                       m->openOutputFile(qualNames[i], temp);
-                       temp.close();
+               if(qFileName != "")     {
+                       m->openInputFile(qFileName, qFile);
+                       qFile.seekg(qline->start);  
                }
                
-                       
-               bool done = false;
                int count = 0;
+               bool moreSeqs = 1;
        
-               while (!done) {
+               while (moreSeqs) {
                                
                        if (m->control_pressed) { 
-                               inFASTA.close(); outFASTA.close(); scrapFASTA.close();
-                               if (oligoFile != "") {   outGroups.close();   }
+                               inFASTA.close(); trimFASTAFile.close(); scrapFASTAFile.close();
+                               if (oligoFile != "") {   outGroupsFile.close();   }
 
                                if(qFileName != ""){
                                        qFile.close();
@@ -518,29 +453,30 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                        }
                        
                        int success = 1;
-                       
+                       string trashCode = "";
+                       int currentSeqsDiffs = 0;
 
                        Sequence currSeq(inFASTA); m->gobble(inFASTA);
 
                        QualityScores currQual;
                        if(qFileName != ""){
-                               currQual = QualityScores(qFile, currSeq.getNumBases());  m->gobble(qFile);
+                               currQual = QualityScores(qFile);  m->gobble(qFile);
                        }
-                       
+
                        string origSeq = currSeq.getUnaligned();
                        if (origSeq != "") {
-                               int groupBar, groupPrime;
-                               string trashCode = "";
-                               int currentSeqsDiffs = 0;
-
+                               
+                               int barcodeIndex = 0;
+                               int primerIndex = 0;
+                               
                                if(barcodes.size() != 0){
-                                       success = stripBarcode(currSeq, currQual, groupBar);
+                                       success = stripBarcode(currSeq, currQual, barcodeIndex);
                                        if(success > bdiffs)            {       trashCode += 'b';       }
                                        else{ currentSeqsDiffs += success;  }
                                }
                                
                                if(numFPrimers != 0){
-                                       success = stripForward(currSeq, currQual, groupPrime);
+                                       success = stripForward(currSeq, currQual, primerIndex);
                                        if(success > pdiffs)            {       trashCode += 'f';       }
                                        else{ currentSeqsDiffs += success;  }
                                }
@@ -592,65 +528,34 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                                
                                if(flip){               // should go last                       
                                        currSeq.reverseComplement();
-                                       currQual.flipQScores(); 
+                                       if(qFileName != ""){
+                                               currQual.flipQScores(); 
+                                       }
                                }
                                
                                if(trashCode.length() == 0){
                                        currSeq.setAligned(currSeq.getUnaligned());
-                                       currSeq.printSequence(outFASTA);
-                                       currQual.printQScores(outQual);
+                                       currSeq.printSequence(trimFASTAFile);
+                                       
+                                       if(qFileName != ""){
+                                               currQual.printQScores(trimQualFile);
+                                       }
                                        
                                        if(barcodes.size() != 0){
-                                               string thisGroup = groupVector[groupBar];
-                                               int indexToFastaFile = groupBar;
-                                               if (primers.size() != 0){
-                                                       //does this primer have a group
-                                                       if (groupVector[groupPrime] != "") {  
-                                                               thisGroup += "." + groupVector[groupPrime]; 
-                                                               indexToFastaFile = combos[thisGroup];
-                                                       }
-                                               }
-                                               outGroups << currSeq.getName() << '\t' << thisGroup << endl;
-                                               if(allFiles){
-                                                       ofstream outTemp;
-                                                       m->openOutputFileAppend(fastaNames[indexToFastaFile], outTemp);
-                                                       //currSeq.printSequence(*fastaFileNames[indexToFastaFile]);
-                                                       currSeq.printSequence(outTemp);
-                                                       outTemp.close();
-                                                       
-                                                       if(qFileName != ""){
-                                                               //currQual.printQScores(*qualFileNames[indexToFastaFile]);
-                                                               ofstream outTemp2;
-                                                               m->openOutputFileAppend(qualNames[indexToFastaFile], outTemp2);
-                                                               currQual.printQScores(outTemp2);
-                                                               outTemp2.close();                                                       
-                                                       }
-                                               }
+                                               outGroupsFile << currSeq.getName() << '\t' << barcodeNameVector[barcodeIndex] << endl;
                                        }
                                        
-                                       if (groupfile != "") {
-                                               string thisGroup = groupMap->getGroup(currSeq.getName());
+                                       
+                                       if(allFiles){
+                                               ofstream output;
+                                               m->openOutputFileAppend(fastaFileNames[barcodeIndex][primerIndex], output);
+                                               currSeq.printSequence(output);
+                                               output.close();
                                                
-                                               if (thisGroup != "not found") {
-                                                       outGroups << currSeq.getName() << '\t' << thisGroup << endl;
-                                                       if (allFiles) {
-                                                               ofstream outTemp;
-                                                               m->openOutputFileAppend(fastaNames[groupToIndex[thisGroup]], outTemp);
-                                                               currSeq.printSequence(outTemp);
-                                                               outTemp.close();
-                                                               if(qFileName != ""){
-                                                                       ofstream outTemp2;
-                                                                       m->openOutputFileAppend(qualNames[groupToIndex[thisGroup]], outTemp2);
-                                                                       currQual.printQScores(outTemp2);
-                                                                       outTemp2.close();                                                       
-                                                               }
-                                                       }
-                                               }else{
-                                                       m->mothurOut(currSeq.getName() + " is not in your groupfile, adding to group XXX."); m->mothurOutEndLine();
-                                                       outGroups << currSeq.getName() << '\t' << "XXX" << endl;
-                                                       if (allFiles) {  
-                                                               m->mothurOut("[ERROR]: " + currSeq.getName() + " will not be added to any .group.fasta or .group.qual file."); m->mothurOutEndLine();
-                                                       }
+                                               if(qFileName != ""){
+                                                       m->openOutputFileAppend(qualFileNames[barcodeIndex][primerIndex], output);
+                                                       currQual.printQScores(output);
+                                                       output.close();                                                 
                                                }
                                        }
                                }
@@ -658,8 +563,10 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                                        currSeq.setName(currSeq.getName() + '|' + trashCode);
                                        currSeq.setUnaligned(origSeq);
                                        currSeq.setAligned(origSeq);
-                                       currSeq.printSequence(scrapFASTA);
-                                       currQual.printQScores(scrapQual);
+                                       currSeq.printSequence(scrapFASTAFile);
+                                       if(qFileName != ""){
+                                               currQual.printQScores(scrapQualFile);
+                                       }
                                }
                                count++;
                        }
@@ -680,10 +587,10 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
 
                
                inFASTA.close();
-               outFASTA.close();
-               scrapFASTA.close();
-               if (oligoFile != "") {   outGroups.close();   }
-               if(qFileName != "")     {       qFile.close();  scrapQual.close(); outQual.close();     }
+               trimFASTAFile.close();
+               scrapFASTAFile.close();
+               if (oligoFile != "") {   outGroupsFile.close();   }
+               if(qFileName != "")     {       qFile.close();  scrapQualFile.close(); trimQualFile.close();    }
                
                return count;
        }
@@ -695,7 +602,7 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
 
 /**************************************************************************************************/
 
-int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName, string trimFile, string scrapFile, string trimQFile, string scrapQFile, string groupFile, vector<string> fastaNames, vector<string> qualNames) {
+int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName, string trimFASTAFileName, string scrapFASTAFileName, string trimQualFileName, string scrapQualFileName, string groupFile, vector<vector<string> > fastaFileNames, vector<vector<string> > qualFileNames) {
        try {
 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
                int process = 1;
@@ -710,22 +617,38 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                                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){
-                               for (int i = 0; i < fastaNames.size(); i++) {
-                                       fastaNames[i] = (fastaNames[i] + toString(getpid()) + ".temp");
-                                       //clear old file if it exists
+                               
+                               vector<vector<string> > tempFASTAFileNames = fastaFileNames;
+                               vector<vector<string> > tempPrimerQualFileNames = qualFileNames;
+
+                               if(allFiles){
                                        ofstream temp;
-                                       m->openOutputFile(fastaNames[i], temp);
-                                       temp.close();
-                                       if(qFileName != ""){
-                                               qualNames[i] = (qualNames[i] + toString(getpid()) + ".temp");
-                                               //clear old file if it exists
-                                               ofstream temp2;
-                                               m->openOutputFile(qualNames[i], temp2);
-                                               temp2.close();
+
+                                       for(int i=0;i<tempFASTAFileNames.size();i++){
+                                               for(int j=0;j<tempFASTAFileNames[i].size();j++){
+                                                       tempFASTAFileNames[i][j] += toString(getpid()) + ".temp";
+                                                       m->openOutputFile(tempFASTAFileNames[i][j], temp);                      temp.close();
+
+                                                       if(qFileName != ""){
+                                                               tempPrimerQualFileNames[i][j] += toString(getpid()) + ".temp";
+                                                               m->openOutputFile(tempPrimerQualFileNames[i][j], temp);         temp.close();
+                                                       }
+                                               }
                                        }
                                }
+                                                       
+                               driverCreateTrim(filename,
+                                                                qFileName,
+                                                                (trimFASTAFileName + toString(getpid()) + ".temp"),
+                                                                (scrapFASTAFileName + toString(getpid()) + ".temp"),
+                                                                (trimQualFileName + toString(getpid()) + ".temp"),
+                                                                (scrapQualFileName + toString(getpid()) + ".temp"),
+                                                                (groupFile + toString(getpid()) + ".temp"),
+                                                                tempFASTAFileNames,
+                                                                tempPrimerQualFileNames,
+                                                                lines[process],
+                                                                qLines[process]);
                                
-                               driverCreateTrim(filename, qFileName, (trimFile + toString(getpid()) + ".temp"), (scrapFile + toString(getpid()) + ".temp"), (trimQFile + toString(getpid()) + ".temp"), (scrapQFile + toString(getpid()) + ".temp"), (groupFile + toString(getpid()) + ".temp"), fastaNames, qualNames, lines[process], qLines[process]);
                                exit(0);
                        }else { 
                                m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
@@ -735,20 +658,15 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                }
                
                //parent do my part
-               for (int i = 0; i < fastaNames.size(); i++) {
-                       //clear old file if it exists
-                       ofstream temp;
-                       m->openOutputFile(fastaNames[i], temp);
-                       temp.close();
-                       if(qFileName != ""){
-                               //clear old file if it exists
-                               ofstream temp2;
-                               m->openOutputFile(qualNames[i], temp2);
-                               temp2.close();
-                       }
-               }
+               ofstream temp;
+               m->openOutputFile(trimFASTAFileName, temp);             temp.close();
+               m->openOutputFile(scrapFASTAFileName, temp);    temp.close();
+               m->openOutputFile(trimQualFileName, temp);              temp.close();
+               m->openOutputFile(scrapQualFileName, temp);             temp.close();
+
+               
                
-               driverCreateTrim(filename, qFileName, trimFile, scrapFile, trimQFile, scrapQFile, groupFile, fastaNames, qualNames, lines[0], qLines[0]);
+               driverCreateTrim(filename, qFileName, trimFASTAFileName, scrapFASTAFileName, trimQualFileName, scrapQualFileName, groupFile, fastaFileNames, qualFileNames, lines[0], qLines[0]);
                
                
                //force parent to wait until all the processes are done
@@ -762,40 +680,36 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                        
                        m->mothurOut("Appending files from process " + toString(processIDS[i])); m->mothurOutEndLine();
                        
-                       m->appendFiles((trimFile + toString(processIDS[i]) + ".temp"), trimFile);
-                       remove((trimFile + toString(processIDS[i]) + ".temp").c_str());
-                       m->appendFiles((scrapFile + toString(processIDS[i]) + ".temp"), scrapFile);
-                       remove((scrapFile + toString(processIDS[i]) + ".temp").c_str());
-                       
-                       m->mothurOut("Done with fasta files"); m->mothurOutEndLine();
+                       m->appendFiles((trimFASTAFileName + toString(processIDS[i]) + ".temp"), trimFASTAFileName);
+                       remove((trimFASTAFileName + toString(processIDS[i]) + ".temp").c_str());
+                       m->appendFiles((scrapFASTAFileName + toString(processIDS[i]) + ".temp"), scrapFASTAFileName);
+                       remove((scrapFASTAFileName + toString(processIDS[i]) + ".temp").c_str());
                        
                        if(qFileName != ""){
-                               m->appendFiles((trimQFile + toString(processIDS[i]) + ".temp"), trimQFile);
-                               remove((trimQFile + toString(processIDS[i]) + ".temp").c_str());
-                               m->appendFiles((scrapQFile + toString(processIDS[i]) + ".temp"), scrapQFile);
-                               remove((scrapQFile + toString(processIDS[i]) + ".temp").c_str());
-                       
-                               m->mothurOut("Done with quality files"); m->mothurOutEndLine();
+                               m->appendFiles((trimQualFileName + toString(processIDS[i]) + ".temp"), trimQualFileName);
+                               remove((trimQualFileName + toString(processIDS[i]) + ".temp").c_str());
+                               m->appendFiles((scrapQualFileName + toString(processIDS[i]) + ".temp"), scrapQualFileName);
+                               remove((scrapQualFileName + toString(processIDS[i]) + ".temp").c_str());
                        }
                        
                        m->appendFiles((groupFile + toString(processIDS[i]) + ".temp"), groupFile);
                        remove((groupFile + toString(processIDS[i]) + ".temp").c_str());
                        
-                       m->mothurOut("Done with group file"); m->mothurOutEndLine();
-                       
-                       for (int j = 0; j < fastaNames.size(); j++) {
-                               m->appendFiles((fastaNames[j] + toString(processIDS[i]) + ".temp"), fastaNames[j]);
-                               remove((fastaNames[j] + toString(processIDS[i]) + ".temp").c_str());
-                       }
                        
-                       if(qFileName != ""){
-                               for (int j = 0; j < qualNames.size(); j++) {
-                                       m->appendFiles((qualNames[j] + toString(processIDS[i]) + ".temp"), qualNames[j]);
-                                       remove((qualNames[j] + toString(processIDS[i]) + ".temp").c_str());
+                       if(allFiles){
+                               for(int j=0;j<fastaFileNames.size();j++){
+                                       for(int k=0;k<fastaFileNames[j].size();k++){
+                                               m->appendFiles((fastaFileNames[j][k] + toString(processIDS[i]) + ".temp"), fastaFileNames[j][k]);
+                                               remove((fastaFileNames[j][k] + toString(processIDS[i]) + ".temp").c_str());
+                                               
+                                               if(qFileName != ""){
+                                                       m->appendFiles((qualFileNames[j][k] + toString(processIDS[i]) + ".temp"), qualFileNames[j][k]);
+                                                       remove((qualFileNames[j][k] + toString(processIDS[i]) + ".temp").c_str());
+                                               }
+                                       }
                                }
                        }
                        
-                       if (allFiles) { m->mothurOut("Done with allfiles"); m->mothurOutEndLine(); }
                }
        
                return exitCommand;
@@ -893,7 +807,7 @@ int TrimSeqsCommand::setLines(string filename, string qfilename, vector<unsigned
 
 //***************************************************************************************************************
 
-void TrimSeqsCommand::getOligos(vector<string>& outFASTAVec, vector<string>& outQualVec){
+void TrimSeqsCommand::getOligos(vector<vector<string> >& fastaFileNames, vector<vector<string> >& qualFileNames){
        try {
                ifstream inOligos;
                m->openInputFile(oligoFile, inOligos);
@@ -901,10 +815,12 @@ void TrimSeqsCommand::getOligos(vector<string>& outFASTAVec, vector<string>& out
                ofstream test;
                
                string type, oligo, group;
-               int index=0;
-               //int indexPrimer = 0;
+
+               int indexPrimer = 0;
+               int indexBarcode = 0;
                
                while(!inOligos.eof()){
+
                        inOligos >> type; m->gobble(inOligos);
                                        
                        if(type[0] == '#'){
@@ -936,29 +852,8 @@ void TrimSeqsCommand::getOligos(vector<string>& outFASTAVec, vector<string>& out
                                        map<string, int>::iterator itPrime = primers.find(oligo);
                                        if (itPrime != primers.end()) { m->mothurOut("primer " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }
                                        
-                                               primers[oligo]=index; index++;
-                                               groupVector.push_back(group);
-                                       
-                                               if(allFiles){
-                                                       outFASTAVec.push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + group + ".fasta"));
-                                                       if(qFileName != ""){
-                                                               outQualVec.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + group + ".qual"));
-                                                       }
-                                                       if (group == "") { //if there is not a group for this primer, then this file will not get written to, but we add it to keep the indexes correct
-                                                               filesToRemove.insert((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + group + ".fasta"));
-                                                               if(qFileName != ""){
-                                                                       filesToRemove.insert((outputDir + m->getRootName(m->getSimpleName(qFileName)) + group + ".qual"));
-                                                               }
-                                                       }else {
-                                                               outputNames.push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + group + ".fasta"));
-                                                               outputTypes["fasta"].push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + group + ".fasta"));
-                                                               if(qFileName != ""){
-                                                                       outputNames.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + group + ".qual"));
-                                                                       outputTypes["qual"].push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + group + ".qual"));
-                                                               }                                                       
-                                                       }
-                                               }
-                                       
+                                       primers[oligo]=indexPrimer; indexPrimer++;              
+                                       primerNameVector.push_back(group);
                                }
                                else if(type == "REVERSE"){
                                        Sequence oligoRC("reverse", oligo);
@@ -971,58 +866,85 @@ void TrimSeqsCommand::getOligos(vector<string>& outFASTAVec, vector<string>& out
                                        //check for repeat barcodes
                                        map<string, int>::iterator itBar = barcodes.find(oligo);
                                        if (itBar != barcodes.end()) { m->mothurOut("barcode " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }
-                                       
-                                               barcodes[oligo]=index; index++;
-                                               groupVector.push_back(group);
                                                
-                                               if(allFiles){
-                                                       outputNames.push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + group + ".fasta"));
-                                                       outputNames.push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + group + ".fasta"));
-                                                       outFASTAVec.push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + group + ".fasta"));
-                                                       if(qFileName != ""){
-                                                               outQualVec.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + group + ".qual"));
-                                                               outputNames.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + group + ".qual"));
-                                                               outputTypes["qual"].push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + group + ".qual"));
-                                                       }                                                       
-                                               }
-                                       
-                               }else{  m->mothurOut(type + " is not recognized as a valid type. Choices are forward, reverse, and barcode. Ignoring " + oligo + "."); m->mothurOutEndLine();  }
+                                       barcodes[oligo]=indexBarcode; indexBarcode++;
+                                       barcodeNameVector.push_back(group);
+                               }
+                               else{   m->mothurOut(type + " is not recognized as a valid type. Choices are forward, reverse, and barcode. Ignoring " + oligo + "."); m->mothurOutEndLine();  }
                        }
                        m->gobble(inOligos);
-               }
-               
+               }       
                inOligos.close();
                
+               if(barcodeNameVector.size() == 0 && primerNameVector[0] == ""){ allFiles = 0;   }
+               
                //add in potential combos
+               if(barcodeNameVector.size() == 0){
+                       barcodes[""] = 0;
+                       barcodeNameVector.push_back("");                        
+               }
+               
+               if(primerNameVector.size() == 0){
+                       primers[""] = 0;
+                       primerNameVector.push_back("");                 
+               }
+               
+               fastaFileNames.resize(barcodeNameVector.size());
+               for(int i=0;i<fastaFileNames.size();i++){
+                       fastaFileNames[i].assign(primerNameVector.size(), "");
+               }
+               if(qFileName != ""){    qualFileNames = fastaFileNames; }
+               
                if(allFiles){
-                       comboStarts = outFASTAVec.size()-1;
-                       for (map<string, int>::iterator itBar = barcodes.begin(); itBar != barcodes.end(); itBar++) {
-                               for (map<string, int>::iterator itPrime = primers.begin(); itPrime != primers.end(); itPrime++) {
-                                       if (groupVector[itPrime->second] != "") { //there is a group for this primer
-                                               outputNames.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + groupVector[itBar->second] + "." + groupVector[itPrime->second] + ".fasta"));
-                                               outputTypes["fasta"].push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + groupVector[itBar->second] + "." + groupVector[itPrime->second] + ".fasta"));
-                                               outFASTAVec.push_back((outputDir + m->getRootName(m->getSimpleName(fastaFile)) + groupVector[itBar->second] + "." + groupVector[itPrime->second] + ".fasta"));
-                                               combos[(groupVector[itBar->second] + "." + groupVector[itPrime->second])] = outFASTAVec.size()-1;
-                                               
-                                               if(qFileName != ""){
-                                                       outQualVec.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + groupVector[itBar->second] + "." + groupVector[itPrime->second] + ".qual"));
-                                                       outputNames.push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + groupVector[itBar->second] + "." + groupVector[itPrime->second] + ".qual"));
-                                                       outputTypes["qual"].push_back((outputDir + m->getRootName(m->getSimpleName(qFileName)) + groupVector[itBar->second] + "." + groupVector[itPrime->second] + ".qual"));
+                       for(map<string, int>::iterator itBar = barcodes.begin();itBar != barcodes.end();itBar++){
+                               for(map<string, int>::iterator itPrimer = primers.begin();itPrimer != primers.end(); itPrimer++){
+                                       
+                                       string primerName = primerNameVector[itPrimer->second];
+                                       string barcodeName = barcodeNameVector[itBar->second];
+                                       
+                                       string comboGroupName = "";
+                                       string fastaFileName = "";
+                                       string qualFileName = "";
+                                       
+                                       if(primerName == ""){
+                                               comboGroupName = barcodeNameVector[itBar->second];
+                                       }
+                                       else{
+                                               if(barcodeName == ""){
+                                                       comboGroupName = primerNameVector[itPrimer->second];
                                                }
+                                               else{
+                                                       comboGroupName = barcodeNameVector[itBar->second] + "." + primerNameVector[itPrimer->second];
+                                               }
+                                       }
+
+                                       ofstream temp;
+                                       fastaFileName = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + comboGroupName + ".fasta";
+                                       outputNames.push_back(fastaFileName);
+                                       outputTypes["fasta"].push_back(fastaFileName);
+                                       fastaFileNames[itBar->second][itPrimer->second] = fastaFileName;
+                                       m->openOutputFile(fastaFileName, temp);         temp.close();
+
+                                       if(qFileName != ""){
+                                               qualFileName = outputDir + m->getRootName(m->getSimpleName(qFileName)) + comboGroupName + ".qual";
+                                               outputNames.push_back(qualFileName);
+                                               outputTypes["qual"].push_back(qualFileName);
+                                               qualFileNames[itBar->second][itPrimer->second] = qualFileName;
+                                               m->openOutputFile(qualFileName, temp);          temp.close();
                                        }
                                }
                        }
                }
-               
                numFPrimers = primers.size();
                numRPrimers = revPrimer.size();
-               
+
        }
        catch(exception& e) {
                m->errorOut(e, "TrimSeqsCommand", "getOligos");
                exit(1);
        }
 }
+
 //***************************************************************************************************************
 
 int TrimSeqsCommand::stripBarcode(Sequence& seq, QualityScores& qual, int& group){
@@ -1053,11 +975,9 @@ int TrimSeqsCommand::stripBarcode(Sequence& seq, QualityScores& qual, int& group
                }
                
                //if you found the barcode or if you don't want to allow for diffs
-//             cout << success;
                if ((bdiffs == 0) || (success == 0)) { return success;  }
                
                else { //try aligning and see if you can find it
-//                     cout << endl;
 
                        int maxLength = 0;
 
@@ -1104,8 +1024,6 @@ int TrimSeqsCommand::stripBarcode(Sequence& seq, QualityScores& qual, int& group
                                
                                int numDiff = countDiffs(oligo, temp);
                                
-//                             cout << oligo << '\t' << temp << '\t' << numDiff << endl;                               
-                               
                                if(numDiff < minDiff){
                                        minDiff = numDiff;
                                        minCount = 1;
@@ -1138,7 +1056,6 @@ int TrimSeqsCommand::stripBarcode(Sequence& seq, QualityScores& qual, int& group
                        if (alignment != NULL) {  delete alignment;  }
                        
                }
-//             cout << success << endl;
                
                return success;
                
@@ -1177,11 +1094,9 @@ int TrimSeqsCommand::stripForward(Sequence& seq, QualityScores& qual, int& group
                }
 
                //if you found the barcode or if you don't want to allow for diffs
-//             cout << success;
                if ((pdiffs == 0) || (success == 0)) { return success;  }
                
                else { //try aligning and see if you can find it
-//                     cout << endl;
 
                        int maxLength = 0;
 
@@ -1228,8 +1143,6 @@ int TrimSeqsCommand::stripForward(Sequence& seq, QualityScores& qual, int& group
                                
                                int numDiff = countDiffs(oligo, temp);
                                
-//                             cout << oligo << '\t' << temp << '\t' << numDiff << endl;                               
-                               
                                if(numDiff < minDiff){
                                        minDiff = numDiff;
                                        minCount = 1;