Skip to content

Commit

Permalink
Merge pull request #39377 from missirol/devel_hltParseXOR
Browse files Browse the repository at this point in the history
support `XOR` operator in `triggerExpression::Parser`
  • Loading branch information
cmsbuild authored Sep 14, 2022
2 parents 38d8d24 + e09de73 commit 2ce7f92
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 46 deletions.
7 changes: 5 additions & 2 deletions HLTrigger/HLTcore/interface/TriggerExpressionParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ 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_xor = qi::lexeme[qi::lit("XOR") >> delimiter];
operand_masking = qi::lexeme[qi::lit("MASKING") >> delimiter];

// "TRUE": keyword to accept all events
Expand All @@ -40,9 +41,9 @@ namespace triggerExpression {
token_l1algo %= qi::raw[qi::lexeme["L1_" >> +(qi::char_("a-zA-Z0-9_*?"))]];

// Decisions of Paths in the CMSSW configuration (e.g. high-level triggers):
// any alphanumeric pattern except for "TRUE", "FALSE", "NOT", "AND", "OR", and "MASKING"
// any alphanumeric pattern except for "TRUE", "FALSE", "NOT", "AND", "OR", "XOR" 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];
operand_and - operand_or - operand_xor - 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)]);
Expand All @@ -68,6 +69,7 @@ namespace triggerExpression {
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_xor >> unary)[qi::_val = new_<OperatorXor>(qi::_val, qi::_1)] |
(operand_masking >> argument_masking)[qi::_val = new_<OperatorMasking>(qi::_val, qi::_1)]);
}

Expand All @@ -82,6 +84,7 @@ namespace triggerExpression {
terminal_rule operand_not;
terminal_rule operand_and;
terminal_rule operand_or;
terminal_rule operand_xor;
terminal_rule operand_masking;

name_rule token_l1algo;
Expand Down
14 changes: 12 additions & 2 deletions HLTrigger/HLTcore/test/test_catch2_TriggerExpressionParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ TEST_CASE("Test TriggerExpressionParser", "[TriggerExpressionParser]") {
"((Uninitialised_Path_Expression AND TRUE) AND (NOT Uninitialised_L1_Expression))"));
REQUIRE(testExpression("NOT NOTThisHLTPath", //
"(NOT Uninitialised_Path_Expression)"));
REQUIRE(testExpression("XYZ XOR TRUE", //
"(Uninitialised_Path_Expression XOR TRUE)"));
REQUIRE(testExpression("XYZ XOR ABC AND L1_* OR DEF/10", //
"(((Uninitialised_Path_Expression XOR Uninitialised_Path_Expression) AND "
"Uninitialised_L1_Expression) OR (Uninitialised_Path_Expression / 10))"));
REQUIRE(testExpression("ThisHLTANDNOTThatORTheOther", //
"Uninitialised_Path_Expression"));
REQUIRE(testExpression("TRUEPath AND NOTPath", //
Expand Down Expand Up @@ -86,8 +91,8 @@ TEST_CASE("Test TriggerExpressionParser", "[TriggerExpressionParser]") {
"L1_*copy* MASKING L1_*copy MASKING ((L1_*copy2))", //
"((Uninitialised_L1_Expression MASKING Uninitialised_L1_Expression) MASKING Uninitialised_L1_Expression)"));
REQUIRE(testExpression(
"(A AND B OR C) MASKING D OR E", //
"((((Uninitialised_Path_Expression AND Uninitialised_Path_Expression) OR Uninitialised_Path_Expression)"
"(A AND B XOR C) MASKING D OR E", //
"((((Uninitialised_Path_Expression AND Uninitialised_Path_Expression) XOR Uninitialised_Path_Expression)"
" MASKING Uninitialised_Path_Expression) OR Uninitialised_Path_Expression)"));
REQUIRE(testExpression("EXPR_A MASKING FALSE", "(Uninitialised_Path_Expression MASKING FALSE)"));
}
Expand All @@ -96,6 +101,11 @@ TEST_CASE("Test TriggerExpressionParser", "[TriggerExpressionParser]") {
SECTION("IncorrectExpressions") {
REQUIRE(not testExpression("A | B"));
REQUIRE(not testExpression("A && B"));
REQUIRE(not testExpression("NOT"));
REQUIRE(not testExpression("AND"));
REQUIRE(not testExpression("OR"));
REQUIRE(not testExpression("XOR"));
REQUIRE(not testExpression("MASKING"));
REQUIRE(not testExpression("NOT L1_SEED1 ANDD L1_SEED2*"));
REQUIRE(not testExpression("NOT (NOTHLT_Path OR HLT_Path2))"));
REQUIRE(not testExpression("HLT_Path* NOT TRUE"));
Expand Down
42 changes: 27 additions & 15 deletions HLTrigger/HLTfilters/test/triggerResultsFilter_by_PathStatus.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@
triggerConditions = ( 'NOT(Path_1/15)AND(NOT Path_2/10)AND(NOT Path_3/6)', )
)

# accept if Path_1 and Path_2 have different results (XOR) without using XOR operator
process.filter_1xor2_withoutXOR = _triggerResultsFilter.clone(
triggerConditions = ( 'Path_1 AND NOT Path_2', 'NOT Path_1 AND Path_2', )
)

# accept if Path_1 and Path_2 have different results (XOR) using XOR operator
process.filter_1xor2_withXOR = _triggerResultsFilter.clone(
triggerConditions = ( 'Path_1 XOR Path_2', )
)

# accept if any path succeeds (wildcard, '*')
process.filter_any_star = _triggerResultsFilter.clone(
triggerConditions = ( 'Path_*', )
Expand Down Expand Up @@ -204,25 +214,27 @@
process.Check_Any_Or = cms.Path( process.filter_any_or )
process.Check_Any_Star = cms.Path( process.filter_any_star )

process.Check_1_Pre = cms.Path( process.filter_1_pre )
process.Check_1_Pre = cms.Path( process.filter_1_pre )
process.Check_1_Pre_With_Masks1 = cms.Path( process.filter_1_pre_with_masks1 )
process.Check_1_Pre_With_Masks2 = cms.Path( process.filter_1_pre_with_masks2 )
process.Check_NOT_1_Pre = cms.Path( process.filter_not_1_pre )
process.Check_2_Pre = cms.Path( process.filter_2_pre )
process.Check_Any_Pre = cms.Path( process.filter_any_pre )
process.Check_NOT_1_Pre = cms.Path( process.filter_not_1_pre )
process.Check_2_Pre = cms.Path( process.filter_2_pre )
process.Check_Any_Pre = cms.Path( process.filter_any_pre )
process.Check_Any_Pre_DoubleNOT = cms.Path( process.filter_any_pre_doubleNOT )
process.Check_Not_Any_Pre = cms.Path( process.filter_not_any_pre )

process.Check_Any_Question = cms.Path( process.filter_any_question )
process.Check_Any_StarQuestion = cms.Path( process.filter_any_starquestion )
process.Check_Wrong_Name = cms.Path( process.filter_wrong_name )
process.Check_Wrong_Pattern = cms.Path( process.filter_wrong_pattern )
process.Check_Not_Wrong_Pattern = cms.Path( ~ process.filter_wrong_pattern )
process.Check_Empty_Pattern = cms.Path( process.filter_empty_pattern )
process.Check_L1Path_Pattern = cms.Path( process.filter_l1path_pattern )
process.Check_Not_Any_Pre = cms.Path( process.filter_not_any_pre )
process.Check_1xor2_withoutXOR = cms.Path( process.filter_1xor2_withoutXOR )
process.Check_1xor2_withXOR = cms.Path( process.filter_1xor2_withXOR )

process.Check_Any_Question = cms.Path( process.filter_any_question )
process.Check_Any_StarQuestion = cms.Path( process.filter_any_starquestion )
process.Check_Wrong_Name = cms.Path( process.filter_wrong_name )
process.Check_Wrong_Pattern = cms.Path( process.filter_wrong_pattern )
process.Check_Not_Wrong_Pattern = cms.Path( ~ process.filter_wrong_pattern )
process.Check_Empty_Pattern = cms.Path( process.filter_empty_pattern )
process.Check_L1Path_Pattern = cms.Path( process.filter_l1path_pattern )
process.Check_L1Singlemuopen_Pattern = cms.Path( process.filter_l1singlemuopen_pattern )
process.Check_True_Pattern = cms.Path( process.filter_true_pattern )
process.Check_False_Pattern = cms.Path( process.filter_false_pattern )
process.Check_True_Pattern = cms.Path( process.filter_true_pattern )
process.Check_False_Pattern = cms.Path( process.filter_false_pattern )
process.Check_AlwaysNOTFalse_Pattern = cms.Path( process.filter_AlwaysNOTFalse_pattern )
process.Check_NOTAlwaysFALSE_Pattern = cms.Path( process.filter_NOTAlwaysFALSE_pattern )

Expand Down
26 changes: 14 additions & 12 deletions HLTrigger/HLTfilters/test/triggerResultsFilter_by_PathStatus.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,20 @@ TrigReport 1 16 1000 33 967 0 Check_2_Pre
TrigReport 1 17 1000 99 901 0 Check_Any_Pre
TrigReport 1 18 1000 99 901 0 Check_Any_Pre_DoubleNOT
TrigReport 1 19 1000 901 99 0 Check_Not_Any_Pre
TrigReport 1 20 1000 733 267 0 Check_Any_Question
TrigReport 1 21 1000 733 267 0 Check_Any_StarQuestion
TrigReport 1 22 1000 0 1000 0 Check_Wrong_Name
TrigReport 1 23 1000 0 1000 0 Check_Wrong_Pattern
TrigReport 1 24 1000 1000 0 0 Check_Not_Wrong_Pattern
TrigReport 1 25 1000 0 1000 0 Check_Empty_Pattern
TrigReport 1 26 1000 0 1000 0 Check_L1Path_Pattern
TrigReport 1 27 1000 0 1000 0 Check_L1Singlemuopen_Pattern
TrigReport 1 28 1000 1000 0 0 Check_True_Pattern
TrigReport 1 29 1000 0 1000 0 Check_False_Pattern
TrigReport 1 30 1000 1000 0 0 Check_AlwaysNOTFalse_Pattern
TrigReport 1 31 1000 1000 0 0 Check_NOTAlwaysFALSE_Pattern
TrigReport 1 20 1000 499 501 0 Check_1xor2_withoutXOR
TrigReport 1 21 1000 499 501 0 Check_1xor2_withXOR
TrigReport 1 22 1000 733 267 0 Check_Any_Question
TrigReport 1 23 1000 733 267 0 Check_Any_StarQuestion
TrigReport 1 24 1000 0 1000 0 Check_Wrong_Name
TrigReport 1 25 1000 0 1000 0 Check_Wrong_Pattern
TrigReport 1 26 1000 1000 0 0 Check_Not_Wrong_Pattern
TrigReport 1 27 1000 0 1000 0 Check_Empty_Pattern
TrigReport 1 28 1000 0 1000 0 Check_L1Path_Pattern
TrigReport 1 29 1000 0 1000 0 Check_L1Singlemuopen_Pattern
TrigReport 1 30 1000 1000 0 0 Check_True_Pattern
TrigReport 1 31 1000 0 1000 0 Check_False_Pattern
TrigReport 1 32 1000 1000 0 0 Check_AlwaysNOTFalse_Pattern
TrigReport 1 33 1000 1000 0 0 Check_NOTAlwaysFALSE_Pattern
@EOF

# compare to expected output of test job
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@
triggerConditions = ( 'NOT(Path_1/15)AND(NOT Path_2/10)AND(NOT Path_3/6)', )
)

# accept if Path_1 and Path_2 have different results (XOR) without using XOR operator
process.filter_1xor2_withoutXOR = _triggerResultsFilter.clone(
triggerConditions = ( 'Path_1 AND NOT Path_2', 'NOT Path_1 AND Path_2', )
)

# accept if Path_1 and Path_2 have different results (XOR) using XOR operator
process.filter_1xor2_withXOR = _triggerResultsFilter.clone(
triggerConditions = ( 'Path_1 XOR Path_2', )
)

# accept if any path succeeds (wildcard, '*')
process.filter_any_star = _triggerResultsFilter.clone(
triggerConditions = ( '*', )
Expand Down Expand Up @@ -157,14 +167,16 @@
process.path_any_or = cms.Path( process.filter_any_or )
process.path_any_star = cms.Path( process.filter_any_star )

process.path_1_pre = cms.Path( process.filter_1_pre )
process.path_1_pre = cms.Path( process.filter_1_pre )
process.path_1_pre_with_masks1 = cms.Path( process.filter_1_pre_with_masks1 )
process.path_1_pre_with_masks2 = cms.Path( process.filter_1_pre_with_masks2 )
process.path_not_1_pre = cms.Path( process.filter_not_1_pre )
process.path_2_pre = cms.Path( process.filter_2_pre )
process.path_any_pre = cms.Path( process.filter_any_pre )
process.path_not_1_pre = cms.Path( process.filter_not_1_pre )
process.path_2_pre = cms.Path( process.filter_2_pre )
process.path_any_pre = cms.Path( process.filter_any_pre )
process.path_any_pre_doubleNOT = cms.Path( process.filter_any_pre_doubleNOT )
process.path_not_any_pre = cms.Path( process.filter_not_any_pre )
process.path_not_any_pre = cms.Path( process.filter_not_any_pre )
process.Check_1xor2_withoutXOR = cms.Path( process.filter_1xor2_withoutXOR )
process.Check_1xor2_withXOR = cms.Path( process.filter_1xor2_withXOR )

process.path_any_doublestar = cms.Path( process.filter_any_doublestar )
process.path_any_question = cms.Path( process.filter_any_question )
Expand Down
22 changes: 12 additions & 10 deletions HLTrigger/HLTfilters/test/triggerResultsFilter_by_TriggerResults.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,18 @@ TrigReport 1 10 1000 33 967 0 path_2_pre
TrigReport 1 11 1000 99 901 0 path_any_pre
TrigReport 1 12 1000 99 901 0 path_any_pre_doubleNOT
TrigReport 1 13 1000 901 99 0 path_not_any_pre
TrigReport 1 14 1000 1000 0 0 path_any_doublestar
TrigReport 1 15 1000 733 267 0 path_any_question
TrigReport 1 16 1000 0 1000 0 path_wrong_name
TrigReport 1 17 1000 0 1000 0 path_wrong_pattern
TrigReport 1 18 1000 1000 0 0 path_not_wrong_pattern
TrigReport 1 19 1000 0 1000 0 path_empty_pattern
TrigReport 1 20 1000 0 1000 0 path_l1path_pattern
TrigReport 1 21 1000 0 1000 0 path_l1singlemuopen_pattern
TrigReport 1 22 1000 1000 0 0 path_true_pattern
TrigReport 1 23 1000 0 1000 0 path_false_pattern
TrigReport 1 14 1000 499 501 0 Check_1xor2_withoutXOR
TrigReport 1 15 1000 499 501 0 Check_1xor2_withXOR
TrigReport 1 16 1000 1000 0 0 path_any_doublestar
TrigReport 1 17 1000 733 267 0 path_any_question
TrigReport 1 18 1000 0 1000 0 path_wrong_name
TrigReport 1 19 1000 0 1000 0 path_wrong_pattern
TrigReport 1 20 1000 1000 0 0 path_not_wrong_pattern
TrigReport 1 21 1000 0 1000 0 path_empty_pattern
TrigReport 1 22 1000 0 1000 0 path_l1path_pattern
TrigReport 1 23 1000 0 1000 0 path_l1singlemuopen_pattern
TrigReport 1 24 1000 1000 0 0 path_true_pattern
TrigReport 1 25 1000 0 1000 0 path_false_pattern
@EOF

# compare to expected output of test job
Expand Down

0 comments on commit 2ce7f92

Please sign in to comment.