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
8using namespace bpp;
9using namespace std;
10
11PhyloTree::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
38std::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
51std::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
65void 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
77void PhyloTree::scaleTree(double factor)
78{
79 scaleTree(getRoot(), factor);
80}
81
82void 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
200void 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 int getId() const
Get the node's id.
Definition: Node.h:170
virtual Clonable * getNodeProperty(const std::string &name)
Definition: Node.h:514
virtual Clonable * getBranchProperty(const std::string &name)
Definition: Node.h:604
virtual std::vector< std::string > getNodePropertyNames() const
Definition: Node.h:577
virtual bool hasDistanceToFather() const
Tell is this node has a distance to the father.
Definition: Node.h:288
virtual bool hasName() const
Tell is this node has a name.
Definition: Node.h:234
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
virtual std::vector< std::string > getBranchPropertyNames() const
Definition: Node.h:667
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