X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=sffinfocommand.cpp;h=2caad96df797bc2d5dca067a4ae2b3f4a4ebed5c;hb=d0954e27635712cdbd8b86e3c4510670803a2665;hp=f8ba25b5fabd1b8485065a548e47911cb0c8c1e3;hpb=058715887611e00dc18324cb0bd4a4a8472530b3;p=mothur.git diff --git a/sffinfocommand.cpp b/sffinfocommand.cpp index f8ba25b..2caad96 100644 --- a/sffinfocommand.cpp +++ b/sffinfocommand.cpp @@ -10,15 +10,65 @@ #include "sffinfocommand.h" #include "endiannessmacros.h" +//********************************************************************************************************************** +vector SffInfoCommand::getValidParameters(){ + try { + string Array[] = {"sff","qfile","fasta","flow","trim","accnos","sfftxt","outputdir","inputdir", "outputdir"}; + vector myArray (Array, Array+(sizeof(Array)/sizeof(string))); + return myArray; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "getValidParameters"); + exit(1); + } +} +//********************************************************************************************************************** +SffInfoCommand::SffInfoCommand(){ + try { + abort = true; calledHelp = true; + vector tempOutNames; + outputTypes["fasta"] = tempOutNames; + outputTypes["flow"] = tempOutNames; + outputTypes["sfftxt"] = tempOutNames; + outputTypes["qfile"] = tempOutNames; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "SffInfoCommand"); + exit(1); + } +} +//********************************************************************************************************************** +vector SffInfoCommand::getRequiredParameters(){ + try { + string Array[] = {"sff", "sfftxt", "or"}; + vector myArray (Array, Array+(sizeof(Array)/sizeof(string))); + return myArray; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "getRequiredParameters"); + exit(1); + } +} +//********************************************************************************************************************** +vector SffInfoCommand::getRequiredFiles(){ + try { + vector myArray; + return myArray; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "getRequiredFiles"); + exit(1); + } +} //********************************************************************************************************************** SffInfoCommand::SffInfoCommand(string option) { try { - abort = false; + abort = false; calledHelp = false; hasAccnos = false; //allow user to run help - if(option == "help") { help(); abort = true; } + if(option == "help") { help(); abort = true; calledHelp = true; } else { //valid paramters for this command @@ -34,6 +84,13 @@ SffInfoCommand::SffInfoCommand(string option) { if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; } } + //initialize outputTypes + vector tempOutNames; + outputTypes["fasta"] = tempOutNames; + outputTypes["flow"] = tempOutNames; + outputTypes["sfftxt"] = tempOutNames; + outputTypes["qfile"] = tempOutNames; + //if the user changes the output directory command factory will send this info to us in the output parameter outputDir = validParameter.validFile(parameters, "outputdir", false); if (outputDir == "not found"){ outputDir = ""; } @@ -41,30 +98,45 @@ SffInfoCommand::SffInfoCommand(string option) { string inputDir = validParameter.validFile(parameters, "inputdir", false); if (inputDir == "not found"){ inputDir = ""; } sffFilename = validParameter.validFile(parameters, "sff", false); - if (sffFilename == "not found") { m->mothurOut("sff is a required parameter for the sffinfo command."); m->mothurOutEndLine(); abort = true; } + if (sffFilename == "not found") { sffFilename = ""; } else { - splitAtDash(sffFilename, filenames); + m->splitAtDash(sffFilename, filenames); //go through files and make sure they are good, if not, then disregard them for (int i = 0; i < filenames.size(); i++) { if (inputDir != "") { - string path = hasPath(filenames[i]); + string path = m->hasPath(filenames[i]); //if the user has not given a path then, add inputdir. else leave path alone. if (path == "") { filenames[i] = inputDir + filenames[i]; } } ifstream in; - int ableToOpen = openInputFile(filenames[i], in, "noerror"); + int ableToOpen = m->openInputFile(filenames[i], in, "noerror"); //if you can't open it, try default location if (ableToOpen == 1) { if (m->getDefaultPath() != "") { //default path is set - string tryPath = m->getDefaultPath() + getSimpleName(filenames[i]); + string tryPath = m->getDefaultPath() + m->getSimpleName(filenames[i]); m->mothurOut("Unable to open " + filenames[i] + ". Trying default " + tryPath); m->mothurOutEndLine(); - ableToOpen = openInputFile(tryPath, in, "noerror"); + ifstream in2; + ableToOpen = m->openInputFile(tryPath, in2, "noerror"); + in2.close(); + filenames[i] = tryPath; + } + } + + //if you can't open it, try default location + if (ableToOpen == 1) { + if (m->getOutputDir() != "") { //default path is set + string tryPath = m->getOutputDir() + m->getSimpleName(filenames[i]); + m->mothurOut("Unable to open " + filenames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine(); + ifstream in2; + ableToOpen = m->openInputFile(tryPath, in2, "noerror"); + in2.close(); filenames[i] = tryPath; } } + in.close(); if (ableToOpen == 1) { @@ -83,25 +155,38 @@ SffInfoCommand::SffInfoCommand(string option) { if (accnosName == "not found") { accnosName = ""; } else { hasAccnos = true; - splitAtDash(accnosName, accnosFileNames); + m->splitAtDash(accnosName, accnosFileNames); //go through files and make sure they are good, if not, then disregard them for (int i = 0; i < accnosFileNames.size(); i++) { if (inputDir != "") { - string path = hasPath(accnosFileNames[i]); + string path = m->hasPath(accnosFileNames[i]); //if the user has not given a path then, add inputdir. else leave path alone. if (path == "") { accnosFileNames[i] = inputDir + accnosFileNames[i]; } } ifstream in; - int ableToOpen = openInputFile(accnosFileNames[i], in, "noerror"); + int ableToOpen = m->openInputFile(accnosFileNames[i], in, "noerror"); //if you can't open it, try default location if (ableToOpen == 1) { if (m->getDefaultPath() != "") { //default path is set - string tryPath = m->getDefaultPath() + getSimpleName(accnosFileNames[i]); + string tryPath = m->getDefaultPath() + m->getSimpleName(accnosFileNames[i]); m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine(); - ableToOpen = openInputFile(tryPath, in, "noerror"); + ifstream in2; + ableToOpen = m->openInputFile(tryPath, in2, "noerror"); + in2.close(); + accnosFileNames[i] = tryPath; + } + } + //if you can't open it, try default location + if (ableToOpen == 1) { + if (m->getOutputDir() != "") { //default path is set + string tryPath = m->getOutputDir() + m->getSimpleName(accnosFileNames[i]); + m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine(); + ifstream in2; + ableToOpen = m->openInputFile(tryPath, in2, "noerror"); + in2.close(); accnosFileNames[i] = tryPath; } } @@ -124,19 +209,38 @@ SffInfoCommand::SffInfoCommand(string option) { } string temp = validParameter.validFile(parameters, "qfile", false); if (temp == "not found"){ temp = "T"; } - qual = isTrue(temp); + qual = m->isTrue(temp); temp = validParameter.validFile(parameters, "fasta", false); if (temp == "not found"){ temp = "T"; } - fasta = isTrue(temp); + fasta = m->isTrue(temp); temp = validParameter.validFile(parameters, "flow", false); if (temp == "not found"){ temp = "F"; } - flow = isTrue(temp); + flow = m->isTrue(temp); temp = validParameter.validFile(parameters, "trim", false); if (temp == "not found"){ temp = "T"; } - trim = isTrue(temp); + trim = m->isTrue(temp); + + temp = validParameter.validFile(parameters, "sfftxt", false); + if (temp == "not found") { temp = "F"; sfftxt = false; sfftxtFilename = ""; } + else if (m->isTrue(temp)) { sfftxt = true; sfftxtFilename = ""; } + else { + //you are a filename + if (inputDir != "") { + map::iterator it = parameters.find("sfftxt"); + //user has given a template file + if(it != parameters.end()){ + string path = m->hasPath(it->second); + //if the user has not given a path then, add inputdir. else leave path alone. + if (path == "") { parameters["sfftxt"] = inputDir + it->second; } + } + } + + sfftxtFilename = validParameter.validFile(parameters, "sfftxt", true); + if (sfftxtFilename == "not found") { sfftxtFilename = ""; } + else if (sfftxtFilename == "not open") { sfftxtFilename = ""; } + } - temp = validParameter.validFile(parameters, "sfftxt", false); if (temp == "not found"){ temp = "F"; } - sfftxt = isTrue(temp); + if ((sfftxtFilename == "") && (filenames.size() == 0)) { m->mothurOut("[ERROR]: you must provide a valid sff or sfftxt file."); m->mothurOutEndLine(); abort=true; } } } catch(exception& e) { @@ -148,13 +252,14 @@ SffInfoCommand::SffInfoCommand(string option) { void SffInfoCommand::help(){ try { - m->mothurOut("The sffinfo command reads a sff file and extracts the sequence data.\n"); + m->mothurOut("The sffinfo command reads a sff file and extracts the sequence data, or you can use it to parse a sfftxt file..\n"); m->mothurOut("The sffinfo command parameters are sff, fasta, qfile, accnos, flow, sfftxt, and trim. sff is required. \n"); 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"); m->mothurOut("The fasta parameter allows you to indicate if you would like a fasta formatted file generated. Default=True. \n"); m->mothurOut("The qfile parameter allows you to indicate if you would like a quality file generated. Default=True. \n"); m->mothurOut("The flow parameter allows you to indicate if you would like a flowgram file generated. Default=False. \n"); m->mothurOut("The sfftxt parameter allows you to indicate if you would like a sff.txt file generated. Default=False. \n"); + m->mothurOut("If you want to parse an existing sfftxt file into flow, fasta and quality file, enter the file name using the sfftxt parameter. \n"); 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"); 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"); m->mothurOut("Example sffinfo(sff=mySffFile.sff, trim=F).\n"); @@ -173,7 +278,7 @@ SffInfoCommand::~SffInfoCommand(){} int SffInfoCommand::execute(){ try { - if (abort == true) { return 0; } + if (abort == true) { if (calledHelp) { return 0; } return 2; } for (int s = 0; s < filenames.size(); s++) { @@ -191,8 +296,22 @@ int SffInfoCommand::execute(){ m->mothurOut("It took " + toString(time(NULL) - start) + " secs to extract " + toString(numReads) + "."); } + if (sfftxtFilename != "") { parseSffTxt(); } + if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; } + //set fasta file as new current fastafile + string current = ""; + itTypes = outputTypes.find("fasta"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); } + } + + itTypes = outputTypes.find("qfile"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setQualFile(current); } + } + //report output filenames m->mothurOutEndLine(); m->mothurOut("Output File Names: "); m->mothurOutEndLine(); @@ -210,27 +329,27 @@ int SffInfoCommand::execute(){ int SffInfoCommand::extractSffInfo(string input, string accnos){ try { - if (outputDir == "") { outputDir += hasPath(input); } + if (outputDir == "") { outputDir += m->hasPath(input); } if (accnos != "") { readAccnosFile(accnos); } else { seqNames.clear(); } ofstream outSfftxt, outFasta, outQual, outFlow; string outFastaFileName, outQualFileName; - string sfftxtFileName = outputDir + getRootName(getSimpleName(input)) + "sff.txt"; - string outFlowFileName = outputDir + getRootName(getSimpleName(input)) + "flow"; + string sfftxtFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "sff.txt"; + string outFlowFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "flow"; if (trim) { - outFastaFileName = outputDir + getRootName(getSimpleName(input)) + "fasta"; - outQualFileName = outputDir + getRootName(getSimpleName(input)) + "qual"; + outFastaFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "fasta"; + outQualFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "qual"; }else{ - outFastaFileName = outputDir + getRootName(getSimpleName(input)) + "raw.fasta"; - outQualFileName = outputDir + getRootName(getSimpleName(input)) + "raw.qual"; + outFastaFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "raw.fasta"; + outQualFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "raw.qual"; } - if (sfftxt) { openOutputFile(sfftxtFileName, outSfftxt); outSfftxt.setf(ios::fixed, ios::floatfield); outSfftxt.setf(ios::showpoint); outputNames.push_back(sfftxtFileName); } - if (fasta) { openOutputFile(outFastaFileName, outFasta); outputNames.push_back(outFastaFileName); } - if (qual) { openOutputFile(outQualFileName, outQual); outputNames.push_back(outQualFileName); } - if (flow) { openOutputFile(outFlowFileName, outFlow); outputNames.push_back(outFlowFileName); } + 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); } + if (fasta) { m->openOutputFile(outFastaFileName, outFasta); outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); } + if (qual) { m->openOutputFile(outQualFileName, outQual); outputNames.push_back(outQualFileName); outputTypes["qfile"].push_back(outQualFileName); } + 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); } ifstream in; in.open(input.c_str(), ios::binary); @@ -245,8 +364,9 @@ int SffInfoCommand::extractSffInfo(string input, string accnos){ if (header.version != "0001") { m->mothurOut("Version is not supported, only support version 0001."); m->mothurOutEndLine(); return count; } //print common header - if (sfftxt) { printCommonHeader(outSfftxt, header); } - + if (sfftxt) { printCommonHeader(outSfftxt, header); } + if (flow) { outFlow << header.numFlowsPerRead << endl; } + //read through the sff file while (!in.eof()) { @@ -405,7 +525,7 @@ int SffInfoCommand::readHeader(ifstream& in, Header& header){ char buffer4 [2]; in.read(buffer4, 2); header.clipQualLeft = be_int2(*(unsigned short *)(&buffer4)); - header.clipQualLeft = 5; + header.clipQualLeft = 5; //read clip qual right char buffer5 [2]; @@ -429,6 +549,9 @@ int SffInfoCommand::readHeader(ifstream& in, Header& header){ if (header.name.length() > header.nameLength) { header.name = header.name.substr(0, header.nameLength); } delete[] tempBuffer; + //extract info from name + decodeName(header.timestamp, header.region, header.xy, header.name); + /* Pad to 8 chars */ unsigned long int spotInFile = in.tellg(); unsigned long int spot = (spotInFile + 7)& ~7; @@ -499,6 +622,47 @@ int SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads, i } } //********************************************************************************************************************** +int SffInfoCommand::decodeName(string& timestamp, string& region, string& xy, string name) { + try { + + if (name.length() >= 6) { + string time = name.substr(0, 6); + unsigned int timeNum = m->fromBase36(time); + + int q1 = timeNum / 60; + int sec = timeNum - 60 * q1; + int q2 = q1 / 60; + int minute = q1 - 60 * q2; + int q3 = q2 / 24; + int hr = q2 - 24 * q3; + int q4 = q3 / 32; + int day = q3 - 32 * q4; + int q5 = q4 / 13; + int mon = q4 - 13 * q5; + int year = 2000 + q5; + + timestamp = toString(year) + "_" + toString(mon) + "_" + toString(day) + "_" + toString(hr) + "_" + toString(minute) + "_" + toString(sec); + } + + if (name.length() >= 9) { + region = name.substr(7, 2); + + string xyNum = name.substr(9); + unsigned int myXy = m->fromBase36(xyNum); + int x = myXy >> 12; + int y = myXy & 4095; + + xy = toString(x) + "_" + toString(y); + } + + return 0; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "decodeName"); + exit(1); + } +} +//********************************************************************************************************************** int SffInfoCommand::printCommonHeader(ofstream& out, CommonHeader& header) { try { @@ -526,9 +690,9 @@ int SffInfoCommand::printHeader(ofstream& out, Header& header) { try { out << ">" << header.name << endl; - out << "Run Prefix: " << endl; - out << "Region #: " << endl; - out << "XY Location: " << endl << endl; + out << "Run Prefix: " << header.timestamp << endl; + out << "Region #: " << header.region << endl; + out << "XY Location: " << header.xy << endl << endl; out << "Run Name: " << endl; out << "Analysis Name: " << endl; @@ -562,6 +726,7 @@ int SffInfoCommand::printSffTxtSeqData(ofstream& out, seqRead& read, Header& hea for (int i = 0; i < read.flowIndex.size(); i++) { sum += read.flowIndex[i]; out << sum << '\t'; } //make the bases you want to clip lowercase and the bases you want to keep upper case + if(header.clipQualRight == 0){ header.clipQualRight = read.bases.length(); } for (int i = 0; i < (header.clipQualLeft-1); i++) { read.bases[i] = tolower(read.bases[i]); } for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) { read.bases[i] = toupper(read.bases[i]); } for (int i = (header.clipQualRight-1); i < read.bases.length(); i++) { read.bases[i] = tolower(read.bases[i]); } @@ -586,7 +751,10 @@ int SffInfoCommand::printFastaSeqData(ofstream& out, seqRead& read, Header& head string seq = read.bases; if (trim) { - if(header.clipQualRight != 0){ + if(header.clipQualRight < header.clipQualLeft){ + seq = "NNNN"; + } + else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){ seq = seq.substr((header.clipQualLeft-1), (header.clipQualRight-header.clipQualLeft)); } else { @@ -603,7 +771,7 @@ int SffInfoCommand::printFastaSeqData(ofstream& out, seqRead& read, Header& head } } - out << ">" << header.name << endl; + out << ">" << header.name << " xy=" << header.xy << endl; out << seq << endl; return 0; @@ -619,16 +787,19 @@ int SffInfoCommand::printQualSeqData(ofstream& out, seqRead& read, Header& heade try { if (trim) { - if(header.clipQualRight != 0){ - out << ">" << header.name << " length=" << (header.clipQualRight-header.clipQualLeft) << endl; + if(header.clipQualRight < header.clipQualLeft){ + out << "0\t0\t0\t0"; + } + else if((header.clipQualRight != 0) && ((header.clipQualRight-header.clipQualLeft) >= 0)){ + out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl; for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) { out << read.qualScores[i] << '\t'; } } else{ - out << ">" << header.name << " length=" << (header.clipQualRight-header.clipQualLeft) << endl; + out << ">" << header.name << " xy=" << header.xy << " length=" << (header.clipQualRight-header.clipQualLeft) << endl; for (int i = (header.clipQualLeft-1); i < read.qualScores.size(); i++) { out << read.qualScores[i] << '\t'; } } }else{ - out << ">" << header.name << " length=" << read.qualScores.size() << endl; + out << ">" << header.name << " xy=" << header.xy << " length=" << read.qualScores.size() << endl; for (int i = 0; i < read.qualScores.size(); i++) { out << read.qualScores[i] << '\t'; } } @@ -645,10 +816,16 @@ int SffInfoCommand::printQualSeqData(ofstream& out, seqRead& read, Header& heade //********************************************************************************************************************** int SffInfoCommand::printFlowSeqData(ofstream& out, seqRead& read, Header& header) { try { + if(header.clipQualRight > header.clipQualLeft){ + + int rightIndex = 0; + for (int i = 0; i < header.clipQualRight; i++) { rightIndex += read.flowIndex[i]; } + + out << header.name << ' ' << rightIndex; + for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << ' ' << (read.flowgram[i]/(float)100); } + out << endl; + } - out << ">" << header.name << endl; - for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << (read.flowgram[i]/(float)100) << '\t'; } - out << endl; return 0; } @@ -664,11 +841,11 @@ int SffInfoCommand::readAccnosFile(string filename) { seqNames.clear(); ifstream in; - openInputFile(filename, in); + m->openInputFile(filename, in); string name; while(!in.eof()){ - in >> name; gobble(in); + in >> name; m->gobble(in); seqNames.insert(name); @@ -683,4 +860,233 @@ int SffInfoCommand::readAccnosFile(string filename) { exit(1); } } -//**********************************************************************************************************************/ +//********************************************************************************************************************** +int SffInfoCommand::parseSffTxt() { + try { + + ifstream inSFF; + m->openInputFile(sfftxtFilename, inSFF); + + if (outputDir == "") { outputDir += m->hasPath(sfftxtFilename); } + + //output file names + ofstream outFasta, outQual, outFlow; + string outFastaFileName, outQualFileName; + string outFlowFileName = outputDir + m->getRootName(m->getSimpleName(sfftxtFilename)) + "flow"; + if (trim) { + outFastaFileName = outputDir + m->getRootName(m->getSimpleName(sfftxtFilename)) + "fasta"; + outQualFileName = outputDir + m->getRootName(m->getSimpleName(sfftxtFilename)) + "qual"; + }else{ + outFastaFileName = outputDir + m->getRootName(m->getSimpleName(sfftxtFilename)) + "raw.fasta"; + outQualFileName = outputDir + m->getRootName(m->getSimpleName(sfftxtFilename)) + "raw.qual"; + } + + if (fasta) { m->openOutputFile(outFastaFileName, outFasta); outputNames.push_back(outFastaFileName); outputTypes["fasta"].push_back(outFastaFileName); } + if (qual) { m->openOutputFile(outQualFileName, outQual); outputNames.push_back(outQualFileName); outputTypes["qual"].push_back(outQualFileName); } + 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); } + + //read common header + string commonHeader = m->getline(inSFF); + string magicNumber = m->getline(inSFF); + string version = m->getline(inSFF); + string indexOffset = m->getline(inSFF); + string indexLength = m->getline(inSFF); + int numReads = parseHeaderLineToInt(inSFF); + string headerLength = m->getline(inSFF); + string keyLength = m->getline(inSFF); + int numFlows = parseHeaderLineToInt(inSFF); + string flowgramCode = m->getline(inSFF); + string flowChars = m->getline(inSFF); + string keySequence = m->getline(inSFF); + m->gobble(inSFF); + + string seqName; + + if (flow) { outFlow << numFlows << endl; } + + for(int i=0;imothurOut("[ERROR]: Expected " + toString(numReads) + " but reached end of file at " + toString(i+1) + "."); m->mothurOutEndLine(); break; } + + Header header; + + //parse read header + inSFF >> seqName; + seqName = seqName.substr(1); + m->gobble(inSFF); + header.name = seqName; + + string runPrefix = parseHeaderLineToString(inSFF); header.timestamp = runPrefix; + string regionNumber = parseHeaderLineToString(inSFF); header.region = regionNumber; + string xyLocation = parseHeaderLineToString(inSFF); header.xy = xyLocation; + m->gobble(inSFF); + + string runName = parseHeaderLineToString(inSFF); + string analysisName = parseHeaderLineToString(inSFF); + string fullPath = parseHeaderLineToString(inSFF); + m->gobble(inSFF); + + string readHeaderLen = parseHeaderLineToString(inSFF); convert(readHeaderLen, header.headerLength); + string nameLength = parseHeaderLineToString(inSFF); convert(nameLength, header.nameLength); + int numBases = parseHeaderLineToInt(inSFF); header.numBases = numBases; + string clipQualLeft = parseHeaderLineToString(inSFF); convert(clipQualLeft, header.clipQualLeft); + int clipQualRight = parseHeaderLineToInt(inSFF); header.clipQualRight = clipQualRight; + string clipAdapLeft = parseHeaderLineToString(inSFF); convert(clipAdapLeft, header.clipAdapterLeft); + string clipAdapRight = parseHeaderLineToString(inSFF); convert(clipAdapRight, header.clipAdapterRight); + m->gobble(inSFF); + + seqRead read; + + //parse read + vector flowVector = parseHeaderLineToFloatVector(inSFF, numFlows); read.flowgram = flowVector; + vector flowIndices = parseHeaderLineToIntVector(inSFF, numBases); + + //adjust for print + vector flowIndicesAdjusted; flowIndicesAdjusted.push_back(flowIndices[0]); + for (int j = 1; j < flowIndices.size(); j++) { flowIndicesAdjusted.push_back(flowIndices[j] - flowIndices[j-1]); } + read.flowIndex = flowIndicesAdjusted; + + string bases = parseHeaderLineToString(inSFF); read.bases = bases; + vector qualityScores = parseHeaderLineToIntVector(inSFF, numBases); read.qualScores = qualityScores; + m->gobble(inSFF); + + //if you have provided an accosfile and this seq is not in it, then dont print + bool print = true; + if (seqNames.size() != 0) { if (seqNames.count(header.name) == 0) { print = false; } } + + //print + if (print) { + if (fasta) { printFastaSeqData(outFasta, read, header); } + if (qual) { printQualSeqData(outQual, read, header); } + if (flow) { printFlowSeqData(outFlow, read, header); } + } + + //report progress + if((i+1) % 10000 == 0){ m->mothurOut(toString(i+1)); m->mothurOutEndLine(); } + + if (m->control_pressed) { break; } + } + + //report progress + if (!m->control_pressed) { if((numReads) % 10000 != 0){ m->mothurOut(toString(numReads)); m->mothurOutEndLine(); } } + + inSFF.close(); + + if (fasta) { outFasta.close(); } + if (qual) { outQual.close(); } + if (flow) { outFlow.close(); } + + return 0; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "parseSffTxt"); + exit(1); + } +} +//********************************************************************************************************************** + +int SffInfoCommand::parseHeaderLineToInt(ifstream& file){ + try { + int number; + + while (!file.eof()) { + + char c = file.get(); + if (c == ':'){ + file >> number; + break; + } + + } + m->gobble(file); + return number; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "parseHeaderLineToInt"); + exit(1); + } + +} + +//********************************************************************************************************************** + +string SffInfoCommand::parseHeaderLineToString(ifstream& file){ + try { + string text; + + while (!file.eof()) { + char c = file.get(); + + if (c == ':'){ + //m->gobble(file); + //text = m->getline(file); + file >> text; + break; + } + } + m->gobble(file); + + return text; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "parseHeaderLineToString"); + exit(1); + } +} + +//********************************************************************************************************************** + +vector SffInfoCommand::parseHeaderLineToFloatVector(ifstream& file, int length){ + try { + vector floatVector(length); + + while (!file.eof()) { + char c = file.get(); + if (c == ':'){ + float temp; + for(int i=0;i> temp; + floatVector[i] = temp * 100; + } + break; + } + } + m->gobble(file); + return floatVector; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "parseHeaderLineToFloatVector"); + exit(1); + } +} + +//********************************************************************************************************************** + +vector SffInfoCommand::parseHeaderLineToIntVector(ifstream& file, int length){ + try { + vector intVector(length); + + while (!file.eof()) { + char c = file.get(); + if (c == ':'){ + for(int i=0;i> intVector[i]; + } + break; + } + } + m->gobble(file); + return intVector; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "parseHeaderLineToIntVector"); + exit(1); + } +} + +//********************************************************************************************************************** + + + +