bpp-phyl3 3.0.0
Node.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
5#ifndef BPP_PHYL_TREE_NODE_H
6#define BPP_PHYL_TREE_NODE_H
7
8#include <Bpp/BppString.h>
9#include <Bpp/Clonable.h>
10#include <Bpp/Numeric/Number.h>
11#include <Bpp/Utils/MapTools.h>
12
13#include "TreeExceptions.h"
14
15// From the STL:
16#include <string>
17#include <vector>
18#include <map>
19#include <iostream>
20#include <algorithm>
21#include <cstddef>
22#include <memory>
23
24namespace bpp
25{
26class PhyloTree;
27class PhyloNode;
58class Node
59{
60protected:
61 int id_;
62 std::string* name_;
63 std::vector<Node*> sons_;
66 mutable std::map<std::string, Clonable*> nodeProperties_;
67 mutable std::map<std::string, Clonable*> branchProperties_;
68
69public:
73 Node() :
74 id_(0),
75 name_(0),
76 sons_(),
77 father_(0),
81 {}
82
86 Node(int id) :
87 id_(id),
88 name_(0),
89 sons_(),
90 father_(0),
94 {}
95
99 Node(const std::string& name) :
100 id_(0),
101 name_(new std::string(name)),
102 sons_(),
103 father_(0),
107 {}
108
112 Node(int id, const std::string& name) :
113 id_(id),
114 name_(new std::string(name)),
115 sons_(),
116 father_(0),
120 {}
121
129 Node(const Node& node);
130
139 Node& operator=(const Node& node);
140
141 Node* clone() const { return new Node(*this); }
142
143public:
144 virtual ~Node()
145 {
146 if (name_) delete name_;
148 for (std::map<std::string, Clonable*>::iterator i = nodeProperties_.begin(); i != nodeProperties_.end(); i++)
149 {
150 delete i->second;
151 }
152 for (std::map<std::string, Clonable*>::iterator i = branchProperties_.begin(); i != branchProperties_.end(); i++)
153 {
154 delete i->second;
155 }
156 }
157
158public:
170 virtual int getId() const { return id_; }
171
177 virtual void setId(int id) { id_ = id; }
178
179 virtual std::vector<int> getSonsId() const
180 {
181 std::vector<int> sonsId(sons_.size());
182 for (size_t i = 0; i < sons_.size(); i++)
183 {
184 sonsId[i] = sons_[i]->getId();
185 }
186 return sonsId;
187 }
188
203 virtual std::string getName() const
204 {
205 if (!hasName()) throw NodePException("Node::getName: no name associated to this node.", this);
206 return *name_;
207 }
208
214 virtual void setName(const std::string& name)
215 {
216 if (name_) delete name_;
217 name_ = new std::string(name);
218 }
219
223 virtual void deleteName()
224 {
225 if (name_) delete name_;
226 name_ = 0;
227 }
228
234 virtual bool hasName() const { return name_ != 0; }
235
250 virtual double getDistanceToFather() const
251 {
252 if (!hasDistanceToFather())
253 throw NodePException("Node::getDistanceToFather: Node has no distance.", this);
254 return *distanceToFather_;
255 }
256
266 virtual void setDistanceToFather(double distance)
267 {
269 delete distanceToFather_;
270 distanceToFather_ = new double(distance);
271 }
272
277 {
279 delete distanceToFather_;
281 }
282
288 virtual bool hasDistanceToFather() const
289 {
290 return distanceToFather_ != 0;
291 }
292
306 virtual const Node* getFather() const { return father_; }
307
313 virtual Node* getFather() { return father_; }
314
315 virtual int getFatherId() const { return father_->getId(); }
316
322 virtual void setFather(Node* node)
323 {
324 if (!node)
325 throw NullPointerException("Node::setFather(). Empty node given as input.");
326 father_ = node;
327 if (find(node->sons_.begin(), node->sons_.end(), this) == node->sons_.end())
328 node->sons_.push_back(this);
329 else // Otherwise node is already present.
330 std::cerr << "DEVEL warning: Node::setFather. Son node already registered! No pb here, but could be a bug in your implementation..." << std::endl;
331 }
332
337 {
338 Node* f = father_;
339 father_ = 0;
340 return f;
341 }
342
346 virtual bool hasFather() const { return father_ != 0; }
347
355 virtual size_t getNumberOfSons() const { return sons_.size(); }
356
357 virtual std::vector<Node*>& getSons()
358 {
359 return sons_;
360 }
361
362 virtual const Node* getSon(size_t pos) const
363 {
364 if (pos >= sons_.size()) throw IndexOutOfBoundsException("Node::getSon() const.", pos, 0, sons_.size() - 1);
365 return sons_[pos];
366 }
367
368 virtual const Node& son(size_t pos) const
369 {
370 if (pos >= sons_.size()) throw IndexOutOfBoundsException("Node::son() const.", pos, 0, sons_.size() - 1);
371 return *sons_[pos];
372 }
373
374 virtual Node* getSon(size_t pos)
375 {
376 if (pos >= sons_.size()) throw IndexOutOfBoundsException("Node::getSon().", pos, 0, sons_.size() - 1);
377 return sons_[pos];
378 }
379
380 virtual Node& son(size_t pos)
381 {
382 if (pos >= sons_.size()) throw IndexOutOfBoundsException("Node::son().", pos, 0, sons_.size() - 1);
383 return *sons_[pos];
384 }
385
386 virtual void addSon(size_t pos, Node* node)
387 {
388 if (!node)
389 throw NullPointerException("Node::addSon(). Empty node given as input.");
390 if (find(sons_.begin(), sons_.end(), node) == sons_.end())
391 sons_.insert(sons_.begin() + static_cast<ptrdiff_t>(pos), node);
392 else // Otherwise node is already present.
393 std::cerr << "DEVEL warning: Node::addSon. Son node already registered! No pb here, but could be a bug in your implementation..." << std::endl;
394
395 node->father_ = this;
396 }
397
398 virtual void addSon(Node* node)
399 {
400 if (!node)
401 throw NullPointerException("Node::addSon(). Empty node given as input.");
402 if (find(sons_.begin(), sons_.end(), node) == sons_.end())
403 sons_.push_back(node);
404 else // Otherwise node is already present.
405 throw NodePException("Node::addSon. Trying to add a node which is already present.");
406 node->father_ = this;
407 }
408
409 virtual void setSon(size_t pos, Node* node)
410 {
411 if (!node)
412 throw NullPointerException("Node::setSon(). Empty node given as input.");
413 if (pos >= sons_.size())
414 throw IndexOutOfBoundsException("Node::setSon(). Invalid node position.", pos, 0, sons_.size() - 1);
415 std::vector<Node*>::iterator search = find(sons_.begin(), sons_.end(), node);
416 if (search == sons_.end() || search == sons_.begin() + static_cast<ptrdiff_t>(pos))
417 sons_[pos] = node;
418 else
419 throw NodePException("Node::setSon. Trying to set a node which is already present.");
420 node->father_ = this;
421 }
422
423 virtual Node* removeSon(size_t pos)
424 {
425 if (pos >= sons_.size())
426 throw IndexOutOfBoundsException("Node::removeSon(). Invalid node position.", pos, 0, sons_.size() - 1);
427 Node* node = sons_[pos];
428 sons_.erase(sons_.begin() + static_cast<ptrdiff_t>(pos));
429 node->removeFather();
430 return node;
431 }
432
433 virtual void removeSon(Node* node)
434 {
435 if (!node)
436 throw NullPointerException("Node::removeSon(). Empty node given as input.");
437 for (size_t i = 0; i < sons_.size(); i++)
438 {
439 if (sons_[i] == node)
440 {
441 sons_.erase(sons_.begin() + static_cast<ptrdiff_t>(i));
442 node->removeFather();
443 return;
444 }
445 }
446 throw NodeNotFoundException("Node::removeSon.", node->getId());
447 }
448
449 virtual void removeSons()
450 {
451 while (sons_.size() != 0)
452 removeSon(static_cast<size_t>(0));
453 }
454
455 virtual void swap(size_t branch1, size_t branch2);
456
457 virtual size_t getSonPosition(const Node* son) const;
458
461 // From PhyloNode
462
463 /*
464 * Add PhyloNode tree as Son of this Node
465 */
466
467 void addSubTree(const PhyloTree& tree, std::shared_ptr<PhyloNode> phyloNode);
468
469 // These functions must not be declared as virtual!!
470
471 std::vector<const Node*> getNeighbors() const;
472
473 std::vector<Node*> getNeighbors();
474
475 virtual size_t degree() const { return getNumberOfSons() + (hasFather() ? 1 : 0); }
476
485 Node* operator[](int i) { return (i < 0) ? father_ : sons_[static_cast<size_t>(i)]; }
486
487 const Node* operator[](int i) const { return (i < 0) ? father_ : sons_[static_cast<size_t>(i)]; }
488
507 virtual void setNodeProperty(const std::string& name, const Clonable& property)
508 {
509 if (hasNodeProperty(name))
510 delete nodeProperties_[name];
511 nodeProperties_[name] = property.clone();
512 }
513
514 virtual Clonable* getNodeProperty(const std::string& name)
515 {
516 if (hasNodeProperty(name))
517 return nodeProperties_[name];
518 else
519 throw PropertyNotFoundException("", name, this);
520 }
521
522 virtual const Clonable* getNodeProperty(const std::string& name) const
523 {
524 if (hasNodeProperty(name))
525 return const_cast<const Clonable*>(nodeProperties_[name]);
526 else
527 throw PropertyNotFoundException("", name, this);
528 }
529
530 virtual Clonable* removeNodeProperty(const std::string& name)
531 {
532 if (hasNodeProperty(name))
533 {
534 Clonable* removed = nodeProperties_[name];
535 nodeProperties_.erase(name);
536 return removed;
537 }
538 else
539 throw PropertyNotFoundException("", name, this);
540 }
541
542 virtual void deleteNodeProperty(const std::string& name)
543 {
544 if (hasNodeProperty(name))
545 {
546 delete nodeProperties_[name];
547 nodeProperties_.erase(name);
548 }
549 else
550 throw PropertyNotFoundException("", name, this);
551 }
552
558 virtual void removeNodeProperties()
559 {
560 nodeProperties_.clear();
561 }
562
566 virtual void deleteNodeProperties()
567 {
568 for (std::map<std::string, Clonable*>::iterator i = nodeProperties_.begin(); i != nodeProperties_.end(); i++)
569 {
570 delete i->second;
571 }
572 nodeProperties_.clear();
573 }
574
575 virtual bool hasNodeProperty(const std::string& name) const { return nodeProperties_.find(name) != nodeProperties_.end(); }
576
577 virtual std::vector<std::string> getNodePropertyNames() const { return MapTools::getKeys(nodeProperties_); }
578
597 virtual void setBranchProperty(const std::string& name, const Clonable& property)
598 {
599 if (hasBranchProperty(name))
600 delete branchProperties_[name];
601 branchProperties_[name] = property.clone();
602 }
603
604 virtual Clonable* getBranchProperty(const std::string& name)
605 {
606 if (hasBranchProperty(name))
607 return branchProperties_[name];
608 else
609 throw PropertyNotFoundException("", name, this);
610 }
611
612 virtual const Clonable* getBranchProperty(const std::string& name) const
613 {
614 if (hasBranchProperty(name))
615 return const_cast<const Clonable*>(branchProperties_[name]);
616 else
617 throw PropertyNotFoundException("", name, this);
618 }
619
620 virtual Clonable* removeBranchProperty(const std::string& name)
621 {
622 if (hasBranchProperty(name))
623 {
624 Clonable* removed = branchProperties_[name];
625 branchProperties_.erase(name);
626 return removed;
627 }
628 else
629 throw PropertyNotFoundException("", name, this);
630 }
631
632 virtual void deleteBranchProperty(const std::string& name)
633 {
634 if (hasBranchProperty(name))
635 {
636 delete branchProperties_[name];
637 branchProperties_.erase(name);
638 }
639 else
640 throw PropertyNotFoundException("", name, this);
641 }
642
649 {
650 branchProperties_.clear();
651 }
652
657 {
658 for (std::map<std::string, Clonable*>::iterator i = branchProperties_.begin(); i != branchProperties_.end(); i++)
659 {
660 delete i->second;
661 }
662 branchProperties_.clear();
663 }
664
665 virtual bool hasBranchProperty(const std::string& name) const { return branchProperties_.find(name) != branchProperties_.end(); }
666
667 virtual std::vector<std::string> getBranchPropertyNames() const { return MapTools::getKeys(branchProperties_); }
668
669 virtual bool hasBootstrapValue() const;
670
671 virtual double getBootstrapValue() const;
673 // Equality operator:
674
675 virtual bool operator==(const Node& node) const { return id_ == node.id_; }
676
677 // Tests:
678
679 virtual bool isLeaf() const { return degree() <= 1; }
680
681 virtual bool hasNoSon() const { return getNumberOfSons() == 0; }
682};
683} // end of namespace bpp.
684#endif // BPP_PHYL_TREE_NODE_H
static std::vector< Key > getKeys(const std::map< Key, T, Cmp > &myMap)
Exception thrown when something is wrong with a particular node.
General exception thrown when something is wrong with a particular node.
The phylogenetic node class.
Definition: Node.h:59
Node(int id)
Build a new Node with specified id.
Definition: Node.h:86
virtual void deleteNodeProperties()
Delete all node properties.
Definition: Node.h:566
virtual void setSon(size_t pos, Node *node)
Definition: Node.h:409
virtual void deleteName()
Delete the name associated to this node (do nothing if there is no name).
Definition: Node.h:223
Node * clone() const
Definition: Node.h:141
Node * father_
Definition: Node.h:64
virtual std::string getName() const
Get the name associated to this node, if there is one, otherwise throw a NodeException.
Definition: Node.h:203
Node(const std::string &name)
Build a new Node with specified name.
Definition: Node.h:99
virtual Node * removeFather()
Remove the father of this node.
Definition: Node.h:336
virtual void setDistanceToFather(double distance)
Set or update the distance toward the father node.
Definition: Node.h:266
virtual void deleteDistanceToFather()
Delete the distance to the father node.
Definition: Node.h:276
virtual Node * removeSon(size_t pos)
Definition: Node.h:423
int id_
Definition: Node.h:61
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual bool hasBranchProperty(const std::string &name) const
Definition: Node.h:665
virtual void setId(int id)
Set this node's id.
Definition: Node.h:177
std::map< std::string, Clonable * > branchProperties_
Definition: Node.h:67
virtual Clonable * getNodeProperty(const std::string &name)
Definition: Node.h:514
virtual Node * getFather()
Get the father of this node is there is one.
Definition: Node.h:313
virtual Clonable * getBranchProperty(const std::string &name)
Definition: Node.h:604
virtual void addSon(size_t pos, Node *node)
Definition: Node.h:386
virtual std::vector< std::string > getNodePropertyNames() const
Definition: Node.h:577
Node(int id, const std::string &name)
Build a new Node with specified id and name.
Definition: Node.h:112
virtual const Node & son(size_t pos) const
Definition: Node.h:368
Node & operator=(const Node &node)
Assignation operator.
Definition: Node.cpp:42
virtual ~Node()
Definition: Node.h:144
virtual bool hasBootstrapValue() const
Definition: Node.cpp:165
virtual void setBranchProperty(const std::string &name, const Clonable &property)
Set/add a branch property.
Definition: Node.h:597
Node * operator[](int i)
Definition: Node.h:485
virtual bool hasDistanceToFather() const
Tell is this node has a distance to the father.
Definition: Node.h:288
Node()
Build a new void Node object.
Definition: Node.h:73
std::vector< Node * > sons_
Definition: Node.h:63
virtual void setNodeProperty(const std::string &name, const Clonable &property)
Set/add a node property.
Definition: Node.h:507
const Node * operator[](int i) const
Definition: Node.h:487
virtual void removeSons()
Definition: Node.h:449
virtual bool hasNoSon() const
Definition: Node.h:681
virtual std::vector< int > getSonsId() const
Definition: Node.h:179
virtual void removeSon(Node *node)
Definition: Node.h:433
virtual const Node * getFather() const
Get the father of this node is there is one.
Definition: Node.h:306
virtual const Node * getSon(size_t pos) const
Definition: Node.h:362
std::string * name_
Definition: Node.h:62
virtual bool isLeaf() const
Definition: Node.h:679
virtual std::vector< Node * > & getSons()
Definition: Node.h:357
virtual size_t getSonPosition(const Node *son) const
Definition: Node.cpp:153
virtual const Clonable * getBranchProperty(const std::string &name) const
Definition: Node.h:612
virtual Clonable * removeNodeProperty(const std::string &name)
Definition: Node.h:530
virtual void deleteNodeProperty(const std::string &name)
Definition: Node.h:542
void addSubTree(const PhyloTree &tree, std::shared_ptr< PhyloNode > phyloNode)
Definition: Node.cpp:72
virtual bool operator==(const Node &node) const
Definition: Node.h:675
virtual Node & son(size_t pos)
Definition: Node.h:380
std::vector< const Node * > getNeighbors() const
Definition: Node.cpp:129
virtual void swap(size_t branch1, size_t branch2)
Definition: Node.cpp:113
virtual void removeNodeProperties()
Remove all node properties.
Definition: Node.h:558
virtual void deleteBranchProperty(const std::string &name)
Definition: Node.h:632
virtual bool hasFather() const
Tell if this node has a father node.
Definition: Node.h:346
virtual void setName(const std::string &name)
Give a name or update the name associated to the node.
Definition: Node.h:214
virtual const Clonable * getNodeProperty(const std::string &name) const
Definition: Node.h:522
double * distanceToFather_
Definition: Node.h:65
virtual Node * getSon(size_t pos)
Definition: Node.h:374
virtual double getBootstrapValue() const
Definition: Node.cpp:170
virtual void deleteBranchProperties()
Delete all branch properties.
Definition: Node.h:656
virtual void addSon(Node *node)
Definition: Node.h:398
virtual bool hasName() const
Tell is this node has a name.
Definition: Node.h:234
virtual void setFather(Node *node)
Set the father node of this node.
Definition: Node.h:322
virtual bool hasNodeProperty(const std::string &name) const
Definition: Node.h:575
std::map< std::string, Clonable * > nodeProperties_
Definition: Node.h:66
virtual Clonable * removeBranchProperty(const std::string &name)
Definition: Node.h:620
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
virtual void removeBranchProperties()
Remove all branch properties.
Definition: Node.h:648
virtual int getFatherId() const
Definition: Node.h:315
virtual size_t getNumberOfSons() const
Definition: Node.h:355
virtual size_t degree() const
Definition: Node.h:475
virtual std::vector< std::string > getBranchPropertyNames() const
Definition: Node.h:667
General exception thrown if a property could not be found.
Defines the basic types of data flow nodes.