42 #include "../TreeTemplate.h" 43 #include "../TreeTemplateTools.h" 45 #include <Bpp/Text/TextTools.h> 46 #include <Bpp/Io/FileTools.h> 47 #include <Bpp/Text/StringTokenizer.h> 48 #include <Bpp/Text/NestedStringTokenizer.h> 49 #include <Bpp/Numeric/VectorTools.h> 52 #include <Bpp/Seq/Io/NexusTools.h> 70 return string(
"Nexus format (trees only). ");
75 #if defined(NO_VIRTUAL_COV) 84 if (trees.size() == 0)
85 throw IOException(
"NexusIOTree::read(). No tree found in file.");
86 for (
size_t i = trees.size() - 1; i > 0; i--)
96 if (! in) {
throw IOException (
"NexusIOTree::read(). Failed to read from stream"); }
100 while (TextTools::toUpper(line) !=
"BEGIN TREES;")
103 throw Exception(
"NexusIOTree::read(). No trees block was found.");
104 line = TextTools::removeSurroundingWhiteSpaces(FileTools::getNextLine(in));
107 string cmdName =
"", cmdArgs =
"";
108 bool cmdFound = NexusTools::getNextCommand(in, cmdName, cmdArgs,
false);
110 throw Exception(
"NexusIOTree::read(). Missing tree command.");
111 cmdName = TextTools::toUpper(cmdName);
114 map<string, string> translation;
115 bool hasTranslation =
false;
116 if (cmdName ==
"TRANSLATE")
119 StringTokenizer st(cmdArgs,
",");
120 while (st.hasMoreToken())
122 string tok = TextTools::removeSurroundingWhiteSpaces(st.nextToken());
123 NestedStringTokenizer nst(tok,
"'",
"'",
" \t");
124 if (nst.numberOfRemainingTokens() != 2)
125 throw Exception(
"NexusIOTree::read(). Unvalid translation description.");
126 string name = nst.nextToken();
127 string tln = nst.nextToken();
128 translation[name] = tln;
130 hasTranslation =
true;
131 cmdFound = NexusTools::getNextCommand(in, cmdName, cmdArgs,
false);
133 throw Exception(
"NexusIOTree::read(). Missing tree command.");
135 cmdName = TextTools::toUpper(cmdName);
139 while (cmdFound && cmdName !=
"END")
141 if (cmdName !=
"TREE")
142 throw Exception(
"NexusIOTree::read(). Unvalid command found: " + cmdName);
143 string::size_type pos = cmdArgs.find(
"=");
144 if (pos == string::npos)
145 throw Exception(
"NexusIOTree::read(). unvalid format, should be tree-name=tree-description");
146 string description = cmdArgs.substr(pos + 1);
153 vector<Node*> leaves = tree->
getLeaves();
154 for (
size_t i = 0; i < leaves.size(); i++)
156 string name = leaves[i]->getName();
157 if (translation.find(name) == translation.end())
159 throw Exception(
"NexusIOTree::read(). No translation was given for this leaf: " + name);
161 leaves[i]->setName(translation[name]);
164 trees.push_back(tree);
165 cmdFound = NexusTools::getNextCommand(in, cmdName, cmdArgs,
false);
166 if (cmdFound) cmdName = TextTools::toUpper(cmdName);
175 trees.push_back(&const_cast<Tree&>(tree));
185 trees.push_back(&const_cast<Tree&>(tree));
194 if (! out) {
throw IOException (
"NexusIOTree::write: failed to write to stream"); }
196 out <<
"#NEXUS" << endl;
198 out <<
"BEGIN TREES;" << endl;
201 vector<string> names;
202 for (
size_t i = 0; i < trees.size(); i++)
204 names = VectorTools::vectorUnion(names, trees[i]->getLeavesNames());
207 map<string, size_t> translation;
209 for (
size_t i = 0; i < names.size(); i++)
211 translation[names[i]] = code++;
215 vector<Tree*> translatedTrees(trees.size());
216 for (
size_t i = 0; i < trees.size(); i++)
218 vector<int> leavesId = trees[i]->getLeavesId();
219 Tree* tree =
dynamic_cast<Tree*
>(trees[i]->clone());
220 for (
size_t j = 0; j < leavesId.size(); j++)
224 translatedTrees[i] = tree;
230 for (map<string, size_t>::iterator it = translation.begin(); it != translation.end(); it++)
232 out << endl <<
" " << it->second <<
"\t" << it->first;
234 if (count < translation.size())
240 for (
size_t i = 0; i < trees.size(); i++)
244 out <<
"END;" << endl;
247 for (
size_t i = 0; i < translatedTrees.size(); i++)
249 delete translatedTrees[i];
259 if (! out) {
throw IOException (
"NexusIOTree::write: failed to write to stream"); }
261 out <<
"#NEXUS" << endl;
263 out <<
"BEGIN TREES;" << endl;
266 vector<string> names;
267 for (
size_t i = 0; i < trees.size(); i++)
269 names = VectorTools::vectorUnion(names, trees[i]->getLeavesNames());
272 map<string, size_t> translation;
274 for (
size_t i = 0; i < names.size(); i++)
276 translation[names[i]] = code++;
280 vector<Tree*> translatedTrees(trees.size());
281 for (
size_t i = 0; i < trees.size(); i++)
283 vector<int> leavesId = trees[i]->getLeavesId();
284 Tree* tree =
dynamic_cast<Tree*
>(trees[i]->clone());
285 for (
size_t j = 0; j < leavesId.size(); j++)
289 translatedTrees[i] = tree;
295 for (map<string, size_t>::iterator it = translation.begin(); it != translation.end(); it++)
297 out << endl <<
" " << it->second <<
"\t" << it->first;
299 if (count < translation.size())
305 for (
size_t i = 0; i < trees.size(); i++)
309 out <<
"END;" << endl;
312 for (
size_t i = 0; i < translatedTrees.size(); i++)
314 delete translatedTrees[i];
const std::string getFormatDescription() const
TreeTemplate< Node > * read(const std::string &path) const
Read a tree from a file.
The phylogenetic tree class.
virtual void setNodeName(int nodeId, const std::string &name)=0
Interface for phylogenetic tree objects.
virtual std::vector< const N * > getLeaves() const
const std::string getFormatName() const
void write_(const Tree &tree, std::ostream &out) const
virtual std::string getNodeName(int nodeId) const =0