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