10 #include <framework/utilities/Conversion.h>
16 #include <boost/algorithm/string.hpp>
90 template <
class AVariableManager>
93 typedef typename AVariableManager::Object
Object;
95 typedef typename AVariableManager::Var
Var;
104 static std::unique_ptr<GeneralCut>
compile(
const std::string& cut)
106 return std::unique_ptr<GeneralCut>(
new GeneralCut(cut));
119 return std::isnan(this->
get(p)) ? false : this->
get(p);
137 throw std::runtime_error(
"Cut string has an invalid format: Invalid operation");
147 case EMPTY: std::cout <<
"EMPTY" << std::endl;
break;
148 case NONE: std::cout <<
"NONE" << std::endl;
break;
149 case AND: std::cout <<
"AND" << std::endl;
break;
150 case OR: std::cout <<
"OR" << std::endl;
break;
151 case LT: std::cout <<
"LT" << std::endl;
break;
152 case LE: std::cout <<
"LE" << std::endl;
break;
153 case GT: std::cout <<
"GT" << std::endl;
break;
154 case GE: std::cout <<
"GE" << std::endl;
break;
155 case EQ: std::cout <<
"EQ" << std::endl;
break;
156 case NE: std::cout <<
"NE" << std::endl;
break;
159 std::cout <<
"Left " << std::endl;
161 std::cout <<
"End Left" << std::endl;
164 std::cout <<
"Right " << std::endl;
166 std::cout <<
"End Right" << std::endl;
175 std::stringstream stringstream;
181 stringstream <<
m_left->decompile();
184 case AND: stringstream <<
" and ";
break;
185 case OR: stringstream <<
" or ";
break;
186 case LT: stringstream <<
" < ";
break;
187 case LE: stringstream <<
" <= ";
break;
188 case GT: stringstream <<
" > ";
break;
189 case GE: stringstream <<
" >= ";
break;
190 case EQ: stringstream <<
" == ";
break;
191 case NE: stringstream <<
" != ";
break;
192 default:
throw std::runtime_error(
"Cut string has an invalid format: Operator does not support left and right!");
break;
195 stringstream <<
m_right->decompile();
203 }
else if (
m_var !=
nullptr) {
204 stringstream <<
m_var->name;
206 throw std::runtime_error(
"Cut string has an invalid format: Variable is empty!");
209 default:
throw std::runtime_error(
"Cut string has an invalid format: Invalid operator without left and right!");
break;
212 throw std::runtime_error(
"Cut string has an invalid format: invalid combination of left and right!");
215 return stringstream.str();
237 m_number = Belle2::convertString<double>(str);
239 }
catch (std::invalid_argument&) {
263 boost::algorithm::trim(str);
266 str = str.substr(1, str.size() - 2);
267 boost::algorithm::trim(str);
279 unsigned long int pos = 0;
303 unsigned long int pos = 0;
349 for (
auto& c : {
"<",
">",
"!",
"="}) {
351 unsigned long int pos1 = 0;
352 unsigned long int pos2 = 0;
361 if (str[pos1 + 1] ==
'=')
377 AVariableManager& manager = AVariableManager::Instance();
378 m_var = manager.getVariable(str);
379 if (
m_var ==
nullptr) {
380 throw std::runtime_error(
381 "Cut string has an invalid format: Variable not found: " + str);
392 }
else if (
m_var !=
nullptr) {
393 return m_var->function(p);
395 throw std::runtime_error(
"Cut string has an invalid format: Neither number nor variable name");
This class implements a common way to implement cut/selection functionality for arbitrary objects.
std::unique_ptr< GeneralCut > m_left
Left-side cut.
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Creates an instance of a cut and returns a unique_ptr to it, if you need a copy-able object instead y...
AVariableManager::Var Var
Variable returned by the variable manager.
enum Belle2::GeneralCut::Operation m_operation
Operation which connects left and right cut.
std::string preprocess(std::string str) const
Preprocess cut string.
GeneralCut(std::string str)
Constructor of the cut.
bool processTernaryNumericConditions(std::string str)
Look for numeric ternary conditions (e.g.
bool processLogicConditions(std::string str)
Look for logical conditions in the given cut string.
Operation
Enum with the allowed operations of the Cut Tree.
std::unique_ptr< GeneralCut > m_right
Right-side cut.
GeneralCut(const GeneralCut &)=delete
Delete Copy constructor.
double get(const Object *p) const
Returns stored number or Variable value for the given object.
bool processBinaryNumericConditions(std::string str)
Look for numeric binary conditions (e.g.
void print() const
Print cut tree.
const Var * m_var
set if there was a valid variable in this cut
AVariableManager::Object Object
Object, that can be checked. This depends on the VariableManager, as the returned variables from the ...
std::string decompile() const
Do the compilation from a string in return.
double m_number
literal number contained in the cut
bool check(const Object *p) const
Check if the current cuts are passed by the given object.
void processVariable(const std::string &str)
Get a variable with the given name from the variable manager using its getVariable(name) function.
GeneralCut & operator=(const GeneralCut &)=delete
Delete assign operator.
bool m_isNumeric
if there was a literal number in this cut
bool almostEqualFloat(const float &a, const float &b)
Helper function to test if two floats are almost equal.
unsigned long int findIgnoringParenthesis(std::string str, std::string pattern, unsigned int begin=0)
Returns the position of a pattern in a string ignoring everything that is in parenthesis.
unsigned long int findMatchedParenthesis(std::string str, char open='[', char close=']')
Returns position of the matched closing parenthesis if the first character in the given string contai...
std::vector< std::string > splitOnDelimiterAndConserveParenthesis(std::string str, char delimiter, char open, char close)
Split into std::vector on delimiter ignoring delimiters between parenthesis.
bool almostEqualDouble(const double &a, const double &b)
Helper function to test if two doubles are almost equal.
Abstract base class for different kinds of events.