Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 // This tests:
0002 //   Behavior of EventSelector functions testSelectionOverlap and
0003 //   maskTriggerResults
0004 
0005 // Note - work in progress - only very cursory testing is done right now!
0006 #include "catch.hpp"
0007 
0008 #include "FWCore/Framework/interface/EventSelector.h"
0009 #include "DataFormats/Common/interface/TriggerResults.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/Framework/interface/TriggerNamesService.h"
0012 #include "FWCore/ServiceRegistry/interface/ServiceWrapper.h"
0013 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
0014 #include "FWCore/ServiceRegistry/interface/ServiceToken.h"
0015 #include "FWCore/Utilities/interface/Exception.h"
0016 
0017 #include <array>
0018 #include <vector>
0019 #include <string>
0020 #include <iostream>
0021 #include <memory>
0022 
0023 using namespace edm;
0024 
0025 typedef std::vector<std::vector<bool> > Answers;
0026 
0027 typedef std::vector<std::string> Strings;
0028 typedef std::vector<Strings> VStrings;
0029 typedef std::vector<bool> Bools;
0030 typedef std::vector<Bools> VBools;
0031 
0032 // Name all our paths. We have as many paths as there are trigger
0033 // bits.
0034 
0035 namespace {
0036   size_t const num_trig_paths = 8;
0037   std::array<char const*, num_trig_paths> cpaths = {{
0038       "ap1",
0039       "ap2",
0040       "aq1",
0041       "aq2",
0042       "bp1",
0043       "bp2",
0044       "bq1",
0045       "bq2",
0046   }};
0047   Strings trigger_path_names(cpaths.begin(), cpaths.end());
0048 
0049   struct PathSpecifiers {
0050     Strings path;
0051     PathSpecifiers(std::string const& s0,
0052                    std::string const& s1 = "",
0053                    std::string const& s2 = "",
0054                    std::string const& s3 = "",
0055                    std::string const& s4 = "",
0056                    std::string const& s5 = "",
0057                    std::string const& s6 = "",
0058                    std::string const& s7 = "",
0059                    std::string const& s8 = "",
0060                    std::string const& s9 = "")
0061         : path() {
0062       if (s0 != "")
0063         path.push_back(s0);
0064       if (s1 != "")
0065         path.push_back(s1);
0066       if (s2 != "")
0067         path.push_back(s2);
0068       if (s3 != "")
0069         path.push_back(s3);
0070       if (s4 != "")
0071         path.push_back(s4);
0072       if (s5 != "")
0073         path.push_back(s5);
0074       if (s6 != "")
0075         path.push_back(s6);
0076       if (s7 != "")
0077         path.push_back(s7);
0078       if (s8 != "")
0079         path.push_back(s8);
0080       if (s9 != "")
0081         path.push_back(s9);
0082     }
0083   };
0084 
0085   const HLTPathStatus pass = HLTPathStatus(edm::hlt::Pass);
0086   const HLTPathStatus fail = HLTPathStatus(edm::hlt::Fail);
0087   const HLTPathStatus excp = HLTPathStatus(edm::hlt::Exception);
0088   const HLTPathStatus redy = HLTPathStatus(edm::hlt::Ready);
0089 
0090   struct TrigResults {
0091     std::vector<HLTPathStatus> bit;
0092     TrigResults(HLTPathStatus const& b0,
0093                 HLTPathStatus const& b1,
0094                 HLTPathStatus const& b2,
0095                 HLTPathStatus const& b3,
0096                 HLTPathStatus const& b4,
0097                 HLTPathStatus const& b5,
0098                 HLTPathStatus const& b6,
0099                 HLTPathStatus const& b7)
0100         : bit(8) {
0101       bit[0] = b0;
0102       bit[1] = b1;
0103       bit[2] = b2;
0104       bit[3] = b3;
0105       bit[4] = b4;
0106       bit[5] = b5;
0107       bit[6] = b6;
0108       bit[7] = b7;
0109       REQUIRE(bit.size() == num_trig_paths);
0110     }
0111     void set(HLTPathStatus const& b0,
0112              HLTPathStatus const& b1,
0113              HLTPathStatus const& b2,
0114              HLTPathStatus const& b3,
0115              HLTPathStatus const& b4,
0116              HLTPathStatus const& b5,
0117              HLTPathStatus const& b6,
0118              HLTPathStatus const& b7) {
0119       bit[0] = b0;
0120       bit[1] = b1;
0121       bit[2] = b2;
0122       bit[3] = b3;
0123       bit[4] = b4;
0124       bit[5] = b5;
0125       bit[6] = b6;
0126       bit[7] = b7;
0127     }
0128   };
0129 
0130   std::ostream& operator<<(std::ostream& ost, const Strings& s) {
0131     for (Strings::const_iterator i(s.begin()), e(s.end()); i != e; ++i) {
0132       ost << *i << " ";
0133     }
0134     return ost;
0135   }
0136   std::ostream& operator<<(std::ostream& ost, const TrigResults& tr) {
0137     for (unsigned int i = 0; i < tr.bit.size(); ++i) {
0138       HLTPathStatus b = tr.bit[i];
0139       if (b.state() == edm::hlt::Ready)
0140         ost << "ready ";
0141       if (b.state() == edm::hlt::Pass)
0142         ost << "pass  ";
0143       if (b.state() == edm::hlt::Fail)
0144         ost << "fail  ";
0145       if (b.state() == edm::hlt::Exception)
0146         ost << "excp  ";
0147     }
0148     return ost;
0149   }
0150 
0151   template <size_t nb>
0152   Bools toBools(std::array<bool, nb> const& t) {
0153     Bools b;
0154     b.insert(b.end(), t.begin(), t.end());
0155     return b;
0156   }
0157 
0158   void maskTest(PathSpecifiers const& ps, TrigResults const& tr, TrigResults const& ans) {
0159     // Prepare a TriggerResults from the simpler tr
0160 
0161     HLTGlobalStatus bm(tr.bit.size());
0162     for (unsigned int b = 0; b < tr.bit.size(); ++b) {
0163       bm[b] = (tr.bit[b]);
0164     }
0165 
0166     TriggerResults results(bm, trigger_path_names);
0167 
0168     // obtain the answer from maskTriggerResults
0169 
0170     EventSelector selector(ps.path, trigger_path_names);
0171     std::shared_ptr<TriggerResults> sptr = selector.maskTriggerResults(results);
0172     TriggerResults maskTR = *sptr;
0173 
0174     // Extract the HLTPathStatus "bits" from the results.  A TriggerResults is
0175     // an HLTGlobalStatus, so this is straightforward:
0176 
0177     TrigResults mask(maskTR[0], maskTR[1], maskTR[2], maskTR[3], maskTR[4], maskTR[5], maskTR[6], maskTR[7]);
0178 
0179     // Check correctness
0180 
0181     bool ok = true;
0182     for (size_t i = 0; i != num_trig_paths; ++i) {
0183       //    HLTPathStatus mbi = mask.bit[i];
0184       //    HLTPathStatus abi =  ans.bit[i];
0185       if (mask.bit[i].state() != ans.bit[i].state())
0186         ok = false;
0187     }
0188 
0189     std::ostringstream s;
0190     if (!ok) {
0191       s << "failed to compare mask trigger results with expected answer\n"
0192         << "correct=" << ans << "\n"
0193         << "results=" << mask << "\n"
0194         << "pathspecs = " << ps.path << "\n"
0195         << "trigger results = " << tr << "\n";
0196     }
0197     REQUIRE_THAT(ok, Catch::Predicate<bool>([](bool iValue) { return iValue; }, s.str()));
0198   }
0199 }  // namespace
0200 TEST_CASE("test EventSelector overlap", "[EventSelector overlap]") {
0201   // We want to create the TriggerNamesService because it is used in
0202   // the tests.  We do that here, but first we need to build a minimal
0203   // parameter set to pass to its constructor.  Then we build the
0204   // service and setup the service system.
0205   ParameterSet proc_pset;
0206 
0207   std::string processName("HLT");
0208   proc_pset.addParameter<std::string>("@process_name", processName);
0209 
0210   ParameterSet trigPaths;
0211   trigPaths.addParameter<Strings>("@trigger_paths", trigger_path_names);
0212   proc_pset.addParameter<ParameterSet>("@trigger_paths", trigPaths);
0213 
0214   Strings endPaths;
0215   proc_pset.addParameter<Strings>("@end_paths", endPaths);
0216 
0217   // We do not care what is in these parameters for the test, they
0218   // just need to exist.
0219   Strings dummy;
0220   for (unsigned int i = 0; i < num_trig_paths; ++i) {
0221     proc_pset.addParameter<Strings>(trigger_path_names[i], dummy);
0222   }
0223   proc_pset.registerIt();
0224 
0225   // Now create and setup the service
0226   typedef edm::service::TriggerNamesService TNS;
0227   typedef serviceregistry::ServiceWrapper<TNS> w_TNS;
0228 
0229   auto tnsptr = std::make_shared<w_TNS>(std::make_unique<TNS>(proc_pset));
0230 
0231   ServiceToken serviceToken_ = ServiceRegistry::createContaining(tnsptr);
0232 
0233   //make the services available
0234   ServiceRegistry::Operate operate(serviceToken_);
0235 
0236   // We are ready to run some tests.  First, for maskTriggerResults:
0237 
0238   PathSpecifiers ps_01("ap1", "ap2", "bp1");
0239   TrigResults tr_01(fail, pass, pass, fail, pass, fail, excp, pass);
0240   TrigResults ans_01(redy, pass, redy, redy, pass, redy, redy, redy);
0241   maskTest(ps_01, tr_01, ans_01);
0242 
0243   PathSpecifiers ps_02("!ap1", "ap2", "!bp2");
0244   TrigResults tr_02(fail, pass, pass, fail, pass, fail, excp, pass);
0245   TrigResults ans_02(fail, pass, redy, redy, redy, fail, redy, redy);
0246   maskTest(ps_02, tr_02, ans_02);
0247 
0248   // TODO - test involving exception, test involving neg wildcard
0249 
0250   // Now test testSelectionOverlap
0251   // TODO - pull out the testing part of this, as for maskTest
0252   // TODO - more extensive tests
0253 
0254   PathSpecifiers ps_01a("ap1", "ap2", "bp1");
0255   PathSpecifiers ps_01b("aq1", "aq2", "bq1");
0256   REQUIRE(EventSelector::testSelectionOverlap(ps_01a.path, ps_01b.path, trigger_path_names) == evtSel::NoOverlap);
0257 
0258   PathSpecifiers ps_02a("ap1", "ap2", "bp1");
0259   PathSpecifiers ps_02b("bp1", "aq2", "bq1");
0260   REQUIRE(EventSelector::testSelectionOverlap(ps_02a.path, ps_02b.path, trigger_path_names) == evtSel::PartialOverlap);
0261 }