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 
24 namespace bpp
25 {
80 {
81 private:
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 
104 public:
114  std::shared_ptr<DiscreteDistributionInterface> rdist,
115  std::shared_ptr<const PhyloTree> tree = 0,
116  std::shared_ptr<FrequencySetInterface> rootFreqs = 0) :
118  AbstractAutonomousSubstitutionProcess(tree, rootFreqs),
119  modelSet_(),
120  rDist_(rdist),
121  nodeToModel_(),
122  modelToNodes_(),
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) :
142  AbstractAutonomousSubstitutionProcess(tree, rootFreqs),
143  modelSet_(),
144  rDist_(rdist),
145  nodeToModel_(),
146  modelToNodes_(),
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 
390 protected:
396  bool checkOrphanNodes(bool throwEx) const;
397 
398  bool checkUnknownNodes(bool throwEx) const;
399 
400 public:
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
414  return rootFrequencySet().getFrequencies();
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.
double getProbabilityForModel(size_t classIndex) const override
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< DiscreteDistributionInterface > rDist_
Rate Distribution.
void setModel(std::shared_ptr< BranchModelInterface > model, size_t modelIndex)
Change a given model.
void fireParameterChanged(const ParameterList &parameters) override
std::shared_ptr< const BranchModelInterface > getModelForNode(unsigned int nodeId) const override
Get the model associated to a particular node id.
std::shared_ptr< const BranchModelInterface > getModel(size_t n)
void clear()
Resets all the information contained in this object.
const DiscreteDistributionInterface & rateDistribution() const override
Get the rate distribution.
const StateMapInterface & stateMap() const override
const std::vector< double > & getRootFrequencies() const override
const BranchModelInterface & model(size_t n) const override
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.
std::shared_ptr< const StateMapInterface > getStateMap() const override
DiscreteDistributionInterface & rateDistribution() override
Get the rate distribution.
void listModelNames(std::ostream &out=std::cout) const
list all model names.
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.
std::shared_ptr< DiscreteDistributionInterface > getRateDistribution() override
Get a pointer to the rate distribution (or null if there is no rate distribution).
ParameterList getBranchLengthParameters(bool independent) const override
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.
NonHomogeneousSubstitutionProcess * clone() const override
double getRateForModel(size_t classIndex) const override
std::shared_ptr< const DiscreteDistributionInterface > getRateDistribution() const override
Get a pointer to the rate distribution (or null if there is no rate distribution).
std::vector< size_t > getModelNumbers() 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.
void setModelToNode(size_t modelIndex, unsigned int nodeNumber)
Associate an existing model with a given node.
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.
std::vector< ParameterList > modelParameters_
Parameters for each model in the set.
ParameterList getRateDistributionParameters(bool independent) const override
Get the parameters attached to the rate distribution.
NonHomogeneousSubstitutionProcess & operator=(const NonHomogeneousSubstitutionProcess &set)
const std::vector< unsigned int > getNodesWithModel(size_t i) const override
Get a list of nodes id for which the given model is associated.
std::shared_ptr< const BranchModelInterface > getModel(size_t n) const override
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