]> git.donarmstrong.com Git - mothur.git/blobdiff - sffinfocommand.cpp
working on pam
[mothur.git] / sffinfocommand.cpp
index bccb75122ffbc9cebc5862f00df0b17d9e644f51..03bcebb591e35b19b10224ff6a4512bdecdf2dbb 100755 (executable)
@@ -17,7 +17,8 @@
 vector<string> SffInfoCommand::setParameters(){        \r
        try {           \r
                CommandParameter psff("sff", "InputTypes", "", "", "none", "none", "none","",false,false,true); parameters.push_back(psff);\r
-        CommandParameter poligos("oligos", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(poligos);\r
+        CommandParameter poligos("oligos", "InputTypes", "", "", "oligosGroup", "none", "none","",false,false); parameters.push_back(poligos);\r
+        CommandParameter pgroup("group", "InputTypes", "", "", "oligosGroup", "none", "none","",false,false); parameters.push_back(pgroup);\r
                CommandParameter paccnos("accnos", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(paccnos);\r
                CommandParameter psfftxt("sfftxt", "String", "", "", "", "", "","",false,false); parameters.push_back(psfftxt);\r
                CommandParameter pflow("flow", "Boolean", "", "T", "", "", "","flow",false,false); parameters.push_back(pflow);\r
@@ -46,11 +47,12 @@ string SffInfoCommand::getHelpString(){
        try {\r
                string helpString = "";\r
                helpString += "The sffinfo command reads a sff file and extracts the sequence data, or you can use it to parse a sfftxt file.\n";\r
-               helpString += "The sffinfo command parameters are sff, fasta, qfile, accnos, flow, sfftxt, oligos, bdiffs, tdiffs, ldiffs, sdiffs, pdiffs and trim. sff is required. \n";\r
+               helpString += "The sffinfo command parameters are sff, fasta, qfile, accnos, flow, sfftxt, oligos, group, bdiffs, tdiffs, ldiffs, sdiffs, pdiffs and trim. sff is required. \n";\r
                helpString += "The sff parameter allows you to enter the sff file you would like to extract data from.  You may enter multiple files by separating them by -'s.\n";\r
                helpString += "The fasta parameter allows you to indicate if you would like a fasta formatted file generated.  Default=True. \n";\r
                helpString += "The qfile parameter allows you to indicate if you would like a quality file generated.  Default=True. \n";\r
         helpString += "The oligos parameter allows you to provide an oligos file to split your sff file into separate sff files by barcode. \n";\r
+        helpString += "The group parameter allows you to provide a group file to split your sff file into separate sff files by group. \n";\r
         helpString += "The tdiffs parameter is used to specify the total number of differences allowed in the sequence. The default is pdiffs + bdiffs + sdiffs + ldiffs.\n";\r
                helpString += "The bdiffs parameter is used to specify the number of differences allowed in the barcode. The default is 0.\n";\r
                helpString += "The pdiffs parameter is used to specify the number of differences allowed in the primer. The default is 0.\n";\r
@@ -112,7 +114,7 @@ SffInfoCommand::SffInfoCommand(){
 SffInfoCommand::SffInfoCommand(string option)  {\r
        try {\r
                abort = false; calledHelp = false;   \r
-               hasAccnos = false; hasOligos = false;\r
+               hasAccnos = false; hasOligos = false; hasGroup = false;\r
         split = 1;\r
                \r
                //allow user to run help\r
@@ -293,7 +295,7 @@ SffInfoCommand::SffInfoCommand(string option)  {
                                        bool ignore = false;\r
                                        if (oligosFileNames[i] == "current") { \r
                                                oligosFileNames[i] = m->getOligosFile(); \r
-                                               if (oligosFileNames[i] != "") {  m->mothurOut("Using " + oligosFileNames[i] + " as input file for the accnos parameter where you had given current."); m->mothurOutEndLine(); }\r
+                                               if (oligosFileNames[i] != "") {  m->mothurOut("Using " + oligosFileNames[i] + " as input file for the oligos parameter where you had given current."); m->mothurOutEndLine(); }\r
                                                else {  \r
                                                        m->mothurOut("You have no current oligosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; \r
                                                        //erase from file list\r
@@ -349,12 +351,87 @@ SffInfoCommand::SffInfoCommand(string option)  {
                                //make sure there is at least one valid file left\r
                                if (oligosFileNames.size() == 0) { m->mothurOut("no valid oligos files."); m->mothurOutEndLine(); abort = true; }\r
                        }\r
+            \r
+            groupfile = validParameter.validFile(parameters, "group", false);\r
+                       if (groupfile == "not found") { groupfile = "";  }\r
+                       else {\r
+                               hasGroup = true;\r
+                               m->splitAtDash(groupfile, groupFileNames);\r
+                               \r
+                               //go through files and make sure they are good, if not, then disregard them\r
+                               for (int i = 0; i < groupFileNames.size(); i++) {\r
+                                       bool ignore = false;\r
+                                       if (groupFileNames[i] == "current") {\r
+                                               groupFileNames[i] = m->getGroupFile();\r
+                                               if (groupFileNames[i] != "") {  m->mothurOut("Using " + groupFileNames[i] + " as input file for the group parameter where you had given current."); m->mothurOutEndLine(); }\r
+                                               else {\r
+                                                       m->mothurOut("You have no current group file, ignoring current."); m->mothurOutEndLine(); ignore=true;\r
+                                                       //erase from file list\r
+                                                       groupFileNames.erase(groupFileNames.begin()+i);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       if (!ignore) {\r
+                        \r
+                                               if (inputDir != "") {\r
+                                                       string path = m->hasPath(groupFileNames[i]);\r
+                                                       //if the user has not given a path then, add inputdir. else leave path alone.\r
+                                                       if (path == "") {       groupFileNames[i] = inputDir + groupFileNames[i];               }\r
+                                               }\r
+                        \r
+                                               ifstream in;\r
+                                               int ableToOpen = m->openInputFile(groupFileNames[i], in, "noerror");\r
+                        \r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getDefaultPath() != "") { //default path is set\r
+                                                               string tryPath = m->getDefaultPath() + m->getSimpleName(groupFileNames[i]);\r
+                                                               m->mothurOut("Unable to open " + groupFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               groupFileNames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               //if you can't open it, try default location\r
+                                               if (ableToOpen == 1) {\r
+                                                       if (m->getOutputDir() != "") { //default path is set\r
+                                                               string tryPath = m->getOutputDir() + m->getSimpleName(groupFileNames[i]);\r
+                                                               m->mothurOut("Unable to open " + groupFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
+                                                               ifstream in2;\r
+                                                               ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
+                                                               in2.close();\r
+                                                               groupFileNames[i] = tryPath;\r
+                                                       }\r
+                                               }\r
+                                               in.close();\r
+                                               \r
+                                               if (ableToOpen == 1) {\r
+                                                       m->mothurOut("Unable to open " + groupFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
+                                                       //erase from file list\r
+                                                       groupFileNames.erase(groupFileNames.begin()+i);\r
+                                                       i--;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               \r
+                               //make sure there is at least one valid file left\r
+                               if (groupFileNames.size() == 0) { m->mothurOut("no valid group files."); m->mothurOutEndLine(); abort = true; }\r
+                       }\r
 \r
-                       if (hasOligos) {\r
+                       if (hasGroup) {\r
+                split = 2;\r
+                               if (groupFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide a group file, you must have one for each sff file."); m->mothurOutEndLine(); }\r
+                       }\r
+            \r
+            if (hasOligos) {\r
                 split = 2;\r
-                               if (oligosFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide a oligos file, you must have one for each sff file."); m->mothurOutEndLine(); }\r
+                               if (oligosFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide an oligos file, you must have one for each sff file."); m->mothurOutEndLine(); }\r
                        }\r
             \r
+            if (hasGroup && hasOligos) { m->mothurOut("You must enter ONLY ONE of the following: oligos or group."); m->mothurOutEndLine(); abort = true;}\r
+            \r
                        if (hasAccnos) {\r
                                if (accnosFileNames.size() != filenames.size()) { abort = true; m->mothurOut("If you provide a accnos file, you must have one for each sff file."); m->mothurOutEndLine(); }\r
                        }\r
@@ -442,7 +519,8 @@ int SffInfoCommand::execute(){
             \r
             string oligos = "";\r
             if (hasOligos) { oligos = oligosFileNames[s]; }\r
-                       \r
+            if (hasGroup) { oligos = groupFileNames[s]; }\r
+            \r
                        int numReads = extractSffInfo(filenames[s], accnos, oligos);\r
 \r
                        m->mothurOut("It took " + toString(time(NULL) - start) + " secs to extract " + toString(numReads) + ".");\r
@@ -490,9 +568,10 @@ int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){
                \r
                if (accnos != "")       {  readAccnosFile(accnos);  }\r
                else                            {       seqNames.clear();               }\r
-         \r
-        if (oligos != "")   {   readOligos(oligos);  split = 2;   }\r
-\r
+        \r
+        if (hasOligos)   {   readOligos(oligos);    split = 2;      }\r
+        if (hasGroup)    {   readGroup(oligos);     split = 2;      }\r
+        \r
                ofstream outSfftxt, outFasta, outQual, outFlow;\r
                string outFastaFileName, outQualFileName;\r
         string rootName = outputDir + m->getRootName(m->getSimpleName(input));\r
@@ -526,7 +605,7 @@ int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){
                //print common header\r
                if (sfftxt) {   printCommonHeader(outSfftxt, header);           }\r
                if (flow)       {       outFlow << header.numFlowsPerRead << endl;      }\r
-                       \r
+               \r
                //read through the sff file\r
                while (!in.eof()) {\r
                        \r
@@ -551,7 +630,7 @@ int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){
                        }\r
                        \r
                        count++;\r
-        \r
+            \r
                        //report progress\r
                        if((count+1) % 10000 == 0){     m->mothurOut(toString(count+1)); m->mothurOutEndLine();         }\r
                \r
@@ -574,13 +653,7 @@ int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){
             //create new common headers for each file with the correct number of reads\r
             adjustCommonHeader(header);\r
             \r
-            //close files and delete ofstreams\r
-            for(int i=0;i<filehandles.size();i++){\r
-                               for(int j=0;j<filehandles[0].size();j++){\r
-                    (filehandles[i][j].begin()->second)->close(); delete (filehandles[i][j].begin()->second);\r
-                    (filehandlesHeaders[i][j].begin()->second)->close(); delete (filehandlesHeaders[i][j].begin()->second);\r
-                }\r
-            }\r
+            if (hasGroup) { delete groupMap; }\r
             \r
             //cout << "here" << endl;\r
                        map<string, string>::iterator it;\r
@@ -588,13 +661,13 @@ int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){
                        for(int i=0;i<filehandles.size();i++){\r
                                for(int j=0;j<filehandles[0].size();j++){\r
                     //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << endl;\r
-                                       if (filehandles[i][j].begin()->first != "") {\r
-                                               if (namesToRemove.count(filehandles[i][j].begin()->first) == 0) {\r
-                                                       if(m->isBlank(filehandles[i][j].begin()->first)){\r
+                                       if (filehandles[i][j] != "") {\r
+                                               if (namesToRemove.count(filehandles[i][j]) == 0) {\r
+                                                       if(m->isBlank(filehandles[i][j])){\r
                                 //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << " is blank removing" << endl;\r
-                                                               m->mothurRemove(filehandles[i][j].begin()->first);\r
-                                m->mothurRemove(filehandlesHeaders[i][j].begin()->first);\r
-                                                               namesToRemove.insert(filehandles[i][j].begin()->first);\r
+                                                               m->mothurRemove(filehandles[i][j]);\r
+                                m->mothurRemove(filehandlesHeaders[i][j]);\r
+                                                               namesToRemove.insert(filehandles[i][j]);\r
                             }\r
                                                }\r
                                        }\r
@@ -604,11 +677,11 @@ int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){
             //append new header to reads\r
             for (int i = 0; i < filehandles.size(); i++) {\r
                 for (int j = 0; j < filehandles[i].size(); j++) {\r
-                    m->appendBinaryFiles(filehandles[i][j].begin()->first, filehandlesHeaders[i][j].begin()->first);\r
-                    m->renameFile(filehandlesHeaders[i][j].begin()->first, filehandles[i][j].begin()->first);\r
-                    m->mothurRemove(filehandlesHeaders[i][j].begin()->first);\r
+                    m->appendBinaryFiles(filehandles[i][j], filehandlesHeaders[i][j]);\r
+                    m->renameFile(filehandlesHeaders[i][j], filehandles[i][j]);\r
+                    m->mothurRemove(filehandlesHeaders[i][j]);\r
                     //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << " done appending headers and removing " << filehandlesHeaders[i][j] << endl;\r
-                    if (numSplitReads[i][j] == 0) { m->mothurRemove(filehandles[i][j].begin()->first); }\r
+                    if (numSplitReads[i][j] == 0) { m->mothurRemove(filehandles[i][j]); }\r
                 }\r
             }\r
                        //cout << "here3" << endl;\r
@@ -733,7 +806,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,4);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -744,7 +820,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,4);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-               (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -765,7 +844,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         thisbuffer[7] = offset & 0xFF;\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {\r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(thisbuffer, 8);\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(thisbuffer, 8);\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(thisbuffer, 8);\r
@@ -784,7 +866,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         thisbuffer2[3] = offset & 0xFF;\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {\r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(thisbuffer2, 4);\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(thisbuffer2, 4);\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(thisbuffer2, 4);\r
@@ -809,7 +894,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
                     thisbuffer[2] = (numSplitReads[i][j] >> 16) & 0xFF;\r
                     thisbuffer[3] = (numSplitReads[i][j] >> 24) & 0xFF;\r
                  }\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(thisbuffer, 4);\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(thisbuffer, 4);\r
+                out.close();\r
                 delete[] thisbuffer;\r
             }\r
         }\r
@@ -834,7 +922,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,2);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -845,7 +936,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,2);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -856,7 +950,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,2);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -867,7 +964,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,1);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -878,7 +978,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,header.numFlowsPerRead);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -889,7 +992,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         in.read(mybuffer,header.keyLength);\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, in.gcount());\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, in.gcount());\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, in.gcount());\r
@@ -904,7 +1010,10 @@ int SffInfoCommand::adjustCommonHeader(CommonHeader header){
         mybuffer = new char[spot-spotInFile];\r
         for (int i = 0; i < filehandlesHeaders.size(); i++) { \r
             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
-                (*(filehandlesHeaders[i][j].begin()->second)).write(mybuffer, spot-spotInFile);\r
+                ofstream out;\r
+                m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
+                out.write(mybuffer, spot-spotInFile);\r
+                out.close();\r
             }\r
         }\r
         outNoMatchHeader.write(mybuffer, spot-spotInFile);\r
@@ -1031,9 +1140,12 @@ bool SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads,
             \r
             if (split > 1) { \r
                \r
-                int barcodeIndex, primerIndex;\r
-                int trashCodeLength = findGroup(header, read, barcodeIndex, primerIndex);\r
-                                \r
+                int barcodeIndex, primerIndex, trashCodeLength;\r
+                \r
+                if (hasOligos)      {  trashCodeLength = findGroup(header, read, barcodeIndex, primerIndex);                }\r
+                else if (hasGroup)  {  trashCodeLength = findGroup(header, read, barcodeIndex, primerIndex, "groupMode");   }\r
+                else {  m->mothurOut("[ERROR]: uh oh, we shouldn't be here...\n"); }\r
+\r
                 char * mybuffer;\r
                 mybuffer = new char [spot-startSpotInFile];\r
                 \r
@@ -1044,7 +1156,10 @@ bool SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads,
                 \r
                 \r
                 if(trashCodeLength == 0){\r
-                    (*(filehandles[barcodeIndex][primerIndex].begin()->second)).write(mybuffer, in2.gcount());\r
+                    ofstream out;\r
+                    m->openOutputFileBinaryAppend(filehandles[barcodeIndex][primerIndex], out);\r
+                    out.write(mybuffer, in2.gcount());\r
+                    out.close();\r
                     numSplitReads[barcodeIndex][primerIndex]++;\r
                                }\r
                                else{\r
@@ -1152,7 +1267,29 @@ int SffInfoCommand::findGroup(Header header, seqRead read, int& barcode, int& pr
                m->errorOut(e, "SffInfoCommand", "findGroup");\r
                exit(1);\r
        }\r
-}     \r
+}\r
+//**********************************************************************************************************************\r
+int SffInfoCommand::findGroup(Header header, seqRead read, int& barcode, int& primer, string groupMode) {\r
+       try {\r
+        string trashCode = "";\r
+        primer = 0;\r
+        \r
+        string group = groupMap->getGroup(header.name);\r
+        if (group == "not found") {     trashCode += "g";   } //scrap for group\r
+        else { //find file group\r
+            map<string, int>::iterator it = barcodes.find(group);\r
+            if (it != barcodes.end()) {\r
+                barcode = it->second;\r
+            }else { trashCode += "g"; }\r
+        }\r
+        \r
+        return trashCode.length();\r
+    }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "findGroup");\r
+               exit(1);\r
+       }\r
+}\r
 //**********************************************************************************************************************\r
 int SffInfoCommand::decodeName(string& timestamp, string& region, string& xy, string name) {\r
        try {\r
@@ -1685,7 +1822,7 @@ bool SffInfoCommand::readOligos(string oligoFile){
                \r
                while(!inOligos.eof()){\r
             \r
-                       inOligos >> type; \r
+                       inOligos >> type;\r
             \r
                        if(type[0] == '#'){\r
                                while (!inOligos.eof()) {       char c = inOligos.get();  if (c == 10 || c == 13){      break;  }       } // get rest of line if there's any crap there\r
@@ -1707,19 +1844,20 @@ bool SffInfoCommand::readOligos(string oligoFile){
                                        group = "";\r
                                        \r
                                        // get rest of line in case there is a primer name\r
-                                       while (!inOligos.eof()) {       \r
-                                               char c = inOligos.get(); \r
+                                       while (!inOligos.eof()) {\r
+                                               char c = inOligos.get();\r
                                                if (c == 10 || c == 13 || c == -1){     break;  }\r
                                                else if (c == 32 || c == 9){;} //space or tab\r
                                                else {  group += c;  }\r
-                                       } \r
+                                       }\r
                                        \r
                                        //check for repeat barcodes\r
                                        map<string, int>::iterator itPrime = primers.find(oligo);\r
                                        if (itPrime != primers.end()) { m->mothurOut("primer " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }\r
                                        \r
-                                       primers[oligo]=indexPrimer; indexPrimer++;              \r
+                                       primers[oligo]=indexPrimer; indexPrimer++;\r
                                        primerNameVector.push_back(group);\r
+                   \r
                                }else if(type == "REVERSE"){\r
                                        //Sequence oligoRC("reverse", oligo);\r
                                        //oligoRC.reverseComplement();\r
@@ -1728,6 +1866,7 @@ bool SffInfoCommand::readOligos(string oligoFile){
                                }\r
                                else if(type == "BARCODE"){\r
                                        inOligos >> group;\r
+                    \r
                                        \r
                                        //check for repeat barcodes\r
                                        map<string, int>::iterator itBar = barcodes.find(oligo);\r
@@ -1743,31 +1882,27 @@ bool SffInfoCommand::readOligos(string oligoFile){
                                else{   m->mothurOut("[WARNING]: " + type + " is not recognized as a valid type. Choices are forward, reverse, and barcode. Ignoring " + oligo + "."); m->mothurOutEndLine(); }\r
                        }\r
                        m->gobble(inOligos);\r
-               }       \r
+               }\r
                inOligos.close();\r
-               \r
+    \r
                if(barcodeNameVector.size() == 0 && primerNameVector[0] == ""){ split = 1;      }\r
-               \r
+    \r
                //add in potential combos\r
                if(barcodeNameVector.size() == 0){\r
                        barcodes[""] = 0;\r
-                       barcodeNameVector.push_back("");                        \r
+                       barcodeNameVector.push_back("");\r
                }\r
                \r
                if(primerNameVector.size() == 0){\r
                        primers[""] = 0;\r
-                       primerNameVector.push_back("");                 \r
+                       primerNameVector.push_back("");\r
                }\r
                \r
                filehandles.resize(barcodeNameVector.size());\r
-        for (int i = 0; i < filehandles.size(); i++) {\r
-            for (int j = 0; j < primerNameVector.size(); j++) {\r
-                ofstream* temp;\r
-                map<string, ofstream*> myMap; myMap[""] = temp;\r
-                filehandles[i].push_back(myMap);\r
-            }\r
-        }\r
-                       \r
+               for(int i=0;i<filehandles.size();i++){\r
+                       filehandles[i].assign(primerNameVector.size(), "");\r
+               }\r
+        \r
                if(split > 1){\r
                        set<string> uniqueNames; //used to cleanup outputFileNames\r
                        for(map<string, int>::iterator itBar = barcodes.begin();itBar != barcodes.end();itBar++){\r
@@ -1793,8 +1928,8 @@ bool SffInfoCommand::readOligos(string oligoFile){
                                                }\r
                                        }\r
                                        \r
-                                       ofstream* temp = new ofstream;\r
-                    map<string, string> variables; \r
+                                       ofstream temp;\r
+                    map<string, string> variables;\r
                     variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
                     variables["[group]"] = comboGroupName;\r
                                        string thisFilename = getOutputFileName("sff",variables);\r
@@ -1804,24 +1939,22 @@ bool SffInfoCommand::readOligos(string oligoFile){
                                                uniqueNames.insert(thisFilename);\r
                                        }\r
                                        \r
-                    map<string, ofstream*> myMap; myMap[thisFilename] = temp;\r
-                    m->openOutputFileBinary(thisFilename, *(temp));\r
-                                       filehandles[itBar->second][itPrimer->second] = myMap;\r
-                    map<string, ofstream*>::iterator itOfstream = filehandles[itBar->second][itPrimer->second].find("");\r
-                    if (itOfstream != filehandles[itBar->second][itPrimer->second].end()) { filehandles[itBar->second][itPrimer->second].erase(itOfstream); } //remove blank entry so we dont mess with .begin() above. code above assumes only 1 file name in the map\r
+                                       filehandles[itBar->second][itPrimer->second] = thisFilename;\r
+                                       temp.open(thisFilename.c_str(), ios::binary);           temp.close();\r
                                }\r
                        }\r
                }\r
                numFPrimers = primers.size();\r
         numLinkers = linker.size();\r
         numSpacers = spacer.size();\r
-        map<string, string> variables; \r
+        map<string, string> variables;\r
         variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
         variables["[group]"] = "scrap";\r
                noMatchFile = getOutputFileName("sff",variables);\r
         m->mothurRemove(noMatchFile);\r
         numNoMatch = 0;\r
         \r
+        \r
                bool allBlank = true;\r
                for (int i = 0; i < barcodeNameVector.size(); i++) {\r
                        if (barcodeNameVector[i] != "") {\r
@@ -1838,15 +1971,10 @@ bool SffInfoCommand::readOligos(string oligoFile){
                \r
         filehandlesHeaders.resize(filehandles.size());\r
         numSplitReads.resize(filehandles.size());\r
-        for (int i = 0; i < filehandles.size(); i++) { \r
-            numSplitReads[i].resize(filehandles[i].size(), 0); \r
+        for (int i = 0; i < filehandles.size(); i++) {\r
+            numSplitReads[i].resize(filehandles[i].size(), 0);\r
             for (int j = 0; j < filehandles[i].size(); j++) {\r
-                ofstream* temp = new ofstream;\r
-                map<string, ofstream* > myMap;\r
-                string thisHeader = (filehandles[i][j].begin())->first+"headers";\r
-                myMap[thisHeader] = temp;\r
-                m->openOutputFileBinary(thisHeader, *(temp));\r
-                filehandlesHeaders[i].push_back(myMap);\r
+                filehandlesHeaders[i].push_back(filehandles[i][j]+"headers");\r
             }\r
         }\r
         \r
@@ -1864,6 +1992,68 @@ bool SffInfoCommand::readOligos(string oligoFile){
                exit(1);\r
        }\r
 }\r
+//***************************************************************************************************************\r
+\r
+bool SffInfoCommand::readGroup(string oligoFile){\r
+       try {\r
+        filehandles.clear();\r
+        numSplitReads.clear();\r
+        filehandlesHeaders.clear();\r
+        barcodes.clear();\r
+        \r
+        groupMap = new GroupMap();\r
+        groupMap->readMap(oligoFile);\r
+    \r
+        //like barcodeNameVector - no primer names\r
+        vector<string> groups = groupMap->getNamesOfGroups();\r
+               \r
+               filehandles.resize(groups.size());\r
+        for (int i = 0; i < filehandles.size(); i++) {\r
+            for (int j = 0; j < 1; j++) {\r
+                \r
+                map<string, string> variables;\r
+                variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
+                variables["[group]"] = groups[i];\r
+                string thisFilename = getOutputFileName("sff",variables);\r
+                outputNames.push_back(thisFilename);\r
+                outputTypes["sff"].push_back(thisFilename);\r
+               \r
+                ofstream temp;\r
+                m->openOutputFileBinary(thisFilename, temp); temp.close();\r
+                filehandles[i].push_back(thisFilename);\r
+                barcodes[groups[i]] = i;\r
+            }\r
+        }\r
+        \r
+        map<string, string> variables;\r
+        variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
+        variables["[group]"] = "scrap";\r
+               noMatchFile = getOutputFileName("sff",variables);\r
+        m->mothurRemove(noMatchFile);\r
+        numNoMatch = 0;\r
+        \r
+               \r
+        filehandlesHeaders.resize(groups.size());\r
+        numSplitReads.resize(filehandles.size());\r
+        for (int i = 0; i < filehandles.size(); i++) {\r
+            numSplitReads[i].resize(filehandles[i].size(), 0);\r
+            for (int j = 0; j < filehandles[i].size(); j++) {\r
+                ofstream temp ;\r
+                string thisHeader = filehandles[i][j]+"headers";\r
+                m->openOutputFileBinary(thisHeader, temp); temp.close();\r
+                filehandlesHeaders[i].push_back(thisHeader);\r
+            }\r
+        }\r
+               \r
+               return true;\r
+               \r
+       }\r
+       catch(exception& e) {\r
+               m->errorOut(e, "SffInfoCommand", "readGroup");\r
+               exit(1);\r
+       }\r
+}\r
+\r
 //********************************************************************/\r
 string SffInfoCommand::reverseOligo(string oligo){\r
        try {\r