Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:25

0001 
0002 #include "catch.hpp"
0003 
0004 #include "FWCore/Framework/interface/EventSelector.h"
0005 #include "DataFormats/Common/interface/TriggerResults.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "FWCore/Framework/interface/TriggerNamesService.h"
0008 #include "FWCore/ServiceRegistry/interface/ServiceWrapper.h"
0009 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0010 #include "FWCore/ServiceRegistry/interface/ServiceToken.h"
0011 #include "FWCore/Utilities/interface/Exception.h"
0012 
0013 #include <array>
0014 #include <vector>
0015 #include <string>
0016 #include <iostream>
0017 #include <memory>
0018 
0019 using namespace edm;
0020 
0021 typedef std::vector<std::vector<bool> > Answers;
0022 
0023 typedef std::vector<std::string> Strings;
0024 typedef std::vector<Strings> VStrings;
0025 typedef std::vector<bool> Bools;
0026 typedef std::vector<Bools> VBools;
0027 
0028 namespace {
0029 
0030   size_t constexpr numBits = 12;  // There must be a better way than this but I choose to
0031                                   // avoid modifying a whole slew of code using the array
0032                                   // instead of push_back()s.
0033 
0034   std::ostream& operator<<(std::ostream& ost, const Strings& s) {
0035     for (Strings::const_iterator i(s.begin()), e(s.end()); i != e; ++i) {
0036       ost << *i << " ";
0037     }
0038     return ost;
0039   }
0040 
0041   std::ostream& operator<<(std::ostream& ost, const Bools& b) {
0042     for (unsigned int i = 0; i < b.size(); ++i) {
0043       ost << b[i] << " ";
0044     }
0045     return ost;
0046   }
0047   template <size_t nb>
0048   Bools toBools(std::array<bool, nb> const& t) {
0049     Bools b;
0050     b.insert(b.end(), t.begin(), t.end());
0051     return b;
0052   }
0053 
0054   void testone(const Strings& paths, const Strings& pattern, const Bools& mask, bool answer, int jmask) {
0055     // There are 2 different ways to build the EventSelector.
0056     // Both should give the same result.  We exercise both here.
0057     EventSelector select_based_on_pattern_paths(pattern, paths);
0058     EventSelector select_based_on_pattern(pattern);
0059 
0060     int number_of_trigger_paths = 0;
0061     std::vector<unsigned char> bitArray;
0062 
0063     HLTGlobalStatus bm(mask.size());
0064     const HLTPathStatus pass = HLTPathStatus(edm::hlt::Pass);
0065     const HLTPathStatus fail = HLTPathStatus(edm::hlt::Fail);
0066     const HLTPathStatus ex = HLTPathStatus(edm::hlt::Exception);
0067     const HLTPathStatus ready = HLTPathStatus(edm::hlt::Ready);
0068     for (unsigned int b = 0; b < mask.size(); ++b) {
0069       bm[b] = (mask[b] ? pass : fail);
0070 
0071       // There is an alternate version of the function acceptEvent
0072       // that takes an array of characters as an argument instead
0073       // of a TriggerResults object.  These next few lines build
0074       // that array so we can test that also.
0075       if ((number_of_trigger_paths % 4) == 0)
0076         bitArray.push_back(0);
0077       int byteIndex = number_of_trigger_paths / 4;
0078       int subIndex = number_of_trigger_paths % 4;
0079       bitArray[byteIndex] |= (mask[b] ? edm::hlt::Pass : edm::hlt::Fail) << (subIndex * 2);
0080       ++number_of_trigger_paths;
0081     }
0082 
0083     if (jmask == 8 && mask.size() > 4) {
0084       bm[0] = ready;
0085       bm[4] = ex;
0086       bitArray[0] = (bitArray[0] & 0xfc) | edm::hlt::Ready;
0087       bitArray[1] = (bitArray[1] & 0xfc) | edm::hlt::Exception;
0088     }
0089 
0090     TriggerResults results(bm, paths);
0091 
0092     bool a = select_based_on_pattern_paths.acceptEvent(results);
0093     bool b = select_based_on_pattern.acceptEvent(results);
0094     bool aa = select_based_on_pattern_paths.acceptEvent(&(bitArray[0]), number_of_trigger_paths);
0095     // select_based_on_pattern.acceptEvent(&(bitArray[0]),
0096     //                                     number_of_trigger_paths);
0097     // is not a valid way to use acceptEvent.
0098     std::ostringstream s;
0099     if (a != answer || b != answer || aa != answer) {
0100       s << "failed to compare pattern with mask: "
0101         << "correct=" << answer << " "
0102         << "results=" << a << "  " << b << "  " << aa << "\n"
0103         << "pattern=" << pattern << "\n"
0104         << "mask=" << mask << "\n"
0105         << "jmask = " << jmask << "\n";
0106     }
0107     REQUIRE_THAT(answer,
0108                  Catch::Predicate<bool>(
0109                      [a, b, aa](bool answer) { return a == answer and b == answer and aa == answer; }, s.str()));
0110 
0111     // Repeat putting the list of trigger names in the pset
0112     // registry
0113 
0114     ParameterSet trigger_pset;
0115     trigger_pset.addParameter<Strings>("@trigger_paths", paths);
0116     trigger_pset.registerIt();
0117 
0118     TriggerResults results_id(bm, trigger_pset.id());
0119 
0120     bool x = select_based_on_pattern_paths.acceptEvent(results_id);
0121     bool y = select_based_on_pattern.acceptEvent(results_id);
0122 
0123     if (x != answer || y != answer) {
0124       s << "failed to compare pattern with mask using pset ID: "
0125         << "correct=" << answer << " "
0126         << "results=" << x << "  " << y << "\n"
0127         << "pattern=" << pattern << "\n"
0128         << "mask=" << mask << "\n"
0129         << "jmask = " << jmask << "\n";
0130     }
0131     REQUIRE_THAT(answer, Catch::Predicate<bool>([x, y](bool answer) { return x == answer and y == answer; }, s.str()));
0132   }
0133 
0134   void testall(const Strings& paths, const VStrings& patterns, const VBools& masks, const Answers& answers) {
0135     for (unsigned int i = 0; i < patterns.size(); ++i) {
0136       for (unsigned int j = 0; j < masks.size(); ++j) {
0137         testone(paths, patterns[i], masks[j], answers[i][j], j);
0138       }
0139     }
0140   }
0141 }  // namespace
0142 
0143 TEST_CASE("test EventSelector wildcard", "[EventSelector wildcard]") {
0144   // Name all our paths. We have as many paths as there are trigger
0145   // bits.
0146 
0147   std::array<char const*, numBits> cpaths = {{
0148       "HLTx1",
0149       "HLTx2",
0150       "HLTy1",
0151       "HLTy2",
0152       "CALIBx1",
0153       "CALIBx2",
0154       "CALIBy1",
0155       "CALIBy2",
0156       "DEBUGx1",
0157       "DEBUGx2",
0158       "DEBUGy1",
0159       "DEBUGy2",
0160   }};
0161   Strings paths(cpaths.begin(), cpaths.end());
0162 
0163   // Create our test patterns.  Each of these will be tested against each mask.
0164 
0165   VStrings patterns;
0166 
0167   Strings criteria_star;
0168   criteria_star.push_back("*");
0169   patterns.push_back(criteria_star);
0170   Strings criteria_notstar;
0171   criteria_notstar.push_back("!*");
0172   patterns.push_back(criteria_notstar);
0173   Strings criteria0;
0174   criteria0.push_back("HLTx1");
0175   criteria0.push_back("HLTy1");
0176   patterns.push_back(criteria0);
0177   Strings criteria1;
0178   criteria1.push_back("CALIBx2");
0179   criteria1.push_back("!HLTx2");
0180   patterns.push_back(criteria1);
0181   Strings criteria2;
0182   criteria2.push_back("HLT*");
0183   patterns.push_back(criteria2);
0184   Strings criteria3;
0185   criteria3.push_back("!HLT*");
0186   patterns.push_back(criteria3);
0187   Strings criteria4;
0188   criteria4.push_back("DEBUG*1");
0189   criteria4.push_back("HLT?2");
0190   patterns.push_back(criteria4);
0191   Strings criteria5;
0192   criteria5.push_back("D*x1");
0193   criteria5.push_back("CALIBx*");
0194   patterns.push_back(criteria5);
0195   Strings criteria6;
0196   criteria6.push_back("HL*1");
0197   criteria6.push_back("C?LIB*2");
0198   patterns.push_back(criteria6);
0199   Strings criteria7;
0200   criteria7.push_back("H*x1");
0201   patterns.push_back(criteria7);
0202   Strings criteria8;
0203   criteria8.push_back("!H*x1");
0204   patterns.push_back(criteria8);
0205   Strings criteria9;
0206   criteria9.push_back("C?LIB*2");
0207   patterns.push_back(criteria9);
0208 
0209   // Create our test trigger masks.
0210 
0211   VBools testmasks;
0212 
0213   std::array<bool, numBits> t0 = {{false, false, false, false, false, false, false, false, false, false, false, false}};
0214   testmasks.push_back(toBools(t0));
0215   std::array<bool, numBits> t1 = {{true, true, true, true, true, true, true, true, true, true, true, true}};
0216   testmasks.push_back(toBools(t1));
0217   std::array<bool, numBits> t2 = {{true, false, false, false, false, false, false, false, false, false, false, false}};
0218   testmasks.push_back(toBools(t2));
0219   std::array<bool, numBits> t3 = {{false, true, false, false, false, false, false, false, false, false, false, false}};
0220   testmasks.push_back(toBools(t3));
0221 
0222   std::array<bool, numBits> t4 = {{false, false, false, false, false, false, false, false, true, false, false, false}};
0223   testmasks.push_back(toBools(t4));
0224   std::array<bool, numBits> t5 = {{true, true, true, true, false, false, true, false, false, false, false, false}};
0225   testmasks.push_back(toBools(t5));
0226   std::array<bool, numBits> t6 = {{false, false, false, false, false, true, false, false, false, false, true, false}};
0227   testmasks.push_back(toBools(t6));
0228   std::array<bool, numBits> t7 = {{true, false, true, false, false, true, true, false, false, true, false, true}};
0229   testmasks.push_back(toBools(t7));
0230   std::array<bool, numBits> t8 = {{false, false, false, false, false, true, false, false, true, true, true, true}};
0231   testmasks.push_back(toBools(t8));  // For j=8 only, the first HLTx1 (false) is
0232                                      // reset to ready and the fifth CALIBx2 (true)
0233                                      // is reset to exception.
0234 
0235   // Create the answers
0236 
0237   Answers ans;
0238 
0239   std::vector<bool> ansstar;  // Answers for criteria star: {{ "*" }};
0240   ansstar.push_back(false);   // f f f f f f f f f f f f
0241   ansstar.push_back(true);    // t t t t t t t t t t t t
0242   ansstar.push_back(true);    // t f f f f f f f f f f f
0243   ansstar.push_back(true);    // f t f f f f f f f f f f
0244   ansstar.push_back(true);    // f f f f f f f f t f f f
0245   ansstar.push_back(true);    // t t t t f f t f f f f f
0246   ansstar.push_back(true);    // f f f f f t f f f f t f
0247   ansstar.push_back(true);    // t f f f f t t f f t f t
0248   ansstar.push_back(true);    // r f f f e t f f t t t t
0249 
0250   ans.push_back(ansstar);
0251 
0252   std::vector<bool> ansnotstar;  // Answers for criteria notstar: {{ "!*" }};
0253   ansnotstar.push_back(true);    // f f f f f f f f f f f f
0254   ansnotstar.push_back(false);   // t t t t t t t t t t t t
0255   ansnotstar.push_back(false);   // t f f f f f f f f f f f
0256   ansnotstar.push_back(false);   // f t f f f f f f f f f f
0257   ansnotstar.push_back(false);   // f f f f f f f f t f f f
0258   ansnotstar.push_back(false);   // t t t t f f t f f f f f
0259   ansnotstar.push_back(false);   // f f f f f t f f f f t f
0260   ansnotstar.push_back(false);   // t f f f f t t f f t f t
0261   ansnotstar.push_back(false);   // r f f f e t f f t t t t
0262 
0263   ans.push_back(ansnotstar);
0264 
0265   std::vector<bool> ans0;  // Answers for criteria 0:{{ "HLTx1", "HLTy1" }};
0266   ans0.push_back(false);   // f f f f f f f f f f f f
0267   ans0.push_back(true);    // t t t t t t t t t t t t
0268   ans0.push_back(true);    // t f f f f f f f f f f f
0269   ans0.push_back(false);   // f t f f f f f f f f f f
0270   ans0.push_back(false);   // f f f f f f f f t f f f
0271   ans0.push_back(true);    // t t t t f f t f f f f f
0272   ans0.push_back(false);   // f f f f f t f f f f t f
0273   ans0.push_back(true);    // t f f f f t t f f t f t
0274   ans0.push_back(false);   // r f f f e t f f t t t t
0275 
0276   ans.push_back(ans0);
0277 
0278   std::vector<bool> ans1;  // Answers for criteria 1:{{"CALIBx2","!HLTx2"}};
0279   ans1.push_back(true);    // f f f f f f f f f f f f
0280   ans1.push_back(true);    // t t t t t t t t t t t t
0281   ans1.push_back(true);    // t f f f f f f f f f f f
0282   ans1.push_back(false);   // f t f f f f f f f f f f
0283   ans1.push_back(true);    // f f f f f f f f t f f f
0284   ans1.push_back(false);   // t t t t f f t f f f f f
0285   ans1.push_back(true);    // f f f f f t f f f f t f
0286   ans1.push_back(true);    // t f f f f t t f f t f t
0287   ans1.push_back(true);    // r f f f e t f f t t t t
0288 
0289   ans.push_back(ans1);
0290 
0291   std::vector<bool> ans2;  // Answers for criteria 2:{{ "HLT*" }};
0292   ans2.push_back(false);   // f f f f f f f f f f f f
0293   ans2.push_back(true);    // t t t t t t t t t t t t
0294   ans2.push_back(true);    // t f f f f f f f f f f f
0295   ans2.push_back(true);    // f t f f f f f f f f f f
0296   ans2.push_back(false);   // f f f f f f f f t f f f
0297   ans2.push_back(true);    // t t t t f f t f f f f f
0298   ans2.push_back(false);   // f f f f f t f f f f t f
0299   ans2.push_back(true);    // t f f f f t t f f t f t
0300   ans2.push_back(false);   // r f f f e t f f t t t t
0301 
0302   ans.push_back(ans2);
0303 
0304   std::vector<bool> ans3;  // Answers for criteria 3:{{ "!HLT*" }};
0305   ans3.push_back(true);    // f f f f f f f f f f f f
0306   ans3.push_back(false);   // t t t t t t t t t t t t
0307   ans3.push_back(false);   // t f f f f f f f f f f f
0308   ans3.push_back(false);   // f t f f f f f f f f f f
0309   ans3.push_back(true);    // f f f f f f f f t f f f
0310   ans3.push_back(false);   // t t t t f f t f f f f f
0311   ans3.push_back(true);    // f f f f f t f f f f t f
0312   ans3.push_back(false);   // t f f f f t t f f t f t
0313   ans3.push_back(false);   // r f f f e t f f t t t t // ready is not fail
0314 
0315   ans.push_back(ans3);
0316 
0317   std::vector<bool> ans4;  // Answers for criteria 4:{{"DEBUG*1","HLT?2"}};
0318   ans4.push_back(false);   // f f f f f f f f f f f f
0319   ans4.push_back(true);    // t t t t t t t t t t t t
0320   ans4.push_back(false);   // t f f f f f f f f f f f
0321   ans4.push_back(true);    // f t f f f f f f f f f f
0322   ans4.push_back(true);    // f f f f f f f f t f f f
0323   ans4.push_back(true);    // t t t t f f t f f f f f
0324   ans4.push_back(true);    // f f f f f t f f f f t f
0325   ans4.push_back(false);   // t f f f f t t f f t f t
0326   ans4.push_back(true);    // r f f f e t f f t t t t
0327 
0328   ans.push_back(ans4);
0329 
0330   std::vector<bool> ans5;  // Answers for criteria 5:{{ "D*x1", "CALIBx*" }};
0331   ans5.push_back(false);   // f f f f f f f f f f f f
0332   ans5.push_back(true);    // t t t t t t t t t t t t
0333   ans5.push_back(false);   // t f f f f f f f f f f f
0334   ans5.push_back(false);   // f t f f f f f f f f f f
0335   ans5.push_back(true);    // f f f f f f f f t f f f
0336   ans5.push_back(false);   // t t t t f f t f f f f f
0337   ans5.push_back(true);    // f f f f f t f f f f t f
0338   ans5.push_back(true);    // t f f f f t t f f t f t
0339   ans5.push_back(true);    // r f f f e t f f t t t t
0340 
0341   ans.push_back(ans5);
0342 
0343   std::vector<bool> ans6;  // Answers for criteria 6:{{ "HL*1", "C?LIB*2" }};
0344   ans6.push_back(false);   // f f f f f f f f f f f f
0345   ans6.push_back(true);    // t t t t t t t t t t t t
0346   ans6.push_back(true);    // t f f f f f f f f f f f
0347   ans6.push_back(false);   // f t f f f f f f f f f f
0348   ans6.push_back(false);   // f f f f f f f f t f f f
0349   ans6.push_back(true);    // t t t t f f t f f f f f
0350   ans6.push_back(true);    // f f f f f t f f f f t f
0351   ans6.push_back(true);    // t f f f f t t f f t f t
0352   ans6.push_back(true);    // r f f f e t f f t t t t
0353 
0354   ans.push_back(ans6);
0355 
0356   std::vector<bool> ans7;  // Answers for criteria7:{{ "H*x1" }};
0357   ans7.push_back(false);   // f f f f f f f f f f f f
0358   ans7.push_back(true);    // t t t t t t t t t t t t
0359   ans7.push_back(true);    // t f f f f f f f f f f f
0360   ans7.push_back(false);   // f t f f f f f f f f f f
0361   ans7.push_back(false);   // f f f f f f f f t f f f
0362   ans7.push_back(true);    // t t t t f f t f f f f f
0363   ans7.push_back(false);   // f f f f f t f f f f t f
0364   ans7.push_back(true);    // t f f f f t t f f t f t
0365   ans7.push_back(false);   // r f f f e t f f t t t t
0366 
0367   ans.push_back(ans7);
0368 
0369   std::vector<bool> ans8;  // Answers for criteria8:{{ "!H*x1" }};
0370   ans8.push_back(true);    // f f f f f f f f f f f f
0371   ans8.push_back(false);   // t t t t t t t t t t t t
0372   ans8.push_back(false);   // t f f f f f f f f f f f
0373   ans8.push_back(true);    // f t f f f f f f f f f f
0374   ans8.push_back(true);    // f f f f f f f f t f f f
0375   ans8.push_back(false);   // t t t t f f t f f f f f
0376   ans8.push_back(true);    // f f f f f t f f f f t f
0377   ans8.push_back(false);   // t f f f f t t f f t f t
0378   ans8.push_back(false);   // r f f f e t f f t t t t -- false because ready does not
0379                            //                 itself cause an accept
0380 
0381   ans.push_back(ans8);
0382 
0383   std::vector<bool> ans9;  // Answers for criteria 9:{{ "C?LIB*2" }};
0384   ans9.push_back(false);   // f f f f f f f f f f f f
0385   ans9.push_back(true);    // t t t t t t t t t t t t
0386   ans9.push_back(false);   // t f f f f f f f f f f f
0387   ans9.push_back(false);   // f t f f f f f f f f f f
0388   ans9.push_back(false);   // f f f f f f f f t f f f
0389   ans9.push_back(false);   // t t t t f f t f f f f f
0390   ans9.push_back(true);    // f f f f f t f f f f t f
0391   ans9.push_back(true);    // t f f f f t t f f t f t
0392   ans9.push_back(true);    // r f f f e t f f t t t t
0393 
0394   ans.push_back(ans9);
0395 
0396   // The following code is identical to that in EventSelector_t.cpp:
0397 
0398   // We want to create the TriggerNamesService because it is used in
0399   // the tests.  We do that here, but first we need to build a minimal
0400   // parameter set to pass to its constructor.  Then we build the
0401   // service and setup the service system.
0402   ParameterSet proc_pset;
0403 
0404   std::string processName("HLT");
0405   proc_pset.addParameter<std::string>("@process_name", processName);
0406 
0407   ParameterSet trigPaths;
0408   trigPaths.addParameter<Strings>("@trigger_paths", paths);
0409   proc_pset.addParameter<ParameterSet>("@trigger_paths", trigPaths);
0410 
0411   Strings endPaths;
0412   proc_pset.addParameter<Strings>("@end_paths", endPaths);
0413 
0414   // We do not care what is in these parameters for the test, they
0415   // just need to exist.
0416   Strings dummy;
0417   for (size_t i = 0; i < numBits; ++i) {
0418     proc_pset.addParameter<Strings>(paths[i], dummy);
0419   }
0420   proc_pset.registerIt();
0421 
0422   // Now create and setup the service
0423   typedef edm::service::TriggerNamesService TNS;
0424   typedef serviceregistry::ServiceWrapper<TNS> w_TNS;
0425 
0426   auto tnsptr = std::make_shared<w_TNS>(std::make_unique<TNS>(proc_pset));
0427 
0428   ServiceToken serviceToken_ = ServiceRegistry::createContaining(tnsptr);
0429 
0430   //make the services available
0431   ServiceRegistry::Operate operate(serviceToken_);
0432 
0433   // We are ready to run some tests
0434 
0435   testall(paths, patterns, testmasks, ans);
0436 }