bpp-phyl3  3.0.0
PhyloTree.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "../Likelihood/ParametrizablePhyloTree.h"
6 #include "PhyloTree.h"
7 
8 using namespace bpp;
9 using namespace std;
10 
11 PhyloTree::PhyloTree(bool rooted) :
13  name_("")
14 {}
15 
18  name_(tree ? tree->name_ : "")
19 {}
20 
23  name_("")
24 {}
25 
27 {
28  std::vector<shared_ptr<PhyloNode>> nodes = getAllNodes();
29  for (unsigned int i = 0; i < nodes.size(); i++)
30  {
31  setNodeIndex(nodes[i], i);
32 
33  if (hasFather(nodes[i]))
34  setEdgeIndex(getEdgeToFather(nodes[i]), i);
35  }
36 }
37 
38 std::shared_ptr<PhyloNode> PhyloTree::getPhyloNode(const std::string& name) const
39 {
40  vector<shared_ptr<PhyloNode>> vpn = getAllNodes();
41 
42  for (auto it:vpn)
43  {
44  if (it->hasName() && it->getName() == name)
45  return it;
46  }
47 
48  return std::make_shared<PhyloNode>();
49 }
50 
51 std::vector<std::string> PhyloTree::getAllLeavesNames() const
52 {
53  vector<string> vn;
54 
55  vector<shared_ptr<PhyloNode>> vpn = getAllLeaves();
56 
57  for (vector<shared_ptr<PhyloNode>>::const_iterator it = vpn.begin(); it != vpn.end(); it++)
58  {
59  vn.push_back((*it)->getName());
60  }
61 
62  return vn;
63 }
64 
65 void PhyloTree::scaleTree(std::shared_ptr<PhyloNode> node, double factor)
66 {
67  vector<shared_ptr<PhyloBranch>> branches = getSubtreeEdges(node);
68  for (vector<shared_ptr<PhyloBranch>>::iterator currBranch = branches.begin(); currBranch != branches.end(); currBranch++)
69  {
70  if ((*currBranch)->hasLength())
71  (*currBranch)->setLength((*currBranch)->getLength() * factor);
72  else
73  throw PhyloBranchPException("PhyloTree::scaleTree : undefined length", (*currBranch).get());
74  }
75 }
76 
77 void PhyloTree::scaleTree(double factor)
78 {
79  scaleTree(getRoot(), factor);
80 }
81 
82 void PhyloTree::pruneTree(std::vector<string> leaves)
83 {
84  vector<shared_ptr<PhyloNode>> vpn = getAllLeaves();
85 
86  for (auto& leaf:vpn)
87  {
88  if (std::find(leaves.begin(), leaves.end(), leaf->getName()) == leaves.end())
89  {
90  while (leaf && isLeaf(leaf)) // to get rid of internal nodes as leaves
91  {
92  auto fat = getFatherOfNode(leaf);
93  deleteNode(leaf);
94  leaf = fat;
95  }
96  }
97  }
98 }
99 
101 {
102  vector<shared_ptr<PhyloBranch>> vpn = getAllEdges();
103 
104  for (auto& it: vpn)
105  {
106  it->setLength(l);
107  }
108 }
109 
111 {
112  Vdouble vl;
113 
114  vector<shared_ptr<PhyloBranch>> vpn = getAllEdges();
115 
116  for (auto& it: vpn)
117  {
118  vl.push_back(it->getLength());
119  }
120  return vl;
121 }
122 
123 
125 {
126  vector<shared_ptr<PhyloBranch>> vpn = getAllEdges();
127 
128  for (auto& it: vpn)
129  {
130  uint ei = getEdgeIndex(it);
131 
132  if (!phylotree.hasEdge(ei))
133  throw Exception("Phylotree::operator+= : argument tree does not have edge " + TextTools::toString(ei));
134  if (!it->hasLength() || !phylotree.getEdge(ei)->hasLength())
135  throw Exception("Phylotree::operator+= : no summing of branches without length.");
136 
137  it->setLength(it->getLength() + phylotree.getEdge(ei)->getLength());
138  }
139 
140  return *this;
141 }
142 
144 {
145  vector<shared_ptr<PhyloBranch>> vpn = getAllEdges();
146 
147  for (auto& it: vpn)
148  {
149  uint ei = getEdgeIndex(it);
150 
151  if (!phylotree.hasEdge(ei))
152  throw Exception("Phylotree::operator+= : argument tree does not have edge " + TextTools::toString(ei));
153  if (!it->hasLength() || !phylotree.getEdge(ei)->hasLength())
154  throw Exception("Phylotree::operator+= : no summing of branches without length.");
155 
156  it->setLength(it->getLength() - phylotree.getEdge(ei)->getLength());
157  }
158 
159  return *this;
160 }
161 
163 {
164  vector<shared_ptr<PhyloBranch>> vpn = getAllEdges();
165 
166  for (auto& it: vpn)
167  {
168  uint ei = getEdgeIndex(it);
169 
170  if (!phylotree.hasEdge(ei))
171  throw Exception("Phylotree::operator/= : argument tree does not have edge " + TextTools::toString(ei));
172  if (!it->hasLength() || !phylotree.getEdge(ei)->hasLength())
173  throw Exception("Phylotree::operator/= : no summing of branches without length.");
174 
175  it->setLength(it->getLength() / phylotree.getEdge(ei)->getLength());
176  }
177 
178  return *this;
179 }
180 
182 {
183  vector<shared_ptr<PhyloBranch>> vpn = getAllEdges();
184 
185  for (auto& it: vpn)
186  {
187  uint ei = getEdgeIndex(it);
188 
189  if (!phylotree.hasEdge(ei))
190  throw Exception("Phylotree::operator/= : argument tree does not have edge " + TextTools::toString(ei));
191  if (!it->hasLength() || !phylotree.getEdge(ei)->hasLength())
192  throw Exception("Phylotree::operator/= : no summing of branches without length.");
193 
194  it->setLength(it->getLength() * phylotree.getEdge(ei)->getLength());
195  }
196 
197  return *this;
198 }
199 
200 void PhyloTree::addSubTree(std::shared_ptr<PhyloNode> phyloNode, const Node& node)
201 {
202  for (int i = 0; i < static_cast<int>(node.getNumberOfSons()); i++)
203  {
204  const Node& fils = *node[i];
205 
206  // the son
207  auto soni = std::make_shared<PhyloNode>(fils.hasName() ? fils.getName() : "");
208  setNodeIndex(soni, (uint)fils.getId());
209 
210  auto propi = fils.getNodePropertyNames();
211  for (const auto& prop:propi)
212  {
213  soni->setProperty(prop, *fils.getNodeProperty(prop));
214  }
215 
216  auto branchi = std::make_shared<PhyloBranch> ();
217  if (fils.hasDistanceToFather())
218  branchi->setLength(fils.getDistanceToFather());
219  setEdgeIndex(branchi, (uint)fils.getId());
220 
221  // the branch to the son
222  propi = fils.getBranchPropertyNames();
223  for (const auto& prop:propi)
224  {
225  branchi->setProperty(prop, *fils.getBranchProperty(prop));
226  }
227 
228  // the link
229  createNode(phyloNode, soni, branchi);
230 
231  // recursion
232  addSubTree(soni, fils);
233  }
234 }
bool isLeaf(const Nref node) const
virtual std::vector< std::shared_ptr< N > > getAllLeaves() const=0
virtual std::vector< std::shared_ptr< E > > getAllEdges() const=0
virtual NodeIndex setNodeIndex(const std::shared_ptr< N > nodeObject, NodeIndex index)=0
virtual void deleteNode(std::shared_ptr< N > nodeObject)=0
virtual std::shared_ptr< N > getRoot() const=0
virtual EdgeIndex getEdgeIndex(const std::shared_ptr< E > edgeObject) const=0
virtual std::vector< std::shared_ptr< N > > getAllNodes() const=0
virtual EdgeIndex setEdgeIndex(const std::shared_ptr< E > edgeObject, EdgeIndex index)=0
virtual std::shared_ptr< E > getEdge(EdgeIndex edgeIndex) const=0
virtual bool hasEdge(EdgeIndex edgeIndex) const=0
virtual void createNode(std::shared_ptr< N > newNodeObject)=0
bool hasFather(const std::shared_ptr< N > nodeObject) const
std::shared_ptr< E > getEdgeToFather(const std::shared_ptr< N > nodeObject) const
std::shared_ptr< N > getFatherOfNode(const std::shared_ptr< N > nodeObject) const
std::vector< std::shared_ptr< E > > getSubtreeEdges(const std::shared_ptr< N > localRoot) const
The phylogenetic node class.
Definition: Node.h:59
virtual std::string getName() const
Get the name associated to this node, if there is one, otherwise throw a NodeException.
Definition: Node.h:203
virtual Clonable * getNodeProperty(const std::string &name)
Definition: Node.h:502
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual bool hasDistanceToFather() const
Tell is this node has a distance to the father.
Definition: Node.h:288
virtual Clonable * getBranchProperty(const std::string &name)
Definition: Node.h:592
virtual std::vector< std::string > getBranchPropertyNames() const
Definition: Node.h:655
virtual bool hasName() const
Tell is this node has a name.
Definition: Node.h:234
virtual std::vector< std::string > getNodePropertyNames() const
Definition: Node.h:565
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
virtual size_t getNumberOfSons() const
Definition: Node.h:355
PhyloTree with Parametrizable Phylo Branches. They SHARE their branch length parameters.
General exception thrown when something is wrong with a particular branch.
PhyloTree & operator*=(const PhyloTree &phylotree)
Multiplies the lengths of branches of this phylotree by the ones of another phylotree....
Definition: PhyloTree.cpp:181
void scaleTree(double factor)
Multiply all branch lengths by a given factor.
Definition: PhyloTree.cpp:77
void addSubTree(std::shared_ptr< PhyloNode > phyloNode, const Node &node)
Concatenate the subtree under a Node (in a TreeTemplate<Node>) to this PhyloTree, under the given phy...
Definition: PhyloTree.cpp:200
Vdouble getBranchLengths() const
Definition: PhyloTree.cpp:110
PhyloTree(bool rooted=false)
Definition: PhyloTree.cpp:11
void resetNodesId()
Definition: PhyloTree.cpp:26
std::vector< std::string > getAllLeavesNames() const
Definition: PhyloTree.cpp:51
std::shared_ptr< PhyloNode > getPhyloNode(const std::string &name) const
Definition: PhyloTree.cpp:38
PhyloTree & operator+=(const PhyloTree &phylotree)
Add the lengths of branches of another phylotree to this one. Just branch ids are considered,...
Definition: PhyloTree.cpp:124
PhyloTree & operator-=(const PhyloTree &phylotree)
Subtracts the lengths of branches of another phylotree to this one. Just branch ids are considered,...
Definition: PhyloTree.cpp:143
void pruneTree(std::vector< std::string > leaves)
Prune a tree to a given set of leaf names.
Definition: PhyloTree.cpp:82
void setBranchLengths(double l)
Definition: PhyloTree.cpp:100
PhyloTree & operator/=(const PhyloTree &phylotree)
Divides the lengths of branches of this phylotree by the ones of another phylotree....
Definition: PhyloTree.cpp:162
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble