Skip to content

Commit

Permalink
introduce MASKING operator in triggerExpression::Parser
Browse files Browse the repository at this point in the history
  • Loading branch information
missirol committed Aug 25, 2022
1 parent 22a8608 commit e8988d9
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 65 deletions.
3 changes: 3 additions & 0 deletions HLTrigger/HLTcore/interface/TriggerExpressionEvaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ namespace triggerExpression {
// dump the logical expression to the output stream
virtual void dump(std::ostream& out) const = 0;

// apply masks based on another Evaluator
virtual void mask(Evaluator*) {}

// virtual destructor
virtual ~Evaluator() = default;
};
Expand Down
20 changes: 19 additions & 1 deletion HLTrigger/HLTcore/interface/TriggerExpressionL1uGTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,36 @@ 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},
m_useTriggersAfterMasking{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) const;

void mask(Evaluator* eval) override;

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

void maskTriggers(L1uGTReader const&);

bool useTriggersAfterMasking() const { return m_useTriggersAfterMasking; }
void useTriggersAfterMasking(bool const foo) { m_useTriggersAfterMasking = foo; }

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;
bool m_useTriggersAfterMasking;
};

} // namespace triggerExpression
Expand Down
44 changes: 41 additions & 3 deletions HLTrigger/HLTcore/interface/TriggerExpressionOperators.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define HLTrigger_HLTfilters_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* 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* 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 Down Expand Up @@ -67,7 +77,7 @@ 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;
Expand All @@ -87,7 +97,7 @@ 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;
Expand All @@ -107,16 +117,44 @@ 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 {
out << '(';
m_arg1->dump(out);
out << " XOR ";
m_arg2->dump(out);
out << ')';
}
};

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

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

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

void dump(std::ostream& out) const override {
out << '(';
m_arg1->dump(out);
out << " MASKING ";
m_arg2->dump(out);
out << ')';
}
};

Expand Down
21 changes: 16 additions & 5 deletions HLTrigger/HLTcore/interface/TriggerExpressionParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ namespace triggerExpression {
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];

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_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)] | // 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")
token_path[qi::_val = new_<PathReader>(qi::_1)]); // * (except "NOT", "AND", "OR" and "MASKING")

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

Expand All @@ -50,9 +52,15 @@ 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)]);
// operand_triggers is used to restrict "masking" to L1uGTReader and PathReader
token_triggers =
(token_l1algo[qi::_val = new_<L1uGTReader>(qi::_1)] | token_path[qi::_val = new_<PathReader>(qi::_1)]);
operand_triggers %= (token_triggers | ('(' >> operand_triggers >> ')'));

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 >> operand_triggers)[qi::_val = new_<OperatorMasking>(qi::_val, qi::_1)]);
}

private:
Expand All @@ -66,15 +74,18 @@ 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;

rule token;
rule token_triggers;
rule parenthesis;
rule element;
rule prescale;
rule operand;
rule operand_triggers;
rule unary;
rule expression;
};
Expand Down
20 changes: 19 additions & 1 deletion HLTrigger/HLTcore/interface/TriggerExpressionPathReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ namespace triggerExpression {

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

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

Expand All @@ -19,11 +24,24 @@ namespace triggerExpression {
std::vector<std::string> patterns() const override { return std::vector<std::string>{m_pattern}; }

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

void mask(Evaluator* eval) override;

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

void maskTriggers(PathReader const&);

bool useTriggersAfterMasking() const { return m_useTriggersAfterMasking; }
void useTriggersAfterMasking(bool const foo) { m_useTriggersAfterMasking = foo; }

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;
bool m_useTriggersAfterMasking;
};

} // namespace triggerExpression
Expand Down
76 changes: 61 additions & 15 deletions HLTrigger/HLTcore/src/TriggerExpressionL1uGTReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,38 @@ namespace triggerExpression {
if (word.empty())
return false;

for (auto const& trigger : m_triggers)
auto const& triggers = m_useTriggersAfterMasking ? m_triggersAfterMasking : m_triggers;

for (auto const& trigger : triggers)
if (trigger.second < word.size() and word[trigger.second])
return true;

return false;
}

void L1uGTReader::dump(std::ostream& out) const {
// in the dump() method inherited from the Evaluator base class,
// show the full list of triggers (useTriggersAfterMasking == false),
// so that the dump of the masking operator is explicit, i.e. "A MASKING B"
dump(out, false);
}

void L1uGTReader::dump(std::ostream& out, bool const useTriggersAfterMasking) const {
if (not m_initialised) {
out << "Uninitialised_L1_Expression";
return;
}
if (m_triggers.empty()) {

auto const& triggers = useTriggersAfterMasking ? m_triggersAfterMasking : m_triggers;

if (triggers.empty()) {
out << "FALSE";
} else if (m_triggers.size() == 1) {
out << m_triggers[0].first;
} else if (triggers.size() == 1) {
out << triggers[0].first;
} else {
out << "(" << m_triggers[0].first;
for (unsigned int i = 1; i < m_triggers.size(); ++i)
out << " OR " << m_triggers[i].first;
out << "(" << triggers[0].first;
for (unsigned int i = 1; i < triggers.size(); ++i)
out << " OR " << triggers[i].first;
out << ")";
}
}
Expand All @@ -61,14 +73,15 @@ namespace triggerExpression {
if (entry != triggerMap.end()) {
// single L1 bit
m_triggers.push_back(std::make_pair(m_pattern, entry->second.getIndex()));
} else
// trigger not found in the current menu
if (data.shouldThrow())
throw cms::Exception("Configuration")
<< "requested L1 trigger \"" << m_pattern << "\" does not exist in the current L1 menu";
else
edm::LogWarning("Configuration") << "requested L1 trigger \"" << m_pattern
<< "\" does not exist in the current L1 menu";
} else {
// trigger not found in the current menu
if (data.shouldThrow())
throw cms::Exception("Configuration")
<< "requested L1 trigger \"" << m_pattern << "\" does not exist in the current L1 menu";
else
edm::LogWarning("Configuration")
<< "requested L1 trigger \"" << m_pattern << "\" does not exist in the current L1 menu";
}
} else {
// expand wildcards in the pattern
bool match = false;
Expand All @@ -90,7 +103,40 @@ namespace triggerExpression {
}
}

m_triggersAfterMasking = m_triggers;
m_initialised = true;
}

void L1uGTReader::mask(Evaluator* eval) {
if (eval == nullptr)
return;

L1uGTReader* l1ugtReader = dynamic_cast<L1uGTReader*>(eval);
if (l1ugtReader == nullptr) {
edm::LogWarning("InvalidArgumentForMasking")
<< "\tL1uGTReader::mask(eval) call is a no-op:"
<< " failed to cast Evaluator* to L1uGTReader* (*eval = \"" << *eval << "\")";
return;
}

maskTriggers(*l1ugtReader);
}

void L1uGTReader::maskTriggers(L1uGTReader const& l1ugtReader) {
m_useTriggersAfterMasking = true;
auto const& triggersToMask = l1ugtReader.triggers();
// clang-format off
m_triggersAfterMasking.erase(
std::remove_if(
m_triggersAfterMasking.begin(),
m_triggersAfterMasking.end(),
[&triggersToMask](auto const& foo) {
return std::find(triggersToMask.begin(), triggersToMask.end(), foo) != triggersToMask.end();
}
),
m_triggersAfterMasking.end()
);
// clang-format on
}

} // namespace triggerExpression
Loading

0 comments on commit e8988d9

Please sign in to comment.