bpp-phyl3  3.0.0
SubstitutionProcessCollectionMember.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 <Bpp/Utils/MapTools.h>
6 
7 #include "../Model/MixedTransitionModel.h"
10 
11 using namespace bpp;
12 using namespace std;
13 
15 {
16  vector<size_t> vMN;
17  for (const auto& it : modelToNodes_)
18  {
19  vMN.push_back(it.first);
20  }
21 
22  return vMN;
23 }
24 
26 {
27  return collection().model(n);
28 }
29 
30 std::shared_ptr<const BranchModelInterface> SubstitutionProcessCollectionMember::getModel(size_t n) const
31 {
32  return collection().getModel(n);
33 }
34 
35 std::shared_ptr<BranchModelInterface> SubstitutionProcessCollectionMember::getModel(size_t n)
36 {
37  return collection().getModel(n);
38 }
39 
40 std::shared_ptr<const ModelScenario> SubstitutionProcessCollectionMember::getModelScenario() const
41 {
42  return collection().getModelScenario(nPath_);
43 }
44 
46 {
47  return collection().getModelScenario(nPath_);
48 }
49 
50 std::shared_ptr<const DiscreteDistributionInterface> SubstitutionProcessCollectionMember::getRateDistribution() const
51 {
52  return collection().getRateDistribution(nDist_);
53 }
54 
55 std::shared_ptr<DiscreteDistributionInterface> SubstitutionProcessCollectionMember::getRateDistribution()
56 {
57  return collection().getRateDistribution(nDist_);
58 }
59 
61 {
62  return collection().rateDistribution(nDist_);
63 }
64 
66 {
67  return collection().rateDistribution(nDist_);
68 }
69 
71 {
72  return collection().getRateDistributionParameters(nDist_, independent);
73 }
74 
76 {
77  if (nTree_ != 0)
78  return collection().getBranchLengthParameters(nTree_, independent);
79  else
80  return ParameterList();
81 }
82 
84 {
85  if (!isStationary())
86  return collection().getRootFrequenciesParameters(nRoot_, independent);
87  else
88  return ParameterList();
89 }
90 
92 {
93  resetParameters_();
94  addParameters_(getSubstitutionModelParameters(true));
95  addParameters_(getRootFrequenciesParameters(true));
96  addParameters_(getRateDistributionParameters(true));
97  addParameters_(getBranchLengthParameters(true));
98 }
99 
101 {
102  ParameterList pl = getSubstitutionModelParameters(false);
103  pl.includeParameters(getRootFrequenciesParameters(false));
104  pl.includeParameters(getRateDistributionParameters(false));
105 
106  pl.includeParameters(getCollection()->getAliasedParameters(pl));
107  pl.includeParameters(getCollection()->getFromParameters(pl));
108 
109  return pl;
110 }
111 
112 
114 {
115  ParameterList pl;
116 
117  // Then we update all models in the set:
118  std::map<size_t, std::vector<unsigned int>>::const_iterator it;
119  for (it = modelToNodes_.begin(); it != modelToNodes_.end(); it++)
120  {
121  pl.includeParameters(getCollection()->getSubstitutionModelParameters(it->first, independent));
122  }
123 
124  return pl;
125 }
126 
127 
128 std::shared_ptr<const FrequencySetInterface> SubstitutionProcessCollectionMember::getRootFrequencySet() const
129 {
130  if (isStationary())
131  return nullptr;
132  else
133  return collection().getFrequencySet(nRoot_);
134 }
135 
136 std::shared_ptr<FrequencySetInterface> SubstitutionProcessCollectionMember::getRootFrequencySet()
137 {
138  if (isStationary())
139  return nullptr;
140  else
141  return collection().getFrequencySet(nRoot_);
142 }
143 
145 {
146  if (isStationary())
147  throw NullPointerException("SubstitutionProcessCollectionMember::rootFrequencySet(). No root frequency parameters, this is a stationary model.");
148  else
149  return collection().frequencySet(nRoot_);
150 }
151 
153 {
154  if (isStationary())
155  throw NullPointerException("SubstitutionProcessCollectionMember::rootFrequencySet(). No root frequency parameters, this is a stationary model.");
156  else
157  return collection().frequencySet(nRoot_);
158 }
159 
161 {
162  auto model = dynamic_pointer_cast<const TransitionModelInterface>(getCollection()->getModel(modelToNodes_.begin()->first));
163 
164  if (isStationary() && model)
165  return model->getFrequencies();
166  else
167  return collection().frequencySet(nRoot_).getFrequencies();
168 }
169 
171 {
172  if (!getCollection()->hasModelScenario(numPath))
173  throw Exception("SubstitutionProcessCollectionMember::setModelScenario: Collection does not have ModelScenario number");
174 
175  auto modelScenario = getCollection()->getModelScenario(numPath);
176 
177  // Now check all the models of the path are included in the process.
178 
179  auto models = modelScenario->getModels();
180 
181  auto modnum = getModelNumbers();
182 
183  for (const auto& model:models)
184  {
185  bool ok = false;
186  for (auto num:modnum)
187  {
188  if (getModel(num) == model)
189  {
190  ok = true;
191  break;
192  }
193  }
194 
195  if (!ok)
196  throw Exception("SubstitutionProcessCollectionMember::setModelScenario: Model " + model->getName() + " in used in scenario" + TextTools::toString(numPath) + " but is unknown from process " + TextTools::toString(nProc_));
197  }
198 
199  nPath_ = numPath;
200 }
201 
202 
204 {
205  if (collection().hasTreeNumber(nTree_))
206  return collection().tree(nTree_);
207  else
208  throw Exception("SubstitutionProcessCollectionMember::parametrizablePhyloTree(). No associated tree.");
209 }
210 
211 std::shared_ptr<const ParametrizablePhyloTree> SubstitutionProcessCollectionMember::getParametrizablePhyloTree() const
212 {
213  return collection().hasTreeNumber(nTree_) ? collection().getTree(nTree_) : nullptr;
214 }
215 
217 {
218  if (collection().hasTreeNumber(nTree_))
219  return collection().tree(nTree_);
220  else
221  throw Exception("SubstitutionProcessCollectionMember::parametrizablePhyloTree(). No associated tree.");
222 }
223 
224 std::shared_ptr<ParametrizablePhyloTree> SubstitutionProcessCollectionMember::getParametrizablePhyloTree()
225 {
226  return collection().hasTreeNumber(nTree_) ? collection().getTree(nTree_) : nullptr;
227 }
228 
230 {
231  if (!collection().hasTreeNumber(nTree))
232  throw BadIntException((int)nTree, "SubstitutionProcessCollectionMember::setTreeNumber(). No associated tree.", getAlphabet());
233 
234  deleteParameters_(getBranchLengthParameters(true).getParameterNames());
235 
236  nTree_ = nTree;
237 
238  addParameters_(getBranchLengthParameters(true));
239 
240  if (check)
241  isFullySetUp();
242 }
243 
244 void SubstitutionProcessCollectionMember::addModel(size_t numModel, const std::vector<unsigned int>& nodesId)
245 {
246  auto& nmod = getCollection()->model(numModel);
247 
248  if (modelToNodes_.size() > 0)
249  {
250  auto& modi = getCollection()->model(modelToNodes_.begin()->first);
251  if (nmod.getAlphabet()->getAlphabetType() != modi.getAlphabet()->getAlphabetType())
252  throw Exception("SubstitutionProcessCollectionMember::addModel. A Substitution Model cannot be added to a Model Set if it does not have the same alphabet.");
253  if (nmod.getNumberOfStates() != modi.getNumberOfStates())
254  throw Exception("SubstitutionProcessCollectionMember::addModel. A Substitution Model cannot be added to a Model Set if it does not have the same number of states.");
255  }
256  else if (!isStationary())
257  {
258  auto& freq = getCollection()->frequencySet(nRoot_);
259  if (freq.getAlphabet()->getAlphabetType() != nmod.getAlphabet()->getAlphabetType())
260  throw Exception("SubstitutionProcessCollectionMember::addModel. A Substitution Model cannot be added to a Model Set if it does not have the same alphabet as the root frequencies.");
261  if (freq.getFrequencies().size() != nmod.getNumberOfStates())
262  throw Exception("SubstitutionProcessCollectionMember::addModel. A Substitution Model cannot be added to a Model Set if it does not have the same number of states as the root frequencies.");
263  }
264 
265  // Associate this model to specified nodes:
266  for (size_t i = 0; i < nodesId.size(); i++)
267  {
268  nodeToModel_[nodesId[i]] = numModel;
269  modelToNodes_[numModel].push_back(nodesId[i]);
270  }
271 
272  updateParameters();
273 }
274 
275 
277 {
278  auto& freq = getCollection()->frequencySet(numFreq);
279  if (modelToNodes_.size() > 0)
280  {
281  auto& modi = getCollection()->model(modelToNodes_.begin()->first);
282 
283  if (freq.getAlphabet()->getAlphabetType() != modi.getAlphabet()->getAlphabetType())
284  throw Exception("SubstitutionProcessCollectionMember::setRootFrequencies. A Frequencies Set cannot be added to a Model Set if it does not have the same alphabet as the models.");
285  if (freq.getFrequencies().size() != modi.getNumberOfStates())
286  throw Exception("SubstitutionProcessCollectionMember::setRootFrequencies. A Frequencies Set cannot be added to a Model Set if it does not have the same number of states as the models.");
287  }
288 
289  nRoot_ = numFreq;
290 
291  updateParameters();
292 }
293 
295 {
296  if (!getParametrizablePhyloTree())
297  {
298  if (throwEx)
299  throw Exception("SubstitutionProcessCollectionMember::checkOrphanNodes(). No Tree");
300 
301  return true;
302  }
303 
304  vector<unsigned int> ids = getParametrizablePhyloTree()->getAllNodesIndexes();
305  unsigned int rootId = getParametrizablePhyloTree()->getNodeIndex(getParametrizablePhyloTree()->getRoot());
306  for (size_t i = 0; i < ids.size(); i++)
307  {
308  if (ids[i] != rootId && nodeToModel_.find(ids[i]) == nodeToModel_.end())
309  {
310  if (throwEx)
311  throw Exception("SubstitutionProcessCollectionMember::checkOrphanNodes(). Node '" + TextTools::toString(ids[i]) + "' in tree has no model associated.");
312  return false;
313  }
314  }
315  return true;
316 }
317 
319 {
320  if (!getParametrizablePhyloTree())
321  {
322  if (throwEx)
323  throw Exception("SubstitutionProcessCollectionMember::checkUnknownNodes(). No Tree");
324 
325  return true;
326  }
327 
328  vector<unsigned int> ids = getParametrizablePhyloTree()->getAllNodesIndexes();
329 
330  unsigned int rootId = getParametrizablePhyloTree()->getNodeIndex(getParametrizablePhyloTree()->getRoot());
331 
332  for (auto& it : modelToNodes_)
333  {
334  for (auto id : it.second)
335  {
336  if (id == rootId || !VectorTools::contains(ids, id))
337  {
338  if (throwEx)
339  throw Exception("SubstitutionProcessCollectionMember::checkUnknownNodes(). Node '" + TextTools::toString(id) + "' is not found in tree or is the root node.");
340  return false;
341  }
342  }
343  }
344  return true;
345 }
346 
348 {
349  for (auto& it : modelToNodes_)
350  {
351  if (dynamic_pointer_cast<const MixedTransitionModelInterface>(collection().getModel(it.first)))
352  {
353  return true;
354  }
355  }
356  return false;
357 }
358 
360 {
361  collection().matchParametersValues(parameters);
363 }
364 
369 {
370  if (classIndex >= rateDistribution().getNumberOfCategories())
371  throw IndexOutOfBoundsException("SubstitutionProcessCollectionMember::getProbabilityForModel.", classIndex, 0, getRateDistribution()->getNumberOfCategories());
372  return rateDistribution().getProbability(classIndex);
373 }
374 
376 {
377  Vdouble vProb;
378 
379  for (size_t i = 0; i < rateDistribution().getNumberOfCategories(); i++)
380  {
381  vProb.push_back(rateDistribution().getProbability(i));
382  }
383 
384  return vProb;
385 }
386 
388 {
389  if (classIndex >= getRateDistribution()->getNumberOfCategories())
390  throw IndexOutOfBoundsException("SubstitutionProcessCollectionMember::getRateForModel.", classIndex, 0, getRateDistribution()->getNumberOfCategories());
391  return rateDistribution().getCategory(classIndex);
392 }
bool matchParametersValues(const ParameterList &parameters) override
Interface for all Branch models.
Parametrize a set of state frequencies.
Definition: FrequencySet.h:29
virtual void includeParameters(const ParameterList &params)
PhyloTree with Parametrizable Phylo Branches. They SHARE their branch length parameters.
void updateParameters()
sets the parameters as the independent parameters on the objects
std::vector< size_t > getModelNumbers() 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).
const DiscreteDistributionInterface & rateDistribution() const override
Get the rate distribution.
const FrequencySetInterface & rootFrequencySet() const override
ParameterList getBranchLengthParameters(bool independent) const override
Get the parameters of the tree.
double getRateForModel(size_t classIndex) const override
bool matchParametersValues(const ParameterList &parameters) override
AbsractParametrizable interface.
const BranchModelInterface & model(size_t n) const override
std::shared_ptr< const ModelScenario > getModelScenario() const override
Get the Model Scenario associated with this process, in case there are mixture models involved.
void addModel(size_t numModel, const std::vector< unsigned int > &nodesId)
Add a new model to the set, and set relationships with nodes.
std::shared_ptr< const FrequencySetInterface > getRootFrequencySet() const override
std::shared_ptr< const BranchModelInterface > getModel(size_t n) const override
ParameterList getSubstitutionModelParameters(bool independent) const override
Get the parameters of the substitution models.
const std::vector< double > & getRootFrequencies() const override
ParameterList getRateDistributionParameters(bool independent) const override
Get the parameters of the rate distribution.
std::shared_ptr< const ParametrizablePhyloTree > getParametrizablePhyloTree() const override
const ParametrizablePhyloTree & parametrizablePhyloTree() const override
void setRootFrequencies(size_t numFreq)
Set the root Frequencies Set.
ParameterList getNonDerivableParameters() const override
get all NonDerivable parameters.
ParameterList getRootFrequenciesParameters(bool independent) const override
Get the parameters of the root frequencies set.
double getProbabilityForModel(size_t classIndex) const override
static bool contains(const std::vector< T > &vec, T el)
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble