2
// File: AbstractNonHomogeneousTreeLikelihood.cpp
3
// Created by: Julien Dutheil
4
// Created on: Tue Oct 09 16:07 2007
5
// From file: AbstractHomogeneousTreeLikelihood.cpp
9
Copyright or Ā© or Copr. CNRS, (November 16, 2004)
11
This software is a computer program whose purpose is to provide classes
12
for phylogenetic data analysis.
14
This software is governed by the CeCILL license under French law and
15
abiding by the rules of distribution of free software. You can use,
16
modify and/ or redistribute the software under the terms of the CeCILL
17
license as circulated by CEA, CNRS and INRIA at the following URL
18
"http://www.cecill.info".
20
As a counterpart to the access to the source code and rights to copy,
21
modify and redistribute granted by the license, users are provided only
22
with a limited warranty and the software's author, the holder of the
23
economic rights, and the successive licensors have only limited
26
In this respect, the user's attention is drawn to the risks associated
27
with loading, using, modifying and/or developing or reproducing the
28
software by the user in light of its specific status of free software,
29
that may mean that it is complicated to manipulate, and that also
30
encouraged to load and test the software's suitability as regards their
31
requirements in conditions enabling the security of their systems and/or
32
data to be ensured and, more generally, to use and operate it in the
33
same conditions as regards security.
35
The fact that you are presently reading this means that you have had
36
knowledge of the CeCILL license and that you accept its terms.
39
#include "AbstractNonHomogeneousTreeLikelihood.h"
40
#include "../PatternTools.h"
43
#include <Bpp/Seq/SiteTools.h>
44
#include <Bpp/Seq/Container/SequenceContainerTools.h>
46
#include <Bpp/Text/TextTools.h>
47
#include <Bpp/App/ApplicationTools.h>
56
/******************************************************************************/
58
AbstractNonHomogeneousTreeLikelihood::AbstractNonHomogeneousTreeLikelihood(
60
SubstitutionModelSet* modelSet,
61
DiscreteDistribution* rDist,
64
AbstractDiscreteRatesAcrossSitesTreeLikelihood(rDist, verbose),
84
init_(tree, modelSet, rDist, verbose);
87
/******************************************************************************/
89
AbstractNonHomogeneousTreeLikelihood::AbstractNonHomogeneousTreeLikelihood(
90
const AbstractNonHomogeneousTreeLikelihood& lik) :
91
AbstractDiscreteRatesAcrossSitesTreeLikelihood(lik),
92
modelSet_(lik.modelSet_),
93
brLenParameters_(lik.brLenParameters_),
97
rootFreqs_(lik.rootFreqs_),
100
nbSites_(lik.nbSites_),
101
nbDistinctSites_(lik.nbDistinctSites_),
102
nbClasses_(lik.nbClasses_),
103
nbStates_(lik.nbStates_),
104
nbNodes_(lik.nbNodes_),
105
verbose_(lik.verbose_),
106
minimumBrLen_(lik.minimumBrLen_),
107
brLenConstraint_(dynamic_cast<Constraint*>(lik.brLenConstraint_->clone())),
111
nodes_ = tree_->getNodes();
112
nodes_.pop_back(); //Remove the root node (the last added!).
113
//Rebuild nodes index:
114
for (unsigned int i = 0; i < nodes_.size(); i++)
116
const Node* node = nodes_[i];
117
idToNode_[node->getId()] = node;
121
/******************************************************************************/
123
AbstractNonHomogeneousTreeLikelihood& AbstractNonHomogeneousTreeLikelihood::operator=(
124
const AbstractNonHomogeneousTreeLikelihood& lik)
126
AbstractDiscreteRatesAcrossSitesTreeLikelihood::operator=(lik);
127
modelSet_ = lik.modelSet_;
128
brLenParameters_ = lik.brLenParameters_;
132
rootFreqs_ = lik.rootFreqs_;
133
nodes_ = tree_->getNodes();
134
nodes_.pop_back(); //Remove the root node (the last added!).
135
nbSites_ = lik.nbSites_;
136
nbDistinctSites_ = lik.nbDistinctSites_;
137
nbClasses_ = lik.nbClasses_;
138
nbStates_ = lik.nbStates_;
139
nbNodes_ = lik.nbNodes_;
140
verbose_ = lik.verbose_;
141
minimumBrLen_ = lik.minimumBrLen_;
142
brLenConstraint_.reset(dynamic_cast<Constraint*>(lik.brLenConstraint_->clone()));
145
//Rebuild nodes index:
146
for( unsigned int i = 0; i < nodes_.size(); i++)
148
const Node * node = nodes_[i];
149
idToNode_[node->getId()] = node;
154
/******************************************************************************/
156
void AbstractNonHomogeneousTreeLikelihood::init_(
158
SubstitutionModelSet* modelSet,
159
DiscreteDistribution* rDist,
160
bool verbose) throw (Exception)
162
TreeTools::checkIds(tree, true);
163
tree_ = new TreeTemplate<Node>(tree);
164
root1_ = tree_->getRootNode()->getSon(0)->getId();
165
root2_ = tree_->getRootNode()->getSon(1)->getId();
166
nodes_ = tree_->getNodes();
167
nodes_.pop_back(); //Remove the root node (the last added!).
168
nbNodes_ = nodes_.size();
170
for (unsigned int i = 0; i < nodes_.size(); i++)
172
const Node * node = nodes_[i];
173
idToNode_[node->getId()] = node;
175
nbClasses_ = rateDistribution_->getNumberOfCategories();
179
minimumBrLen_ = 0.000001;
180
brLenConstraint_.reset(new IncludingPositiveReal(minimumBrLen_));
181
setSubstitutionModelSet(modelSet);
184
/******************************************************************************/
186
void AbstractNonHomogeneousTreeLikelihood::setSubstitutionModelSet(SubstitutionModelSet* modelSet) throw (Exception)
191
if (modelSet->getAlphabet()->getAlphabetType() != data_->getAlphabet()->getAlphabetType())
192
throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::setSubstitutionModelSet(). Model alphabet do not match existing data.");
195
modelSet_ = modelSet;
199
if (modelSet->getNumberOfStates() != modelSet_->getNumberOfStates())
200
setData(*data_); //Have to reinitialize the whole data structure.
203
nbStates_ = modelSet->getNumberOfStates();
205
//Allocate transition probabilities arrays:
206
for (unsigned int l = 0; l < nbNodes_; l++)
208
//For each son node,i
209
Node* son = nodes_[l];
211
VVVdouble* pxy__son = & pxy_[son->getId()];
212
pxy__son->resize(nbClasses_);
213
for (unsigned int c = 0; c < nbClasses_; c++)
215
VVdouble * pxy__son_c = & (* pxy__son)[c];
216
pxy__son_c->resize(nbStates_);
217
for(unsigned int x = 0; x < nbStates_; x++)
219
(*pxy__son_c)[x].resize(nbStates_);
223
VVVdouble* dpxy__son = & dpxy_[son->getId()];
224
dpxy__son->resize(nbClasses_);
225
for (unsigned int c = 0; c < nbClasses_; c++)
227
VVdouble * dpxy__son_c = & (* dpxy__son)[c];
228
dpxy__son_c->resize(nbStates_);
229
for(unsigned int x = 0; x < nbStates_; x++)
231
(* dpxy__son_c)[x].resize(nbStates_);
235
VVVdouble* d2pxy__son = & d2pxy_[son->getId()];
236
d2pxy__son->resize(nbClasses_);
237
for (unsigned int c = 0; c < nbClasses_; c++)
239
VVdouble * d2pxy__son_c = & (* d2pxy__son)[c];
240
d2pxy__son_c->resize(nbStates_);
241
for(unsigned int x = 0; x < nbStates_; x++)
243
(* d2pxy__son_c)[x].resize(nbStates_);
248
//We have to reset parameters. If the instance is not initialized, this will be done by the initialize method.
252
computeAllTransitionProbabilities();
253
fireParameterChanged(getParameters());
257
/******************************************************************************/
259
void AbstractNonHomogeneousTreeLikelihood::initialize() throw (Exception)
261
if (initialized_) throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::initialize(). Object is already initialized.");
262
if (!data_) throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::initialize(). Data are no set.");
265
computeAllTransitionProbabilities();
266
fireParameterChanged(getParameters());
269
/******************************************************************************/
271
ParameterList AbstractNonHomogeneousTreeLikelihood::getBranchLengthsParameters() const
273
if(!initialized_) throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::getBranchLengthsParameters(). Object is not initialized.");
274
return brLenParameters_.getCommonParametersWith(getParameters());
277
/******************************************************************************/
279
ParameterList AbstractNonHomogeneousTreeLikelihood::getSubstitutionModelParameters() const
281
if(!initialized_) throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::getSubstitutionModelParameters(). Object is not initialized.");
282
return modelSet_->getParameters().getCommonParametersWith(getParameters());
285
/******************************************************************************/
287
void AbstractNonHomogeneousTreeLikelihood::initParameters()
293
initBranchLengthsParameters();
294
addParameters_(brLenParameters_);
296
// Substitution model:
297
addParameters_(modelSet_->getIndependentParameters());
299
// Rate distribution:
300
addParameters_(rateDistribution_->getIndependentParameters());
303
/******************************************************************************/
305
void AbstractNonHomogeneousTreeLikelihood::applyParameters() throw (Exception)
307
if(!initialized_) throw Exception("AbstractBranchNonHomogeneousTreeLikelihood::applyParameters(). Object not initialized.");
308
//Apply branch lengths:
309
for(unsigned int i = 0; i < nbNodes_; i++)
311
int id = nodes_[i]->getId();
314
const Parameter * rootBrLen = &getParameter("BrLenRoot");
315
const Parameter * rootPos = &getParameter("RootPosition");
316
nodes_[i]->setDistanceToFather(rootBrLen->getValue() * rootPos->getValue());
318
else if(id == root2_)
320
const Parameter * rootBrLen = &getParameter("BrLenRoot");
321
const Parameter * rootPos = &getParameter("RootPosition");
322
nodes_[i]->setDistanceToFather(rootBrLen->getValue() * (1. - rootPos->getValue()));
326
const Parameter * brLen = &getParameter(string("BrLen") + TextTools::toString(i));
327
if(brLen != NULL) nodes_[i]->setDistanceToFather(brLen->getValue());
330
//Apply substitution model parameters:
331
modelSet_->matchParametersValues(getParameters());
332
//Apply rate distribution parameters:
333
rateDistribution_->matchParametersValues(getParameters());
336
/******************************************************************************/
338
void AbstractNonHomogeneousTreeLikelihood::initBranchLengthsParameters()
340
brLenParameters_.reset();
341
double l1 = 0, l2 = 0;
342
for (unsigned int i = 0; i < nbNodes_; i++)
344
double d = minimumBrLen_;
345
if (!nodes_[i]->hasDistanceToFather())
347
ApplicationTools::displayWarning("Missing branch length " + TextTools::toString(i) + ". Value is set to " + TextTools::toString(minimumBrLen_));
348
nodes_[i]->setDistanceToFather(minimumBrLen_);
352
d = nodes_[i]->getDistanceToFather();
353
if (d < minimumBrLen_)
355
ApplicationTools::displayWarning("Branch length " + TextTools::toString(i) + " is too small: " + TextTools::toString(d) + ". Value is set to " + TextTools::toString(minimumBrLen_));
356
nodes_[i]->setDistanceToFather(minimumBrLen_);
360
if (nodes_[i]->getId() == root1_)
362
else if(nodes_[i]->getId() == root2_)
366
brLenParameters_.addParameter(Parameter("BrLen" + TextTools::toString(i), d, brLenConstraint_->clone(), true)); //Attach constraint to avoid clonage problems!
369
brLenParameters_.addParameter(Parameter("BrLenRoot", l1 + l2, brLenConstraint_->clone(), true));
370
brLenParameters_.addParameter(Parameter("RootPosition", l1 / (l1 + l2), &Parameter::PROP_CONSTRAINT_EX));
373
/*******************************************************************************/
375
void AbstractNonHomogeneousTreeLikelihood::computeAllTransitionProbabilities()
377
for(unsigned int l = 0; l < nbNodes_; l++)
380
Node * node = nodes_[l];
381
computeTransitionProbabilitiesForNode(node);
383
rootFreqs_ = modelSet_->getRootFrequencies();
386
/*******************************************************************************/
388
void AbstractNonHomogeneousTreeLikelihood::computeTransitionProbabilitiesForNode(const Node* node)
390
const SubstitutionModel* model = modelSet_->getModelForNode(node->getId());
391
double l = node->getDistanceToFather();
393
//Computes all pxy and pyx once for all:
394
VVVdouble * pxy__node = & pxy_[node->getId()];
395
for(unsigned int c = 0; c < nbClasses_; c++)
397
VVdouble * pxy__node_c = & (* pxy__node)[c];
398
RowMatrix<double> Q = model->getPij_t(l * rateDistribution_->getCategory(c));
399
for(unsigned int x = 0; x < nbStates_; x++)
401
Vdouble * pxy__node_c_x = & (* pxy__node_c)[x];
402
for(unsigned int y = 0; y < nbStates_; y++)
404
(* pxy__node_c_x)[y] = Q(x, y);
409
if(computeFirstOrderDerivatives_)
411
//Computes all dpxy/dt once for all:
412
VVVdouble * dpxy__node = & dpxy_[node->getId()];
414
for(unsigned int c = 0; c < nbClasses_; c++)
416
VVdouble * dpxy__node_c = & (* dpxy__node)[c];
417
double rc = rateDistribution_->getCategory(c);
419
RowMatrix<double> dQ = model->getdPij_dt(l * rc);
421
for(unsigned int x = 0; x < nbStates_; x++)
423
Vdouble * dpxy__node_c_x = & (* dpxy__node_c)[x];
424
for(unsigned int y = 0; y < nbStates_; y++)
425
(* dpxy__node_c_x)[y] = rc * dQ(x, y);
430
if(computeSecondOrderDerivatives_)
432
//Computes all d2pxy/dt2 once for all:
433
VVVdouble * d2pxy__node = & d2pxy_[node->getId()];
434
for(unsigned int c = 0; c < nbClasses_; c++)
436
VVdouble * d2pxy__node_c = & (* d2pxy__node)[c];
437
double rc = rateDistribution_->getCategory(c);
438
RowMatrix<double> d2Q = model->getd2Pij_dt2(l * rc);
439
for(unsigned int x = 0; x < nbStates_; x++)
441
Vdouble * d2pxy__node_c_x = & (* d2pxy__node_c)[x];
442
for(unsigned int y = 0; y < nbStates_; y++)
444
(* d2pxy__node_c_x)[y] = rc * rc * d2Q(x, y);
451
/*******************************************************************************/