Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-11 04:32:51

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::DQMStore DQMStore;
0062 
0063   explicit HLTDQMTagAndProbeEff(const edm::ParameterSet& pset, edm::ConsumesCollector&& cc);
0064 
0065   static edm::ParameterSetDescription makePSetDescription();
0066 
0067   void beginRun(const edm::Run& run, const edm::EventSetup& setup);
0068   void bookHists(DQMStore::IBooker& iBooker);
0069   void fill(const edm::Event& event, const edm::EventSetup& setup);
0070 
0071 private:
0072   template <typename ObjType, typename ObjCollType>
0073   std::vector<edm::Ref<ObjCollType> > getPassingRefs(const edm::Handle<ObjCollType>& objCollHandle,
0074                                                      const trigger::TriggerEvent& trigEvt,
0075                                                      const std::vector<std::string>& filterNames,
0076                                                      const bool orFilters,
0077                                                      const edm::Handle<edm::ValueMap<bool> >& vidHandle,
0078                                                      const VarRangeCutColl<ObjType>& rangeCuts);
0079 
0080 private:
0081   edm::EDGetTokenT<TagCollType> tagToken_;
0082   edm::EDGetTokenT<ProbeCollType> probeToken_;
0083   edm::EDGetTokenT<trigger::TriggerEvent> trigEvtToken_;
0084   edm::EDGetTokenT<edm::ValueMap<bool> > tagVIDToken_;
0085   edm::EDGetTokenT<edm::ValueMap<bool> > probeVIDToken_;
0086 
0087   std::string hltProcess_;
0088 
0089   std::string tagTrigger_;
0090 
0091   std::vector<std::string> tagFilters_;
0092   bool tagFiltersORed_;  //true=ORed, false=ANDed
0093   VarRangeCutColl<TagType> tagRangeCuts_;
0094 
0095   std::vector<std::string> probeFilters_;
0096   bool probeFiltersORed_;  //true=ORed, false=ANDed
0097   VarRangeCutColl<ProbeType> probeRangeCuts_;
0098 
0099   float minTagProbeDR2_;
0100   float minMass_;
0101   float maxMass_;
0102   bool requireOpSign_;
0103 
0104   std::vector<edm::ParameterSet> histConfigs_;
0105   std::vector<HLTDQMFilterTnPEffHists<TagType, ProbeType> > filterHists_;
0106 
0107   GenericTriggerEventFlag sampleTrigRequirements_;
0108 };
0109 
0110 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0111 HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::HLTDQMTagAndProbeEff(
0112     const edm::ParameterSet& pset, edm::ConsumesCollector&& cc)
0113     : tagRangeCuts_(pset.getParameter<std::vector<edm::ParameterSet> >("tagRangeCuts")),
0114       probeRangeCuts_(pset.getParameter<std::vector<edm::ParameterSet> >("probeRangeCuts")),
0115       sampleTrigRequirements_(pset.getParameter<edm::ParameterSet>("sampleTrigRequirements"), cc) {
0116   edm::InputTag trigEvtTag = pset.getParameter<edm::InputTag>("trigEvent");
0117 
0118   tagToken_ = cc.consumes<TagCollType>(pset.getParameter<edm::InputTag>("tagColl"));
0119   probeToken_ = cc.consumes<ProbeCollType>(pset.getParameter<edm::InputTag>("probeColl"));
0120   trigEvtToken_ = cc.consumes<trigger::TriggerEvent>(trigEvtTag);
0121   tagVIDToken_ = cc.consumes<edm::ValueMap<bool> >(pset.getParameter<edm::InputTag>("tagVIDCuts"));
0122   probeVIDToken_ = cc.consumes<edm::ValueMap<bool> >(pset.getParameter<edm::InputTag>("probeVIDCuts"));
0123 
0124   hltProcess_ = trigEvtTag.process();
0125 
0126   tagFilters_ = pset.getParameter<std::vector<std::string> >("tagFilters");
0127   tagFiltersORed_ = pset.getParameter<bool>("tagFiltersORed");
0128   probeFilters_ = pset.getParameter<std::vector<std::string> >("probeFilters");
0129   probeFiltersORed_ = pset.getParameter<bool>("tagFiltersORed");
0130 
0131   double minDR = pset.getParameter<double>("minTagProbeDR");
0132   minTagProbeDR2_ = minDR * minDR;
0133   minMass_ = pset.getParameter<double>("minMass");
0134   maxMass_ = pset.getParameter<double>("maxMass");
0135   requireOpSign_ = pset.getParameter<bool>("requireOpSign");
0136 
0137   histConfigs_ = pset.getParameter<std::vector<edm::ParameterSet> >("histConfigs");
0138   const auto& filterConfigs = pset.getParameter<std::vector<edm::ParameterSet> >("filterConfigs");
0139 
0140   std::string baseHistName = pset.getParameter<std::string>("baseHistName");
0141 
0142   for (auto& config : filterConfigs) {
0143     filterHists_.emplace_back(HLTDQMFilterTnPEffHists<TagType, ProbeType>(config, baseHistName, hltProcess_));
0144   }
0145 }
0146 
0147 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0148 edm::ParameterSetDescription HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::makePSetDescription() {
0149   edm::ParameterSetDescription desc;
0150   //it does not matter for makePSetDescription whether tag or probe types are used
0151   desc.addVPSet("tagRangeCuts", VarRangeCut<TagType>::makePSetDescription(), std::vector<edm::ParameterSet>());
0152   desc.addVPSet("probeRangeCuts", VarRangeCut<TagType>::makePSetDescription(), std::vector<edm::ParameterSet>());
0153   desc.add<edm::InputTag>("trigEvent", edm::InputTag("hltTriggerSummaryAOD", "", "HLT"));
0154   desc.add<edm::InputTag>("tagColl", edm::InputTag());
0155   desc.add<edm::InputTag>("probeColl", edm::InputTag());
0156   desc.add<edm::InputTag>("tagVIDCuts", edm::InputTag());
0157   desc.add<edm::InputTag>("probeVIDCuts", edm::InputTag());
0158   desc.add<std::vector<std::string> >("tagFilters", std::vector<std::string>());
0159   desc.add<std::vector<std::string> >("probeFilters", std::vector<std::string>());
0160   desc.add<bool>(
0161       "tagFiltersORed",
0162       true);  //default to OR probe filters (use case is multiple tag triggers, eg Ele27, Ele32, Ele35 tight etc)
0163   desc.add<bool>(
0164       "probeFiltersORed",
0165       false);  //default to AND probe filters (cant think why you would want to OR them but made if configurable just in case)
0166   desc.add<double>("minTagProbeDR", 0);
0167   desc.add<double>("minMass");
0168   desc.add<double>("maxMass");
0169   desc.add<bool>("requireOpSign");
0170   desc.addVPSet("histConfigs",
0171                 HLTDQMFilterTnPEffHists<TagType, ProbeType>::makePSetDescriptionHistConfigs(),
0172                 std::vector<edm::ParameterSet>());
0173   desc.addVPSet("filterConfigs",
0174                 HLTDQMFilterTnPEffHists<TagType, ProbeType>::makePSetDescription(),
0175                 std::vector<edm::ParameterSet>());
0176   desc.add<std::string>("baseHistName");
0177 
0178   edm::ParameterSetDescription trigEvtFlagDesc;
0179   trigEvtFlagDesc.add<bool>("andOr", false);
0180   trigEvtFlagDesc.add<unsigned int>("verbosityLevel", 1);
0181   trigEvtFlagDesc.add<bool>("andOrDcs", false);
0182   trigEvtFlagDesc.add<edm::InputTag>("dcsInputTag", edm::InputTag("scalersRawToDigi"));
0183   trigEvtFlagDesc.add<edm::InputTag>("dcsRecordInputTag", edm::InputTag("onlineMetaDataDigis"));
0184   trigEvtFlagDesc.add<std::vector<int> >("dcsPartitions", {24, 25, 26, 27, 28, 29});
0185   trigEvtFlagDesc.add<bool>("errorReplyDcs", true);
0186   trigEvtFlagDesc.add<std::string>("dbLabel", "");
0187   trigEvtFlagDesc.add<bool>("andOrHlt", true);  //true = OR, false = and
0188   trigEvtFlagDesc.add<edm::InputTag>("hltInputTag", edm::InputTag("TriggerResults::HLT"));
0189   trigEvtFlagDesc.add<std::vector<std::string> >("hltPaths", {});
0190   trigEvtFlagDesc.add<std::string>("hltDBKey", "");
0191   trigEvtFlagDesc.add<bool>("errorReplyHlt", false);
0192   desc.add<edm::ParameterSetDescription>("sampleTrigRequirements", trigEvtFlagDesc);
0193 
0194   return desc;
0195 }
0196 
0197 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0198 void HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::bookHists(DQMStore::IBooker& iBooker) {
0199   for (auto& filterHist : filterHists_)
0200     filterHist.bookHists(iBooker, histConfigs_);
0201 }
0202 
0203 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0204 void HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::beginRun(const edm::Run& run,
0205                                                                                     const edm::EventSetup& setup) {
0206   if (sampleTrigRequirements_.on())
0207     sampleTrigRequirements_.initRun(run, setup);
0208 }
0209 
0210 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0211 void HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::fill(const edm::Event& event,
0212                                                                                 const edm::EventSetup& setup) {
0213   auto tagCollHandle = getHandle(event, tagToken_);
0214   auto probeCollHandle = getHandle(event, probeToken_);
0215   auto trigEvtHandle = getHandle(event, trigEvtToken_);
0216   auto tagVIDHandle = getHandle(event, tagVIDToken_);
0217   auto probeVIDHandle = getHandle(event, probeVIDToken_);
0218 
0219   //we need the object collection and trigger info at the minimum
0220   if (!tagCollHandle.isValid() || !probeCollHandle.isValid() || !trigEvtHandle.isValid())
0221     return;
0222 
0223   //if GenericTriggerEventFlag is "off", it'll return true regardless
0224   //if so if its off, we auto pass which is the behaviour we wish to have
0225   //if its null, we auto fail (because that shouldnt happen)
0226   if (sampleTrigRequirements_.accept(event, setup) == false)
0227     return;
0228 
0229   std::vector<edm::Ref<TagCollType> > tagRefs =
0230       getPassingRefs(tagCollHandle, *trigEvtHandle, tagFilters_, tagFiltersORed_, tagVIDHandle, tagRangeCuts_);
0231 
0232   std::vector<edm::Ref<ProbeCollType> > probeRefs = getPassingRefs(
0233       probeCollHandle, *trigEvtHandle, probeFilters_, probeFiltersORed_, probeVIDHandle, probeRangeCuts_);
0234 
0235   for (auto& tagRef : tagRefs) {
0236     float tagEta = tagRef->eta();
0237     float tagPhi = tagRef->phi();
0238     for (auto& probeRef : probeRefs) {
0239       //first check if its the same object via its memory localation
0240       //note for different collections another method is needed to determine
0241       //if the probe and tag are the same object just recoed differently
0242       //suggest dR cut (although mass cut should also help here)
0243       if (static_cast<const void*>(&*tagRef) == static_cast<const void*>(&*probeRef))
0244         continue;
0245       float dR2 = reco::deltaR2(tagEta, tagPhi, probeRef->eta(), probeRef->phi());
0246       float mass = (tagRef->p4() + probeRef->p4()).mag();
0247       if ((mass >= minMass_ || minMass_ < 0) && (mass < maxMass_ || maxMass_ < 0) && (dR2 >= minTagProbeDR2_) &&
0248           (!requireOpSign_ || tagRef->charge() != probeRef->charge())) {
0249         for (auto& filterHist : filterHists_) {
0250           filterHist.fillHists(*tagRef, *probeRef, event, setup, *trigEvtHandle);
0251         }
0252       }  //end of t&p pair cuts
0253     }  //end of probe loop
0254   }  //end of tag loop
0255 }
0256 
0257 //yo dawg, I heard you like templates...
0258 //okay this might be a little confusing to the student expected to maintain this
0259 //here we have a templated function inside a templated class as it needs to be able to take probe or tag types
0260 //so this is function of a class HLTDQMTagAndProbeEff<TagType,TagCollType,ProbeType,ProbeCollType>
0261 //hence why it needs to specify that those types even if it doesnt use them
0262 //However also templated to take a type of ObjCollType
0263 //(which we know will either be ProbeCollType or TagCollType but c++ doesnt and therefore it can anything)
0264 //this is why there are two seperate template declarations
0265 template <typename TagType, typename TagCollType, typename ProbeType, typename ProbeCollType>
0266 template <typename ObjType, typename ObjCollType>
0267 std::vector<edm::Ref<ObjCollType> > HLTDQMTagAndProbeEff<TagType, TagCollType, ProbeType, ProbeCollType>::getPassingRefs(
0268     const edm::Handle<ObjCollType>& objCollHandle,
0269     const trigger::TriggerEvent& trigEvt,
0270     const std::vector<std::string>& filterNames,
0271     const bool orFilters,
0272     const edm::Handle<edm::ValueMap<bool> >& vidHandle,
0273     const VarRangeCutColl<ObjType>& rangeCuts) {
0274   std::vector<edm::Ref<ObjCollType> > passingRefs;
0275   for (size_t objNr = 0; objNr < objCollHandle->size(); objNr++) {
0276     edm::Ref<ObjCollType> ref(objCollHandle, objNr);
0277     if (rangeCuts(*ref) && hltdqm::passTrig(ref->eta(), ref->phi(), trigEvt, filterNames, orFilters, hltProcess_) &&
0278         (vidHandle.isValid() == false || (*vidHandle)[ref] == true)) {
0279       passingRefs.push_back(ref);
0280     }
0281   }
0282   return passingRefs;
0283 }
0284 #endif