Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 
0002 #include "DataFormats/Common/interface/Handle.h"
0003 #include "DataFormats/Common/interface/TriggerResults.h"
0004 #include "DataFormats/Provenance/interface/ParameterSetID.h"
0005 #include "FWCore/Common/interface/Provenance.h"
0006 #include "FWCore/Common/interface/TriggerNames.h"
0007 #include "FWCore/Common/interface/TriggerResultsByName.h"
0008 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0009 #include "FWCore/Framework/interface/Event.h"
0010 #include "FWCore/Framework/interface/GetterOfProducts.h"
0011 #include "FWCore/Framework/interface/MakerMacros.h"
0012 #include "FWCore/Framework/interface/TriggerNamesService.h"
0013 #include "FWCore/Framework/interface/TypeMatch.h"
0014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0015 #include "FWCore/ParameterSet/interface/Registry.h"
0016 #include "FWCore/ServiceRegistry/interface/Service.h"
0017 #include "FWCore/Utilities/interface/InputTag.h"
0018 #include "FWCore/Utilities/interface/ThreadSafeRegistry.h"
0019 #include "FWCore/Utilities/interface/Exception.h"
0020 
0021 #include <cstdlib>
0022 #include <iostream>
0023 #include <string>
0024 #include <vector>
0025 
0026 namespace edm {
0027   class EventSetup;
0028 }
0029 
0030 using namespace edm;
0031 
0032 namespace edmtest {
0033 
0034   class TestTriggerNames : public edm::one::EDAnalyzer<> {
0035   public:
0036     typedef std::vector<std::string> Strings;
0037 
0038     explicit TestTriggerNames(edm::ParameterSet const&);
0039     virtual ~TestTriggerNames();
0040 
0041     virtual void analyze(edm::Event const& e, edm::EventSetup const& c);
0042     void endJob();
0043 
0044   private:
0045     unsigned int iEvent_;
0046     Strings expected_trigger_paths_;
0047     Strings expected_trigger_previous_;
0048     Strings expected_end_paths_;
0049     bool streamerSource_;
0050     bool dumpPSetRegistry_;
0051     std::vector<unsigned int> expectedTriggerResultsHLT_;
0052     std::vector<unsigned int> expectedTriggerResultsPROD_;
0053     edm::GetterOfProducts<edm::TriggerResults> getterOfTriggerResults_;
0054   };
0055 
0056   // -----------------------------------------------------------------
0057 
0058   TestTriggerNames::TestTriggerNames(edm::ParameterSet const& ps)
0059       : iEvent_(0U),
0060         expected_trigger_paths_(ps.getUntrackedParameter<Strings>("trigPaths", Strings())),
0061         expected_trigger_previous_(ps.getUntrackedParameter<Strings>("trigPathsPrevious", Strings())),
0062         expected_end_paths_(ps.getUntrackedParameter<Strings>("endPaths", Strings())),
0063         streamerSource_(ps.getUntrackedParameter<bool>("streamerSource", false)),
0064         dumpPSetRegistry_(ps.getUntrackedParameter<bool>("dumpPSetRegistry", false)),
0065         expectedTriggerResultsHLT_(ps.getUntrackedParameter<std::vector<unsigned int> >("expectedTriggerResultsHLT",
0066                                                                                         std::vector<unsigned int>())),
0067         expectedTriggerResultsPROD_(ps.getUntrackedParameter<std::vector<unsigned int> >("expectedTriggerResultsPROD",
0068                                                                                          std::vector<unsigned int>())),
0069         getterOfTriggerResults_(edm::TypeMatch(), this) {
0070     if (not expected_trigger_previous_.empty()) {
0071       callWhenNewProductsRegistered(getterOfTriggerResults_);
0072     }
0073     if (not expectedTriggerResultsHLT_.empty()) {
0074       consumes<edm::TriggerResults>(edm::InputTag("TriggerResults", "", "HLT"));
0075     }
0076     if (not expectedTriggerResultsPROD_.empty()) {
0077       consumes<edm::TriggerResults>(edm::InputTag("TriggerResults", "", "PROD"));
0078     }
0079   }
0080 
0081   // -----------------------------------------------------------------
0082 
0083   TestTriggerNames::~TestTriggerNames() {}
0084 
0085   // -----------------------------------------------------------------
0086 
0087   void TestTriggerNames::analyze(edm::Event const& e, edm::EventSetup const&) {
0088     if (dumpPSetRegistry_) {
0089       pset::Registry* psetRegistry = pset::Registry::instance();
0090       psetRegistry->print(std::cout);
0091     }
0092 
0093     // Runs some tests on the TriggerNamesService
0094     if (expected_trigger_paths_.size() > 0) {
0095       Strings triggernames;
0096       edm::Service<edm::service::TriggerNamesService> tns;
0097       triggernames = tns->getTrigPaths();
0098       if (triggernames.size() != expected_trigger_paths_.size()) {
0099         throw cms::Exception("Test Failure") << "TestTriggerNames: "
0100                                              << "Expected and actual trigger path list not the same size" << std::endl;
0101       }
0102       for (Strings::size_type i = 0; i < expected_trigger_paths_.size(); ++i) {
0103         if (triggernames[i] != expected_trigger_paths_[i]) {
0104           throw cms::Exception("Test Failure") << "TestTriggerNames: "
0105                                                << "Expected and actual trigger paths don't match" << std::endl;
0106         }
0107       }
0108     }
0109 
0110     if (expected_end_paths_.size() > 0) {
0111       Strings endnames;
0112       edm::Service<edm::service::TriggerNamesService> tns;
0113       endnames = tns->getEndPaths();
0114       if (endnames.size() != expected_end_paths_.size()) {
0115         throw cms::Exception("Test Failure") << "TestTriggerNames: "
0116                                              << "Expected and actual end path list not the same size" << std::endl;
0117       }
0118       for (Strings::size_type i = 0; i < expected_end_paths_.size(); ++i) {
0119         if (endnames[i] != expected_end_paths_[i]) {
0120           throw cms::Exception("Test Failure") << "TestTriggerNames: "
0121                                                << "Expected and actual end paths don't match" << std::endl;
0122         }
0123       }
0124     }
0125 
0126     if (expected_trigger_previous_.size() > 0) {
0127       typedef std::vector<edm::Handle<edm::TriggerResults> > Trig;
0128       Trig prod;
0129       getterOfTriggerResults_.fillHandles(e, prod);
0130 
0131       if (prod.size() == 0) {
0132         throw cms::Exception("Test Failure")
0133             << "TestTriggerNames: "
0134             << "No TriggerResults object found, expected previous trigger results" << std::endl;
0135       }
0136 
0137       Strings triggernames;
0138       edm::Service<edm::service::TriggerNamesService> tns;
0139       std::string previousProcessName;
0140       bool failFindingPreviousTriggerResults = false;
0141       auto processHistoryIter = e.processHistory().rbegin();
0142       if (processHistoryIter == e.processHistory().rend()) {
0143         failFindingPreviousTriggerResults = true;
0144       } else {
0145         ++processHistoryIter;
0146         if (processHistoryIter == e.processHistory().rend()) {
0147           failFindingPreviousTriggerResults = true;
0148         } else {
0149           previousProcessName = processHistoryIter->processName();
0150         }
0151       }
0152 
0153       auto index = 0U;
0154       while (index < prod.size() && previousProcessName != prod[index].provenance()->processName()) {
0155         ++index;
0156       }
0157       if (index == prod.size()) {
0158         failFindingPreviousTriggerResults = true;
0159       }
0160       if (failFindingPreviousTriggerResults) {
0161         throw cms::Exception("Test Failure") << "TestTriggerNames: "
0162                                              << "Failed finding previous process TriggerResults" << std::endl;
0163       }
0164 
0165       if (tns->getTrigPaths(*prod[index], triggernames)) {
0166         if (triggernames.size() != expected_trigger_previous_.size()) {
0167           std::string et;
0168           for (auto const& n : expected_trigger_previous_) {
0169             et += n + " ";
0170           }
0171           std::string tn;
0172           for (auto const& n : triggernames) {
0173             tn += n + " ";
0174           }
0175           throw cms::Exception("Test Failure") << "TestTriggerNames: "
0176                                                << "Expected and actual previous trigger path lists not the same size"
0177                                                << "\n expected: " << et << "\n actual: " << tn << std::endl;
0178         }
0179         for (Strings::size_type i = 0; i < expected_trigger_previous_.size(); ++i) {
0180           if (triggernames[i] != expected_trigger_previous_[i]) {
0181             std::string et;
0182             for (auto const& n : expected_trigger_previous_) {
0183               et += n + " ";
0184             }
0185             std::string tn;
0186             for (auto const& n : triggernames) {
0187               tn += n + " ";
0188             }
0189 
0190             throw cms::Exception("Test Failure") << "TestTriggerNames: "
0191                                                  << "Expected and actual previous trigger paths don't match"
0192                                                  << "\n expected: " << et << "\n actual: " << tn << std::endl;
0193           }
0194         }
0195       } else {
0196         throw cms::Exception("Test Failure") << "TestTriggerNames: "
0197                                              << "Failed finding trigger names from a previous process" << std::endl;
0198       }
0199       bool fromPSetRegistry;
0200       if (tns->getTrigPaths(*prod[index], triggernames, fromPSetRegistry)) {
0201         if (!fromPSetRegistry) {
0202           throw cms::Exception("Test Failure") << "TestTriggerNames: "
0203                                                << "fromPSetRegistry returned with incorrect value" << std::endl;
0204         }
0205       }
0206 
0207       // The provenance of the TriggerResults object should also determine the
0208       // ID for the parameter set that lists the trigger paths.
0209       // Test this by getting this parameter set and verifying the trigger
0210       // paths are the correct size.
0211       if (!streamerSource_) {
0212         ParameterSet const& trigpset = parameterSet(prod[index].provenance()->stable(), e.processHistory());
0213         Strings trigpaths = trigpset.getParameter<Strings>("@trigger_paths");
0214         if (trigpaths.size() != expected_trigger_previous_.size()) {
0215           throw cms::Exception("Test Failure")
0216               << "TestTriggerNames: Using provenance\n"
0217               << "Expected and actual previous trigger path not the same size" << std::endl;
0218         }
0219       }
0220 
0221       // Look again using the TriggerNames class instead
0222       // of going to the service.
0223 
0224       TriggerNames const& triggerNamesFromEvent = e.triggerNames(*prod[index]);
0225 
0226       Strings namesFromEvent = triggerNamesFromEvent.triggerNames();
0227       if (namesFromEvent.size() != expected_trigger_previous_.size()) {
0228         throw cms::Exception("Test Failure")
0229             << "TestTriggerNames: While exercising TriggerNames class\n"
0230             << "Expected and actual previous trigger path lists not the same size" << std::endl;
0231       }
0232       for (Strings::size_type i = 0; i < expected_trigger_previous_.size(); ++i) {
0233         if (namesFromEvent[i] != expected_trigger_previous_[i]) {
0234           throw cms::Exception("Test Failure") << "TestTriggerNames: While exercising TriggerNames class\n"
0235                                                << "Expected and actual previous trigger paths don't match" << std::endl;
0236         }
0237         if (triggerNamesFromEvent.triggerName(i) != expected_trigger_previous_[i]) {
0238           throw cms::Exception("Test Failure") << "TestTriggerNames: While exercising TriggerNames class\n"
0239                                                << "name from index accessor\n"
0240                                                << "Expected and actual previous trigger paths don't match" << std::endl;
0241         }
0242         // Exercise the function that returns an index
0243         if (i != triggerNamesFromEvent.triggerIndex(expected_trigger_previous_[i])) {
0244           throw cms::Exception("Test Failure") << "TestTriggerNames: While exercising TriggerNames class\n"
0245                                                << "index from name accessor\n"
0246                                                << "Expected and actual previous trigger paths don't match" << std::endl;
0247         }
0248         if (triggerNamesFromEvent.size() != expected_trigger_previous_.size()) {
0249           throw cms::Exception("Test Failure") << "TestTriggerNames: While exercising TriggerNames class\n"
0250                                                << "Checking size accessor\n"
0251                                                << "Expected and actual previous trigger paths don't match" << std::endl;
0252         }
0253       }
0254       // This causes it to find the results in the map lookup in the TEST configuration
0255       // and exercises that execution path in the code.
0256       // If you follow the execution in the debugger in EventBase::triggerNames_ in EventBase.cc
0257       // you can verify this is working correctly.
0258       if (prod.size() > 1U) {
0259         e.triggerNames(*prod[1]);
0260       }
0261     }
0262 
0263     edm::InputTag tag("TriggerResults", "", "HLT");
0264     edm::Handle<edm::TriggerResults> hTriggerResults;
0265 
0266     if (expectedTriggerResultsHLT_.size() > 0) {
0267       if (e.getByLabel(tag, hTriggerResults)) {
0268         if (hTriggerResults->size() == 0) {
0269           throw cms::Exception("Test Failure") << "TestTriggerNames: TriggerResults object from the Event "
0270                                                   "(InputTag = \"TriggerResults::HLT\") is empty (size == 0)";
0271         }
0272 
0273         edm::TriggerResultsByName resultsByNameHLT = e.triggerResultsByName(*hTriggerResults);
0274 
0275         if (hTriggerResults->parameterSetID() != resultsByNameHLT.parameterSetID() ||
0276             hTriggerResults->wasrun() != resultsByNameHLT.wasrun() ||
0277             hTriggerResults->accept() != resultsByNameHLT.accept() ||
0278             hTriggerResults->error() != resultsByNameHLT.error() ||
0279             hTriggerResults->at(0).state() != resultsByNameHLT.at("p01").state() ||
0280             hTriggerResults->at(0).index() != resultsByNameHLT.at("p01").index() ||
0281             (*hTriggerResults)[0].state() != resultsByNameHLT["p01"].state() ||
0282             (*hTriggerResults)[0].index() != resultsByNameHLT["p01"].index() ||
0283             hTriggerResults->wasrun(0) != resultsByNameHLT.wasrun("p01") ||
0284             hTriggerResults->accept(0) != resultsByNameHLT.accept("p01") ||
0285             hTriggerResults->error(0) != resultsByNameHLT.error("p01") ||
0286             hTriggerResults->state(0) != resultsByNameHLT.state("p01") ||
0287             hTriggerResults->index(0) != resultsByNameHLT.index("p01") ||
0288             hTriggerResults->at(0).state() != resultsByNameHLT.at(0).state() ||
0289             hTriggerResults->at(0).index() != resultsByNameHLT.at(0).index() ||
0290             (*hTriggerResults)[0].state() != resultsByNameHLT[0].state() ||
0291             (*hTriggerResults)[0].index() != resultsByNameHLT[0].index() ||
0292             hTriggerResults->wasrun(0) != resultsByNameHLT.wasrun(0) ||
0293             hTriggerResults->accept(0) != resultsByNameHLT.accept(0) ||
0294             hTriggerResults->error(0) != resultsByNameHLT.error(0) ||
0295             hTriggerResults->state(0) != resultsByNameHLT.state(0) ||
0296             hTriggerResults->index(0) != resultsByNameHLT.index(0)) {
0297           throw cms::Exception("Test Failure") << "TestTriggerNames: While testing TriggerResultsByName class\n"
0298                                                << "TriggerResults values do not match TriggerResultsByName values";
0299         }
0300         edm::TriggerNames const& names = e.triggerNames(*hTriggerResults);
0301         if (names.triggerNames() != resultsByNameHLT.triggerNames() || names.size() != resultsByNameHLT.size() ||
0302             names.triggerName(0) != resultsByNameHLT.triggerName(0) ||
0303             names.triggerIndex("p01") != resultsByNameHLT.triggerIndex("p01")) {
0304           throw cms::Exception("Test Failure")
0305               << "TestTriggerNames: While testing TriggerResultsByName class\n"
0306               << "TriggerNames values do not match TriggerResultsByName values" << std::endl;
0307         }
0308       }
0309     }
0310 
0311     if (expectedTriggerResultsHLT_.size() > iEvent_) {
0312       if (!hTriggerResults.isValid()) {
0313         throw cms::Exception("Test Failure") << "TestTriggerNames: While testing TriggerResultsByName class\n"
0314                                              << "Invalid TriggerResults Handle for HLT" << std::endl;
0315       }
0316 
0317       edm::TriggerResultsByName resultsByNameHLT = e.triggerResultsByName(*hTriggerResults);
0318 
0319       if (!resultsByNameHLT.isValid()) {
0320         throw cms::Exception("Test Failure") << "TestTriggerNames: While testing TriggerResultsByName class\n"
0321                                              << "Invalid object for HLT" << std::endl;
0322       }
0323       if (resultsByNameHLT.accept("p02") != (expectedTriggerResultsHLT_[iEvent_] == 1)) {
0324         throw cms::Exception("Test Failure") << "TestTriggerNames: While testing TriggerResultsByName class\n"
0325                                              << "Expected and actual HLT trigger results don't match" << std::endl;
0326       }
0327       edm::LogAbsolute("TEST") << "Event " << iEvent_ << "  " << resultsByNameHLT.accept("p02") << std::endl;
0328     }
0329 
0330     edm::InputTag tagPROD("TriggerResults", "", "PROD");
0331     edm::Handle<edm::TriggerResults> hTriggerResultsPROD;
0332 
0333     if (expectedTriggerResultsPROD_.size() > iEvent_) {
0334       e.getByLabel(tagPROD, hTriggerResultsPROD);
0335 
0336       if (!hTriggerResultsPROD.isValid()) {
0337         throw cms::Exception("Test Failure") << "TestTriggerNames: While testing TriggerResultsByName class\n"
0338                                              << "Invalid TriggerResults Handle for PROD" << std::endl;
0339       }
0340 
0341       edm::TriggerResultsByName resultsByNamePROD = e.triggerResultsByName(*hTriggerResultsPROD);
0342       if (!resultsByNamePROD.isValid()) {
0343         throw cms::Exception("Test Failure") << "TestTriggerNames: While testing TriggerResultsByName class\n"
0344                                              << "Invalid object for PROD" << std::endl;
0345       }
0346       if (resultsByNamePROD.accept("p1") != (expectedTriggerResultsPROD_[iEvent_] == 1)) {
0347         throw cms::Exception("Test Failure") << "TestTriggerNames: While testing TriggerResultsByName class\n"
0348                                              << "Expected and actual PROD trigger results don't match" << std::endl;
0349       }
0350       edm::LogAbsolute("TEST") << "Event " << iEvent_ << "  " << resultsByNamePROD.accept("p1") << std::endl;
0351     }
0352     ++iEvent_;
0353   }
0354 
0355   void TestTriggerNames::endJob() {}
0356 }  // namespace edmtest
0357 
0358 using edmtest::TestTriggerNames;
0359 
0360 DEFINE_FWK_MODULE(TestTriggerNames);