]> git.donarmstrong.com Git - mothur.git/blobdiff - trimseqscommand.cpp
changed normalize.shared and sub.sample commands to fix bug in normalize.shared and...
[mothur.git] / trimseqscommand.cpp
index 61a58a4aaeddcdbde6a0b9bdd6f57c56c4079fe9..a8c3fc697ae10c1c6a117ce68c550a928281ec44 100644 (file)
@@ -16,6 +16,7 @@ vector<string> TrimSeqsCommand::setParameters(){
                CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(pfasta);
                CommandParameter poligos("oligos", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(poligos);
                CommandParameter pqfile("qfile", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pqfile);
+               CommandParameter pname("name", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pname);
                CommandParameter pflip("flip", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(pflip);
                CommandParameter pmaxambig("maxambig", "Number", "", "-1", "", "", "",false,false); parameters.push_back(pmaxambig);
                CommandParameter pmaxhomop("maxhomop", "Number", "", "0", "", "", "",false,false); parameters.push_back(pmaxhomop);
@@ -53,10 +54,11 @@ string TrimSeqsCommand::getHelpString(){
                string helpString = "";
                helpString += "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";
                helpString += "The .trim.fasta contains sequences that meet your requirements, and the .scrap.fasta contains those which don't.\n";
-               helpString += "The trim.seqs command parameters are fasta, flip, oligos, maxambig, maxhomop, minlength, maxlength, qfile, qthreshold, qaverage, diffs, qtrim, keepfirst, removelast and allfiles.\n";
+               helpString += "The trim.seqs command parameters are fasta, name, flip, oligos, maxambig, maxhomop, minlength, maxlength, qfile, qthreshold, qaverage, diffs, qtrim, keepfirst, removelast and allfiles.\n";
                helpString += "The fasta parameter is required.\n";
                helpString += "The flip parameter will output the reverse compliment of your trimmed sequence. The default is false.\n";
                helpString += "The oligos parameter allows you to provide an oligos file.\n";
+               helpString += "The name parameter allows you to provide a names file with your fasta file.\n";
                helpString += "The maxambig parameter allows you to set the maximum number of ambigious bases allowed. The default is -1.\n";
                helpString += "The maxhomop parameter allows you to set a maximum homopolymer length. \n";
                helpString += "The minlength parameter allows you to set and minimum sequence length. \n";
@@ -100,6 +102,7 @@ TrimSeqsCommand::TrimSeqsCommand(){
                outputTypes["fasta"] = tempOutNames;
                outputTypes["qfile"] = tempOutNames;
                outputTypes["group"] = tempOutNames;
+               outputTypes["name"] = tempOutNames;
        }
        catch(exception& e) {
                m->errorOut(e, "TrimSeqsCommand", "TrimSeqsCommand");
@@ -137,6 +140,7 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                        outputTypes["fasta"] = tempOutNames;
                        outputTypes["qfile"] = tempOutNames;
                        outputTypes["group"] = tempOutNames;
+                       outputTypes["name"] = 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);              
@@ -167,6 +171,14 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                                        if (path == "") {       parameters["qfile"] = inputDir + it->second;            }
                                }
                                
+                               it = parameters.find("name");
+                               //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["name"] = inputDir + it->second;             }
+                               }
+                               
                        }
 
                        
@@ -177,6 +189,7 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                                if (fastaFile != "") { m->mothurOut("Using " + fastaFile + " 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 if (fastaFile == "not open") { abort = true; }    
+                       else { m->setFastaFile(fastaFile); }
                        
                        //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"){  
@@ -195,7 +208,7 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                        temp = validParameter.validFile(parameters, "oligos", true);
                        if (temp == "not found"){       oligoFile = "";         }
                        else if(temp == "not open"){    abort = true;   } 
-                       else                                    {       oligoFile = temp;               }
+                       else                                    {       oligoFile = temp; m->setOligosFile(oligoFile);          }
                        
                        
                        temp = validParameter.validFile(parameters, "maxambig", false);         if (temp == "not found") { temp = "-1"; }
@@ -224,7 +237,12 @@ TrimSeqsCommand::TrimSeqsCommand(string option)  {
                        temp = validParameter.validFile(parameters, "qfile", true);     
                        if (temp == "not found")        {       qFileName = "";         }
                        else if(temp == "not open")     {       abort = true;           }
-                       else                                            {       qFileName = temp;       }
+                       else                                            {       qFileName = temp;       m->setQualFile(qFileName); }
+                       
+                       temp = validParameter.validFile(parameters, "name", true);      
+                       if (temp == "not found")        {       nameFile = "";          }
+                       else if(temp == "not open")     {       nameFile = "";  abort = true;           }
+                       else                                            {       nameFile = temp;        m->setNameFile(nameFile); }
                        
                        temp = validParameter.validFile(parameters, "qthreshold", false);       if (temp == "not found") { temp = "0"; }
                        convert(temp, qThreshold);
@@ -290,8 +308,10 @@ int TrimSeqsCommand::execute(){
                
                numFPrimers = 0;  //this needs to be initialized
                numRPrimers = 0;
+               createGroup = false;
                vector<vector<string> > fastaFileNames;
                vector<vector<string> > qualFileNames;
+               vector<vector<string> > nameFileNames;
                
                string trimSeqFile = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "trim.fasta";
                outputNames.push_back(trimSeqFile); outputTypes["fasta"].push_back(trimSeqFile);
@@ -301,6 +321,7 @@ int TrimSeqsCommand::execute(){
                
                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);
@@ -308,11 +329,26 @@ int TrimSeqsCommand::execute(){
                        outputTypes["qfile"].push_back(scrapQualFile); 
                }
                
+               string trimNameFile = outputDir + m->getRootName(m->getSimpleName(nameFile)) + "trim.names";
+               string scrapNameFile = outputDir + m->getRootName(m->getSimpleName(nameFile)) + "scrap.names";
+               
+               if (nameFile != "") {
+                       m->readNames(nameFile, nameMap);
+                       outputNames.push_back(trimNameFile);
+                       outputNames.push_back(scrapNameFile);
+                       outputTypes["name"].push_back(trimNameFile);
+                       outputTypes["name"].push_back(scrapNameFile); 
+               }
+               
+               if (m->control_pressed) { return 0; }
+               
                string outputGroupFileName;
                if(oligoFile != ""){
-                       outputGroupFileName = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "groups";
-                       outputNames.push_back(outputGroupFileName); outputTypes["group"].push_back(outputGroupFileName);
-                       getOligos(fastaFileNames, qualFileNames);
+                       createGroup = getOligos(fastaFileNames, qualFileNames, nameFileNames);
+                       if (createGroup) {
+                               outputGroupFileName = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + "groups";
+                               outputNames.push_back(outputGroupFileName); outputTypes["group"].push_back(outputGroupFileName);
+                       }
                }
                
                vector<unsigned long int> fastaFilePos;
@@ -328,16 +364,16 @@ int TrimSeqsCommand::execute(){
                
                #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
                                if(processors == 1){
-                                       driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, outputGroupFileName, fastaFileNames, qualFileNames, lines[0], qLines[0]);
+                                       driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, trimNameFile, scrapNameFile, outputGroupFileName, fastaFileNames, qualFileNames, nameFileNames, lines[0], qLines[0]);
                                }else{
-                                       createProcessesCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, outputGroupFileName, fastaFileNames, qualFileNames); 
+                                       createProcessesCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, trimNameFile, scrapNameFile, outputGroupFileName, fastaFileNames, qualFileNames, nameFileNames); 
                                }       
                #else
-                               driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, outputGroupFileName, fastaFileNames, qualFileNames, lines[0], qLines[0]);
+                               driverCreateTrim(fastaFile, qFileName, trimSeqFile, scrapSeqFile, trimQualFile, scrapQualFile, trimNameFile, scrapNameFile, outputGroupFileName, fastaFileNames, qualFileNames, nameFileNames, lines[0], qLines[0]);
                #endif
                
                if (m->control_pressed) {  return 0; }                  
-       
+       
                if(allFiles){
                        map<string, string> uniqueFastaNames;// so we don't add the same groupfile multiple times
                        map<string, string>::iterator it;
@@ -347,13 +383,18 @@ int TrimSeqsCommand::execute(){
                                        if (fastaFileNames[i][j] != "") {
                                                if (namesToRemove.count(fastaFileNames[i][j]) == 0) {
                                                        if(m->isBlank(fastaFileNames[i][j])){
-                                                               remove(fastaFileNames[i][j].c_str());
+                                                               m->mothurRemove(fastaFileNames[i][j]);
                                                                namesToRemove.insert(fastaFileNames[i][j]);
                                                        
                                                                if(qFileName != ""){
-                                                                       remove(qualFileNames[i][j].c_str());
+                                                                       m->mothurRemove(qualFileNames[i][j]);
                                                                        namesToRemove.insert(qualFileNames[i][j]);
                                                                }
+                                                               
+                                                               if(nameFile != ""){
+                                                                       m->mothurRemove(nameFileNames[i][j]);
+                                                                       namesToRemove.insert(nameFileNames[i][j]);
+                                                               }
                                                        }else{  
                                                                it = uniqueFastaNames.find(fastaFileNames[i][j]);
                                                                if (it == uniqueFastaNames.end()) {     
@@ -390,17 +431,18 @@ int TrimSeqsCommand::execute(){
                        }
                }
                
-               if (m->control_pressed) {       for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); } return 0;     }
+               if (m->control_pressed) {       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]); } return 0;    }
 
                //output group counts
                m->mothurOutEndLine();
                int total = 0;
+               if (groupCounts.size() != 0) {  m->mothurOut("Group count: \n");  }
                for (map<string, int>::iterator it = groupCounts.begin(); it != groupCounts.end(); it++) {
-                        total += it->second; m->mothurOut("Group " + it->first + " contains " + toString(it->second) + " sequences."); m->mothurOutEndLine(); 
+                        total += it->second; m->mothurOut(it->first + "\t" + toString(it->second)); m->mothurOutEndLine(); 
                }
                if (total != 0) { m->mothurOut("Total of all groups is " + toString(total)); m->mothurOutEndLine(); }
                
-               if (m->control_pressed) {       for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); } return 0;     }
+               if (m->control_pressed) {       for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]); } return 0;    }
 
                //set fasta file as new current fastafile
                string current = "";
@@ -409,6 +451,11 @@ int TrimSeqsCommand::execute(){
                        if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); }
                }
                
+               itTypes = outputTypes.find("name");
+               if (itTypes != outputTypes.end()) {
+                       if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setNameFile(current); }
+               }
+               
                itTypes = outputTypes.find("qfile");
                if (itTypes != outputTypes.end()) {
                        if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setQualFile(current); }
@@ -435,7 +482,7 @@ int TrimSeqsCommand::execute(){
                
 /**************************************************************************************/
 
-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) {       
+int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string trimFileName, string scrapFileName, string trimQFileName, string scrapQFileName, string trimNFileName, string scrapNFileName, string groupFileName, vector<vector<string> > fastaFileNames, vector<vector<string> > qualFileNames, vector<vector<string> > nameFileNames, linePair* line, linePair* qline) {   
                
        try {
                
@@ -452,8 +499,16 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                        m->openOutputFile(scrapQFileName, scrapQualFile);
                }
                
+               ofstream trimNameFile;
+               ofstream scrapNameFile;
+               if(nameFile != ""){
+                       m->openOutputFile(trimNFileName, trimNameFile);
+                       m->openOutputFile(scrapNFileName, scrapNameFile);
+               }
+               
+               
                ofstream outGroupsFile;
-               if (oligoFile != ""){   m->openOutputFile(groupFileName, outGroupsFile);   }
+               if (createGroup){       m->openOutputFile(groupFileName, outGroupsFile);   }
                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
@@ -463,6 +518,10 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                                                if(qFileName != ""){
                                                        m->openOutputFile(qualFileNames[i][j], temp);                   temp.close();
                                                }
+                                               
+                                               if(nameFile != ""){
+                                                       m->openOutputFile(nameFileNames[i][j], temp);                   temp.close();
+                                               }
                                        }
                                }
                        }
@@ -485,12 +544,12 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                                
                        if (m->control_pressed) { 
                                inFASTA.close(); trimFASTAFile.close(); scrapFASTAFile.close();
-                               if (oligoFile != "") {   outGroupsFile.close();   }
+                               if (createGroup) {       outGroupsFile.close();   }
 
                                if(qFileName != ""){
                                        qFile.close();
                                }
-                               for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); }
+                               for (int i = 0; i < outputNames.size(); i++) {  m->mothurRemove(outputNames[i]); }
 
                                return 0;
                        }
@@ -500,12 +559,12 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                        int currentSeqsDiffs = 0;
 
                        Sequence currSeq(inFASTA); m->gobble(inFASTA);
-                       
+                       //cout << currSeq.getName() << '\t' << currSeq.getUnaligned().length() << endl;
                        QualityScores currQual;
                        if(qFileName != ""){
                                currQual = QualityScores(qFile);  m->gobble(qFile);
                        }
-
+                       
                        string origSeq = currSeq.getUnaligned();
                        if (origSeq != "") {
                                
@@ -549,7 +608,7 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                                        else if(qRollAverage != 0)      {       success = currQual.stripQualRollingAverage(currSeq, qRollAverage);      }
                                        else if(qWindowAverage != 0){   success = currQual.stripQualWindowAverage(currSeq, qWindowStep, qWindowSize, qWindowAverage);   }
                                        else                                            {       success = 1;                            }
-                               
+                                       
                                        //you don't want to trim, if it fails above then scrap it
                                        if ((!qtrim) && (origLength != currSeq.getNumBases())) {  success = 0; }
                                        
@@ -584,18 +643,44 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                                                currQual.printQScores(trimQualFile);
                                        }
                                        
-                                       if(barcodes.size() != 0){
-                                               string thisGroup = barcodeNameVector[barcodeIndex];
-                                               if (primers.size() != 0) { if (primerNameVector[primerIndex] != "") { thisGroup += "." + primerNameVector[primerIndex]; } }
-                                               
-                                               outGroupsFile << currSeq.getName() << '\t' << thisGroup << endl;
-                                               
-                                               map<string, int>::iterator it = groupCounts.find(thisGroup);
-                                               if (it == groupCounts.end()) {  groupCounts[thisGroup] = 1; }
-                                               else { groupCounts[it->first]++; }
-                                                       
+                                       if(nameFile != ""){
+                                               map<string, string>::iterator itName = nameMap.find(currSeq.getName());
+                                               if (itName != nameMap.end()) {  trimNameFile << itName->first << '\t' << itName->second << endl; }
+                                               else { m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); m->mothurOutEndLine(); }
                                        }
                                        
+                                       if (createGroup) {
+                                               if(barcodes.size() != 0){
+                                                       string thisGroup = barcodeNameVector[barcodeIndex];
+                                                       if (primers.size() != 0) { 
+                                                               if (primerNameVector[primerIndex] != "") { 
+                                                                       if(thisGroup != "") {
+                                                                               thisGroup += "." + primerNameVector[primerIndex]; 
+                                                                       }else {
+                                                                               thisGroup = primerNameVector[primerIndex]; 
+                                                                       }
+                                                               } 
+                                                       }
+                                                       
+                                                       outGroupsFile << currSeq.getName() << '\t' << thisGroup << endl;
+                                                       
+                                                       if (nameFile != "") {
+                                                               map<string, string>::iterator itName = nameMap.find(currSeq.getName());
+                                                               if (itName != nameMap.end()) { 
+                                                                       vector<string> thisSeqsNames; 
+                                                                       m->splitAtChar(itName->second, thisSeqsNames, ',');
+                                                                       for (int k = 1; k < thisSeqsNames.size(); k++) { //start at 1 to skip self
+                                                                               outGroupsFile << thisSeqsNames[k] << '\t' << thisGroup << endl;
+                                                                       }
+                                                               }else { m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); m->mothurOutEndLine(); }                                                   
+                                                       }
+                                                       
+                                                       map<string, int>::iterator it = groupCounts.find(thisGroup);
+                                                       if (it == groupCounts.end()) {  groupCounts[thisGroup] = 1; }
+                                                       else { groupCounts[it->first]++; }
+                                                               
+                                               }
+                                       }
                                        
                                        if(allFiles){
                                                ofstream output;
@@ -608,9 +693,23 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                                                        currQual.printQScores(output);
                                                        output.close();                                                 
                                                }
+                                               
+                                               if(nameFile != ""){
+                                                       map<string, string>::iterator itName = nameMap.find(currSeq.getName());
+                                                       if (itName != nameMap.end()) { 
+                                                               m->openOutputFileAppend(nameFileNames[barcodeIndex][primerIndex], output);
+                                                               output << itName->first << '\t' << itName->second << endl; 
+                                                               output.close();
+                                                       }else { m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); m->mothurOutEndLine(); }
+                                               }
                                        }
                                }
                                else{
+                                       if(nameFile != ""){ //needs to be before the currSeq name is changed
+                                               map<string, string>::iterator itName = nameMap.find(currSeq.getName());
+                                               if (itName != nameMap.end()) {  scrapNameFile << itName->first << '\t' << itName->second << endl; }
+                                               else { m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); m->mothurOutEndLine(); }
+                                       }
                                        currSeq.setName(currSeq.getName() + '|' + trashCode);
                                        currSeq.setUnaligned(origSeq);
                                        currSeq.setAligned(origSeq);
@@ -625,23 +724,25 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
                        #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
                                unsigned long int pos = inFASTA.tellg();
                                if ((pos == -1) || (pos >= line->end)) { break; }
+                       
                        #else
                                if (inFASTA.eof()) { break; }
                        #endif
-                               
+                       
                        //report progress
                        if((count) % 1000 == 0){        m->mothurOut(toString(count)); m->mothurOutEndLine();           }
                        
                }
                //report progress
                if((count) % 1000 != 0){        m->mothurOut(toString(count)); m->mothurOutEndLine();           }
-
+               
                
                inFASTA.close();
                trimFASTAFile.close();
                scrapFASTAFile.close();
-               if (oligoFile != "") {   outGroupsFile.close();   }
+               if (createGroup) {       outGroupsFile.close();   }
                if(qFileName != "")     {       qFile.close();  scrapQualFile.close(); trimQualFile.close();    }
+               if(nameFile != "")      {       scrapNameFile.close(); trimNameFile.close();    }
                
                return count;
        }
@@ -653,7 +754,7 @@ int TrimSeqsCommand::driverCreateTrim(string filename, string qFileName, string
 
 /**************************************************************************************************/
 
-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) {
+int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName, string trimFASTAFileName, string scrapFASTAFileName, string trimQualFileName, string scrapQualFileName, string trimNameFileName, string scrapNameFileName, string groupFile, vector<vector<string> > fastaFileNames, vector<vector<string> > qualFileNames, vector<vector<string> > nameFileNames) {
        try {
 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
                int process = 1;
@@ -671,6 +772,7 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                                
                                vector<vector<string> > tempFASTAFileNames = fastaFileNames;
                                vector<vector<string> > tempPrimerQualFileNames = qualFileNames;
+                               vector<vector<string> > tempNameFileNames = nameFileNames;
 
                                if(allFiles){
                                        ofstream temp;
@@ -685,6 +787,10 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                                                                        tempPrimerQualFileNames[i][j] += toString(getpid()) + ".temp";
                                                                        m->openOutputFile(tempPrimerQualFileNames[i][j], temp);         temp.close();
                                                                }
+                                                               if(nameFile != ""){
+                                                                       tempNameFileNames[i][j] += toString(getpid()) + ".temp";
+                                                                       m->openOutputFile(tempNameFileNames[i][j], temp);               temp.close();
+                                                               }
                                                        }
                                                }
                                        }
@@ -696,21 +802,28 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                                                                 (scrapFASTAFileName + toString(getpid()) + ".temp"),
                                                                 (trimQualFileName + toString(getpid()) + ".temp"),
                                                                 (scrapQualFileName + toString(getpid()) + ".temp"),
+                                                                (trimNameFileName + toString(getpid()) + ".temp"),
+                                                                (scrapNameFileName + toString(getpid()) + ".temp"),
                                                                 (groupFile + toString(getpid()) + ".temp"),
                                                                 tempFASTAFileNames,
                                                                 tempPrimerQualFileNames,
+                                                                tempNameFileNames,
                                                                 lines[process],
                                                                 qLines[process]);
                                
                                //pass groupCounts to parent
-                               ofstream out;
-                               string tempFile = filename + toString(getpid()) + ".num.temp";
-                               m->openOutputFile(tempFile, out);
-                               for (map<string, int>::iterator it = groupCounts.begin(); it != groupCounts.end(); it++) {
-                                       out << it->first << '\t' << it->second << endl;
+                               if(createGroup){
+                                       ofstream out;
+                                       string tempFile = filename + toString(getpid()) + ".num.temp";
+                                       m->openOutputFile(tempFile, out);
+                                       
+                                       out << groupCounts.size() << endl;
+                                       
+                                       for (map<string, int>::iterator it = groupCounts.begin(); it != groupCounts.end(); it++) {
+                                               out << it->first << '\t' << it->second << endl;
+                                       }
+                                       out.close();
                                }
-                               out.close();
-                               
                                exit(0);
                        }else { 
                                m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
@@ -723,10 +836,16 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                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();
+               if(qFileName != ""){
+                       m->openOutputFile(trimQualFileName, temp);              temp.close();
+                       m->openOutputFile(scrapQualFileName, temp);             temp.close();
+               }
+               if (nameFile != "") {
+                       m->openOutputFile(trimNameFileName, temp);              temp.close();
+                       m->openOutputFile(scrapNameFileName, temp);             temp.close();
+               }
 
-               driverCreateTrim(filename, qFileName, trimFASTAFileName, scrapFASTAFileName, trimQualFileName, scrapQualFileName, groupFile, fastaFileNames, qualFileNames, lines[0], qLines[0]);
+               driverCreateTrim(filename, qFileName, trimFASTAFileName, scrapFASTAFileName, trimQualFileName, scrapQualFileName, trimNameFileName, scrapNameFileName, groupFile, fastaFileNames, qualFileNames, nameFileNames, lines[0], qLines[0]);
                
                //force parent to wait until all the processes are done
                for (int i=0;i<processIDS.size();i++) { 
@@ -740,19 +859,28 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                        m->mothurOut("Appending files from process " + toString(processIDS[i])); m->mothurOutEndLine();
                        
                        m->appendFiles((trimFASTAFileName + toString(processIDS[i]) + ".temp"), trimFASTAFileName);
-                       remove((trimFASTAFileName + toString(processIDS[i]) + ".temp").c_str());
+                       m->mothurRemove((trimFASTAFileName + toString(processIDS[i]) + ".temp"));
                        m->appendFiles((scrapFASTAFileName + toString(processIDS[i]) + ".temp"), scrapFASTAFileName);
-                       remove((scrapFASTAFileName + toString(processIDS[i]) + ".temp").c_str());
+                       m->mothurRemove((scrapFASTAFileName + toString(processIDS[i]) + ".temp"));
                        
                        if(qFileName != ""){
                                m->appendFiles((trimQualFileName + toString(processIDS[i]) + ".temp"), trimQualFileName);
-                               remove((trimQualFileName + toString(processIDS[i]) + ".temp").c_str());
+                               m->mothurRemove((trimQualFileName + toString(processIDS[i]) + ".temp"));
                                m->appendFiles((scrapQualFileName + toString(processIDS[i]) + ".temp"), scrapQualFileName);
-                               remove((scrapQualFileName + toString(processIDS[i]) + ".temp").c_str());
+                               m->mothurRemove((scrapQualFileName + toString(processIDS[i]) + ".temp"));
+                       }
+                       
+                       if(nameFile != ""){
+                               m->appendFiles((trimNameFileName + toString(processIDS[i]) + ".temp"), trimNameFileName);
+                               m->mothurRemove((trimNameFileName + toString(processIDS[i]) + ".temp"));
+                               m->appendFiles((scrapNameFileName + toString(processIDS[i]) + ".temp"), scrapNameFileName);
+                               m->mothurRemove((scrapNameFileName + toString(processIDS[i]) + ".temp"));
                        }
                        
-                       m->appendFiles((groupFile + toString(processIDS[i]) + ".temp"), groupFile);
-                       remove((groupFile + toString(processIDS[i]) + ".temp").c_str());
+                       if(createGroup){
+                               m->appendFiles((groupFile + toString(processIDS[i]) + ".temp"), groupFile);
+                               m->mothurRemove((groupFile + toString(processIDS[i]) + ".temp"));
+                       }
                        
                        
                        if(allFiles){
@@ -760,30 +888,42 @@ int TrimSeqsCommand::createProcessesCreateTrim(string filename, string qFileName
                                        for(int k=0;k<fastaFileNames[j].size();k++){
                                                if (fastaFileNames[j][k] != "") {
                                                        m->appendFiles((fastaFileNames[j][k] + toString(processIDS[i]) + ".temp"), fastaFileNames[j][k]);
-                                                       remove((fastaFileNames[j][k] + toString(processIDS[i]) + ".temp").c_str());
+                                                       m->mothurRemove((fastaFileNames[j][k] + toString(processIDS[i]) + ".temp"));
                                                        
                                                        if(qFileName != ""){
                                                                m->appendFiles((qualFileNames[j][k] + toString(processIDS[i]) + ".temp"), qualFileNames[j][k]);
-                                                               remove((qualFileNames[j][k] + toString(processIDS[i]) + ".temp").c_str());
+                                                               m->mothurRemove((qualFileNames[j][k] + toString(processIDS[i]) + ".temp"));
+                                                       }
+                                                       
+                                                       if(nameFile != ""){
+                                                               m->appendFiles((nameFileNames[j][k] + toString(processIDS[i]) + ".temp"), nameFileNames[j][k]);
+                                                               m->mothurRemove((nameFileNames[j][k] + toString(processIDS[i]) + ".temp"));
                                                        }
                                                }
                                        }
                                }
                        }
                        
-                       ifstream in;
-                       string tempFile =  filename + toString(processIDS[i]) + ".num.temp";
-                       m->openInputFile(tempFile, in);
-                       int tempNum;
-                       string group;
-                       while (!in.eof()) { 
-                               in >> group >> tempNum; m->gobble(in);
+                       if(createGroup){
+                               ifstream in;
+                               string tempFile =  filename + toString(processIDS[i]) + ".num.temp";
+                               m->openInputFile(tempFile, in);
+                               int tempNum;
+                               string group;
                                
-                               map<string, int>::iterator it = groupCounts.find(group);
-                               if (it == groupCounts.end()) {  groupCounts[group] = tempNum; }
-                               else { groupCounts[it->first] += tempNum; }
+                               in >> tempNum; m->gobble(in);
+                               
+                               if (tempNum != 0) {
+                                       while (!in.eof()) { 
+                                               in >> group >> tempNum; m->gobble(in);
+                               
+                                               map<string, int>::iterator it = groupCounts.find(group);
+                                               if (it == groupCounts.end()) {  groupCounts[group] = tempNum; }
+                                               else { groupCounts[it->first] += tempNum; }
+                                       }
+                               }
+                               in.close(); m->mothurRemove(tempFile);
                        }
-                       in.close(); remove(tempFile.c_str());
                        
                }
        
@@ -916,7 +1056,7 @@ int TrimSeqsCommand::setLines(string filename, string qfilename, vector<unsigned
 
 //***************************************************************************************************************
 
-void TrimSeqsCommand::getOligos(vector<vector<string> >& fastaFileNames, vector<vector<string> >& qualFileNames){
+bool TrimSeqsCommand::getOligos(vector<vector<string> >& fastaFileNames, vector<vector<string> >& qualFileNames, vector<vector<string> >& nameFileNames){
        try {
                ifstream inOligos;
                m->openInputFile(oligoFile, inOligos);
@@ -1004,7 +1144,8 @@ void TrimSeqsCommand::getOligos(vector<vector<string> >& fastaFileNames, vector<
                for(int i=0;i<fastaFileNames.size();i++){
                        fastaFileNames[i].assign(primerNameVector.size(), "");
                }
-               if(qFileName != ""){    qualFileNames = fastaFileNames; }
+               if(qFileName != "")     {       qualFileNames = fastaFileNames; }
+               if(nameFile != "")      {       nameFileNames = fastaFileNames; }
                
                if(allFiles){
                        set<string> uniqueNames; //used to cleanup outputFileNames
@@ -1017,6 +1158,7 @@ void TrimSeqsCommand::getOligos(vector<vector<string> >& fastaFileNames, vector<
                                        string comboGroupName = "";
                                        string fastaFileName = "";
                                        string qualFileName = "";
+                                       string nameFileName = "";
                                        
                                        if(primerName == ""){
                                                comboGroupName = barcodeNameVector[itBar->second];
@@ -1030,36 +1172,68 @@ void TrimSeqsCommand::getOligos(vector<vector<string> >& fastaFileNames, vector<
                                                }
                                        }
                                        
-                                       if ((comboGroupName == "") || (comboGroupName == ".")) {}
-                                       else {
-                                               ofstream temp;
-                                               fastaFileName = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + comboGroupName + ".fasta";
-                                               if (uniqueNames.count(fastaFileName) == 0) {
-                                                       outputNames.push_back(fastaFileName);
-                                                       outputTypes["fasta"].push_back(fastaFileName);
-                                                       uniqueNames.insert(fastaFileName);
+                                       
+                                       ofstream temp;
+                                       fastaFileName = outputDir + m->getRootName(m->getSimpleName(fastaFile)) + comboGroupName + ".fasta";
+                                       if (uniqueNames.count(fastaFileName) == 0) {
+                                               outputNames.push_back(fastaFileName);
+                                               outputTypes["fasta"].push_back(fastaFileName);
+                                               uniqueNames.insert(fastaFileName);
+                                       }
+                                       
+                                       fastaFileNames[itBar->second][itPrimer->second] = fastaFileName;
+                                       m->openOutputFile(fastaFileName, temp);         temp.close();
+                                       
+                                       if(qFileName != ""){
+                                               qualFileName = outputDir + m->getRootName(m->getSimpleName(qFileName)) + comboGroupName + ".qual";
+                                               if (uniqueNames.count(qualFileName) == 0) {
+                                                       outputNames.push_back(qualFileName);
+                                                       outputTypes["qfile"].push_back(qualFileName);
                                                }
                                                
-                                               fastaFileNames[itBar->second][itPrimer->second] = fastaFileName;
-                                               m->openOutputFile(fastaFileName, temp);         temp.close();
-                                               
-                                               if(qFileName != ""){
-                                                       qualFileName = outputDir + m->getRootName(m->getSimpleName(qFileName)) + comboGroupName + ".qual";
-                                                       if (uniqueNames.count(fastaFileName) == 0) {
-                                                               outputNames.push_back(qualFileName);
-                                                               outputTypes["qfile"].push_back(qualFileName);
-                                                       }
-                                                       
-                                                       qualFileNames[itBar->second][itPrimer->second] = qualFileName;
-                                                       m->openOutputFile(qualFileName, temp);          temp.close();
+                                               qualFileNames[itBar->second][itPrimer->second] = qualFileName;
+                                               m->openOutputFile(qualFileName, temp);          temp.close();
+                                       }
+                                       
+                                       if(nameFile != ""){
+                                               nameFileName = outputDir + m->getRootName(m->getSimpleName(nameFile)) + comboGroupName + ".names";
+                                               if (uniqueNames.count(nameFileName) == 0) {
+                                                       outputNames.push_back(nameFileName);
+                                                       outputTypes["name"].push_back(nameFileName);
                                                }
+                                               
+                                               nameFileNames[itBar->second][itPrimer->second] = nameFileName;
+                                               m->openOutputFile(nameFileName, temp);          temp.close();
                                        }
+                                       
                                }
                        }
                }
                numFPrimers = primers.size();
                numRPrimers = revPrimer.size();
-
+               
+               bool allBlank = true;
+               for (int i = 0; i < barcodeNameVector.size(); i++) {
+                       if (barcodeNameVector[i] != "") {
+                               allBlank = false;
+                               break;
+                       }
+               }
+               for (int i = 0; i < primerNameVector.size(); i++) {
+                       if (primerNameVector[i] != "") {
+                               allBlank = false;
+                               break;
+                       }
+               }
+               
+               if (allBlank) {
+                       m->mothurOut("[WARNING]: your oligos file does not contain any group names.  mothur will not create a groupfile."); m->mothurOutEndLine();
+                       allFiles = false;
+                       return false;
+               }
+               
+               return true;
+               
        }
        catch(exception& e) {
                m->errorOut(e, "TrimSeqsCommand", "getOligos");
@@ -1178,7 +1352,7 @@ int TrimSeqsCommand::stripBarcode(Sequence& seq, QualityScores& qual, int& group
                        if (alignment != NULL) {  delete alignment;  }
                        
                }
-               
+       
                return success;
                
        }