ComPWA
Common Partial-Wave-Analysis Framework
TreeNode.cpp
Go to the documentation of this file.
1 // Copyright (c) 2013 The ComPWA Team.
2 // This file is part of the ComPWA framework, check
3 // https://github.com/ComPWA/ComPWA/license.txt for details.
4 
5 #include <complex>
6 #include <memory>
7 #include <string>
8 
9 #include "Functions.hpp"
10 #include "TreeNode.hpp"
11 
12 namespace ComPWA {
13 namespace FunctionTree {
14 
15 TreeNode::TreeNode(std::shared_ptr<Strategy> strategy)
16  : OutputParameter(nullptr), HasChanged(true), Strat(strategy) {
17  if (!strategy)
18  throw std::runtime_error("TreeNode::TreeNode() | No strategy given!");
19 }
20 
21 TreeNode::TreeNode(std::shared_ptr<Parameter> parameter,
22  std::shared_ptr<Strategy> strategy)
23  : OutputParameter(parameter), HasChanged(false), Strat(strategy) {
24  if (!parameter)
25  throw std::runtime_error(
26  "TreeNode::TreeNode() | No output parameter given!");
27  if (strategy) {
28  // if a strategy is given its no leaf
29  HasChanged = true;
30  }
31 }
32 
34  for (auto x : ChildNodes) {
35  x->removeExpiredParents();
36  }
37  if (0 == ChildNodes.size()) { // if leaf
38  OutputParameter->detachExpired();
39  }
40 }
41 
43  Parents.erase(std::remove_if(Parents.begin(), Parents.end(),
44  [](auto x) { return x.expired(); }),
45  Parents.end());
46 }
47 
48 void TreeNode::addNode(std::shared_ptr<TreeNode> node) {
49  node->addParent(shared_from_this());
50  ChildNodes.push_back(node);
51 }
52 
53 void TreeNode::addNodes(std::vector<std::shared_ptr<TreeNode>> nodes) {
54  auto ThisNode = shared_from_this();
55  for (auto node : nodes) {
56  node->addParent(ThisNode);
57  ChildNodes.push_back(node);
58  }
59 }
60 
61 void TreeNode::addParent(std::weak_ptr<TreeNode> node) {
62  Parents.push_back(node);
63 }
64 
66  for (auto x : Parents)
67  x.lock()->update();
68  HasChanged = true;
69 };
70 
71 std::shared_ptr<Parameter> TreeNode::parameter() {
72  if (!OutputParameter && 0 == ChildNodes.size())
73  throw std::runtime_error("TreeNode::parameter() | Caching is disabled but "
74  "Node is a lead node!");
75 
76  // has been changed or is lead node -> return Parameter
77  if (OutputParameter && (!HasChanged || !ChildNodes.size()))
78  return OutputParameter;
79 
80  auto result = recalculate();
81 
82  if (OutputParameter) {
83  OutputParameter = result;
84  HasChanged = false;
85  }
86 
87  return result;
88 }
89 
90 std::shared_ptr<Parameter> TreeNode::recalculate() {
91  // has been changed or is leaf node -> return Parameter
92  if (OutputParameter && (!HasChanged || 0 == ChildNodes.size()))
93  return OutputParameter;
94 
95  std::shared_ptr<Parameter> result;
96  if (OutputParameter)
97  result = OutputParameter;
98 
99  ParameterList newVals;
100  for (auto ch : ChildNodes) {
101  auto p = ch->parameter();
102  if (p->isParameter())
103  newVals.addParameter(p);
104  else
105  newVals.addValue(p);
106  }
107  try {
108  Strat->execute(newVals, result);
109  } catch (std::exception &ex) {
110  LOG(INFO) << "TreeNode::Recalculate() | Strategy " << Strat
111  << " failed with input ParameterList:\n"
112  << newVals << ": " << ex.what();
113  throw;
114  }
115 
116  return result;
117 }
118 
120  for (auto ch : ChildNodes) {
121  ch->fillParameters(list);
122  }
123  list.addParameter(parameter());
124 }
125 
126 std::string TreeNode::print(int level, std::string prefix) {
127  std::stringstream oss;
128  oss << prefix;
129 
130  auto p = recalculate();
131  if (!ChildNodes.size()) { // Print leaf nodes
132  if (p->name() != "")
133  oss << "[" << p->name() << "]";
134  oss << " = " << p->val_to_str() << std::endl;
135  } else { // Print non-leaf nodes
136  oss << Strat->str() << " [";
137  if (!OutputParameter)
138  oss << "-, ";
139  oss << ChildNodes.size() << "]";
141  oss << " = ?";
142  else
143  oss << " = " << p->val_to_str() << std::endl;
144  }
145 
146  // Abort recursion
147  if (level == 0)
148  return oss.str();
149 
150  for (auto ch : ChildNodes) {
151  oss << ch->print(level - 1, prefix + ". ");
152  }
153  return oss.str();
154 }
155 
156 std::shared_ptr<TreeNode> createLeaf(std::shared_ptr<Parameter> parameter) {
157  auto leaf = std::make_shared<TreeNode>(parameter);
158  parameter->attach(leaf);
159  return leaf;
160 }
161 
162 } // namespace FunctionTree
163 } // namespace ComPWA
virtual void addValue(std::shared_ptr< Parameter > value)
void fillParameters(ParameterList &list)
Fill ParameterList with parameters.
Definition: TreeNode.cpp:119
bool HasChanged
Node has changed and needs to call recalculate()
Definition: TreeNode.hpp:86
std::string print(int level=-1, std::string prefix="")
Print node and its child nodes to std::string.
Definition: TreeNode.cpp:126
std::shared_ptr< Parameter > parameter()
Obtain parameter of node.
Definition: TreeNode.cpp:71
TreeNode(std::shared_ptr< Strategy > strategy)
Constructor for tree using a strategy.
Definition: TreeNode.cpp:15
virtual void addParameter(std::shared_ptr< Parameter > par)
std::shared_ptr< Strategy > Strat
Node strategy.
Definition: TreeNode.hpp:90
This file contains Functions implementing the Strategy interface so they can be used inside a node of...
std::shared_ptr< ComPWA::FunctionTree::Parameter > OutputParameter
(cached) node value
Definition: TreeNode.hpp:83
void addNode(std::shared_ptr< TreeNode > node)
Definition: TreeNode.cpp:48
std::vector< std::weak_ptr< TreeNode > > Parents
List of parent nodes.
Definition: TreeNode.hpp:77
std::shared_ptr< TreeNode > createLeaf(std::shared_ptr< Parameter > parameter)
Definition: TreeNode.cpp:156
void addParent(std::weak_ptr< TreeNode > node)
Definition: TreeNode.cpp:61
std::vector< std::shared_ptr< TreeNode > > ChildNodes
Definition: TreeNode.hpp:80
TreeNode class.
void addNodes(std::vector< std::shared_ptr< TreeNode >> nodes)
Definition: TreeNode.cpp:53
std::shared_ptr< ComPWA::FunctionTree::Parameter > recalculate()
Obtain parameter of node.
Definition: TreeNode.cpp:90
This class provides a list of parameters and values of different types.
void update()
Flags the node as modified. Should only be called from its child nodes.
Definition: TreeNode.cpp:65