bpp-phyl3  3.0.0
SubstitutionModelSet.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_LEGACY_MODEL_SUBSTITUTIONMODELSET_H
6 #define BPP_PHYL_LEGACY_MODEL_SUBSTITUTIONMODELSET_H
7 
8 #include <Bpp/Exceptions.h>
11 
12 #include "../../Model/AbstractSubstitutionModel.h"
13 #include "../../Model/FrequencySet/FrequencySet.h"
14 #include "../../Tree/Tree.h"
15 
16 // From bpp-seq:
19 
20 // From the STL:
21 #include <vector>
22 #include <map>
23 #include <algorithm>
24 #include <memory>
25 #include <typeinfo>
26 
27 namespace bpp
28 {
69 {
70 protected:
74  std::shared_ptr<const Alphabet> alphabet_;
75 
76  size_t nbStates_;
77 
81  std::vector< std::shared_ptr<TransitionModelInterface>> modelSet_;
82 
83 private:
87  std::shared_ptr<FrequencySetInterface> rootFrequencies_;
88 
92  mutable std::map<int, size_t> nodeToModel_;
93  mutable std::map<size_t, std::vector<int>> modelToNodes_;
94 
102  std::vector<ParameterList> modelParameters_;
103 
105 
106 public:
113  SubstitutionModelSet(std::shared_ptr<const Alphabet> alpha) :
115  alphabet_(alpha),
116  nbStates_(0),
117  modelSet_(),
119  nodeToModel_(),
120  modelToNodes_(),
122  stationarity_(true)
123  {}
124 
133  std::shared_ptr<const Alphabet> alpha,
134  std::shared_ptr<FrequencySetInterface> rootFreqs) :
136  alphabet_(alpha),
137  nbStates_(0),
138  modelSet_(),
140  nodeToModel_(),
141  modelToNodes_(),
143  stationarity_(true)
144  {
145  setRootFrequencies(rootFreqs);
146  }
147 
152  void clear();
153 
154  bool isStationary() const
155  {
156  return stationarity_;
157  }
158 
164  void setRootFrequencies(std::shared_ptr<FrequencySetInterface> rootFreqs);
165 
167 
169 
171 
172  SubstitutionModelSet* clone() const { return new SubstitutionModelSet(*this); }
173 
174 public:
181  size_t getNumberOfStates() const
182  {
183  return nbStates_;
184  }
185 
191  virtual void fireParameterChanged(const ParameterList& parameters);
192 
196  size_t getNumberOfModels() const { return modelSet_.size(); }
197 
202  bool hasMixedTransitionModel() const;
203 
210  std::shared_ptr<const TransitionModelInterface> getModel(size_t i) const
211  {
212  if (i >= modelSet_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::getModel(i).", i, 0, modelSet_.size() - 1);
213  return modelSet_[i];
214  }
215 
216  const TransitionModelInterface& model(size_t i) const
217  {
218  if (i >= modelSet_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::model(i).", i, 0, modelSet_.size() - 1);
219  return *modelSet_[i];
220  }
221 
222  std::shared_ptr<TransitionModelInterface> getModel(size_t i)
223  {
224  if (i >= modelSet_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::getModel(i).", i, 0, modelSet_.size() - 1);
225  return modelSet_[i];
226  }
227 
229  {
230  if (i >= modelSet_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::model(i).", i, 0, modelSet_.size() - 1);
231  return *modelSet_[i];
232  }
236  std::shared_ptr<const SubstitutionModelInterface> getSubstitutionModel(size_t i) const
237  {
238  auto m = std::dynamic_pointer_cast<const SubstitutionModelInterface>(getModel(i));
239  if (m) return m;
240  else
241  throw Exception("SubstitutionModelSet::getSubstitutionModel : " + model(i).getName() + " is not a substitution model.");
242  }
243 
244 
245  std::shared_ptr<SubstitutionModelInterface> getSubstitutionModel(size_t i)
246  {
247  auto m = std::dynamic_pointer_cast<SubstitutionModelInterface>(getModel(i));
248  if (m) return m;
249  else
250  throw Exception("SubstitutionModelSet::getSubstitutionModel : " + model(i).getName() + " is not a substitution model.");
251  }
252 
254  {
255  try
256  {
257  auto& m = dynamic_cast<const SubstitutionModelInterface&>(model(i));
258  return m;
259  }
260  catch (Exception& ex)
261  {
262  throw Exception("SubstitutionModelSet::substitutionModel : " + model(i).getName() + " is not a substitution model.");
263  }
264  }
265 
270  {
271  for (const auto& mod : modelSet_)
272  {
273  auto model = std::dynamic_pointer_cast<const SubstitutionModelInterface>(mod);
274  if (!model) return false;
275  }
276  return true;
277  }
278 
286  size_t getModelIndexForNode(int nodeId) const
287  {
288  auto i = nodeToModel_.find(nodeId);
289  if (i == nodeToModel_.end())
290  throw Exception("SubstitutionModelSet::getModelIndexForNode(). No model associated to node with id " + TextTools::toString(nodeId));
291  return i->second;
292  }
293 
301  std::shared_ptr<const TransitionModelInterface> getModelForNode(int nodeId) const
302  {
303  auto i = nodeToModel_.find(nodeId);
304  if (i == nodeToModel_.end())
305  throw Exception("SubstitutionModelSet::getModelForNode(). No model associated to node with id " + TextTools::toString(nodeId));
306  return modelSet_[i->second];
307  }
308  std::shared_ptr<TransitionModelInterface> getModelForNode(int nodeId)
309  {
310  auto i = nodeToModel_.find(nodeId);
311  if (i == nodeToModel_.end())
312  throw Exception("SubstitutionModelSet::getModelForNode(). No model associated to node with id " + TextTools::toString(nodeId));
313  return modelSet_[i->second];
314  }
315 
316  std::shared_ptr<const SubstitutionModelInterface> getSubstitutionModelForNode(int nodeId) const
317  {
318  return std::dynamic_pointer_cast<const SubstitutionModelInterface>(getModelForNode(nodeId));
319  }
320 
321  std::shared_ptr<SubstitutionModelInterface> getSubstitutionModelForNode(int nodeId)
322  {
323  return std::dynamic_pointer_cast<SubstitutionModelInterface>(getModelForNode(nodeId));
324  }
325 
333  const std::vector<int>& getNodesWithModel(size_t i) const
334  {
335  if (i >= modelSet_.size()) throw IndexOutOfBoundsException("SubstitutionModelSet::getNodesWithModel().", i, 0, modelSet_.size());
336  return modelToNodes_[i];
337  }
338 
345  std::vector<int> getNodesWithParameter(const std::string& name) const;
346 
363  void addModel(std::shared_ptr<TransitionModelInterface> model, const std::vector<int>& nodesId); // , const std::vector<std::string>& newParams);
364 
373  void setNodeToModel(size_t modelIndex, int nodeId); // Keren: added on my own to allow alternation of nodes assignments to existing nodes
374 
378  void resetModelToNodeIds(); // Keren: added on my own to allow alternation of nodes assignments to existing nodes
379 
389  void replaceModel(size_t modelIndex, std::shared_ptr<TransitionModelInterface> model);
390 
391  void listModelNames(std::ostream& out = std::cout) const;
392 
396  const std::shared_ptr<FrequencySetInterface> getRootFrequencySet() const { return rootFrequencies_; }
397 
402  {
403  if (rootFrequencies_)
404  {
405  return *rootFrequencies_;
406  }
407  else
408  {
409  throw NullPointerException("SubstitutionModelSet::rootFrequencySet. No associated root frequencies.");
410  }
411  }
412 
416  std::vector<double> getRootFrequencies() const
417  {
418  if (stationarity_)
419  return modelSet_[0]->getFrequencies();
420  else
421  return rootFrequencies_->getFrequencies();
422  }
423 
430  {
431  if (stationarity_)
432  return ParameterList();
433  else
434  return rootFrequencies_->getParameters();
435  }
436 
445  {
446  ParameterList pl;
447  for (size_t i = stationarity_ ? 0 : rootFrequencies_->getNumberOfParameters();
448  i < getNumberOfParameters(); i++)
449  {
451  }
452  return pl;
453  }
454 
463  ParameterList getModelParameters(size_t modelIndex) const;
464 
465  std::shared_ptr<const Alphabet> getAlphabet() const { return alphabet_; }
466 
467  const Alphabet& alphabet() const { return *alphabet_; }
468 
474  const std::vector<int>& getAlphabetStates() const
475  {
476  return model(0).getAlphabetStates();
477  }
478 
480  {
481  return model(0).stateMap();
482  }
483 
484  std::shared_ptr<const StateMapInterface> getStateMap() const
485  {
486  return model(0).getStateMap();
487  }
488 
489  std::vector<size_t> getModelStates(int code) const
490  {
491  return model(0).getModelStates(code);
492  }
493 
494  std::vector<size_t> getModelStates(const std::string& code) const
495  {
496  return model(0).getModelStates(code);
497  }
498 
503  int getAlphabetStateAsInt(size_t index) const
504  {
505  return model(0).getAlphabetStateAsInt(index);
506  }
507 
512  std::string getAlphabetStateAsChar(size_t index) const
513  {
514  return model(0).getAlphabetStateAsChar(index);
515  }
516 
529  bool isFullySetUpFor(const Tree& tree, bool throwEx = true) const
530  {
531  return checkOrphanModels(throwEx)
532  // && checkOrphanParameters(throwEx)
533  && checkOrphanNodes(tree, throwEx)
534  && checkUnknownNodes(tree, throwEx);
535  }
536 
537 protected:
542  {
543  if (!stationarity_)
544  rootFrequencies_->matchParametersValues(getParameters());
545  }
546 
552  bool checkOrphanModels(bool throwEx) const;
553 
554  bool checkOrphanNodes(const Tree& tree, bool throwEx) const;
555 
556  bool checkUnknownNodes(const Tree& tree, bool throwEx) const;
558 };
559 } // end of namespace bpp.
560 #endif // BPP_PHYL_LEGACY_MODEL_SUBSTITUTIONMODELSET_H
size_t getNumberOfParameters() const override
const ParameterList & getParameters() const override
Parameter & getParameter_(const std::string &name)
virtual int getAlphabetStateAsInt(size_t index) const =0
virtual const std::vector< int > & getAlphabetStates() const =0
virtual std::string getAlphabetStateAsChar(size_t index) const =0
virtual std::vector< size_t > getModelStates(int code) const =0
Get the state in the model corresponding to a particular state in the alphabet.
virtual std::shared_ptr< const StateMapInterface > getStateMap() const =0
virtual const StateMapInterface & stateMap() const =0
Parametrize a set of state frequencies.
Definition: FrequencySet.h:29
virtual void addParameter(const Parameter &param)
Map the states of a given alphabet which have a model state.
Definition: StateMap.h:25
Interface for all substitution models.
Substitution models manager for non-homogeneous / non-reversible models of evolution.
virtual void fireParameterChanged(const ParameterList &parameters)
std::shared_ptr< const SubstitutionModelInterface > getSubstitutionModelForNode(int nodeId) const
void setNodeToModel(size_t modelIndex, int nodeId)
Sets an assignment of a given model index to a given onde id.
const std::shared_ptr< FrequencySetInterface > getRootFrequencySet() const
SubstitutionModelSet(std::shared_ptr< const Alphabet > alpha)
Create a model set according to the specified alphabet. Stationarity is assumed.
std::vector< size_t > getModelStates(int code) const
const TransitionModelInterface & model(size_t i) const
std::shared_ptr< FrequencySetInterface > rootFrequencies_
Root frequencies.
const std::vector< int > & getAlphabetStates() const
std::shared_ptr< TransitionModelInterface > getModelForNode(int nodeId)
std::vector< int > getNodesWithParameter(const std::string &name) const
const std::vector< int > & getNodesWithModel(size_t i) const
Get a list of nodes id for which the given model is associated.
bool isFullySetUpFor(const Tree &tree, bool throwEx=true) const
Check if the model set is fully specified for a given tree.
bool checkOrphanModels(bool throwEx) const
std::shared_ptr< const TransitionModelInterface > getModel(size_t i) const
Get one model from the set knowing its index.
std::shared_ptr< const Alphabet > alphabet_
A pointer toward the common alphabet to all models in the set.
bool checkOrphanNodes(const Tree &tree, bool throwEx) const
void setRootFrequencies(std::shared_ptr< FrequencySetInterface > rootFreqs)
Sets a given FrequencySet for root frequencies.
ParameterList getModelParameters(size_t modelIndex) const
Get the parameters attached to a Model.
int getAlphabetStateAsInt(size_t index) const
std::map< int, size_t > nodeToModel_
Contains for each node in a tree the index of the corresponding model in modelSet_.
std::shared_ptr< SubstitutionModelInterface > getSubstitutionModel(size_t i)
std::shared_ptr< const SubstitutionModelInterface > getSubstitutionModel(size_t i) const
Return a markovian substitution model (or null)
std::shared_ptr< TransitionModelInterface > getModel(size_t i)
std::shared_ptr< SubstitutionModelInterface > getSubstitutionModelForNode(int nodeId)
std::shared_ptr< const TransitionModelInterface > getModelForNode(int nodeId) const
Get the model associated to a particular node id.
ParameterList getRootFrequenciesParameters() const
Get the parameters corresponding to the root frequencies.
size_t getNumberOfStates() const
Get the number of states associated to this model set.
std::shared_ptr< const StateMapInterface > getStateMap() const
std::vector< double > getRootFrequencies() const
const SubstitutionModelInterface & substitutionModel(size_t i) const
size_t getModelIndexForNode(int nodeId) const
Get the index in the set of the model associated to a particular node id.
bool hasOnlySubstitutionModels() const
check if has only markovian substitution models
const Alphabet & alphabet() const
void addModel(std::shared_ptr< TransitionModelInterface > model, const std::vector< int > &nodesId)
Add a new model to the set, and set relationships with nodes and params.
SubstitutionModelSet * clone() const
std::vector< size_t > getModelStates(const std::string &code) const
void listModelNames(std::ostream &out=std::cout) const
void resetModelToNodeIds()
Reset model indices to node ids assignment.
SubstitutionModelSet & operator=(const SubstitutionModelSet &set)
std::map< size_t, std::vector< int > > modelToNodes_
ParameterList getNodeParameters() const
Get the parameters corresponding attached to the nodes of the tree.
std::string getAlphabetStateAsChar(size_t index) const
bool checkUnknownNodes(const Tree &tree, bool throwEx) const
void replaceModel(size_t modelIndex, std::shared_ptr< TransitionModelInterface > model)
Replace a model in the set, and all corresponding parameters. The replaced model deleted.
std::vector< std::shared_ptr< TransitionModelInterface > > modelSet_
Contains all models used in this tree.
std::vector< ParameterList > modelParameters_
Parameters for each model in the set.
TransitionModelInterface & model(size_t i)
const StateMapInterface & stateMap() const
std::shared_ptr< const Alphabet > getAlphabet() const
const FrequencySetInterface & rootFrequencySet() const
SubstitutionModelSet(std::shared_ptr< const Alphabet > alpha, std::shared_ptr< FrequencySetInterface > rootFreqs)
Create a model set according to the specified alphabet and root frequencies. Stationarity is not assu...
void clear()
Resets all the information contained in this object.
Interface for all transition models.
Interface for phylogenetic tree objects.
Definition: Tree.h:115
std::string toString(T t)
Defines the basic types of data flow nodes.