Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:47:13

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