X-Git-Url: https://git.donarmstrong.com/?p=mothur.git;a=blobdiff_plain;f=getlineagecommand.cpp;h=438aa3808441e60b9fb4fa22d4e9313a58956b2a;hp=5ace2a1077b4fe6984c470218c2aaee80113a041;hb=1a20e24ee786195ab0e1cccd4f5aede7a88f3f4e;hpb=ca0785e447ca7aa7e2f0ab8bb1155db126b551ea diff --git a/getlineagecommand.cpp b/getlineagecommand.cpp index 5ace2a1..438aa38 100644 --- a/getlineagecommand.cpp +++ b/getlineagecommand.cpp @@ -10,20 +10,106 @@ #include "getlineagecommand.h" #include "sequence.hpp" #include "listvector.hpp" +#include "counttable.h" //********************************************************************************************************************** - +vector GetLineageCommand::setParameters(){ + try { + CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "FNGLT", "none","fasta",false,false, true); parameters.push_back(pfasta); + CommandParameter pname("name", "InputTypes", "", "", "NameCount", "FNGLT", "none","name",false,false, true); parameters.push_back(pname); + CommandParameter pcount("count", "InputTypes", "", "", "NameCount-CountGroup", "FNGLT", "none","count",false,false, true); parameters.push_back(pcount); + CommandParameter pgroup("group", "InputTypes", "", "", "CountGroup", "FNGLT", "none","group",false,false, true); parameters.push_back(pgroup); + CommandParameter plist("list", "InputTypes", "", "", "none", "FNGLT", "none","list",false,false, true); parameters.push_back(plist); + CommandParameter ptaxonomy("taxonomy", "InputTypes", "", "", "none", "FNGLT", "none","taxonomy",false,true, true); parameters.push_back(ptaxonomy); + CommandParameter palignreport("alignreport", "InputTypes", "", "", "none", "FNGLT", "none","alignreport",false,false); parameters.push_back(palignreport); + CommandParameter ptaxon("taxon", "String", "", "", "", "", "","",false,true, true); parameters.push_back(ptaxon); + CommandParameter pdups("dups", "Boolean", "", "T", "", "", "","",false,false); parameters.push_back(pdups); + 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, "GetLineageCommand", "setParameters"); + exit(1); + } +} +//********************************************************************************************************************** +string GetLineageCommand::getHelpString(){ + try { + string helpString = ""; + helpString += "The get.lineage command reads a taxonomy file and any of the following file types: fasta, name, group, count, list or alignreport file.\n"; + helpString += "It outputs a file containing only the sequences from the taxonomy file that are from the taxon requested.\n"; + helpString += "The get.lineage command parameters are taxon, fasta, name, group, count, list, taxonomy, alignreport and dups. You must provide taxonomy unless you have a valid current taxonomy file.\n"; + helpString += "The dups parameter allows you to add the entire line from a name file if you add any name from the line. default=false. \n"; + helpString += "The taxon parameter allows you to select the taxons you would like to get and is required.\n"; + helpString += "You may enter your taxons with confidence scores, doing so will get only those sequences that belong to the taxonomy and whose cofidence scores is above the scores you give.\n"; + helpString += "If they belong to the taxonomy and have confidences below those you provide the sequence will not be selected.\n"; + helpString += "The get.lineage command should be in the following format: get.lineage(taxonomy=yourTaxonomyFile, taxon=yourTaxons).\n"; + helpString += "Example get.lineage(taxonomy=amazon.silva.taxonomy, taxon=Bacteria;Firmicutes;Bacilli;Lactobacillales;).\n"; + helpString += "Note: If you are running mothur in script mode you must wrap the taxon in ' characters so mothur will ignore the ; in the taxon.\n"; + helpString += "Example get.lineage(taxonomy=amazon.silva.taxonomy, taxon='Bacteria;Firmicutes;Bacilli;Lactobacillales;').\n"; + helpString += "Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFasta).\n"; + return helpString; + } + catch(exception& e) { + m->errorOut(e, "GetLineageCommand", "getHelpString"); + exit(1); + } +} +//********************************************************************************************************************** +string GetLineageCommand::getOutputPattern(string type) { + try { + string pattern = ""; + + if (type == "fasta") { pattern = "[filename],pick,[extension]"; } + else if (type == "taxonomy") { pattern = "[filename],pick,[extension]"; } + else if (type == "name") { pattern = "[filename],pick,[extension]"; } + else if (type == "group") { pattern = "[filename],pick,[extension]"; } + else if (type == "count") { pattern = "[filename],pick,[extension]"; } + else if (type == "list") { pattern = "[filename],pick,[extension]"; } + else if (type == "alignreport") { pattern = "[filename],pick.align.report"; } + else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true; } + + return pattern; + } + catch(exception& e) { + m->errorOut(e, "GetLineageCommand", "getOutputPattern"); + exit(1); + } +} +//********************************************************************************************************************** +GetLineageCommand::GetLineageCommand(){ + try { + abort = true; calledHelp = true; + setParameters(); + vector tempOutNames; + outputTypes["fasta"] = tempOutNames; + outputTypes["taxonomy"] = tempOutNames; + outputTypes["name"] = tempOutNames; + outputTypes["group"] = tempOutNames; + outputTypes["alignreport"] = tempOutNames; + outputTypes["list"] = tempOutNames; + outputTypes["count"] = tempOutNames; + } + catch(exception& e) { + m->errorOut(e, "GetLineageCommand", "GetLineageCommand"); + exit(1); + } +} +//********************************************************************************************************************** GetLineageCommand::GetLineageCommand(string option) { try { - abort = false; + abort = false; calledHelp = 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[] = {"fasta","name", "group", "alignreport", "taxon", "dups", "list","taxonomy","outputdir","inputdir"}; - vector myArray (Array, Array+(sizeof(Array)/sizeof(string))); + vector myArray = setParameters(); OptionParser parser(option); map parameters = parser.getParameters(); @@ -36,6 +122,16 @@ GetLineageCommand::GetLineageCommand(string option) { if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; } } + //initialize outputTypes + vector tempOutNames; + outputTypes["fasta"] = tempOutNames; + outputTypes["taxonomy"] = tempOutNames; + outputTypes["name"] = tempOutNames; + outputTypes["group"] = tempOutNames; + outputTypes["alignreport"] = tempOutNames; + outputTypes["list"] = tempOutNames; + outputTypes["count"] = 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 = ""; } @@ -91,21 +187,32 @@ GetLineageCommand::GetLineageCommand(string option) { //if the user has not given a path then, add inputdir. else leave path alone. if (path == "") { parameters["taxonomy"] = inputDir + it->second; } } + + it = parameters.find("count"); + //user has given a template file + if(it != parameters.end()){ + path = m->hasPath(it->second); + //if the user has not given a path then, add inputdir. else leave path alone. + if (path == "") { parameters["count"] = inputDir + it->second; } + } } //check for required parameters fastafile = validParameter.validFile(parameters, "fasta", true); - if (fastafile == "not open") { abort = true; } - else if (fastafile == "not found") { fastafile = ""; } + if (fastafile == "not open") { fastafile = ""; abort = true; } + else if (fastafile == "not found") { fastafile = ""; } + else { m->setFastaFile(fastafile); } namefile = validParameter.validFile(parameters, "name", true); - if (namefile == "not open") { abort = true; } + if (namefile == "not open") { namefile = ""; abort = true; } else if (namefile == "not found") { namefile = ""; } + else { m->setNameFile(namefile); } groupfile = validParameter.validFile(parameters, "group", true); if (groupfile == "not open") { abort = true; } else if (groupfile == "not found") { groupfile = ""; } + else { m->setGroupFile(groupfile); } alignfile = validParameter.validFile(parameters, "alignreport", true); if (alignfile == "not open") { abort = true; } @@ -114,14 +221,36 @@ GetLineageCommand::GetLineageCommand(string option) { listfile = validParameter.validFile(parameters, "list", true); if (listfile == "not open") { abort = true; } else if (listfile == "not found") { listfile = ""; } + else { m->setListFile(listfile); } taxfile = validParameter.validFile(parameters, "taxonomy", true); - if (taxfile == "not open") { abort = true; } - else if (taxfile == "not found") { taxfile = ""; m->mothurOut("The taxonomy parameter is required for the get.lineage command."); m->mothurOutEndLine(); abort = true; } + if (taxfile == "not open") { taxfile = ""; abort = true; } + else if (taxfile == "not found") { + taxfile = m->getTaxonomyFile(); + if (taxfile != "") { m->mothurOut("Using " + taxfile + " as input file for the taxonomy parameter."); m->mothurOutEndLine(); } + else { m->mothurOut("You have no current taxonomy file and the taxonomy parameter is required."); m->mothurOutEndLine(); abort = true; } + }else { m->setTaxonomyFile(taxfile); } string usedDups = "true"; - string temp = validParameter.validFile(parameters, "dups", false); if (temp == "not found") { temp = "false"; usedDups = ""; } + string temp = validParameter.validFile(parameters, "dups", false); + if (temp == "not found") { + if (namefile != "") { temp = "true"; } + else { temp = "false"; usedDups = ""; } + } dups = m->isTrue(temp); + + countfile = validParameter.validFile(parameters, "count", true); + if (countfile == "not open") { countfile = ""; abort = true; } + else if (countfile == "not found") { countfile = ""; } + else { m->setCountTableFile(countfile); } + + if ((namefile != "") && (countfile != "")) { + m->mothurOut("[ERROR]: you may only use one of the following: name or count."); m->mothurOutEndLine(); abort = true; + } + + if ((groupfile != "") && (countfile != "")) { + m->mothurOut("[ERROR]: you may only use one of the following: group or count."); m->mothurOutEndLine(); abort=true; + } taxons = validParameter.validFile(parameters, "taxon", false); if (taxons == "not found") { taxons = ""; m->mothurOut("No taxons given, please correct."); m->mothurOutEndLine(); abort = true; } @@ -130,12 +259,16 @@ GetLineageCommand::GetLineageCommand(string option) { if (taxons[0] == '\'') { taxons = taxons.substr(1); } if (taxons[(taxons.length()-1)] == '\'') { taxons = taxons.substr(0, (taxons.length()-1)); } } + m->splitAtChar(taxons, listOfTaxons, '-'); - - if ((fastafile == "") && (namefile == "") && (groupfile == "") && (alignfile == "") && (listfile == "") && (taxfile == "")) { m->mothurOut("You must provide one of the following: fasta, name, group, alignreport, taxonomy or listfile."); m->mothurOutEndLine(); abort = true; } + if ((fastafile == "") && (namefile == "") && (groupfile == "") && (alignfile == "") && (listfile == "") && (taxfile == "") && (countfile == "")) { m->mothurOut("You must provide one of the following: fasta, name, group, count, alignreport, taxonomy or listfile."); m->mothurOutEndLine(); abort = true; } - if ((usedDups != "") && (namefile == "")) { m->mothurOut("You may only use dups with the name option."); m->mothurOutEndLine(); abort = true; } - + if (countfile == "") { + if ((namefile == "") && ((fastafile != "") || (taxfile != ""))){ + vector files; files.push_back(fastafile); files.push_back(taxfile); + parser.getNameFile(files); + } + } } } @@ -146,50 +279,68 @@ GetLineageCommand::GetLineageCommand(string option) { } //********************************************************************************************************************** -void GetLineageCommand::help(){ - try { - m->mothurOut("The get.lineage command reads a taxonomy file and any of the following file types: fasta, name, group, list or alignreport file.\n"); - m->mothurOut("It outputs a file containing only the sequences from the taxonomy file that are from the taxon requested.\n"); - m->mothurOut("The get.lineage command parameters are taxon, fasta, name, group, list, taxonomy, alignreport and dups. You must provide taxonomy and taxon.\n"); - m->mothurOut("The dups parameter allows you to add the entire line from a name file if you add any name from the line. default=false. \n"); - m->mothurOut("The taxon parameter allows you to select the taxons you would like to get.\n"); - m->mothurOut("The get.lineage command should be in the following format: get.lineage(taxonomy=yourTaxonomyFile, taxon=yourTaxons).\n"); - m->mothurOut("Example get.lineage(taxonomy=amazon.silva.taxonomy, taxon=Bacteria;Firmicutes;Bacilli;Lactobacillales;).\n"); - m->mothurOut("Note: If you are running mothur in script mode you must wrap the taxon in ' characters so mothur will ignore the ; in the taxon.\n"); - m->mothurOut("Example get.lineage(taxonomy=amazon.silva.taxonomy, taxon='Bacteria;Firmicutes;Bacilli;Lactobacillales;').\n"); - m->mothurOut("Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFasta).\n\n"); - } - catch(exception& e) { - m->errorOut(e, "GetLineageCommand", "help"); - exit(1); - } -} - -//********************************************************************************************************************** - int GetLineageCommand::execute(){ try { - if (abort == true) { return 0; } + if (abort == true) { if (calledHelp) { return 0; } return 2; } if (m->control_pressed) { return 0; } + + if (countfile != "") { + if ((fastafile != "") || (listfile != "") || (taxfile != "")) { + m->mothurOut("\n[NOTE]: The count file should contain only unique names, so mothur assumes your fasta, list and taxonomy files also contain only uniques.\n\n"); + } + } //read through the correct file and output lines you want to keep if (taxfile != "") { readTax(); } //fills the set of names to get if (namefile != "") { readName(); } if (fastafile != "") { readFasta(); } + if (countfile != "") { readCount(); } if (groupfile != "") { readGroup(); } if (alignfile != "") { readAlign(); } if (listfile != "") { readList(); } - if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; } + if (m->control_pressed) { outputTypes.clear(); for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; } if (outputNames.size() != 0) { m->mothurOutEndLine(); m->mothurOut("Output File Names: "); m->mothurOutEndLine(); for (int i = 0; i < outputNames.size(); i++) { m->mothurOut(outputNames[i]); m->mothurOutEndLine(); } m->mothurOutEndLine(); + + //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("name"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setNameFile(current); } + } + + itTypes = outputTypes.find("group"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setGroupFile(current); } + } + + itTypes = outputTypes.find("list"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setListFile(current); } + } + + itTypes = outputTypes.find("taxonomy"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setTaxonomyFile(current); } + } + + itTypes = outputTypes.find("count"); + if (itTypes != outputTypes.end()) { + if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setCountTableFile(current); } + } } return 0; @@ -206,7 +357,10 @@ int GetLineageCommand::readFasta(){ try { string thisOutputDir = outputDir; if (outputDir == "") { thisOutputDir += m->hasPath(fastafile); } - string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(fastafile)) + "pick" + m->getExtension(fastafile); + map variables; + variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(fastafile)); + variables["[extension]"] = m->getExtension(fastafile); + string outputFileName = getOutputFileName("fasta", variables); ofstream out; m->openOutputFile(outputFileName, out); @@ -219,7 +373,7 @@ int GetLineageCommand::readFasta(){ while(!in.eof()){ - if (m->control_pressed) { in.close(); out.close(); remove(outputFileName.c_str()); return 0; } + if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(outputFileName); return 0; } Sequence currSeq(in); name = currSeq.getName(); @@ -237,8 +391,8 @@ int GetLineageCommand::readFasta(){ in.close(); out.close(); - if (wroteSomething == false) { m->mothurOut("Your file does not contain any sequence from the .accnos file."); m->mothurOutEndLine(); } - outputNames.push_back(outputFileName); + if (wroteSomething == false) { m->mothurOut("Your file contains does not contain any sequences from " + taxons + "."); m->mothurOutEndLine(); } + outputNames.push_back(outputFileName); outputTypes["fasta"].push_back(outputFileName); return 0; @@ -249,11 +403,71 @@ int GetLineageCommand::readFasta(){ } } //********************************************************************************************************************** +int GetLineageCommand::readCount(){ + try { + string thisOutputDir = outputDir; + if (outputDir == "") { thisOutputDir += m->hasPath(countfile); } + map variables; + variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(countfile)); + variables["[extension]"] = m->getExtension(countfile); + string outputFileName = getOutputFileName("count", variables); + + ofstream out; + m->openOutputFile(outputFileName, out); + + ifstream in; + m->openInputFile(countfile, in); + + bool wroteSomething = false; + + string headers = m->getline(in); m->gobble(in); + out << headers << endl; + + string name, rest; int thisTotal; + while (!in.eof()) { + + if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(outputFileName); return 0; } + + in >> name; m->gobble(in); + in >> thisTotal; m->gobble(in); + rest = m->getline(in); m->gobble(in); + if (m->debug) { m->mothurOut("[DEBUG]: " + name + '\t' + rest + "\n"); } + + if (names.count(name) != 0) { + out << name << '\t' << thisTotal << '\t' << rest << endl; + wroteSomething = true; + } + } + in.close(); + out.close(); + + //check for groups that have been eliminated + CountTable ct; + if (ct.testGroups(outputFileName)) { + ct.readTable(outputFileName); + ct.printTable(outputFileName); + } + + + if (wroteSomething == false) { m->mothurOut("Your file contains does not contain any sequences from " + taxons + "."); m->mothurOutEndLine(); } + outputTypes["count"].push_back(outputFileName); outputNames.push_back(outputFileName); + + return 0; + } + catch(exception& e) { + m->errorOut(e, "GetLineageCommand", "readCount"); + exit(1); + } +} +//********************************************************************************************************************** int GetLineageCommand::readList(){ try { string thisOutputDir = outputDir; if (outputDir == "") { thisOutputDir += m->hasPath(listfile); } - string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(listfile)) + "pick" + m->getExtension(listfile); + map variables; + variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(listfile)); + variables["[extension]"] = m->getExtension(listfile); + string outputFileName = getOutputFileName("list", variables); ofstream out; m->openOutputFile(outputFileName, out); @@ -264,7 +478,7 @@ int GetLineageCommand::readList(){ while(!in.eof()){ - if (m->control_pressed) { in.close(); out.close(); remove(outputFileName.c_str()); return 0; } + if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(outputFileName); return 0; } //read in list vector ListVector list(in); @@ -309,8 +523,8 @@ int GetLineageCommand::readList(){ in.close(); out.close(); - if (wroteSomething == false) { m->mothurOut("Your file does not contain any sequence from the .accnos file."); m->mothurOutEndLine(); } - outputNames.push_back(outputFileName); + if (wroteSomething == false) { m->mothurOut("Your file contains does not contain any sequences from " + taxons + "."); m->mothurOutEndLine(); } + outputNames.push_back(outputFileName); outputTypes["list"].push_back(outputFileName); return 0; @@ -325,7 +539,10 @@ int GetLineageCommand::readName(){ try { string thisOutputDir = outputDir; if (outputDir == "") { thisOutputDir += m->hasPath(namefile); } - string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(namefile)) + "pick" + m->getExtension(namefile); + map variables; + variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(namefile)); + variables["[extension]"] = m->getExtension(namefile); + string outputFileName = getOutputFileName("name", variables); ofstream out; m->openOutputFile(outputFileName, out); @@ -339,7 +556,7 @@ int GetLineageCommand::readName(){ while(!in.eof()){ - if (m->control_pressed) { in.close(); out.close(); remove(outputFileName.c_str()); return 0; } + if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(outputFileName); return 0; } in >> firstCol; in >> secondCol; @@ -348,15 +565,7 @@ int GetLineageCommand::readName(){ if (dups) { hold = secondCol; } vector parsedNames; - //parse second column saving each name - while (secondCol.find_first_of(',') != -1) { - name = secondCol.substr(0,secondCol.find_first_of(',')); - secondCol = secondCol.substr(secondCol.find_first_of(',')+1, secondCol.length()); - parsedNames.push_back(name); - } - - //get name after last , - parsedNames.push_back(secondCol); + m->splitAtComma(secondCol, parsedNames); vector validSecond; for (int i = 0; i < parsedNames.size(); i++) { @@ -402,8 +611,8 @@ int GetLineageCommand::readName(){ in.close(); out.close(); - if (wroteSomething == false) { m->mothurOut("Your file does not contain any sequence from the .accnos file."); m->mothurOutEndLine(); } - outputNames.push_back(outputFileName); + if (wroteSomething == false) { m->mothurOut("Your file contains does not contain any sequences from " + taxons + "."); m->mothurOutEndLine(); } + outputNames.push_back(outputFileName); outputTypes["name"].push_back(outputFileName); return 0; @@ -419,7 +628,10 @@ int GetLineageCommand::readGroup(){ try { string thisOutputDir = outputDir; if (outputDir == "") { thisOutputDir += m->hasPath(groupfile); } - string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(groupfile)) + "pick" + m->getExtension(groupfile); + map variables; + variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(groupfile)); + variables["[extension]"] = m->getExtension(groupfile); + string outputFileName = getOutputFileName("group", variables); ofstream out; m->openOutputFile(outputFileName, out); @@ -432,7 +644,7 @@ int GetLineageCommand::readGroup(){ while(!in.eof()){ - if (m->control_pressed) { in.close(); out.close(); remove(outputFileName.c_str()); return 0; } + if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(outputFileName); return 0; } in >> name; //read from first column @@ -450,8 +662,8 @@ int GetLineageCommand::readGroup(){ in.close(); out.close(); - if (wroteSomething == false) { m->mothurOut("Your file does not contain any sequence from the .accnos file."); m->mothurOutEndLine(); } - outputNames.push_back(outputFileName); + if (wroteSomething == false) { m->mothurOut("Your file contains does not contain any sequences from " + taxons + "."); m->mothurOutEndLine(); } + outputNames.push_back(outputFileName); outputTypes["group"].push_back(outputFileName); return 0; @@ -466,7 +678,10 @@ int GetLineageCommand::readTax(){ try { string thisOutputDir = outputDir; if (outputDir == "") { thisOutputDir += m->hasPath(taxfile); } - string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(taxfile)) + "pick" + m->getExtension(taxfile); + map variables; + variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(taxfile)); + variables["[extension]"] = m->getExtension(taxfile); + string outputFileName = getOutputFileName("taxonomy", variables); ofstream out; m->openOutputFile(outputFileName, out); @@ -474,28 +689,123 @@ int GetLineageCommand::readTax(){ m->openInputFile(taxfile, in); string name, tax; - bool wroteSomething = false; + //bool wroteSomething = false; + vector taxonsHasConfidence; taxonsHasConfidence.resize(listOfTaxons.size(), false); + vector< vector< map > > searchTaxons; searchTaxons.resize(listOfTaxons.size()); + vector noConfidenceTaxons; noConfidenceTaxons.resize(listOfTaxons.size(), ""); + + for (int i = 0; i < listOfTaxons.size(); i++) { + noConfidenceTaxons[i] = listOfTaxons[i]; + int hasConPos = listOfTaxons[i].find_first_of('('); + if (hasConPos != string::npos) { + taxonsHasConfidence[i] = true; + searchTaxons[i] = getTaxons(listOfTaxons[i]); + noConfidenceTaxons[i] = listOfTaxons[i]; + m->removeConfidences(noConfidenceTaxons[i]); + } + } + while(!in.eof()){ - if (m->control_pressed) { in.close(); out.close(); remove(outputFileName.c_str()); return 0; } + if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(outputFileName); return 0; } in >> name; //read from first column in >> tax; //read from second column - string newtax = tax; - - //if the users file contains confidence scores we want to ignore them when searching for the taxons - int hasConfidences = tax.find_first_of('('); - if (hasConfidences != string::npos) { - newtax = removeConfidences(tax); - } - - int pos = newtax.find(taxons); + string noQuotesTax = m->removeQuotes(tax); + + for (int j = 0; j < listOfTaxons.size(); j++) { + + string newtax = noQuotesTax; + + //if the users file contains confidence scores we want to ignore them when searching for the taxons, unless the taxon has them + if (!taxonsHasConfidence[j]) { + int hasConfidences = noQuotesTax.find_first_of('('); + if (hasConfidences != string::npos) { + newtax = noQuotesTax; + m->removeConfidences(newtax); + } + + int pos = newtax.find(noConfidenceTaxons[j]); + + if (pos != string::npos) { //this sequence contains the taxon the user wants + names.insert(name); + out << name << '\t' << tax << endl; + //since you belong to at least one of the taxons we want you are included so no need to search for other + break; + } + }else{//if listOfTaxons[i] has them and you don't them remove taxons + int hasConfidences = noQuotesTax.find_first_of('('); + if (hasConfidences == string::npos) { + + int pos = newtax.find(noConfidenceTaxons[j]); + + if (pos != string::npos) { //this sequence contains the taxon the user wants + names.insert(name); + out << name << '\t' << tax << endl; + //since you belong to at least one of the taxons we want you are included so no need to search for other + break; + } + }else { //both have confidences so we want to make sure the users confidences are greater then or equal to the taxons + //first remove confidences from both and see if the taxonomy exists + + string noNewTax = noQuotesTax; + int hasConfidences = noQuotesTax.find_first_of('('); + if (hasConfidences != string::npos) { + noNewTax = noQuotesTax; + m->removeConfidences(noNewTax); + } + + int pos = noNewTax.find(noConfidenceTaxons[j]); + + if (pos != string::npos) { //if yes, then are the confidences okay + + bool good = true; + vector< map > usersTaxon = getTaxons(newtax); + + //the usersTaxon is most likely longer than the searchTaxons, and searchTaxon[0] may relate to userTaxon[4] + //we want to "line them up", so we will find the the index where the searchstring starts + int index = 0; + for (int i = 0; i < usersTaxon.size(); i++) { + + if (usersTaxon[i].begin()->first == searchTaxons[j][0].begin()->first) { + index = i; + int spot = 0; + bool goodspot = true; + //is this really the start, or are we dealing with a taxon of the same name? + while ((spot < searchTaxons[j].size()) && ((i+spot) < usersTaxon.size())) { + if (usersTaxon[i+spot].begin()->first != searchTaxons[j][spot].begin()->first) { goodspot = false; break; } + else { spot++; } + } + + if (goodspot) { break; } + } + } + + for (int i = 0; i < searchTaxons[j].size(); i++) { + + if ((i+index) < usersTaxon.size()) { //just in case, should never be false + if (usersTaxon[i+index].begin()->second < searchTaxons[j][i].begin()->second) { //is the users cutoff less than the search taxons + good = false; + break; + } + }else { + good = false; + break; + } + } + + //passed the test so add you + if (good) { + names.insert(name); + out << name << '\t' << tax << endl; + break; + } + } + } + } - if (pos != string::npos) { //this sequence contains the taxon the user wants - names.insert(name); - out << name << '\t' << tax << endl; } m->gobble(in); @@ -504,7 +814,7 @@ int GetLineageCommand::readTax(){ out.close(); if (names.size() == 0) { m->mothurOut("Your taxonomy file does not contain any sequences from " + taxons + "."); m->mothurOutEndLine(); } - outputNames.push_back(outputFileName); + outputNames.push_back(outputFileName); outputTypes["taxonomy"].push_back(outputFileName); return 0; @@ -515,25 +825,52 @@ int GetLineageCommand::readTax(){ } } /**************************************************************************************************/ -string GetLineageCommand::removeConfidences(string tax) { +vector< map > GetLineageCommand::getTaxons(string tax) { try { - + + vector< map > t; string taxon = ""; int taxLength = tax.length(); + for(int i=0;iisNumeric1(confidenceScore)) { //its a confidence + newtaxon = taxon.substr(0, openParen); //rip off confidence + confidence = taxon.substr((openParen+1), (closeParen-openParen-1)); + }else { //its part of the taxon + newtaxon = taxon; + confidence = "0"; + } + }else{ + newtaxon = taxon; + confidence = "0"; + } + float con = 0; + convert(confidence, con); + + map temp; + temp[newtaxon] = con; + + t.push_back(temp); + taxon = ""; } else{ taxon += tax[i]; + } } - - return taxon; + + return t; } catch(exception& e) { - m->errorOut(e, "GetLineageCommand", "removeConfidences"); + m->errorOut(e, "GetLineageCommand", "getTaxons"); exit(1); } } @@ -543,7 +880,11 @@ int GetLineageCommand::readAlign(){ try { string thisOutputDir = outputDir; if (outputDir == "") { thisOutputDir += m->hasPath(alignfile); } - string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(alignfile)) + "pick.align.report"; + map variables; + variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(alignfile)); + variables["[extension]"] = m->getExtension(alignfile); + string outputFileName = getOutputFileName("alignreport", variables); + ofstream out; m->openOutputFile(outputFileName, out); @@ -563,7 +904,7 @@ int GetLineageCommand::readAlign(){ while(!in.eof()){ - if (m->control_pressed) { in.close(); out.close(); remove(outputFileName.c_str()); return 0; } + if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(outputFileName); return 0; } in >> name; //read from first column @@ -594,8 +935,8 @@ int GetLineageCommand::readAlign(){ in.close(); out.close(); - if (wroteSomething == false) { m->mothurOut("Your file does not contain any sequence from the .accnos file."); m->mothurOutEndLine(); } - outputNames.push_back(outputFileName); + if (wroteSomething == false) { m->mothurOut("Your file contains does not contain any sequences from " + taxons + "."); m->mothurOutEndLine(); } + outputNames.push_back(outputFileName); outputTypes["alignreport"].push_back(outputFileName); return 0;