Belle II Software  release-08-01-10
VariableFormulaConstructor.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <analysis/VariableManager/Manager.h>
10 #include <framework/utilities/FormulaParser.h>
11 
12 namespace Belle2 {
26  type operator()(const std::string& name)
27  {
28  auto var = Variable::Manager::Instance().getVariable(name);
29  if (!var) throw std::runtime_error("Could not find " + name + " via the Variable::Manager. Check the name");
30  return var->function;
31  }
32 
34  type operator()(double value)
35  {
36  return [value](const Particle*) { return value; };
37  }
38 
40  type operator()(Op op, const type& a, const type& b)
41  {
42  return [op, a, b](const Particle * p) {
43  switch (op) {
44  case Op::c_plus:
45  try {
46  return std::get<double>(a(p)) + std::get<double>(b(p));
47  } catch (std::bad_variant_access&) {
48  try {
49  return std::get<double>(a(p)) + std::get<int>(b(p));
50  } catch (std::bad_variant_access&) {
51  try {
52  return std::get<int>(a(p)) + std::get<double>(b(p));
53  } catch (std::bad_variant_access&) {
54  return double(std::get<int>(a(p)) + std::get<int>(b(p)));
55  }
56  }
57  }
58  case Op::c_minus:
59  try {
60  return std::get<double>(a(p)) - std::get<double>(b(p));
61  } catch (std::bad_variant_access&) {
62  try {
63  return std::get<double>(a(p)) - std::get<int>(b(p));
64  } catch (std::bad_variant_access&) {
65  try {
66  return std::get<int>(a(p)) - std::get<double>(b(p));
67  } catch (std::bad_variant_access&) {
68  return double(std::get<int>(a(p)) - std::get<int>(b(p)));
69  }
70  }
71  }
72  case Op::c_multiply:
73  try {
74  return std::get<double>(a(p)) * std::get<double>(b(p));
75  } catch (std::bad_variant_access&) {
76  try {
77  return std::get<double>(a(p)) * std::get<int>(b(p));
78  } catch (std::bad_variant_access&) {
79  try {
80  return std::get<int>(a(p)) * std::get<double>(b(p));
81  } catch (std::bad_variant_access&) {
82  return double(std::get<int>(a(p)) * std::get<int>(b(p)));
83  }
84  }
85  }
86  case Op::c_divide:
87  try {
88  return std::get<double>(a(p)) / std::get<double>(b(p));
89  } catch (std::bad_variant_access&) {
90  try {
91  return std::get<double>(a(p)) / std::get<int>(b(p));
92  } catch (std::bad_variant_access&) {
93  try {
94  return std::get<int>(a(p)) / std::get<double>(b(p));
95  } catch (std::bad_variant_access&) {
96  return double(std::get<int>(a(p)) / std::get<int>(b(p)));
97  }
98  }
99  }
100  case Op::c_power:
101  try {
102  return std::pow(std::get<double>(a(p)), std::get<double>(b(p)));
103  } catch (std::bad_variant_access&) {
104  try {
105  return std::pow(std::get<double>(a(p)), std::get<int>(b(p)));
106  } catch (std::bad_variant_access&) {
107  try {
108  return std::pow(std::get<int>(a(p)), std::get<double>(b(p)));
109  } catch (std::bad_variant_access&) {
110  return std::pow(std::get<int>(a(p)), std::get<int>(b(p)));
111  }
112  }
113  }
114  default: break;
115  }
116  throw std::runtime_error("Cannot handle operator " + std::to_string((int)op));
117  };
118  }
119 
121  type operator()(Op op, double& a, const type& b)
122  {
123  return [op, a, b](const Particle * p) {
124  switch (op) {
125  case Op::c_plus:
126  try {
127  return a + std::get<double>(b(p));
128  } catch (std::bad_variant_access&) {
129  try {
130  return a + std::get<int>(b(p));
131  } catch (std::bad_variant_access&) {
132  return a + std::get<bool>(b(p));
133  }
134  }
135  case Op::c_minus:
136  try {
137  return a - std::get<double>(b(p));
138  } catch (std::bad_variant_access&) {
139  try {
140  return a - std::get<int>(b(p));
141  } catch (std::bad_variant_access&) {
142  return a - std::get<bool>(b(p));
143  }
144  }
145  case Op::c_multiply:
146  try {
147  return a * std::get<double>(b(p));
148  } catch (std::bad_variant_access&) {
149  try {
150  return a * std::get<int>(b(p));
151  } catch (std::bad_variant_access&) {
152  return a * std::get<bool>(b(p));
153  }
154  }
155  case Op::c_divide:
156  try {
157  return a / std::get<double>(b(p));
158  } catch (std::bad_variant_access&) {
159  try {
160  return a / std::get<int>(b(p));
161  } catch (std::bad_variant_access&) {
162  return a / std::get<bool>(b(p));
163  }
164  }
165  case Op::c_power:
166  try {
167  return std::pow(a, std::get<double>(b(p)));
168  } catch (std::bad_variant_access&) {
169  try {
170  return std::pow(a, std::get<int>(b(p)));
171  } catch (std::bad_variant_access&) {
172  return std::pow(a, std::get<bool>(b(p)));
173  }
174  }
175  default: break;
176  }
177  throw std::runtime_error("Cannot handle operator " + std::to_string((int)op));
178  };
179  }
180 
182  type operator()(Op op, const type& a, double b)
183  {
184  return [op, a, b](const Particle * p) {
185  switch (op) {
186  case Op::c_plus:
187  try {
188  return std::get<double>(a(p)) + b;
189  } catch (std::bad_variant_access&) {
190  try {
191  return std::get<int>(a(p)) + b;
192  } catch (std::bad_variant_access&) {
193  return std::get<bool>(a(p)) + b;
194  }
195  }
196  case Op::c_minus:
197  try {
198  return std::get<double>(a(p)) - b;
199  } catch (std::bad_variant_access&) {
200  try {
201  return std::get<int>(a(p)) - b;
202  } catch (std::bad_variant_access&) {
203  return std::get<bool>(a(p)) - b;
204  }
205  }
206  case Op::c_multiply:
207  try {
208  return std::get<double>(a(p)) * b;
209  } catch (std::bad_variant_access&) {
210  try {
211  return std::get<int>(a(p)) * b;
212  } catch (std::bad_variant_access&) {
213  return std::get<bool>(a(p)) * b;
214  }
215  }
216  case Op::c_divide:
217  try {
218  return std::get<double>(a(p)) / b;
219  } catch (std::bad_variant_access&) {
220  try {
221  return std::get<int>(a(p)) / b;
222  } catch (std::bad_variant_access&) {
223  return std::get<bool>(a(p)) / b;
224  }
225  }
226  case Op::c_power:
227  try {
228  return std::pow(std::get<double>(a(p)), b);
229  } catch (std::bad_variant_access&) {
230  try {
231  return std::pow(std::get<int>(a(p)), b);
232  } catch (std::bad_variant_access&) {
233  return std::pow(std::get<bool>(a(p)), b);
234  }
235  }
236  default: break;
237  }
238  throw std::runtime_error("Cannot handle operator " + std::to_string((int)op));
239  };
240  }
241  };
243 }
EOperator
List of known operators.
Definition: FormulaParser.h:31
Class to store reconstructed particles.
Definition: Particle.h:75
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
Definition: Manager.h:113
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
Definition: Manager.cc:57
static Manager & Instance()
get singleton instance.
Definition: Manager.cc:25
Abstract base class for different kinds of events.
Struct to construct new variable function objects from a name or a double value or to apply operation...
type operator()(Op op, const type &a, double b)
Apply operator on a variable and a double.
FormulaParserBase::EOperator Op
Shorthand for the operator enum.
type operator()(Op op, const type &a, const type &b)
Apply operator on two variables.
type operator()(Op op, double &a, const type &b)
Apply operator on a double and a variable.
type operator()(const std::string &name)
Construct a variable from a given name.
type operator()(double value)
Construct a variable from a double value.
Variable::Manager::FunctionPtr type
Return value we want for the FormulaParser::parse.