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> 
   21namespace py = boost::python;
 
   22typedef 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.