bpp-phyl  2.1.0
 All Classes Namespaces Files Functions Variables Friends Pages
Node.h
Go to the documentation of this file.
1 //
2 // File: Node.h
3 // Created by: Julien Dutheil
4 // Created on: Thu Mar 13 12:03:18 2003
5 //
6 
7 /*
8  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
9 
10  This software is a computer program whose purpose is to provide classes
11  for phylogenetic data analysis.
12 
13  This software is governed by the CeCILL license under French law and
14  abiding by the rules of distribution of free software. You can use,
15  modify and/ or redistribute the software under the terms of the CeCILL
16  license as circulated by CEA, CNRS and INRIA at the following URL
17  "http://www.cecill.info".
18 
19  As a counterpart to the access to the source code and rights to copy,
20  modify and redistribute granted by the license, users are provided only
21  with a limited warranty and the software's author, the holder of the
22  economic rights, and the successive licensors have only limited
23  liability.
24 
25  In this respect, the user's attention is drawn to the risks associated
26  with loading, using, modifying and/or developing or reproducing the
27  software by the user in light of its specific status of free software,
28  that may mean that it is complicated to manipulate, and that also
29  therefore means that it is reserved for developers and experienced
30  professionals having in-depth computer knowledge. Users are therefore
31  encouraged to load and test the software's suitability as regards their
32  requirements in conditions enabling the security of their systems and/or
33  data to be ensured and, more generally, to use and operate it in the
34  same conditions as regards security.
35 
36  The fact that you are presently reading this means that you have had
37  knowledge of the CeCILL license and that you accept its terms.
38  */
39 
40 #ifndef _NODE_H_
41 #define _NODE_H_
42 
43 #include "TreeExceptions.h"
44 
45 #include <Bpp/Clonable.h>
46 #include <Bpp/Utils/MapTools.h>
47 #include <Bpp/BppString.h>
48 #include <Bpp/Numeric/Number.h>
49 
50 // From the STL:
51 #include <string>
52 #include <vector>
53 #include <map>
54 #include <iostream>
55 #include <algorithm>
56 
57 namespace bpp
58 {
89 class Node
90 {
91 
92 protected:
93  int id_;
94  std::string* name_;
95  std::vector<Node*> sons_;
98  mutable std::map<std::string, Clonable*> nodeProperties_;
99  mutable std::map<std::string, Clonable*> branchProperties_;
100 
101 public:
105  Node() :
106  id_(0),
107  name_(0),
108  sons_(),
109  father_(0),
111  nodeProperties_(),
113  {}
114 
118  Node(int id) :
119  id_(id),
120  name_(0),
121  sons_(),
122  father_(0),
124  nodeProperties_(),
126  {}
127 
131  Node(const std::string& name) :
132  id_(0),
133  name_(new std::string(name)),
134  sons_(),
135  father_(0),
137  nodeProperties_(),
139  {}
140 
144  Node(int id, const std::string& name) :
145  id_(id),
146  name_(new std::string(name)),
147  sons_(),
148  father_(0),
150  nodeProperties_(),
152  {}
153 
161  Node(const Node& node);
162 
171  Node& operator=(const Node& node);
172 
173  Node* clone() const { return new Node(*this); }
174 
175 public:
176  virtual ~Node()
177  {
178  if (name_) delete name_;
180  for (std::map<std::string, Clonable*>::iterator i = nodeProperties_.begin(); i != nodeProperties_.end(); i++)
181  {
182  delete i->second;
183  }
184  for (std::map<std::string, Clonable*>::iterator i = branchProperties_.begin(); i != branchProperties_.end(); i++)
185  {
186  delete i->second;
187  }
188  }
189 
190 public:
202  virtual int getId() const { return id_; }
203 
209  virtual void setId(int id) { id_ = id; }
210 
211  virtual std::vector<int> getSonsId() const
212  {
213  std::vector<int> sonsId(sons_.size());
214  for (size_t i = 0; i < sons_.size(); i++)
215  {
216  sonsId[i] = sons_[i]->getId();
217  }
218  return sonsId;
219  }
220 
235  virtual std::string getName() const throw (NodePException)
236  {
237  if (!hasName()) throw NodePException("Node::getName: no name associated to this node.", this);
238  return *name_;
239  }
240 
246  virtual void setName(const std::string& name)
247  {
248  if (name_) delete name_;
249  name_ = new std::string(name);
250  }
251 
255  virtual void deleteName()
256  {
257  if (name_) delete name_;
258  name_ = 0;
259  }
260 
266  virtual bool hasName() const { return name_ != 0; }
267 
282  virtual double getDistanceToFather() const
283  {
284  if (!hasDistanceToFather())
285  throw NodePException("Node::getDistanceToFather: Node has no distance.", this);
286  return *distanceToFather_;
287  }
288 
298  virtual void setDistanceToFather(double distance)
299  {
300  if (distanceToFather_)
301  delete distanceToFather_;
302  distanceToFather_ = new double(distance);
303  }
304 
308  virtual void deleteDistanceToFather()
309  {
310  if (distanceToFather_)
311  delete distanceToFather_;
312  distanceToFather_ = 0;
313  }
314 
320  virtual bool hasDistanceToFather() const
321  {
322  return distanceToFather_ != 0;
323  }
324 
338  virtual const Node* getFather() const { return father_; }
339 
345  virtual Node* getFather() { return father_; }
346 
347  virtual int getFatherId() const { return father_->getId(); }
348 
354  virtual void setFather(Node* node) throw (NullPointerException)
355  {
356  if (!node)
357  throw NullPointerException("Node::setFather(). Empty node given as input.");
358  father_ = node;
359  if (find(node->sons_.begin(), node->sons_.end(), this) == node->sons_.end())
360  node->sons_.push_back(this);
361  else // Otherwise node is already present.
362  std::cerr << "DEVEL warning: Node::setFather. Son node already registered! No pb here, but could be a bug in your implementation..." << std::endl;
363  }
364 
368  virtual Node* removeFather()
369  {
370  Node* f = father_;
371  father_ = 0;
372  return f;
373  }
374 
378  virtual bool hasFather() const { return father_ != 0; }
379 
387  virtual size_t getNumberOfSons() const { return sons_.size(); }
388 
389  virtual std::vector<Node*>& getSons()
390  {
391  return sons_;
392  }
393 
394  virtual const Node* getSon(size_t pos) const throw (IndexOutOfBoundsException)
395  {
396  if (pos >= sons_.size()) throw IndexOutOfBoundsException("Node::getSon().", pos, 0, sons_.size() - 1);
397  return sons_[pos];
398  }
399 
400  virtual Node* getSon(size_t pos) throw (IndexOutOfBoundsException)
401  {
402  if (pos >= sons_.size()) throw IndexOutOfBoundsException("Node::getSon().", pos, 0, sons_.size() - 1);
403  return sons_[pos];
404  }
405 
406  virtual void addSon(size_t pos, Node* node) throw (NullPointerException, NodePException)
407  {
408  if (!node)
409  throw NullPointerException("Node::addSon(). Empty node given as input.");
410  if (find(sons_.begin(), sons_.end(), node) == sons_.end())
411  sons_.insert(sons_.begin() + pos, node);
412  else // Otherwise node is already present.
413  std::cerr << "DEVEL warning: Node::addSon. Son node already registered! No pb here, but could be a bug in your implementation..." << std::endl;
414 
415  node->father_ = this;
416  }
417 
418  virtual void addSon(Node* node) throw (NullPointerException, NodePException)
419  {
420  if (!node)
421  throw NullPointerException("Node::addSon(). Empty node given as input.");
422  if (find(sons_.begin(), sons_.end(), node) == sons_.end())
423  sons_.push_back(node);
424  else // Otherwise node is already present.
425  throw NodePException("Node::addSon. Trying to add a node which is already present.");
426  node->father_ = this;
427  }
428 
429  virtual void setSon(size_t pos, Node* node) throw (IndexOutOfBoundsException, NullPointerException, NodePException)
430  {
431  if (!node)
432  throw NullPointerException("Node::setSon(). Empty node given as input.");
433  if (pos >= sons_.size())
434  throw IndexOutOfBoundsException("Node::setSon(). Invalid node position.", pos, 0, sons_.size() - 1);
435  std::vector<Node*>::iterator search = find(sons_.begin(), sons_.end(), node);
436  if (search == sons_.end() || search == sons_.begin() + pos)
437  sons_[pos] = node;
438  else
439  throw NodePException("Node::setSon. Trying to set a node which is already present.");
440  node->father_ = this;
441  }
442 
443  virtual Node* removeSon(size_t pos) throw (IndexOutOfBoundsException)
444  {
445  if (pos >= sons_.size())
446  throw IndexOutOfBoundsException("Node::removeSon(). Invalid node position.", pos, 0, sons_.size() - 1);
447  Node* node = sons_[pos];
448  sons_.erase(sons_.begin() + pos);
449  node->removeFather();
450  return node;
451  }
452 
454  {
455  if (!node)
456  throw NullPointerException("Node::removeSon(). Empty node given as input.");
457  for (size_t i = 0; i < sons_.size(); i++)
458  {
459  if (sons_[i] == node)
460  {
461  sons_.erase(sons_.begin() + i);
462  node->removeFather();
463  return;
464  }
465  }
466  throw NodeNotFoundException("Node::removeSon.", node->getId());
467  }
468 
469  virtual void removeSons()
470  {
471  while (sons_.size() != 0)
472  removeSon(static_cast<size_t>(0));
473  }
474 
475  virtual void swap(size_t branch1, size_t branch2) throw (IndexOutOfBoundsException);
476 
477  virtual size_t getSonPosition(const Node* son) const throw (NodeNotFoundException, NullPointerException);
478 
481  // These functions must not be declared as virtual!!
482 
483  std::vector<const Node*> getNeighbors() const;
484 
485  std::vector<Node*> getNeighbors();
486 
487  virtual size_t degree() const { return getNumberOfSons() + (hasFather() ? 1 : 0); }
488 
497  Node* operator[](int i) { return (i < 0) ? father_ : sons_[i]; }
498 
499  const Node* operator[](int i) const { return (i < 0) ? father_ : sons_[i]; }
500 
519  virtual void setNodeProperty(const std::string& name, const Clonable& property)
520  {
521  if (hasNodeProperty(name))
522  delete nodeProperties_[name];
523  nodeProperties_[name] = property.clone();
524  }
525 
526  virtual Clonable* getNodeProperty(const std::string& name) throw (PropertyNotFoundException)
527  {
528  if (hasNodeProperty(name))
529  return nodeProperties_[name];
530  else
531  throw PropertyNotFoundException("", name, this);
532  }
533 
534  virtual const Clonable* getNodeProperty(const std::string& name) const throw (PropertyNotFoundException)
535  {
536  if (hasNodeProperty(name))
537  return const_cast<const Clonable*>(nodeProperties_[name]);
538  else
539  throw PropertyNotFoundException("", name, this);
540  }
541 
542  virtual Clonable* removeNodeProperty(const std::string& name) throw (PropertyNotFoundException)
543  {
544  if (hasNodeProperty(name))
545  {
546  Clonable* removed = nodeProperties_[name];
547  nodeProperties_.erase(name);
548  return removed;
549  }
550  else
551  throw PropertyNotFoundException("", name, this);
552  }
553 
554  virtual void deleteNodeProperty(const std::string& name) throw (PropertyNotFoundException)
555  {
556  if (hasNodeProperty(name))
557  {
558  delete nodeProperties_[name];
559  nodeProperties_.erase(name);
560  }
561  else
562  throw PropertyNotFoundException("", name, this);
563  }
564 
570  virtual void removeNodeProperties()
571  {
572  nodeProperties_.clear();
573  }
574 
578  virtual void deleteNodeProperties()
579  {
580  for (std::map<std::string, Clonable*>::iterator i = nodeProperties_.begin(); i != nodeProperties_.end(); i++)
581  {
582  delete i->second;
583  }
584  nodeProperties_.clear();
585  }
586 
587  virtual bool hasNodeProperty(const std::string& name) const { return nodeProperties_.find(name) != nodeProperties_.end(); }
588 
589  virtual std::vector<std::string> getNodePropertyNames() const { return MapTools::getKeys(nodeProperties_); }
590 
609  virtual void setBranchProperty(const std::string& name, const Clonable& property)
610  {
611  if (hasBranchProperty(name))
612  delete branchProperties_[name];
613  branchProperties_[name] = property.clone();
614  }
615 
616  virtual Clonable* getBranchProperty(const std::string& name) throw (PropertyNotFoundException)
617  {
618  if (hasBranchProperty(name))
619  return branchProperties_[name];
620  else
621  throw PropertyNotFoundException("", name, this);
622  }
623 
624  virtual const Clonable* getBranchProperty(const std::string& name) const throw (PropertyNotFoundException)
625  {
626  if (hasBranchProperty(name))
627  return const_cast<const Clonable*>(branchProperties_[name]);
628  else
629  throw PropertyNotFoundException("", name, this);
630  }
631 
632  virtual Clonable* removeBranchProperty(const std::string& name) throw (PropertyNotFoundException)
633  {
634  if (hasBranchProperty(name))
635  {
636  Clonable* removed = branchProperties_[name];
637  branchProperties_.erase(name);
638  return removed;
639  }
640  else
641  throw PropertyNotFoundException("", name, this);
642  }
643 
644  virtual void deleteBranchProperty(const std::string& name) throw (PropertyNotFoundException)
645  {
646  if (hasBranchProperty(name))
647  {
648  delete branchProperties_[name];
649  branchProperties_.erase(name);
650  }
651  else
652  throw PropertyNotFoundException("", name, this);
653  }
654 
660  virtual void removeBranchProperties()
661  {
662  branchProperties_.clear();
663  }
664 
668  virtual void deleteBranchProperties()
669  {
670  for (std::map<std::string, Clonable*>::iterator i = branchProperties_.begin(); i != branchProperties_.end(); i++)
671  {
672  delete i->second;
673  }
674  branchProperties_.clear();
675  }
676 
677  virtual bool hasBranchProperty(const std::string& name) const { return branchProperties_.find(name) != branchProperties_.end(); }
678 
679  virtual std::vector<std::string> getBranchPropertyNames() const { return MapTools::getKeys(branchProperties_); }
680 
681  virtual bool hasBootstrapValue() const;
682 
683  virtual double getBootstrapValue() const throw (PropertyNotFoundException);
685  // Equality operator:
686 
687  virtual bool operator==(const Node& node) const { return id_ == node.id_; }
688 
689  // Tests:
690 
691  virtual bool isLeaf() const { return degree() <= 1; }
692 
693 };
694 } // end of namespace bpp.
695 
696 #endif // _NODE_H_
697