11 #include <framework/utilities/CutHelpers.h> 
   12 #include <framework/utilities/CutNodes.h> 
   13 #include <framework/logging/Logger.h> 
   15 #include <boost/python/tuple.hpp> 
   16 #include <boost/python/extract.hpp> 
   17 #include <boost/algorithm/string.hpp> 
   19 namespace py = boost::python;
 
   20 typedef const py::tuple& Nodetuple;
 
   31   template<
class AVariableManager>
 
   32   class UnaryBooleanNode;
 
   34   template<
class AVariableManager>
 
   35   class BinaryBooleanNode;
 
   37   template<
class AVariableManager>
 
   38   class UnaryRelationalNode;
 
   40   template<
class AVariableManager>
 
   41   class BinaryRelationalNode;
 
   43   template<
class AVariableManager>
 
   44   class TernaryRelationalNode;
 
   46   template<
class AVariableManager>
 
   47   class UnaryExpressionNode;
 
   49   template<
class AVariableManager>
 
   50   class BinaryExpressionNode;
 
   52   template<
class AVariableManager, 
typename T>
 
   55   template<
class AVariableManager>
 
   58   template<
class AVariableManager>
 
   79     template<
class AVariableManager>
 
   82       if (py::len(tuple) == 0) B2FATAL(
"BooleanNode tuple is empty, this is invalid.");
 
   84       NodeType node_type = 
static_cast<NodeType>(
static_cast<int>(py::extract<int>(tuple[0])));
 
   86       if (node_type == NodeType::UnaryBooleanNode) {
 
   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]);
 
   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]);
 
  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]);
 
  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]);
 
  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]);
 
  122                center_node, right_node,
 
  123                lc_coperator, cr_coperator));
 
  125         throw std::runtime_error(
"error NodeFactory::compile_boolean_node: got invalid boolean NodeType.");
 
  140     template<
class AVariableManager>
 
  143       if (py::len(tuple) == 0) B2FATAL(
"ExpressionNode tuple is empty, this is invalid.");
 
  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]);
 
  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]);
 
  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]);
 
  169           B2WARNING(
"Overflow for integer constant in cut detected. Create Double Node instead.");
 
  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)));
 
  176         py::object math = py::import(
"math");
 
  178         py::object data = 
static_cast<py::object
>(tuple[1]);
 
  179         if (py::extract<bool>(math.attr(
"isinf")(data))) {
 
  181           double inf_sign = py::extract<double>(math.attr(
"copysign")(1.0, data));
 
  184             inf = std::numeric_limits<double>::infinity();
 
  186             inf = -1 * std::numeric_limits<double>::infinity();
 
  190         if (py::extract<bool>(math.attr(
"isnan")(data))) {
 
  191           double nan = std::nan(
"");
 
  194         double d = py::extract<double>(tuple[1]);
 
  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]);
 
  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]);
 
  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)));
 
  208         std::string functionName = py::extract<std::string>(tuple[1]);
 
  211         std::string argument = py::extract<std::string>(tuple[2]);
 
  212         boost::algorithm::trim(argument);
 
  215         for (
auto& str : functionArguments) {
 
  216           boost::algorithm::trim(str);
 
  218             B2WARNING(
"Empty parameter for metavariable '" << functionName << 
"' in cut.");
 
  225         throw std::runtime_error(
"error NodeFactory::compile_expression_node: got invalid expression NodeType.");
 
Nodeclass with two AbstractBooleanNode as children and a Boolean Operator (AND, OR) Check() method ev...
BinaryExpressionNode Node which connects two expression nodes with an arithemtic operation.
BooleanNode which has two AbstractExpressionNodes nodes and a ComparisonOperator.
Template class for storing the Constants (int, double, bool) of the Cutstring.
FunctionNode Node class for handling MetaVariables in cuts.
Class which stores the name of a variable.
Wrapper class for static node compile functions.
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...
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 t...
BooleanNode which has three AbstractExpressionNodes nodes and two ComparisonOperator.
Nodeclass with a single AbstractBooleanNode as child.
UnaryExpressionNode Node class with a single expression node as child.
Nodeclass with a single AbstractExpressioNode as child.
Class to store variables with their name which were sent to the logging service.
NodeType
Enum of possible Nodes in parsing tree.
std::vector< std::string > splitOnDelimiterAndConserveParenthesis(std::string str, char delimiter, char open, char close)
Split into std::vector on delimiter ignoring delimiters between parenthesis.
ComparisonOperator
Enum for decoding the comparison operator type.
BooleanOperator
Enum for decoding the boolean operator type.
ArithmeticOperation
Enum for decoding the comparison operator type.
Abstract base class for different kinds of events.