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
17using namespace bpp;
18using namespace std;
19
20ProcessTree::ProcessTree(Context& context,
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
201std::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
214std::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()
std::shared_ptr< ProcessTree > getProcessTree(size_t treeIndex)
const SubstitutionProcessCollection & collection() const
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...
uint Speciesindex
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
Specialisation of Dimension<T> for floating point types.