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.