bpp-phyl  2.1.0
Bpp/Phyl/TreeTemplate.h
Go to the documentation of this file.
00001 //
00002 // File: TreeTemplate.h
00003 // Created by: Julien Dutheil
00004 //             Celine Scornavacca
00005 // Created on: Thu Mar 13 12:03:18 2003
00006 //
00007 
00008 /*
00009    Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
00010 
00011    This software is a computer program whose purpose is to provide classes
00012    for phylogenetic data analysis.
00013 
00014    This software is governed by the CeCILL  license under French law and
00015    abiding by the rules of distribution of free software.  You can  use,
00016    modify and/ or redistribute the software under the terms of the CeCILL
00017    license as circulated by CEA, CNRS and INRIA at the following URL
00018    "http://www.cecill.info".
00019 
00020    As a counterpart to the access to the source code and  rights to copy,
00021    modify and redistribute granted by the license, users are provided only
00022    with a limited warranty  and the software's author,  the holder of the
00023    economic rights,  and the successive licensors  have only  limited
00024    liability.
00025 
00026    In this respect, the user's attention is drawn to the risks associated
00027    with loading,  using,  modifying and/or developing or reproducing the
00028    software by the user in light of its specific status of free software,
00029    that may mean  that it is complicated to manipulate,  and  that  also
00030    therefore means  that it is reserved for developers  and  experienced
00031    professionals having in-depth computer knowledge. Users are therefore
00032    encouraged to load and test the software's suitability as regards their
00033    requirements in conditions enabling the security of their systems and/or
00034    data to be ensured and,  more generally, to use and operate it in the
00035    same conditions as regards security.
00036 
00037    The fact that you are presently reading this means that you have had
00038    knowledge of the CeCILL license and that you accept its terms.
00039  */
00040 
00041 #ifndef _TREETEMPLATE_H_
00042 #define _TREETEMPLATE_H_
00043 
00044 #include "TreeExceptions.h"
00045 #include "TreeTemplateTools.h"
00046 #include "Tree.h"
00047 
00048 // From the STL:
00049 #include <string>
00050 #include <vector>
00051 #include <map>
00052 
00053 namespace bpp
00054 {
00091 template<class N>
00092 class TreeTemplate :
00093   public Tree
00094 {
00099 private:
00100   N* root_;
00101   std::string name_;
00102 
00103 public:
00104   // Constructors and destructor:
00105   TreeTemplate() : root_(0),
00106     name_() {}
00107 
00108   TreeTemplate(const TreeTemplate<N>& t) :
00109     root_(0),
00110     name_(t.name_)
00111   {
00112     // Perform a hard copy of the nodes:
00113     root_ = TreeTemplateTools::cloneSubtree<N>(*t.getRootNode());
00114   }
00115 
00116   TreeTemplate(const Tree& t) :
00117     root_(0),
00118     name_(t.getName())
00119   {
00120     // Create new nodes from an existing tree:
00121     root_ = TreeTemplateTools::cloneSubtree<N>(t, t.getRootId());
00122   }
00123 
00124   TreeTemplate(N* root) : root_(root),
00125     name_()
00126   {
00127     root_->removeFather(); // In case this is a subtree from somewhere else...
00128   }
00129 
00130   TreeTemplate<N>& operator=(const TreeTemplate<N>& t)
00131   {
00132     // Perform a hard copy of the nodes:
00133     if (root_) { TreeTemplateTools::deleteSubtree(root_); delete root_; }
00134     root_ = TreeTemplateTools::cloneSubtree<N>(*t.getRootNode());
00135     name_ = t.name_;
00136     return *this;
00137   }
00138 
00139   TreeTemplate<N>* cloneSubtree(int newRootId) const
00140   {
00141     N* newRoot = TreeTemplateTools::cloneSubtree<N>(*this, newRootId);
00142     return new TreeTemplate<N>(newRoot);
00143   }
00144 
00145   virtual ~TreeTemplate()
00146   {
00147     TreeTemplateTools::deleteSubtree(root_);
00148     delete root_;
00149   }
00150 
00151   TreeTemplate<N>* clone() const { return new TreeTemplate<N>(*this); }
00152 
00157 public:
00158   std::string getName() const { return name_; }
00159 
00160   void setName(const std::string& name) { name_ = name; }
00161 
00162   int getRootId() const { return root_->getId(); }
00163 
00164   size_t getNumberOfLeaves() const { return TreeTemplateTools::getNumberOfLeaves(*root_); }
00165 
00166   size_t getNumberOfNodes() const { return TreeTemplateTools::getNumberOfNodes(*root_); }
00167 
00168   int getLeafId(const std::string& name) const throw (NodeNotFoundException) { return TreeTemplateTools::getLeafId(*root_, name); }
00169 
00170   std::vector<int> getLeavesId() const { return TreeTemplateTools::getLeavesId(*root_); }
00171 
00172   std::vector<int> getNodesId() const { return TreeTemplateTools::getNodesId(*root_); }
00173 
00174   std::vector<int> getInnerNodesId() const { return TreeTemplateTools::getInnerNodesId(*root_); }
00175 
00176   std::vector<int> getBranchesId() const { return TreeTemplateTools::getBranchesId(*root_); }
00177 
00178   std::vector<double> getBranchLengths() const { return TreeTemplateTools::getBranchLengths(*root_); }
00179 
00180   std::vector<std::string> getLeavesNames() const { return TreeTemplateTools::getLeavesNames(*const_cast<const N*>( root_)); }
00181 
00182   std::vector<int> getSonsId(int parentId) const throw (NodeNotFoundException)  { return getNode(parentId)->getSonsId(); }
00183 
00184   std::vector<int> getAncestorsId(int nodeId) const throw (NodeNotFoundException) { return TreeTemplateTools::getAncestorsId(*getNode(nodeId)); }
00185 
00186   int getFatherId(int parentId) const throw (NodeNotFoundException) { return getNode(parentId)->getFatherId(); }
00187 
00188   bool hasFather(int nodeId) const throw (NodeNotFoundException) { return getNode(nodeId)->hasFather(); }
00189 
00190   std::string getNodeName(int nodeId) const throw (NodeNotFoundException) { return getNode(nodeId)->getName(); }
00191 
00192   bool hasNodeName(int nodeId) const throw (NodeNotFoundException) { return getNode(nodeId)->hasName(); }
00193 
00194   void setNodeName(int nodeId, const std::string& name) throw (NodeNotFoundException) { getNode(nodeId)->setName(name); }
00195 
00196   void deleteNodeName(int nodeId) throw (NodeNotFoundException) { return getNode(nodeId)->deleteName(); }
00197 
00198   bool hasNode(int nodeId) const { return TreeTemplateTools::hasNodeWithId(*root_, nodeId); }
00199 
00200   bool isLeaf(int nodeId) const throw (NodeNotFoundException) { return getNode(nodeId)->isLeaf(); }
00201 
00202   bool isRoot(int nodeId) const throw (NodeNotFoundException) { return TreeTemplateTools::isRoot(*getNode(nodeId)); }
00203 
00204   double getDistanceToFather(int nodeId) const { return getNode(nodeId)->getDistanceToFather(); }
00205 
00206   void setDistanceToFather(int nodeId, double length) { getNode(nodeId)->setDistanceToFather(length); }
00207 
00208   void deleteDistanceToFather(int nodeId) { getNode(nodeId)->deleteDistanceToFather(); }
00209 
00210   bool hasDistanceToFather(int nodeId) const { return getNode(nodeId)->hasDistanceToFather(); }
00211 
00212   bool hasNodeProperty(int nodeId, const std::string& name) const throw (NodeNotFoundException) { return getNode(nodeId)->hasNodeProperty(name); }
00213 
00214   void setNodeProperty(int nodeId, const std::string& name, const Clonable& property) throw (NodeNotFoundException) { getNode(nodeId)->setNodeProperty(name, property); }
00215 
00216   Clonable* getNodeProperty(int nodeId, const std::string& name) throw (NodeNotFoundException) { return getNode(nodeId)->getNodeProperty(name); }
00217 
00218   const Clonable* getNodeProperty(int nodeId, const std::string& name) const throw (NodeNotFoundException) { return getNode(nodeId)->getNodeProperty(name); }
00219 
00220   Clonable* removeNodeProperty(int nodeId, const std::string& name) throw (NodeNotFoundException) { return getNode(nodeId)->removeNodeProperty(name); }
00221 
00222   std::vector<std::string> getNodePropertyNames(int nodeId) const throw (NodeNotFoundException) { return getNode(nodeId)->getNodePropertyNames(); }
00223 
00224   bool hasBranchProperty(int nodeId, const std::string& name) const throw (NodeNotFoundException) { return getNode(nodeId)->hasBranchProperty(name); }
00225 
00226   void setBranchProperty(int nodeId, const std::string& name, const Clonable& property) throw (NodeNotFoundException) { getNode(nodeId)->setBranchProperty(name, property); }
00227 
00228   Clonable* getBranchProperty(int nodeId, const std::string& name) throw (NodeNotFoundException) { return getNode(nodeId)->getBranchProperty(name); }
00229 
00230   const Clonable* getBranchProperty(int nodeId, const std::string& name) const throw (NodeNotFoundException) { return getNode(nodeId)->getBranchProperty(name); }
00231 
00232   Clonable* removeBranchProperty(int nodeId, const std::string& name) throw (NodeNotFoundException) { return getNode(nodeId)->removeBranchProperty(name); }
00233 
00234   std::vector<std::string> getBranchPropertyNames(int nodeId) const throw (NodeNotFoundException) { return getNode(nodeId)->getBranchPropertyNames(); }
00235 
00236   void rootAt(int nodeId) throw (NodeNotFoundException) { rootAt(getNode(nodeId)); }
00237 
00238   void newOutGroup(int nodeId) throw (NodeNotFoundException) {  newOutGroup(getNode(nodeId)); }
00239 
00240   bool isRooted() const { return root_->getNumberOfSons() == 2; }
00241 
00242   bool unroot() throw (UnrootedTreeException)
00243   {
00244     if (!isRooted()) throw UnrootedTreeException("Tree::unroot", this);
00245     else
00246     {
00247       N* son1 = root_->getSon(0);
00248       N* son2 = root_->getSon(1);
00249       if (son1->isLeaf() && son2->isLeaf()) return false;  // We can't unroot a single branch!
00250 
00251       // We manage to have a subtree in position 0:
00252       if (son1->isLeaf())
00253       {
00254         root_->swap(0, 1);
00255         son1 = root_->getSon(0);
00256         son2 = root_->getSon(1);
00257       }
00258 
00259       // Take care of branch lengths:
00260       if (son1->hasDistanceToFather())
00261       {
00262         if (son2->hasDistanceToFather())
00263         {
00264           // Both nodes have lengths, we sum them:
00265           son2->setDistanceToFather(son1->getDistanceToFather() + son2->getDistanceToFather());
00266         }
00267         else
00268         {
00269           // Only node 1 has length, we set it to node 2:
00270           son2->setDistanceToFather(son1->getDistanceToFather());
00271         }
00272         son1->deleteDistanceToFather();
00273       } // Else node 2 may or may not have a branch length, we do not care!
00274 
00275       // Remove the root:
00276       root_->removeSons();
00277       son1->addSon(son2);
00278       delete root_;
00279       setRootNode(son1);
00280       return true;
00281     }
00282   }
00283 
00284   void resetNodesId()
00285   {
00286     std::vector<N*> nodes = getNodes();
00287     for (size_t i = 0; i < nodes.size(); i++)
00288     {
00289       nodes[i]->setId(static_cast<int>(i));
00290     }
00291   }
00292 
00293   bool isMultifurcating() const
00294   {
00295     if (root_->getNumberOfSons() > 3) return true;
00296     for (size_t i = 0; i < root_->getNumberOfSons(); i++)
00297       if (TreeTemplateTools::isMultifurcating(*root_->getSon(i)))
00298         return true;
00299     return false;
00300   }
00301 
00315   template<class N2>
00316   bool hasSameTopologyAs(const TreeTemplate<N2>& tree, bool ordered = false) const
00317   {
00318     const TreeTemplate<N>* t1 = 0;
00319     const TreeTemplate<N2>* t2 = 0;
00320     if (ordered)
00321     {
00322       t1 = this;
00323       t2 = &tree;
00324     }
00325     else
00326     {
00327       TreeTemplate<N>* t1tmp = this->clone();
00328       TreeTemplate<N2>* t2tmp = tree.clone();
00329       TreeTemplateTools::orderTree(*t1tmp->getRootNode(), true, true);
00330       TreeTemplateTools::orderTree(*t2tmp->getRootNode(), true, true);
00331       t1 = t1tmp;
00332       t2 = t2tmp;
00333     }
00334     bool test = TreeTemplateTools::haveSameOrderedTopology(*t1->getRootNode(), *t2->getRootNode());
00335     if (!ordered)
00336     {
00337       delete t1;
00338       delete t2;
00339     }
00340     return test;
00341   }
00342 
00343   std::vector<double> getBranchLengths() throw (NodeException)
00344   {
00345     Vdouble brLen(1);
00346     for (size_t i = 0; i < root_->getNumberOfSons(); i++)
00347     {
00348       Vdouble sonBrLen = TreeTemplateTools::getBranchLengths(*root_->getSon(i));
00349       for (size_t j = 0; j < sonBrLen.size(); j++) { brLen.push_back(sonBrLen[j]); }
00350     }
00351     return brLen;
00352   }
00353 
00354   double getTotalLength() throw (NodeException)
00355   {
00356     return TreeTemplateTools::getTotalLength(*root_, false);
00357   }
00358 
00359   void setBranchLengths(double brLen)
00360   {
00361     for (size_t i = 0; i < root_->getNumberOfSons(); i++)
00362     {
00363       TreeTemplateTools::setBranchLengths(*root_->getSon(i), brLen);
00364     }
00365   }
00366 
00367   void setVoidBranchLengths(double brLen)
00368   {
00369     for (size_t i = 0; i < root_->getNumberOfSons(); i++)
00370     {
00371       TreeTemplateTools::setVoidBranchLengths(*root_->getSon(i), brLen);
00372     }
00373   }
00374 
00375   void scaleTree(double factor) throw (NodeException)
00376   {
00377     for (size_t i = 0; i < root_->getNumberOfSons(); i++)
00378     {
00379       TreeTemplateTools::scaleTree(*root_->getSon(i), factor);
00380     }
00381   }
00382 
00383   int getNextId()
00384   {
00385     return TreeTools::getMPNUId(*this, root_->getId());
00386   }
00387 
00388   void swapNodes(int parentId, size_t i1, size_t i2) throw (NodeNotFoundException, IndexOutOfBoundsException)
00389   {
00390     std::vector<N*> nodes = TreeTemplateTools::searchNodeWithId<N>(*root_, parentId);
00391     if (nodes.size() == 0) throw NodeNotFoundException("TreeTemplate:swapNodes(): Node with id not found.", "" + parentId);
00392     for (size_t i = 0; i < nodes.size(); i++) { nodes[i]->swap(i1, i2); }
00393   }
00394 
00395 
00401   virtual void setRootNode(N* root) { root_ = root; }
00402 
00403   virtual N* getRootNode() { return root_; }
00404 
00405   virtual const N* getRootNode() const { return root_; }
00406 
00407   virtual std::vector<const N*> getLeaves() const { return TreeTemplateTools::getLeaves(*const_cast<const N*>(root_)); }
00408 
00409   virtual std::vector<N*> getLeaves() { return TreeTemplateTools::getLeaves(*root_); }
00410 
00411   virtual std::vector<const N*> getNodes() const { return TreeTemplateTools::getNodes(*const_cast<const N*>(root_)); }
00412 
00413   virtual std::vector<N*> getNodes() { return TreeTemplateTools::getNodes(*root_); }
00414 
00415   virtual std::vector<const N*> getInnerNodes() const { return TreeTemplateTools::getInnerNodes(*const_cast<const N*>(root_)); }
00416 
00417   virtual std::vector<N*> getInnerNodes() { return TreeTemplateTools::getInnerNodes(*root_); }
00418 
00419   virtual N* getNode(int id, bool checkId = false) throw (NodeNotFoundException, Exception)
00420   {
00421     if (checkId) {
00422       std::vector<N*> nodes;
00423       TreeTemplateTools::searchNodeWithId<N>(*root_, id, nodes);
00424       if (nodes.size() > 1) throw Exception("TreeTemplate::getNode(): Non-unique id! (" + TextTools::toString(id) + ").");
00425       if (nodes.size() == 0) throw NodeNotFoundException("TreeTemplate::getNode(): Node with id not found.", TextTools::toString(id));
00426       return nodes[0];
00427     } else {
00428       N* node = dynamic_cast<N*>(TreeTemplateTools::searchFirstNodeWithId(*root_, id));
00429       if (node)
00430         return node;
00431       else
00432         throw NodeNotFoundException("TreeTemplate::getNode(): Node with id not found.", TextTools::toString(id));
00433     }
00434   }
00435 
00436   virtual const N* getNode(int id, bool checkId = false) const throw (NodeNotFoundException, Exception)
00437   {
00438     if (checkId) {
00439       std::vector<const N*> nodes;
00440       TreeTemplateTools::searchNodeWithId<const N>(*root_, id, nodes);
00441       if (nodes.size() > 1) throw Exception("TreeTemplate::getNode(): Non-unique id! (" + TextTools::toString(id) + ").");
00442       if (nodes.size() == 0) throw NodeNotFoundException("TreeTemplate::getNode(): Node with id not found.", TextTools::toString(id));
00443       return nodes[0];
00444     } else {
00445       const N* node = dynamic_cast<const N*>(TreeTemplateTools::searchFirstNodeWithId(*root_, id));
00446       if (node)
00447         return node;
00448       else
00449         throw NodeNotFoundException("TreeTemplate::getNode(): Node with id not found.", TextTools::toString(id));
00450     }
00451   }
00452 
00453   virtual N* getNode(const std::string& name) throw (NodeNotFoundException, Exception)
00454   {
00455     std::vector<N*> nodes;
00456     TreeTemplateTools::searchNodeWithName(*root_, name, nodes);
00457     if (nodes.size() > 1) throw NodeNotFoundException("TreeTemplate::getNode(): Non-unique name.", "" + name);
00458     if (nodes.size() == 0) throw NodeNotFoundException("TreeTemplate::getNode(): Node with name not found.", "" + name);
00459     return nodes[0];
00460   }
00461 
00462   virtual const N* getNode(const std::string& name) const throw (NodeNotFoundException, Exception)
00463   {
00464     std::vector<const N*> nodes;
00465     TreeTemplateTools::searchNodeWithName<const N>(*root_, name, nodes);
00466     if (nodes.size() > 1) throw NodeNotFoundException("TreeTemplate::getNode(): Non-unique name.", "" + name);
00467     if (nodes.size() == 0) throw NodeNotFoundException("TreeTemplate::getNode(): Node with name not found.", "" + name);
00468     return nodes[0];
00469   }
00470 
00471   void rootAt(N* newRoot)
00472   {
00473     if (root_ == newRoot) return;
00474     if (isRooted()) unroot();
00475     std::vector<Node*> path = TreeTemplateTools::getPathBetweenAnyTwoNodes(*root_, *newRoot);
00476 
00477     for (size_t i = 0; i < path.size() - 1; i++)
00478     {
00479       // pathMatrix[i] -> _father = pathMatrix[i + 1];
00480       // pathMatrix[i] -> setDistanceToFather(pathMatrix[i + 1] -> getDistanceToFather());
00481       // typename vector<Node *>::iterator vec_iter;
00482       // vec_iter = remove(pathMatrix[i] -> _sons.begin(), pathMatrix[i] -> _sons.end(), pathMatrix[i + 1]);
00483       // pathMatrix[i] -> _sons.erase(vec_iter, pathMatrix[i] -> _sons.end()); // pg 1170, primer.
00484       // pathMatrix[i+1] -> _sons.push_back(pathMatrix[i + 1] -> getFather());
00485       // pathMatrix[i+1] -> _father = 0;
00486       path[i]->removeSon(path[i + 1]);
00487       if (path[i + 1]->hasDistanceToFather()) path[i]->setDistanceToFather(path[i + 1]->getDistanceToFather());
00488       else path[i]->deleteDistanceToFather();
00489       path[i + 1]->addSon(path[i]);
00490 
00491       std::vector<std::string> names = path[i + 1]->getBranchPropertyNames();
00492       for (size_t j = 0; j < names.size(); j++)
00493       {
00494         path[i]->setBranchProperty(names[j], *path[i + 1]->getBranchProperty(names[j]));
00495       }
00496       path[i + 1]->deleteBranchProperties();
00497     }
00498     newRoot->deleteDistanceToFather();
00499     newRoot->deleteBranchProperties();
00500     root_ = newRoot;
00501   }
00502 
00503   void newOutGroup(N* outGroup)
00504   {
00505     if (root_ == outGroup) return;
00506     int rootId;
00507     if (isRooted())
00508     {
00509       for (size_t i = 0; i < root_->getNumberOfSons(); i++)
00510       {
00511         if (root_->getSon(i) == outGroup) return;  // This tree is already rooted appropriately.
00512       }
00513       rootId = getRootId();
00514       unroot();
00515     }
00516     else
00517     {
00518       rootId = getNextId();
00519     }
00520     rootAt(outGroup->getFather());
00521     N* oldRoot = root_;
00522     oldRoot->removeSon(outGroup);
00523     root_ = new N();
00524     root_->setId(rootId);
00525     root_->addSon(oldRoot);
00526     root_->addSon(outGroup);
00527     // Check lengths:
00528     if (outGroup->hasDistanceToFather())
00529     {
00530       double l = outGroup->getDistanceToFather() / 2.;
00531       outGroup->setDistanceToFather(l);
00532       oldRoot->setDistanceToFather(l);
00533     }
00534   }
00535 
00537 };
00538 } // end of namespace bpp.
00539 
00540 #endif  // _TREETEMPLATE_H_
00541 
 All Classes Namespaces Files Functions Variables Typedefs Friends