bpp-phyl3 3.0.0
NonHomogeneousSubstitutionProcess.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
5#ifndef BPP_PHYL_LIKELIHOOD_NONHOMOGENEOUSSUBSTITUTIONPROCESS_H
6#define BPP_PHYL_LIKELIHOOD_NONHOMOGENEOUSSUBSTITUTIONPROCESS_H
7
8
9#include "../Model/FrequencySet/FrequencySet.h"
11
12// From bpp-core:
13#include <Bpp/Exceptions.h>
16
17// From the STL:
18#include <vector>
19#include <map>
20// #include <algorithm>
21#include <memory>
22#include <numeric>
23
24namespace bpp
25{
80{
81private:
86 std::vector<std::shared_ptr<BranchModelInterface>> modelSet_;
87
91 std::shared_ptr<DiscreteDistributionInterface> rDist_;
92
96 mutable std::map<unsigned int, size_t> nodeToModel_;
97 mutable std::map<size_t, std::vector<unsigned int>> modelToNodes_;
98
102 std::vector<ParameterList> modelParameters_;
103
104public:
114 std::shared_ptr<DiscreteDistributionInterface> rdist,
115 std::shared_ptr<const PhyloTree> tree = 0,
116 std::shared_ptr<FrequencySetInterface> rootFreqs = 0) :
119 modelSet_(),
120 rDist_(rdist),
121 nodeToModel_(),
124 {
125 if (rDist_)
126 addParameters_(rDist_->getIndependentParameters());
127 }
128
138 std::shared_ptr<DiscreteDistributionInterface> rdist,
139 std::shared_ptr<ParametrizablePhyloTree> tree,
140 std::shared_ptr<FrequencySetInterface> rootFreqs = 0) :
143 modelSet_(),
144 rDist_(rdist),
145 nodeToModel_(),
148 {
149 if (rDist_)
150 addParameters_(rDist_->getIndependentParameters());
151 }
152
154
156
158 {
159 clear();
160 }
161
163
169 void clear();
170
178 void fireParameterChanged(const ParameterList& parameters) override;
179
180 const StateMapInterface& stateMap() const override
181 {
182 if (modelSet_.size() == 0)
183 throw Exception("NonHomogeneousSubstitutionProcess::getStateMap : no model associated");
184 else
185 return modelSet_[0]->stateMap();
186 }
187
188 std::shared_ptr<const StateMapInterface> getStateMap() const override
189 {
190 if (modelSet_.size() == 0)
191 throw Exception("NonHomogeneousSubstitutionProcess::getStateMap : no model associated");
192 else
193 return modelSet_[0]->getStateMap();
194 }
195
199 size_t getNumberOfModels() const override { return modelSet_.size(); }
200
205 bool hasMixedTransitionModel() const;
206
213 void setModelScenario(std::shared_ptr<ModelScenario> modelscenario) override;
214
215 std::vector<size_t> getModelNumbers() const override
216 {
217 std::vector<size_t> v(getNumberOfModels());
218 std::iota(std::begin(v), std::end(v), 1);
219 return v;
220 }
221
222 const BranchModelInterface& model(size_t n) const override
223 {
224 if ((n == 0) || (n > modelSet_.size())) throw IndexOutOfBoundsException("NonHomogeneousSubstitutionProcess::model().", 1, modelSet_.size(), n);
225 return *modelSet_[n - 1];
226 }
227
228 std::shared_ptr<const BranchModelInterface> getModel(size_t n) const override
229 {
230 if ((n == 0) || (n > modelSet_.size())) throw IndexOutOfBoundsException("NonHomogeneousSubstitutionProcess::getModel().", 1, modelSet_.size(), n);
231 return modelSet_[n - 1];
232 }
233
234 std::shared_ptr<const BranchModelInterface> getModel(size_t n)
235 {
236 if ((n == 0) || (n > modelSet_.size())) throw IndexOutOfBoundsException("NonHomogeneousSubstitutionProcess::getModel().", 1, modelSet_.size(), n);
237 return modelSet_[n - 1];
238 }
239
248 size_t getModelNumberForNode(unsigned int nodeId) const override
249 {
250 const auto i = nodeToModel_.find(nodeId);
251 if (i == nodeToModel_.end())
252 throw Exception("NonHomogeneousSubstitutionProcess::getModelNumberForNode(). No model associated to node with id " + TextTools::toString(nodeId));
253 return i->second + 1;
254 }
255
263 std::shared_ptr<const BranchModelInterface> getModelForNode(unsigned int nodeId) const override
264 {
265 std::map<unsigned int, size_t>::const_iterator i = nodeToModel_.find(nodeId);
266 if (i == nodeToModel_.end())
267 throw Exception("NonHomogeneousSubstitutionProcess::getModelForNode(). No model associated to node with id " + TextTools::toString(nodeId));
268 return modelSet_[i->second];
269 }
270
278 const std::vector<unsigned int> getNodesWithModel(size_t i) const override
279 {
280 if (i > modelSet_.size()) throw IndexOutOfBoundsException("NonHomogeneousSubstitutionProcess::getNodesWithModel().", i, 0, modelSet_.size());
281 return modelToNodes_[i - 1];
282 }
283
299 void addModel(std::shared_ptr<BranchModelInterface> model, const std::vector<unsigned int>& nodesId);
300
311 void setModel(std::shared_ptr<BranchModelInterface> model, size_t modelIndex);
312
322 void setModelToNode(size_t modelIndex, unsigned int nodeNumber);
323
327 void listModelNames(std::ostream& out = std::cout) const;
328
329 ParameterList getBranchLengthParameters(bool independent) const override
330 {
332 return getParametrizablePhyloTree()->getParameters();
333 else
334 return ParameterList();
335 }
336
340 ParameterList getRateDistributionParameters(bool independent) const override
341 {
342 return rDist_.get() ? (independent ? rDist_->getIndependentParameters() : rDist_->getParameters()) : ParameterList();
343 }
344
346 {
347 if (!rDist_)
348 throw NullPointerException("NonHomogeneousSubstitutionProcess::rateDistribution. No associated rate distribution.");
349 return *rDist_;
350 }
351
353 {
354 if (!rDist_)
355 throw NullPointerException("NonHomogeneousSubstitutionProcess::rateDistribution. No associated rate distribution.");
356 return *rDist_;
357 }
358
359 std::shared_ptr<const DiscreteDistributionInterface> getRateDistribution() const override
360 {
361 return rDist_ ? rDist_ : nullptr;
362 }
363
364 std::shared_ptr<DiscreteDistributionInterface> getRateDistribution() override
365 {
366 return rDist_ ? rDist_ : nullptr;
367 }
368
372 ParameterList getSubstitutionModelParameters(bool independent) const override;
373
384 bool isFullySetUp(bool throwEx = true) const
385 {
386 return checkOrphanNodes(throwEx)
387 && checkUnknownNodes(throwEx);
388 }
389
390protected:
396 bool checkOrphanNodes(bool throwEx) const;
397
398 bool checkUnknownNodes(bool throwEx) const;
399
400public:
404 const std::vector<double>& getRootFrequencies() const override
405 {
406 if (!hasRootFrequencySet())
407 {
408 if (std::dynamic_pointer_cast<const TransitionModelInterface>(modelSet_[0]))
409 return std::dynamic_pointer_cast<const TransitionModelInterface>(modelSet_[0])->getFrequencies();
410 else
411 throw Exception("NonHomogeneousSubstitutionProcess::getRootFrequencies not callable.");
412 }
413 else
415 }
416
417 const BranchModelInterface& model(unsigned int nodeId, size_t classIndex) const override
418 {
419 return *modelSet_[nodeToModel_[nodeId]];
420 }
421
422 std::shared_ptr<const BranchModelInterface> getModel(unsigned int nodeId, size_t classIndex) const override
423 {
424 return modelSet_[nodeToModel_[nodeId]];
425 }
426
427 double getProbabilityForModel(size_t classIndex) const override
428 {
429 if (classIndex >= (rDist_ ? rDist_->getNumberOfCategories() : 1))
430 throw IndexOutOfBoundsException("NonHomogeneousSubstitutionProcess::getProbabilityForModel.", classIndex, 0, rDist_->getNumberOfCategories());
431 return rDist_ ? rDist_->getProbability(classIndex) : 1.;
432 }
433
435 {
436 Vdouble vProb;
437
438 if (!rDist_)
439 vProb.push_back(1.);
440 else
441 for (size_t i = 0; i < rDist_->getNumberOfCategories(); i++)
442 {
443 vProb.push_back(rDist_->getProbability(i));
444 }
445
446 return vProb;
447 }
448
449 double getRateForModel(size_t classIndex) const override
450 {
451 if (classIndex >= (rDist_ ? rDist_->getNumberOfCategories() : 1))
452 throw IndexOutOfBoundsException("NonHomogeneousSubstitutionProcess::getRateForModel.", classIndex, 0, (rDist_ ? rDist_->getNumberOfCategories() : 1));
453 return rDist_ ? rDist_->getCategory(classIndex) : 1;
454 }
455
474 static std::unique_ptr<AutonomousSubstitutionProcessInterface> createHomogeneousSubstitutionProcess(
475 std::shared_ptr<BranchModelInterface> model,
476 std::shared_ptr<DiscreteDistributionInterface> rdist,
477 std::shared_ptr<PhyloTree> tree,
478 std::shared_ptr<FrequencySetInterface> rootFreqs = 0,
479 std::shared_ptr<ModelScenario> scenario = 0
480 );
481
497 static std::unique_ptr<NonHomogeneousSubstitutionProcess> createNonHomogeneousSubstitutionProcess(
498 std::shared_ptr<BranchModelInterface> model,
499 std::shared_ptr<DiscreteDistributionInterface> rdist,
500 std::shared_ptr<PhyloTree> tree,
501 std::shared_ptr<FrequencySetInterface> rootFreqs,
502 const std::vector<std::string>& globalParameterNames,
503 std::shared_ptr<ModelScenario> scenario = 0
504 );
505
506
508};
509} // end of namespace bpp.
510#endif // BPP_PHYL_LIKELIHOOD_NONHOMOGENEOUSSUBSTITUTIONPROCESS_H
A partial implementation of the SubstitutionProcess interface.
std::shared_ptr< const ParametrizablePhyloTree > getParametrizablePhyloTree() const
void addParameters_(const ParameterList &parameters)
Interface for all Branch models.
virtual const Vdouble & getFrequencies() const =0
Substitution process manager for non-homogeneous / non-reversible models of evolution.
size_t getModelNumberForNode(unsigned int nodeId) const override
Get the number of the model associated to a particular node id.
DiscreteDistributionInterface & rateDistribution() override
Get the rate distribution.
double getProbabilityForModel(size_t classIndex) const override
std::shared_ptr< DiscreteDistributionInterface > getRateDistribution() override
Get a pointer to the rate distribution (or null if there is no rate distribution).
std::vector< std::shared_ptr< BranchModelInterface > > modelSet_
Contains all models used in this tree.
std::map< unsigned int, size_t > nodeToModel_
Contains for each node in a tree the index of the corresponding model in modelSet_.
std::shared_ptr< const BranchModelInterface > getModelForNode(unsigned int nodeId) const override
Get the model associated to a particular node id.
std::shared_ptr< DiscreteDistributionInterface > rDist_
Rate Distribution.
std::shared_ptr< const DiscreteDistributionInterface > getRateDistribution() const override
Get a pointer to the rate distribution (or null if there is no rate distribution).
void setModel(std::shared_ptr< BranchModelInterface > model, size_t modelIndex)
Change a given model.
void fireParameterChanged(const ParameterList &parameters) override
const BranchModelInterface & model(unsigned int nodeId, size_t classIndex) const override
Get the substitution model corresponding to a certain branch, site pattern, and model class.
void clear()
Resets all the information contained in this object.
std::shared_ptr< const BranchModelInterface > getModel(unsigned int nodeId, size_t classIndex) const override
Get the substitution model corresponding to a certain branch, site pattern, and model class.
const DiscreteDistributionInterface & rateDistribution() const override
Get the rate distribution.
void setModelScenario(std::shared_ptr< ModelScenario > modelscenario) override
Set the modelPath, after checking it is valid (ie modelpath has only the model of the process).
bool isFullySetUp(bool throwEx=true) const
Check if the model set is fully specified for a given tree.
const StateMapInterface & stateMap() const override
const std::vector< unsigned int > getNodesWithModel(size_t i) const override
Get a list of nodes id for which the given model is associated.
const BranchModelInterface & model(size_t n) const override
void listModelNames(std::ostream &out=std::cout) const
list all model names.
std::shared_ptr< const BranchModelInterface > getModel(size_t n)
std::map< size_t, std::vector< unsigned int > > modelToNodes_
ParameterList getSubstitutionModelParameters(bool independent) const override
Get the INDEPENDENT parameters corresponding to the models.
NonHomogeneousSubstitutionProcess(std::shared_ptr< DiscreteDistributionInterface > rdist, std::shared_ptr< const PhyloTree > tree=0, std::shared_ptr< FrequencySetInterface > rootFreqs=0)
Create a model set according to the specified alphabet and root frequencies. Stationarity is not assu...
NonHomogeneousSubstitutionProcess(std::shared_ptr< DiscreteDistributionInterface > rdist, std::shared_ptr< ParametrizablePhyloTree > tree, std::shared_ptr< FrequencySetInterface > rootFreqs=0)
Create a model set according to the specified alphabet and root frequencies. Stationarity is not assu...
void addModel(std::shared_ptr< BranchModelInterface > model, const std::vector< unsigned int > &nodesId)
Add a new model to the set, and set relationships with nodes and params.
const std::vector< double > & getRootFrequencies() const override
ParameterList getBranchLengthParameters(bool independent) const override
double getRateForModel(size_t classIndex) const override
std::shared_ptr< const StateMapInterface > getStateMap() const override
static std::unique_ptr< NonHomogeneousSubstitutionProcess > createNonHomogeneousSubstitutionProcess(std::shared_ptr< BranchModelInterface > model, std::shared_ptr< DiscreteDistributionInterface > rdist, std::shared_ptr< PhyloTree > tree, std::shared_ptr< FrequencySetInterface > rootFreqs, const std::vector< std::string > &globalParameterNames, std::shared_ptr< ModelScenario > scenario=0)
Create a NonHomogeneousSubstitutionProcess object, with one model per branch.
static std::unique_ptr< AutonomousSubstitutionProcessInterface > createHomogeneousSubstitutionProcess(std::shared_ptr< BranchModelInterface > model, std::shared_ptr< DiscreteDistributionInterface > rdist, std::shared_ptr< PhyloTree > tree, std::shared_ptr< FrequencySetInterface > rootFreqs=0, std::shared_ptr< ModelScenario > scenario=0)
Create a NonHomogeneousSubstitutionProcess object, corresponding to the homogeneous case.
NonHomogeneousSubstitutionProcess * clone() const override
void setModelToNode(size_t modelIndex, unsigned int nodeNumber)
Associate an existing model with a given node.
std::shared_ptr< const BranchModelInterface > getModel(size_t n) const override
std::vector< ParameterList > modelParameters_
Parameters for each model in the set.
std::vector< size_t > getModelNumbers() const override
ParameterList getRateDistributionParameters(bool independent) const override
Get the parameters attached to the rate distribution.
NonHomogeneousSubstitutionProcess & operator=(const NonHomogeneousSubstitutionProcess &set)
Map the states of a given alphabet which have a model state.
Definition: StateMap.h:25
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble