Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:28:17

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