42 #include "../TreeTemplate.h" 45 #include <Bpp/Text/TextTools.h> 46 #include <Bpp/BppString.h> 47 #include <Bpp/BppBoolean.h> 48 #include <Bpp/Numeric/Number.h> 61 supportedProperties_(),
62 useTagsAsPropertyNames_(useTagsAsPptNames),
93 return string(
"New Hampshire eXtended parenthesis format. ") +
94 "See http://www.phylosoft.org/NHX/ for more info.";
99 #if defined(NO_VIRTUAL_COV) 107 if (! in) {
throw IOException (
"Nhx ::read: failed to read from stream"); }
110 string temp, description;
114 getline(in, temp,
'\n');
115 string::size_type index = temp.find(
";");
116 if (index != string::npos)
118 description += temp.substr(0, index + 1);
121 else description += temp;
123 vector<string> beginnings, endings;
124 beginnings.push_back(
"[&&NHX:");
125 description = TextTools::removeSubstrings(description,
'[',
']', beginnings, endings);
126 return parenthesisToTree(description);
134 if (! out) {
throw IOException (
"Nhx::writeTree: failed to write to stream"); }
135 out << treeToParenthesis(tree);
144 if (! out) {
throw IOException (
"Nhx::writeTree: failed to write to stream"); }
145 out << treeToParenthesis(tree);
150 void Nhx::read(istream& in, vector<Tree*>& trees)
const throw (Exception)
153 if (! in) {
throw IOException (
"Nhx::read: failed to read from stream"); }
156 string temp, description;
157 string::size_type index;
158 vector <string > beginnings, endings;
159 beginnings.push_back(
"[&&NHX:");
165 getline(in, temp,
'\n');
166 index = temp.find(
";");
167 if (index != string::npos)
169 description += temp.substr(0, index + 1);
170 description = TextTools::removeSubstrings(description,
'[',
']', beginnings, endings);
171 trees.push_back(parenthesisToTree(description));
172 description = temp.substr(index + 1);
174 else description += temp;
181 void Nhx::write_(
const vector<Tree*>& trees, ostream& out)
const throw (Exception)
184 if (! out) {
throw IOException (
"Nhx::write: failed to write to stream"); }
185 for(
unsigned int i = 0; i < trees.size(); i++)
187 out << treeToParenthesis(*trees[i]);
197 if (! out) {
throw IOException (
"Nhx::write: failed to write to stream"); }
198 for(
unsigned int i = 0; i < trees.size(); i++)
200 out << treeToParenthesis(*trees[i]);
214 size_t lastP = elt.rfind(
")"), firstP;
215 size_t beginAnno = string::npos;
216 if (lastP == string::npos)
217 beginAnno = elt.rfind(
"[&&NHX:");
219 beginAnno = elt.find(
"[&&NHX:", lastP + 1);
220 string elementWithoutAnnotation;
221 if (beginAnno != string::npos) {
222 size_t endAnno = elt.find(
"]", beginAnno + 7);
223 element.
annotation = elt.substr(beginAnno + 7, endAnno - beginAnno - 7);
224 elementWithoutAnnotation = elt.substr(0, beginAnno);
227 elementWithoutAnnotation = elt;
233 bool hasColon =
false;
234 for (colonIndex = elementWithoutAnnotation.size() - 1; colonIndex > 0 && elementWithoutAnnotation[colonIndex] !=
')' && !hasColon; --colonIndex)
236 if (elementWithoutAnnotation[colonIndex] ==
':')
247 elt2 = elementWithoutAnnotation.substr(0, colonIndex + 1);
248 element.
length = elementWithoutAnnotation.substr(colonIndex + 2);
253 elt2 = elementWithoutAnnotation;
256 lastP = elt2.rfind(
')');
257 firstP = elt2.find(
'(');
258 if (firstP == string::npos)
267 if (lastP < firstP)
throw IOException(
"Nhx::getElement(). Invalid format: bad closing parenthesis in " + elt2);
268 element.
content = elt2.substr(firstP + 1, lastP - firstP - 1);
273 throw IOException(
"Bad tree description: " + elt);
294 if (!TextTools::isEmpty(elt.
length))
304 throw Exception(
"Nhx::parenthesisToNode. At least one one is missing an id (ND tag).");
307 NestedStringTokenizer nt(elt.
content,
"(",
")",
",");
308 vector<string> elements;
309 while (nt.hasMoreToken())
311 elements.push_back(nt.nextToken());
316 string name = TextTools::removeSurroundingWhiteSpaces(elements[0]);
322 for (
size_t i = 0; i < elements.size(); ++i)
337 string::size_type semi = description.rfind(
';');
338 if (semi == string::npos)
339 throw Exception(
"Nhx::parenthesisToTree(). Bad format: no semi-colon found.");
340 string content = description.substr(0, semi);
341 Node* node = parenthesisToNode(content);
356 const BppString* castedPptObject =
dynamic_cast<const BppString*
>(pptObject);
358 return castedPptObject->toSTL();
360 throw Exception(
"Nhx::propertyToString_. Unvalid property type, should be of class BppString.");
361 }
else if (type == 1) {
362 const Number<int>* castedPptObject =
dynamic_cast<const Number<int>*
>(pptObject);
364 return TextTools::toString(castedPptObject->getValue());
366 throw Exception(
"Nhx::propertyToString_. Unvalid property type, should be of class Number<int>.");
367 }
else if (type == 2) {
368 const Number<double>* castedPptObject =
dynamic_cast<const Number<double>*
>(pptObject);
370 return TextTools::toString(castedPptObject->getValue());
372 throw Exception(
"Nhx::propertyToString_. Unvalid property type, should be of class Number<double>.");
373 }
else if (type == 3) {
374 const BppBoolean* castedPptObject =
dynamic_cast<const BppBoolean*
>(pptObject);
376 return TextTools::toString(castedPptObject->getValue());
378 throw Exception(
"Nhx::propertyToString_. Unvalid property type, should be of class BppBoolean.");
380 throw Exception(
"Nhx::propertyToString_. Unsupported type: " + TextTools::toString(type));
389 return new BppString(pptDesc);
390 }
else if (type == 1) {
391 return new Number<int>(TextTools::toInt(pptDesc));
392 }
else if (type == 2) {
393 return new Number<double>(TextTools::toDouble(pptDesc));
394 }
else if (type == 3) {
395 return new BppBoolean(TextTools::to<bool>(pptDesc));
397 throw Exception(
"Nhx::stringToProperty_. Unsupported type: " + TextTools::toString(type));
425 s <<
":ND="<<TextTools::toString(node.
getId());
492 string propsDesc = TextTools::removeChar(properties,
']');
493 StringTokenizer st(propsDesc,
":",
true,
true);
494 map<string, string> props;
495 while (st.hasMoreToken())
497 string token = st.nextToken();
498 if (TextTools::hasSubstring(token,
"=")) {
499 StringTokenizer pt(token,
"=",
true,
true);
500 string tag = pt.nextToken();
501 string value = pt.nextToken();
507 if (props.find(it->tag) != props.end()) {
520 if (props.find(
"ND") != props.end()) {
521 string prop = props[
"ND"];
522 if (TextTools::isDecimalNumber(prop))
524 node.
setId(TextTools::toInt(prop));
virtual N * getRootNode()
virtual void addSon(size_t pos, Node *node)
void changeNamesToTags(Node &node) const
Convert property names from names to tags.
Element getElement(const std::string &elt) const
virtual bool hasNodeProperty(const std::string &name) const
virtual std::string getName() const
Get the name associated to this node, if there is one, otherwise throw a NodeException.
virtual void deleteNodeProperty(const std::string &name)
virtual Clonable * getBranchProperty(const std::string &name)
virtual const Node * getSon(size_t pos) const
TreeTemplate< Node > * parenthesisToTree(const std::string &description) const
virtual bool hasDistanceToFather() const
Tell is this node has a distance to the father.
The phylogenetic tree class.
Interface for phylogenetic tree objects.
void registerProperty(const Property &property)
std::string nodeToParenthesis(const Node &node) const
virtual void deleteBranchProperty(const std::string &name)
virtual void setName(const std::string &name)
Give a name or update the name associated to the node.
bool useTagsAsPropertyNames_
virtual bool isLeaf() const
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
const std::string getFormatDescription() const
std::set< Property > supportedProperties_
virtual void setRootNode(N *root)
virtual int getId() const
Get the node's id.
const std::string getFormatName() const
Node * parenthesisToNode(const std::string &description) const
std::string propertiesToParenthesis(const Node &node) const
void changeTagsToNames(Node &node) const
Convert property names from tag to names.
std::string treeToParenthesis(const TreeTemplate< Node > &tree) const
The phylogenetic node class.
virtual void setId(int id)
Set this node's id.
virtual Clonable * getNodeProperty(const std::string &name)
TreeTemplate< Node > * read(const std::string &path) const
Read a tree from a file.
virtual void setDistanceToFather(double distance)
Set or update the distance toward the father node.
Nhx(bool useTagsAsPptNames=true)
Build a new Nhx reader/writer.
void write_(const Tree &tree, std::ostream &out) const
bool setNodeProperties(Node &node, const std::string properties) const
virtual size_t getNumberOfSons() const
void resetNodesId()
Number nodes.
virtual bool hasBranchProperty(const std::string &name) const
virtual void setBranchProperty(const std::string &name, const Clonable &property)
Set/add a branch property.
static Clonable * stringToProperty_(const std::string &pptDesc, short type)
virtual void setNodeProperty(const std::string &name, const Clonable &property)
Set/add a node property.
static std::string propertyToString_(const Clonable *pptObject, short type)