bpp-phyl3  3.0.0
ProcessTree.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
9 
10 #include "Model.h"
11 #include "Parametrizable.h"
12 #include "ProcessTree.h"
13 
14 // From the stl:
15 #include <string>
16 
17 using namespace bpp;
18 using namespace std;
19 
21  const ParametrizablePhyloTree& tree) :
23  context_(context)
24 {
25  // Set Nodes
26  auto vNodes = tree.getAllNodes();
27 
28  for (const auto& node:vNodes)
29  {
30  uint index = tree.getNodeIndex(node);
31  auto pn = make_shared<ProcessNode>(*node, index);
32  associateNode(pn, tree.getNodeGraphid(node));
33  setNodeIndex(pn, index);
34  }
35 
36  // Set Edges
37 
38  std::vector<std::shared_ptr<PhyloBranchParam>> vB = tree.getAllEdges();
39 
40  for (auto& branch:vB)
41  {
42  const auto& bp = branch->getParameters()[0]; // Get BrLen Parameter
43 
44  auto parDF = ConfiguredParameter::create(context, bp);
45  auto index = tree.getEdgeIndex(branch);
46  auto brref = make_shared<ProcessEdge>(index, parDF, nullptr);
47 
48  associateEdge(brref, tree.getEdgeGraphid(branch));
49  setEdgeIndex(brref, index);
50  }
51 }
52 
54  ValueRef<double> rate) :
56 {
57  // Adjust Edges
58  auto aEit = allEdgesIterator();
59 
60  while (!aEit->end())
61  {
62  auto edge = **aEit;
63 
64  if (edge->getBrLen())
65  {
66  auto mulref = CWiseMul<double, std::tuple<double, double>>::create (context_, {edge->getBrLen()->dependency(0), rate}, Dimension<double>());
67  auto confpar = std::dynamic_pointer_cast<ConfiguredParameter>(edge->getBrLen()->recreate(context_, {std::move(mulref)}));
68  edge->setBrLen(confpar);
69  }
70  aEit->next();
71  }
72 }
73 
75  const ParametrizablePhyloTree& tree,
76  const ParameterList& parList,
77  const std::string& suff) :
79  context_(context)
80 {
81  // Set Nodes
82  auto vNodes = tree.getAllNodes();
83 
84  for (const auto& node:vNodes)
85  {
86  uint index = tree.getNodeIndex(node);
87  auto pn = make_shared<ProcessNode>(*node, index);
88  associateNode(pn, tree.getNodeGraphid(node));
89  setNodeIndex(pn, index);
90  }
91 
92  // Set Edges
93 
94  std::vector<std::shared_ptr<PhyloBranchParam>> vB = tree.getAllEdges();
95 
96  for (auto& branch:vB)
97  {
98  const auto& bp = branch->getParameters()[0]; // Get BrLen Parameter
99 
100  std::string name = bp.getName() + suff;
101  if (!parList.hasParameter(name) && suff == "")
102  {
103  if (!parList.hasParameter(bp.getName() + "_1"))
104  throw Exception("makeTreeNode: unknown ConfiguredParameter " + name);
105  else
106  name = bp.getName() + "_1";
107  }
108 
109  auto confPar = dynamic_cast<ConfiguredParameter*>(parList.getParameter(name).get());
110  if (!confPar)
111  throw Exception("ProcessTree::ProcessTree: unknown ConfiguredParameter " + name);
112 
113  // Share numeric dependency with this parameter
114  auto parDF = ConfiguredParameter::create(context, {confPar->dependency(0)}, bp);
115  auto index = tree.getEdgeIndex(branch);
116  auto brref = make_shared<ProcessEdge>(index, parDF, nullptr);
117 
118  associateEdge(brref, tree.getEdgeGraphid(branch));
119  setEdgeIndex(brref, index);
120  }
121 }
122 
125  const ProcessTree& phyloTree) :
126  AssociationTreeGlobalGraphObserver<ProcessNode, ProcessEdge>(tree.getGraph()), context_(phyloTree.context_)
127 {
128  // Set Nodes
129  auto vNodes = tree.getAllNodes();
130 
131  for (const auto& node:vNodes)
132  {
133  auto pn = make_shared<ProcessNode>(*node);
134  associateNode(pn, tree.getNodeGraphid(node));
135  setNodeIndex(pn, tree.getNodeIndex(node));
136  }
137 
138  // Assign References on all branches
139 
140  auto vEdges = tree.getAllEdges();
141 
142  for (const auto& edge:vEdges)
143  {
144  std::shared_ptr<ProcessEdge> brref;
145 
146  auto id = tree.getEdgeGraphid(edge);
147  uint spIndex = edge->getSpeciesIndex(); // index of the matching
148  // edge in the
149  // ParametrizablePhyloTree
150 
151  auto model = edge->getModel();
152  if (!model) // ie empty branch
153  {
154  brref = make_shared<ProcessEdge>(spIndex, nullptr);
155  associateEdge(brref, id);
156  setEdgeIndex(brref, tree.getEdgeIndex(edge));
157  continue;
158  }
159 
160  if (!modelColl.hasObject(edge->getModelNumber()))
161  throw Exception("ProcessTree::ProcessTree : Model unknown " + model->getName() + " for node " + TextTools::toString(spIndex));
162 
163  std::shared_ptr<ConfiguredModel> pmodel = dynamic_pointer_cast<ConfiguredModel>(modelColl[edge->getModelNumber()]);
164 
165  auto vNb = edge->subModelNumbers();
166  if (vNb.size() > 1)
167  throw Exception("ProcessTree::ProcessTree : only simple submodels are used, not combinations. Ask developers");
168 
169  if (!edge->useProb()) // model transition is used
170  {
171  if (!phyloTree.hasEdge(spIndex)) // ie there is no branch length
172  throw Exception("ProcessTree::ProcessTree missing branch length for branch " + TextTools::toString(spIndex));
173 
174  auto edge2 = phyloTree.getEdge(spIndex);
175  if (vNb.size() == 0) // ie full model
176  brref = make_shared<ProcessEdge>(spIndex, edge2->getBrLen(), pmodel);
177  else
178  {
179  auto nMod = NumericConstant<size_t>::create(context_, vNb[0]); // Only 1st submodel is used
180  brref = make_shared<ProcessEdge>(spIndex, edge2->getBrLen(), pmodel, nMod);
181  }
182  }
183  else // a branch issued from a mixture.
184  {
185  if (vNb.size() == 0)
186  brref = make_shared<ProcessEdge>(spIndex, ConstantOne<double>::create (context_, Dimension<double>()));
187  else
188  {
189  auto nMod = NumericConstant<size_t>::create(context_, (size_t)vNb[0]); // Only 1st submodel is used
190  auto brprob = ProbabilityFromMixedModel::create(context_, {pmodel}, (size_t)vNb[0]);
191  brref = make_shared<ProcessEdge>(spIndex, brprob);
192  }
193  }
194 
195  associateEdge(brref, id);
196  setEdgeIndex(brref, tree.getEdgeIndex(edge));
197  }
198 }
199 
200 
201 std::shared_ptr<ProcessTree> ProcessTree::makeProcessTree(CollectionNodes& collection, size_t pNum)
202 {
203  auto process = collection.collection().getSubstitutionProcess(pNum);
204 
205  auto& pt = *collection.getProcessTree(process->getTreeNumber());
206 
207  ProcessComputationTree tree(process);
208 
209  // then process tree with DF objects
210 
211  return std::make_shared<ProcessTree>(tree, collection.getModelCollection(), pt);
212 }
213 
214 std::shared_ptr<ProcessTree> ProcessTree::makeProcessTree(
215  Context& context,
216  std::shared_ptr<const SubstitutionProcessInterface> process,
217  ParameterList& parList,
218  const std::string& suff)
219 {
220  auto parTree = process->getParametrizablePhyloTree();
221 
222  if (!parTree)
223  throw Exception("ProcessTree::makeProcessTree: missing Tree in process.");
224 
225  auto modelColl = makeConfiguredModelCollection(context, *process, parList);
226 
227  ProcessTree pt(context, *parTree, parList, suff); // tree with only branches
228 
229  ProcessComputationTree tree(process);
230 
231  // then process tree with DF objects
232 
233  return std::make_shared<ProcessTree>(tree, modelColl, pt);
234 }
235 
237 {
238  auto vB = getAllEdges();
239 
240  DAGindexes dag;
241  for (auto& branch:vB)
242  {
243  if (branch->getSpeciesIndex() == speciesIndex)
244  dag.push_back(getEdgeIndex(branch));
245  }
246 
247  return dag;
248 }
virtual std::unique_ptr< EdgeIterator > allEdgesIterator()=0
virtual NodeGraphid getNodeGraphid(const std::shared_ptr< N > nodeObject) const=0
virtual std::vector< std::shared_ptr< E > > getAllEdges() const=0
virtual NodeIndex setNodeIndex(const std::shared_ptr< N > nodeObject, NodeIndex index)=0
virtual void associateNode(std::shared_ptr< N > nodeObject, NodeGraphid node)=0
virtual EdgeIndex getEdgeIndex(const std::shared_ptr< E > edgeObject) const=0
virtual EdgeGraphid getEdgeGraphid(const std::shared_ptr< E > edgeObject) const=0
virtual std::vector< std::shared_ptr< N > > getAllNodes() const=0
virtual EdgeIndex setEdgeIndex(const std::shared_ptr< E > edgeObject, EdgeIndex index)=0
virtual NodeIndex getNodeIndex(const std::shared_ptr< N > nodeObject) const=0
virtual std::shared_ptr< E > getEdge(EdgeIndex edgeIndex) const=0
virtual bool hasEdge(EdgeIndex edgeIndex) const=0
virtual void associateEdge(std::shared_ptr< E > edgeObject, EdgeGraphid edge)=0
ParametrizableCollection< ConfiguredModel > & getModelCollection()
const SubstitutionProcessCollection & collection() const
std::shared_ptr< ProcessTree > getProcessTree(size_t treeIndex)
Data flow node representing a parameter.
Definition: Parameter.h:27
static std::shared_ptr< Self > create(Context &c, NodeRefVec &&deps, const Parameter &param)
Build a new ConfiguredParameter node.
Definition: Parameter.h:36
r = 1 for each component.
Context for dataflow node construction.
Definition: DataFlow.h:527
static std::shared_ptr< Self > create(Context &c, Args &&... args)
Build a new NumericConstant node with T(args...) value.
virtual bool hasParameter(const std::string &name) const
virtual const std::shared_ptr< Parameter > & getParameter(size_t i) const
bool hasObject(size_t objectIndex) const
PhyloTree with Parametrizable Phylo Branches. They SHARE their branch length parameters.
static std::shared_ptr< Self > create(Context &c, NodeRefVec &&deps, size_t nCat)
Definition: Model.cpp:437
Tree Organization of Computing Nodes.
static std::shared_ptr< ProcessTree > makeProcessTree(Context &context, std::shared_ptr< const SubstitutionProcessInterface > process, ParameterList &parList, const std::string &suff="")
Create a Process Tree following a Substitution Process. Tree Node parameters are got from ConfiguredP...
ProcessTree(Context &context, const ParametrizablePhyloTree &tree)
Build a ProcessTree with same topology as a given ParametrizablePhyloTree, and new ConfiguredParamete...
Definition: ProcessTree.cpp:20
DAGindexes getDAGEdgesIndexes(const Speciesindex speciesIndex) const
std::shared_ptr< SubstitutionProcessCollectionMember > getSubstitutionProcess(size_t i)
std::string toString(T t)
Defines the basic types of data flow nodes.
std::shared_ptr< Value< T > > ValueRef
Shared pointer alias for Value<T>.
Definition: DataFlow.h:84
std::vector< uint > DAGindexes
Helper: create a map with mutable dataflow nodes for each branch of the tree. The map is indexed by b...
ParametrizableCollection< ConfiguredModel > makeConfiguredModelCollection(Context &context, const SubstitutionProcessInterface &process, ParameterList &parList)
Make a Collection of ConfiguredModel, from the models described in the SubstitutionProcess,...
Definition: ProcessTree.h:262
uint Speciesindex
Specialisation of Dimension<T> for floating point types.