]> git.donarmstrong.com Git - mothur.git/blob - sffinfocommand.cpp
testing 1.14.0
[mothur.git] / sffinfocommand.cpp
1 /*
2  *  sffinfocommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 7/7/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "sffinfocommand.h"
11 #include "endiannessmacros.h"
12
13 //**********************************************************************************************************************
14 vector<string> SffInfoCommand::getValidParameters(){    
15         try {
16                 string Array[] =  {"sff","qfile","fasta","flow","trim","accnos","sfftxt","outputdir","inputdir", "outputdir"};
17                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
18                 return myArray;
19         }
20         catch(exception& e) {
21                 m->errorOut(e, "SffInfoCommand", "getValidParameters");
22                 exit(1);
23         }
24 }
25 //**********************************************************************************************************************
26 SffInfoCommand::SffInfoCommand(){       
27         try {
28                 //initialize outputTypes
29                 vector<string> tempOutNames;
30                 outputTypes["fasta"] = tempOutNames;
31                 outputTypes["flow"] = tempOutNames;
32                 outputTypes["sfftxt"] = tempOutNames;
33                 outputTypes["qual"] = tempOutNames;
34         }
35         catch(exception& e) {
36                 m->errorOut(e, "SffInfoCommand", "SffInfoCommand");
37                 exit(1);
38         }
39 }
40 //**********************************************************************************************************************
41 vector<string> SffInfoCommand::getRequiredParameters(){ 
42         try {
43                 string Array[] =  {"sff"};
44                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
45                 return myArray;
46         }
47         catch(exception& e) {
48                 m->errorOut(e, "SffInfoCommand", "getRequiredParameters");
49                 exit(1);
50         }
51 }
52 //**********************************************************************************************************************
53 vector<string> SffInfoCommand::getRequiredFiles(){      
54         try {
55                 vector<string> myArray;
56                 return myArray;
57         }
58         catch(exception& e) {
59                 m->errorOut(e, "SffInfoCommand", "getRequiredFiles");
60                 exit(1);
61         }
62 }
63 //**********************************************************************************************************************
64
65 SffInfoCommand::SffInfoCommand(string option)  {
66         try {
67                 abort = false;
68                 hasAccnos = false;
69                 
70                 //allow user to run help
71                 if(option == "help") { help(); abort = true; }
72                 
73                 else {
74                         //valid paramters for this command
75                         string Array[] =  {"sff","qfile","fasta","flow","trim","accnos","sfftxt","outputdir","inputdir", "outputdir"};
76                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
77                         
78                         OptionParser parser(option);
79                         map<string, string> parameters = parser.getParameters();
80                         
81                         ValidParameters validParameter;
82                         //check to make sure all parameters are valid for command
83                         for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) { 
84                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
85                         }
86                         
87                         //initialize outputTypes
88                         vector<string> tempOutNames;
89                         outputTypes["fasta"] = tempOutNames;
90                         outputTypes["flow"] = tempOutNames;
91                         outputTypes["sfftxt"] = tempOutNames;
92                         outputTypes["qual"] = tempOutNames;
93                         
94                         //if the user changes the output directory command factory will send this info to us in the output parameter 
95                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
96                         
97                         //if the user changes the input directory command factory will send this info to us in the output parameter 
98                         string inputDir = validParameter.validFile(parameters, "inputdir", false);        if (inputDir == "not found"){ inputDir = "";          }
99
100                         sffFilename = validParameter.validFile(parameters, "sff", false);
101                         if (sffFilename == "not found") { m->mothurOut("sff is a required parameter for the sffinfo command."); m->mothurOutEndLine(); abort = true;  }
102                         else { 
103                                 m->splitAtDash(sffFilename, filenames);
104                                 
105                                 //go through files and make sure they are good, if not, then disregard them
106                                 for (int i = 0; i < filenames.size(); i++) {
107                                         if (inputDir != "") {
108                                                 string path = m->hasPath(filenames[i]);
109                                                 //if the user has not given a path then, add inputdir. else leave path alone.
110                                                 if (path == "") {       filenames[i] = inputDir + filenames[i];         }
111                                         }
112         
113                                         ifstream in;
114                                         int ableToOpen = m->openInputFile(filenames[i], in, "noerror");
115                                 
116                                         //if you can't open it, try default location
117                                         if (ableToOpen == 1) {
118                                                 if (m->getDefaultPath() != "") { //default path is set
119                                                         string tryPath = m->getDefaultPath() + m->getSimpleName(filenames[i]);
120                                                         m->mothurOut("Unable to open " + filenames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
121                                                         ifstream in2;
122                                                         ableToOpen = m->openInputFile(tryPath, in2, "noerror");
123                                                         in2.close();
124                                                         filenames[i] = tryPath;
125                                                 }
126                                         }
127                                         
128                                         //if you can't open it, try default location
129                                         if (ableToOpen == 1) {
130                                                 if (m->getOutputDir() != "") { //default path is set
131                                                         string tryPath = m->getOutputDir() + m->getSimpleName(filenames[i]);
132                                                         m->mothurOut("Unable to open " + filenames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
133                                                         ifstream in2;
134                                                         ableToOpen = m->openInputFile(tryPath, in2, "noerror");
135                                                         in2.close();
136                                                         filenames[i] = tryPath;
137                                                 }
138                                         }
139                                         
140                                         in.close();
141                                         
142                                         if (ableToOpen == 1) { 
143                                                 m->mothurOut("Unable to open " + filenames[i] + ". It will be disregarded."); m->mothurOutEndLine();
144                                                 //erase from file list
145                                                 filenames.erase(filenames.begin()+i);
146                                                 i--;
147                                         }
148                                 }
149                                 
150                                 //make sure there is at least one valid file left
151                                 if (filenames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }
152                         }
153                         
154                         accnosName = validParameter.validFile(parameters, "accnos", false);
155                         if (accnosName == "not found") { accnosName = "";  }
156                         else { 
157                                 hasAccnos = true;
158                                 m->splitAtDash(accnosName, accnosFileNames);
159                                 
160                                 //go through files and make sure they are good, if not, then disregard them
161                                 for (int i = 0; i < accnosFileNames.size(); i++) {
162                                         if (inputDir != "") {
163                                                 string path = m->hasPath(accnosFileNames[i]);
164                                                 //if the user has not given a path then, add inputdir. else leave path alone.
165                                                 if (path == "") {       accnosFileNames[i] = inputDir + accnosFileNames[i];             }
166                                         }
167         
168                                         ifstream in;
169                                         int ableToOpen = m->openInputFile(accnosFileNames[i], in, "noerror");
170                                 
171                                         //if you can't open it, try default location
172                                         if (ableToOpen == 1) {
173                                                 if (m->getDefaultPath() != "") { //default path is set
174                                                         string tryPath = m->getDefaultPath() + m->getSimpleName(accnosFileNames[i]);
175                                                         m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
176                                                         ifstream in2;
177                                                         ableToOpen = m->openInputFile(tryPath, in2, "noerror");
178                                                         in2.close();
179                                                         accnosFileNames[i] = tryPath;
180                                                 }
181                                         }
182                                         //if you can't open it, try default location
183                                         if (ableToOpen == 1) {
184                                                 if (m->getOutputDir() != "") { //default path is set
185                                                         string tryPath = m->getOutputDir() + m->getSimpleName(accnosFileNames[i]);
186                                                         m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
187                                                         ifstream in2;
188                                                         ableToOpen = m->openInputFile(tryPath, in2, "noerror");
189                                                         in2.close();
190                                                         accnosFileNames[i] = tryPath;
191                                                 }
192                                         }
193                                         in.close();
194                                         
195                                         if (ableToOpen == 1) { 
196                                                 m->mothurOut("Unable to open " + accnosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine();
197                                                 //erase from file list
198                                                 accnosFileNames.erase(accnosFileNames.begin()+i);
199                                                 i--;
200                                         }
201                                 }
202                                 
203                                 //make sure there is at least one valid file left
204                                 if (accnosFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }
205                         }
206                         
207                         if (hasAccnos) {
208                                 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(); }
209                         }
210                         
211                         string temp = validParameter.validFile(parameters, "qfile", false);                     if (temp == "not found"){       temp = "T";                             }
212                         qual = m->isTrue(temp); 
213                         
214                         temp = validParameter.validFile(parameters, "fasta", false);                            if (temp == "not found"){       temp = "T";                             }
215                         fasta = m->isTrue(temp); 
216                         
217                         temp = validParameter.validFile(parameters, "flow", false);                                     if (temp == "not found"){       temp = "F";                             }
218                         flow = m->isTrue(temp); 
219                         
220                         temp = validParameter.validFile(parameters, "trim", false);                                     if (temp == "not found"){       temp = "T";                             }
221                         trim = m->isTrue(temp); 
222                         
223                         temp = validParameter.validFile(parameters, "sfftxt", false);                           if (temp == "not found"){       temp = "F";                             }
224                         sfftxt = m->isTrue(temp); 
225                 }
226         }
227         catch(exception& e) {
228                 m->errorOut(e, "SffInfoCommand", "SffInfoCommand");
229                 exit(1);
230         }
231 }
232 //**********************************************************************************************************************
233
234 void SffInfoCommand::help(){
235         try {
236                 m->mothurOut("The sffinfo command reads a sff file and extracts the sequence data.\n");
237                 m->mothurOut("The sffinfo command parameters are sff, fasta, qfile, accnos, flow, sfftxt, and trim. sff is required. \n");
238                 m->mothurOut("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");
239                 m->mothurOut("The fasta parameter allows you to indicate if you would like a fasta formatted file generated.  Default=True. \n");
240                 m->mothurOut("The qfile parameter allows you to indicate if you would like a quality file generated.  Default=True. \n");
241                 m->mothurOut("The flow parameter allows you to indicate if you would like a flowgram file generated.  Default=False. \n");
242                 m->mothurOut("The sfftxt parameter allows you to indicate if you would like a sff.txt file generated.  Default=False. \n");
243                 m->mothurOut("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");
244                 m->mothurOut("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");
245                 m->mothurOut("Example sffinfo(sff=mySffFile.sff, trim=F).\n");
246                 m->mothurOut("Note: No spaces between parameter labels (i.e. sff), '=' and parameters (i.e.yourSffFileName).\n\n");
247         }
248         catch(exception& e) {
249                 m->errorOut(e, "SffInfoCommand", "help");
250                 exit(1);
251         }
252 }
253 //**********************************************************************************************************************
254
255 SffInfoCommand::~SffInfoCommand(){}
256
257 //**********************************************************************************************************************
258 int SffInfoCommand::execute(){
259         try {
260                 
261                 if (abort == true) { return 0; }
262                 
263                 for (int s = 0; s < filenames.size(); s++) {
264                         
265                         if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       remove(outputNames[i].c_str());         } return 0; }
266                         
267                         int start = time(NULL);
268                         
269                         m->mothurOut("Extracting info from " + filenames[s] + " ..." ); m->mothurOutEndLine();
270                         
271                         string accnos = "";
272                         if (hasAccnos) { accnos = accnosFileNames[s]; }
273                         
274                         int numReads = extractSffInfo(filenames[s], accnos);
275
276                         m->mothurOut("It took " + toString(time(NULL) - start) + " secs to extract " + toString(numReads) + ".");
277                 }
278                 
279                 if (m->control_pressed) {  for (int i = 0; i < outputNames.size(); i++) {       remove(outputNames[i].c_str());         } return 0; }
280                 
281                 //report output filenames
282                 m->mothurOutEndLine();
283                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
284                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
285                 m->mothurOutEndLine();
286
287                 return 0;
288         }
289         catch(exception& e) {
290                 m->errorOut(e, "SffInfoCommand", "execute");
291                 exit(1);
292         }
293 }
294 //**********************************************************************************************************************
295 int SffInfoCommand::extractSffInfo(string input, string accnos){
296         try {
297                 
298                 if (outputDir == "") {  outputDir += m->hasPath(input); }
299                 
300                 if (accnos != "")       {  readAccnosFile(accnos);  }
301                 else                            {       seqNames.clear();               }
302
303                 ofstream outSfftxt, outFasta, outQual, outFlow;
304                 string outFastaFileName, outQualFileName;
305                 string sfftxtFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "sff.txt";
306                 string outFlowFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "flow";
307                 if (trim) {
308                         outFastaFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "fasta";
309                         outQualFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "qual";
310                 }else{
311                         outFastaFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "raw.fasta";
312                         outQualFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "raw.qual";
313                 }
314                 
315                 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); }
316                 if (fasta)      { m->openOutputFile(outFastaFileName, outFasta);        outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); }
317                 if (qual)       { m->openOutputFile(outQualFileName, outQual);          outputNames.push_back(outQualFileName); outputTypes["qual"].push_back(outQualFileName);  }
318                 if (flow)       { m->openOutputFile(outFlowFileName, outFlow);          outputNames.push_back(outFlowFileName);  outputTypes["flow"].push_back(outFlowFileName);  }
319                 
320                 ifstream in;
321                 in.open(input.c_str(), ios::binary);
322                 
323                 CommonHeader header; 
324                 readCommonHeader(in, header);
325                 
326                 int count = 0;
327                 
328                 //check magic number and version
329                 if (header.magicNumber != 779314790) { m->mothurOut("Magic Number is not correct, not a valid .sff file"); m->mothurOutEndLine(); return count; }
330                 if (header.version != "0001") { m->mothurOut("Version is not supported, only support version 0001."); m->mothurOutEndLine(); return count; }
331         
332                 //print common header
333                 if (sfftxt) { printCommonHeader(outSfftxt, header); }
334         
335                 //read through the sff file
336                 while (!in.eof()) {
337                         
338                         bool print = true;
339                         
340                         //read header
341                         Header readheader;
342                         readHeader(in, readheader);
343                         
344                         //read data
345                         seqRead read; 
346                         readSeqData(in, read, header.numFlowsPerRead, readheader.numBases);
347                                 
348                         //if you have provided an accosfile and this seq is not in it, then dont print
349                         if (seqNames.size() != 0) {   if (seqNames.count(readheader.name) == 0) { print = false; }  }
350                         
351                         //print 
352                         if (print) {
353                                 if (sfftxt) { printHeader(outSfftxt, readheader); printSffTxtSeqData(outSfftxt, read, readheader); }
354                                 if (fasta)      {       printFastaSeqData(outFasta, read, readheader);  }
355                                 if (qual)       {       printQualSeqData(outQual, read, readheader);    }
356                                 if (flow)       {       printFlowSeqData(outFlow, read, readheader);    }
357                         }
358                         
359                         count++;
360                 
361                         //report progress
362                         if((count+1) % 10000 == 0){     m->mothurOut(toString(count+1)); m->mothurOutEndLine();         }
363                 
364                         if (m->control_pressed) { count = 0; break;   }
365                         
366                         if (count >= header.numReads) { break; }
367                 }
368                 
369                 //report progress
370                 if (!m->control_pressed) {   if((count) % 10000 != 0){  m->mothurOut(toString(count)); m->mothurOutEndLine();           }  }
371                 
372                 in.close();
373                 
374                 if (sfftxt) {  outSfftxt.close();       }
375                 if (fasta)      {  outFasta.close();    }
376                 if (qual)       {  outQual.close();             }
377                 if (flow)       {  outFlow.close();             }
378                 
379                 return count;
380         }
381         catch(exception& e) {
382                 m->errorOut(e, "SffInfoCommand", "extractSffInfo");
383                 exit(1);
384         }
385 }
386 //**********************************************************************************************************************
387 int SffInfoCommand::readCommonHeader(ifstream& in, CommonHeader& header){
388         try {
389
390                 if (!in.eof()) {
391
392                         //read magic number
393                         char buffer[4];
394                         in.read(buffer, 4);
395                         header.magicNumber = be_int4(*(unsigned int *)(&buffer));
396                 
397                         //read version
398                         char buffer9[4];
399                         in.read(buffer9, 4);
400                         header.version = "";
401                         for (int i = 0; i < 4; i++) {  header.version += toString((int)(buffer9[i])); }
402                                 
403                         //read offset
404                         char buffer2 [8];
405                         in.read(buffer2, 8);
406                         header.indexOffset =  be_int8(*(unsigned long int *)(&buffer2));
407                         
408                         //read index length
409                         char buffer3 [4];
410                         in.read(buffer3, 4);
411                         header.indexLength =  be_int4(*(unsigned int *)(&buffer3));
412                         
413                         //read num reads
414                         char buffer4 [4];
415                         in.read(buffer4, 4);
416                         header.numReads =  be_int4(*(unsigned int *)(&buffer4));
417                                 
418                         //read header length
419                         char buffer5 [2];
420                         in.read(buffer5, 2);
421                         header.headerLength =  be_int2(*(unsigned short *)(&buffer5));
422                                         
423                         //read key length
424                         char buffer6 [2];
425                         in.read(buffer6, 2);
426                         header.keyLength = be_int2(*(unsigned short *)(&buffer6));
427                         
428                         //read number of flow reads
429                         char buffer7 [2];
430                         in.read(buffer7, 2);
431                         header.numFlowsPerRead =  be_int2(*(unsigned short *)(&buffer7));
432                                 
433                         //read format code
434                         char buffer8 [1];
435                         in.read(buffer8, 1);
436                         header.flogramFormatCode = (int)(buffer8[0]);
437                         
438                         //read flow chars
439                         char* tempBuffer = new char[header.numFlowsPerRead];
440                         in.read(&(*tempBuffer), header.numFlowsPerRead); 
441                         header.flowChars = tempBuffer;
442                         if (header.flowChars.length() > header.numFlowsPerRead) { header.flowChars = header.flowChars.substr(0, header.numFlowsPerRead);  }
443                         delete[] tempBuffer;
444                         
445                         //read key
446                         char* tempBuffer2 = new char[header.keyLength];
447                         in.read(&(*tempBuffer2), header.keyLength);
448                         header.keySequence = tempBuffer2;
449                         if (header.keySequence.length() > header.keyLength) { header.keySequence = header.keySequence.substr(0, header.keyLength);  }
450                         delete[] tempBuffer2;
451                                 
452                         /* Pad to 8 chars */
453                         unsigned long int spotInFile = in.tellg();
454                         unsigned long int spot = (spotInFile + 7)& ~7;  // ~ inverts
455                         in.seekg(spot);
456                         
457                 }else{
458                         m->mothurOut("Error reading sff common header."); m->mothurOutEndLine();
459                 }
460
461                 return 0;
462         }
463         catch(exception& e) {
464                 m->errorOut(e, "SffInfoCommand", "readCommonHeader");
465                 exit(1);
466         }
467 }
468 //**********************************************************************************************************************
469 int SffInfoCommand::readHeader(ifstream& in, Header& header){
470         try {
471         
472                 if (!in.eof()) {
473                         
474                         //read header length
475                         char buffer [2];
476                         in.read(buffer, 2);
477                         header.headerLength = be_int2(*(unsigned short *)(&buffer));
478                                                 
479                         //read name length
480                         char buffer2 [2];
481                         in.read(buffer2, 2);
482                         header.nameLength = be_int2(*(unsigned short *)(&buffer2));
483
484                         //read num bases
485                         char buffer3 [4];
486                         in.read(buffer3, 4);
487                         header.numBases =  be_int4(*(unsigned int *)(&buffer3));
488                         
489                         //read clip qual left
490                         char buffer4 [2];
491                         in.read(buffer4, 2);
492                         header.clipQualLeft =  be_int2(*(unsigned short *)(&buffer4));
493                         header.clipQualLeft = 5; 
494                         
495                         //read clip qual right
496                         char buffer5 [2];
497                         in.read(buffer5, 2);
498                         header.clipQualRight =  be_int2(*(unsigned short *)(&buffer5));
499                         
500                         //read clipAdapterLeft
501                         char buffer6 [2];
502                         in.read(buffer6, 2);
503                         header.clipAdapterLeft = be_int2(*(unsigned short *)(&buffer6));
504
505                         //read clipAdapterRight
506                         char buffer7 [2];
507                         in.read(buffer7, 2);
508                         header.clipAdapterRight = be_int2(*(unsigned short *)(&buffer7));
509                 
510                         //read name
511                         char* tempBuffer = new char[header.nameLength];
512                         in.read(&(*tempBuffer), header.nameLength);
513                         header.name = tempBuffer;
514                         if (header.name.length() > header.nameLength) { header.name = header.name.substr(0, header.nameLength);  }
515                         delete[] tempBuffer;
516                         
517                         /* Pad to 8 chars */
518                         unsigned long int spotInFile = in.tellg();
519                         unsigned long int spot = (spotInFile + 7)& ~7;
520                         in.seekg(spot);
521                         
522                 }else{
523                         m->mothurOut("Error reading sff header info."); m->mothurOutEndLine();
524                 }
525
526                 return 0;
527         }
528         catch(exception& e) {
529                 m->errorOut(e, "SffInfoCommand", "readHeader");
530                 exit(1);
531         }
532 }
533 //**********************************************************************************************************************
534 int SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads, int numBases){
535         try {
536         
537                 if (!in.eof()) {
538         
539                         //read flowgram
540                         read.flowgram.resize(numFlowReads);
541                         for (int i = 0; i < numFlowReads; i++) {  
542                                 char buffer [2];
543                                 in.read(buffer, 2);
544                                 read.flowgram[i] = be_int2(*(unsigned short *)(&buffer));
545                         }
546         
547                         //read flowIndex
548                         read.flowIndex.resize(numBases);
549                         for (int i = 0; i < numBases; i++) {  
550                                 char temp[1];
551                                 in.read(temp, 1);
552                                 read.flowIndex[i] = be_int1(*(unsigned char *)(&temp));
553                         }
554         
555                         //read bases
556                         char* tempBuffer = new char[numBases];
557                         in.read(&(*tempBuffer), numBases);
558                         read.bases = tempBuffer;
559                         if (read.bases.length() > numBases) { read.bases = read.bases.substr(0, numBases);  }
560                         delete[] tempBuffer;
561
562                         //read qual scores
563                         read.qualScores.resize(numBases);
564                         for (int i = 0; i < numBases; i++) {  
565                                 char temp[1];
566                                 in.read(temp, 1);
567                                 read.qualScores[i] = be_int1(*(unsigned char *)(&temp));
568                         }
569         
570                         /* Pad to 8 chars */
571                         unsigned long int spotInFile = in.tellg();
572                         unsigned long int spot = (spotInFile + 7)& ~7;
573                         in.seekg(spot);
574                         
575                 }else{
576                         m->mothurOut("Error reading."); m->mothurOutEndLine();
577                 }
578
579                 return 0;
580         }
581         catch(exception& e) {
582                 m->errorOut(e, "SffInfoCommand", "readSeqData");
583                 exit(1);
584         }
585 }
586 //**********************************************************************************************************************
587 int SffInfoCommand::printCommonHeader(ofstream& out, CommonHeader& header) {
588         try {
589         
590                 out << "Common Header:\nMagic Number: " << header.magicNumber << endl;
591                 out << "Version: " << header.version << endl;
592                 out << "Index Offset: " << header.indexOffset << endl;
593                 out << "Index Length: " << header.indexLength << endl;
594                 out << "Number of Reads: " << header.numReads << endl;
595                 out << "Header Length: " << header.headerLength << endl;
596                 out << "Key Length: " << header.keyLength << endl;
597                 out << "Number of Flows: " << header.numFlowsPerRead << endl;
598                 out << "Format Code: " << header.flogramFormatCode << endl;
599                 out << "Flow Chars: " << header.flowChars << endl;
600                 out << "Key Sequence: " << header.keySequence << endl << endl;
601                         
602                 return 0;
603         }
604         catch(exception& e) {
605                 m->errorOut(e, "SffInfoCommand", "printCommonHeader");
606                 exit(1);
607         }
608 }
609 //**********************************************************************************************************************
610 int SffInfoCommand::printHeader(ofstream& out, Header& header) {
611         try {
612                 
613                 out << ">" << header.name << endl;
614                 out << "Run Prefix: " << endl;
615                 out << "Region #:  " << endl;
616                 out << "XY Location: " << endl << endl;
617                 
618                 out << "Run Name:  " << endl;
619                 out << "Analysis Name:  " << endl;
620                 out << "Full Path: " << endl << endl;
621                 
622                 out << "Read Header Len: " << header.headerLength << endl;
623                 out << "Name Length: " << header.nameLength << endl;
624                 out << "# of Bases: " << header.numBases << endl;
625                 out << "Clip Qual Left: " << header.clipQualLeft << endl;
626                 out << "Clip Qual Right: " << header.clipQualRight << endl;
627                 out << "Clip Adap Left: " << header.clipAdapterLeft << endl;
628                 out << "Clip Adap Right: " << header.clipAdapterRight << endl << endl;
629                 
630                 return 0;
631         }
632         catch(exception& e) {
633                 m->errorOut(e, "SffInfoCommand", "printHeader");
634                 exit(1);
635         }
636 }
637
638 //**********************************************************************************************************************
639 int SffInfoCommand::printSffTxtSeqData(ofstream& out, seqRead& read, Header& header) {
640         try {
641                 
642                 out << "Flowgram: ";
643                 for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << (read.flowgram[i]/(float)100) << '\t';  }
644                 
645                 out << endl <<  "Flow Indexes: ";
646                 int sum = 0;
647                 for (int i = 0; i < read.flowIndex.size(); i++) {  sum +=  read.flowIndex[i];  out << sum << '\t'; }
648                 
649                 //make the bases you want to clip lowercase and the bases you want to keep upper case
650                 if(header.clipQualRight == 0){  header.clipQualRight = read.bases.length();     }
651                 for (int i = 0; i < (header.clipQualLeft-1); i++) { read.bases[i] = tolower(read.bases[i]); }
652                 for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) {   read.bases[i] = toupper(read.bases[i]);  }
653                 for (int i = (header.clipQualRight-1); i < read.bases.length(); i++) {   read.bases[i] = tolower(read.bases[i]);  }
654                 
655                 out << endl <<  "Bases: " << read.bases << endl << "Quality Scores: ";
656                 for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }
657         
658                 
659                 out << endl << endl;
660                 
661                 return 0;
662         }
663         catch(exception& e) {
664                 m->errorOut(e, "SffInfoCommand", "printSffTxtSeqData");
665                 exit(1);
666         }
667 }
668 //**********************************************************************************************************************
669 int SffInfoCommand::printFastaSeqData(ofstream& out, seqRead& read, Header& header) {
670         try {
671                 
672                 string seq = read.bases;
673                 
674                 if (trim) {
675                         if(header.clipQualRight < header.clipQualLeft){
676                                 seq = "NNNN";
677                         }
678                         else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){
679                                 seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft));
680                         }
681                         else {
682                                 seq = seq.substr(header.clipQualLeft-1);
683                         }
684                 }else{
685                         //if you wanted the sfftxt then you already converted the bases to the right case
686                         if (!sfftxt) {
687                                 //make the bases you want to clip lowercase and the bases you want to keep upper case
688                                 if(header.clipQualRight == 0){  header.clipQualRight = seq.length();    }
689                                 for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]);  }
690                                 for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++)  {   seq[i] = toupper(seq[i]);  }
691                                 for (int i = (header.clipQualRight-1); i < seq.length(); i++) {   seq[i] = tolower(seq[i]);  }
692                         }
693                 }
694                 
695                 out << ">" << header.name << endl;
696                 out << seq << endl;
697                 
698                 return 0;
699         }
700         catch(exception& e) {
701                 m->errorOut(e, "SffInfoCommand", "printFastaSeqData");
702                 exit(1);
703         }
704 }
705
706 //**********************************************************************************************************************
707 int SffInfoCommand::printQualSeqData(ofstream& out, seqRead& read, Header& header) {
708         try {
709                 
710                 if (trim) {
711                         if(header.clipQualRight < header.clipQualLeft){
712                                 out << "0\t0\t0\t0";
713                         }
714                         else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){
715                                 out << ">" << header.name << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;
716                                 for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) {   out << read.qualScores[i] << '\t'; }
717                         }
718                         else{
719                                 out << ">" << header.name << " length=" << (header.clipQualRight-header.clipQualLeft) << endl;
720                                 for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';   }                       
721                         }
722                 }else{
723                         out << ">" << header.name << " length=" << read.qualScores.size() << endl;
724                         for (int i = 0; i < read.qualScores.size(); i++) {   out << read.qualScores[i] << '\t';  }
725                 }
726                 
727                 out << endl;
728                 
729                 return 0;
730         }
731         catch(exception& e) {
732                 m->errorOut(e, "SffInfoCommand", "printQualSeqData");
733                 exit(1);
734         }
735 }
736
737 //**********************************************************************************************************************
738 int SffInfoCommand::printFlowSeqData(ofstream& out, seqRead& read, Header& header) {
739         try {
740                 
741                 out << ">" << header.name << endl;
742                 for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << (read.flowgram[i]/(float)100) << '\t';  }
743                 out << endl;
744                 
745                 return 0;
746         }
747         catch(exception& e) {
748                 m->errorOut(e, "SffInfoCommand", "printFlowSeqData");
749                 exit(1);
750         }
751 }
752 //**********************************************************************************************************************
753 int SffInfoCommand::readAccnosFile(string filename) {
754         try {
755                 //remove old names
756                 seqNames.clear();
757                 
758                 ifstream in;
759                 m->openInputFile(filename, in);
760                 string name;
761                 
762                 while(!in.eof()){
763                         in >> name; m->gobble(in);
764                                                 
765                         seqNames.insert(name);
766                         
767                         if (m->control_pressed) { seqNames.clear(); break; }
768                 }
769                 in.close();             
770                 
771                 return 0;
772         }
773         catch(exception& e) {
774                 m->errorOut(e, "SffInfoCommand", "readAccnosFile");
775                 exit(1);
776         }
777 }
778 //**********************************************************************************************************************/