Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:37:21

0001 // -*- C++ -*-
0002 //
0003 // Package:    PatAlgos
0004 // Class:      pat::PATTriggerEventProducer
0005 //
0006 //
0007 /**
0008   \class    pat::PATTriggerEventProducer PATTriggerEventProducer.h "PhysicsTools/PatAlgos/plugins/PATTriggerEventProducer.h"
0009   \brief    Produces the central entry point to full PAT trigger information
0010 
0011    This producer extract general trigger and conditions information from
0012    - the edm::TriggerResults written by the HLT process,
0013    - the ConditionsInEdm products,
0014    - the process history and
0015    - the GlobalTrigger information in the event and the event setup
0016    and writes it together with links to the full PAT trigger information collections and PAT trigger match results to
0017    - the pat::TriggerEvent
0018 
0019    For me information, s.
0020    https://twiki.cern.ch/twiki/bin/view/CMS/SWGuidePATTrigger
0021 
0022   \author   Volker Adler
0023   \version  $Id: PATTriggerEventProducer.h,v 1.11 2010/11/27 15:16:20 vadler Exp $
0024 */
0025 
0026 #include "FWCore/Utilities/interface/transform.h"
0027 #include "FWCore/Framework/interface/InputTagMatch.h"
0028 #include "DataFormats/Common/interface/TriggerResults.h"
0029 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
0030 #include "CondFormats/L1TObjects/interface/L1GtTriggerMenu.h"
0031 #include "CondFormats/DataRecord/interface/L1GtTriggerMenuRcd.h"
0032 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0033 #include "FWCore/ParameterSet/interface/Registry.h"
0034 #include "DataFormats/Common/interface/AssociativeIterator.h"
0035 #include "FWCore/Framework/interface/ESHandle.h"
0036 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0037 #include "FWCore/Framework/interface/stream/EDProducer.h"
0038 #include "FWCore/Framework/interface/GetterOfProducts.h"
0039 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0040 #include "FWCore/Utilities/interface/InputTag.h"
0041 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
0042 #include "DataFormats/PatCandidates/interface/TriggerEvent.h"
0043 #include "DataFormats/Common/interface/ConditionsInEdm.h"
0044 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0045 #include "HLTrigger/HLTcore/interface/HLTConfigProvider.h"
0046 
0047 #include <cassert>
0048 #include <string>
0049 #include <vector>
0050 
0051 namespace pat {
0052 
0053   class PATTriggerEventProducer : public edm::stream::EDProducer<> {
0054   public:
0055     explicit PATTriggerEventProducer(const edm::ParameterSet& iConfig);
0056     ~PATTriggerEventProducer() override {}
0057 
0058   private:
0059     void beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) override;
0060     void beginLuminosityBlock(const edm::LuminosityBlock& iLumi, const edm::EventSetup& iSetup) override;
0061     void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0062 
0063     std::string nameProcess_;  // configuration
0064     bool autoProcessName_;
0065     edm::InputTag tagTriggerProducer_;  // configuration (optional with default)
0066     edm::EDGetTokenT<TriggerAlgorithmCollection> triggerAlgorithmCollectionToken_;
0067     edm::EDGetTokenT<TriggerConditionCollection> triggerConditionCollectionToken_;
0068     edm::EDGetTokenT<TriggerPathCollection> triggerPathCollectionToken_;
0069     edm::EDGetTokenT<TriggerFilterCollection> triggerFilterCollectionToken_;
0070     edm::EDGetTokenT<TriggerObjectCollection> triggerObjectCollectionToken_;
0071     std::vector<edm::InputTag> tagsTriggerMatcher_;  // configuration (optional)
0072     std::vector<edm::EDGetTokenT<TriggerObjectStandAloneMatch> > triggerMatcherTokens_;
0073     // L1
0074     edm::InputTag tagL1Gt_;  // configuration (optional with default)
0075     edm::EDGetTokenT<L1GlobalTriggerReadoutRecord> l1GtToken_;
0076     // HLT
0077     HLTConfigProvider hltConfig_;
0078     bool hltConfigInit_;
0079     edm::InputTag tagTriggerResults_;  // configuration (optional with default)
0080     edm::GetterOfProducts<edm::TriggerResults> triggerResultsGetter_;
0081     edm::InputTag tagTriggerEvent_;  // configuration (optional with default)
0082     // Conditions
0083     edm::InputTag tagCondGt_;  // configuration (optional with default)
0084     edm::EDGetTokenT<edm::ConditionsInRunBlock> tagCondGtRunToken_;
0085     edm::EDGetTokenT<edm::ConditionsInLumiBlock> tagCondGtLumiToken_;
0086     edm::EDGetTokenT<edm::ConditionsInEventBlock> tagCondGtEventToken_;
0087     edm::ConditionsInRunBlock condRun_;
0088     edm::ConditionsInLumiBlock condLumi_;
0089     bool gtCondRunInit_ = false;
0090     bool gtCondLumiInit_ = false;
0091     const edm::ESGetToken<L1GtTriggerMenu, L1GtTriggerMenuRcd> handleL1GtTriggerMenuToken_;
0092   };
0093 
0094 }  // namespace pat
0095 
0096 using namespace pat;
0097 using namespace edm;
0098 
0099 PATTriggerEventProducer::PATTriggerEventProducer(const ParameterSet& iConfig)
0100     : nameProcess_(iConfig.getParameter<std::string>("processName")),
0101       autoProcessName_(nameProcess_ == "*"),
0102       tagTriggerProducer_("patTrigger"),
0103       tagsTriggerMatcher_(),
0104       // L1 configuration parameters
0105       tagL1Gt_(),
0106       // HLTConfigProvider
0107       hltConfigInit_(false),
0108       // HLT configuration parameters
0109       tagTriggerResults_("TriggerResults"),
0110       tagTriggerEvent_("hltTriggerSummaryAOD"),
0111       // Conditions configuration parameters
0112       tagCondGt_(),
0113       // Conditions
0114       condRun_(),
0115       condLumi_(),
0116       handleL1GtTriggerMenuToken_{esConsumes()} {
0117   if (iConfig.exists("triggerResults"))
0118     tagTriggerResults_ = iConfig.getParameter<InputTag>("triggerResults");
0119   triggerResultsGetter_ =
0120       GetterOfProducts<TriggerResults>(InputTagMatch(InputTag(tagTriggerResults_.label(),
0121                                                               tagTriggerResults_.instance(),
0122                                                               autoProcessName_ ? std::string("") : nameProcess_)),
0123                                        this);
0124   if (iConfig.exists("triggerEvent"))
0125     tagTriggerEvent_ = iConfig.getParameter<InputTag>("triggerEvent");
0126   if (iConfig.exists("patTriggerProducer"))
0127     tagTriggerProducer_ = iConfig.getParameter<InputTag>("patTriggerProducer");
0128   triggerAlgorithmCollectionToken_ = mayConsume<TriggerAlgorithmCollection>(tagTriggerProducer_);
0129   triggerConditionCollectionToken_ = mayConsume<TriggerConditionCollection>(tagTriggerProducer_);
0130   triggerPathCollectionToken_ = mayConsume<TriggerPathCollection>(tagTriggerProducer_);
0131   triggerFilterCollectionToken_ = mayConsume<TriggerFilterCollection>(tagTriggerProducer_);
0132   triggerObjectCollectionToken_ = mayConsume<TriggerObjectCollection>(tagTriggerProducer_);
0133   if (iConfig.exists("condGtTag")) {
0134     tagCondGt_ = iConfig.getParameter<InputTag>("condGtTag");
0135     tagCondGtRunToken_ = mayConsume<ConditionsInRunBlock, InRun>(tagCondGt_);
0136     tagCondGtLumiToken_ = mayConsume<ConditionsInLumiBlock, InLumi>(tagCondGt_);
0137     tagCondGtEventToken_ = mayConsume<ConditionsInEventBlock>(tagCondGt_);
0138   }
0139   if (iConfig.exists("l1GtTag"))
0140     tagL1Gt_ = iConfig.getParameter<InputTag>("l1GtTag");
0141   l1GtToken_ = mayConsume<L1GlobalTriggerReadoutRecord>(tagL1Gt_);
0142   if (iConfig.exists("patTriggerMatches"))
0143     tagsTriggerMatcher_ = iConfig.getParameter<std::vector<InputTag> >("patTriggerMatches");
0144   triggerMatcherTokens_ = vector_transform(
0145       tagsTriggerMatcher_, [this](InputTag const& tag) { return mayConsume<TriggerObjectStandAloneMatch>(tag); });
0146 
0147   callWhenNewProductsRegistered([this](BranchDescription const& bd) {
0148     if (not(this->autoProcessName_ and bd.processName() == this->moduleDescription().processName())) {
0149       triggerResultsGetter_(bd);
0150     }
0151   });
0152 
0153   for (size_t iMatch = 0; iMatch < tagsTriggerMatcher_.size(); ++iMatch) {
0154     produces<TriggerObjectMatch>(tagsTriggerMatcher_.at(iMatch).label());
0155   }
0156   produces<TriggerEvent>();
0157 }
0158 
0159 void PATTriggerEventProducer::beginRun(const Run& iRun, const EventSetup& iSetup) {
0160   // Initialize process name
0161   if (autoProcessName_) {
0162     // reset
0163     nameProcess_ = "*";
0164     // determine process name from last run TriggerSummaryProducerAOD module in process history of input
0165     const ProcessHistory& processHistory(iRun.processHistory());
0166     ProcessConfiguration processConfiguration;
0167     ParameterSet processPSet;
0168     // unbroken loop, which relies on time ordering (accepts the last found entry)
0169     for (ProcessHistory::const_iterator iHist = processHistory.begin(); iHist != processHistory.end(); ++iHist) {
0170       if (processHistory.getConfigurationForProcess(iHist->processName(), processConfiguration) &&
0171           pset::Registry::instance()->getMapped(processConfiguration.parameterSetID(), processPSet) &&
0172           processPSet.exists(tagTriggerEvent_.label())) {
0173         nameProcess_ = iHist->processName();
0174         LogDebug("autoProcessName") << "HLT process name '" << nameProcess_ << "' discovered";
0175       }
0176     }
0177     // terminate, if nothing is found
0178     if (nameProcess_ == "*") {
0179       LogError("autoProcessName") << "trigger::TriggerEvent product with label '" << tagTriggerEvent_.label()
0180                                   << "' not produced according to process history of input data\n"
0181                                   << "No trigger information produced.";
0182       return;
0183     }
0184     LogInfo("autoProcessName") << "HLT process name " << nameProcess_ << " used for PAT trigger information";
0185   }
0186   // adapt configuration of used input tags
0187   if (tagTriggerResults_.process().empty() || tagTriggerResults_.process() == "*") {
0188     tagTriggerResults_ = InputTag(tagTriggerResults_.label(), tagTriggerResults_.instance(), nameProcess_);
0189   } else if (tagTriggerResults_.process() != nameProcess_) {
0190     LogWarning("triggerResultsTag") << "TriggerResults process name '" << tagTriggerResults_.process()
0191                                     << "' differs from HLT process name '" << nameProcess_ << "'";
0192   }
0193   if (tagTriggerEvent_.process().empty() || tagTriggerEvent_.process() == "*") {
0194     tagTriggerEvent_ = InputTag(tagTriggerEvent_.label(), tagTriggerEvent_.instance(), nameProcess_);
0195   } else if (tagTriggerEvent_.process() != nameProcess_) {
0196     LogWarning("triggerEventTag") << "TriggerEvent process name '" << tagTriggerEvent_.process()
0197                                   << "' differs from HLT process name '" << nameProcess_ << "'";
0198   }
0199 
0200   gtCondRunInit_ = false;
0201   if (!tagCondGt_.label().empty()) {
0202     Handle<ConditionsInRunBlock> condRunBlock;
0203     iRun.getByToken(tagCondGtRunToken_, condRunBlock);
0204     if (condRunBlock.isValid()) {
0205       condRun_ = *condRunBlock;
0206       gtCondRunInit_ = true;
0207     } else {
0208       LogError("conditionsInEdm") << "ConditionsInRunBlock product with InputTag '" << tagCondGt_.encode()
0209                                   << "' not in run";
0210     }
0211   }
0212 
0213   // Initialize HLTConfigProvider
0214   hltConfigInit_ = false;
0215   bool changed(true);
0216   if (!hltConfig_.init(iRun, iSetup, nameProcess_, changed)) {
0217     LogError("hltConfigExtraction") << "HLT config extraction error with process name '" << nameProcess_ << "'";
0218   } else if (hltConfig_.size() <= 0) {
0219     LogError("hltConfigSize") << "HLT config size error";
0220   } else
0221     hltConfigInit_ = true;
0222 }
0223 
0224 void PATTriggerEventProducer::beginLuminosityBlock(const LuminosityBlock& iLuminosityBlock, const EventSetup& iSetup) {
0225   // Terminate, if auto process name determination failed
0226   if (nameProcess_ == "*")
0227     return;
0228 
0229   gtCondLumiInit_ = false;
0230   if (!tagCondGt_.label().empty()) {
0231     Handle<ConditionsInLumiBlock> condLumiBlock;
0232     iLuminosityBlock.getByToken(tagCondGtLumiToken_, condLumiBlock);
0233     if (condLumiBlock.isValid()) {
0234       condLumi_ = *condLumiBlock;
0235       gtCondLumiInit_ = true;
0236     } else {
0237       LogError("conditionsInEdm") << "ConditionsInLumiBlock product with InputTag '" << tagCondGt_.encode()
0238                                   << "' not in lumi";
0239     }
0240   }
0241 }
0242 
0243 void PATTriggerEventProducer::produce(Event& iEvent, const EventSetup& iSetup) {
0244   // Terminate, if auto process name determination failed
0245   if (nameProcess_ == "*")
0246     return;
0247 
0248   if (!hltConfigInit_)
0249     return;
0250 
0251   auto handleL1GtTriggerMenu = iSetup.getHandle(handleL1GtTriggerMenuToken_);
0252   Handle<TriggerResults> handleTriggerResults;
0253   iEvent.getByLabel(tagTriggerResults_, handleTriggerResults);
0254   //   iEvent.getByToken( triggerResultsToken_, handleTriggerResults );
0255   if (!handleTriggerResults.isValid()) {
0256     LogError("triggerResultsValid") << "TriggerResults product with InputTag '" << tagTriggerResults_.encode()
0257                                     << "' not in event\n"
0258                                     << "No trigger information produced";
0259     return;
0260   }
0261   Handle<TriggerAlgorithmCollection> handleTriggerAlgorithms;
0262   iEvent.getByToken(triggerAlgorithmCollectionToken_, handleTriggerAlgorithms);
0263   Handle<TriggerConditionCollection> handleTriggerConditions;
0264   iEvent.getByToken(triggerConditionCollectionToken_, handleTriggerConditions);
0265   Handle<TriggerPathCollection> handleTriggerPaths;
0266   iEvent.getByToken(triggerPathCollectionToken_, handleTriggerPaths);
0267   Handle<TriggerFilterCollection> handleTriggerFilters;
0268   iEvent.getByToken(triggerFilterCollectionToken_, handleTriggerFilters);
0269   Handle<TriggerObjectCollection> handleTriggerObjects;
0270   iEvent.getByToken(triggerObjectCollectionToken_, handleTriggerObjects);
0271 
0272   bool physDecl(false);
0273   if (iEvent.isRealData() && !tagL1Gt_.label().empty()) {
0274     Handle<L1GlobalTriggerReadoutRecord> handleL1GlobalTriggerReadoutRecord;
0275     iEvent.getByToken(l1GtToken_, handleL1GlobalTriggerReadoutRecord);
0276     if (handleL1GlobalTriggerReadoutRecord.isValid()) {
0277       L1GtFdlWord fdlWord = handleL1GlobalTriggerReadoutRecord->gtFdlWord();
0278       if (fdlWord.physicsDeclared() == 1) {
0279         physDecl = true;
0280       }
0281     } else {
0282       LogError("l1GlobalTriggerReadoutRecordValid")
0283           << "L1GlobalTriggerReadoutRecord product with InputTag '" << tagL1Gt_.encode() << "' not in event";
0284     }
0285   } else {
0286     physDecl = true;
0287   }
0288 
0289   // produce trigger event
0290 
0291   auto triggerEvent = std::make_unique<TriggerEvent>(handleL1GtTriggerMenu->gtTriggerMenuName(),
0292                                                      std::string(hltConfig_.tableName()),
0293                                                      handleTriggerResults->wasrun(),
0294                                                      handleTriggerResults->accept(),
0295                                                      handleTriggerResults->error(),
0296                                                      physDecl);
0297   // set product references to trigger collections
0298   if (handleTriggerAlgorithms.isValid()) {
0299     triggerEvent->setAlgorithms(handleTriggerAlgorithms);
0300   } else {
0301     LogError("triggerAlgorithmsValid") << "pat::TriggerAlgorithmCollection product with InputTag '"
0302                                        << tagTriggerProducer_.encode() << "' not in event";
0303   }
0304   if (handleTriggerConditions.isValid()) {
0305     triggerEvent->setConditions(handleTriggerConditions);
0306   } else {
0307     LogError("triggerConditionsValid") << "pat::TriggerConditionCollection product with InputTag '"
0308                                        << tagTriggerProducer_.encode() << "' not in event";
0309   }
0310   if (handleTriggerPaths.isValid()) {
0311     triggerEvent->setPaths(handleTriggerPaths);
0312   } else {
0313     LogError("triggerPathsValid") << "pat::TriggerPathCollection product with InputTag '"
0314                                   << tagTriggerProducer_.encode() << "' not in event";
0315   }
0316   if (handleTriggerFilters.isValid()) {
0317     triggerEvent->setFilters(handleTriggerFilters);
0318   } else {
0319     LogError("triggerFiltersValid") << "pat::TriggerFilterCollection product with InputTag '"
0320                                     << tagTriggerProducer_.encode() << "' not in event";
0321   }
0322   if (handleTriggerObjects.isValid()) {
0323     triggerEvent->setObjects(handleTriggerObjects);
0324   } else {
0325     LogError("triggerObjectsValid") << "pat::TriggerObjectCollection product with InputTag '"
0326                                     << tagTriggerProducer_.encode() << "' not in event";
0327   }
0328   if (gtCondRunInit_) {
0329     triggerEvent->setLhcFill(condRun_.lhcFillNumber);
0330     triggerEvent->setBeamMode(condRun_.beamMode);
0331     triggerEvent->setBeamMomentum(condRun_.beamMomentum);
0332     triggerEvent->setBCurrentStart(condRun_.BStartCurrent);
0333     triggerEvent->setBCurrentStop(condRun_.BStopCurrent);
0334     triggerEvent->setBCurrentAvg(condRun_.BAvgCurrent);
0335   }
0336   if (gtCondLumiInit_) {
0337     triggerEvent->setIntensityBeam1(condLumi_.totalIntensityBeam1);
0338     triggerEvent->setIntensityBeam2(condLumi_.totalIntensityBeam2);
0339   }
0340   if (!tagCondGt_.label().empty()) {
0341     Handle<ConditionsInEventBlock> condEventBlock;
0342     iEvent.getByToken(tagCondGtEventToken_, condEventBlock);
0343     if (condEventBlock.isValid()) {
0344       triggerEvent->setBstMasterStatus(condEventBlock->bstMasterStatus);
0345       triggerEvent->setTurnCount(condEventBlock->turnCountNumber);
0346     } else {
0347       LogError("conditionsInEdm") << "ConditionsInEventBlock product with InputTag '" << tagCondGt_.encode()
0348                                   << "' not in event";
0349     }
0350   }
0351 
0352   // produce trigger match association and set references
0353   if (handleTriggerObjects.isValid()) {
0354     for (size_t iMatch = 0; iMatch < tagsTriggerMatcher_.size(); ++iMatch) {
0355       const std::string labelTriggerObjectMatcher(tagsTriggerMatcher_.at(iMatch).label());
0356       // copy trigger match association using TriggerObjectStandAlone to those using TriggerObject
0357       // relying on the fact, that only one candidate collection is present in the association
0358       Handle<TriggerObjectStandAloneMatch> handleTriggerObjectStandAloneMatch;
0359       iEvent.getByToken(triggerMatcherTokens_.at(iMatch), handleTriggerObjectStandAloneMatch);
0360       if (!handleTriggerObjectStandAloneMatch.isValid()) {
0361         LogError("triggerMatchValid") << "pat::TriggerObjectStandAloneMatch product with InputTag '"
0362                                       << labelTriggerObjectMatcher << "' not in event";
0363         continue;
0364       }
0365       auto it = makeAssociativeIterator<reco::CandidateBaseRef>(*handleTriggerObjectStandAloneMatch, iEvent);
0366       auto itEnd = it.end();
0367       Handle<reco::CandidateView> handleCands;
0368       if (it != itEnd)
0369         iEvent.get(it->first.id(), handleCands);
0370       std::vector<int> indices;
0371       while (it != itEnd) {
0372         indices.push_back(it->second.key());
0373         ++it;
0374       }
0375       auto triggerObjectMatch = std::make_unique<TriggerObjectMatch>(handleTriggerObjects);
0376       TriggerObjectMatch::Filler matchFiller(*triggerObjectMatch);
0377       if (handleCands.isValid()) {
0378         matchFiller.insert(handleCands, indices.begin(), indices.end());
0379       }
0380       matchFiller.fill();
0381       OrphanHandle<TriggerObjectMatch> handleTriggerObjectMatch(
0382           iEvent.put(std::move(triggerObjectMatch), labelTriggerObjectMatcher));
0383       // set product reference to trigger match association
0384       if (!handleTriggerObjectMatch.isValid()) {
0385         LogError("triggerMatchValid") << "pat::TriggerObjectMatch product with InputTag '" << labelTriggerObjectMatcher
0386                                       << "' not in event";
0387         continue;
0388       }
0389       if (!(triggerEvent->addObjectMatchResult(handleTriggerObjectMatch, labelTriggerObjectMatcher))) {
0390         LogWarning("triggerObjectMatchReplication")
0391             << "pat::TriggerEvent contains already a pat::TriggerObjectMatch from matcher module '"
0392             << labelTriggerObjectMatcher << "'";
0393       }
0394     }
0395   }
0396 
0397   iEvent.put(std::move(triggerEvent));
0398 }
0399 
0400 #include "FWCore/Framework/interface/MakerMacros.h"
0401 DEFINE_FWK_MODULE(PATTriggerEventProducer);