bpp-phyl3  3.0.0
AbstractHomogeneousTreeLikelihood.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
6 #include <Bpp/Text/TextTools.h>
7 
8 #include "../../PatternTools.h"
10 
11 // From bpp-seq:
12 #include <Bpp/Seq/SiteTools.h>
14 
15 using namespace bpp;
16 
17 // From the STL:
18 #include <iostream>
19 
20 using namespace std;
21 
22 /******************************************************************************/
23 
25  const Tree& tree,
26  std::shared_ptr<TransitionModelInterface> model,
27  std::shared_ptr<DiscreteDistributionInterface> rDist,
28  bool checkRooted,
29  bool verbose) :
31  model_(0),
32  brLenParameters_(),
33  pxy_(),
34  dpxy_(),
35  d2pxy_(),
36  rootFreqs_(),
37  nodes_(),
38  nbSites_(),
39  nbDistinctSites_(),
40  nbClasses_(),
41  nbStates_(),
42  nbNodes_(),
43  verbose_(),
44  minimumBrLen_(),
45  maximumBrLen_(),
46  brLenConstraint_()
47 {
48  init_(tree, model, rDist, checkRooted, verbose);
49 }
50 
51 /******************************************************************************/
52 
56  model_(lik.model_),
57  brLenParameters_(lik.brLenParameters_),
58  pxy_(lik.pxy_),
59  dpxy_(lik.dpxy_),
60  d2pxy_(lik.d2pxy_),
61  rootFreqs_(lik.rootFreqs_),
62  nodes_(),
63  nbSites_(lik.nbSites_),
64  nbDistinctSites_(lik.nbDistinctSites_),
65  nbClasses_(lik.nbClasses_),
66  nbStates_(lik.nbStates_),
67  nbNodes_(lik.nbNodes_),
68  verbose_(lik.verbose_),
69  minimumBrLen_(lik.minimumBrLen_),
70  maximumBrLen_(lik.maximumBrLen_),
71  brLenConstraint_(lik.brLenConstraint_->clone())
72 {
73  nodes_ = tree_->getNodes();
74  nodes_.pop_back(); // Remove the root node (the last added!).
75 }
76 
77 /******************************************************************************/
78 
81 {
83  model_ = lik.model_;
85  pxy_ = lik.pxy_;
86  dpxy_ = lik.dpxy_;
87  d2pxy_ = lik.d2pxy_;
88  rootFreqs_ = lik.rootFreqs_;
89  nodes_ = tree_->getNodes();
90  nodes_.pop_back(); // Remove the root node (the last added!).
91  nbSites_ = lik.nbSites_;
93  nbClasses_ = lik.nbClasses_;
94  nbStates_ = lik.nbStates_;
95  nbNodes_ = lik.nbNodes_;
96  verbose_ = lik.verbose_;
99  brLenConstraint_ = std::shared_ptr<ConstraintInterface>(lik.brLenConstraint_->clone());
100  return *this;
101 }
102 
103 /******************************************************************************/
104 
106  const Tree& tree,
107  std::shared_ptr<TransitionModelInterface> model,
108  std::shared_ptr<DiscreteDistributionInterface> rDist,
109  bool checkRooted,
110  bool verbose)
111 {
112  TreeTools::checkIds(tree, true);
113  tree_ = make_unique<TreeTemplate<Node>>(tree);
114  if (checkRooted && tree_->isRooted())
115  {
116  if (verbose)
117  ApplicationTools::displayWarning("Tree has been unrooted.");
118  tree_->unroot();
119  }
120  nodes_ = tree_->getNodes();
121  nodes_.pop_back(); // Remove the root node (the last added!).
122  nbNodes_ = nodes_.size();
123  nbClasses_ = rateDistribution_->getNumberOfCategories();
124  setModel(model);
125 
126  verbose_ = verbose;
127 
128  minimumBrLen_ = 0.000001;
129  maximumBrLen_ = 10000;
130  brLenConstraint_ = std::make_shared<IntervalConstraint>(minimumBrLen_, maximumBrLen_, true, true);
131 }
132 
133 /******************************************************************************/
134 
135 void AbstractHomogeneousTreeLikelihood::setModel(std::shared_ptr<TransitionModelInterface> model)
136 {
137  // Check:
138  if (data_)
139  {
140  if (model->getAlphabet()->getAlphabetType() != data_->getAlphabet()->getAlphabetType())
141  throw Exception("AbstractHomogeneousTreeLikelihood::setSubstitutionModel(). Model alphabet do not match existing data.");
142  }
143 
144  model_ = model;
145 
146  if (data_)
147  {
148  if (model->getNumberOfStates() != model_->getNumberOfStates())
149  setData(*data_); // Have to reinitialize the whole data structure.
150  }
151 
152  nbStates_ = model->getNumberOfStates();
153 
154  // Allocate transition probabilities arrays:
155  for (unsigned int l = 0; l < nbNodes_; l++)
156  {
157  // For each son node,i
158  Node* son = nodes_[l];
159 
160  VVVdouble* pxy__son = &pxy_[son->getId()];
161  pxy__son->resize(nbClasses_);
162  for (unsigned int c = 0; c < nbClasses_; c++)
163  {
164  VVdouble* pxy__son_c = &(*pxy__son)[c];
165  pxy__son_c->resize(nbStates_);
166  for (unsigned int x = 0; x < nbStates_; x++)
167  {
168  (*pxy__son_c)[x].resize(nbStates_);
169  }
170  }
171 
172  VVVdouble* dpxy__son = &dpxy_[son->getId()];
173  dpxy__son->resize(nbClasses_);
174  for (unsigned int c = 0; c < nbClasses_; c++)
175  {
176  VVdouble* dpxy__son_c = &(*dpxy__son)[c];
177  dpxy__son_c->resize(nbStates_);
178  for (unsigned int x = 0; x < nbStates_; x++)
179  {
180  (*dpxy__son_c)[x].resize(nbStates_);
181  }
182  }
183 
184  VVVdouble* d2pxy__son = &d2pxy_[son->getId()];
185  d2pxy__son->resize(nbClasses_);
186  for (unsigned int c = 0; c < nbClasses_; c++)
187  {
188  VVdouble* d2pxy__son_c = &(*d2pxy__son)[c];
189  d2pxy__son_c->resize(nbStates_);
190  for (unsigned int x = 0; x < nbStates_; x++)
191  {
192  (*d2pxy__son_c)[x].resize(nbStates_);
193  }
194  }
195  }
196 }
197 
198 /******************************************************************************/
199 
201 {
202  if (initialized_)
203  throw Exception("AbstractHomogeneousTreeLikelihood::initialize(). Object is already initialized.");
204  if (!data_)
205  throw Exception("AbstractHomogeneousTreeLikelihood::initialize(). Data are no set.");
206  initParameters();
207  initialized_ = true;
209 }
210 
211 /******************************************************************************/
212 
214 {
215  if (!initialized_)
216  throw Exception("AbstractHomogeneousTreeLikelihood::getBranchLengthsParameters(). Object is not initialized.");
218 }
219 
220 /******************************************************************************/
221 
223 {
224  if (!initialized_)
225  throw Exception("AbstractHomogeneousTreeLikelihood::getSubstitutionModelParameters(). Object is not initialized.");
226  return model_->getParameters().getCommonParametersWith(getParameters());
227 }
228 
229 /******************************************************************************/
230 
232 {
233  // Reset parameters:
235 
236  // Branch lengths:
239 
240  // Substitution model:
241  addParameters_(model_->getIndependentParameters());
242 
243  // Rate distribution:
244  addParameters_(rateDistribution_->getIndependentParameters());
245 }
246 
247 /******************************************************************************/
248 
250 {
251  if (!initialized_)
252  throw Exception("AbstractHomogeneousTreeLikelihood::applyParameters(). Object not initialized.");
253  // Apply branch lengths:
254  // brLenParameters_.matchParametersValues(parameters_); Not necessary!
255  for (unsigned int i = 0; i < nbNodes_; i++)
256  {
257  const Parameter* brLen = &parameter(string("BrLen") + TextTools::toString(i));
258  if (brLen)
259  nodes_[i]->setDistanceToFather(brLen->getValue());
260  }
261  // Apply substitution model parameters:
262  model_->matchParametersValues(getParameters());
263  rootFreqs_ = model_->getFrequencies();
264  // Apply rate distribution parameters:
265  rateDistribution_->matchParametersValues(getParameters());
266 }
267 
268 /******************************************************************************/
269 
271 {
273  for (unsigned int i = 0; i < nbNodes_; i++)
274  {
275  double d = minimumBrLen_;
276  if (!nodes_[i]->hasDistanceToFather())
277  {
278  if (verbose)
279  ApplicationTools::displayWarning("Missing branch length " + TextTools::toString(i) + ". Value is set to " + TextTools::toString(minimumBrLen_));
280  nodes_[i]->setDistanceToFather(minimumBrLen_);
281  }
282  else
283  {
284  d = nodes_[i]->getDistanceToFather();
285  if (d < minimumBrLen_)
286  {
287  if (verbose)
288  ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too small: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(minimumBrLen_));
289  nodes_[i]->setDistanceToFather(minimumBrLen_);
290  d = minimumBrLen_;
291  }
292  if (d > maximumBrLen_)
293  {
294  if (verbose)
295  ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too big: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(maximumBrLen_));
296  nodes_[i]->setDistanceToFather(maximumBrLen_);
297  d = maximumBrLen_;
298  }
299  }
301  }
302 }
303 
304 /*******************************************************************************/
305 
307 {
308  for (unsigned int l = 0; l < nbNodes_; l++)
309  {
310  // For each node,
311  Node* node = nodes_[l];
313  }
314  rootFreqs_ = model_->getFrequencies();
315 }
316 
317 /*******************************************************************************/
318 
320 {
321  double l = node->getDistanceToFather();
322 
323  // Computes all pxy and pyx once for all:
324  VVVdouble* pxy__node = &pxy_[node->getId()];
325  for (unsigned int c = 0; c < nbClasses_; c++)
326  {
327  VVdouble* pxy__node_c = &(*pxy__node)[c];
328  RowMatrix<double> Q = model_->getPij_t(l * rateDistribution_->getCategory(c));
329 
330  for (unsigned int x = 0; x < nbStates_; x++)
331  {
332  Vdouble* pxy__node_c_x = &(*pxy__node_c)[x];
333  for (unsigned int y = 0; y < nbStates_; y++)
334  {
335  (*pxy__node_c_x)[y] = Q(x, y);
336  }
337  }
338  }
339 
341  {
342  // Computes all dpxy/dt once for all:
343  VVVdouble* dpxy__node = &dpxy_[node->getId()];
344  for (unsigned int c = 0; c < nbClasses_; c++)
345  {
346  VVdouble* dpxy__node_c = &(*dpxy__node)[c];
347  double rc = rateDistribution_->getCategory(c);
348  RowMatrix<double> dQ = model_->getdPij_dt(l * rc);
349  for (unsigned int x = 0; x < nbStates_; x++)
350  {
351  Vdouble* dpxy__node_c_x = &(*dpxy__node_c)[x];
352  for (unsigned int y = 0; y < nbStates_; y++)
353  {
354  (*dpxy__node_c_x)[y] = rc * dQ(x, y);
355  }
356  }
357  }
358  }
359 
361  {
362  // Computes all d2pxy/dt2 once for all:
363  VVVdouble* d2pxy__node = &d2pxy_[node->getId()];
364  for (unsigned int c = 0; c < nbClasses_; c++)
365  {
366  VVdouble* d2pxy__node_c = &(*d2pxy__node)[c];
367  double rc = rateDistribution_->getCategory(c);
368  RowMatrix<double> d2Q = model_->getd2Pij_dt2(l * rc);
369  for (unsigned int x = 0; x < nbStates_; x++)
370  {
371  Vdouble* d2pxy__node_c_x = &(*d2pxy__node_c)[x];
372  for (unsigned int y = 0; y < nbStates_; y++)
373  {
374  (*d2pxy__node_c_x)[y] = rc * rc * d2Q(x, y);
375  }
376  }
377  }
378  }
379 }
380 
381 /*******************************************************************************/
Partial implementation of the DiscreteRatesAcrossSitesTreeLikelihood interface.
AbstractDiscreteRatesAcrossSitesTreeLikelihood & operator=(const AbstractDiscreteRatesAcrossSitesTreeLikelihood &tl)
Partial implementation for homogeneous model of the TreeLikelihood interface.
virtual void initParameters()
This builds the parameters list from all parametrizable objects, i.e. substitution model,...
std::vector< Node * > nodes_
Pointer toward all nodes in the tree.
void setModel(std::shared_ptr< TransitionModelInterface > model)
virtual void applyParameters()
All parameters are stored in a parameter list. This function apply these parameters to the substituti...
std::shared_ptr< TransitionModelInterface > model_
ParameterList getBranchLengthsParameters() const
Get the branch lengths parameters.
virtual void computeTransitionProbabilitiesForNode(const Node *node)
Fill the pxy_, dpxy_ and d2pxy_ arrays for one node.
std::shared_ptr< ConstraintInterface > brLenConstraint_
void init_(const Tree &tree, std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< DiscreteDistributionInterface > rDist, bool checkRooted, bool verbose)
Method called by constructor.
ParameterList getSubstitutionModelParameters() const
Get the parameters associated to substitution model(s).
AbstractHomogeneousTreeLikelihood(const Tree &tree, std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< DiscreteDistributionInterface > rDist, bool checkRooted=true, bool verbose=true)
virtual void computeAllTransitionProbabilities()
Fill the pxy_, dpxy_ and d2pxy_ arrays for all nodes.
AbstractHomogeneousTreeLikelihood & operator=(const AbstractHomogeneousTreeLikelihood &lik)
Assignation operator.
const Parameter & parameter(const std::string &name) const override
virtual void fireParameterChanged(const ParameterList &parameters)
virtual void addParameters_(const ParameterList &parameters)
const ParameterList & getParameters() const override
const Tree & tree() const
Get the tree (topology and branch lengths).
std::unique_ptr< const AlignmentDataInterface > data_
std::shared_ptr< TreeTemplate< Node > > tree_
static void displayWarning(const std::string &text)
The phylogenetic node class.
Definition: Node.h:59
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
virtual ParameterList getCommonParametersWith(const ParameterList &params) const
virtual void addParameter(const Parameter &param)
virtual void reset()
virtual double getValue() const
virtual void setData(const AlignmentDataInterface &sites)=0
Set the dataset for which the likelihood must be evaluated.
static bool checkIds(const Tree &tree, bool throwException)
Check if the ids are uniques.
Definition: TreeTools.cpp:747
Interface for phylogenetic tree objects.
Definition: Tree.h:115
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble
std::vector< VVdouble > VVVdouble
std::vector< Vdouble > VVdouble