Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:13:29

0001 #include "FWCore/Framework/interface/Frameworkfwd.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003 #include "FWCore/Framework/interface/MakerMacros.h"
0004 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0005 #include "DQMServices/Core/interface/DQMStore.h"
0006 #include "DQMOffline/Trigger/plugins/TriggerDQMBase.h"
0007 #include "CommonTools/TriggerUtils/interface/GenericTriggerEventFlag.h"
0008 
0009 #include "DataFormats/METReco/interface/PFMET.h"
0010 #include "DataFormats/METReco/interface/PFMETCollection.h"
0011 #include "DataFormats/METReco/interface/MET.h"
0012 #include "DataFormats/METReco/interface/METCollection.h"
0013 #include "DataFormats/JetReco/interface/PFJet.h"
0014 #include "DataFormats/BTauReco/interface/JetTag.h"
0015 #include "DataFormats/Common/interface/TriggerResults.h"
0016 #include "DataFormats/HLTReco/interface/TriggerObject.h"
0017 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
0018 #include "DataFormats/HLTReco/interface/TriggerEventWithRefs.h"
0019 #include "DataFormats/HLTReco/interface/TriggerEventWithRefs.h"
0020 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0021 #include "DataFormats/VertexReco/interface/Vertex.h"
0022 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0023 #include "DataFormats/Common/interface/ValueMap.h"
0024 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0025 #include "DataFormats/MuonReco/interface/Muon.h"
0026 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0027 #include "DataFormats/EgammaCandidates/interface/Electron.h"
0028 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0029 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
0030 #include "CommonTools/Egamma/interface/ConversionTools.h"
0031 
0032 #include <limits>
0033 #include <algorithm>
0034 
0035 class LepHTMonitor : public DQMEDAnalyzer, public TriggerDQMBase {
0036 public:
0037   typedef dqm::reco::MonitorElement MonitorElement;
0038   typedef dqm::reco::DQMStore DQMStore;
0039 
0040   LepHTMonitor(const edm::ParameterSet &ps);
0041   ~LepHTMonitor() throw() override;
0042 
0043 protected:
0044   void bookHistograms(DQMStore::IBooker &ibooker, const edm::Run &, const edm::EventSetup &) override;
0045   void analyze(const edm::Event &e, const edm::EventSetup &eSetup) override;
0046 
0047 private:
0048   edm::InputTag theElectronTag_;
0049   edm::EDGetTokenT<edm::View<reco::GsfElectron> > theElectronCollection_;
0050   edm::InputTag theElectronVIDTag_;
0051   edm::EDGetTokenT<edm::ValueMap<bool> > theElectronVIDMap_;
0052   edm::InputTag theMuonTag_;
0053   edm::EDGetTokenT<reco::MuonCollection> theMuonCollection_;
0054   edm::InputTag thePfMETTag_;
0055   edm::EDGetTokenT<reco::PFMETCollection> thePfMETCollection_;
0056   edm::InputTag thePfJetTag_;
0057   edm::EDGetTokenT<reco::PFJetCollection> thePfJetCollection_;
0058   edm::InputTag theJetTagTag_;
0059   edm::EDGetTokenT<reco::JetTagCollection> theJetTagCollection_;
0060   edm::InputTag theVertexCollectionTag_;
0061   edm::EDGetTokenT<reco::VertexCollection> theVertexCollection_;
0062   edm::InputTag theConversionCollectionTag_;
0063   edm::EDGetTokenT<reco::ConversionCollection> theConversionCollection_;
0064   edm::InputTag theBeamSpotTag_;
0065   edm::EDGetTokenT<reco::BeamSpot> theBeamSpot_;
0066 
0067   std::unique_ptr<GenericTriggerEventFlag> num_genTriggerEventFlag_;
0068   std::unique_ptr<GenericTriggerEventFlag> den_lep_genTriggerEventFlag_;
0069   std::unique_ptr<GenericTriggerEventFlag> den_HT_genTriggerEventFlag_;
0070 
0071   const std::string folderName_;
0072 
0073   const bool requireValidHLTPaths_;
0074   bool hltPathsAreValid_;
0075 
0076   int muonIDlevel_;
0077 
0078   double jetPtCut_;
0079   double jetEtaCut_;
0080   double metCut_;
0081   double htCut_;
0082   double nmusCut_;
0083   double nelsCut_;
0084   double lep_pt_plateau_;
0085   double lep_counting_threshold_;
0086   double lep_iso_cut_;
0087   double lep_eta_cut_;
0088   double lep_d0_cut_b_;
0089   double lep_dz_cut_b_;
0090   double lep_d0_cut_e_;
0091   double lep_dz_cut_e_;
0092 
0093   std::vector<double> ptbins_;
0094   std::vector<double> htbins_;
0095   int nbins_eta_;
0096   int nbins_phi_;
0097   int nbins_npv_;
0098   float etabins_min_;
0099   float etabins_max_;
0100   float phibins_min_;
0101   float phibins_max_;
0102   float npvbins_min_;
0103   float npvbins_max_;
0104 
0105   // Histograms
0106   MonitorElement *h_pfHTTurnOn_num_;
0107   MonitorElement *h_pfHTTurnOn_den_;
0108   MonitorElement *h_lepPtTurnOn_num_;
0109   MonitorElement *h_lepPtTurnOn_den_;
0110   MonitorElement *h_lepEtaTurnOn_num_;
0111   MonitorElement *h_lepEtaTurnOn_den_;
0112   MonitorElement *h_lepPhiTurnOn_num_;
0113   MonitorElement *h_lepPhiTurnOn_den_;
0114   MonitorElement *h_lepEtaPhiTurnOn_num_;
0115   MonitorElement *h_lepEtaPhiTurnOn_den_;
0116   MonitorElement *h_NPVTurnOn_num_;
0117   MonitorElement *h_NPVTurnOn_den_;
0118 };
0119 
0120 namespace {
0121 
0122   //Offline electron definition
0123   bool isGood(const reco::GsfElectron &el,
0124               const reco::Vertex::Point &pv_position,
0125               const reco::BeamSpot::Point &bs_position,
0126               const edm::Handle<reco::ConversionCollection> &convs,
0127               bool pass_id,
0128               const double lep_counting_threshold,
0129               const double lep_iso_cut,
0130               const double lep_eta_cut,
0131               const double d0_cut_b,
0132               const double dz_cut_b,
0133               const double d0_cut_e,
0134               const double dz_cut_e) {
0135     //Electron ID
0136     if (!pass_id)
0137       return false;
0138 
0139     //pT
0140     if (el.pt() < lep_counting_threshold || std::abs(el.superCluster()->eta()) > lep_eta_cut)
0141       return false;
0142 
0143     //Isolation
0144     auto const &iso = el.pfIsolationVariables();
0145     const float absiso =
0146         iso.sumChargedHadronPt + std::max(0.0, iso.sumNeutralHadronEt + iso.sumPhotonEt - 0.5 * iso.sumPUPt);
0147     const float relisowithdb = absiso / el.pt();
0148     if (relisowithdb > lep_iso_cut)
0149       return false;
0150 
0151     //Conversion matching
0152     bool pass_conversion = false;
0153     if (convs.isValid()) {
0154       pass_conversion = !ConversionTools::hasMatchedConversion(el, *convs, bs_position);
0155     } else {
0156       edm::LogError("LepHTMonitor") << "Electron conversion matching failed.\n";
0157     }
0158     if (!pass_conversion)
0159       return false;
0160 
0161     //Impact parameter
0162     float d0 = 999., dz = 999.;
0163     if (el.gsfTrack().isNonnull()) {
0164       d0 = -(el.gsfTrack()->dxy(pv_position));
0165       dz = el.gsfTrack()->dz(pv_position);
0166     } else {
0167       edm::LogError("LepHTMonitor") << "Could not read electron.gsfTrack().\n";
0168       return false;
0169     }
0170     float etasc = el.superCluster()->eta();
0171     if (std::abs(etasc) > 1.479) {  //Endcap
0172       if (std::abs(d0) > d0_cut_e || std::abs(dz) > dz_cut_e)
0173         return false;
0174 
0175     } else {  //Barrel
0176       if (std::abs(d0) > d0_cut_b || std::abs(dz) > dz_cut_b)
0177         return false;
0178     }
0179 
0180     return true;
0181   }
0182 
0183   //Offline muon definition
0184   bool isGood(const reco::Muon &mu,
0185               const reco::Vertex &pv,
0186               const double lep_counting_threshold,
0187               const double lep_iso_cut,
0188               const double lep_eta_cut,
0189               const double d0_cut,
0190               const double dz_cut,
0191               int muonIDlevel) {
0192     const reco::Vertex::Point &pv_position = pv.position();
0193 
0194     // Muon pt and eta acceptance
0195     if (mu.pt() < lep_counting_threshold || std::abs(mu.eta()) > lep_eta_cut)
0196       return false;
0197 
0198     // Muon isolation
0199     auto const &iso = mu.pfIsolationR04();
0200     const float absiso =
0201         iso.sumChargedHadronPt + std::max(0.0, iso.sumNeutralHadronEt + iso.sumPhotonEt - 0.5 * iso.sumPUPt);
0202     const float relisowithdb = absiso / mu.pt();
0203     if (relisowithdb > lep_iso_cut)
0204       return false;
0205 
0206     // Muon ID
0207     bool pass_id = false;
0208     if (muonIDlevel == 1)
0209       pass_id = muon::isLooseMuon(mu);
0210     else if (muonIDlevel == 3)
0211       pass_id = muon::isTightMuon(mu, pv);
0212     else
0213       pass_id = muon::isMediumMuon(mu);
0214 
0215     if (!pass_id)
0216       return false;
0217 
0218     // Muon impact parameter
0219     float d0 = std::abs(mu.muonBestTrack()->dxy(pv_position));
0220     float dz = std::abs(mu.muonBestTrack()->dz(pv_position));
0221     if (d0 > d0_cut || dz > dz_cut)
0222       return false;
0223 
0224     return true;
0225   }
0226 }  // namespace
0227 
0228 LepHTMonitor::LepHTMonitor(const edm::ParameterSet &ps)
0229     : theElectronTag_(ps.getParameter<edm::InputTag>("electronCollection")),
0230       theElectronCollection_(consumes<edm::View<reco::GsfElectron> >(theElectronTag_)),
0231       theElectronVIDTag_(ps.getParameter<edm::InputTag>("electronVID")),
0232       theElectronVIDMap_(consumes<edm::ValueMap<bool> >(theElectronVIDTag_)),
0233       theMuonTag_(ps.getParameter<edm::InputTag>("muonCollection")),
0234       theMuonCollection_(consumes<reco::MuonCollection>(theMuonTag_)),
0235       thePfMETTag_(ps.getParameter<edm::InputTag>("pfMetCollection")),
0236       thePfMETCollection_(consumes<reco::PFMETCollection>(thePfMETTag_)),
0237       thePfJetTag_(ps.getParameter<edm::InputTag>("pfJetCollection")),
0238       thePfJetCollection_(consumes<reco::PFJetCollection>(thePfJetTag_)),
0239       theJetTagTag_(ps.getParameter<edm::InputTag>("jetTagCollection")),
0240       theJetTagCollection_(consumes<reco::JetTagCollection>(theJetTagTag_)),
0241       theVertexCollectionTag_(ps.getParameter<edm::InputTag>("vertexCollection")),
0242       theVertexCollection_(consumes<reco::VertexCollection>(theVertexCollectionTag_)),
0243       theConversionCollectionTag_(ps.getParameter<edm::InputTag>("conversionCollection")),
0244       theConversionCollection_(consumes<reco::ConversionCollection>(theConversionCollectionTag_)),
0245       theBeamSpotTag_(ps.getParameter<edm::InputTag>("beamSpot")),
0246       theBeamSpot_(consumes<reco::BeamSpot>(theBeamSpotTag_)),
0247 
0248       num_genTriggerEventFlag_(new GenericTriggerEventFlag(
0249           ps.getParameter<edm::ParameterSet>("numGenericTriggerEventPSet"), consumesCollector(), *this)),
0250       den_lep_genTriggerEventFlag_(new GenericTriggerEventFlag(
0251           ps.getParameter<edm::ParameterSet>("den_lep_GenericTriggerEventPSet"), consumesCollector(), *this)),
0252       den_HT_genTriggerEventFlag_(new GenericTriggerEventFlag(
0253           ps.getParameter<edm::ParameterSet>("den_HT_GenericTriggerEventPSet"), consumesCollector(), *this)),
0254 
0255       folderName_(ps.getParameter<std::string>("folderName")),
0256       requireValidHLTPaths_(ps.getParameter<bool>("requireValidHLTPaths")),
0257       hltPathsAreValid_(false),
0258 
0259       muonIDlevel_(ps.getUntrackedParameter<int>("muonIDlevel")),
0260       jetPtCut_(ps.getUntrackedParameter<double>("jetPtCut")),
0261       jetEtaCut_(ps.getUntrackedParameter<double>("jetEtaCut")),
0262       metCut_(ps.getUntrackedParameter<double>("metCut")),
0263       htCut_(ps.getUntrackedParameter<double>("htCut")),
0264 
0265       nmusCut_(ps.getUntrackedParameter<double>("nmus")),
0266       nelsCut_(ps.getUntrackedParameter<double>("nels")),
0267       lep_pt_plateau_(ps.getUntrackedParameter<double>("leptonPtPlateau")),
0268       lep_counting_threshold_(ps.getUntrackedParameter<double>("leptonCountingThreshold")),
0269       lep_iso_cut_(ps.getUntrackedParameter<double>("lepIsoCut")),
0270       lep_eta_cut_(ps.getUntrackedParameter<double>("lepEtaCut")),
0271       lep_d0_cut_b_(ps.getUntrackedParameter<double>("lep_d0_cut_b")),
0272       lep_dz_cut_b_(ps.getUntrackedParameter<double>("lep_dz_cut_b")),
0273       lep_d0_cut_e_(ps.getUntrackedParameter<double>("lep_d0_cut_e")),
0274       lep_dz_cut_e_(ps.getUntrackedParameter<double>("lep_dz_cut_e")),
0275       ptbins_(ps.getParameter<std::vector<double> >("ptbins")),
0276       htbins_(ps.getParameter<std::vector<double> >("htbins")),
0277 
0278       nbins_eta_(ps.getUntrackedParameter<int>("nbins_eta")),
0279       nbins_phi_(ps.getUntrackedParameter<int>("nbins_phi")),
0280       nbins_npv_(ps.getUntrackedParameter<int>("nbins_npv")),
0281       etabins_min_(ps.getUntrackedParameter<double>("etabins_min")),
0282       etabins_max_(ps.getUntrackedParameter<double>("etabins_max")),
0283       phibins_min_(ps.getUntrackedParameter<double>("phibins_min")),
0284       phibins_max_(ps.getUntrackedParameter<double>("phibins_max")),
0285       npvbins_min_(ps.getUntrackedParameter<double>("npvbins_min")),
0286       npvbins_max_(ps.getUntrackedParameter<double>("npvbins_max")),
0287 
0288       h_pfHTTurnOn_num_(nullptr),
0289       h_pfHTTurnOn_den_(nullptr),
0290       h_lepPtTurnOn_num_(nullptr),
0291       h_lepPtTurnOn_den_(nullptr),
0292       h_lepEtaTurnOn_num_(nullptr),
0293       h_lepEtaTurnOn_den_(nullptr),
0294       h_lepPhiTurnOn_num_(nullptr),
0295       h_lepPhiTurnOn_den_(nullptr),
0296       h_NPVTurnOn_num_(nullptr),
0297       h_NPVTurnOn_den_(nullptr) {
0298   edm::LogInfo("LepHTMonitor") << "Constructor LepHTMonitor::LepHTMonitor\n";
0299 }
0300 
0301 LepHTMonitor::~LepHTMonitor() throw() {
0302   if (num_genTriggerEventFlag_) {
0303     num_genTriggerEventFlag_.reset();
0304   }
0305   if (den_lep_genTriggerEventFlag_) {
0306     den_lep_genTriggerEventFlag_.reset();
0307   }
0308   if (den_HT_genTriggerEventFlag_) {
0309     den_HT_genTriggerEventFlag_.reset();
0310   }
0311 }
0312 
0313 void LepHTMonitor::bookHistograms(DQMStore::IBooker &ibooker, const edm::Run &iRun, const edm::EventSetup &iSetup) {
0314   // Initialize trigger flags
0315   if (num_genTriggerEventFlag_ && num_genTriggerEventFlag_->on()) {
0316     num_genTriggerEventFlag_->initRun(iRun, iSetup);
0317   }
0318   if (den_lep_genTriggerEventFlag_ && den_lep_genTriggerEventFlag_->on()) {
0319     den_lep_genTriggerEventFlag_->initRun(iRun, iSetup);
0320   }
0321   if (den_HT_genTriggerEventFlag_ && den_HT_genTriggerEventFlag_->on()) {
0322     den_HT_genTriggerEventFlag_->initRun(iRun, iSetup);
0323   }
0324 
0325   // check if every HLT path specified in numerator and denominator has a valid match in the HLT Menu
0326   hltPathsAreValid_ = ((num_genTriggerEventFlag_ && num_genTriggerEventFlag_->on() &&
0327                         num_genTriggerEventFlag_->allHLTPathsAreValid()) &&
0328                        ((den_lep_genTriggerEventFlag_ && den_lep_genTriggerEventFlag_->on() &&
0329                          den_lep_genTriggerEventFlag_->allHLTPathsAreValid()) ||
0330                         (den_HT_genTriggerEventFlag_ && den_HT_genTriggerEventFlag_->on() &&
0331                          den_HT_genTriggerEventFlag_->allHLTPathsAreValid())));
0332 
0333   // if valid HLT paths are required,
0334   // create DQM outputs only if all paths are valid
0335   if (requireValidHLTPaths_ and (not hltPathsAreValid_)) {
0336     return;
0337   }
0338 
0339   // book at beginRun
0340   ibooker.cd();
0341   ibooker.setCurrentFolder("HLT/SUSY/LepHT/" + folderName_);
0342 
0343   bool is_mu = false;
0344   bool is_ele = false;
0345   if (theElectronTag_.label().empty() and not theMuonTag_.label().empty()) {
0346     is_mu = true;
0347   } else if (not theElectronTag_.label().empty() and theMuonTag_.label().empty()) {
0348     is_ele = true;
0349   }
0350 
0351   // Cosmetic axis names
0352   std::string lepton = "lepton", Lepton = "Lepton";
0353   if (is_mu && !is_ele) {
0354     lepton = "muon";
0355     Lepton = "Muon";
0356   } else if (is_ele && !is_mu) {
0357     lepton = "electron";
0358     Lepton = "Electron";
0359   }
0360 
0361   //Convert to vfloat for picky TH1F constructor
0362   vector<float> f_ptbins;
0363   for (double ptbin : ptbins_)
0364     f_ptbins.push_back(static_cast<float>(ptbin));
0365   vector<float> f_htbins;
0366   for (double htbin : htbins_)
0367     f_htbins.push_back(static_cast<float>(htbin));
0368 
0369   //num and den hists to be divided in harvesting step to make turn on curves
0370   h_pfHTTurnOn_num_ =
0371       ibooker.book1D("pfHTTurnOn_num", "Numerator;Offline H_{T} [GeV];", f_htbins.size() - 1, f_htbins.data());
0372   h_pfHTTurnOn_den_ =
0373       ibooker.book1D("pfHTTurnOn_den", "Denominator;Offline H_{T} [GeV];", f_htbins.size() - 1, f_htbins.data());
0374 
0375   h_lepPtTurnOn_num_ = ibooker.book1D("lepPtTurnOn_num",
0376                                       ("Numerator;Offline " + lepton + " p_{T} [GeV];").c_str(),
0377                                       f_ptbins.size() - 1,
0378                                       f_ptbins.data());
0379   h_lepPtTurnOn_den_ = ibooker.book1D("lepPtTurnOn_den",
0380                                       ("Denominator;Offline " + lepton + " p_{T} [GeV];").c_str(),
0381                                       f_ptbins.size() - 1,
0382                                       f_ptbins.data());
0383   h_lepEtaTurnOn_num_ =
0384       ibooker.book1D("lepEtaTurnOn_num", "Numerator;Offline lepton #eta;", nbins_eta_, etabins_min_, etabins_max_);
0385   h_lepEtaTurnOn_den_ =
0386       ibooker.book1D("lepEtaTurnOn_den", "Denominator;Offline lepton #eta;", nbins_eta_, etabins_min_, etabins_max_);
0387   h_lepPhiTurnOn_num_ =
0388       ibooker.book1D("lepPhiTurnOn_num", "Numerator;Offline lepton #phi;", nbins_phi_, phibins_min_, phibins_max_);
0389   h_lepPhiTurnOn_den_ =
0390       ibooker.book1D("lepPhiTurnOn_den", "Denominator;Offline lepton #phi;", nbins_phi_, phibins_min_, phibins_max_);
0391 
0392   h_lepEtaPhiTurnOn_num_ = ibooker.book2D("lepEtaPhiTurnOn_num",
0393                                           "Numerator;Offline lepton #eta;Offline lepton #phi;",
0394                                           nbins_eta_ / 2,
0395                                           etabins_min_,
0396                                           etabins_max_,
0397                                           nbins_phi_ / 2,
0398                                           phibins_min_,
0399                                           phibins_max_);
0400   h_lepEtaPhiTurnOn_den_ = ibooker.book2D("lepEtaPhiTurnOn_den",
0401                                           "Denominator;Offline lepton #eta;Offline lepton #phi;",
0402                                           nbins_eta_ / 2,
0403                                           etabins_min_,
0404                                           etabins_max_,
0405                                           nbins_phi_ / 2,
0406                                           phibins_min_,
0407                                           phibins_max_);
0408 
0409   h_NPVTurnOn_num_ = ibooker.book1D("NPVTurnOn_num", "Numerator;N_{PV};", nbins_npv_, npvbins_min_, npvbins_max_);
0410   h_NPVTurnOn_den_ = ibooker.book1D("NPVTurnOn_den", "Denominator;N_{PV};", nbins_npv_, npvbins_min_, npvbins_max_);
0411 
0412   ibooker.cd();
0413 }
0414 
0415 void LepHTMonitor::analyze(const edm::Event &e, const edm::EventSetup &eSetup) {
0416   // if valid HLT paths are required,
0417   // analyze event only if all paths are valid
0418   if (requireValidHLTPaths_ and (not hltPathsAreValid_)) {
0419     return;
0420   }
0421 
0422   // Find whether main and auxilliary triggers fired
0423   bool hasFired = false;
0424   bool hasFiredAuxiliary = false;
0425   bool hasFiredLeptonAuxiliary = false;
0426   if (den_lep_genTriggerEventFlag_->on() && den_lep_genTriggerEventFlag_->accept(e, eSetup))
0427     hasFiredLeptonAuxiliary = true;
0428   if (den_HT_genTriggerEventFlag_->on() && den_HT_genTriggerEventFlag_->accept(e, eSetup))
0429     hasFiredAuxiliary = true;
0430   if (num_genTriggerEventFlag_->on() && num_genTriggerEventFlag_->accept(e, eSetup))
0431     hasFired = true;
0432 
0433   if (!(hasFiredAuxiliary || hasFiredLeptonAuxiliary))
0434     return;
0435   int npv = 0;
0436   //Vertex
0437   edm::Handle<reco::VertexCollection> VertexCollection;
0438   if (not theVertexCollectionTag_.label().empty()) {
0439     e.getByToken(theVertexCollection_, VertexCollection);
0440     if (!VertexCollection.isValid()) {
0441       edm::LogWarning("LepHTMonitor") << "Invalid VertexCollection: " << theVertexCollectionTag_.label() << '\n';
0442     } else
0443       npv = VertexCollection->size();
0444   }
0445 
0446   //Get electron ID map
0447   edm::Handle<edm::ValueMap<bool> > ele_id_decisions;
0448   if (not theElectronVIDTag_.label().empty()) {
0449     e.getByToken(theElectronVIDMap_, ele_id_decisions);
0450     if (!ele_id_decisions.isValid()) {
0451       edm::LogWarning("LepHTMonitor") << "Invalid Electron VID map: " << theElectronVIDTag_.label() << '\n';
0452     }
0453   }
0454 
0455   //Conversions
0456   edm::Handle<reco::ConversionCollection> ConversionCollection;
0457   if (not theConversionCollectionTag_.label().empty()) {
0458     e.getByToken(theConversionCollection_, ConversionCollection);
0459     if (!ConversionCollection.isValid()) {
0460       edm::LogWarning("LepHTMonitor") << "Invalid ConversionCollection: " << theConversionCollectionTag_.label()
0461                                       << '\n';
0462     }
0463   }
0464 
0465   //Beam Spot
0466   edm::Handle<reco::BeamSpot> BeamSpot;
0467   if (not theBeamSpotTag_.label().empty()) {
0468     e.getByToken(theBeamSpot_, BeamSpot);
0469     if (!BeamSpot.isValid()) {
0470       edm::LogWarning("LepHTMonitor") << "Invalid BeamSpot: " << theBeamSpotTag_.label() << '\n';
0471     }
0472   }
0473 
0474   //MET
0475   edm::Handle<reco::PFMETCollection> pfMETCollection;
0476   if (not thePfMETTag_.label().empty()) {
0477     e.getByToken(thePfMETCollection_, pfMETCollection);
0478     if (!pfMETCollection.isValid()) {
0479       edm::LogWarning("LepHTMonitor") << "Invalid PFMETCollection: " << thePfMETTag_.label() << '\n';
0480     }
0481   }
0482 
0483   //Jets
0484   edm::Handle<reco::PFJetCollection> pfJetCollection;
0485   if (not thePfJetTag_.label().empty()) {
0486     e.getByToken(thePfJetCollection_, pfJetCollection);
0487     if (!pfJetCollection.isValid()) {
0488       edm::LogWarning("LepHTMonitor") << "Invalid PFJetCollection: " << thePfJetTag_.label() << '\n';
0489     }
0490   }
0491 
0492   //Electron
0493   edm::Handle<edm::View<reco::GsfElectron> > ElectronCollection;
0494   if (not theElectronTag_.label().empty()) {
0495     e.getByToken(theElectronCollection_, ElectronCollection);
0496     if (!ElectronCollection.isValid()) {
0497       edm::LogWarning("LepHTMonitor") << "Invalid GsfElectronCollection: " << theElectronTag_.label() << '\n';
0498     }
0499   }
0500 
0501   //Muon
0502   edm::Handle<reco::MuonCollection> MuonCollection;
0503   if (not theMuonTag_.label().empty()) {
0504     e.getByToken(theMuonCollection_, MuonCollection);
0505     if (!MuonCollection.isValid()) {
0506       edm::LogWarning("LepHTMonitor") << "Invalid MuonCollection: " << theMuonTag_.label() << '\n';
0507     }
0508   }
0509 
0510   //Get offline HT
0511   double pfHT = -1.0;
0512   if (pfJetCollection.isValid()) {
0513     pfHT = 0.0;
0514     for (auto const &pfjet : *pfJetCollection) {
0515       if (pfjet.pt() < jetPtCut_)
0516         continue;
0517       if (std::abs(pfjet.eta()) > jetEtaCut_)
0518         continue;
0519       pfHT += pfjet.pt();
0520     }
0521   }
0522 
0523   //Get offline MET
0524   double pfMET = -1.0;
0525   if (pfMETCollection.isValid() && !pfMETCollection->empty()) {
0526     pfMET = pfMETCollection->front().et();
0527   }
0528 
0529   //Find offline leptons and keep track of pt,eta of leading and trailing leptons
0530   double lep_max_pt = -1.0;
0531   double lep_eta = 0;
0532   double lep_phi = 0;
0533   double trailing_ele_eta = 0;
0534   double trailing_ele_phi = 0;
0535   double trailing_mu_eta = 0;
0536   double trailing_mu_phi = 0;
0537   double min_ele_pt = -1.0;
0538   double min_mu_pt = -1.0;
0539   int nels = 0;
0540   int nmus = 0;
0541   if (VertexCollection.isValid() && !VertexCollection->empty()) {  //for quality checks
0542     //Try to find a reco electron
0543     if (ElectronCollection.isValid() && ConversionCollection.isValid() && BeamSpot.isValid() &&
0544         ele_id_decisions.isValid()) {
0545       size_t index = 0;
0546       for (auto const &electron : *ElectronCollection) {
0547         const auto el = ElectronCollection->ptrAt(index);
0548         bool pass_id = (*ele_id_decisions)[el];
0549         if (isGood(electron,
0550                    VertexCollection->front().position(),
0551                    BeamSpot->position(),
0552                    ConversionCollection,
0553                    pass_id,
0554                    lep_counting_threshold_,
0555                    lep_iso_cut_,
0556                    lep_eta_cut_,
0557                    lep_d0_cut_b_,
0558                    lep_dz_cut_b_,
0559                    lep_d0_cut_e_,
0560                    lep_dz_cut_e_)) {
0561           if (electron.pt() > lep_max_pt) {
0562             lep_max_pt = electron.pt();
0563             lep_eta = electron.eta();
0564             lep_phi = electron.phi();
0565           }
0566           if (electron.pt() < min_ele_pt || min_ele_pt < 0) {
0567             min_ele_pt = electron.pt();
0568             trailing_ele_eta = electron.eta();
0569             trailing_ele_phi = electron.phi();
0570           }
0571           nels++;
0572         }
0573         index++;
0574       }
0575     }
0576 
0577     //Try to find a reco muon
0578     if (MuonCollection.isValid()) {
0579       for (auto const &muon : *MuonCollection) {
0580         if (isGood(muon,
0581                    VertexCollection->front(),
0582                    lep_counting_threshold_,
0583                    lep_iso_cut_,
0584                    lep_eta_cut_,
0585                    lep_d0_cut_b_,
0586                    lep_dz_cut_b_,
0587                    muonIDlevel_)) {
0588           if (muon.pt() > lep_max_pt) {
0589             lep_max_pt = muon.pt();
0590             lep_eta = muon.eta();
0591             lep_phi = muon.phi();
0592           }
0593           if (muon.pt() < min_mu_pt || min_mu_pt < 0) {
0594             min_mu_pt = muon.pt();
0595             trailing_mu_eta = muon.eta();
0596             trailing_mu_phi = muon.phi();
0597           }
0598           nmus++;
0599         }
0600       }
0601     }
0602   }
0603 
0604   //Fill single lepton triggers with leading lepton pT
0605   float lep_pt = lep_max_pt;
0606 
0607   //For dilepton triggers, use trailing rather than leading lepton
0608   if (nmusCut_ >= 2) {
0609     lep_pt = min_mu_pt;
0610     lep_eta = trailing_mu_eta;
0611     lep_phi = trailing_mu_phi;
0612   }
0613   if (nelsCut_ >= 2) {
0614     lep_pt = min_ele_pt;
0615     lep_eta = trailing_ele_eta;
0616     lep_phi = trailing_ele_phi;
0617   }
0618   if (nelsCut_ >= 1 && nmusCut_ >= 1) {
0619     if (min_ele_pt < min_mu_pt) {
0620       lep_pt = min_ele_pt;
0621       lep_eta = trailing_ele_eta;
0622       lep_phi = trailing_ele_phi;
0623     } else {
0624       lep_pt = min_mu_pt;
0625       lep_eta = trailing_mu_eta;
0626       lep_phi = trailing_mu_phi;
0627     }
0628   }
0629 
0630   const bool nleps_cut = nels >= nelsCut_ && nmus >= nmusCut_;
0631   bool lep_plateau = lep_pt > lep_pt_plateau_ || lep_pt_plateau_ < 0.0;
0632 
0633   //Fill lepton pT and eta histograms
0634   if (hasFiredLeptonAuxiliary || !e.isRealData()) {
0635     if (nleps_cut && (pfMET > metCut_ || metCut_ < 0.0) && (pfHT > htCut_ || htCut_ < 0.0)) {
0636       if (h_lepPtTurnOn_den_) {
0637         if (lep_pt > ptbins_.back())
0638           lep_pt = ptbins_.back() - 1;  //Overflow protection
0639         h_lepPtTurnOn_den_->Fill(lep_pt);
0640       }
0641       if (h_lepPtTurnOn_num_ && hasFired)
0642         h_lepPtTurnOn_num_->Fill(lep_pt);
0643 
0644       if (lep_plateau) {
0645         //Fill Eta and Phi histograms for leptons above pT threshold
0646         if (h_lepEtaTurnOn_den_)
0647           h_lepEtaTurnOn_den_->Fill(lep_eta);
0648         if (h_lepEtaTurnOn_num_ && hasFired)
0649           h_lepEtaTurnOn_num_->Fill(lep_eta);
0650         if (h_lepPhiTurnOn_den_)
0651           h_lepPhiTurnOn_den_->Fill(lep_phi);
0652         if (h_lepPhiTurnOn_num_ && hasFired)
0653           h_lepPhiTurnOn_num_->Fill(lep_phi);
0654         if (h_lepEtaPhiTurnOn_den_)
0655           h_lepEtaPhiTurnOn_den_->Fill(lep_eta, lep_phi);
0656         if (h_lepEtaPhiTurnOn_num_ && hasFired)
0657           h_lepEtaPhiTurnOn_num_->Fill(lep_eta, lep_phi);
0658 
0659         //Fill NPV histograms
0660         if (h_NPVTurnOn_den_)
0661           h_NPVTurnOn_den_->Fill(npv);
0662         if (h_NPVTurnOn_num_ && hasFired)
0663           h_NPVTurnOn_num_->Fill(npv);
0664       }
0665     }
0666   }
0667 
0668   //Fill HT turn-on histograms
0669   if (hasFiredAuxiliary || !e.isRealData()) {
0670     if (nleps_cut && lep_plateau) {
0671       if (h_pfHTTurnOn_den_) {
0672         if (pfHT > htbins_.back())
0673           pfHT = htbins_.back() - 1;  //Overflow protection
0674         h_pfHTTurnOn_den_->Fill(pfHT);
0675       }
0676       if (h_pfHTTurnOn_num_ && hasFired)
0677         h_pfHTTurnOn_num_->Fill(pfHT);
0678     }
0679   }
0680 }
0681 
0682 DEFINE_FWK_MODULE(LepHTMonitor);