X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=sffinfocommand.cpp;h=4965cfd75e06c9f8ba8157056922514581e3e10e;hb=ae57e166b2ed7b475ec3f466106bd76fabadd063;hp=66f65ac9f8422eb5a8b8877000228cdabc21b487;hpb=f54925b51425c714502e90dd40b621a80fe1f583;p=mothur.git diff --git a/sffinfocommand.cpp b/sffinfocommand.cpp index 66f65ac..4965cfd 100644 --- a/sffinfocommand.cpp +++ b/sffinfocommand.cpp @@ -10,19 +10,83 @@ #include "sffinfocommand.h" #include "endiannessmacros.h" +//********************************************************************************************************************** +vector SffInfoCommand::setParameters(){ + try { + CommandParameter psff("sff", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(psff); + CommandParameter paccnos("accnos", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(paccnos); + CommandParameter psfftxt("sfftxt", "String", "", "", "", "", "",false,false); parameters.push_back(psfftxt); + CommandParameter pflow("flow", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(pflow); + CommandParameter ptrim("trim", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(ptrim); + CommandParameter pfasta("fasta", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pfasta); + CommandParameter pqfile("name", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pqfile); + CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir); + CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir); + + vector myArray; + for (int i = 0; i < parameters.size(); i++) { myArray.push_back(parameters[i].name); } + return myArray; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "setParameters"); + exit(1); + } +} +//********************************************************************************************************************** +string SffInfoCommand::getHelpString(){ + try { + string helpString = ""; + helpString += "The sffinfo command reads a sff file and extracts the sequence data, or you can use it to parse a sfftxt file.\n"; + helpString += "The sffinfo command parameters are sff, fasta, qfile, accnos, flow, sfftxt, and trim. sff is required. \n"; + helpString += "The sff parameter allows you to enter the sff file you would like to extract data from. You may enter multiple files by separating them by -'s.\n"; + helpString += "The fasta parameter allows you to indicate if you would like a fasta formatted file generated. Default=True. \n"; + helpString += "The qfile parameter allows you to indicate if you would like a quality file generated. Default=True. \n"; + helpString += "The flow parameter allows you to indicate if you would like a flowgram file generated. Default=False. \n"; + helpString += "The sfftxt parameter allows you to indicate if you would like a sff.txt file generated. Default=False. \n"; + helpString += "If you want to parse an existing sfftxt file into flow, fasta and quality file, enter the file name using the sfftxt parameter. \n"; + helpString += "The trim parameter allows you to indicate if you would like a sequences and quality scores trimmed to the clipQualLeft and clipQualRight values. Default=True. \n"; + helpString += "The accnos parameter allows you to provide a accnos file containing the names of the sequences you would like extracted. You may enter multiple files by separating them by -'s. \n"; + helpString += "Example sffinfo(sff=mySffFile.sff, trim=F).\n"; + helpString += "Note: No spaces between parameter labels (i.e. sff), '=' and parameters (i.e.yourSffFileName).\n"; + return helpString; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "getHelpString"); + exit(1); + } +} + + +//********************************************************************************************************************** +SffInfoCommand::SffInfoCommand(){ + try { + abort = true; calledHelp = true; + setParameters(); + vector tempOutNames; + outputTypes["fasta"] = tempOutNames; + outputTypes["flow"] = tempOutNames; + outputTypes["sfftxt"] = tempOutNames; + outputTypes["qfile"] = tempOutNames; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "SffInfoCommand"); + 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 if(option == "citation") { citation(); abort = true; calledHelp = true;} else { //valid paramters for this command - string Array[] = {"sff","outputdir","inputdir", "outputdir"}; - vector myArray (Array, Array+(sizeof(Array)/sizeof(string))); + vector myArray = setParameters(); OptionParser parser(option); map parameters = parser.getParameters(); @@ -33,6 +97,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 = ""; } @@ -40,33 +111,183 @@ 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]); - //if the user has not given a path then, add inputdir. else leave path alone. - if (path == "") { filenames[i] = inputDir + filenames[i]; } + bool ignore = false; + if (filenames[i] == "current") { + filenames[i] = m->getSFFFile(); + if (filenames[i] != "") { m->mothurOut("Using " + filenames[i] + " as input file for the sff parameter where you had given current."); m->mothurOutEndLine(); } + else { + m->mothurOut("You have no current sfffile, ignoring current."); m->mothurOutEndLine(); ignore=true; + //erase from file list + filenames.erase(filenames.begin()+i); + i--; + } } - - ifstream in; - int ableToOpen = openInputFile(filenames[i], in); - in.close(); - if (ableToOpen == 1) { - m->mothurOut(filenames[i] + " will be disregarded."); m->mothurOutEndLine(); - //erase from file list - filenames.erase(filenames.begin()+i); - i--; + if (!ignore) { + if (inputDir != "") { + 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 = 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() + m->getSimpleName(filenames[i]); + m->mothurOut("Unable to open " + filenames[i] + ". Trying default " + tryPath); m->mothurOutEndLine(); + 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) { + m->mothurOut("Unable to open " + filenames[i] + ". It will be disregarded."); m->mothurOutEndLine(); + //erase from file list + filenames.erase(filenames.begin()+i); + i--; + }else { m->setSFFFile(filenames[i]); } } } //make sure there is at least one valid file left if (filenames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; } } + + accnosName = validParameter.validFile(parameters, "accnos", false); + if (accnosName == "not found") { accnosName = ""; } + else { + hasAccnos = true; + 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++) { + bool ignore = false; + if (accnosFileNames[i] == "current") { + accnosFileNames[i] = m->getAccnosFile(); + if (accnosFileNames[i] != "") { m->mothurOut("Using " + accnosFileNames[i] + " as input file for the accnos parameter where you had given current."); m->mothurOutEndLine(); } + else { + m->mothurOut("You have no current accnosfile, ignoring current."); m->mothurOutEndLine(); ignore=true; + //erase from file list + accnosFileNames.erase(accnosFileNames.begin()+i); + i--; + } + } + + if (!ignore) { + + if (inputDir != "") { + 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 = 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() + m->getSimpleName(accnosFileNames[i]); + m->mothurOut("Unable to open " + accnosFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine(); + 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; + } + } + in.close(); + + if (ableToOpen == 1) { + m->mothurOut("Unable to open " + accnosFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); + //erase from file list + accnosFileNames.erase(accnosFileNames.begin()+i); + i--; + } + } + } + + //make sure there is at least one valid file left + if (accnosFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; } + } + + if (hasAccnos) { + 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(); } + } + + string temp = validParameter.validFile(parameters, "qfile", false); if (temp == "not found"){ temp = "T"; } + qual = m->isTrue(temp); + + temp = validParameter.validFile(parameters, "fasta", false); if (temp == "not found"){ temp = "T"; } + fasta = m->isTrue(temp); + + temp = validParameter.validFile(parameters, "flow", false); if (temp == "not found"){ temp = "F"; } + flow = m->isTrue(temp); + + temp = validParameter.validFile(parameters, "trim", false); if (temp == "not found"){ temp = "T"; } + 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 = ""; } + } + + if ((sfftxtFilename == "") && (filenames.size() == 0)) { + //if there is a current sff file, use it + string filename = m->getSFFFile(); + if (filename != "") { filenames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the sff parameter."); m->mothurOutEndLine(); } + else { m->mothurOut("[ERROR]: you must provide a valid sff or sfftxt file."); m->mothurOutEndLine(); abort=true; } + } } } catch(exception& e) { @@ -74,47 +295,48 @@ SffInfoCommand::SffInfoCommand(string option) { exit(1); } } -//********************************************************************************************************************** - -void SffInfoCommand::help(){ - try { - m->mothurOut("The sffinfo command reads a sff file and outputs a .sff.txt file.\n"); - - m->mothurOut("Example sffinfo(sff=...).\n"); - m->mothurOut("Note: No spaces between parameter labels (i.e. sff), '=' and parameters (i.e.yourSffFileName).\n\n"); - } - catch(exception& e) { - m->errorOut(e, "SffInfoCommand", "help"); - exit(1); - } -} -//********************************************************************************************************************** - -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++) { - if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; } + if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; } + + int start = time(NULL); m->mothurOut("Extracting info from " + filenames[s] + " ..." ); m->mothurOutEndLine(); - if (outputDir == "") { outputDir += hasPath(filenames[s]); } - string outputFileName = outputDir + getRootName(getSimpleName(filenames[s])) + "sff.txt"; - - extractSffInfo(filenames[s], outputFileName); + string accnos = ""; + if (hasAccnos) { accnos = accnosFileNames[s]; } - outputNames.push_back(outputFileName); + int numReads = extractSffInfo(filenames[s], accnos); - m->mothurOut("Done."); m->mothurOutEndLine(); + 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++) { m->mothurRemove(outputNames[i]); } 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); } } - if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; } + itTypes = outputTypes.find("qfile"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setQualFile(current); } + } + + itTypes = outputTypes.find("flow"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFlowFile(current); } + } //report output filenames m->mothurOutEndLine(); @@ -130,51 +352,94 @@ int SffInfoCommand::execute(){ } } //********************************************************************************************************************** -int SffInfoCommand::extractSffInfo(string input, string output){ +int SffInfoCommand::extractSffInfo(string input, string accnos){ try { - ofstream out; - openOutputFile(output, out); + + if (outputDir == "") { outputDir += m->hasPath(input); } + + if (accnos != "") { readAccnosFile(accnos); } + else { seqNames.clear(); } + + ofstream outSfftxt, outFasta, outQual, outFlow; + string outFastaFileName, outQualFileName; + string sfftxtFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "sff.txt"; + string outFlowFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "flow"; + if (trim) { + outFastaFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "fasta"; + outQualFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "qual"; + }else{ + outFastaFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "raw.fasta"; + outQualFileName = outputDir + m->getRootName(m->getSimpleName(input)) + "raw.qual"; + } + + 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); - CommonHeader* header = new CommonHeader(); + CommonHeader header; readCommonHeader(in, header); + + int count = 0; + mycount = 0; - cout << strlen(header->flowChars) << endl; - //cout << "magic = " << header->magicNumber << endl << "version = " << header->version << endl << "index offset = " << header->indexOffset << endl << "index length = "<< header->indexLength << endl << "numreads = " << header->numReads << endl << "header length = " << header->headerLength << endl << "key length = " << header->keyLength << endl; -//cout << "numflowreads = "<< header->numFlowsPerRead << endl << "flow format code = "<< header->flogramFormatCode << endl << "flow chars = " << header->flowChars << endl << "key sequence = " << header->keySequence << endl << endl; - cout << in.tellg() << endl; + //check magic number and version + if (header.magicNumber != 779314790) { m->mothurOut("Magic Number is not correct, not a valid .sff file"); m->mothurOutEndLine(); return count; } + 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 (flow) { outFlow << header.numFlowsPerRead << endl; } + //read through the sff file while (!in.eof()) { - //print common header - printCommonHeader(out, header, true); - - //read header - Header* readheader = new Header(); - readHeader(in, readheader); - cout << in.tellg() << endl; + bool print = true; - //print header - printHeader(out, readheader, true); + //read header + Header readheader; + readHeader(in, readheader); //read data - seqRead* read = new seqRead(); - readSeqData(in, read, header->numFlowsPerRead, readheader->numBases); + seqRead read; + readSeqData(in, read, header.numFlowsPerRead, readheader.numBases); + + //if you have provided an accosfile and this seq is not in it, then dont print + if (seqNames.size() != 0) { if (seqNames.count(readheader.name) == 0) { print = false; } } - cout << in.tellg() << endl; + //print + if (print) { + if (sfftxt) { printHeader(outSfftxt, readheader); printSffTxtSeqData(outSfftxt, read, readheader); } + if (fasta) { printFastaSeqData(outFasta, read, readheader); } + if (qual) { printQualSeqData(outQual, read, readheader); } + if (flow) { printFlowSeqData(outFlow, read, readheader); } + } - //print data - printSeqData(out, read, true); - + count++; + mycount++; + + //report progress + if((count+1) % 10000 == 0){ m->mothurOut(toString(count+1)); m->mothurOutEndLine(); } + + if (m->control_pressed) { count = 0; break; } + + if (count >= header.numReads) { break; } } + //report progress + if (!m->control_pressed) { if((count) % 10000 != 0){ m->mothurOut(toString(count)); m->mothurOutEndLine(); } } in.close(); - out.close(); - return 0; + if (sfftxt) { outSfftxt.close(); } + if (fasta) { outFasta.close(); } + if (qual) { outQual.close(); } + if (flow) { outFlow.close(); } + + return count; } catch(exception& e) { m->errorOut(e, "SffInfoCommand", "extractSffInfo"); @@ -182,103 +447,76 @@ int SffInfoCommand::extractSffInfo(string input, string output){ } } //********************************************************************************************************************** -int SffInfoCommand::readCommonHeader(ifstream& in, CommonHeader*& header){ +int SffInfoCommand::readCommonHeader(ifstream& in, CommonHeader& header){ try { if (!in.eof()) { - + //read magic number - char* buffer = new char(sizeof(header->magicNumber)); - in.read(buffer, sizeof(header->magicNumber)); - header->magicNumber = be_int4(*(unsigned int *)(buffer)); - delete[] buffer; - //cout << "here " << header->magicNumber << '\t' << in.tellg() << endl; + char buffer[4]; + in.read(buffer, 4); + header.magicNumber = be_int4(*(unsigned int *)(&buffer)); + //read version - header->version = new char(4); - in.read(header->version, 4); - string tempBuf0 = header->version; //this is in here because the read sometimes tacks on extra chars, not sure why? - if (tempBuf0.length() > 4) { tempBuf0 = tempBuf0.substr(0, 4); strcpy(header->version, tempBuf0.c_str()); } - //memcpy(header->version, buffer+4, 4); - //cout << "here " << header->version << '\t' << in.tellg() << endl; + char buffer9[4]; + in.read(buffer9, 4); + header.version = ""; + for (int i = 0; i < 4; i++) { header.version += toString((int)(buffer9[i])); } + //read offset - buffer = new char(sizeof(header->indexOffset)); - in.read(buffer, sizeof(header->indexOffset)); - header->indexOffset = be_int8(*(unsigned long int *)(buffer)); - delete[] buffer; - //cout << "here " << header->indexOffset << '\t' << in.tellg() << endl; + char buffer2 [8]; + in.read(buffer2, 8); + header.indexOffset = be_int8(*(unsigned long long *)(&buffer2)); + //read index length - buffer = new char(sizeof(header->indexLength)); - in.read(buffer, sizeof(header->indexLength)); - header->indexLength = be_int4(*(unsigned int *)(buffer)); - delete[] buffer; - //cout << "here " << header->indexLength << '\t' << in.tellg() << endl; + char buffer3 [4]; + in.read(buffer3, 4); + header.indexLength = be_int4(*(unsigned int *)(&buffer3)); + //read num reads - buffer = new char(sizeof(header->numReads)); - in.read(buffer, sizeof(header->numReads)); - header->numReads = be_int4(*(unsigned int *)(buffer)); - delete[] buffer; - //cout << "here " << header->numReads << '\t' << in.tellg() << endl; + char buffer4 [4]; + in.read(buffer4, 4); + header.numReads = be_int4(*(unsigned int *)(&buffer4)); + //read header length - buffer = new char(sizeof(header->headerLength)); - in.read(buffer, sizeof(header->headerLength)); - header->headerLength = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; - //cout << "here " << header->headerLength << '\t' << in.tellg() << endl; + char buffer5 [2]; + in.read(buffer5, 2); + header.headerLength = be_int2(*(unsigned short *)(&buffer5)); + //read key length - buffer = new char(sizeof(header->keyLength)); - in.read(buffer, sizeof(header->keyLength)); - header->keyLength = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; - -//cout << "here " << header->keyLength << '\t' << in.tellg() << endl; + char buffer6 [2]; + in.read(buffer6, 2); + header.keyLength = be_int2(*(unsigned short *)(&buffer6)); + //read number of flow reads - buffer = new char(sizeof(header->numFlowsPerRead)); - in.read(buffer, sizeof(header->numFlowsPerRead)); - header->numFlowsPerRead = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; - //cout << "here " << header->numFlowsPerRead << '\t' << in.tellg() << endl; + char buffer7 [2]; + in.read(buffer7, 2); + header.numFlowsPerRead = be_int2(*(unsigned short *)(&buffer7)); + //read format code - buffer = new char(sizeof(header->flogramFormatCode)); - in.read(buffer, sizeof(header->flogramFormatCode)); - header->flogramFormatCode = be_int1(*(char *)(buffer)); - delete[] buffer; - //cout << "here " << header->flogramFormatCode << '\t' << in.tellg() << endl; - + char buffer8 [1]; + in.read(buffer8, 1); + header.flogramFormatCode = (int)(buffer8[0]); + //read flow chars - //header->numFlowsPerRead = 800; - header->flowChars = new char(header->numFlowsPerRead); - buffer = new char(header->numFlowsPerRead); - //cout << "here" << endl; - //in.read(header->flowChars, header->numFlowsPerRead); - in.read(buffer, header->numFlowsPerRead); - memcpy(header->flowChars, buffer, header->numFlowsPerRead); - delete[] buffer; - //cout << "here" << endl; - //string tempBuf1 = header->flowChars; - //cout << "here " << in.tellg() << endl; - //if (tempBuf1.length() > header->numFlowsPerRead) { tempBuf1 = tempBuf1.substr(0, header->numFlowsPerRead); strcpy(header->flowChars, tempBuf1.c_str()); } - - // cout << "here " << header->flowChars << '\t' << in.tellg() << endl; + char* tempBuffer = new char[header.numFlowsPerRead]; + in.read(&(*tempBuffer), header.numFlowsPerRead); + header.flowChars = tempBuffer; + if (header.flowChars.length() > header.numFlowsPerRead) { header.flowChars = header.flowChars.substr(0, header.numFlowsPerRead); } + delete[] tempBuffer; + //read key - //header->keyLength = 4; - //char* myAlloc2 = new char(4); cout << "alloced" << endl; - header->keySequence = new char(header->keyLength); - //char* myAlloc = new char(4); - // cout << "here " << endl; - in.read(header->keySequence, header->keyLength); - string tempBuf2 = header->keySequence; - if (tempBuf2.length() > header->keyLength) { tempBuf2 = tempBuf2.substr(0, header->keyLength); strcpy(header->keySequence, tempBuf2.c_str()); } - //cout << "here " << header->keySequence << '\t' << in.tellg() << endl; - + char* tempBuffer2 = new char[header.keyLength]; + in.read(&(*tempBuffer2), header.keyLength); + header.keySequence = tempBuffer2; + if (header.keySequence.length() > header.keyLength) { header.keySequence = header.keySequence.substr(0, header.keyLength); } + delete[] tempBuffer2; + /* Pad to 8 chars */ - int spotInFile = in.tellg(); - //cout << spotInFile << endl; - int spot = floor((spotInFile + 7) /(float) 8) * 8; - //cout << spot << endl; + unsigned long long spotInFile = in.tellg(); + unsigned long long spot = (spotInFile + 7)& ~7; // ~ inverts in.seekg(spot); - - //exit(1); - + }else{ m->mothurOut("Error reading sff common header."); m->mothurOutEndLine(); } @@ -291,61 +529,62 @@ int SffInfoCommand::readCommonHeader(ifstream& in, CommonHeader*& header){ } } //********************************************************************************************************************** -int SffInfoCommand::readHeader(ifstream& in, Header*& header){ +int SffInfoCommand::readHeader(ifstream& in, Header& header){ try { if (!in.eof()) { - string tempBuf = ""; //read header length - char* buffer = new char(sizeof(header->headerLength)); - in.read(buffer, sizeof(header->headerLength)); - header->headerLength = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; + char buffer [2]; + in.read(buffer, 2); + header.headerLength = be_int2(*(unsigned short *)(&buffer)); //read name length - buffer = new char(sizeof(header->nameLength)); - in.read(buffer, sizeof(header->nameLength)); - header->nameLength = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; + char buffer2 [2]; + in.read(buffer2, 2); + header.nameLength = be_int2(*(unsigned short *)(&buffer2)); //read num bases - buffer = new char(sizeof(header->numBases)); - in.read(buffer, sizeof(header->numBases)); - header->numBases = be_int4(*(unsigned int *)(buffer)); - delete[] buffer; + char buffer3 [4]; + in.read(buffer3, 4); + header.numBases = be_int4(*(unsigned int *)(&buffer3)); //read clip qual left - buffer = new char(sizeof(header->clipQualLeft)); - in.read(buffer, sizeof(header->clipQualLeft)); - header->clipQualLeft = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; + char buffer4 [2]; + in.read(buffer4, 2); + header.clipQualLeft = be_int2(*(unsigned short *)(&buffer4)); + header.clipQualLeft = 5; //read clip qual right - buffer = new char(sizeof(header->clipQualRight)); - in.read(buffer, sizeof(header->clipQualRight)); - header->clipQualRight = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; + char buffer5 [2]; + in.read(buffer5, 2); + header.clipQualRight = be_int2(*(unsigned short *)(&buffer5)); //read clipAdapterLeft - buffer = new char(sizeof(header->clipAdapterLeft)); - in.read(buffer, sizeof(header->clipAdapterLeft)); - header->clipAdapterLeft = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; + char buffer6 [2]; + in.read(buffer6, 2); + header.clipAdapterLeft = be_int2(*(unsigned short *)(&buffer6)); //read clipAdapterRight - buffer = new char(sizeof(header->clipAdapterRight)); - in.read(buffer, sizeof(header->clipAdapterRight)); - header->clipAdapterRight = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; + char buffer7 [2]; + in.read(buffer7, 2); + header.clipAdapterRight = be_int2(*(unsigned short *)(&buffer7)); //read name - header->name = new char(header->nameLength); - //buffer = new char(header->nameLength); - in.read(header->name, header->nameLength); - //memcpy(header->name, buffer, header->nameLength); - //delete[] buffer; - + char* tempBuffer = new char[header.nameLength]; + in.read(&(*tempBuffer), header.nameLength); + header.name = tempBuffer; + 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 long spotInFile = in.tellg(); + unsigned long long spot = (spotInFile + 7)& ~7; + in.seekg(spot); + }else{ m->mothurOut("Error reading sff header info."); m->mothurOutEndLine(); } @@ -358,53 +597,45 @@ int SffInfoCommand::readHeader(ifstream& in, Header*& header){ } } //********************************************************************************************************************** -int SffInfoCommand::readSeqData(ifstream& in, seqRead*& read, int numFlowReads, int numBases){ +int SffInfoCommand::readSeqData(ifstream& in, seqRead& read, int numFlowReads, int numBases){ try { if (!in.eof()) { - - string tempBuf = ""; - char* buffer; - + //read flowgram - read->flowgram.resize(numFlowReads); + read.flowgram.resize(numFlowReads); for (int i = 0; i < numFlowReads; i++) { - buffer = new char((sizeof(unsigned short))); - in.read(buffer, (sizeof(unsigned short))); - read->flowgram[i] = be_int2(*(unsigned short *)(buffer)); - delete[] buffer; + char buffer [2]; + in.read(buffer, 2); + read.flowgram[i] = be_int2(*(unsigned short *)(&buffer)); } - - //read flowgram - read->flowIndex.resize(numBases); + + //read flowIndex + read.flowIndex.resize(numBases); for (int i = 0; i < numBases; i++) { - buffer = new char(1); - in.read(buffer, 1); - read->flowgram[i] = be_int1(*(unsigned int *)(buffer)); - delete[] buffer; + char temp[1]; + in.read(temp, 1); + read.flowIndex[i] = be_int1(*(unsigned char *)(&temp)); } - + //read bases - read->bases = new char(numBases); - in.read(read->bases, numBases); - tempBuf = buffer; - if (tempBuf.length() > numBases) { tempBuf = tempBuf.substr(0, numBases); strcpy(read->bases, tempBuf.c_str()); } - + char* tempBuffer = new char[numBases]; + in.read(&(*tempBuffer), numBases); + read.bases = tempBuffer; + if (read.bases.length() > numBases) { read.bases = read.bases.substr(0, numBases); } + delete[] tempBuffer; - //read flowgram - read->qualScores.resize(numBases); + //read qual scores + read.qualScores.resize(numBases); for (int i = 0; i < numBases; i++) { - buffer = new char(1); - in.read(buffer, 1); - read->qualScores[i] = be_int1(*(unsigned int *)(buffer)); - delete[] buffer; + char temp[1]; + in.read(temp, 1); + read.qualScores[i] = be_int1(*(unsigned char *)(&temp)); } - + /* Pad to 8 chars */ - int spotInFile = in.tellg(); - cout << spotInFile << endl; - int spot = floor((spotInFile + 7) /(float) 8) * 8; - cout << spot << endl; + unsigned long long spotInFile = in.tellg(); + unsigned long long spot = (spotInFile + 7)& ~7; in.seekg(spot); }else{ @@ -419,25 +650,61 @@ int SffInfoCommand::readSeqData(ifstream& in, seqRead*& read, int numFlowReads, } } //********************************************************************************************************************** -int SffInfoCommand::printCommonHeader(ofstream& out, CommonHeader* header, bool debug) { +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 { - string output = "Common Header:\nMagic Number: "; - output += toString(header->magicNumber) + '\n'; - output += "Version: " + toString(header->version) + '\n'; - output += "Index Offset: " + toString(header->indexOffset) + '\n'; - output += "Index Length: " + toString(header->indexLength) + '\n'; - output += "Number of Reads: " + toString(header->numReads) + '\n'; - output += "Header Length: " + toString(header->headerLength) + '\n'; - output += "Key Length: " + toString(header->keyLength) + '\n'; - output += "Number of Flows: " + toString(header->numFlowsPerRead) + '\n'; - output += "Format Code: " + toString(header->flogramFormatCode) + '\n'; - output += "Flow Chars: " + toString(header->flowChars) + '\n'; - output += "Key Sequence: " + toString(header->keySequence) + '\n'; - - out << output << endl; - - if (debug) { cout << output << endl; } + out << "Common Header:\nMagic Number: " << header.magicNumber << endl; + out << "Version: " << header.version << endl; + out << "Index Offset: " << header.indexOffset << endl; + out << "Index Length: " << header.indexLength << endl; + out << "Number of Reads: " << header.numReads << endl; + out << "Header Length: " << header.headerLength << endl; + out << "Key Length: " << header.keyLength << endl; + out << "Number of Flows: " << header.numFlowsPerRead << endl; + out << "Format Code: " << header.flogramFormatCode << endl; + out << "Flow Chars: " << header.flowChars << endl; + out << "Key Sequence: " << header.keySequence << endl << endl; return 0; } @@ -447,21 +714,26 @@ int SffInfoCommand::printCommonHeader(ofstream& out, CommonHeader* header, bool } } //********************************************************************************************************************** -int SffInfoCommand::printHeader(ofstream& out, Header* header, bool debug) { +int SffInfoCommand::printHeader(ofstream& out, Header& header) { try { - string name = header->name; - string output = ">" + name + "\nRead Header Length: " + toString(header->headerLength) + '\n'; - output += "Name Length: " + toString(header->nameLength) + '\n'; - output += "Number of Bases: " + toString(header->numBases) + '\n'; - output += "Clip Qual Left: " + toString(header->clipQualLeft) + '\n'; - output += "Clip Qual Right: " + toString(header->clipQualLeft) + '\n'; - output += "Clip Adap Left: " + toString(header->clipQualLeft) + '\n'; - output += "Clip Adap Right: " + toString(header->clipQualLeft) + '\n'; - - out << output << endl; - - if (debug) { cout << output << endl; } - + + out << ">" << header.name << 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; + out << "Full Path: " << endl << endl; + + out << "Read Header Len: " << header.headerLength << endl; + out << "Name Length: " << header.nameLength << endl; + out << "# of Bases: " << header.numBases << endl; + out << "Clip Qual Left: " << header.clipQualLeft << endl; + out << "Clip Qual Right: " << header.clipQualRight << endl; + out << "Clip Adap Left: " << header.clipAdapterLeft << endl; + out << "Clip Adap Right: " << header.clipAdapterRight << endl << endl; + return 0; } catch(exception& e) { @@ -471,27 +743,386 @@ int SffInfoCommand::printHeader(ofstream& out, Header* header, bool debug) { } //********************************************************************************************************************** -int SffInfoCommand::printSeqData(ofstream& out, seqRead* read, bool debug) { +int SffInfoCommand::printSffTxtSeqData(ofstream& out, seqRead& read, Header& header) { + try { + + out << "Flowgram: "; + for (int i = 0; i < read.flowgram.size(); i++) { out << setprecision(2) << (read.flowgram[i]/(float)100) << '\t'; } + + out << endl << "Flow Indexes: "; + int sum = 0; + 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]); } + + out << endl << "Bases: " << read.bases << endl << "Quality Scores: "; + for (int i = 0; i < read.qualScores.size(); i++) { out << read.qualScores[i] << '\t'; } + + + out << endl << endl; + + return 0; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "printSffTxtSeqData"); + exit(1); + } +} +//********************************************************************************************************************** +int SffInfoCommand::printFastaSeqData(ofstream& out, seqRead& read, Header& header) { + try { + + string seq = read.bases; + + if (trim) { + 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 { + seq = seq.substr(header.clipQualLeft-1); + } + }else{ + //if you wanted the sfftxt then you already converted the bases to the right case + if (!sfftxt) { + //make the bases you want to clip lowercase and the bases you want to keep upper case + if(header.clipQualRight == 0){ header.clipQualRight = seq.length(); } + for (int i = 0; i < (header.clipQualLeft-1); i++) { seq[i] = tolower(seq[i]); } + for (int i = (header.clipQualLeft-1); i < (header.clipQualRight-1); i++) { seq[i] = toupper(seq[i]); } + for (int i = (header.clipQualRight-1); i < seq.length(); i++) { seq[i] = tolower(seq[i]); } + } + } + + out << ">" << header.name << " xy=" << header.xy << endl; + out << seq << endl; + + return 0; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "printFastaSeqData"); + exit(1); + } +} + +//********************************************************************************************************************** +int SffInfoCommand::printQualSeqData(ofstream& out, seqRead& read, Header& header) { try { + + if (trim) { + if(header.clipQualRight < header.clipQualLeft){ + out << ">" << header.name << " xy=" << header.xy << endl; + 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 << " 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 << " xy=" << header.xy << " length=" << read.qualScores.size() << endl; + for (int i = 0; i < read.qualScores.size(); i++) { out << read.qualScores[i] << '\t'; } + } + + out << endl; + + return 0; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "printQualSeqData"); + exit(1); + } +} - string output = "FlowGram: "; - for (int i = 0; i < read->flowgram.size(); i++) { output += toString(read->flowgram[i]) +'\t'; } - output += "\nFlow Indexes: "; - for (int i = 0; i < read->flowIndex.size(); i++) { output += toString(read->flowIndex[i]) +'\t'; } - string bases = read->bases; - output += "\nBases: " + bases + '\n'; - for (int i = 0; i < read->qualScores.size(); i++) { output += toString(read->qualScores[i]) +'\t'; } - output += '\n'; +//********************************************************************************************************************** +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 << output << endl; - if (debug) { cout << output << endl; } + return 0; + } + catch(exception& e) { + m->errorOut(e, "SffInfoCommand", "printFlowSeqData"); + exit(1); + } +} +//********************************************************************************************************************** +int SffInfoCommand::readAccnosFile(string filename) { + try { + //remove old names + seqNames.clear(); + + ifstream in; + m->openInputFile(filename, in); + string name; + + while(!in.eof()){ + in >> name; m->gobble(in); + + seqNames.insert(name); + + if (m->control_pressed) { seqNames.clear(); break; } + } + in.close(); return 0; } catch(exception& e) { - m->errorOut(e, "SffInfoCommand", "printSeqData"); + m->errorOut(e, "SffInfoCommand", "readAccnosFile"); 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 fileRoot = m->getRootName(m->getSimpleName(sfftxtFilename)); + if (fileRoot.length() > 0) { + //rip off last . + fileRoot = fileRoot.substr(0, fileRoot.length()-1); + fileRoot = m->getRootName(fileRoot); + } + + string outFlowFileName = outputDir + fileRoot + "flow"; + if (trim) { + outFastaFileName = outputDir + fileRoot + "fasta"; + outQualFileName = outputDir + fileRoot + "qual"; + }else{ + outFastaFileName = outputDir + fileRoot + "raw.fasta"; + outQualFileName = outputDir + fileRoot + "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); + } +} + +//********************************************************************************************************************** + + + +