Skip to content

Commit

Permalink
Merge pull request #39196 from missirol/devel_hltParserMaskOperator_3
Browse files Browse the repository at this point in the history
introduce `MASKING` operator in `triggerExpression::Parser`
  • Loading branch information
cmsbuild authored Sep 8, 2022
2 parents 134267b + aa32f59 commit 435424d
Show file tree
Hide file tree
Showing 16 changed files with 340 additions and 127 deletions.
8 changes: 4 additions & 4 deletions HLTrigger/HLTcore/interface/TriggerExpressionConstant.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef HLTrigger_HLTfilters_TriggerExpressionConstant_h
#define HLTrigger_HLTfilters_TriggerExpressionConstant_h
#ifndef HLTrigger_HLTcore_TriggerExpressionConstant_h
#define HLTrigger_HLTcore_TriggerExpressionConstant_h

#include "HLTrigger/HLTcore/interface/TriggerExpressionEvaluator.h"

Expand All @@ -13,12 +13,12 @@ namespace triggerExpression {

bool operator()(const Data& data) const override { return m_value; }

void dump(std::ostream& out) const override { out << (m_value ? "TRUE" : "FALSE"); }
void dump(std::ostream& out, bool const ignoreMasks = false) const override { out << (m_value ? "TRUE" : "FALSE"); }

private:
bool m_value;
};

} // namespace triggerExpression

#endif // HLTrigger_HLTfilters_TriggerExpressionConstant_h
#endif // HLTrigger_HLTcore_TriggerExpressionConstant_h
6 changes: 3 additions & 3 deletions HLTrigger/HLTcore/interface/TriggerExpressionData.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef HLTrigger_HLTfilters_TriggerExpressionData_h
#define HLTrigger_HLTfilters_TriggerExpressionData_h
#ifndef HLTrigger_HLTcore_TriggerExpressionData_h
#define HLTrigger_HLTcore_TriggerExpressionData_h

#include "FWCore/Framework/interface/ConsumesCollector.h"
#include "FWCore/Utilities/interface/InputTag.h"
Expand Down Expand Up @@ -220,4 +220,4 @@ namespace triggerExpression {

} // namespace triggerExpression

#endif // HLTrigger_HLTfilters_TriggerExpressionData_h
#endif // HLTrigger_HLTcore_TriggerExpressionData_h
27 changes: 21 additions & 6 deletions HLTrigger/HLTcore/interface/TriggerExpressionEvaluator.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#ifndef HLTrigger_HLTfilters_TriggerExpressionEvaluator_h
#define HLTrigger_HLTfilters_TriggerExpressionEvaluator_h
#ifndef HLTrigger_HLTcore_TriggerExpressionEvaluator_h
#define HLTrigger_HLTcore_TriggerExpressionEvaluator_h

#include <iostream>
#include <string>
#include <vector>
#include <utility>

namespace triggerExpression {

Expand All @@ -13,6 +14,9 @@ namespace triggerExpression {
public:
Evaluator() = default;

// virtual destructor
virtual ~Evaluator() = default;

// check if the data satisfies the logical expression
virtual bool operator()(const Data& data) const = 0;

Expand All @@ -22,11 +26,22 @@ namespace triggerExpression {
// list CMSSW path patterns associated to the logical expression
virtual std::vector<std::string> patterns() const { return {}; }

// list of triggers associated to the Evaluator (filled only for certain derived classes)
virtual std::vector<std::pair<std::string, unsigned int>> triggers() const { return {}; }

// dump the logical expression to the output stream
virtual void dump(std::ostream& out) const = 0;
virtual void dump(std::ostream& out, bool const ignoreMasks = false) const = 0;

// virtual destructor
virtual ~Evaluator() = default;
// apply masks based on another Evaluator
virtual void mask(Evaluator const&) {}

// methods to control m_masksEnabled boolean
virtual bool masksEnabled() const { return m_masksEnabled; }
virtual void enableMasks() { m_masksEnabled = true; }
virtual void disableMasks() { m_masksEnabled = false; }

private:
bool m_masksEnabled = false;
};

inline std::ostream& operator<<(std::ostream& out, const Evaluator& eval) {
Expand All @@ -36,4 +51,4 @@ namespace triggerExpression {

} // namespace triggerExpression

#endif // HLTrigger_HLTfilters_TriggerExpressionEvaluator_h
#endif // HLTrigger_HLTcore_TriggerExpressionEvaluator_h
20 changes: 12 additions & 8 deletions HLTrigger/HLTcore/interface/TriggerExpressionL1uGTReader.h
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
#ifndef HLTrigger_HLTfilters_TriggerExpressionL1uGTReader_h
#define HLTrigger_HLTfilters_TriggerExpressionL1uGTReader_h

#include <vector>
#include <string>
#ifndef HLTrigger_HLTcore_TriggerExpressionL1uGTReader_h
#define HLTrigger_HLTcore_TriggerExpressionL1uGTReader_h

#include "HLTrigger/HLTcore/interface/TriggerExpressionEvaluator.h"

namespace triggerExpression {

class L1uGTReader : public Evaluator {
public:
L1uGTReader(const std::string& pattern) : m_pattern{pattern}, m_triggers{}, m_initialised{false} {}
L1uGTReader(const std::string& pattern)
: m_pattern{pattern}, m_triggers{}, m_triggersAfterMasking{}, m_initialised{false} {}

bool operator()(const Data& data) const override;

void init(const Data& data) override;

void dump(std::ostream& out) const override;
void dump(std::ostream& out, bool const ignoreMasks = false) const override;

void mask(Evaluator const& eval) override;

std::vector<std::pair<std::string, unsigned int>> triggers() const override { return m_triggers; }
std::vector<std::pair<std::string, unsigned int>> triggersAfterMasking() const { return m_triggersAfterMasking; }

private:
std::string m_pattern;
std::vector<std::pair<std::string, unsigned int>> m_triggers;
std::vector<std::pair<std::string, unsigned int>> m_triggersAfterMasking;
bool m_initialised;
};

} // namespace triggerExpression

#endif // HLTrigger_HLTfilters_TriggerExpressionL1uGTReader_h
#endif // HLTrigger_HLTcore_TriggerExpressionL1uGTReader_h
72 changes: 55 additions & 17 deletions HLTrigger/HLTcore/interface/TriggerExpressionOperators.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#ifndef HLTrigger_HLTfilters_TriggerExpressionOperators_h
#define HLTrigger_HLTfilters_TriggerExpressionOperators_h
#ifndef HLTrigger_HLTcore_TriggerExpressionOperators_h
#define HLTrigger_HLTcore_TriggerExpressionOperators_h

#include <memory>

#include "HLTrigger/HLTcore/interface/TriggerExpressionEvaluator.h"

namespace triggerExpression {
Expand All @@ -14,6 +15,9 @@ namespace triggerExpression {
// initialize the depending modules
void init(const Data& data) override { m_arg->init(data); }

// apply mask(s) to the Evaluator
void mask(Evaluator const& arg) override { m_arg->mask(arg); }

// return the patterns from the depending modules
std::vector<std::string> patterns() const override { return m_arg->patterns(); }

Expand All @@ -32,6 +36,12 @@ namespace triggerExpression {
m_arg2->init(data);
}

// apply mask(s) to the Evaluators
void mask(Evaluator const& arg) override {
m_arg1->mask(arg);
m_arg2->mask(arg);
}

// return the patterns from the depending modules
std::vector<std::string> patterns() const override {
std::vector<std::string> patterns = m_arg1->patterns();
Expand All @@ -54,10 +64,10 @@ namespace triggerExpression {

bool operator()(const Data& data) const override { return not(*m_arg)(data); }

void dump(std::ostream& out) const override {
void dump(std::ostream& out, bool const ignoreMasks = false) const override {
out << '(';
out << "NOT ";
m_arg->dump(out);
m_arg->dump(out, ignoreMasks);
out << ')';
}
};
Expand All @@ -67,17 +77,17 @@ namespace triggerExpression {
OperatorAnd(Evaluator* arg1, Evaluator* arg2) : BinaryOperator(arg1, arg2) {}

bool operator()(const Data& data) const override {
// force the execution af both arguments, otherwise precalers won't work properly
// force the execution of both arguments, otherwise prescalers won't work properly
bool r1 = (*m_arg1)(data);
bool r2 = (*m_arg2)(data);
return r1 and r2;
}

void dump(std::ostream& out) const override {
void dump(std::ostream& out, bool const ignoreMasks = false) const override {
out << '(';
m_arg1->dump(out);
m_arg1->dump(out, ignoreMasks);
out << " AND ";
m_arg2->dump(out);
m_arg2->dump(out, ignoreMasks);
out << ')';
}
};
Expand All @@ -87,17 +97,17 @@ namespace triggerExpression {
OperatorOr(Evaluator* arg1, Evaluator* arg2) : BinaryOperator(arg1, arg2) {}

bool operator()(const Data& data) const override {
// force the execution af both arguments, otherwise precalers won't work properly
// force the execution of both arguments, otherwise prescalers won't work properly
bool r1 = (*m_arg1)(data);
bool r2 = (*m_arg2)(data);
return r1 or r2;
}

void dump(std::ostream& out) const override {
void dump(std::ostream& out, bool const ignoreMasks = false) const override {
out << '(';
m_arg1->dump(out);
m_arg1->dump(out, ignoreMasks);
out << " OR ";
m_arg2->dump(out);
m_arg2->dump(out, ignoreMasks);
out << ')';
}
};
Expand All @@ -107,19 +117,47 @@ namespace triggerExpression {
OperatorXor(Evaluator* arg1, Evaluator* arg2) : BinaryOperator(arg1, arg2) {}

bool operator()(const Data& data) const override {
// force the execution af both arguments, otherwise precalers won't work properly
// force the execution of both arguments, otherwise prescalers won't work properly
bool r1 = (*m_arg1)(data);
bool r2 = (*m_arg2)(data);
return r1 xor r2;
}

void dump(std::ostream& out) const override {
m_arg1->dump(out);
void dump(std::ostream& out, bool const ignoreMasks = false) const override {
out << '(';
m_arg1->dump(out, ignoreMasks);
out << " XOR ";
m_arg2->dump(out);
m_arg2->dump(out, ignoreMasks);
out << ')';
}
};

class OperatorMasking : public BinaryOperator {
public:
OperatorMasking(Evaluator* arg1, Evaluator* arg2) : BinaryOperator(arg1, arg2) {}

bool operator()(const Data& data) const override { return (*m_arg1)(data); }

void init(const Data& data) override {
m_arg1->init(data);
m_arg2->init(data);
m_arg1->mask(*m_arg2);
}

// apply mask(s) only to the first Evaluator
// (the second Evaluator is not used in the decision of OperatorMasking)
void mask(Evaluator const& arg) override { m_arg1->mask(arg); }

void dump(std::ostream& out, bool const ignoreMasks = false) const override {
out << '(';
// ignore masks on the first Evaluator to dump the full logical expression
m_arg1->dump(out, true);
out << " MASKING ";
m_arg2->dump(out, ignoreMasks);
out << ')';
}
};

} // namespace triggerExpression

#endif // HLTrigger_HLTfilters_TriggerExpressionOperators_h
#endif // HLTrigger_HLTcore_TriggerExpressionOperators_h
47 changes: 33 additions & 14 deletions HLTrigger/HLTcore/interface/TriggerExpressionParser.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef HLTrigger_HLTfilters_TriggerExpressionParser_h
#define HLTrigger_HLTfilters_TriggerExpressionParser_h
#ifndef HLTrigger_HLTcore_TriggerExpressionParser_h
#define HLTrigger_HLTcore_TriggerExpressionParser_h

// Note: this requires Boost 1.41 or higher, for Spirit 2.1 or higher
#include <boost/phoenix.hpp>
Expand All @@ -25,20 +25,27 @@ namespace triggerExpression {
Parser() : Parser::base_type(expression) {
auto delimiter = qi::copy(qi::eoi | !qi::char_("a-zA-Z0-9_*?"));

token_true = qi::lexeme[qi::lit("TRUE") >> delimiter];
token_false = qi::lexeme[qi::lit("FALSE") >> delimiter];

operand_not = qi::lexeme[qi::lit("NOT") >> delimiter];
operand_and = qi::lexeme[qi::lit("AND") >> delimiter];
operand_or = qi::lexeme[qi::lit("OR") >> delimiter];
operand_masking = qi::lexeme[qi::lit("MASKING") >> delimiter];

// "TRUE": keyword to accept all events
token_true = qi::lexeme[qi::lit("TRUE") >> delimiter];

// "FALSE": keyword to reject all events
token_false = qi::lexeme[qi::lit("FALSE") >> delimiter];

// Level-1 Global Trigger decisions: must begin with characters "L1_"
token_l1algo %= qi::raw[qi::lexeme["L1_" >> +(qi::char_("a-zA-Z0-9_*?"))]];
token_path %= qi::raw[qi::lexeme[+(qi::char_("a-zA-Z0-9_*?"))] - operand_not - operand_and - operand_or];

token = (token_true[qi::_val = new_<Constant>(true)] | // TRUE
token_false[qi::_val = new_<Constant>(false)] | // FALSE
token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] | // L1_*
token_path[qi::_val = new_<PathReader>(qi::_1)]); // * (except "NOT", "AND" and "OR")
// Decisions of Paths in the CMSSW configuration (e.g. high-level triggers):
// any alphanumeric pattern except for "TRUE", "FALSE", "NOT", "AND", "OR", and "MASKING"
token_path %= qi::raw[qi::lexeme[+(qi::char_("a-zA-Z0-9_*?"))] - token_true - token_false - operand_not -
operand_and - operand_or - operand_masking];

token = (token_true[qi::_val = new_<Constant>(true)] | token_false[qi::_val = new_<Constant>(false)] |
token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] | token_path[qi::_val = new_<PathReader>(qi::_1)]);

parenthesis %= ('(' >> expression >> ')');

Expand All @@ -50,9 +57,18 @@ namespace triggerExpression {

unary = ((operand_not >> unary)[qi::_val = new_<OperatorNot>(qi::_1)] | operand[qi::_val = qi::_1]);

expression =
unary[qi::_val = qi::_1] >> *((operand_and >> unary)[qi::_val = new_<OperatorAnd>(qi::_val, qi::_1)] |
(operand_or >> unary)[qi::_val = new_<OperatorOr>(qi::_val, qi::_1)]);
// token_masking is used to restrict the argument (rhs) of the "MASKING"
// operation to Constant[FALSE], L1uGTReader and PathReader evaluators
token_masking =
(token_false[qi::_val = new_<Constant>(false)] | token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] |
token_path[qi::_val = new_<PathReader>(qi::_1)]);

argument_masking %= (token_masking | ('(' >> argument_masking >> ')'));

expression = unary[qi::_val = qi::_1] >>
*((operand_and >> unary)[qi::_val = new_<OperatorAnd>(qi::_val, qi::_1)] |
(operand_or >> unary)[qi::_val = new_<OperatorOr>(qi::_val, qi::_1)] |
(operand_masking >> argument_masking)[qi::_val = new_<OperatorMasking>(qi::_val, qi::_1)]);
}

private:
Expand All @@ -66,6 +82,7 @@ namespace triggerExpression {
terminal_rule operand_not;
terminal_rule operand_and;
terminal_rule operand_or;
terminal_rule operand_masking;

name_rule token_l1algo;
name_rule token_path;
Expand All @@ -76,6 +93,8 @@ namespace triggerExpression {
rule prescale;
rule operand;
rule unary;
rule token_masking;
rule argument_masking;
rule expression;
};

Expand Down Expand Up @@ -121,4 +140,4 @@ namespace triggerExpression {

} // namespace triggerExpression

#endif // HLTrigger_HLTfilters_TriggerExpressionParser_h
#endif // HLTrigger_HLTcore_TriggerExpressionParser_h
Loading

0 comments on commit 435424d

Please sign in to comment.