bpp-phyl3  3.0.0
SubstitutionModelSetTools.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "../../Model/MixedTransitionModel.h"
8 
9 using namespace bpp;
10 
11 using namespace std;
12 
14  shared_ptr<TransitionModelInterface> model,
15  shared_ptr<FrequencySetInterface> rootFreqs,
16  const Tree& tree
17  )
18 {
19  // Check alphabet:
20  if (model->getAlphabet()->getAlphabetType() != rootFreqs->getAlphabet()->getAlphabetType())
21  throw AlphabetMismatchException("SubstitutionModelSetTools::createHomogeneousModelSet()", model->getAlphabet(), rootFreqs->getAlphabet());
22  if (dynamic_cast<MixedTransitionModelInterface*>(model.get()) != nullptr)
23  throw Exception("createHomogeneousModelSet non yet programmed for mixture models.");
24 
25  auto modelSet = make_unique<SubstitutionModelSet>(model->getAlphabet());
26 
27  modelSet->setRootFrequencies(rootFreqs);
28  // We assign this model to all nodes in the tree (excepted root node), and link all parameters with it.
29  vector<int> ids = tree.getNodesId();
30  int rootId = tree.getRootId();
31  unsigned int pos = 0;
32  for (unsigned int i = 0; i < ids.size(); ++i)
33  {
34  if (ids[i] == rootId)
35  {
36  pos = i;
37  break;
38  }
39  }
40  ids.erase(ids.begin() + pos);
41  modelSet->addModel(model, ids);
42 
43  return modelSet;
44 }
45 
47  shared_ptr<TransitionModelInterface> model,
48  shared_ptr<FrequencySetInterface> rootFreqs,
49  const Tree& tree,
50  const map<string, string>& aliasFreqNames,
51  const map<string, vector<Vint>>& globalParameterNames
52  )
53 {
54  // Check alphabet:
55  if (rootFreqs && model->alphabet().getAlphabetType() != rootFreqs->alphabet().getAlphabetType())
56  throw AlphabetMismatchException("SubstitutionModelSetTools::createNonHomogeneousModelSet()", model->getAlphabet(), rootFreqs->getAlphabet());
57  ParameterList globalParameters;
58  globalParameters = model->getParameters();
59 
60  vector<string> modelParamNames = globalParameters.getParameterNames();
61 
62  map<string, vector<Vint>> globalParameterNames2;
63 
64  // First get correct parameter names
65 
66  for (const auto& name : globalParameterNames)
67  {
68  vector<string> complName = ApplicationTools::matchingParameters(name.first, modelParamNames);
69 
70  if (complName.size() == 0)
71  throw Exception("SubstitutionModelSetTools::createNonHomogeneousModelSet. Parameter '" + name.first + "' is not valid.");
72  else
73  for (auto& cni : complName)
74  {
75  globalParameterNames2[cni] = name.second;
76  }
77  }
78 
79  auto modelSet = make_unique<SubstitutionModelSet>(model->getAlphabet());
80 
81  if (rootFreqs)
82  modelSet->setRootFrequencies(rootFreqs);
83 
84  // We assign a copy of this model to all nodes in the tree (excepted root node), and link all parameters with it.
85  vector<int> ids = tree.getNodesId();
86  int rootId = tree.getRootId();
87  size_t pos = 0;
88  for (size_t i = 0; i < ids.size(); ++i)
89  {
90  if (ids[i] == rootId)
91  {
92  pos = i;
93  break;
94  }
95  }
96 
97  ids.erase(ids.begin() + static_cast<ptrdiff_t>(pos));
98  for (size_t i = 0; i < ids.size(); ++i)
99  {
100  modelSet->addModel(shared_ptr<TransitionModelInterface>(model->clone()), vector<int>(1, ids[i]));
101  }
102 
103  // Now alias all global parameters on all nodes:
104  for (size_t nn = 0; nn < globalParameters.size(); ++nn)
105  {
106  const Parameter& param = globalParameters[nn];
107 
108  string pname = param.getName();
109 
110  if (globalParameterNames2.find(pname) != globalParameterNames2.end())
111  {
112  const vector<Vint>& vvids(globalParameterNames2[pname]);
113 
114  if (vvids.size() == 0)
115  {
116  size_t fmid = modelSet->getModelIndexForNode(ids[0]) + 1;
117  for (size_t i = 1; i < ids.size(); ++i)
118  {
119  modelSet->aliasParameters(pname + "_" + TextTools::toString(fmid), pname + "_" + TextTools::toString(modelSet->getModelIndexForNode(ids[i]) + 1));
120  }
121  }
122  else
123  for (const auto& vids : vvids)
124  {
125  size_t fmid = modelSet->getModelIndexForNode(vids[0] + 1);
126  for (size_t i = 1; i < vids.size(); i++)
127  {
128  modelSet->aliasParameters(pname + "_" + TextTools::toString(fmid), pname + "_" + TextTools::toString(modelSet->getModelIndexForNode(vids[i]) + 1));
129  }
130  }
131  }
132  }
133 
134  // and alias on the root
135  for (auto& it : aliasFreqNames)
136  {
137  if (globalParameterNames2.find(it.second) != globalParameterNames2.end())
138  modelSet->aliasParameters(it.second + "_1", it.first);
139  }
140 
141  return modelSet;
142 }
static std::vector< std::string > matchingParameters(const std::string &pattern, const std::map< std::string, std::string > &params)
Interface for Transition models, defined as a mixture of "simple" transition models.
size_t size() const
virtual std::vector< std::string > getParameterNames() const
virtual const std::string & getName() const
static std::unique_ptr< SubstitutionModelSet > createNonHomogeneousModelSet(std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< FrequencySetInterface > rootFreqs, const Tree &tree, const std::map< std::string, std::string > &aliasFreqNames, const std::map< std::string, std::vector< Vint >> &globalParameterNames)
Create a SubstitutionModelSet object, with one model per branch.
static std::unique_ptr< SubstitutionModelSet > createHomogeneousModelSet(std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< FrequencySetInterface > rootFreqs, const Tree &tree)
Create a SubstitutionModelSet object, corresponding to the homogeneous case.
Interface for phylogenetic tree objects.
Definition: Tree.h:115
virtual std::vector< int > getNodesId() const =0
virtual int getRootId() const =0
std::string toString(T t)
Defines the basic types of data flow nodes.