Belle II Software development
NodeFactory Class Reference

Wrapper class for static node compile functions. More...

#include <NodeFactory.h>

Static Public Member Functions

template<class AVariableManager >
static std::unique_ptr< const AbstractBooleanNode< AVariableManager > > compile_boolean_node (Nodetuple tuple)
 This template function creates a boolean node from a boost::python::tuple The Python Parser encodes the node type as int as the first argument of each tuple.
 
template<class AVariableManager >
static std::unique_ptr< const AbstractExpressionNode< AVariableManager > > compile_expression_node (Nodetuple tuple)
 This template function creates a ExpressionNode from a boost::python::tuple The Python Parser encodes the node type as int in the first argument of each tuple.
 

Detailed Description

Wrapper class for static node compile functions.

Definition at line 64 of file NodeFactory.h.

Member Function Documentation

◆ compile_boolean_node()

static std::unique_ptr< const AbstractBooleanNode< AVariableManager > > compile_boolean_node ( Nodetuple  tuple)
inlinestatic

This template function creates a boolean node from a boost::python::tuple The Python Parser encodes the node type as int as the first argument of each tuple.

Node types are decoded via the NodeType enum defined in framework/utilities/include/AbstractNodes.h e.g (2, (11, True)) is a UnaryRelationalNode (nodetype value 2), which has a BooleanNode(nodetype value 11) as a child. List of Nodes:

Definition at line 80 of file NodeFactory.h.

81 {
82 if (py::len(tuple) == 0) B2FATAL("BooleanNode tuple is empty, this is invalid.");
83 // First argument of every NodeTuple is an integer indicating the NodeType
84 NodeType node_type = static_cast<NodeType>(static_cast<int>(py::extract<int>(tuple[0])));
85
86 if (node_type == NodeType::UnaryBooleanNode) {
87 // Extract first child tuple
88 if (py::len(tuple) != 4) B2FATAL("UnaryBooleanNode tuple has to have length 4." << LogVar("actual length", py::len(tuple)));
89 Nodetuple child = static_cast<const py::tuple>(tuple[1]);
90 bool negation = py::extract<bool>(tuple[2]);
91 bool bracketized = py::extract<bool>(tuple[3]);
92 return std::unique_ptr<const AbstractBooleanNode<AVariableManager>>(new UnaryBooleanNode<AVariableManager>(child, negation,
93 bracketized));
94
95 } else if (node_type == NodeType::BinaryBooleanNode) {
96 if (py::len(tuple) != 4) B2FATAL("BinaryBooleanNode tuple has to have length 4." << LogVar("actual length", py::len(tuple)));
97 Nodetuple left_node = static_cast<const py::tuple>(tuple[1]);
98 Nodetuple right_node = static_cast<const py::tuple>(tuple[2]);
99 BooleanOperator boperator = static_cast<BooleanOperator>(static_cast<int>(py::extract<int>(tuple[3])));
100 return std::unique_ptr<const AbstractBooleanNode<AVariableManager>>(new BinaryBooleanNode<AVariableManager>(left_node, right_node,
101 boperator));
102 } else if (node_type == NodeType::UnaryRelationalNode) {
103 if (py::len(tuple) != 2) B2FATAL("UnaryRelationalNode tuple has to have length 2." << LogVar("actual length", py::len(tuple)));
104 Nodetuple node = static_cast<const py::tuple>(tuple[1]);
105 return std::unique_ptr<const AbstractBooleanNode<AVariableManager>>(new UnaryRelationalNode<AVariableManager>(node));
106 } else if (node_type == NodeType::BinaryRelationalNode) {
107 if (py::len(tuple) != 4) B2FATAL("BinaryRelationalNode tuple has to have length 4." << LogVar("actual length", py::len(tuple)));
108 Nodetuple left_node = static_cast<const py::tuple>(tuple[1]);
109 Nodetuple right_node = static_cast<const py::tuple>(tuple[2]);
110 ComparisonOperator coperator = static_cast<ComparisonOperator>(static_cast<int>(py::extract<int>(tuple[3])));
111 return std::unique_ptr<const AbstractBooleanNode<AVariableManager>>(new BinaryRelationalNode<AVariableManager>(left_node,
112 right_node, coperator));
113 } else if (node_type == NodeType::TernaryRelationalNode) {
114 if (py::len(tuple) != 6) B2FATAL("TernaryRelationalNode tuple has to have length 6." << LogVar("actual length", py::len(tuple)));
115 Nodetuple left_node = static_cast<const py::tuple>(tuple[1]);
116 Nodetuple center_node = static_cast<const py::tuple>(tuple[2]);
117 Nodetuple right_node = static_cast<const py::tuple>(tuple[3]);
118 ComparisonOperator lc_coperator = static_cast<ComparisonOperator>(static_cast<int>(py::extract<int>(tuple[4])));
119 ComparisonOperator cr_coperator = static_cast<ComparisonOperator>(static_cast<int>(py::extract<int>(tuple[5])));
120
121 return std::unique_ptr<const AbstractBooleanNode<AVariableManager>>(new TernaryRelationalNode<AVariableManager>(left_node,
122 center_node, right_node,
123 lc_coperator, cr_coperator));
124 } else {
125 throw std::runtime_error("error NodeFactory::compile_boolean_node: got invalid boolean NodeType.");
126 }
127 }
Class to store variables with their name which were sent to the logging service.
NodeType
Enum of possible Nodes in parsing tree.
ComparisonOperator
Enum for decoding the comparison operator type.
BooleanOperator
Enum for decoding the boolean operator type.

◆ compile_expression_node()

static std::unique_ptr< const AbstractExpressionNode< AVariableManager > > compile_expression_node ( Nodetuple  tuple)
inlinestatic

This template function creates a ExpressionNode from a boost::python::tuple The Python Parser encodes the node type as int in the first argument of each tuple.

Node types are decoded via the NodeType enum defined in framework/utilities/include/AbstractNodes.h e.g (9, 1.2) is a DataNode<double> with value 1.2 List of Nodes:

Definition at line 141 of file NodeFactory.h.

142 {
143 if (py::len(tuple) == 0) B2FATAL("ExpressionNode tuple is empty, this is invalid.");
144
145 // int is extracted from the py::tuple and cast as NodeTuple enum
146 NodeType node_type = static_cast<NodeType>(static_cast<int>(py::extract<int>(tuple[0])));
147 if (node_type == NodeType::UnaryExpressionNode) {
148 if (py::len(tuple) != 4) B2FATAL("UnaryExpression nodetuple has to have length 4." << LogVar("actual length", py::len(tuple)));
149 Nodetuple node = static_cast<const py::tuple>(tuple[1]);
150 bool unary_minus = py::extract<bool>(tuple[2]);
151 bool parenthesized = py::extract<bool>(tuple[3]);
152 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new UnaryExpressionNode<AVariableManager>(node,
153 unary_minus, parenthesized));
154 } else if (node_type == NodeType::BinaryExpressionNode) {
155 if (py::len(tuple) != 4) B2FATAL("BinaryExpression nodetuple has to have length 4." << LogVar("actual length", py::len(tuple)));
156 Nodetuple left_node = static_cast<const py::tuple>(tuple[1]);
157 Nodetuple right_node = static_cast<const py::tuple>(tuple[2]);
158 ArithmeticOperation aoperation = static_cast<ArithmeticOperation>(static_cast<int>(py::extract<int>(tuple[3])));
159 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new BinaryExpressionNode<AVariableManager>(left_node,
160 right_node,
161 aoperation));
162 } else if (node_type == NodeType::IntegerNode) {
163 if (py::len(tuple) != 2) B2FATAL("IntegerNode nodetuple has to have length 2." << LogVar("actual length", py::len(tuple)));
164 double d = py::extract<double>(tuple[1]);
165 if (std::numeric_limits<int>::min() <= d && d <= std::numeric_limits<int>::max()) {
166 int i = py::extract<int>(tuple[1]);
167 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new DataNode<AVariableManager, int>(i));
168 } else {
169 B2WARNING("Overflow for integer constant in cut detected. Create Double Node instead.");
170 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new DataNode<AVariableManager, double>(d));
171 }
172 } else if (node_type == NodeType::DoubleNode) {
173 if (py::len(tuple) != 2) B2FATAL("DoubleNode nodetuple has to have length 2." << LogVar("actual length", py::len(tuple)));
174 // We have to check for inf and nan values.
175 // use python math functions to check
176 py::object math = py::import("math");
177 // Get tuple item as object
178 py::object data = static_cast<py::object>(tuple[1]);
179 if (py::extract<bool>(math.attr("isinf")(data))) {
180 // Extract sign of inf float object
181 double inf_sign = py::extract<double>(math.attr("copysign")(1.0, data));
182 double inf;
183 if (inf_sign > 0) {
184 inf = std::numeric_limits<double>::infinity();
185 } else {
186 inf = -1 * std::numeric_limits<double>::infinity();
187 }
188 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new DataNode<AVariableManager, double>(inf));
189 }
190 if (py::extract<bool>(math.attr("isnan")(data))) {
191 double nan = std::nan("");
192 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new DataNode<AVariableManager, double>(nan));
193 }
194 double d = py::extract<double>(tuple[1]);
195 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new DataNode<AVariableManager, double>(d));
196 } else if (node_type == NodeType::BooleanNode) {
197 if (py::len(tuple) != 2) B2FATAL("BooleanNode nodetuple has to have length 2." << LogVar("actual length", py::len(tuple)));
198 bool b = py::extract<bool>(tuple[1]);
199 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new DataNode<AVariableManager, bool>(b));
200 } else if (node_type == NodeType::IdentifierNode) {
201 if (py::len(tuple) != 2) B2FATAL("IdentifierNode nodetuple has to have length 2." << LogVar("actual length", py::len(tuple)));
202 std::string identifier = py::extract<std::string>(tuple[1]);
203 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new IdentifierNode<AVariableManager>(identifier));
204 } else if (node_type == NodeType::FunctionNode) {
205 if (py::len(tuple) != 3) B2FATAL("FunctionNode nodetuple has to have length 3." << LogVar("actual length", py::len(tuple)));
206
207 // Extract functionName as second argument of the tuple
208 std::string functionName = py::extract<std::string>(tuple[1]);
209
210 // Extract argument tuple
211 std::string argument = py::extract<std::string>(tuple[2]);
212 boost::algorithm::trim(argument);
213 // Define vector for function arguments
214 std::vector<std::string> functionArguments = splitOnDelimiterAndConserveParenthesis(argument, ',', '(', ')');
215 for (auto& str : functionArguments) {
216 boost::algorithm::trim(str);
217 if (str.empty()) {
218 B2WARNING("Empty parameter for metavariable '" << functionName << "' in cut.");
219 }
220 }
221
222 return std::unique_ptr<const AbstractExpressionNode<AVariableManager>>(new FunctionNode<AVariableManager>(functionName,
223 functionArguments));
224 } else {
225 throw std::runtime_error("error NodeFactory::compile_expression_node: got invalid expression NodeType.");
226 }
227 }
std::vector< std::string > splitOnDelimiterAndConserveParenthesis(std::string str, char delimiter, char open, char close)
Split into std::vector on delimiter ignoring delimiters between parenthesis.
Definition: CutHelpers.cc:81
ArithmeticOperation
Enum for decoding the comparison operator type.

The documentation for this class was generated from the following file: