Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-03 23:52:55

0001 #ifndef DQMOffline_Trigger_HLTTagAndProbeEff_h
0002 #define DQMOffline_Trigger_HLTTagAndProbeEff_h
0003 
0004 //***************************************************************************
0005 //
0006 // Description:
0007 //   This class produces histograms which can be used to make tag&probe efficiencies
0008 //   for specified HLT filters
0009 //   These histograms can be binned in various variables
0010 //
0011 //   In a nutshell:
0012 //   1) requires the tag trigger to pass for the event
0013 //   2) creates a collection of tags, with the tags required to pass the a specified
0014 //      filter and selection ID. The selection is in the form of a value map calculated
0015 //      by a previous module. Additional kinematic cuts can be applied (its not limited to
0016 //      kinematic cuts per se but thats the intention)
0017 //   3) likewise creates a collection of probes passing filter, ID and kinematic requirements
0018 //   4) applies selection like mass & opp sign to the t&p pair
0019 //   5) passes the t&p pair to HLTDQMFilterTnPEffHists, with each one corresponding to a
0020 //      specific HLT filter whose efficiency we wish to measure. This class then creates the
0021 //      numerator and denominator histograms for the efficiency calculation done at harvesting
0022 //
0023 //
0024 // Author: Sam Harper (RAL) , 2017
0025 //
0026 //***************************************************************************
0027 
0028 #include "FWCore/Framework/interface/ConsumesCollector.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 
0032 #include "DQMServices/Core/interface/DQMStore.h"
0033 
0034 #include "DataFormats/Common/interface/ValueMap.h"
0035 #include "DataFormats/Common/interface/Handle.h"
0036 #include "DataFormats/Common/interface/Ref.h"
0037 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
0038 #include "DataFormats/Math/interface/deltaR.h"
0039 
0040 #include "DQMOffline/Trigger/interface/UtilFuncs.h"
0041 #include "DQMOffline/Trigger/interface/VarRangeCutColl.h"
0042 #include "DQMOffline/Trigger/interface/HLTDQMFilterTnPEffHists.h"
0043 
0044 #include "CommonTools/TriggerUtils/interface/GenericTriggerEventFlag.h"
0045 
0046 #include <vector>
0047 #include <string>
0048 
0049 namespace {
0050   template <typename T>
0051   edm::Handle<T> getHandle(const edm::Event& event, const edm::EDGetTokenT<T>& token) {
0052     edm::Handle<T> handle;
0053     event.getByToken(token, handle);
0054     return handle;
0055   }
0056 }  // namespace
0057 
0058 template <typename TagType, typename TagCollType, typename ProbeType = TagType, typename ProbeCollType = TagCollType>
0059 class HLTDQMTagAndProbeEff {
0060 public:
0061   typedef dqm::legacy::MonitorElement MonitorElement;
0062   typedef dqm::legacy::DQMStore DQMStore;
0063 
0064   explicit HLTDQMTagAndProbeEff(const edm::ParameterSet& pset, edm::ConsumesCollector&& cc);
0065 
0066   static edm::ParameterSetDescription makePSetDescription();
0067 
0068   void beginRun(const edm::Run& run, const edm::EventSetup& setup);
0069   void bookHists(DQMStore::IBooker& iBooker);
0070   void fill(const edm::Event& event, const edm::EventSetup& setup);
0071 
0072 private:
0073   template <typename ObjType, typename ObjCollType>
0074   std::vector<edm::Ref<ObjCollType> > getPassingRefs(const edm::Handle<ObjCollType>& objCollHandle,
0075                                                      const trigger::TriggerEvent& trigEvt,
0076                                                      const std::vector<std::string>& filterNames,
0077                                                      const bool orFilters,
0078                                                      const edm::Handle<edm::ValueMap<bool> >& vidHandle,
0079                                                      const VarRangeCutColl<ObjType>& rangeCuts);
0080 
0081 private:
0082   edm::EDGetTokenT<TagCollType> tagToken_;
0083   edm::EDGetTokenT<ProbeCollType> probeToken_;
0084   edm::EDGetTokenT<trigger::TriggerEvent> trigEvtToken_;
0085   edm::EDGetTokenT<edm::ValueMap<bool> > tagVIDToken_;
0086   edm::EDGetTokenT<edm::ValueMap<bool> > probeVIDToken_;
0087 
0088   std::string hltProcess_;
0089 
0090   std::string tagTrigger_;
0091 
0092   std::vector<std::string> tagFilters_;
0093   bool tagFiltersORed_;  //true=ORed, false=ANDed
0094   VarRangeCutColl<TagType> tagRangeCuts_;
0095 
0096   std::vector<std::string> probeFilters_;
0097   bool probeFiltersORed_;  //true=ORed, false=ANDed
0098   VarRangeCutColl<ProbeType> probeRangeCuts_;
0099 
0100   float minTagProbeDR2_;
0101   float minMass_;
0102   float maxMass_;
0103   bool requireOpSign_;
0104 
0105   std::vector<edm::ParameterSet> histConfigs_;
0106   std::vector<HLTDQMFilterTnPEffHists<TagType, ProbeType> > filterHists_;
0107 
0108   GenericTriggerEventFlag sampleTrigRequirements_;
0109 };
0110 
0111 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0112 HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::HLTDQMTagAndProbeEff(
0113     const edm::ParameterSet& pset, edm::ConsumesCollector&& cc)
0114     : tagRangeCuts_(pset.getParameter<std::vector<edm::ParameterSet> >("tagRangeCuts")),
0115       probeRangeCuts_(pset.getParameter<std::vector<edm::ParameterSet> >("probeRangeCuts")),
0116       sampleTrigRequirements_(pset.getParameter<edm::ParameterSet>("sampleTrigRequirements"), cc) {
0117   edm::InputTag trigEvtTag = pset.getParameter<edm::InputTag>("trigEvent");
0118 
0119   tagToken_ = cc.consumes<TagCollType>(pset.getParameter<edm::InputTag>("tagColl"));
0120   probeToken_ = cc.consumes<ProbeCollType>(pset.getParameter<edm::InputTag>("probeColl"));
0121   trigEvtToken_ = cc.consumes<trigger::TriggerEvent>(trigEvtTag);
0122   tagVIDToken_ = cc.consumes<edm::ValueMap<bool> >(pset.getParameter<edm::InputTag>("tagVIDCuts"));
0123   probeVIDToken_ = cc.consumes<edm::ValueMap<bool> >(pset.getParameter<edm::InputTag>("probeVIDCuts"));
0124 
0125   hltProcess_ = trigEvtTag.process();
0126 
0127   tagFilters_ = pset.getParameter<std::vector<std::string> >("tagFilters");
0128   tagFiltersORed_ = pset.getParameter<bool>("tagFiltersORed");
0129   probeFilters_ = pset.getParameter<std::vector<std::string> >("probeFilters");
0130   probeFiltersORed_ = pset.getParameter<bool>("tagFiltersORed");
0131 
0132   double minDR = pset.getParameter<double>("minTagProbeDR");
0133   minTagProbeDR2_ = minDR * minDR;
0134   minMass_ = pset.getParameter<double>("minMass");
0135   maxMass_ = pset.getParameter<double>("maxMass");
0136   requireOpSign_ = pset.getParameter<bool>("requireOpSign");
0137 
0138   histConfigs_ = pset.getParameter<std::vector<edm::ParameterSet> >("histConfigs");
0139   const auto& filterConfigs = pset.getParameter<std::vector<edm::ParameterSet> >("filterConfigs");
0140 
0141   std::string baseHistName = pset.getParameter<std::string>("baseHistName");
0142 
0143   for (auto& config : filterConfigs) {
0144     filterHists_.emplace_back(HLTDQMFilterTnPEffHists<TagType, ProbeType>(config, baseHistName, hltProcess_));
0145   }
0146 }
0147 
0148 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0149 edm::ParameterSetDescription HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::makePSetDescription() {
0150   edm::ParameterSetDescription desc;
0151   //it does not matter for makePSetDescription whether tag or probe types are used
0152   desc.addVPSet("tagRangeCuts", VarRangeCut<TagType>::makePSetDescription(), std::vector<edm::ParameterSet>());
0153   desc.addVPSet("probeRangeCuts", VarRangeCut<TagType>::makePSetDescription(), std::vector<edm::ParameterSet>());
0154   desc.add<edm::InputTag>("trigEvent", edm::InputTag("hltTriggerSummaryAOD", "", "HLT"));
0155   desc.add<edm::InputTag>("tagColl", edm::InputTag());
0156   desc.add<edm::InputTag>("probeColl", edm::InputTag());
0157   desc.add<edm::InputTag>("tagVIDCuts", edm::InputTag());
0158   desc.add<edm::InputTag>("probeVIDCuts", edm::InputTag());
0159   desc.add<std::vector<std::string> >("tagFilters", std::vector<std::string>());
0160   desc.add<std::vector<std::string> >("probeFilters", std::vector<std::string>());
0161   desc.add<bool>(
0162       "tagFiltersORed",
0163       true);  //default to OR probe filters (use case is multiple tag triggers, eg Ele27, Ele32, Ele35 tight etc)
0164   desc.add<bool>(
0165       "probeFiltersORed",
0166       false);  //default to AND probe filters (cant think why you would want to OR them but made if configurable just in case)
0167   desc.add<double>("minTagProbeDR", 0);
0168   desc.add<double>("minMass");
0169   desc.add<double>("maxMass");
0170   desc.add<bool>("requireOpSign");
0171   desc.addVPSet("histConfigs",
0172                 HLTDQMFilterTnPEffHists<TagType, ProbeType>::makePSetDescriptionHistConfigs(),
0173                 std::vector<edm::ParameterSet>());
0174   desc.addVPSet("filterConfigs",
0175                 HLTDQMFilterTnPEffHists<TagType, ProbeType>::makePSetDescription(),
0176                 std::vector<edm::ParameterSet>());
0177   desc.add<std::string>("baseHistName");
0178 
0179   edm::ParameterSetDescription trigEvtFlagDesc;
0180   trigEvtFlagDesc.add<bool>("andOr", false);
0181   trigEvtFlagDesc.add<unsigned int>("verbosityLevel", 1);
0182   trigEvtFlagDesc.add<bool>("andOrDcs", false);
0183   trigEvtFlagDesc.add<edm::InputTag>("dcsInputTag", edm::InputTag("scalersRawToDigi"));
0184   trigEvtFlagDesc.add<edm::InputTag>("dcsRecordInputTag", edm::InputTag("onlineMetaDataDigis"));
0185   trigEvtFlagDesc.add<std::vector<int> >("dcsPartitions", {24, 25, 26, 27, 28, 29});
0186   trigEvtFlagDesc.add<bool>("errorReplyDcs", true);
0187   trigEvtFlagDesc.add<std::string>("dbLabel", "");
0188   trigEvtFlagDesc.add<bool>("andOrHlt", true);  //true = OR, false = and
0189   trigEvtFlagDesc.add<edm::InputTag>("hltInputTag", edm::InputTag("TriggerResults::HLT"));
0190   trigEvtFlagDesc.add<std::vector<std::string> >("hltPaths", {});
0191   trigEvtFlagDesc.add<std::string>("hltDBKey", "");
0192   trigEvtFlagDesc.add<bool>("errorReplyHlt", false);
0193   desc.add<edm::ParameterSetDescription>("sampleTrigRequirements", trigEvtFlagDesc);
0194 
0195   return desc;
0196 }
0197 
0198 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0199 void HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::bookHists(DQMStore::IBooker& iBooker) {
0200   for (auto& filterHist : filterHists_)
0201     filterHist.bookHists(iBooker, histConfigs_);
0202 }
0203 
0204 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0205 void HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::beginRun(const edm::Run& run,
0206                                                                                     const edm::EventSetup& setup) {
0207   if (sampleTrigRequirements_.on())
0208     sampleTrigRequirements_.initRun(run, setup);
0209 }
0210 
0211 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0212 void HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::fill(const edm::Event& event,
0213                                                                                 const edm::EventSetup& setup) {
0214   auto tagCollHandle = getHandle(event, tagToken_);
0215   auto probeCollHandle = getHandle(event, probeToken_);
0216   auto trigEvtHandle = getHandle(event, trigEvtToken_);
0217   auto tagVIDHandle = getHandle(event, tagVIDToken_);
0218   auto probeVIDHandle = getHandle(event, probeVIDToken_);
0219 
0220   //we need the object collection and trigger info at the minimum
0221   if (!tagCollHandle.isValid() || !probeCollHandle.isValid() || !trigEvtHandle.isValid())
0222     return;
0223 
0224   //if GenericTriggerEventFlag is "off", it'll return true regardless
0225   //if so if its off, we auto pass which is the behaviour we wish to have
0226   //if its null, we auto fail (because that shouldnt happen)
0227   if (sampleTrigRequirements_.accept(event, setup) == false)
0228     return;
0229 
0230   std::vector<edm::Ref<TagCollType> > tagRefs =
0231       getPassingRefs(tagCollHandle, *trigEvtHandle, tagFilters_, tagFiltersORed_, tagVIDHandle, tagRangeCuts_);
0232 
0233   std::vector<edm::Ref<ProbeCollType> > probeRefs = getPassingRefs(
0234       probeCollHandle, *trigEvtHandle, probeFilters_, probeFiltersORed_, probeVIDHandle, probeRangeCuts_);
0235 
0236   for (auto& tagRef : tagRefs) {
0237     float tagEta = tagRef->eta();
0238     float tagPhi = tagRef->phi();
0239     for (auto& probeRef : probeRefs) {
0240       //first check if its the same object via its memory localation
0241       //note for different collections another method is needed to determine
0242       //if the probe and tag are the same object just recoed differently
0243       //suggest dR cut (although mass cut should also help here)
0244       if (static_cast<const void*>(&*tagRef) == static_cast<const void*>(&*probeRef))
0245         continue;
0246       float dR2 = reco::deltaR2(tagEta, tagPhi, probeRef->eta(), probeRef->phi());
0247       float mass = (tagRef->p4() + probeRef->p4()).mag();
0248       if ((mass >= minMass_ || minMass_ < 0) && (mass < maxMass_ || maxMass_ < 0) && (dR2 >= minTagProbeDR2_) &&
0249           (!requireOpSign_ || tagRef->charge() != probeRef->charge())) {
0250         for (auto& filterHist : filterHists_) {
0251           filterHist.fillHists(*tagRef, *probeRef, event, setup, *trigEvtHandle);
0252         }
0253       }  //end of t&p pair cuts
0254     }    //end of probe loop
0255   }      //end of tag loop
0256 }
0257 
0258 //yo dawg, I heard you like templates...
0259 //okay this might be a little confusing to the student expected to maintain this
0260 //here we have a templated function inside a templated class as it needs to be able to take probe or tag types
0261 //so this is function of a class HLTDQMTagAndProbeEff<TagType,TagCollType,ProbeType,ProbeCollType>
0262 //hence why it needs to specify that those types even if it doesnt use them
0263 //However also templated to take a type of ObjCollType
0264 //(which we know will either be ProbeCollType or TagCollType but c++ doesnt and therefore it can anything)
0265 //this is why there are two seperate template declarations
0266 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0267 template <typename ObjType, typename ObjCollType>
0268 std::vector<edm::Ref<ObjCollType> > HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::getPassingRefs(
0269     const edm::Handle<ObjCollType>& objCollHandle,
0270     const trigger::TriggerEvent& trigEvt,
0271     const std::vector<std::string>& filterNames,
0272     const bool orFilters,
0273     const edm::Handle<edm::ValueMap<bool> >& vidHandle,
0274     const VarRangeCutColl<ObjType>& rangeCuts) {
0275   std::vector<edm::Ref<ObjCollType> > passingRefs;
0276   for (size_t objNr = 0; objNr < objCollHandle->size(); objNr++) {
0277     edm::Ref<ObjCollType> ref(objCollHandle, objNr);
0278     if (rangeCuts(*ref) && hltdqm::passTrig(ref->eta(), ref->phi(), trigEvt, filterNames, orFilters, hltProcess_) &&
0279         (vidHandle.isValid() == false || (*vidHandle)[ref] == true)) {
0280       passingRefs.push_back(ref);
0281     }
0282   }
0283   return passingRefs;
0284 }
0285 #endif