|
bpp-phyl
2.1.0
|
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