14 #include <framework/utilities/AbstractNodes.h> 
   15 #include <framework/utilities/NodeFactory.h> 
   16 #include <framework/logging/Logger.h> 
   18 #include <boost/algorithm/string.hpp> 
   19 #include <boost/python/tuple.hpp> 
   21 namespace py = boost::python;
 
   22 typedef const py::tuple& Nodetuple;
 
   54   template <
template <
typename type> 
class operation>
 
   61       return operation<double> {}(val0, val1);
 
   68       return operation<double> {}(val0, val1);
 
   75       return operation<double> {}(val0, val1);
 
   82       return operation<int> {}(val0, val1);
 
   89       return operation<int> {}(val0, val1);
 
   96       return operation<double> {}(val0, val1);
 
  103       return operation<bool> {}(val0, val1);
 
  110       return operation<double> {}(val0, val1);
 
  117       return operation<int> {}(val0, val1);
 
  152       return std::equal_to<int> {}(val0, val1);
 
  159       return std::equal_to<int> {}(val0, val1);
 
  173       return std::equal_to<bool> {}(val0, val1);
 
  187       return std::equal_to<int> {}(val0, val1);
 
  197   template<
class AVariableManager>
 
  202     typedef typename AVariableManager::Object 
Object;
 
  234       std::stringstream stringstream;
 
  238       stringstream << 
m_bnode->decompile();
 
  241       return stringstream.str();
 
  260     std::unique_ptr<const AbstractBooleanNode<AVariableManager>> 
m_bnode; 
 
  273   template<
class AVariableManager>
 
  278     typedef typename AVariableManager::Object 
Object;
 
  289         case BooleanOperator::AND:
 
  292         case BooleanOperator::OR:
 
  296           throw std::runtime_error(
"BinaryBooleanNode has an invalid BooleanOperator");
 
  317       std::stringstream stringstream;
 
  322       return stringstream.str();
 
  341     std::unique_ptr<const AbstractBooleanNode<AVariableManager>> 
m_left_bnode; 
 
  350   template<
class AVariableManager>
 
  355     typedef typename AVariableManager::Object 
Object;
 
  363       typename AVariableManager::VarVariant ret = 
m_enode->evaluate(p);
 
  364       if (std::holds_alternative<bool>(ret)) {
 
  365         return std::get<bool>(ret);
 
  366       } 
else if (std::holds_alternative<int>(ret)) {
 
  367         return static_cast<bool>(std::get<int>(ret));
 
  368       } 
else if (std::holds_alternative<double>(ret)) {
 
  369         if (
static_cast<bool>(std::get<double>(ret))) {
 
  371           if (std::isnan(std::get<double>(ret))) {
 
  374           if (std::get<double>(ret) != 1.0)
 
  375             B2WARNING(
"Static casting of double value to bool in cutstring evaluation." <<  
LogVar(
"Cut substring",
 
  376                       m_enode->decompile()) << 
LogVar(
" Casted value", std::get<double>(ret)) << 
LogVar(
"Casted to", 
"true"));
 
  378           if (std::get<double>(ret) != 0.0)
 
  379             B2WARNING(
"Static casting of double value to bool in cutstring evaluation." <<  
LogVar(
"Cut substring",
 
  380                       m_enode->decompile()) << 
LogVar(
" Casted value", std::get<double>(ret)) << 
LogVar(
"Casted to", 
"false"));
 
  383         return static_cast<bool>(std::get<double>(ret));
 
  385         throw std::runtime_error(
"UnaryRelationalNode should evaluate to bool.");
 
  418     std::unique_ptr<const AbstractExpressionNode<AVariableManager>> 
m_enode; 
 
  426   template<
class AVariableManager>
 
  431     typedef typename AVariableManager::Object 
Object;
 
  442       typename AVariableManager::VarVariant left_eval = 
m_left_enode->evaluate(p);
 
  443       typename AVariableManager::VarVariant right_eval = 
m_right_enode->evaluate(p);
 
  445         case ComparisonOperator::EQUALEQUAL:
 
  446           return std::visit(
EqualVisitor{}, left_eval, right_eval);
 
  448         case ComparisonOperator::GREATEREQUAL:
 
  451         case ComparisonOperator::LESSEQUAL:
 
  454         case ComparisonOperator::GREATER:
 
  457         case ComparisonOperator::LESS:
 
  461         case ComparisonOperator::NOTEQUAL:
 
  462           return !std::visit(
EqualVisitor{}, left_eval, right_eval);
 
  465           throw std::runtime_error(
"BinaryRelationalNode has an invalid ComparisonOperator.");
 
  485       std::stringstream stringstream;
 
  491       return stringstream.str();
 
  511     std::unique_ptr<const AbstractExpressionNode<AVariableManager>> 
m_left_enode; 
 
  512     std::unique_ptr<const AbstractExpressionNode<AVariableManager>> 
m_right_enode; 
 
  522   template<
class AVariableManager>
 
  537       typename AVariableManager::VarVariant left_eval = 
m_left_enode->evaluate(p);
 
  538       typename AVariableManager::VarVariant center_eval = 
m_center_enode->evaluate(p);
 
  539       typename AVariableManager::VarVariant right_eval = 
m_right_enode->evaluate(p);
 
  542         case ComparisonOperator::EQUALEQUAL:
 
  543           if (not std::visit(
EqualVisitor {}, left_eval, center_eval)) 
return false;
 
  545         case ComparisonOperator::GREATEREQUAL:
 
  548         case ComparisonOperator::LESSEQUAL:
 
  551         case ComparisonOperator::GREATER:
 
  554         case ComparisonOperator::LESS:
 
  557         case ComparisonOperator::NOTEQUAL:
 
  558           if (std::visit(
EqualVisitor {}, left_eval, center_eval)) 
return false;
 
  561           throw std::runtime_error(
"TernaryRelational has an invalid m_lc_operator");
 
  564         case ComparisonOperator::EQUALEQUAL:
 
  565           if (not std::visit(
EqualVisitor {}, center_eval, right_eval)) 
return false;
 
  567         case ComparisonOperator::GREATEREQUAL:
 
  570         case ComparisonOperator::LESSEQUAL:
 
  573         case ComparisonOperator::GREATER:
 
  576         case ComparisonOperator::LESS:
 
  579         case ComparisonOperator::NOTEQUAL:
 
  580           if (std::visit(
EqualVisitor {}, center_eval, right_eval)) 
return false;
 
  583           throw std::runtime_error(
"TernaryRelational has an invalid m_cr_operator");
 
  605       std::stringstream stringstream;
 
  611       return stringstream.str();
 
  635     std::unique_ptr<const AbstractExpressionNode<AVariableManager>>
 
  637     std::unique_ptr<const AbstractExpressionNode<AVariableManager>>
 
  639     std::unique_ptr<const AbstractExpressionNode<AVariableManager>>
 
  652   template<
class AVariableManager>
 
  666       typename AVariableManager::VarVariant ret = 
m_enode->evaluate(p);
 
  668         if (std::holds_alternative<int>(ret)) 
return -1 * std::get<int>(ret);
 
  669         if (std::holds_alternative<double>(ret)) 
return -1.0 * std::get<double>(ret);
 
  670         throw std::runtime_error(
"Attempted unary sign with boolean type value.");
 
  691       std::stringstream stringstream;
 
  694       stringstream << 
m_enode->decompile();
 
  696       return stringstream.str();
 
  715     std::unique_ptr<const AbstractExpressionNode<AVariableManager>> 
m_enode; 
 
  725   template<
class AVariableManager>
 
  730     typedef typename AVariableManager::Object 
Object;
 
  739       typename AVariableManager::VarVariant l_val, r_val, ret;
 
  743         case ArithmeticOperation::PLUS:
 
  744           if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
 
  745             ret = std::get<int>(l_val) + std::get<int>(r_val);
 
  747           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
 
  748             ret = std::get<double>(l_val) + std::get<double>(r_val);
 
  750           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
 
  751             ret = std::get<double>(l_val) + std::get<int>(r_val);
 
  753           } 
else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
 
  754             ret = std::get<int>(l_val) + std::get<double>(r_val);
 
  757             throw std::runtime_error(
"Invalid datatypes in plus operation.");
 
  760         case ArithmeticOperation::MINUS:
 
  761           if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
 
  762             ret = std::get<int>(l_val) - std::get<int>(r_val);
 
  764           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
 
  765             ret = std::get<double>(l_val) - std::get<double>(r_val);
 
  767           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
 
  768             ret = std::get<double>(l_val) - std::get<int>(r_val);
 
  770           } 
else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
 
  771             ret = std::get<int>(l_val) - std::get<double>(r_val);
 
  774             throw std::runtime_error(
"Invalid datatypes in minus operation.");
 
  777         case ArithmeticOperation::PRODUCT:
 
  778           if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
 
  779             ret = std::get<int>(l_val) * std::get<int>(r_val);
 
  781           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
 
  782             ret = std::get<double>(l_val) * std::get<double>(r_val);
 
  784           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
 
  785             ret = std::get<double>(l_val) * std::get<int>(r_val);
 
  787           } 
else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
 
  788             ret = std::get<int>(l_val) * std::get<double>(r_val);
 
  791             throw std::runtime_error(
"Invalid datatypes in product operation.");
 
  794         case ArithmeticOperation::DIVISION:
 
  795           if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
 
  797             double d = std::get<int>(r_val);
 
  798             ret = std::get<int>(l_val) / d;
 
  800           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
 
  801             ret = std::get<double>(l_val) / std::get<double>(r_val);
 
  803           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
 
  804             ret = std::get<double>(l_val) / std::get<int>(r_val);
 
  806           } 
else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
 
  807             ret = std::get<int>(l_val) / std::get<double>(r_val);
 
  810             throw std::runtime_error(
"Invalid datatypes in division operation.");
 
  813         case ArithmeticOperation::POWER:
 
  814           if (std::holds_alternative<int>(l_val) && std::holds_alternative<int>(r_val)) {
 
  815             ret = std::pow(std::get<int>(l_val), std::get<int>(r_val));
 
  817           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<double>(r_val)) {
 
  818             ret = std::pow(std::get<double>(l_val), std::get<double>(r_val));
 
  820           } 
else if (std::holds_alternative<double>(l_val) && std::holds_alternative<int>(r_val)) {
 
  821             ret = std::pow(std::get<double>(l_val), std::get<int>(r_val));
 
  823           } 
else if (std::holds_alternative<int>(l_val) && std::holds_alternative<double>(r_val)) {
 
  824             ret = std::pow(std::get<int>(l_val), std::get<double>(r_val));
 
  827             throw std::runtime_error(
"Invalid datatypes in power operation.");
 
  831           throw std::runtime_error(
"Operation not valid");
 
  852       std::stringstream stringstream;
 
  857       return stringstream.str();
 
  876     std::unique_ptr<const AbstractExpressionNode<AVariableManager>> 
m_left_enode; 
 
  877     std::unique_ptr<const AbstractExpressionNode<AVariableManager>> 
m_right_enode; 
 
  885   template<
class AVariableManager, 
typename T>
 
  907       typename AVariableManager::VarVariant ret{
m_value};
 
  915       std::cout << std::boolalpha;
 
  925       std::stringstream stringstream;
 
  926       stringstream << std::boolalpha;
 
  928       return stringstream.str();
 
  940   template<
class AVariableManager>
 
  945     typedef typename AVariableManager::Object 
Object;
 
  949     typedef typename AVariableManager::Var 
Var;
 
  957       if (
m_var != 
nullptr) {
 
  958         return m_var->function(p);
 
  960         throw std::runtime_error(
"Cut string has an invalid format: Neither number nor variable name");
 
  985       AVariableManager& manager = AVariableManager::Instance();
 
  987       if (
m_var == 
nullptr) {
 
  988         throw std::runtime_error(
 
  989           "Cut string has an invalid format: Variable not found: " + 
m_name);
 
 1012   template<
class AVariableManager>
 
 1017     typedef typename AVariableManager::Object 
Object;
 
 1021     typedef typename AVariableManager::Var 
Var;
 
 1029       return m_var->function(p);
 
 1036       std::string fullname = 
m_name + 
"(" + boost::algorithm::join(
m_arguments, 
", ") + 
")";
 
 1037       std::cout << fullname;
 
 1046       std::string fullname = 
m_name + 
"(" + boost::algorithm::join(
m_arguments, 
", ") + 
")";
 
 1056       AVariableManager& manager = AVariableManager::Instance();
 
 1058       if (
m_var == 
nullptr) {
 
 1061         throw std::runtime_error(
 
 1062           "Cut string has an invalid format: Metavariable not found: " + fullname);
 
 1077     explicit FunctionNode(
const std::string& functionName, 
const std::vector<std::string>& functionArguments): 
m_name{functionName},
 
A parsed cut-string naturally has a tree shape which incorporates the infomation of operator preceden...
AVariableManager::Object Object
Template argument dependent Particle type definition.
AbstractExpressionNode Superclass for all nodes which host expressions.
AVariableManager::Object Object
Template argument dependent Particle type definition.
Nodeclass with two AbstractBooleanNode as children and a Boolean Operator (AND, OR) Check() method ev...
BinaryBooleanNode(Nodetuple left_node, Nodetuple right_node, BooleanOperator boperator)
bool check(const Object *p) const override
Check if object passes this subexpression of the cut by calling check on the children nodes.
~BinaryBooleanNode()
Destructor.
std::string decompile() const override
Decompile Node back to a string.
std::unique_ptr< const AbstractBooleanNode< AVariableManager > > m_left_bnode
boolean subexpression of a cut
std::unique_ptr< const AbstractBooleanNode< AVariableManager > > m_right_bnode
boolean subexpression of a cut
AVariableManager::Object Object
Template argument dependent Particle type definition.
const BooleanOperator m_boperator
Boolean operation to be applied to the check() results of the child nodes.
void print() const override
Print node.
BinaryExpressionNode Node which connects two expression nodes with an arithemtic operation.
BinaryExpressionNode(Nodetuple left_node, Nodetuple right_node, ArithmeticOperation aoperation)
Constructor.
AVariableManager::VarVariant evaluate(const Object *p) const override
Evaluation of the child nodes and return result as a variant<double, int, bool> apply arithmetic oper...
~BinaryExpressionNode()
Destructor.
std::string decompile() const override
Decompile Node back to a string.
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_left_enode
left expression node
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_right_enode
right expression node
AVariableManager::Object Object
Template argument dependent Particle type definition.
ArithmeticOperation m_aoperation
arithmetic operation to be applied to the evaluations of left and right expressions
void print() const override
Print node.
BooleanNode which has two AbstractExpressionNodes nodes and a ComparisonOperator.
const ComparisonOperator m_coperator
comparison operator to be applied to the expression evaluations
bool check(const Object *p) const override
Evaluate the Expression children nodes which yield std::variant values.
~BinaryRelationalNode()
Destructor.
std::string decompile() const override
Decompile Node back to a string.
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_left_enode
subexpression of a cut
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_right_enode
subexpression of a cut
BinaryRelationalNode(Nodetuple left_node, Nodetuple right_node, ComparisonOperator coperator)
Constructor.
AVariableManager::Object Object
Template argument dependent Particle type definition.
void print() const override
Print node.
Template class for storing the Constants (int, double, bool) of the Cutstring.
const T m_value
constant of type T which is always returned by evaluate(const Object* p)
AVariableManager::VarVariant evaluate(const Object *p) const override
return m_value as a variant<double, int, bool>
DataNode(T value)
Constructor.
std::string decompile() const override
Decompile Node back to a string.
AbstractExpressionNode< AVariableManager >::Object Object
Template argument dependent Particle type definition.
void print() const override
Print node.
FunctionNode Node class for handling MetaVariables in cuts.
const std::vector< std::string > m_arguments
vector of string arguments of the MetaVariable
AVariableManager::Var Var
Template argument dependent Variable type definition.
const std::string m_name
Function name of the MetaVariable.
AVariableManager::VarVariant evaluate(const Object *p) const override
evaluate m_var with p and return the result
FunctionNode(const std::string &functionName, const std::vector< std::string > &functionArguments)
Constructor.
void processMetaVariable()
Get MetaVariable from AVariableManager.
std::string decompile() const override
Decompile Node back to a string.
~FunctionNode()
Destructor.
const Var * m_var
set if there was a valid variable in this cut
AVariableManager::Object Object
Template argument dependent Particle type definition.
void print() const override
Print node.
Class which stores the name of a variable.
void processVariable()
Get variable from AVariableManger.
AVariableManager::Var Var
Template argument dependent Variable type definition.
~IdentifierNode()
Destructor.
IdentifierNode(const std::string &name)
Constructor.
const std::string m_name
name of the variable
AVariableManager::VarVariant evaluate(const Object *p) const override
evaluate m_var with p and return the result
std::string decompile() const override
Decompile Node back to a string.
const Var * m_var
set if there was a valid variable in this cut
AVariableManager::Object Object
Template argument dependent Particle type definition.
void print() const override
Print node.
Wrapper class for static node compile functions.
BooleanNode which has three AbstractExpressionNodes nodes and two ComparisonOperator.
const ComparisonOperator m_cr_coperator
comparison operator to be applied to the evaluations of the center and right expressions
bool check(const Object *p) const override
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_center_enode
center expression of the ternary relational expression
std::string decompile() const override
Decompile Node back to a string.
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_left_enode
left expression of the ternary relational expression
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_right_enode
right expression of the ternary relational expression
AbstractBooleanNode< AVariableManager >::Object Object
Template argument dependent Particle type definition.
const ComparisonOperator m_lc_coperator
comparison operator to be applied to the evaluations of the left and center expression
void print() const override
Print node.
~TernaryRelationalNode()
Destructor.
TernaryRelationalNode(Nodetuple left_node, Nodetuple center_node, Nodetuple right_node, ComparisonOperator lc_coperator, ComparisonOperator cr_coperator)
Constructor.
Nodeclass with a single AbstractBooleanNode as child.
const bool m_bracketized
if the boolean expression from which this node is compiled was in brackets, relevant in decompile to ...
bool check(const Object *p) const override
Check if Object passes this subexpression of the cut by calling check on the child node.
~UnaryBooleanNode()
Destructor.
const bool m_negation
if the evaluation of m_bnode->check(p) should be negated in check()
UnaryBooleanNode(Nodetuple node, bool negation, bool bracketized)
std::string decompile() const override
Decompile Node back to a string.
AVariableManager::Object Object
Template argument dependent Particle type definition.
std::unique_ptr< const AbstractBooleanNode< AVariableManager > > m_bnode
boolean subexpression of a cut
void print() const override
Print node brackets and negation keywords are added if m_bracketized, m_negation are set to true.
UnaryExpressionNode Node class with a single expression node as child.
const bool m_parenthesized
flag if expression in cut was in parenthesis
AVariableManager::VarVariant evaluate(const Object *p) const override
Evaluation of the child nodes and return result as a variant<double, int, bool> return negative resul...
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_enode
pointer to single expression node
const bool m_unary_minus
flag if expression evaluation should be returned times -1
UnaryExpressionNode(Nodetuple node, bool unary_minus, bool parenthesized)
Constructor.
std::string decompile() const override
Decompile Node back to a string.
~UnaryExpressionNode()
Destructor.
AbstractExpressionNode< AVariableManager >::Object Object
Template argument dependent Particle type definition.
void print() const override
Print node.
Nodeclass with a single AbstractExpressioNode as child.
UnaryRelationalNode(Nodetuple node)
Constructor.
bool check(const Object *p) const override
Evaluate the Expression Node child and assert that it is boolean.
std::unique_ptr< const AbstractExpressionNode< AVariableManager > > m_enode
subexpression of a cut
std::string decompile() const override
Decompile Node back to a string.
AVariableManager::Object Object
Template argument dependent Particle type definition.
~UnaryRelationalNode()
Destructor.
void print() const override
Print node.
Class to store variables with their name which were sent to the logging service.
void injectArithmeticOperatorToStream(std::ostream &stream, const ArithmeticOperation &aoperation)
Helper functions for AbstractBooleanNode and AbstractExpressionNode print() and decompile() members S...
void injectComparisonOperatorToStream(std::ostream &stream, const ComparisonOperator &coperator)
Helper functions for AbstractBooleanNode and AbstractExpressionNode print() and decompile() members S...
void injectBooleanOperatorToStream(std::ostream &stream, const BooleanOperator &boperator)
Helper functions for AbstractBooleanNode and AbstractExpressionNode print() and decompile() members S...
ComparisonOperator
Enum for decoding the comparison operator type.
BooleanOperator
Enum for decoding the boolean operator type.
bool almostEqualDouble(const double &a, const double &b)
Helper function to test if two doubles are almost equal.
ArithmeticOperation
Enum for decoding the comparison operator type.
Abstract base class for different kinds of events.
Seperate Visitor struct for equal_to comparison of variant<double, int bool>.
bool operator()(const double &val0, const int &val1)
double int overload with double comparison.
bool operator()(const double &val0, const bool &val1)
double bool overload with double comparison.
bool operator()(const double &val0, const double &val1)
double double overload with double comparison.
bool operator()(const bool &val0, const double &val1)
bool double overload with double comparison.
bool operator()(const int &val0, const int &val1)
int int overload with int comparison.
bool operator()(const bool &val0, const int &val1)
bool int overload with int comparison.
bool operator()(const int &val0, const bool &val1)
int bool overload with int comparison.
bool operator()(const int &val0, const double &val1)
int double overload with double comparison.
bool operator()(const bool &val0, const bool &val1)
bool bool overload with bool comparison.
This is a class template which takes a template class operation as template argument.
bool operator()(const double &val0, const int &val1)
double int overload with double comparison.
bool operator()(const double &val0, const bool &val1)
double bool overload with double comparison.
bool operator()(const double &val0, const double &val1)
double double overload with double comparison.
bool operator()(const bool &val0, const double &val1)
bool double overload with double comparison.
bool operator()(const int &val0, const int &val1)
int int overload with int comparison.
bool operator()(const bool &val0, const int &val1)
bool int overload with int comparison.
bool operator()(const int &val0, const bool &val1)
int bool overload with int comparison.
bool operator()(const int &val0, const double &val1)
int double overload with double comparison.
bool operator()(const bool &val0, const bool &val1)
bool bool overload with bool comparison.