]> git.donarmstrong.com Git - mothur.git/blob - sffinfocommand.cpp
26d48320e685d28e94e8e5dc417e875484710b13
[mothur.git] / sffinfocommand.cpp
1 /*\r
2  *  sffinfocommand.cpp\r
3  *  Mothur\r
4  *\r
5  *  Created by westcott on 7/7/10.\r
6  *  Copyright 2010 Schloss Lab. All rights reserved.\r
7  *\r
8  */\r
9 \r
10 #include "sffinfocommand.h"\r
11 #include "endiannessmacros.h"\r
12 #include "trimoligos.h"\r
13 #include "sequence.hpp"\r
14 #include "qualityscores.h"\r
15 \r
16 //**********************************************************************************************************************\r
17 vector<string> SffInfoCommand::setParameters(){ \r
18         try {           \r
19                 CommandParameter psff("sff", "InputTypes", "", "", "none", "none", "none","",false,false,true); parameters.push_back(psff);\r
20         CommandParameter poligos("oligos", "InputTypes", "", "", "oligosGroup", "none", "none","",false,false); parameters.push_back(poligos);\r
21         CommandParameter pgroup("group", "InputTypes", "", "", "oligosGroup", "none", "none","",false,false); parameters.push_back(pgroup);\r
22                 CommandParameter paccnos("accnos", "InputTypes", "", "", "none", "none", "none","",false,false); parameters.push_back(paccnos);\r
23                 CommandParameter psfftxt("sfftxt", "String", "", "", "", "", "","",false,false); parameters.push_back(psfftxt);\r
24                 CommandParameter pflow("flow", "Boolean", "", "T", "", "", "","flow",false,false); parameters.push_back(pflow);\r
25                 CommandParameter ptrim("trim", "Boolean", "", "T", "", "", "","",false,false); parameters.push_back(ptrim);\r
26                 CommandParameter pfasta("fasta", "Boolean", "", "T", "", "", "","fasta",false,false); parameters.push_back(pfasta);\r
27                 CommandParameter pqfile("qfile", "Boolean", "", "T", "", "", "","qfile",false,false); parameters.push_back(pqfile);\r
28         CommandParameter ppdiffs("pdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(ppdiffs);\r
29                 CommandParameter pbdiffs("bdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pbdiffs);\r
30         CommandParameter pldiffs("ldiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pldiffs);\r
31                 CommandParameter psdiffs("sdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(psdiffs);\r
32         CommandParameter ptdiffs("tdiffs", "Number", "", "0", "", "", "","",false,false); parameters.push_back(ptdiffs);\r
33                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);\r
34                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);\r
35                 \r
36                 vector<string> myArray;\r
37                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }\r
38                 return myArray;\r
39         }\r
40         catch(exception& e) {\r
41                 m->errorOut(e, "SffInfoCommand", "setParameters");\r
42                 exit(1);\r
43         }\r
44 }\r
45 //**********************************************************************************************************************\r
46 string SffInfoCommand::getHelpString(){ \r
47         try {\r
48                 string helpString = "";\r
49                 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
50                 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
51                 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
52                 helpString += "The fasta parameter allows you to indicate if you would like a fasta formatted file generated.  Default=True. \n";\r
53                 helpString += "The qfile parameter allows you to indicate if you would like a quality file generated.  Default=True. \n";\r
54         helpString += "The oligos parameter allows you to provide an oligos file to split your sff file into separate sff files by barcode. \n";\r
55         helpString += "The group parameter allows you to provide a group file to split your sff file into separate sff files by group. \n";\r
56         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
57                 helpString += "The bdiffs parameter is used to specify the number of differences allowed in the barcode. The default is 0.\n";\r
58                 helpString += "The pdiffs parameter is used to specify the number of differences allowed in the primer. The default is 0.\n";\r
59         helpString += "The ldiffs parameter is used to specify the number of differences allowed in the linker. The default is 0.\n";\r
60                 helpString += "The sdiffs parameter is used to specify the number of differences allowed in the spacer. The default is 0.\n";\r
61                 helpString += "The flow parameter allows you to indicate if you would like a flowgram file generated.  Default=True. \n";\r
62                 helpString += "The sfftxt parameter allows you to indicate if you would like a sff.txt file generated.  Default=False. \n";\r
63                 helpString += "If you want to parse an existing sfftxt file into flow, fasta and quality file, enter the file name using the sfftxt parameter. \n";\r
64                 helpString += "The trim parameter allows you to indicate if you would like a sequences and quality scores trimmed to the clipQualLeft and clipQualRight values.  Default=True. \n";\r
65                 helpString += "The accnos parameter allows you to provide a accnos file containing the names of the sequences you would like extracted. You may enter multiple files by separating them by -'s. \n";\r
66                 helpString += "Example sffinfo(sff=mySffFile.sff, trim=F).\n";\r
67                 helpString += "Note: No spaces between parameter labels (i.e. sff), '=' and parameters (i.e.yourSffFileName).\n";\r
68                 return helpString;\r
69         }\r
70         catch(exception& e) {\r
71                 m->errorOut(e, "SffInfoCommand", "getHelpString");\r
72                 exit(1);\r
73         }\r
74 }\r
75 \r
76 //**********************************************************************************************************************\r
77 string SffInfoCommand::getOutputPattern(string type) {\r
78     try {\r
79         string pattern = "";\r
80         \r
81         if (type == "fasta")            {   pattern =  "[filename],fasta-[filename],[tag],fasta";   }\r
82         else if (type == "flow")    {   pattern =  "[filename],flow";   }\r
83         else if (type == "sfftxt")        {   pattern =  "[filename],sff.txt";   }\r
84         else if (type == "sff")        {   pattern =  "[filename],[group],sff";   }\r
85         else if (type == "qfile")       {   pattern =  "[filename],qual-[filename],[tag],qual";   }\r
86         else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }\r
87         \r
88         return pattern;\r
89     }\r
90     catch(exception& e) {\r
91         m->errorOut(e, "SffInfoCommand", "getOutputPattern");\r
92         exit(1);\r
93     }\r
94 }\r
95 //**********************************************************************************************************************\r
96 SffInfoCommand::SffInfoCommand(){       \r
97         try {\r
98                 abort = true; calledHelp = true; \r
99                 setParameters();\r
100                 vector<string> tempOutNames;\r
101                 outputTypes["fasta"] = tempOutNames;\r
102                 outputTypes["flow"] = tempOutNames;\r
103                 outputTypes["sfftxt"] = tempOutNames;\r
104                 outputTypes["qfile"] = tempOutNames;\r
105         outputTypes["sff"] = tempOutNames;\r
106         }\r
107         catch(exception& e) {\r
108                 m->errorOut(e, "SffInfoCommand", "SffInfoCommand");\r
109                 exit(1);\r
110         }\r
111 }\r
112 //**********************************************************************************************************************\r
113 \r
114 SffInfoCommand::SffInfoCommand(string option)  {\r
115         try {\r
116                 abort = false; calledHelp = false;   \r
117                 hasAccnos = false; hasOligos = false; hasGroup = false;\r
118         split = 1;\r
119                 \r
120                 //allow user to run help\r
121                 if(option == "help") { help(); abort = true; calledHelp = true; }\r
122                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}\r
123                 \r
124                 else {\r
125                         //valid paramters for this command\r
126                         vector<string> myArray = setParameters();\r
127                         \r
128                         OptionParser parser(option);\r
129                         map<string, string> parameters = parser.getParameters();\r
130                         \r
131                         ValidParameters validParameter;\r
132                         //check to make sure all parameters are valid for command\r
133                         for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) { \r
134                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }\r
135                         }\r
136                         \r
137                         //initialize outputTypes\r
138                         vector<string> tempOutNames;\r
139                         outputTypes["fasta"] = tempOutNames;\r
140                         outputTypes["flow"] = tempOutNames;\r
141                         outputTypes["sfftxt"] = tempOutNames;\r
142                         outputTypes["qfile"] = tempOutNames;\r
143             outputTypes["sff"] = tempOutNames;\r
144                         \r
145                         //if the user changes the output directory command factory will send this info to us in the output parameter \r
146                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }\r
147                         \r
148                         //if the user changes the input directory command factory will send this info to us in the output parameter \r
149                         string inputDir = validParameter.validFile(parameters, "inputdir", false);        if (inputDir == "not found"){ inputDir = "";          }\r
150 \r
151                         sffFilename = validParameter.validFile(parameters, "sff", false);\r
152                         if (sffFilename == "not found") { sffFilename = "";  }\r
153                         else { \r
154                                 m->splitAtDash(sffFilename, filenames);\r
155                                 \r
156                                 //go through files and make sure they are good, if not, then disregard them\r
157                                 for (int i = 0; i < filenames.size(); i++) {\r
158                                         bool ignore = false;\r
159                                         if (filenames[i] == "current") { \r
160                                                 filenames[i] = m->getSFFFile(); \r
161                                                 if (filenames[i] != "") {  m->mothurOut("Using " + filenames[i] + " as input file for the sff parameter where you had given current."); m->mothurOutEndLine(); }\r
162                                                 else {  \r
163                                                         m->mothurOut("You have no current sfffile, ignoring current."); m->mothurOutEndLine(); ignore=true; \r
164                                                         //erase from file list\r
165                                                         filenames.erase(filenames.begin()+i);\r
166                                                         i--;\r
167                                                 }\r
168                                         }\r
169                                         \r
170                                         if (!ignore) {\r
171                                                 if (inputDir != "") {\r
172                                                         string path = m->hasPath(filenames[i]);\r
173                                                         //if the user has not given a path then, add inputdir. else leave path alone.\r
174                                                         if (path == "") {       filenames[i] = inputDir + filenames[i];         }\r
175                                                 }\r
176                 \r
177                                                 ifstream in;\r
178                                                 int ableToOpen = m->openInputFile(filenames[i], in, "noerror");\r
179                                         \r
180                                                 //if you can't open it, try default location\r
181                                                 if (ableToOpen == 1) {\r
182                                                         if (m->getDefaultPath() != "") { //default path is set\r
183                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(filenames[i]);\r
184                                                                 m->mothurOut("Unable to open " + filenames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
185                                                                 ifstream in2;\r
186                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
187                                                                 in2.close();\r
188                                                                 filenames[i] = tryPath;\r
189                                                         }\r
190                                                 }\r
191                                                 \r
192                                                 //if you can't open it, try default location\r
193                                                 if (ableToOpen == 1) {\r
194                                                         if (m->getOutputDir() != "") { //default path is set\r
195                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(filenames[i]);\r
196                                                                 m->mothurOut("Unable to open " + filenames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
197                                                                 ifstream in2;\r
198                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
199                                                                 in2.close();\r
200                                                                 filenames[i] = tryPath;\r
201                                                         }\r
202                                                 }\r
203                                                 \r
204                                                 in.close();\r
205                                                 \r
206                                                 if (ableToOpen == 1) { \r
207                                                         m->mothurOut("Unable to open " + filenames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
208                                                         //erase from file list\r
209                                                         filenames.erase(filenames.begin()+i);\r
210                                                         i--;\r
211                                                 }else { m->setSFFFile(filenames[i]); }\r
212                                         }\r
213                                 }\r
214                                 \r
215                                 //make sure there is at least one valid file left\r
216                                 if (filenames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }\r
217                         }\r
218                         \r
219                         accnosName = validParameter.validFile(parameters, "accnos", false);\r
220                         if (accnosName == "not found") { accnosName = "";  }\r
221                         else { \r
222                                 hasAccnos = true;\r
223                                 m->splitAtDash(accnosName, accnosFileNames);\r
224                                 \r
225                                 //go through files and make sure they are good, if not, then disregard them\r
226                                 for (int i = 0; i < accnosFileNames.size(); i++) {\r
227                                         bool ignore = false;\r
228                                         if (accnosFileNames[i] == "current") { \r
229                                                 accnosFileNames[i] = m->getAccnosFile(); \r
230                                                 if (accnosFileNames[i] != "") {  m->mothurOut("Using " + accnosFileNames[i] + " as input file for the accnos parameter where you had given current."); m->mothurOutEndLine(); }\r
231                                                 else {  \r
232                                                         m->mothurOut("You have no current accnosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; \r
233                                                         //erase from file list\r
234                                                         accnosFileNames.erase(accnosFileNames.begin()+i);\r
235                                                         i--;\r
236                                                 }\r
237                                         }\r
238                                         \r
239                                         if (!ignore) {\r
240                                         \r
241                                                 if (inputDir != "") {\r
242                                                         string path = m->hasPath(accnosFileNames[i]);\r
243                                                         //if the user has not given a path then, add inputdir. else leave path alone.\r
244                                                         if (path == "") {       accnosFileNames[i] = inputDir + accnosFileNames[i];             }\r
245                                                 }\r
246                 \r
247                                                 ifstream in;\r
248                                                 int ableToOpen = m->openInputFile(accnosFileNames[i], in, "noerror");\r
249                                         \r
250                                                 //if you can't open it, try default location\r
251                                                 if (ableToOpen == 1) {\r
252                                                         if (m->getDefaultPath() != "") { //default path is set\r
253                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(accnosFileNames[i]);\r
254                                                                 m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
255                                                                 ifstream in2;\r
256                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
257                                                                 in2.close();\r
258                                                                 accnosFileNames[i] = tryPath;\r
259                                                         }\r
260                                                 }\r
261                                                 //if you can't open it, try default location\r
262                                                 if (ableToOpen == 1) {\r
263                                                         if (m->getOutputDir() != "") { //default path is set\r
264                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(accnosFileNames[i]);\r
265                                                                 m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
266                                                                 ifstream in2;\r
267                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
268                                                                 in2.close();\r
269                                                                 accnosFileNames[i] = tryPath;\r
270                                                         }\r
271                                                 }\r
272                                                 in.close();\r
273                                                 \r
274                                                 if (ableToOpen == 1) { \r
275                                                         m->mothurOut("Unable to open " + accnosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
276                                                         //erase from file list\r
277                                                         accnosFileNames.erase(accnosFileNames.begin()+i);\r
278                                                         i--;\r
279                                                 }\r
280                                         }\r
281                                 }\r
282                                 \r
283                                 //make sure there is at least one valid file left\r
284                                 if (accnosFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }\r
285                         }\r
286             \r
287             oligosfile = validParameter.validFile(parameters, "oligos", false);\r
288                         if (oligosfile == "not found") { oligosfile = "";  }\r
289                         else { \r
290                                 hasOligos = true;\r
291                                 m->splitAtDash(oligosfile, oligosFileNames);\r
292                                 \r
293                                 //go through files and make sure they are good, if not, then disregard them\r
294                                 for (int i = 0; i < oligosFileNames.size(); i++) {\r
295                                         bool ignore = false;\r
296                                         if (oligosFileNames[i] == "current") { \r
297                                                 oligosFileNames[i] = m->getOligosFile(); \r
298                                                 if (oligosFileNames[i] != "") {  m->mothurOut("Using " + oligosFileNames[i] + " as input file for the oligos parameter where you had given current."); m->mothurOutEndLine(); }\r
299                                                 else {  \r
300                                                         m->mothurOut("You have no current oligosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; \r
301                                                         //erase from file list\r
302                                                         oligosFileNames.erase(oligosFileNames.begin()+i);\r
303                                                         i--;\r
304                                                 }\r
305                                         }\r
306                                         \r
307                                         if (!ignore) {\r
308                         \r
309                                                 if (inputDir != "") {\r
310                                                         string path = m->hasPath(oligosFileNames[i]);\r
311                                                         //if the user has not given a path then, add inputdir. else leave path alone.\r
312                                                         if (path == "") {       oligosFileNames[i] = inputDir + oligosFileNames[i];             }\r
313                                                 }\r
314                         \r
315                                                 ifstream in;\r
316                                                 int ableToOpen = m->openInputFile(oligosFileNames[i], in, "noerror");\r
317                         \r
318                                                 //if you can't open it, try default location\r
319                                                 if (ableToOpen == 1) {\r
320                                                         if (m->getDefaultPath() != "") { //default path is set\r
321                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(oligosFileNames[i]);\r
322                                                                 m->mothurOut("Unable to open " + oligosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
323                                                                 ifstream in2;\r
324                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
325                                                                 in2.close();\r
326                                                                 oligosFileNames[i] = tryPath;\r
327                                                         }\r
328                                                 }\r
329                                                 //if you can't open it, try default location\r
330                                                 if (ableToOpen == 1) {\r
331                                                         if (m->getOutputDir() != "") { //default path is set\r
332                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(oligosFileNames[i]);\r
333                                                                 m->mothurOut("Unable to open " + oligosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
334                                                                 ifstream in2;\r
335                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
336                                                                 in2.close();\r
337                                                                 oligosFileNames[i] = tryPath;\r
338                                                         }\r
339                                                 }\r
340                                                 in.close();\r
341                                                 \r
342                                                 if (ableToOpen == 1) { \r
343                                                         m->mothurOut("Unable to open " + oligosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
344                                                         //erase from file list\r
345                                                         oligosFileNames.erase(oligosFileNames.begin()+i);\r
346                                                         i--;\r
347                                                 }\r
348                                         }\r
349                                 }\r
350                                 \r
351                                 //make sure there is at least one valid file left\r
352                                 if (oligosFileNames.size() == 0) { m->mothurOut("no valid oligos files."); m->mothurOutEndLine(); abort = true; }\r
353                         }\r
354             \r
355             groupfile = validParameter.validFile(parameters, "group", false);\r
356                         if (groupfile == "not found") { groupfile = "";  }\r
357                         else {\r
358                                 hasGroup = true;\r
359                                 m->splitAtDash(groupfile, groupFileNames);\r
360                                 \r
361                                 //go through files and make sure they are good, if not, then disregard them\r
362                                 for (int i = 0; i < groupFileNames.size(); i++) {\r
363                                         bool ignore = false;\r
364                                         if (groupFileNames[i] == "current") {\r
365                                                 groupFileNames[i] = m->getGroupFile();\r
366                                                 if (groupFileNames[i] != "") {  m->mothurOut("Using " + groupFileNames[i] + " as input file for the group parameter where you had given current."); m->mothurOutEndLine(); }\r
367                                                 else {\r
368                                                         m->mothurOut("You have no current group file, ignoring current."); m->mothurOutEndLine(); ignore=true;\r
369                                                         //erase from file list\r
370                                                         groupFileNames.erase(groupFileNames.begin()+i);\r
371                                                         i--;\r
372                                                 }\r
373                                         }\r
374                                         \r
375                                         if (!ignore) {\r
376                         \r
377                                                 if (inputDir != "") {\r
378                                                         string path = m->hasPath(groupFileNames[i]);\r
379                                                         //if the user has not given a path then, add inputdir. else leave path alone.\r
380                                                         if (path == "") {       groupFileNames[i] = inputDir + groupFileNames[i];               }\r
381                                                 }\r
382                         \r
383                                                 ifstream in;\r
384                                                 int ableToOpen = m->openInputFile(groupFileNames[i], in, "noerror");\r
385                         \r
386                                                 //if you can't open it, try default location\r
387                                                 if (ableToOpen == 1) {\r
388                                                         if (m->getDefaultPath() != "") { //default path is set\r
389                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(groupFileNames[i]);\r
390                                                                 m->mothurOut("Unable to open " + groupFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();\r
391                                                                 ifstream in2;\r
392                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
393                                                                 in2.close();\r
394                                                                 groupFileNames[i] = tryPath;\r
395                                                         }\r
396                                                 }\r
397                                                 //if you can't open it, try default location\r
398                                                 if (ableToOpen == 1) {\r
399                                                         if (m->getOutputDir() != "") { //default path is set\r
400                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(groupFileNames[i]);\r
401                                                                 m->mothurOut("Unable to open " + groupFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();\r
402                                                                 ifstream in2;\r
403                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");\r
404                                                                 in2.close();\r
405                                                                 groupFileNames[i] = tryPath;\r
406                                                         }\r
407                                                 }\r
408                                                 in.close();\r
409                                                 \r
410                                                 if (ableToOpen == 1) {\r
411                                                         m->mothurOut("Unable to open " + groupFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();\r
412                                                         //erase from file list\r
413                                                         groupFileNames.erase(groupFileNames.begin()+i);\r
414                                                         i--;\r
415                                                 }\r
416                                         }\r
417                                 }\r
418                                 \r
419                                 //make sure there is at least one valid file left\r
420                                 if (groupFileNames.size() == 0) { m->mothurOut("no valid group files."); m->mothurOutEndLine(); abort = true; }\r
421                         }\r
422 \r
423                         if (hasGroup) {\r
424                 split = 2;\r
425                                 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
426                         }\r
427             \r
428             if (hasOligos) {\r
429                 split = 2;\r
430                                 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
431                         }\r
432             \r
433             if (hasGroup && hasOligos) { m->mothurOut("You must enter ONLY ONE of the following: oligos or group."); m->mothurOutEndLine(); abort = true;}\r
434             \r
435                         if (hasAccnos) {\r
436                                 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
437                         }\r
438                         \r
439                         string temp = validParameter.validFile(parameters, "qfile", false);                     if (temp == "not found"){       temp = "T";                             }\r
440                         qual = m->isTrue(temp); \r
441                         \r
442                         temp = validParameter.validFile(parameters, "fasta", false);                            if (temp == "not found"){       temp = "T";                             }\r
443                         fasta = m->isTrue(temp); \r
444                         \r
445                         temp = validParameter.validFile(parameters, "flow", false);                                     if (temp == "not found"){       temp = "T";                             }\r
446                         flow = m->isTrue(temp); \r
447                         \r
448                         temp = validParameter.validFile(parameters, "trim", false);                                     if (temp == "not found"){       temp = "T";                             }\r
449                         trim = m->isTrue(temp); \r
450             \r
451             temp = validParameter.validFile(parameters, "bdiffs", false);               if (temp == "not found") { temp = "0"; }\r
452                         m->mothurConvert(temp, bdiffs);\r
453                         \r
454                         temp = validParameter.validFile(parameters, "pdiffs", false);           if (temp == "not found") { temp = "0"; }\r
455                         m->mothurConvert(temp, pdiffs);\r
456             \r
457             temp = validParameter.validFile(parameters, "ldiffs", false);               if (temp == "not found") { temp = "0"; }\r
458                         m->mothurConvert(temp, ldiffs);\r
459             \r
460             temp = validParameter.validFile(parameters, "sdiffs", false);               if (temp == "not found") { temp = "0"; }\r
461                         m->mothurConvert(temp, sdiffs);\r
462                         \r
463                         temp = validParameter.validFile(parameters, "tdiffs", false);           if (temp == "not found") { int tempTotal = pdiffs + bdiffs + ldiffs + sdiffs;  temp = toString(tempTotal); }\r
464                         m->mothurConvert(temp, tdiffs);\r
465                         \r
466                         if(tdiffs == 0){        tdiffs = bdiffs + pdiffs + ldiffs + sdiffs;     }\r
467             \r
468                         temp = validParameter.validFile(parameters, "sfftxt", false);                           \r
469                         if (temp == "not found")        {       temp = "F";      sfftxt = false; sfftxtFilename = "";           }\r
470                         else if (m->isTrue(temp))       {       sfftxt = true;          sfftxtFilename = "";                            }\r
471                         else {\r
472                                 //you are a filename\r
473                                 if (inputDir != "") {\r
474                                         map<string,string>::iterator it = parameters.find("sfftxt");\r
475                                         //user has given a template file\r
476                                         if(it != parameters.end()){ \r
477                                                 string path = m->hasPath(it->second);\r
478                                                 //if the user has not given a path then, add inputdir. else leave path alone.\r
479                                                 if (path == "") {       parameters["sfftxt"] = inputDir + it->second;           }\r
480                                         }\r
481                                 }\r
482                                 \r
483                                 sfftxtFilename = validParameter.validFile(parameters, "sfftxt", true);\r
484                                 if (sfftxtFilename == "not found") { sfftxtFilename = "";  }\r
485                                 else if (sfftxtFilename == "not open") { sfftxtFilename = "";  }\r
486                         }\r
487                         \r
488                         if ((sfftxtFilename == "") && (filenames.size() == 0)) {  \r
489                                 //if there is a current sff file, use it\r
490                                 string filename = m->getSFFFile(); \r
491                                 if (filename != "") { filenames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the sff parameter."); m->mothurOutEndLine(); }\r
492                                 else {  m->mothurOut("[ERROR]: you must provide a valid sff or sfftxt file."); m->mothurOutEndLine(); abort=true;  }\r
493                         }\r
494             \r
495             \r
496                 }\r
497         }\r
498         catch(exception& e) {\r
499                 m->errorOut(e, "SffInfoCommand", "SffInfoCommand");\r
500                 exit(1);\r
501         }\r
502 }\r
503 //**********************************************************************************************************************\r
504 int SffInfoCommand::execute(){\r
505         try {\r
506                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }\r
507                 \r
508                 for (int s = 0; s < filenames.size(); s++) {\r
509                         \r
510                         if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]);        } return 0; }\r
511                         \r
512                         int start = time(NULL);\r
513                         \r
514             filenames[s] = m->getFullPathName(filenames[s]);\r
515                         m->mothurOut("Extracting info from " + filenames[s] + " ..." ); m->mothurOutEndLine();\r
516                         \r
517                         string accnos = "";\r
518                         if (hasAccnos) { accnos = accnosFileNames[s]; }\r
519             \r
520             string oligos = "";\r
521             if (hasOligos) { oligos = oligosFileNames[s]; }\r
522             if (hasGroup) { oligos = groupFileNames[s]; }\r
523             \r
524                         int numReads = extractSffInfo(filenames[s], accnos, oligos);\r
525 \r
526                         m->mothurOut("It took " + toString(time(NULL) - start) + " secs to extract " + toString(numReads) + ".");\r
527                 }\r
528                 \r
529                 if (sfftxtFilename != "") {  parseSffTxt(); }\r
530                 \r
531                 if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]);        } return 0; }\r
532                 \r
533                 //set fasta file as new current fastafile\r
534                 string current = "";\r
535                 itTypes = outputTypes.find("fasta");\r
536                 if (itTypes != outputTypes.end()) {\r
537                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); }\r
538                 }\r
539                 \r
540                 itTypes = outputTypes.find("qfile");\r
541                 if (itTypes != outputTypes.end()) {\r
542                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setQualFile(current); }\r
543                 }\r
544                 \r
545                 itTypes = outputTypes.find("flow");\r
546                 if (itTypes != outputTypes.end()) {\r
547                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFlowFile(current); }\r
548                 }\r
549                 \r
550                 //report output filenames\r
551                 m->mothurOutEndLine();\r
552                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();\r
553                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }\r
554                 m->mothurOutEndLine();\r
555 \r
556                 return 0;\r
557         }\r
558         catch(exception& e) {\r
559                 m->errorOut(e, "SffInfoCommand", "execute");\r
560                 exit(1);\r
561         }\r
562 }\r
563 //**********************************************************************************************************************\r
564 int SffInfoCommand::extractSffInfo(string input, string accnos, string oligos){\r
565         try {\r
566                 currentFileName = input;\r
567                 if (outputDir == "") {  outputDir += m->hasPath(input); }\r
568                 \r
569                 if (accnos != "")       {  readAccnosFile(accnos);  }\r
570                 else                            {       seqNames.clear();               }\r
571         \r
572         if (hasOligos)   {   readOligos(oligos);    split = 2;      }\r
573         if (hasGroup)    {   readGroup(oligos);     split = 2;      }\r
574         \r
575                 ofstream outSfftxt, outFasta, outQual, outFlow;\r
576                 string outFastaFileName, outQualFileName;\r
577         string rootName = outputDir + m->getRootName(m->getSimpleName(input));\r
578         if(rootName.find_last_of(".") == rootName.npos){ rootName += "."; }\r
579         \r
580         map<string, string> variables; \r
581                 variables["[filename]"] = rootName;\r
582                 string sfftxtFileName = getOutputFileName("sfftxt",variables);\r
583                 string outFlowFileName = getOutputFileName("flow",variables);\r
584                 if (!trim) { variables["[tag]"] = "raw"; }\r
585                 outFastaFileName = getOutputFileName("fasta",variables);\r
586         outQualFileName = getOutputFileName("qfile",variables);\r
587         \r
588                 if (sfftxt) { m->openOutputFile(sfftxtFileName, outSfftxt); outSfftxt.setf(ios::fixed, ios::floatfield); outSfftxt.setf(ios::showpoint);  outputNames.push_back(sfftxtFileName);  outputTypes["sfftxt"].push_back(sfftxtFileName); }\r
589                 if (fasta)      { m->openOutputFile(outFastaFileName, outFasta);        outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); }\r
590                 if (qual)       { m->openOutputFile(outQualFileName, outQual);          outputNames.push_back(outQualFileName); outputTypes["qfile"].push_back(outQualFileName);  }\r
591                 if (flow)       { m->openOutputFile(outFlowFileName, outFlow);          outputNames.push_back(outFlowFileName);  outFlow.setf(ios::fixed, ios::floatfield); outFlow.setf(ios::showpoint); outputTypes["flow"].push_back(outFlowFileName);  }\r
592                 \r
593                 ifstream in;\r
594                 m->openInputFileBinary(input, in);\r
595                 \r
596                 CommonHeader header;\r
597                 readCommonHeader(in, header);\r
598         \r
599                 int count = 0;\r
600                 \r
601                 //check magic number and version\r
602                 if (header.magicNumber != 779314790) { m->mothurOut("Magic Number is not correct, not a valid .sff file"); m->mothurOutEndLine(); return count; }\r
603                 if (header.version != "0001") { m->mothurOut("Version is not supported, only support version 0001."); m->mothurOutEndLine(); return count; }\r
604         \r
605                 //print common header\r
606                 if (sfftxt) {   printCommonHeader(outSfftxt, header);           }\r
607                 if (flow)       {       outFlow << header.numFlowsPerRead << endl;      }\r
608                 \r
609                 //read through the sff file\r
610                 while (!in.eof()) {\r
611                         \r
612                         bool print = true;\r
613                                                 \r
614                         //read data\r
615                         seqRead read;  Header readheader;\r
616             readSeqData(in, read, header.numFlowsPerRead, readheader);\r
617             \r
618             bool okay = sanityCheck(readheader, read);\r
619             if (!okay) { break; }\r
620             \r
621                         //if you have provided an accosfile and this seq is not in it, then dont print\r
622                         if (seqNames.size() != 0) {   if (seqNames.count(readheader.name) == 0) { print = false; }  }\r
623                         \r
624                         //print \r
625                         if (print) {\r
626                                 if (sfftxt) { printHeader(outSfftxt, readheader); printSffTxtSeqData(outSfftxt, read, readheader); }\r
627                                 if (fasta)      {       printFastaSeqData(outFasta, read, readheader);  }\r
628                                 if (qual)       {       printQualSeqData(outQual, read, readheader);    }\r
629                                 if (flow)       {       printFlowSeqData(outFlow, read, readheader);    }\r
630                         }\r
631                         \r
632                         count++;\r
633             \r
634                         //report progress\r
635                         if((count+1) % 10000 == 0){     m->mothurOut(toString(count+1)); m->mothurOutEndLine();         }\r
636                 \r
637                         if (m->control_pressed) { count = 0; break;   }\r
638                         \r
639                         if (count >= header.numReads) { break; }\r
640                 }\r
641                 \r
642                 //report progress\r
643                 if (!m->control_pressed) {   if((count) % 10000 != 0){  m->mothurOut(toString(count)); m->mothurOutEndLine();           }  }\r
644                 \r
645                 in.close();\r
646                 \r
647                 if (sfftxt) {  outSfftxt.close();       }\r
648                 if (fasta)      {  outFasta.close();    }\r
649                 if (qual)       {  outQual.close();             }\r
650                 if (flow)       {  outFlow.close();             }\r
651                 \r
652         if (split > 1) {\r
653             //create new common headers for each file with the correct number of reads\r
654             adjustCommonHeader(header);\r
655             \r
656             if (hasGroup) { delete groupMap; }\r
657             \r
658             //cout << "here" << endl;\r
659                         map<string, string>::iterator it;\r
660                         set<string> namesToRemove;\r
661                         for(int i=0;i<filehandles.size();i++){\r
662                                 for(int j=0;j<filehandles[0].size();j++){\r
663                     //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << endl;\r
664                                         if (filehandles[i][j] != "") {\r
665                                                 if (namesToRemove.count(filehandles[i][j]) == 0) {\r
666                                                         if(m->isBlank(filehandles[i][j])){\r
667                                 //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << " is blank removing" << endl;\r
668                                                                 m->mothurRemove(filehandles[i][j]);\r
669                                 m->mothurRemove(filehandlesHeaders[i][j]);\r
670                                                                 namesToRemove.insert(filehandles[i][j]);\r
671                             }\r
672                                                 }\r
673                                         }\r
674                                 }\r
675                         }\r
676             //cout << "here2" << endl;\r
677             //append new header to reads\r
678             for (int i = 0; i < filehandles.size(); i++) {\r
679                 for (int j = 0; j < filehandles[i].size(); j++) {\r
680                     if (filehandles[i][j] != "") {\r
681                         m->appendBinaryFiles(filehandles[i][j], filehandlesHeaders[i][j]);\r
682                         m->renameFile(filehandlesHeaders[i][j], filehandles[i][j]);\r
683                         m->mothurRemove(filehandlesHeaders[i][j]);\r
684                         //cout << i << '\t' << '\t' << j  << '\t' << filehandles[i][j] << " done appending headers and removing " << filehandlesHeaders[i][j] << endl;\r
685                         if (numSplitReads[i][j] == 0) { m->mothurRemove(filehandles[i][j]); }\r
686                     }\r
687                 }\r
688             }\r
689                         //cout << "here3" << endl;\r
690                         //remove names for outputFileNames, just cleans up the output\r
691                         for(int i = 0; i < outputNames.size(); i++) { \r
692                 if (namesToRemove.count(outputNames[i]) != 0) {\r
693                     //cout << "erasing " << i << '\t' << outputNames[i] << endl;\r
694                     outputNames.erase(outputNames.begin()+i);\r
695                     i--;\r
696                 } \r
697             }\r
698             //cout << "here4" << endl;\r
699             if(m->isBlank(noMatchFile)){  m->mothurRemove(noMatchFile); }\r
700             else { outputNames.push_back(noMatchFile); outputTypes["sff"].push_back(noMatchFile); }\r
701         }\r
702         \r
703                 return count;\r
704         }\r
705         catch(exception& e) {\r
706                 m->errorOut(e, "SffInfoCommand", "extractSffInfo");\r
707                 exit(1);\r
708         }\r
709 }\r
710 //**********************************************************************************************************************\r
711 int SffInfoCommand::readCommonHeader(ifstream& in, CommonHeader& header){\r
712         try {\r
713         \r
714                 if (!in.eof()) {\r
715 \r
716                         //read magic number\r
717                         char buffer[4];\r
718                         in.read(buffer, 4);\r
719                         header.magicNumber = be_int4(*(unsigned int *)(&buffer));\r
720             \r
721                         //read version\r
722                         char buffer9[4];\r
723                         in.read(buffer9, 4);\r
724                         header.version = "";\r
725                         for (int i = 0; i < 4; i++) {  header.version += toString((int)(buffer9[i]));  }\r
726     \r
727                         //read offset\r
728                         char buffer2 [8];\r
729                         in.read(buffer2, 8);\r
730                         header.indexOffset =  be_int8(*(unsigned long long *)(&buffer2));\r
731                         \r
732                         //read index length\r
733                         char buffer3 [4];\r
734                         in.read(buffer3, 4);\r
735                         header.indexLength =  be_int4(*(unsigned int *)(&buffer3));\r
736             \r
737                         //read num reads\r
738                         char buffer4 [4];\r
739                         in.read(buffer4, 4);\r
740                         header.numReads =  be_int4(*(unsigned int *)(&buffer4));\r
741             \r
742             if (m->debug) { m->mothurOut("[DEBUG]: numReads = " + toString(header.numReads) + "\n"); }\r
743                                 \r
744                         //read header length\r
745                         char buffer5 [2];\r
746                         in.read(buffer5, 2);\r
747                         header.headerLength =  be_int2(*(unsigned short *)(&buffer5));\r
748                                         \r
749                         //read key length\r
750                         char buffer6 [2];\r
751                         in.read(buffer6, 2);\r
752                         header.keyLength = be_int2(*(unsigned short *)(&buffer6));\r
753                         \r
754                         //read number of flow reads\r
755                         char buffer7 [2];\r
756                         in.read(buffer7, 2);\r
757                         header.numFlowsPerRead =  be_int2(*(unsigned short *)(&buffer7));\r
758                                 \r
759                         //read format code\r
760                         char buffer8 [1];\r
761                         in.read(buffer8, 1);\r
762                         header.flogramFormatCode = (int)(buffer8[0]);\r
763                         \r
764                         //read flow chars\r
765                         char* tempBuffer = new char[header.numFlowsPerRead];\r
766                         in.read(&(*tempBuffer), header.numFlowsPerRead); \r
767                         header.flowChars = tempBuffer;\r
768                         if (header.flowChars.length() > header.numFlowsPerRead) { header.flowChars = header.flowChars.substr(0, header.numFlowsPerRead);  }\r
769                         delete[] tempBuffer;\r
770                         \r
771                         //read key\r
772                         char* tempBuffer2 = new char[header.keyLength];\r
773                         in.read(&(*tempBuffer2), header.keyLength);\r
774                         header.keySequence = tempBuffer2;\r
775                         if (header.keySequence.length() > header.keyLength) { header.keySequence = header.keySequence.substr(0, header.keyLength);  }\r
776                         delete[] tempBuffer2;\r
777                         \r
778                         /* Pad to 8 chars */\r
779                         unsigned long long spotInFile = in.tellg();\r
780                         unsigned long long spot = (spotInFile + 7)& ~7;  // ~ inverts\r
781                         in.seekg(spot);\r
782             \r
783         }else{\r
784                         m->mothurOut("Error reading sff common header."); m->mothurOutEndLine();\r
785                 }\r
786         \r
787                 return 0;\r
788         \r
789         }\r
790         catch(exception& e) {\r
791                 m->errorOut(e, "SffInfoCommand", "readCommonHeader");\r
792                 exit(1);\r
793         }\r
794 }\r
795 //**********************************************************************************************************************\r
796 int SffInfoCommand::adjustCommonHeader(CommonHeader header){\r
797         try {\r
798         string endian = m->findEdianness();\r
799         char* mybuffer = new char[4];\r
800         ifstream in;\r
801         m->openInputFileBinary(currentFileName, in);\r
802         \r
803         ofstream outNoMatchHeader;\r
804         string tempNoHeader = "tempNoMatchHeader";\r
805         m->openOutputFileBinary(tempNoHeader, outNoMatchHeader);\r
806         \r
807         //magic number\r
808         in.read(mybuffer,4);\r
809         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
810             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
811                 ofstream out;\r
812                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
813                 out.write(mybuffer, in.gcount());\r
814                 out.close();\r
815             }\r
816         }\r
817         outNoMatchHeader.write(mybuffer, in.gcount());\r
818         delete[] mybuffer;\r
819         \r
820         //version\r
821         mybuffer = new char[4];\r
822         in.read(mybuffer,4);\r
823         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
824             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
825                 ofstream out;\r
826                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
827                 out.write(mybuffer, in.gcount());\r
828                 out.close();\r
829             }\r
830         }\r
831         outNoMatchHeader.write(mybuffer, in.gcount());\r
832         delete[] mybuffer;\r
833         \r
834         //offset\r
835         mybuffer = new char[8];\r
836         in.read(mybuffer,8);\r
837         unsigned long long offset = 0;\r
838         char* thisbuffer = new char[8];\r
839         thisbuffer[0] = (offset >> 56) & 0xFF;\r
840         thisbuffer[1] = (offset >> 48) & 0xFF;\r
841         thisbuffer[2] = (offset >> 40) & 0xFF;\r
842         thisbuffer[3] = (offset >> 32) & 0xFF;\r
843         thisbuffer[4] = (offset >> 24) & 0xFF;\r
844         thisbuffer[5] = (offset >> 16) & 0xFF;\r
845         thisbuffer[6] = (offset >> 8) & 0xFF;\r
846         thisbuffer[7] = offset & 0xFF;\r
847         for (int i = 0; i < filehandlesHeaders.size(); i++) {\r
848             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
849                 ofstream out;\r
850                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
851                 out.write(thisbuffer, 8);\r
852                 out.close();\r
853             }\r
854         }\r
855         outNoMatchHeader.write(thisbuffer, 8);\r
856         delete[] thisbuffer;\r
857         delete[] mybuffer;\r
858             \r
859                         \r
860         //read index length\r
861                 mybuffer = new char[4];\r
862         in.read(mybuffer,4);\r
863         offset = 0;\r
864         char* thisbuffer2 = new char[4];\r
865         thisbuffer2[0] = (offset >> 24) & 0xFF;\r
866         thisbuffer2[1] = (offset >> 16) & 0xFF;\r
867         thisbuffer2[2] = (offset >> 8) & 0xFF;\r
868         thisbuffer2[3] = offset & 0xFF;\r
869         for (int i = 0; i < filehandlesHeaders.size(); i++) {\r
870             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
871                 ofstream out;\r
872                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
873                 out.write(thisbuffer2, 4);\r
874                 out.close();\r
875             }\r
876         }\r
877         outNoMatchHeader.write(thisbuffer2, 4);\r
878         delete[] thisbuffer2;\r
879         delete[] mybuffer;\r
880                 \r
881         //change num reads\r
882         mybuffer = new char[4];\r
883         in.read(mybuffer,4);\r
884         delete[] mybuffer;\r
885         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
886             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
887                 char* thisbuffer = new char[4];\r
888                 if (endian == "BIG_ENDIAN") {\r
889                     thisbuffer[0] = (numSplitReads[i][j] >> 24) & 0xFF;\r
890                     thisbuffer[1] = (numSplitReads[i][j] >> 16) & 0xFF;\r
891                     thisbuffer[2] = (numSplitReads[i][j] >> 8) & 0xFF;\r
892                     thisbuffer[3] = numSplitReads[i][j] & 0xFF;\r
893                 }else {\r
894                     thisbuffer[0] = numSplitReads[i][j] & 0xFF;\r
895                     thisbuffer[1] = (numSplitReads[i][j] >> 8) & 0xFF;\r
896                     thisbuffer[2] = (numSplitReads[i][j] >> 16) & 0xFF;\r
897                     thisbuffer[3] = (numSplitReads[i][j] >> 24) & 0xFF;\r
898                  }\r
899                 ofstream out;\r
900                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
901                 out.write(thisbuffer, 4);\r
902                 out.close();\r
903                 delete[] thisbuffer;\r
904             }\r
905         }\r
906         char* thisbuffer3 = new char[4];\r
907         if (endian == "BIG_ENDIAN") {\r
908             thisbuffer3[0] = (numNoMatch >> 24) & 0xFF;\r
909             thisbuffer3[1] = (numNoMatch >> 16) & 0xFF;\r
910             thisbuffer3[2] = (numNoMatch >> 8) & 0xFF;\r
911             thisbuffer3[3] = numNoMatch & 0xFF;\r
912         }else {\r
913             thisbuffer3[0] = numNoMatch & 0xFF;\r
914             thisbuffer3[1] = (numNoMatch >> 8) & 0xFF;\r
915             thisbuffer3[2] = (numNoMatch >> 16) & 0xFF;\r
916             thisbuffer3[3] = (numNoMatch >> 24) & 0xFF;\r
917         }\r
918         outNoMatchHeader.write(thisbuffer3, 4);\r
919         delete[] thisbuffer3;\r
920         \r
921         \r
922         //read header length\r
923         mybuffer = new char[2];\r
924         in.read(mybuffer,2);\r
925         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
926             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
927                 ofstream out;\r
928                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
929                 out.write(mybuffer, in.gcount());\r
930                 out.close();\r
931             }\r
932         }\r
933         outNoMatchHeader.write(mybuffer, in.gcount());\r
934         delete[] mybuffer;\r
935             \r
936         //read key length\r
937         mybuffer = new char[2];\r
938         in.read(mybuffer,2);\r
939         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
940             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
941                 ofstream out;\r
942                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
943                 out.write(mybuffer, in.gcount());\r
944                 out.close();\r
945             }\r
946         }\r
947         outNoMatchHeader.write(mybuffer, in.gcount());\r
948         delete[] mybuffer;\r
949                         \r
950         //read number of flow reads\r
951         mybuffer = new char[2];\r
952         in.read(mybuffer,2);\r
953         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
954             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
955                 ofstream out;\r
956                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
957                 out.write(mybuffer, in.gcount());\r
958                 out.close();\r
959             }\r
960         }\r
961         outNoMatchHeader.write(mybuffer, in.gcount());\r
962         delete[] mybuffer;\r
963             \r
964         //read format code\r
965         mybuffer = new char[1];\r
966         in.read(mybuffer,1);\r
967         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
968             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
969                 ofstream out;\r
970                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
971                 out.write(mybuffer, in.gcount());\r
972                 out.close();\r
973             }\r
974         }\r
975         outNoMatchHeader.write(mybuffer, in.gcount());\r
976         delete[] mybuffer;\r
977                         \r
978         //read flow chars\r
979         mybuffer = new char[header.numFlowsPerRead];\r
980         in.read(mybuffer,header.numFlowsPerRead);\r
981         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
982             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
983                 ofstream out;\r
984                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
985                 out.write(mybuffer, in.gcount());\r
986                 out.close();\r
987             }\r
988         }\r
989         outNoMatchHeader.write(mybuffer, in.gcount());\r
990         delete[] mybuffer;\r
991                         \r
992         //read key\r
993         mybuffer = new char[header.keyLength];\r
994         in.read(mybuffer,header.keyLength);\r
995         for (int i = 0; i < filehandlesHeaders.size(); i++) {  \r
996             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
997                 ofstream out;\r
998                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
999                 out.write(mybuffer, in.gcount());\r
1000                 out.close();\r
1001             }\r
1002         }\r
1003         outNoMatchHeader.write(mybuffer, in.gcount());\r
1004         delete[] mybuffer;\r
1005         \r
1006                         \r
1007         /* Pad to 8 chars */\r
1008         unsigned long long spotInFile = in.tellg();\r
1009         unsigned long long spot = (spotInFile + 7)& ~7;  // ~ inverts\r
1010         in.seekg(spot);\r
1011         \r
1012         mybuffer = new char[spot-spotInFile];\r
1013         for (int i = 0; i < filehandlesHeaders.size(); i++) { \r
1014             for (int j = 0; j < filehandlesHeaders[i].size(); j++) {\r
1015                 ofstream out;\r
1016                 m->openOutputFileBinaryAppend(filehandlesHeaders[i][j], out);\r
1017                 out.write(mybuffer, spot-spotInFile);\r
1018                 out.close();\r
1019             }\r
1020         }\r
1021         outNoMatchHeader.write(mybuffer, spot-spotInFile);\r
1022         outNoMatchHeader.close();\r
1023         delete[] mybuffer;\r
1024         in.close();\r
1025         \r
1026         m->appendBinaryFiles(noMatchFile, tempNoHeader);\r
1027         m->renameFile(tempNoHeader, noMatchFile);\r
1028         m->mothurRemove(tempNoHeader);\r
1029         \r
1030                 return 0;\r
1031         \r
1032         }\r
1033         catch(exception& e) {\r
1034                 m->errorOut(e, "SffInfoCommand", "adjustCommonHeader");\r
1035                 exit(1);\r
1036         }\r
1037 }\r
1038 //**********************************************************************************************************************\r
1039 bool SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads, Header& header){\r
1040         try {\r
1041         unsigned long long startSpotInFile = in.tellg();\r
1042                 if (!in.eof()) {\r
1043             \r
1044             /*****************************************/\r
1045             //read header\r
1046             \r
1047             //read header length\r
1048                         char buffer [2];\r
1049                         in.read(buffer, 2); \r
1050                         header.headerLength = be_int2(*(unsigned short *)(&buffer));\r
1051             \r
1052                         //read name length\r
1053                         char buffer2 [2];\r
1054                         in.read(buffer2, 2);\r
1055                         header.nameLength = be_int2(*(unsigned short *)(&buffer2));\r
1056             \r
1057                         //read num bases\r
1058                         char buffer3 [4];\r
1059                         in.read(buffer3, 4);\r
1060                         header.numBases =  be_int4(*(unsigned int *)(&buffer3));\r
1061             \r
1062                         \r
1063                         //read clip qual left\r
1064                         char buffer4 [2];\r
1065                         in.read(buffer4, 2);\r
1066                         header.clipQualLeft =  be_int2(*(unsigned short *)(&buffer4));\r
1067                         header.clipQualLeft = 5;\r
1068             \r
1069                         \r
1070                         //read clip qual right\r
1071                         char buffer5 [2];\r
1072                         in.read(buffer5, 2);\r
1073                         header.clipQualRight =  be_int2(*(unsigned short *)(&buffer5));\r
1074            \r
1075             \r
1076                         //read clipAdapterLeft\r
1077                         char buffer6 [2];\r
1078                         in.read(buffer6, 2);\r
1079                         header.clipAdapterLeft = be_int2(*(unsigned short *)(&buffer6));\r
1080             \r
1081             \r
1082                         //read clipAdapterRight\r
1083                         char buffer7 [2];\r
1084                         in.read(buffer7, 2);\r
1085                         header.clipAdapterRight = be_int2(*(unsigned short *)(&buffer7));\r
1086             \r
1087             \r
1088                         //read name\r
1089                         char* tempBuffer = new char[header.nameLength];\r
1090                         in.read(&(*tempBuffer), header.nameLength);\r
1091                         header.name = tempBuffer;\r
1092                         if (header.name.length() > header.nameLength) { header.name = header.name.substr(0, header.nameLength);  }\r
1093             \r
1094                         delete[] tempBuffer;\r
1095                         \r
1096                         //extract info from name\r
1097                         decodeName(header.timestamp, header.region, header.xy, header.name);\r
1098                         \r
1099                         /* Pad to 8 chars */\r
1100                         unsigned long long spotInFile = in.tellg();\r
1101                         unsigned long long spot = (spotInFile + 7)& ~7;\r
1102                         in.seekg(spot);\r
1103 \r
1104             /*****************************************/\r
1105             //sequence read \r
1106             \r
1107                         //read flowgram\r
1108                         read.flowgram.resize(numFlowReads);\r
1109                         for (int i = 0; i < numFlowReads; i++) {  \r
1110                                 char buffer [2];\r
1111                                 in.read(buffer, 2);\r
1112                                 read.flowgram[i] = be_int2(*(unsigned short *)(&buffer));\r
1113                         }\r
1114             \r
1115                         //read flowIndex\r
1116                         read.flowIndex.resize(header.numBases);\r
1117                         for (int i = 0; i < header.numBases; i++) {  \r
1118                                 char temp[1];\r
1119                                 in.read(temp, 1);\r
1120                                 read.flowIndex[i] = be_int1(*(unsigned char *)(&temp));\r
1121                         }\r
1122         \r
1123                         //read bases\r
1124                         char* tempBuffer6 = new char[header.numBases];\r
1125                         in.read(&(*tempBuffer6), header.numBases);\r
1126                         read.bases = tempBuffer6;\r
1127                         if (read.bases.length() > header.numBases) { read.bases = read.bases.substr(0, header.numBases);  }\r
1128                         delete[] tempBuffer6;\r
1129 \r
1130                         //read qual scores\r
1131                         read.qualScores.resize(header.numBases);\r
1132                         for (int i = 0; i < header.numBases; i++) {  \r
1133                                 char temp[1];\r
1134                                 in.read(temp, 1);\r
1135                                 read.qualScores[i] = be_int1(*(unsigned char *)(&temp));\r
1136                         }\r
1137         \r
1138                         /* Pad to 8 chars */\r
1139                         spotInFile = in.tellg();\r
1140                         spot = (spotInFile + 7)& ~7;\r
1141                         in.seekg(spot);\r
1142             \r
1143             if (split > 1) { \r
1144                \r
1145                 int barcodeIndex, primerIndex, trashCodeLength;\r
1146                 \r
1147                 if (hasOligos)      {  trashCodeLength = findGroup(header, read, barcodeIndex, primerIndex);                }\r
1148                 else if (hasGroup)  {  trashCodeLength = findGroup(header, read, barcodeIndex, primerIndex, "groupMode");   }\r
1149                 else {  m->mothurOut("[ERROR]: uh oh, we shouldn't be here...\n"); }\r
1150 \r
1151                 char * mybuffer;\r
1152                 mybuffer = new char [spot-startSpotInFile];\r
1153                 \r
1154                 ifstream in2;\r
1155                 m->openInputFileBinary(currentFileName, in2);\r
1156                 in2.seekg(startSpotInFile);\r
1157                 in2.read(mybuffer,spot-startSpotInFile);\r
1158                 \r
1159                 \r
1160                 if(trashCodeLength == 0){\r
1161                     ofstream out;\r
1162                     m->openOutputFileBinaryAppend(filehandles[barcodeIndex][primerIndex], out);\r
1163                     out.write(mybuffer, in2.gcount());\r
1164                     out.close();\r
1165                     numSplitReads[barcodeIndex][primerIndex]++;\r
1166                                 }\r
1167                                 else{\r
1168                                         ofstream out;\r
1169                     m->openOutputFileBinaryAppend(noMatchFile, out);\r
1170                     out.write(mybuffer, in2.gcount());\r
1171                     out.close();\r
1172                     numNoMatch++;\r
1173                                 }\r
1174                                 delete[] mybuffer;\r
1175                 in2.close();\r
1176         }    \r
1177             \r
1178                 }else{\r
1179                         m->mothurOut("Error reading."); m->mothurOutEndLine();\r
1180                 }\r
1181         \r
1182         if (in.eof()) {  return true; }\r
1183         \r
1184                 return false;\r
1185         }\r
1186         catch(exception& e) {\r
1187                 m->errorOut(e, "SffInfoCommand", "readSeqData");\r
1188                 exit(1);\r
1189         }\r
1190 }\r
1191 //**********************************************************************************************************************\r
1192 int SffInfoCommand::findGroup(Header header, seqRead read, int& barcode, int& primer) {\r
1193         try {\r
1194         //find group read belongs to\r
1195         TrimOligos trimOligos(pdiffs, bdiffs, ldiffs, sdiffs, primers, barcodes, revPrimer, linker, spacer);\r
1196         \r
1197         int success = 1;\r
1198         string trashCode = "";\r
1199         int currentSeqsDiffs = 0;\r
1200         \r
1201         string seq = read.bases;\r
1202         \r
1203         if (trim) {\r
1204             if(header.clipQualRight < header.clipQualLeft){\r
1205                 if (header.clipQualRight == 0) { //don't trim right\r
1206                     seq = seq.substr(header.clipQualLeft-1);\r
1207                 }else {\r
1208                     seq = "NNNN";\r
1209                 }\r
1210             }\r
1211             else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){\r
1212                 seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft));\r
1213             }\r
1214             else {\r
1215                 seq = seq.substr(header.clipQualLeft-1);\r
1216             }\r
1217         }else{\r
1218             //if you wanted the sfftxt then you already converted the bases to the right case\r
1219             if (!sfftxt) {\r
1220                 int endValue = header.clipQualRight;\r
1221                 //make the bases you want to clip lowercase and the bases you want to keep upper case\r
1222                 if(endValue == 0){      endValue = seq.length();        }\r
1223                 for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]);  }\r
1224                 for (int i = (header.clipQualLeft-1); i < (endValue-1); i++)  {   seq[i] = toupper(seq[i]);  }\r
1225                 for (int i = (endValue-1); i < seq.length(); i++) {   seq[i] = tolower(seq[i]);  }\r
1226             }\r
1227         }\r
1228         \r
1229         Sequence currSeq(header.name, seq);\r
1230         QualityScores currQual;\r
1231         \r
1232         if(numLinkers != 0){\r
1233             success = trimOligos.stripLinker(currSeq, currQual);\r
1234             if(success > ldiffs)                {       trashCode += 'k';       }\r
1235             else{ currentSeqsDiffs += success;  }\r
1236             \r
1237         }\r
1238         \r
1239         if(barcodes.size() != 0){\r
1240             success = trimOligos.stripBarcode(currSeq, currQual, barcode);\r
1241             if(success > bdiffs)                {       trashCode += 'b';       }\r
1242             else{ currentSeqsDiffs += success;  }\r
1243         }\r
1244         \r
1245         if(numSpacers != 0){\r
1246             success = trimOligos.stripSpacer(currSeq, currQual);\r
1247             if(success > sdiffs)                {       trashCode += 's';       }\r
1248             else{ currentSeqsDiffs += success;  }\r
1249             \r
1250         }\r
1251         \r
1252         if(numFPrimers != 0){\r
1253             success = trimOligos.stripForward(currSeq, currQual, primer, true);\r
1254             if(success > pdiffs)                {       trashCode += 'f';       }\r
1255             else{ currentSeqsDiffs += success;  }\r
1256         }\r
1257         \r
1258         if (currentSeqsDiffs > tdiffs)  {       trashCode += 't';   }\r
1259         \r
1260         if(revPrimer.size() != 0){\r
1261             success = trimOligos.stripReverse(currSeq, currQual);\r
1262             if(!success)                                {       trashCode += 'r';       }\r
1263         }\r
1264 \r
1265         if (trashCode.length() == 0) { //is this sequence in the ignore group\r
1266             string thisGroup = "";\r
1267             \r
1268             if(barcodes.size() != 0){\r
1269                 thisGroup = barcodeNameVector[barcode];\r
1270                 if (numFPrimers != 0) {\r
1271                     if (primerNameVector[primer] != "") {\r
1272                         if(thisGroup != "") {\r
1273                             thisGroup += "." + primerNameVector[primer];\r
1274                         }else {\r
1275                             thisGroup = primerNameVector[primer];\r
1276                         }\r
1277                     }\r
1278                 }\r
1279             }\r
1280             \r
1281             int pos = thisGroup.find("ignore");\r
1282             if (pos != string::npos) {  trashCode += "i"; }\r
1283         }\r
1284         \r
1285         return trashCode.length();\r
1286     }\r
1287         catch(exception& e) {\r
1288                 m->errorOut(e, "SffInfoCommand", "findGroup");\r
1289                 exit(1);\r
1290         }\r
1291 }\r
1292 //**********************************************************************************************************************\r
1293 int SffInfoCommand::findGroup(Header header, seqRead read, int& barcode, int& primer, string groupMode) {\r
1294         try {\r
1295         string trashCode = "";\r
1296         primer = 0;\r
1297         \r
1298         string group = groupMap->getGroup(header.name);\r
1299         if (group == "not found") {     trashCode += "g";   } //scrap for group\r
1300         else { //find file group\r
1301             map<string, int>::iterator it = barcodes.find(group);\r
1302             if (it != barcodes.end()) {\r
1303                 barcode = it->second;\r
1304             }else { trashCode += "g"; }\r
1305         }\r
1306         \r
1307         return trashCode.length();\r
1308     }\r
1309         catch(exception& e) {\r
1310                 m->errorOut(e, "SffInfoCommand", "findGroup");\r
1311                 exit(1);\r
1312         }\r
1313 }\r
1314 //**********************************************************************************************************************\r
1315 int SffInfoCommand::decodeName(string& timestamp, string& region, string& xy, string name) {\r
1316         try {\r
1317                 \r
1318                 if (name.length() >= 6) {\r
1319                         string time = name.substr(0, 6);\r
1320                         unsigned int timeNum = m->fromBase36(time);\r
1321                         \r
1322                         int q1 = timeNum / 60;\r
1323                         int sec = timeNum - 60 * q1;\r
1324                         int q2 = q1 / 60;\r
1325                         int minute = q1 - 60 * q2;\r
1326                         int q3 = q2 / 24;\r
1327                         int hr = q2 - 24 * q3;\r
1328                         int q4 = q3 / 32;\r
1329                         int day = q3 - 32 * q4;\r
1330                         int q5 = q4 / 13;\r
1331                         int mon = q4 - 13 * q5;\r
1332                         int year = 2000 + q5;\r
1333                 \r
1334                         timestamp = toString(year) + "_" + toString(mon) + "_" + toString(day) + "_" + toString(hr) + "_" + toString(minute) + "_" + toString(sec);\r
1335                 }\r
1336                 \r
1337                 if (name.length() >= 9) {\r
1338                         region = name.substr(7, 2);\r
1339                 \r
1340                         string xyNum = name.substr(9);\r
1341                         unsigned int myXy = m->fromBase36(xyNum);\r
1342                         int x = myXy >> 12;\r
1343                         int y = myXy & 4095;\r
1344                 \r
1345                         xy = toString(x) + "_" + toString(y);\r
1346                 }\r
1347                 \r
1348                 return 0;\r
1349         }\r
1350         catch(exception& e) {\r
1351                 m->errorOut(e, "SffInfoCommand", "decodeName");\r
1352                 exit(1);\r
1353         }\r
1354 }\r
1355 //**********************************************************************************************************************\r
1356 int SffInfoCommand::printCommonHeader(ofstream& out, CommonHeader& header) {\r
1357         try {\r
1358         \r
1359                 out << "Common Header:\nMagic Number: " << header.magicNumber << endl;\r
1360                 out << "Version: " << header.version << endl;\r
1361                 out << "Index Offset: " << header.indexOffset << endl;\r
1362                 out << "Index Length: " << header.indexLength << endl;\r
1363                 out << "Number of Reads: " << header.numReads << endl;\r
1364                 out << "Header Length: " << header.headerLength << endl;\r
1365                 out << "Key Length: " << header.keyLength << endl;\r
1366                 out << "Number of Flows: " << header.numFlowsPerRead << endl;\r
1367                 out << "Format Code: " << header.flogramFormatCode << endl;\r
1368                 out << "Flow Chars: " << header.flowChars << endl;\r
1369                 out << "Key Sequence: " << header.keySequence << endl << endl;\r
1370                         \r
1371                 return 0;\r
1372         }\r
1373         catch(exception& e) {\r
1374                 m->errorOut(e, "SffInfoCommand", "printCommonHeader");\r
1375                 exit(1);\r
1376         }\r
1377 }\r
1378 //**********************************************************************************************************************\r
1379 int SffInfoCommand::printHeader(ofstream& out, Header& header) {\r
1380         try {\r
1381                 \r
1382                 out << ">" << header.name << endl;\r
1383                 out << "Run Prefix: " << header.timestamp << endl;\r
1384                 out << "Region #:  " << header.region << endl;\r
1385                 out << "XY Location: " << header.xy << endl << endl;\r
1386                 \r
1387                 out << "Run Name:  " << endl;\r
1388                 out << "Analysis Name:  " << endl;\r
1389                 out << "Full Path: " << endl << endl;\r
1390                 \r
1391                 out << "Read Header Len: " << header.headerLength << endl;\r
1392                 out << "Name Length: " << header.nameLength << endl;\r
1393                 out << "# of Bases: " << header.numBases << endl;\r
1394                 out << "Clip Qual Left: " << header.clipQualLeft << endl;\r
1395                 out << "Clip Qual Right: " << header.clipQualRight << endl;\r
1396                 out << "Clip Adap Left: " << header.clipAdapterLeft << endl;\r
1397                 out << "Clip Adap Right: " << header.clipAdapterRight << endl << endl;\r
1398                 \r
1399                 return 0;\r
1400         }\r
1401         catch(exception& e) {\r
1402                 m->errorOut(e, "SffInfoCommand", "printHeader");\r
1403                 exit(1);\r
1404         }\r
1405 }\r
1406 //**********************************************************************************************************************\r
1407 bool SffInfoCommand::sanityCheck(Header& header, seqRead& read) {\r
1408         try {\r
1409         bool okay = true;\r
1410         string message = "[WARNING]: Your sff file may be corrupted! Sequence: " + header.name + "\n";\r
1411         \r
1412         if (header.clipQualLeft > read.bases.length()) {\r
1413             okay = false; message += "Clip Qual Left = " + toString(header.clipQualLeft) + ", but we only read " + toString(read.bases.length()) + " bases.\n";\r
1414         }\r
1415         if (header.clipQualRight > read.bases.length()) {\r
1416             okay = false; message += "Clip Qual Right = " + toString(header.clipQualRight) + ", but we only read " + toString(read.bases.length()) + " bases.\n";\r
1417         }\r
1418         if (header.clipQualLeft > read.qualScores.size()) {\r
1419             okay = false; message += "Clip Qual Left = " + toString(header.clipQualLeft) + ", but we only read " + toString(read.qualScores.size()) + " quality scores.\n";\r
1420         }\r
1421         if (header.clipQualRight > read.qualScores.size()) {\r
1422             okay = false; message += "Clip Qual Right = " + toString(header.clipQualRight) + ", but we only read " + toString(read.qualScores.size()) + " quality scores.\n";\r
1423         }\r
1424         \r
1425         if (okay == false) {\r
1426             m->mothurOut(message); m->mothurOutEndLine();\r
1427         }\r
1428         \r
1429                 return okay;\r
1430         }\r
1431         catch(exception& e) {\r
1432                 m->errorOut(e, "SffInfoCommand", "sanityCheck");\r
1433                 exit(1);\r
1434         }\r
1435 }\r
1436 //**********************************************************************************************************************\r
1437 int SffInfoCommand::printSffTxtSeqData(ofstream& out, seqRead& read, Header& header) {\r
1438         try {\r
1439                 out << "Flowgram: ";\r
1440                 for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << (read.flowgram[i]/(float)100) << '\t';  }\r
1441                 \r
1442                 out << endl <<  "Flow Indexes: ";\r
1443                 int sum = 0;\r
1444                 for (int i = 0; i < read.flowIndex.size(); i++) {  sum +=  read.flowIndex[i];  out << sum << '\t'; }\r
1445                 \r
1446                 //make the bases you want to clip lowercase and the bases you want to keep upper case\r
1447         int endValue = header.clipQualRight;\r
1448                 if(endValue == 0){      endValue = read.bases.length(); }\r
1449                 for (int i = 0; i < (header.clipQualLeft-1); i++) { read.bases[i] = tolower(read.bases[i]); }\r
1450                 for (int i = (header.clipQualLeft-1); i < (endValue-1); i++) {   read.bases[i] = toupper(read.bases[i]);  }\r
1451                 for (int i = (endValue-1); i < read.bases.length(); i++) {   read.bases[i] = tolower(read.bases[i]);  }\r
1452                 \r
1453                 out << endl <<  "Bases: " << read.bases << endl << "Quality Scores: ";\r
1454                 for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }\r
1455         \r
1456                 \r
1457                 out << endl << endl;\r
1458                 \r
1459                 return 0;\r
1460         }\r
1461         catch(exception& e) {\r
1462                 m->errorOut(e, "SffInfoCommand", "printSffTxtSeqData");\r
1463                 exit(1);\r
1464         }\r
1465 }\r
1466 //**********************************************************************************************************************\r
1467 int SffInfoCommand::printFastaSeqData(ofstream& out, seqRead& read, Header& header) {\r
1468         try {\r
1469                 string seq = read.bases;\r
1470                 \r
1471         if (trim) {\r
1472                         if(header.clipQualRight < header.clipQualLeft){\r
1473                                 if (header.clipQualRight == 0) { //don't trim right\r
1474                     seq = seq.substr(header.clipQualLeft-1);\r
1475                 }else {\r
1476                     seq = "NNNN";\r
1477                 }\r
1478                         }\r
1479                         else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){\r
1480                                 seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft));\r
1481                         }\r
1482                         else {\r
1483                                 seq = seq.substr(header.clipQualLeft-1);\r
1484                         }\r
1485                 }else{\r
1486                         //if you wanted the sfftxt then you already converted the bases to the right case\r
1487                         if (!sfftxt) {\r
1488                 int endValue = header.clipQualRight;\r
1489                                 //make the bases you want to clip lowercase and the bases you want to keep upper case\r
1490                                 if(endValue == 0){      endValue = seq.length();        }\r
1491                                 for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]);  }\r
1492                                 for (int i = (header.clipQualLeft-1); i < (endValue-1); i++)  {   seq[i] = toupper(seq[i]);  }\r
1493                                 for (int i = (endValue-1); i < seq.length(); i++) {   seq[i] = tolower(seq[i]);  }\r
1494                         }\r
1495                 }\r
1496                 \r
1497                 out << ">" << header.name  << " xy=" << header.xy << endl;\r
1498                 out << seq << endl;\r
1499                 \r
1500                 return 0;\r
1501         }\r
1502         catch(exception& e) {\r
1503                 m->errorOut(e, "SffInfoCommand", "printFastaSeqData");\r
1504                 exit(1);\r
1505         }\r
1506 }\r
1507 \r
1508 //**********************************************************************************************************************\r
1509 int SffInfoCommand::printQualSeqData(ofstream& out, seqRead& read, Header& header) {\r
1510         try {\r
1511                 \r
1512                 if (trim) {\r
1513                         if(header.clipQualRight < header.clipQualLeft){\r
1514                 if (header.clipQualRight == 0) { //don't trim right\r
1515                     out << ">" << header.name << " xy=" << header.xy << " length=" << (read.qualScores.size()-header.clipQualLeft) << endl;\r
1516                     for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';       }       \r
1517                 }else {\r
1518                     out << ">" << header.name << " xy=" << header.xy << endl;\r
1519                     out << "0\t0\t0\t0";\r
1520                 }\r
1521                         }\r
1522                         else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){\r
1523                                 out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;\r
1524                                 for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) {   out << read.qualScores[i] << '\t'; }\r
1525                         }\r
1526                         else{\r
1527                                 out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;\r
1528                                 for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';   }                       \r
1529                         }\r
1530                 }else{\r
1531                         out << ">" << header.name << " xy=" << header.xy << " length=" << read.qualScores.size() << endl;\r
1532                         for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }\r
1533                 }\r
1534                 \r
1535                 out << endl;\r
1536                 \r
1537                 return 0;\r
1538         }\r
1539         catch(exception& e) {\r
1540                 m->errorOut(e, "SffInfoCommand", "printQualSeqData");\r
1541                 exit(1);\r
1542         }\r
1543 }\r
1544 \r
1545 //**********************************************************************************************************************\r
1546 int SffInfoCommand::printFlowSeqData(ofstream& out, seqRead& read, Header& header) {\r
1547         try {\r
1548         \r
1549         int endValue = header.clipQualRight;\r
1550         if (header.clipQualRight == 0) {\r
1551             endValue = read.flowIndex.size();\r
1552             if (m->debug) { m->mothurOut("[DEBUG]: " + header.name + " has clipQualRight=0.\n"); }\r
1553         }\r
1554         if(endValue > header.clipQualLeft){\r
1555             \r
1556             int rightIndex = 0;\r
1557             for (int i = 0; i < endValue; i++) {  rightIndex +=  read.flowIndex[i];      }\r
1558             \r
1559             out << header.name << ' ' << rightIndex;\r
1560             for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << ' ' << (read.flowgram[i]/(float)100);  }\r
1561             out << endl;\r
1562         }\r
1563                 \r
1564                 \r
1565                 return 0;\r
1566         }\r
1567         catch(exception& e) {\r
1568                 m->errorOut(e, "SffInfoCommand", "printFlowSeqData");\r
1569                 exit(1);\r
1570         }\r
1571 }\r
1572 //**********************************************************************************************************************\r
1573 int SffInfoCommand::readAccnosFile(string filename) {\r
1574         try {\r
1575                 //remove old names\r
1576                 seqNames.clear();\r
1577                 \r
1578                 ifstream in;\r
1579                 m->openInputFile(filename, in);\r
1580                 string name;\r
1581                 \r
1582                 while(!in.eof()){\r
1583                         in >> name; m->gobble(in);\r
1584                                                 \r
1585                         seqNames.insert(name);\r
1586                         \r
1587                         if (m->control_pressed) { seqNames.clear(); break; }\r
1588                 }\r
1589                 in.close();             \r
1590                 \r
1591                 return 0;\r
1592         }\r
1593         catch(exception& e) {\r
1594                 m->errorOut(e, "SffInfoCommand", "readAccnosFile");\r
1595                 exit(1);\r
1596         }\r
1597 }\r
1598 //**********************************************************************************************************************\r
1599 int SffInfoCommand::parseSffTxt() {\r
1600         try {\r
1601                 \r
1602                 ifstream inSFF;\r
1603                 m->openInputFile(sfftxtFilename, inSFF);\r
1604                 \r
1605                 if (outputDir == "") {  outputDir += m->hasPath(sfftxtFilename); }\r
1606                 \r
1607                 //output file names\r
1608                 ofstream outFasta, outQual, outFlow;\r
1609                 string outFastaFileName, outQualFileName;\r
1610                 string fileRoot = m->getRootName(m->getSimpleName(sfftxtFilename));\r
1611                 if (fileRoot.length() > 0) {\r
1612                         //rip off last .\r
1613                         fileRoot = fileRoot.substr(0, fileRoot.length()-1);\r
1614                         fileRoot = m->getRootName(fileRoot);\r
1615                 }\r
1616                 \r
1617         map<string, string> variables; \r
1618                 variables["[filename]"] = fileRoot;\r
1619                 string sfftxtFileName = getOutputFileName("sfftxt",variables);\r
1620                 string outFlowFileName = getOutputFileName("flow",variables);\r
1621                 if (!trim) { variables["[tag]"] = "raw"; }\r
1622                 outFastaFileName = getOutputFileName("fasta",variables);\r
1623         outQualFileName = getOutputFileName("qfile",variables);\r
1624                 \r
1625                 if (fasta)      { m->openOutputFile(outFastaFileName, outFasta);        outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); }\r
1626                 if (qual)       { m->openOutputFile(outQualFileName, outQual);          outputNames.push_back(outQualFileName); outputTypes["qfile"].push_back(outQualFileName);  }\r
1627                 if (flow)       { m->openOutputFile(outFlowFileName, outFlow);          outputNames.push_back(outFlowFileName);  outFlow.setf(ios::fixed, ios::floatfield); outFlow.setf(ios::showpoint); outputTypes["flow"].push_back(outFlowFileName);  }\r
1628                 \r
1629                 //read common header\r
1630                 string commonHeader = m->getline(inSFF);\r
1631                 string magicNumber = m->getline(inSFF); \r
1632                 string version = m->getline(inSFF);\r
1633                 string indexOffset = m->getline(inSFF);\r
1634                 string indexLength = m->getline(inSFF);\r
1635                 int numReads = parseHeaderLineToInt(inSFF);\r
1636                 string headerLength = m->getline(inSFF);\r
1637                 string keyLength = m->getline(inSFF);\r
1638                 int numFlows = parseHeaderLineToInt(inSFF);\r
1639                 string flowgramCode = m->getline(inSFF);\r
1640                 string flowChars = m->getline(inSFF);\r
1641                 string keySequence = m->getline(inSFF);\r
1642                 m->gobble(inSFF);\r
1643                 \r
1644                 string seqName;\r
1645                 \r
1646                 if (flow)       {       outFlow << numFlows << endl;    }\r
1647                 \r
1648                 for(int i=0;i<numReads;i++){\r
1649                         \r
1650                         //sanity check\r
1651                         if (inSFF.eof()) { m->mothurOut("[ERROR]: Expected " + toString(numReads) + " but reached end of file at " + toString(i+1) + "."); m->mothurOutEndLine(); break; }\r
1652                         \r
1653                         Header header;\r
1654                         \r
1655                         //parse read header\r
1656                         inSFF >> seqName;\r
1657                         seqName = seqName.substr(1);\r
1658                         m->gobble(inSFF);\r
1659                         header.name = seqName;\r
1660                         \r
1661                         string runPrefix = parseHeaderLineToString(inSFF);              header.timestamp = runPrefix;\r
1662                         string regionNumber = parseHeaderLineToString(inSFF);   header.region = regionNumber;\r
1663                         string xyLocation = parseHeaderLineToString(inSFF);             header.xy = xyLocation;\r
1664                         m->gobble(inSFF);\r
1665                                 \r
1666                         string runName = parseHeaderLineToString(inSFF);\r
1667                         string analysisName = parseHeaderLineToString(inSFF);\r
1668                         string fullPath = parseHeaderLineToString(inSFF);\r
1669                         m->gobble(inSFF);\r
1670                         \r
1671                         string readHeaderLen = parseHeaderLineToString(inSFF);  convert(readHeaderLen, header.headerLength);\r
1672                         string nameLength = parseHeaderLineToString(inSFF);             convert(nameLength, header.nameLength);\r
1673                         int numBases = parseHeaderLineToInt(inSFF);                             header.numBases = numBases;\r
1674                         string clipQualLeft = parseHeaderLineToString(inSFF);   convert(clipQualLeft, header.clipQualLeft);\r
1675                         int clipQualRight = parseHeaderLineToInt(inSFF);                header.clipQualRight = clipQualRight;\r
1676                         string clipAdapLeft = parseHeaderLineToString(inSFF);   convert(clipAdapLeft, header.clipAdapterLeft);\r
1677                         string clipAdapRight = parseHeaderLineToString(inSFF);  convert(clipAdapRight, header.clipAdapterRight);\r
1678                         m->gobble(inSFF);\r
1679                                 \r
1680                         seqRead read;\r
1681                         \r
1682                         //parse read\r
1683                         vector<unsigned short> flowVector = parseHeaderLineToFloatVector(inSFF, numFlows);      read.flowgram = flowVector;\r
1684                         vector<unsigned int> flowIndices = parseHeaderLineToIntVector(inSFF, numBases); \r
1685                         \r
1686                         //adjust for print\r
1687                         vector<unsigned int> flowIndicesAdjusted; flowIndicesAdjusted.push_back(flowIndices[0]);\r
1688                         for (int j = 1; j < flowIndices.size(); j++) {   flowIndicesAdjusted.push_back(flowIndices[j] - flowIndices[j-1]);   }\r
1689                         read.flowIndex = flowIndicesAdjusted;\r
1690                         \r
1691                         string bases = parseHeaderLineToString(inSFF);                                                                          read.bases = bases;\r
1692                         vector<unsigned int> qualityScores = parseHeaderLineToIntVector(inSFF, numBases);       read.qualScores = qualityScores;\r
1693                         m->gobble(inSFF);\r
1694                                         \r
1695                         //if you have provided an accosfile and this seq is not in it, then dont print\r
1696                         bool print = true;\r
1697                         if (seqNames.size() != 0) {   if (seqNames.count(header.name) == 0) { print = false; }  }\r
1698                         \r
1699                         //print \r
1700                         if (print) {\r
1701                                 if (fasta)      {       printFastaSeqData(outFasta, read, header);      }\r
1702                                 if (qual)       {       printQualSeqData(outQual, read, header);        }\r
1703                                 if (flow)       {       printFlowSeqData(outFlow, read, header);        }\r
1704                         }\r
1705                         \r
1706                         //report progress\r
1707                         if((i+1) % 10000 == 0){ m->mothurOut(toString(i+1)); m->mothurOutEndLine();             }\r
1708                         \r
1709                         if (m->control_pressed) {  break;  }\r
1710                 }\r
1711                 \r
1712                 //report progress\r
1713                 if (!m->control_pressed) {   if((numReads) % 10000 != 0){       m->mothurOut(toString(numReads)); m->mothurOutEndLine();                }  }\r
1714                 \r
1715                 inSFF.close();\r
1716                 \r
1717                 if (fasta)      {  outFasta.close();    }\r
1718                 if (qual)       {  outQual.close();             }\r
1719                 if (flow)       {  outFlow.close();             }\r
1720                 \r
1721                 return 0;\r
1722         }\r
1723         catch(exception& e) {\r
1724                 m->errorOut(e, "SffInfoCommand", "parseSffTxt");\r
1725                 exit(1);\r
1726         }\r
1727 }\r
1728 //**********************************************************************************************************************\r
1729 \r
1730 int SffInfoCommand::parseHeaderLineToInt(ifstream& file){\r
1731         try {\r
1732                 int number;\r
1733                 \r
1734                 while (!file.eof())     {\r
1735                         \r
1736                         char c = file.get(); \r
1737                         if (c == ':'){\r
1738                                 file >> number;\r
1739                                 break;\r
1740                         }\r
1741                         \r
1742                 }\r
1743                 m->gobble(file);\r
1744                 return number;\r
1745         }\r
1746         catch(exception& e) {\r
1747                 m->errorOut(e, "SffInfoCommand", "parseHeaderLineToInt");\r
1748                 exit(1);\r
1749         }\r
1750         \r
1751 }\r
1752 \r
1753 //**********************************************************************************************************************\r
1754 \r
1755 string SffInfoCommand::parseHeaderLineToString(ifstream& file){\r
1756         try {\r
1757                 string text;\r
1758                 \r
1759                 while (!file.eof())     {\r
1760                         char c = file.get(); \r
1761                         \r
1762                         if (c == ':'){\r
1763                                 //m->gobble(file);\r
1764                                 //text = m->getline(file);      \r
1765                                 file >> text;\r
1766                                 break;\r
1767                         }\r
1768                 }\r
1769                 m->gobble(file);\r
1770                 \r
1771                 return text;\r
1772         }\r
1773         catch(exception& e) {\r
1774                 m->errorOut(e, "SffInfoCommand", "parseHeaderLineToString");\r
1775                 exit(1);\r
1776         }\r
1777 }\r
1778 \r
1779 //**********************************************************************************************************************\r
1780 \r
1781 vector<unsigned short> SffInfoCommand::parseHeaderLineToFloatVector(ifstream& file, int length){\r
1782         try {\r
1783                 vector<unsigned short> floatVector(length);\r
1784                 \r
1785                 while (!file.eof())     {\r
1786                         char c = file.get(); \r
1787                         if (c == ':'){\r
1788                                 float temp;\r
1789                                 for(int i=0;i<length;i++){\r
1790                                         file >> temp;\r
1791                                         floatVector[i] = temp * 100;\r
1792                                 }\r
1793                                 break;\r
1794                         }\r
1795                 }\r
1796                 m->gobble(file);        \r
1797                 return floatVector;\r
1798         }\r
1799         catch(exception& e) {\r
1800                 m->errorOut(e, "SffInfoCommand", "parseHeaderLineToFloatVector");\r
1801                 exit(1);\r
1802         }\r
1803 }\r
1804 \r
1805 //**********************************************************************************************************************\r
1806 \r
1807 vector<unsigned int> SffInfoCommand::parseHeaderLineToIntVector(ifstream& file, int length){\r
1808         try {\r
1809                 vector<unsigned int> intVector(length);\r
1810                 \r
1811                 while (!file.eof())     {\r
1812                         char c = file.get(); \r
1813                         if (c == ':'){\r
1814                                 for(int i=0;i<length;i++){\r
1815                                         file >> intVector[i];\r
1816                                 }\r
1817                                 break;\r
1818                         }\r
1819                 }\r
1820                 m->gobble(file);        \r
1821                 return intVector;\r
1822         }\r
1823         catch(exception& e) {\r
1824                 m->errorOut(e, "SffInfoCommand", "parseHeaderLineToIntVector");\r
1825                 exit(1);\r
1826         }\r
1827 }\r
1828 //***************************************************************************************************************\r
1829 \r
1830 bool SffInfoCommand::readOligos(string oligoFile){\r
1831         try {\r
1832         filehandles.clear();\r
1833         numSplitReads.clear();\r
1834         filehandlesHeaders.clear();\r
1835         \r
1836                 ifstream inOligos;\r
1837                 m->openInputFile(oligoFile, inOligos);\r
1838                 \r
1839                 string type, oligo, group;\r
1840         \r
1841                 int indexPrimer = 0;\r
1842                 int indexBarcode = 0;\r
1843                 \r
1844                 while(!inOligos.eof()){\r
1845             \r
1846                         inOligos >> type;\r
1847             \r
1848                         if(type[0] == '#'){\r
1849                                 while (!inOligos.eof()) {       char c = inOligos.get();  if (c == 10 || c == 13){      break;  }       } // get rest of line if there's any crap there\r
1850                                 m->gobble(inOligos);\r
1851                         }\r
1852                         else{\r
1853                                 m->gobble(inOligos);\r
1854                                 //make type case insensitive\r
1855                                 for(int i=0;i<type.length();i++){       type[i] = toupper(type[i]);  }\r
1856                                 \r
1857                                 inOligos >> oligo;\r
1858                                 \r
1859                                 for(int i=0;i<oligo.length();i++){\r
1860                                         oligo[i] = toupper(oligo[i]);\r
1861                                         if(oligo[i] == 'U')     {       oligo[i] = 'T'; }\r
1862                                 }\r
1863                                 \r
1864                                 if(type == "FORWARD"){\r
1865                                         group = "";\r
1866                                         \r
1867                                         // get rest of line in case there is a primer name\r
1868                                         while (!inOligos.eof()) {\r
1869                                                 char c = inOligos.get();\r
1870                                                 if (c == 10 || c == 13 || c == -1){     break;  }\r
1871                                                 else if (c == 32 || c == 9){;} //space or tab\r
1872                                                 else {  group += c;  }\r
1873                                         }\r
1874                                         \r
1875                                         //check for repeat barcodes\r
1876                                         map<string, int>::iterator itPrime = primers.find(oligo);\r
1877                                         if (itPrime != primers.end()) { m->mothurOut("primer " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }\r
1878                                         \r
1879                                         primers[oligo]=indexPrimer; indexPrimer++;\r
1880                                         primerNameVector.push_back(group);\r
1881                    \r
1882                                 }else if(type == "REVERSE"){\r
1883                                         //Sequence oligoRC("reverse", oligo);\r
1884                                         //oligoRC.reverseComplement();\r
1885                     string oligoRC = reverseOligo(oligo);\r
1886                                         revPrimer.push_back(oligoRC);\r
1887                                 }\r
1888                                 else if(type == "BARCODE"){\r
1889                                         inOligos >> group;\r
1890                     \r
1891                                         \r
1892                                         //check for repeat barcodes\r
1893                                         map<string, int>::iterator itBar = barcodes.find(oligo);\r
1894                                         if (itBar != barcodes.end()) { m->mothurOut("barcode " + oligo + " is in your oligos file already."); m->mothurOutEndLine();  }\r
1895                     \r
1896                                         barcodes[oligo]=indexBarcode; indexBarcode++;\r
1897                                         barcodeNameVector.push_back(group);\r
1898                                 }else if(type == "LINKER"){\r
1899                                         linker.push_back(oligo);\r
1900                                 }else if(type == "SPACER"){\r
1901                                         spacer.push_back(oligo);\r
1902                                 }\r
1903                                 else{   m->mothurOut("[WARNING]: " + type + " is not recognized as a valid type. Choices are forward, reverse, and barcode. Ignoring " + oligo + "."); m->mothurOutEndLine(); }\r
1904                         }\r
1905                         m->gobble(inOligos);\r
1906                 }\r
1907                 inOligos.close();\r
1908     \r
1909                 if(barcodeNameVector.size() == 0 && primerNameVector[0] == ""){ split = 1;      }\r
1910     \r
1911                 //add in potential combos\r
1912                 if(barcodeNameVector.size() == 0){\r
1913                         barcodes[""] = 0;\r
1914                         barcodeNameVector.push_back("");\r
1915                 }\r
1916                 \r
1917                 if(primerNameVector.size() == 0){\r
1918                         primers[""] = 0;\r
1919                         primerNameVector.push_back("");\r
1920                 }\r
1921                 \r
1922                 filehandles.resize(barcodeNameVector.size());\r
1923                 for(int i=0;i<filehandles.size();i++){\r
1924                         filehandles[i].assign(primerNameVector.size(), "");\r
1925                 }\r
1926         \r
1927                 if(split > 1){\r
1928                         set<string> uniqueNames; //used to cleanup outputFileNames\r
1929                         for(map<string, int>::iterator itBar = barcodes.begin();itBar != barcodes.end();itBar++){\r
1930                                 for(map<string, int>::iterator itPrimer = primers.begin();itPrimer != primers.end(); itPrimer++){\r
1931                                         \r
1932                                         string primerName = primerNameVector[itPrimer->second];\r
1933                                         string barcodeName = barcodeNameVector[itBar->second];\r
1934                                         \r
1935                     if ((primerName == "ignore") || (barcodeName == "ignore")) { } //do nothing\r
1936                     else {\r
1937                         string comboGroupName = "";\r
1938                         string fastaFileName = "";\r
1939                         string qualFileName = "";\r
1940                         string nameFileName = "";\r
1941                         \r
1942                         if(primerName == ""){\r
1943                             comboGroupName = barcodeNameVector[itBar->second];\r
1944                         }\r
1945                         else{\r
1946                             if(barcodeName == ""){\r
1947                                 comboGroupName = primerNameVector[itPrimer->second];\r
1948                             }\r
1949                             else{\r
1950                                 comboGroupName = barcodeNameVector[itBar->second] + "." + primerNameVector[itPrimer->second];\r
1951                             }\r
1952                         }\r
1953                         \r
1954                         ofstream temp;\r
1955                         map<string, string> variables;\r
1956                         variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
1957                         variables["[group]"] = comboGroupName;\r
1958                         string thisFilename = getOutputFileName("sff",variables);\r
1959                         if (uniqueNames.count(thisFilename) == 0) {\r
1960                             outputNames.push_back(thisFilename);\r
1961                             outputTypes["sff"].push_back(thisFilename);\r
1962                             uniqueNames.insert(thisFilename);\r
1963                         }\r
1964                         \r
1965                         filehandles[itBar->second][itPrimer->second] = thisFilename;\r
1966                         temp.open(thisFilename.c_str(), ios::binary);           temp.close();\r
1967                     }\r
1968                                 }\r
1969                         }\r
1970                 }\r
1971                 numFPrimers = primers.size();\r
1972         numLinkers = linker.size();\r
1973         numSpacers = spacer.size();\r
1974         map<string, string> variables;\r
1975         variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
1976         variables["[group]"] = "scrap";\r
1977                 noMatchFile = getOutputFileName("sff",variables);\r
1978         m->mothurRemove(noMatchFile);\r
1979         numNoMatch = 0;\r
1980         \r
1981         \r
1982                 bool allBlank = true;\r
1983                 for (int i = 0; i < barcodeNameVector.size(); i++) {\r
1984                         if (barcodeNameVector[i] != "") {\r
1985                                 allBlank = false;\r
1986                                 break;\r
1987                         }\r
1988                 }\r
1989                 for (int i = 0; i < primerNameVector.size(); i++) {\r
1990                         if (primerNameVector[i] != "") {\r
1991                                 allBlank = false;\r
1992                                 break;\r
1993                         }\r
1994                 }\r
1995                 \r
1996         filehandlesHeaders.resize(filehandles.size());\r
1997         numSplitReads.resize(filehandles.size());\r
1998         for (int i = 0; i < filehandles.size(); i++) {\r
1999             numSplitReads[i].resize(filehandles[i].size(), 0);\r
2000             for (int j = 0; j < filehandles[i].size(); j++) {\r
2001                 filehandlesHeaders[i].push_back(filehandles[i][j]+"headers");\r
2002             }\r
2003         }\r
2004         \r
2005                 if (allBlank) {\r
2006                         m->mothurOut("[WARNING]: your oligos file does not contain any group names.  mothur will not create a split the sff file."); m->mothurOutEndLine();\r
2007                         split = 1;\r
2008                         return false;\r
2009                 }\r
2010                 \r
2011                 return true;\r
2012                 \r
2013         }\r
2014         catch(exception& e) {\r
2015                 m->errorOut(e, "SffInfoCommand", "readOligos");\r
2016                 exit(1);\r
2017         }\r
2018 }\r
2019 //***************************************************************************************************************\r
2020 \r
2021 bool SffInfoCommand::readGroup(string oligoFile){\r
2022         try {\r
2023         filehandles.clear();\r
2024         numSplitReads.clear();\r
2025         filehandlesHeaders.clear();\r
2026         barcodes.clear();\r
2027         \r
2028         groupMap = new GroupMap();\r
2029         groupMap->readMap(oligoFile);\r
2030     \r
2031         //like barcodeNameVector - no primer names\r
2032         vector<string> groups = groupMap->getNamesOfGroups();\r
2033                 \r
2034                 filehandles.resize(groups.size());\r
2035         for (int i = 0; i < filehandles.size(); i++) {\r
2036             for (int j = 0; j < 1; j++) {\r
2037                 \r
2038                 map<string, string> variables;\r
2039                 variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
2040                 variables["[group]"] = groups[i];\r
2041                 string thisFilename = getOutputFileName("sff",variables);\r
2042                 outputNames.push_back(thisFilename);\r
2043                 outputTypes["sff"].push_back(thisFilename);\r
2044                \r
2045                 ofstream temp;\r
2046                 m->openOutputFileBinary(thisFilename, temp); temp.close();\r
2047                 filehandles[i].push_back(thisFilename);\r
2048                 barcodes[groups[i]] = i;\r
2049             }\r
2050         }\r
2051         \r
2052         map<string, string> variables;\r
2053         variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(currentFileName));\r
2054         variables["[group]"] = "scrap";\r
2055                 noMatchFile = getOutputFileName("sff",variables);\r
2056         m->mothurRemove(noMatchFile);\r
2057         numNoMatch = 0;\r
2058         \r
2059                 \r
2060         filehandlesHeaders.resize(groups.size());\r
2061         numSplitReads.resize(filehandles.size());\r
2062         for (int i = 0; i < filehandles.size(); i++) {\r
2063             numSplitReads[i].resize(filehandles[i].size(), 0);\r
2064             for (int j = 0; j < filehandles[i].size(); j++) {\r
2065                 ofstream temp ;\r
2066                 string thisHeader = filehandles[i][j]+"headers";\r
2067                 m->openOutputFileBinary(thisHeader, temp); temp.close();\r
2068                 filehandlesHeaders[i].push_back(thisHeader);\r
2069             }\r
2070         }\r
2071                 \r
2072                 return true;\r
2073                 \r
2074         }\r
2075         catch(exception& e) {\r
2076                 m->errorOut(e, "SffInfoCommand", "readGroup");\r
2077                 exit(1);\r
2078         }\r
2079 }\r
2080 \r
2081 //********************************************************************/\r
2082 string SffInfoCommand::reverseOligo(string oligo){\r
2083         try {\r
2084         string reverse = "";\r
2085         \r
2086         for(int i=oligo.length()-1;i>=0;i--){\r
2087             \r
2088             if(oligo[i] == 'A')         {       reverse += 'T'; }\r
2089             else if(oligo[i] == 'T'){   reverse += 'A'; }\r
2090             else if(oligo[i] == 'U'){   reverse += 'A'; }\r
2091             \r
2092             else if(oligo[i] == 'G'){   reverse += 'C'; }\r
2093             else if(oligo[i] == 'C'){   reverse += 'G'; }\r
2094             \r
2095             else if(oligo[i] == 'R'){   reverse += 'Y'; }\r
2096             else if(oligo[i] == 'Y'){   reverse += 'R'; }\r
2097             \r
2098             else if(oligo[i] == 'M'){   reverse += 'K'; }\r
2099             else if(oligo[i] == 'K'){   reverse += 'M'; }\r
2100             \r
2101             else if(oligo[i] == 'W'){   reverse += 'W'; }\r
2102             else if(oligo[i] == 'S'){   reverse += 'S'; }\r
2103             \r
2104             else if(oligo[i] == 'B'){   reverse += 'V'; }\r
2105             else if(oligo[i] == 'V'){   reverse += 'B'; }\r
2106             \r
2107             else if(oligo[i] == 'D'){   reverse += 'H'; }\r
2108             else if(oligo[i] == 'H'){   reverse += 'D'; }\r
2109             \r
2110             else                                                {       reverse += 'N'; }\r
2111         }\r
2112         \r
2113         \r
2114         return reverse;\r
2115     }\r
2116         catch(exception& e) {\r
2117                 m->errorOut(e, "SffInfoCommand", "reverseOligo");\r
2118                 exit(1);\r
2119         }\r
2120 }\r
2121 \r
2122 //**********************************************************************************************************************\r
2123 \r
2124 \r
2125                                 \r
2126                                 \r