bpp-phyl3  3.0.0
NonHomogeneousSequenceSimulator.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
6 #include "../Model/SubstitutionModelSetTools.h"
7 #include "../../Tree/PhyloTreeTools.h"
8 
12 
13 // From bpp-seq:
16 
17 using namespace bpp;
18 using namespace std;
19 
20 /******************************************************************************/
21 
23  std::shared_ptr<const SubstitutionModelSet> modelSet,
24  std::shared_ptr<const DiscreteDistributionInterface> rate,
25  std::shared_ptr<const Tree> tree) :
26  modelSet_(modelSet),
27  alphabet_(modelSet_->getAlphabet()),
28  supportedStates_(modelSet_->getAlphabetStates()),
29  rate_(rate),
30  templateTree_(tree),
31  tree_(*tree),
32  phyloTree_(make_shared<const ParametrizablePhyloTree>(*PhyloTreeTools::buildFromTreeTemplate(*tree))),
33  leaves_(tree_.getLeaves()),
34  seqNames_(),
35  nbNodes_(),
36  nbClasses_(rate_->getNumberOfCategories()),
37  nbStates_(modelSet_->getNumberOfStates()),
38  continuousRates_(false),
39  outputInternalSequences_(false)
40 {
41  if (!modelSet->isFullySetUpFor(*tree))
42  throw Exception("NonHomogeneousSequenceSimulator(constructor). Model set is not fully specified.");
43  init();
44 }
45 
46 /******************************************************************************/
47 
49  std::shared_ptr<const TransitionModelInterface> model,
50  std::shared_ptr<const DiscreteDistributionInterface> rate,
51  std::shared_ptr<const Tree> tree) :
52  modelSet_(0),
53  alphabet_(model->getAlphabet()),
54  supportedStates_(model->getAlphabetStates()),
55  rate_(rate),
56  templateTree_(tree),
57  tree_(*tree),
58  phyloTree_(make_shared<const ParametrizablePhyloTree>(*PhyloTreeTools::buildFromTreeTemplate(*tree))),
59  leaves_(tree_.getLeaves()),
60  seqNames_(),
61  nbNodes_(),
62  nbClasses_(rate_->getNumberOfCategories()),
63  nbStates_(model->getNumberOfStates()),
64  continuousRates_(false),
65  outputInternalSequences_(false)
66 {
67  auto fSet = make_shared<FixedFrequencySet>(model->getStateMap(), model->getFrequencies());
68  fSet->setNamespace("anc.");
69  modelSet_ = SubstitutionModelSetTools::createHomogeneousModelSet(shared_ptr<TransitionModelInterface>(model->clone()), fSet, *templateTree_);
70  init();
71 }
72 
73 /******************************************************************************/
74 
76 {
77  vector<SNode*> nodes = tree_.getNodes();
78 
80  {
81  seqNames_.resize(nodes.size());
82  for (size_t i = 0; i < seqNames_.size(); i++)
83  {
84  if (nodes[i]->isLeaf())
85  {
86  seqNames_[i] = nodes[i]->getName();
87  }
88  else
89  {
90  seqNames_[i] = TextTools::toString( nodes[i]->getId() );
91  }
92  }
93  }
94  else
95  {
96  seqNames_.resize(leaves_.size());
97  for (size_t i = 0; i < seqNames_.size(); i++)
98  {
99  seqNames_[i] = leaves_[i]->getName();
100  }
101  }
102  // Initialize cumulative pxy:
103  nodes.pop_back(); // remove root
104  nbNodes_ = nodes.size();
105 
106  for (size_t i = 0; i < nodes.size(); i++)
107  {
108  SNode* node = nodes[i];
109  node->getInfos().model = modelSet_->getModelForNode(node->getId());
110  double d = node->getDistanceToFather();
111  VVVdouble* cumpxy_node_ = &node->getInfos().cumpxy;
112  cumpxy_node_->resize(nbClasses_);
113  for (size_t c = 0; c < nbClasses_; c++)
114  {
115  VVdouble* cumpxy_node_c_ = &(*cumpxy_node_)[c];
116  cumpxy_node_c_->resize(nbStates_);
117  RowMatrix<double> P = node->getInfos().model->getPij_t(d * rate_->getCategory(c));
118  for (size_t x = 0; x < nbStates_; x++)
119  {
120  Vdouble* cumpxy_node_c_x_ = &(*cumpxy_node_c_)[x];
121  cumpxy_node_c_x_->resize(nbStates_);
122  (*cumpxy_node_c_x_)[0] = P(x, 0);
123  for (size_t y = 1; y < nbStates_; y++)
124  {
125  (*cumpxy_node_c_x_)[y] = (*cumpxy_node_c_x_)[y - 1] + P(x, y);
126  }
127  }
128  }
129  }
130 }
131 
132 /******************************************************************************/
133 
135 {
136  // Draw an initial state randomly according to equilibrium frequencies:
137  size_t initialStateIndex = 0;
139  double cumprob = 0;
140  vector<double> freqs = modelSet_->getRootFrequencies();
141  for (size_t i = 0; i < nbStates_; i++)
142  {
143  cumprob += freqs[i];
144  if (r <= cumprob)
145  {
146  initialStateIndex = i;
147  break;
148  }
149  }
150  return simulateSite(initialStateIndex);
151 }
152 
153 /******************************************************************************/
154 
155 unique_ptr<Site> NonHomogeneousSequenceSimulator::simulateSite(size_t ancestralStateIndex) const
156 {
157  if (continuousRates_)
158  {
159  // Draw a random rate:
160  double rate = rate_->randC();
161  // Make this state evolve:
162  return simulateSite(ancestralStateIndex, rate);
163  }
164  else
165  {
166  // Draw a random rate:
167  size_t rateClass = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(rate_->getNumberOfCategories());
168  // Make this state evolve:
169  return simulateSite(ancestralStateIndex, rateClass);
170  }
171 }
172 
173 /******************************************************************************/
174 
175 std::unique_ptr<Site> NonHomogeneousSequenceSimulator::simulateSite(size_t ancestralStateIndex, size_t rateClass) const
176 {
177  // Launch recursion:
178  SNode* root = tree_.getRootNode();
179  root->getInfos().state = ancestralStateIndex;
180  for (size_t i = 0; i < root->getNumberOfSons(); ++i)
181  {
182  evolveInternal(root->getSon(i), rateClass);
183  }
184  // Now create a Site object:
185  size_t n = nbNodes_ + 1;
187  {
188  n = leaves_.size();
189  }
190  Vint site(n);
191 
193  {
194  vector<SNode*> nodes = tree_.getNodes();
195  for (size_t i = 0; i < n; i++)
196  {
197  if (i == n - 1) // We take the model of node i-1 because the root has no model
198  {
199  site[i] = nodes[i - 1]->getInfos().model->getAlphabetStateAsInt(nodes[i]->getInfos().state);
200  }
201  else
202  {
203  site[i] = nodes[i]->getInfos().model->getAlphabetStateAsInt(nodes[i]->getInfos().state);
204  }
205  }
206  }
207  else
208  {
209  for (size_t i = 0; i < leaves_.size(); ++i)
210  {
211  site[i] = leaves_[i]->getInfos().model->getAlphabetStateAsInt(leaves_[i]->getInfos().state);
212  }
213  }
214  return make_unique<Site>(site, alphabet_);
215 }
216 
217 /******************************************************************************/
218 
219 std::unique_ptr<Site> NonHomogeneousSequenceSimulator::simulateSite(size_t ancestralStateIndex, double rate) const
220 {
221  // Launch recursion:
222  SNode* root = tree_.getRootNode();
223  root->getInfos().state = ancestralStateIndex;
224  for (size_t i = 0; i < root->getNumberOfSons(); i++)
225  {
226  evolveInternal(root->getSon(i), rate);
227  }
228  // Now create a Site object:
229  size_t n = nbNodes_ + 1;
231  {
232  n = leaves_.size();
233  }
234  Vint site(n);
235 
237  {
238  vector<SNode*> nodes = tree_.getNodes();
239  for (size_t i = 0; i < n; i++)
240  {
241  if (i == n - 1) // We take the model of node i-1 because the root has no model
242  {
243  site[i] = nodes[i - 1]->getInfos().model->getAlphabetStateAsInt(nodes[i]->getInfos().state);
244  }
245  else
246  {
247  site[i] = nodes[i]->getInfos().model->getAlphabetStateAsInt(nodes[i]->getInfos().state);
248  }
249  }
250  }
251  else
252  {
253  for (size_t i = 0; i < leaves_.size(); i++)
254  {
255  site[i] = leaves_[i]->getInfos().model->getAlphabetStateAsInt(leaves_[i]->getInfos().state);
256  }
257  }
258  return make_unique<Site>(site, alphabet_);
259 }
260 
261 /******************************************************************************/
262 
263 unique_ptr<Site> NonHomogeneousSequenceSimulator::simulateSite(double rate) const
264 {
265  // Draw an initial state randomly according to equilibrium frequencies:
266  size_t ancestralStateIndex = 0;
268  double cumprob = 0;
269  vector<double> freqs = modelSet_->getRootFrequencies();
270  for (size_t i = 0; i < nbStates_; i++)
271  {
272  cumprob += freqs[i];
273  if (r <= cumprob)
274  {
275  ancestralStateIndex = i;
276  break;
277  }
278  }
279  // Make this state evolve:
280  return simulateSite(ancestralStateIndex, rate);
281 }
282 
283 /******************************************************************************/
284 
285 unique_ptr<SiteContainerInterface> NonHomogeneousSequenceSimulator::simulate(size_t numberOfSites) const
286 {
287  vector<size_t> ancestralStateIndices(numberOfSites, 0);
288  for (size_t j = 0; j < numberOfSites; j++)
289  {
291  double cumprob = 0;
292  vector<double> freqs = modelSet_->getRootFrequencies();
293  for (size_t i = 0; i < nbStates_; i++)
294  {
295  cumprob += freqs[i];
296  if (r <= cumprob)
297  {
298  ancestralStateIndices[j] = i;
299  break;
300  }
301  }
302  }
303  if (continuousRates_)
304  {
305  auto sites = make_unique<VectorSiteContainer>(seqNames_.size(), alphabet_);
306  sites->setSequenceNames(seqNames_, true);
307  for (size_t j = 0; j < numberOfSites; j++)
308  {
309  auto site = simulateSite();
310  site->setCoordinate(static_cast<int>(j));
311  sites->addSite(site);
312  }
313  return sites;
314  }
315  else
316  {
317  // More efficient to do site this way:
318  // Draw random rates:
319  vector<size_t> rateClasses(numberOfSites);
320  size_t nCat = rate_->getNumberOfCategories();
321  for (size_t j = 0; j < numberOfSites; j++)
322  {
323  rateClasses[j] = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nCat);
324  }
325  // Make these states evolve:
326  return multipleEvolve(ancestralStateIndices, rateClasses);
327  }
328 }
329 
330 /******************************************************************************/
331 
332 std::unique_ptr<SiteSimulationResult> NonHomogeneousSequenceSimulator::dSimulateSite() const
333 {
334  // Draw an initial state randomly according to equilibrium frequencies:
335  size_t ancestralStateIndex = 0;
337  double cumprob = 0;
338  vector<double> freqs = modelSet_->getRootFrequencies();
339  for (size_t i = 0; i < nbStates_; i++)
340  {
341  cumprob += freqs[i];
342  if (r <= cumprob)
343  {
344  ancestralStateIndex = i;
345  break;
346  }
347  }
348 
349  return dSimulateSite(ancestralStateIndex);
350 }
351 
352 /******************************************************************************/
353 
354 std::unique_ptr<SiteSimulationResult> NonHomogeneousSequenceSimulator::dSimulateSite(size_t ancestralStateIndex) const
355 {
356  // Draw a random rate:
357  if (continuousRates_)
358  {
359  double rate = rate_->randC();
360  return dSimulateSite(ancestralStateIndex, rate);
361  }
362  else
363  {
364  size_t rateClass = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(rate_->getNumberOfCategories());
365  return dSimulateSite(ancestralStateIndex, rateClass);
366  // NB: this is more efficient than dSimulate(initialState, rDist_->rand())
367  }
368 }
369 
370 /******************************************************************************/
371 
372 unique_ptr<SiteSimulationResult> NonHomogeneousSequenceSimulator::dSimulateSite(size_t ancestralStateIndex, double rate) const
373 {
374  // Make this state evolve:
375  auto hssr = make_unique<RASiteSimulationResult>(phyloTree_, modelSet_->getStateMap(), ancestralStateIndex, rate);
376  dEvolve(ancestralStateIndex, rate, *hssr);
377  return std::move(hssr);
378 }
379 
380 /******************************************************************************/
381 
382 unique_ptr<SiteSimulationResult> NonHomogeneousSequenceSimulator::dSimulateSite(size_t ancestralStateIndex, size_t rateClass) const
383 {
384  return dSimulateSite(ancestralStateIndex, rate_->getCategory(rateClass));
385 }
386 
387 /******************************************************************************/
388 
389 unique_ptr<SiteSimulationResult> NonHomogeneousSequenceSimulator::dSimulateSite(double rate) const
390 {
391  // Draw an initial state randomly according to equilibrium frequencies:
392  size_t ancestralStateIndex = 0;
394  double cumprob = 0;
395  vector<double> freqs = modelSet_->getRootFrequencies();
396  for (size_t i = 0; i < nbStates_; i++)
397  {
398  cumprob += freqs[i];
399  if (r <= cumprob)
400  {
401  ancestralStateIndex = i;
402  break;
403  }
404  }
405  return dSimulateSite(ancestralStateIndex, rate);
406 }
407 
408 /******************************************************************************/
409 
410 size_t NonHomogeneousSequenceSimulator::evolve(const SNode* node, size_t initialStateIndex, size_t rateClass) const
411 {
412  const Vdouble* cumpxy_node_c_x_ = &node->getInfos().cumpxy[rateClass][initialStateIndex];
414  for (size_t y = 0; y < nbStates_; y++)
415  {
416  if (rand < (*cumpxy_node_c_x_)[y])
417  return y;
418  }
419  throw Exception("HomogeneousSequenceSimulator::evolve. The impossible happened! rand = " + TextTools::toString(rand) + ".");
420 }
421 
422 /******************************************************************************/
423 
424 size_t NonHomogeneousSequenceSimulator::evolve(const SNode* node, size_t initialStateIndex, double rate) const
425 {
426  double cumpxy = 0;
428  double l = rate * node->getDistanceToFather();
429  auto model = node->getInfos().model;
430  for (size_t y = 0; y < nbStates_; y++)
431  {
432  cumpxy += model->Pij_t(initialStateIndex, y, l);
433  if (rand < cumpxy)
434  return y;
435  }
436  MatrixTools::print(model->getPij_t(l));
437  throw Exception("HomogeneousSequenceSimulator::evolve. The impossible happened! rand = " + TextTools::toString(rand) + ".");
438 }
439 
440 /******************************************************************************/
441 
443  const SNode* node,
444  const std::vector<size_t>& initialStateIndices,
445  const vector<size_t>& rateClasses,
446  std::vector<size_t>& finalStateIndices) const
447 {
448  const VVVdouble* cumpxy_node_ = &node->getInfos().cumpxy;
449  for (size_t i = 0; i < initialStateIndices.size(); i++)
450  {
451  const Vdouble* cumpxy_node_c_x_ = &(*cumpxy_node_)[rateClasses[i]][initialStateIndices[i]];
453  for (size_t y = 0; y < nbStates_; y++)
454  {
455  if (rand < (*cumpxy_node_c_x_)[y])
456  {
457  finalStateIndices[i] = y;
458  break;
459  }
460  }
461  }
462 }
463 
464 /******************************************************************************/
465 
466 void NonHomogeneousSequenceSimulator::evolveInternal(SNode* node, size_t rateClass) const
467 {
468  if (!node->hasFather())
469  {
470  cerr << "DEBUG: NonHomogeneousSequenceSimulator::evolveInternal. Forbidden call of method on root node." << endl;
471  return;
472  }
473  node->getInfos().state = evolve(node, node->getFather()->getInfos().state, rateClass);
474  for (size_t i = 0; i < node->getNumberOfSons(); i++)
475  {
476  evolveInternal(node->getSon(i), rateClass);
477  }
478 }
479 
480 /******************************************************************************/
481 
483 {
484  if (!node->hasFather())
485  {
486  cerr << "DEBUG: NonHomogeneousSequenceSimulator::evolveInternal. Forbidden call of method on root node." << endl;
487  return;
488  }
489  node->getInfos().state = evolve(node, node->getFather()->getInfos().state, rate);
490  for (size_t i = 0; i < node->getNumberOfSons(); i++)
491  {
492  evolveInternal(node->getSon(i), rate);
493  }
494 }
495 
496 /******************************************************************************/
497 
498 void NonHomogeneousSequenceSimulator::multipleEvolveInternal(SNode* node, const vector<size_t>& rateClasses) const
499 {
500  if (!node->hasFather())
501  {
502  cerr << "DEBUG: NonHomogeneousSequenceSimulator::multipleEvolveInternal. Forbidden call of method on root node." << endl;
503  return;
504  }
505  const vector<size_t>* initialStates = &node->getFather()->getInfos().states;
506  size_t n = initialStates->size();
507  node->getInfos().states.resize(n); // allocation.
508  multipleEvolve(node, node->getFather()->getInfos().states, rateClasses, node->getInfos().states);
509  for (size_t i = 0; i < node->getNumberOfSons(); i++)
510  {
511  multipleEvolveInternal(node->getSon(i), rateClasses);
512  }
513 }
514 
515 /******************************************************************************/
516 
517 unique_ptr<SiteContainerInterface> NonHomogeneousSequenceSimulator::multipleEvolve(
518  const std::vector<size_t>& initialStateIndices,
519  const vector<size_t>& rateClasses) const
520 {
521  // Launch recursion:
522  SNode* root = tree_.getRootNode();
523  root->getInfos().states = initialStateIndices;
524  for (size_t i = 0; i < root->getNumberOfSons(); i++)
525  {
526  multipleEvolveInternal(root->getSon(i), rateClasses);
527  }
528  // Now create a SiteContainer object:
529  auto sites = make_unique<AlignedSequenceContainer>(alphabet_);
530  size_t nbSites = initialStateIndices.size();
531  shared_ptr<const TransitionModelInterface> model = nullptr;
533  {
534  vector<SNode*> nodes = tree_.getNodes();
535  size_t n = nbNodes_ + 1;
536  for (size_t i = 0; i < n; i++)
537  {
538  vector<int> content(nbSites);
539  vector<size_t>& states = nodes[i]->getInfos().states;
540  if (i == n - 1) // If at the root, there is no model, so we take the model of node n-1.
541  {
542  model = nodes[i - 1]->getInfos().model;
543  }
544  else
545  {
546  model = nodes[i]->getInfos().model;
547  }
548  for (size_t j = 0; j < nbSites; j++)
549  {
550  content[j] = model->getAlphabetStateAsInt(states[j]);
551  }
552  if (nodes[i]->isLeaf())
553  {
554  auto seq = make_unique<Sequence>(nodes[i]->getName(), content, alphabet_);
555  sites->addSequence(nodes[i]->getName(), seq);
556  }
557  else
558  {
559  auto seq = make_unique<Sequence>(TextTools::toString(nodes[i]->getId()), content, alphabet_);
560  sites->addSequence(TextTools::toString(nodes[i]->getId()), seq);
561  }
562  }
563  }
564  else
565  {
566  size_t n = leaves_.size();
567  for (size_t i = 0; i < n; i++)
568  {
569  vector<int> content(nbSites);
570  vector<size_t>& states = leaves_[i]->getInfos().states;
571  model = leaves_[i]->getInfos().model;
572  for (size_t j = 0; j < nbSites; j++)
573  {
574  content[j] = model->getAlphabetStateAsInt(states[j]);
575  }
576  auto seq = make_unique<Sequence>(leaves_[i]->getName(), content, alphabet_);
577  sites->addSequence(leaves_[i]->getName(), seq);
578  }
579  }
580  return std::move(sites);
581 }
582 
583 /******************************************************************************/
584 
585 void NonHomogeneousSequenceSimulator::dEvolve(size_t initialState, double rate, RASiteSimulationResult& rassr) const
586 {
587  // Launch recursion:
588  SNode* root = tree_.getRootNode();
589  root->getInfos().state = initialState;
590  for (size_t i = 0; i < root->getNumberOfSons(); i++)
591  {
592  dEvolveInternal(root->getSon(i), rate, rassr);
593  }
594 }
595 
596 /******************************************************************************/
597 
599 {
600  if (!node->hasFather())
601  {
602  cerr << "DEBUG: NonHomogeneousSequenceSimulator::evolveInternal. Forbidden call of method on root node." << endl;
603  return;
604  }
605  auto tm = node->getInfos().model;
606  if (!dynamic_pointer_cast<const SubstitutionModelInterface>(tm))
607  throw Exception("NonHomogeneousSequenceSimulator::dEvolveInternal : detailed simulation not possible for non-markovian model");
608 
609  SimpleMutationProcess process(dynamic_pointer_cast<const SubstitutionModelInterface>(tm));
610 
611  MutationPath mp = process.detailedEvolve(node->getFather()->getInfos().state, node->getDistanceToFather() * rate);
612  node->getInfos().state = mp.getFinalState();
613 
614  // Now append infos in rassr:
615  rassr.addNode(static_cast<unsigned int>(node->getId()), mp);
616 
617  // Now jump to son nodes:
618  for (size_t i = 0; i < node->getNumberOfSons(); i++)
619  {
620  dEvolveInternal(node->getSon(i), rate, rassr);
621  }
622 }
623 
624 /******************************************************************************/
625 
627 {
630  {
631  vector<SNode*> nodes = tree_.getNodes();
632  seqNames_.resize(nodes.size());
633  for (size_t i = 0; i < seqNames_.size(); i++)
634  {
635  if (nodes[i]->isLeaf())
636  {
637  seqNames_[i] = nodes[i]->getName();
638  }
639  else
640  {
641  seqNames_[i] = TextTools::toString( nodes[i]->getId() );
642  }
643  }
644  }
645  else
646  {
647  seqNames_.resize(leaves_.size());
648  for (size_t i = 0; i < seqNames_.size(); i++)
649  {
650  seqNames_[i] = leaves_[i]->getName();
651  }
652  }
653 }
654 
655 /******************************************************************************/
MutationPath detailedEvolve(size_t initialState, double time) const
Simulation a character evolution during a specified time according to the given substitution model an...
static void print(const Matrix &m, std::ostream &out=std::cout)
This class is used by MutationProcess to store detailed results of simulations.
size_t getFinalState() const
Retrieve the final state of this path.
The NodeTemplate class.
Definition: NodeTemplate.h:39
const NodeTemplate< NodeInfos > * getSon(size_t i) const
Definition: NodeTemplate.h:108
const NodeTemplate< NodeInfos > * getFather() const
Get the father of this node is there is one.
Definition: NodeTemplate.h:102
virtual const NodeInfos & getInfos() const
Definition: NodeTemplate.h:144
virtual int getId() const
Get the node's id.
Definition: Node.h:170
virtual bool hasFather() const
Tell if this node has a father node.
Definition: Node.h:346
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
virtual size_t getNumberOfSons() const
Definition: Node.h:355
std::shared_ptr< const SubstitutionModelSet > modelSet_
std::unique_ptr< SiteContainerInterface > simulate(size_t numberOfSites) const override
std::shared_ptr< const DiscreteDistributionInterface > rate_
void multipleEvolve(const SNode *node, const std::vector< size_t > &initialStateIndices, const std::vector< size_t > &rateClasses, std::vector< size_t > &finalStates) const
The same as the evolve(initialState, rateClass) function, but for several sites at a time.
std::unique_ptr< Site > simulateSite() const override
void outputInternalSequences(bool yn) override
Sets whether we will output the internal sequences or not.
void multipleEvolveInternal(SNode *node, const std::vector< size_t > &rateClasses) const
const Tree & tree() const
Get the tree associated to this instance.
std::vector< SNode * > leaves_
This stores once for all all leaves in a given order. This order will be used during site creation.
void dEvolve(size_t initialState, double rate, RASiteSimulationResult &rassr) const
void dEvolveInternal(SNode *node, double rate, RASiteSimulationResult &rassr) const
NonHomogeneousSequenceSimulator(std::shared_ptr< const SubstitutionModelSet > modelSet, std::shared_ptr< const DiscreteDistributionInterface > rate, std::shared_ptr< const Tree > tree)
size_t evolve(const SNode *node, size_t initialStateIndex, size_t rateClass) const
Evolve from an initial state along a branch, knowing the evolutionary rate class.
std::unique_ptr< SiteSimulationResult > dSimulateSite() const override
Get a detailed simulation result for one site.
std::shared_ptr< const ParametrizablePhyloTree > phyloTree_
void evolveInternal(SNode *node, size_t rateClass) const
PhyloTree with Parametrizable Phylo Branches. They SHARE their branch length parameters.
Generic utilitary methods dealing with trees.
Data structure to store the result of a DetailedSiteSimulator.
static double giveRandomNumberBetweenZeroAndEntry(double entry)
Generally used mutation process model.
virtual void addNode(unsigned int nodeId, MutationPath path)
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.
std::string toString(T t)
Defines the basic types of data flow nodes.
std::vector< double > Vdouble
std::vector< int > Vint
std::vector< VVdouble > VVVdouble
std::vector< Vdouble > VVdouble