Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:09:35

0001 #include "DQMOffline/L1Trigger/interface/L1TEGammaOffline.h"
0002 #include "DQMOffline/L1Trigger/interface/L1TFillWithinLimits.h"
0003 #include "DQMOffline/L1Trigger/interface/L1TCommon.h"
0004 
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 #include "FWCore/Framework/interface/MakerMacros.h"
0007 // Geometry
0008 #include "DataFormats/Math/interface/deltaR.h"
0009 #include "DataFormats/Math/interface/deltaPhi.h"
0010 #include "DataFormats/Math/interface/LorentzVector.h"
0011 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
0012 #include "TLorentzVector.h"
0013 
0014 #include <iostream>
0015 #include <iomanip>
0016 #include <cstdio>
0017 #include <string>
0018 #include <sstream>
0019 #include <cmath>
0020 #include <algorithm>
0021 
0022 const std::map<std::string, unsigned int> L1TEGammaOffline::PlotConfigNames = {
0023     {"nVertex", PlotConfig::nVertex}, {"ETvsET", PlotConfig::ETvsET}, {"PHIvsPHI", PlotConfig::PHIvsPHI}};
0024 
0025 //
0026 // -------------------------------------- Constructor --------------------------------------------
0027 //
0028 L1TEGammaOffline::L1TEGammaOffline(const edm::ParameterSet& ps)
0029     : theGsfElectronCollection_(
0030           consumes<reco::GsfElectronCollection>(ps.getParameter<edm::InputTag>("electronCollection"))),
0031       thePhotonCollection_(consumes<std::vector<reco::Photon> >(ps.getParameter<edm::InputTag>("photonCollection"))),
0032       thePVCollection_(consumes<reco::VertexCollection>(ps.getParameter<edm::InputTag>("PVCollection"))),
0033       theBSCollection_(consumes<reco::BeamSpot>(ps.getParameter<edm::InputTag>("beamSpotCollection"))),
0034       triggerInputTag_(consumes<trigger::TriggerEvent>(ps.getParameter<edm::InputTag>("triggerInputTag"))),
0035       triggerResultsInputTag_(consumes<edm::TriggerResults>(ps.getParameter<edm::InputTag>("triggerResults"))),
0036       triggerProcess_(ps.getParameter<std::string>("triggerProcess")),
0037       triggerNames_(ps.getParameter<std::vector<std::string> >("triggerNames")),
0038       histFolder_(ps.getParameter<std::string>("histFolder")),
0039       efficiencyFolder_(histFolder_ + "/efficiency_raw"),
0040       stage2CaloLayer2EGammaToken_(
0041           consumes<l1t::EGammaBxCollection>(ps.getParameter<edm::InputTag>("stage2CaloLayer2EGammaSource"))),
0042       electronEfficiencyThresholds_(ps.getParameter<std::vector<double> >("electronEfficiencyThresholds")),
0043       electronEfficiencyBins_(ps.getParameter<std::vector<double> >("electronEfficiencyBins")),
0044       probeToL1Offset_(ps.getParameter<double>("probeToL1Offset")),
0045       deepInspectionElectronThresholds_(ps.getParameter<std::vector<double> >("deepInspectionElectronThresholds")),
0046       photonEfficiencyThresholds_(ps.getParameter<std::vector<double> >("photonEfficiencyThresholds")),
0047       photonEfficiencyBins_(ps.getParameter<std::vector<double> >("photonEfficiencyBins")),
0048       maxDeltaRForL1Matching_(ps.getParameter<double>("maxDeltaRForL1Matching")),
0049       maxDeltaRForHLTMatching_(ps.getParameter<double>("maxDeltaRForHLTMatching")),
0050       recoToL1TThresholdFactor_(ps.getParameter<double>("recoToL1TThresholdFactor")),
0051       tagElectron_(),
0052       probeElectron_(),
0053       tagAndProbleInvariantMass_(-1.),
0054       hltConfig_(),
0055       triggerIndices_(),
0056       triggerResults_(),
0057       triggerEvent_(),
0058       histDefinitions_(dqmoffline::l1t::readHistDefinitions(ps.getParameterSet("histDefinitions"), PlotConfigNames)),
0059       h_nVertex_(),
0060       h_tagAndProbeMass_(),
0061       h_L1EGammaETvsElectronET_EB_(),
0062       h_L1EGammaETvsElectronET_EE_(),
0063       h_L1EGammaETvsElectronET_EB_EE_(),
0064       h_L1EGammaPhivsElectronPhi_EB_(),
0065       h_L1EGammaPhivsElectronPhi_EE_(),
0066       h_L1EGammaPhivsElectronPhi_EB_EE_(),
0067       h_L1EGammaEtavsElectronEta_(),
0068       h_resolutionElectronET_EB_(),
0069       h_resolutionElectronET_EE_(),
0070       h_resolutionElectronET_EB_EE_(),
0071       h_resolutionElectronPhi_EB_(),
0072       h_resolutionElectronPhi_EE_(),
0073       h_resolutionElectronPhi_EB_EE_(),
0074       h_resolutionElectronEta_(),
0075       h_efficiencyElectronET_EB_pass_(),
0076       h_efficiencyElectronET_EE_pass_(),
0077       h_efficiencyElectronET_EB_EE_pass_(),
0078       h_efficiencyElectronPhi_vs_Eta_pass_(),
0079       h_efficiencyElectronEta_pass_(),
0080       h_efficiencyElectronPhi_pass_(),
0081       h_efficiencyElectronNVertex_pass_(),
0082       h_efficiencyElectronET_EB_total_(),
0083       h_efficiencyElectronET_EE_total_(),
0084       h_efficiencyElectronET_EB_EE_total_(),
0085       h_efficiencyElectronPhi_vs_Eta_total_(),
0086       h_efficiencyElectronEta_total_(),
0087       h_efficiencyElectronPhi_total_(),
0088       h_efficiencyElectronNVertex_total_(),
0089       h_L1EGammaETvsPhotonET_EB_(),
0090       h_L1EGammaETvsPhotonET_EE_(),
0091       h_L1EGammaETvsPhotonET_EB_EE_(),
0092       h_L1EGammaPhivsPhotonPhi_EB_(),
0093       h_L1EGammaPhivsPhotonPhi_EE_(),
0094       h_L1EGammaPhivsPhotonPhi_EB_EE_(),
0095       h_L1EGammaEtavsPhotonEta_(),
0096       h_resolutionPhotonEta_(),
0097       h_efficiencyPhotonET_EB_pass_(),
0098       h_efficiencyPhotonET_EE_pass_(),
0099       h_efficiencyPhotonET_EB_EE_pass_(),
0100       h_efficiencyPhotonET_EB_total_(),
0101       h_efficiencyPhotonET_EE_total_(),
0102       h_efficiencyPhotonET_EB_EE_total_() {
0103   edm::LogInfo("L1TEGammaOffline") << "Constructor "
0104                                    << "L1TEGammaOffline::L1TEGammaOffline " << std::endl;
0105 }
0106 
0107 //
0108 // -- Destructor
0109 //
0110 L1TEGammaOffline::~L1TEGammaOffline() {
0111   edm::LogInfo("L1TEGammaOffline") << "Destructor L1TEGammaOffline::~L1TEGammaOffline " << std::endl;
0112 }
0113 
0114 //
0115 // -------------------------------------- beginRun --------------------------------------------
0116 //
0117 void L1TEGammaOffline::dqmBeginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) {
0118   edm::LogInfo("L1TEGammaOffline") << "L1TEGammaOffline::beginRun" << std::endl;
0119   bool changed(true);
0120   if (!hltConfig_.init(iRun, iSetup, triggerProcess_, changed)) {
0121     edm::LogError("L1TEGammaOffline") << " HLT config extraction failure with process name " << triggerProcess_
0122                                       << std::endl;
0123     triggerNames_.clear();
0124   } else {
0125     triggerIndices_ = dqmoffline::l1t::getTriggerIndices(triggerNames_, hltConfig_.triggerNames());
0126   }
0127 }
0128 
0129 //
0130 // -------------------------------------- bookHistos --------------------------------------------
0131 //
0132 void L1TEGammaOffline::bookHistograms(DQMStore::IBooker& ibooker, edm::Run const&, edm::EventSetup const&) {
0133   edm::LogInfo("L1TEGammaOffline") << "L1TEGammaOffline::bookHistograms" << std::endl;
0134 
0135   //book at beginRun
0136   bookElectronHistos(ibooker);
0137   // bookPhotonHistos(ibooker);
0138 }
0139 
0140 //
0141 // -------------------------------------- Analyze --------------------------------------------
0142 //
0143 void L1TEGammaOffline::analyze(edm::Event const& e, edm::EventSetup const& eSetup) {
0144   edm::LogInfo("L1TEGammaOffline") << "L1TEGammaOffline::analyze" << std::endl;
0145 
0146   edm::Handle<edm::TriggerResults> triggerResultHandle;
0147   e.getByToken(triggerResultsInputTag_, triggerResultHandle);
0148   if (!triggerResultHandle.isValid()) {
0149     edm::LogWarning("L1TEGammaOffline") << "invalid edm::TriggerResults handle" << std::endl;
0150     return;
0151   }
0152   triggerResults_ = *triggerResultHandle;
0153 
0154   edm::Handle<trigger::TriggerEvent> triggerEventHandle;
0155   e.getByToken(triggerInputTag_, triggerEventHandle);
0156   if (!triggerEventHandle.isValid()) {
0157     edm::LogWarning("L1TEGammaOffline") << "invalid trigger::TriggerEvent handle" << std::endl;
0158     return;
0159   }
0160   triggerEvent_ = *triggerEventHandle;
0161 
0162   edm::Handle<reco::VertexCollection> vertexHandle;
0163   e.getByToken(thePVCollection_, vertexHandle);
0164   if (!vertexHandle.isValid()) {
0165     edm::LogWarning("L1TEGammaOffline") << "invalid collection: vertex " << std::endl;
0166     return;
0167   }
0168 
0169   unsigned int nVertex = vertexHandle->size();
0170   dqmoffline::l1t::fillWithinLimits(h_nVertex_, nVertex);
0171 
0172   if (!dqmoffline::l1t::passesAnyTriggerFromList(triggerIndices_, triggerResults_)) {
0173     return;
0174   }
0175   // L1T
0176   fillElectrons(e, nVertex);
0177   // fillPhotons(e, nVertex);
0178 }
0179 
0180 void L1TEGammaOffline::fillElectrons(edm::Event const& e, const unsigned int nVertex) {
0181   edm::Handle<l1t::EGammaBxCollection> l1EGamma;
0182   e.getByToken(stage2CaloLayer2EGammaToken_, l1EGamma);
0183 
0184   edm::Handle<reco::GsfElectronCollection> gsfElectrons;
0185   e.getByToken(theGsfElectronCollection_, gsfElectrons);
0186 
0187   if (!gsfElectrons.isValid()) {
0188     edm::LogWarning("L1TEGammaOffline") << "invalid collection: GSF electrons " << std::endl;
0189     return;
0190   }
0191   if (gsfElectrons->empty()) {
0192     LogDebug("L1TEGammaOffline") << "empty collection: GSF electrons " << std::endl;
0193     return;
0194   }
0195   if (!l1EGamma.isValid()) {
0196     edm::LogWarning("L1TEGammaOffline") << "invalid collection: L1 EGamma " << std::endl;
0197     return;
0198   }
0199   if (!findTagAndProbePair(gsfElectrons)) {
0200     LogDebug("L1TEGammaOffline") << "Could not find a tag & probe pair" << std::endl;
0201     return;  //continue to next event
0202   }
0203 
0204   auto probeElectron = probeElectron_;
0205 
0206   // find corresponding L1 EG
0207   double minDeltaR = maxDeltaRForL1Matching_;
0208   l1t::EGamma closestL1EGamma;
0209   bool foundMatch = false;
0210 
0211   int bunchCrossing = 0;
0212   for (auto egamma = l1EGamma->begin(bunchCrossing); egamma != l1EGamma->end(bunchCrossing); ++egamma) {
0213     double currentDeltaR = deltaR(egamma->eta(), egamma->phi(), probeElectron.eta(), probeElectron.phi());
0214     if (currentDeltaR > minDeltaR) {
0215       continue;
0216     } else {
0217       minDeltaR = currentDeltaR;
0218       closestL1EGamma = *egamma;
0219       foundMatch = true;
0220     }
0221   }
0222 
0223   if (!foundMatch) {
0224     LogDebug("L1TEGammaOffline") << "Could not find a matching L1 EGamma " << std::endl;
0225     return;
0226   }
0227 
0228   double recoEt = probeElectron.et();
0229   double recoEta = probeElectron.eta();
0230   double recoPhi = probeElectron.phi();
0231 
0232   double l1Et = closestL1EGamma.et();
0233   double l1Eta = closestL1EGamma.eta();
0234   double l1Phi = closestL1EGamma.phi();
0235 
0236   // if no reco value, relative resolution does not make sense -> sort to overflow
0237   double outOfBounds = 9999;
0238   double resolutionEt = recoEt > 0 ? (l1Et - recoEt) / recoEt : outOfBounds;
0239   double resolutionEta = l1Eta - recoEta;
0240   double resolutionPhi = reco::deltaPhi(l1Phi, recoPhi);
0241 
0242   using namespace dqmoffline::l1t;
0243   // eta
0244   fill2DWithinLimits(h_L1EGammaEtavsElectronEta_, recoEta, l1Eta);
0245   fillWithinLimits(h_resolutionElectronEta_, resolutionEta);
0246 
0247   // plots for deeper inspection
0248   for (auto threshold : deepInspectionElectronThresholds_) {
0249     if (recoEt > threshold * recoToL1TThresholdFactor_) {
0250       fillWithinLimits(h_efficiencyElectronEta_total_[threshold], recoEta);
0251       fillWithinLimits(h_efficiencyElectronPhi_total_[threshold], recoPhi);
0252       fillWithinLimits(h_efficiencyElectronNVertex_total_[threshold], nVertex);
0253       if (l1Et > threshold + probeToL1Offset_) {
0254         fillWithinLimits(h_efficiencyElectronEta_pass_[threshold], recoEta);
0255         fillWithinLimits(h_efficiencyElectronPhi_pass_[threshold], recoPhi);
0256         fillWithinLimits(h_efficiencyElectronNVertex_pass_[threshold], nVertex);
0257       }
0258     }
0259   }
0260 
0261   for (auto threshold : electronEfficiencyThresholds_) {
0262     if (recoEt > threshold * recoToL1TThresholdFactor_) {
0263       fill2DWithinLimits(h_efficiencyElectronPhi_vs_Eta_total_[threshold], recoEta, recoPhi);
0264       if (l1Et > threshold + probeToL1Offset_) {
0265         fill2DWithinLimits(h_efficiencyElectronPhi_vs_Eta_pass_[threshold], recoEta, recoPhi);
0266       }
0267     }
0268   }
0269 
0270   if (std::abs(recoEta) <= 1.479) {  // barrel
0271     // et
0272     fill2DWithinLimits(h_L1EGammaETvsElectronET_EB_, recoEt, l1Et);
0273     fill2DWithinLimits(h_L1EGammaETvsElectronET_EB_EE_, recoEt, l1Et);
0274     //resolution
0275     fillWithinLimits(h_resolutionElectronET_EB_, resolutionEt);
0276     fillWithinLimits(h_resolutionElectronET_EB_EE_, resolutionEt);
0277     // phi
0278     fill2DWithinLimits(h_L1EGammaPhivsElectronPhi_EB_, recoPhi, l1Phi);
0279     fill2DWithinLimits(h_L1EGammaPhivsElectronPhi_EB_EE_, recoPhi, l1Phi);
0280     // resolution
0281     fillWithinLimits(h_resolutionElectronPhi_EB_, resolutionPhi);
0282     fillWithinLimits(h_resolutionElectronPhi_EB_EE_, resolutionPhi);
0283 
0284     // turn-ons
0285     for (auto threshold : electronEfficiencyThresholds_) {
0286       fillWithinLimits(h_efficiencyElectronET_EB_total_[threshold], recoEt);
0287       fillWithinLimits(h_efficiencyElectronET_EB_EE_total_[threshold], recoEt);
0288       if (l1Et > threshold) {
0289         fillWithinLimits(h_efficiencyElectronET_EB_pass_[threshold], recoEt);
0290         fillWithinLimits(h_efficiencyElectronET_EB_EE_pass_[threshold], recoEt);
0291       }
0292     }
0293   } else {  // end-cap
0294     // et
0295     fill2DWithinLimits(h_L1EGammaETvsElectronET_EE_, recoEt, l1Et);
0296     fill2DWithinLimits(h_L1EGammaETvsElectronET_EB_EE_, recoEt, l1Et);
0297     //resolution
0298     fillWithinLimits(h_resolutionElectronET_EE_, resolutionEt);
0299     fillWithinLimits(h_resolutionElectronET_EB_EE_, resolutionEt);
0300     // phi
0301     fill2DWithinLimits(h_L1EGammaPhivsElectronPhi_EE_, recoPhi, l1Phi);
0302     fill2DWithinLimits(h_L1EGammaPhivsElectronPhi_EB_EE_, recoPhi, l1Phi);
0303     // resolution
0304     fillWithinLimits(h_resolutionElectronPhi_EE_, resolutionPhi);
0305     fillWithinLimits(h_resolutionElectronPhi_EB_EE_, resolutionPhi);
0306 
0307     // turn-ons
0308     for (auto threshold : electronEfficiencyThresholds_) {
0309       fillWithinLimits(h_efficiencyElectronET_EE_total_[threshold], recoEt);
0310       fillWithinLimits(h_efficiencyElectronET_EB_EE_total_[threshold], recoEt);
0311       if (l1Et > threshold) {
0312         fillWithinLimits(h_efficiencyElectronET_EE_pass_[threshold], recoEt);
0313         fillWithinLimits(h_efficiencyElectronET_EB_EE_pass_[threshold], recoEt);
0314       }
0315     }
0316   }
0317 }
0318 
0319 /**
0320  * From https://cds.cern.ch/record/2202966/files/DP2016_044.pdf slide 8
0321  * Filter on
0322  * HLT_Ele30WP60_Ele8_Mass55 (TODO)
0323  * HLT_Ele30WP60_SC4_Mass55 (TODO)
0324  * Seeded by L1SingleEG, unprescaled required
0325  *
0326  * Tag & probe selection
0327  * Electron required to be within ECAL fiducial volume (|η|<1.4442 ||
0328  * 1.566<|η|<2.5).
0329  * 60 < m(ee) < 120 GeV.
0330  * Opposite charge requirement.
0331  * Tag required to pass medium electron ID and ET > 30 GeV.
0332  * Probe required to pass loose electron ID.
0333  *
0334  * @param electrons
0335  * @return
0336  */
0337 bool L1TEGammaOffline::findTagAndProbePair(edm::Handle<reco::GsfElectronCollection> const& electrons) {
0338   bool foundBoth(false);
0339   auto nElectrons = electrons->size();
0340   if (nElectrons < 2)
0341     return false;
0342 
0343   for (const auto& tagElectron : *electrons) {
0344     for (const auto& probeElectron : *electrons) {
0345       if (tagElectron.p4() == probeElectron.p4())
0346         continue;
0347 
0348       auto combined(tagElectron.p4() + probeElectron.p4());
0349       auto tagAbsEta = std::abs(tagElectron.eta());
0350       auto probeAbsEta = std::abs(probeElectron.eta());
0351 
0352       // EB-EE transition region
0353       bool isEBEEGap = tagElectron.isEBEEGap() || probeElectron.isEBEEGap();
0354       bool passesEta = !isEBEEGap && tagAbsEta < 2.5 && probeAbsEta < 2.5;
0355       bool passesCharge = tagElectron.charge() == -probeElectron.charge();
0356 
0357       // https://github.com/ikrav/cmssw/blob/egm_id_80X_v1/RecoEgamma/ElectronIdentification/plugins/cuts/GsfEleFull5x5SigmaIEtaIEtaCut.cc#L45
0358       bool tagPassesMediumID = passesMediumEleId(tagElectron) && tagElectron.et() > 30.;
0359       bool probePassesLooseID = passesLooseEleId(probeElectron);
0360       bool passesInvariantMass = combined.M() > 60 && combined.M() < 120;
0361       bool tagMatchesHLTObject = matchesAnHLTObject(tagElectron.eta(), tagElectron.phi());
0362 
0363       if (passesEta && passesInvariantMass && passesCharge && tagPassesMediumID && probePassesLooseID &&
0364           tagMatchesHLTObject) {
0365         foundBoth = true;
0366         tagElectron_ = tagElectron;
0367         probeElectron_ = probeElectron;
0368         // plot tag & probe invariant mass
0369         dqmoffline::l1t::fillWithinLimits(h_tagAndProbeMass_, combined.M());
0370         return foundBoth;
0371       }
0372     }
0373   }
0374   return foundBoth;
0375 }
0376 
0377 /**
0378  * Structure from
0379  * https://github.com/cms-sw/cmssw/blob/CMSSW_9_0_X/DQMOffline/EGamma/plugins/ElectronAnalyzer.cc
0380  * Values from
0381  * https://twiki.cern.ch/twiki/bin/view/CMS/CutBasedElectronIdentificationRun2
0382  */
0383 bool L1TEGammaOffline::passesLooseEleId(reco::GsfElectron const& electron) const {
0384   const float ecal_energy_inverse = 1.0 / electron.ecalEnergy();
0385   const float eSCoverP = electron.eSuperClusterOverP();
0386   const float eOverP = std::abs(1.0 - eSCoverP) * ecal_energy_inverse;
0387 
0388   if (electron.isEB() && eOverP > 0.241)
0389     return false;
0390   if (electron.isEE() && eOverP > 0.14)
0391     return false;
0392   if (electron.isEB() && std::abs(electron.deltaEtaSuperClusterTrackAtVtx()) > 0.00477)
0393     return false;
0394   if (electron.isEE() && std::abs(electron.deltaEtaSuperClusterTrackAtVtx()) > 0.00868)
0395     return false;
0396   if (electron.isEB() && std::abs(electron.deltaPhiSuperClusterTrackAtVtx()) > 0.222)
0397     return false;
0398   if (electron.isEE() && std::abs(electron.deltaPhiSuperClusterTrackAtVtx()) > 0.213)
0399     return false;
0400   if (electron.isEB() && electron.scSigmaIEtaIEta() > 0.011)
0401     return false;
0402   if (electron.isEE() && electron.scSigmaIEtaIEta() > 0.0314)
0403     return false;
0404   if (electron.isEB() && electron.hadronicOverEm() > 0.298)
0405     return false;
0406   if (electron.isEE() && electron.hadronicOverEm() > 0.101)
0407     return false;
0408   return true;
0409 }
0410 
0411 /*
0412  * Structure from
0413  * https://github.com/cms-sw/cmssw/blob/CMSSW_9_0_X/DQMOffline/EGamma/plugins/ElectronAnalyzer.cc
0414  * Values from
0415  * https://twiki.cern.ch/twiki/bin/view/CMS/CutBasedElectronIdentificationRun2
0416  */
0417 bool L1TEGammaOffline::passesMediumEleId(reco::GsfElectron const& electron) const {
0418   const float ecal_energy_inverse = 1.0 / electron.ecalEnergy();
0419   const float eSCoverP = electron.eSuperClusterOverP();
0420   const float eOverP = std::abs(1.0 - eSCoverP) * ecal_energy_inverse;
0421 
0422   if (electron.isEB() && eOverP < 0.134)
0423     return false;
0424   if (electron.isEE() && eOverP > 0.13)
0425     return false;
0426   if (electron.isEB() && std::abs(electron.deltaEtaSuperClusterTrackAtVtx()) > 0.00311)
0427     return false;
0428   if (electron.isEE() && std::abs(electron.deltaEtaSuperClusterTrackAtVtx()) > 0.00609)
0429     return false;
0430   if (electron.isEB() && std::abs(electron.deltaPhiSuperClusterTrackAtVtx()) > 0.103)
0431     return false;
0432   if (electron.isEE() && std::abs(electron.deltaPhiSuperClusterTrackAtVtx()) > 0.045)
0433     return false;
0434   if (electron.isEB() && electron.scSigmaIEtaIEta() > 0.00998)
0435     return false;
0436   if (electron.isEE() && electron.scSigmaIEtaIEta() > 0.0298)
0437     return false;
0438   if (electron.isEB() && electron.hadronicOverEm() > 0.253)
0439     return false;
0440   if (electron.isEE() && electron.hadronicOverEm() > 0.0878)
0441     return false;
0442   return true;
0443 }
0444 
0445 bool L1TEGammaOffline::matchesAnHLTObject(double eta, double phi) const {
0446   // get HLT objects of fired triggers
0447   using namespace dqmoffline::l1t;
0448   std::vector<bool> results = getTriggerResults(triggerIndices_, triggerResults_);
0449   std::vector<unsigned int> firedTriggers = getFiredTriggerIndices(triggerIndices_, results);
0450   std::vector<edm::InputTag> hltFilters = getHLTFilters(firedTriggers, hltConfig_, triggerProcess_);
0451   const trigger::TriggerObjectCollection hltObjects = getTriggerObjects(hltFilters, triggerEvent_);
0452   const trigger::TriggerObjectCollection matchedObjects =
0453       getMatchedTriggerObjects(eta, phi, maxDeltaRForHLTMatching_, hltObjects);
0454 
0455   return !matchedObjects.empty();
0456 }
0457 
0458 void L1TEGammaOffline::fillPhotons(edm::Event const& e, const unsigned int nVertex) {
0459   // TODO - just an example here
0460   edm::Handle<l1t::EGammaBxCollection> l1EGamma;
0461   e.getByToken(stage2CaloLayer2EGammaToken_, l1EGamma);
0462 
0463   edm::Handle<reco::PhotonCollection> photons;
0464   e.getByToken(thePhotonCollection_, photons);
0465 
0466   if (!photons.isValid()) {
0467     edm::LogWarning("L1TEGammaOffline") << "invalid collection: reco::Photons " << std::endl;
0468     return;
0469   }
0470   if (!l1EGamma.isValid()) {
0471     edm::LogWarning("L1TEGammaOffline") << "invalid collection: L1 EGamma " << std::endl;
0472     return;
0473   }
0474 
0475   if (photons->empty()) {
0476     LogDebug("L1TEGammaOffline") << "No photons found in event." << std::endl;
0477     return;
0478   }
0479 
0480   auto probePhoton = photons->at(0);
0481 
0482   double minDeltaR = 0.3;
0483   l1t::EGamma closestL1EGamma;
0484   bool foundMatch = false;
0485 
0486   int bunchCrossing = 0;
0487   for (auto egamma = l1EGamma->begin(bunchCrossing); egamma != l1EGamma->end(bunchCrossing); ++egamma) {
0488     double currentDeltaR = deltaR(egamma->eta(), egamma->phi(), probePhoton.eta(), probePhoton.phi());
0489     if (currentDeltaR > minDeltaR) {
0490       continue;
0491     } else {
0492       minDeltaR = currentDeltaR;
0493       closestL1EGamma = *egamma;
0494       foundMatch = true;
0495     }
0496   }
0497 
0498   if (!foundMatch) {
0499     LogDebug("L1TEGammaOffline") << "Could not find a matching L1 EGamma " << std::endl;
0500     return;
0501   }
0502 
0503   double recoEt = probePhoton.et();
0504   double recoEta = probePhoton.eta();
0505   double recoPhi = probePhoton.phi();
0506 
0507   double l1Et = closestL1EGamma.et();
0508   double l1Eta = closestL1EGamma.eta();
0509   double l1Phi = closestL1EGamma.phi();
0510 
0511   // if no reco value, relative resolution does not make sense -> sort to overflow
0512   double outOfBounds = 9999;
0513   double resolutionEt = recoEt > 0 ? (l1Et - recoEt) / recoEt : outOfBounds;
0514   double resolutionEta = l1Eta - recoEta;
0515   double resolutionPhi = reco::deltaPhi(l1Phi, recoPhi);
0516 
0517   using namespace dqmoffline::l1t;
0518   // eta
0519   fill2DWithinLimits(h_L1EGammaEtavsPhotonEta_, recoEta, l1Eta);
0520   fillWithinLimits(h_resolutionPhotonEta_, resolutionEta);
0521 
0522   if (std::abs(recoEta) <= 1.479) {  // barrel
0523     // et
0524     fill2DWithinLimits(h_L1EGammaETvsPhotonET_EB_, recoEt, l1Et);
0525     fill2DWithinLimits(h_L1EGammaETvsPhotonET_EB_EE_, recoEt, l1Et);
0526     //resolution
0527     fillWithinLimits(h_resolutionPhotonET_EB_, resolutionEt);
0528     fillWithinLimits(h_resolutionPhotonET_EB_EE_, resolutionEt);
0529     // phi
0530     fill2DWithinLimits(h_L1EGammaPhivsPhotonPhi_EB_, recoPhi, l1Phi);
0531     fill2DWithinLimits(h_L1EGammaPhivsPhotonPhi_EB_EE_, recoPhi, l1Phi);
0532     // resolution
0533     fillWithinLimits(h_resolutionPhotonPhi_EB_, resolutionPhi);
0534     fillWithinLimits(h_resolutionPhotonPhi_EB_EE_, resolutionPhi);
0535 
0536     // turn-ons
0537     for (auto threshold : photonEfficiencyThresholds_) {
0538       fillWithinLimits(h_efficiencyPhotonET_EB_total_[threshold], recoEt);
0539       fillWithinLimits(h_efficiencyPhotonET_EB_EE_total_[threshold], recoEt);
0540       if (l1Et > threshold) {
0541         fillWithinLimits(h_efficiencyPhotonET_EB_pass_[threshold], recoEt);
0542         fillWithinLimits(h_efficiencyPhotonET_EB_EE_pass_[threshold], recoEt);
0543       }
0544     }
0545   } else {  // end-cap
0546     // et
0547     fill2DWithinLimits(h_L1EGammaETvsPhotonET_EE_, recoEt, l1Et);
0548     fill2DWithinLimits(h_L1EGammaETvsPhotonET_EB_EE_, recoEt, l1Et);
0549     //resolution
0550     fillWithinLimits(h_resolutionPhotonET_EE_, resolutionEt);
0551     fillWithinLimits(h_resolutionPhotonET_EB_EE_, resolutionEt);
0552     // phi
0553     fill2DWithinLimits(h_L1EGammaPhivsPhotonPhi_EE_, recoPhi, l1Phi);
0554     fill2DWithinLimits(h_L1EGammaPhivsPhotonPhi_EB_EE_, recoPhi, l1Phi);
0555     // resolution
0556     fillWithinLimits(h_resolutionPhotonPhi_EE_, resolutionPhi);
0557     fillWithinLimits(h_resolutionPhotonPhi_EB_EE_, resolutionPhi);
0558 
0559     // turn-ons
0560     for (auto threshold : photonEfficiencyThresholds_) {
0561       fillWithinLimits(h_efficiencyPhotonET_EE_total_[threshold], recoEt);
0562       fillWithinLimits(h_efficiencyPhotonET_EB_EE_total_[threshold], recoEt);
0563       if (l1Et > threshold) {
0564         fillWithinLimits(h_efficiencyPhotonET_EE_pass_[threshold], recoEt);
0565         fillWithinLimits(h_efficiencyPhotonET_EB_EE_pass_[threshold], recoEt);
0566       }
0567     }
0568   }
0569 }
0570 
0571 //
0572 // -------------------------------------- endRun --------------------------------------------
0573 //
0574 void L1TEGammaOffline::dqmEndRun(edm::Run const& run, edm::EventSetup const& eSetup) {
0575   normalise2DHistogramsToBinArea();
0576 }
0577 
0578 //
0579 // -------------------------------------- book histograms --------------------------------------------
0580 //
0581 void L1TEGammaOffline::bookElectronHistos(DQMStore::IBooker& ibooker) {
0582   ibooker.cd();
0583   ibooker.setCurrentFolder(histFolder_);
0584   // since there are endRun manipulations.
0585   ibooker.setScope(MonitorElementData::Scope::RUN);
0586 
0587   dqmoffline::l1t::HistDefinition nVertexDef = histDefinitions_[PlotConfig::nVertex];
0588   h_nVertex_ = ibooker.book1D(nVertexDef.name, nVertexDef.title, nVertexDef.nbinsX, nVertexDef.xmin, nVertexDef.xmax);
0589   h_tagAndProbeMass_ = ibooker.book1D("tagAndProbeMass", "Invariant mass of tag & probe pair", 100, 40, 140);
0590   // electron reco vs L1
0591   dqmoffline::l1t::HistDefinition templateETvsET = histDefinitions_[PlotConfig::ETvsET];
0592   h_L1EGammaETvsElectronET_EB_ =
0593       ibooker.book2D("L1EGammaETvsElectronET_EB",
0594                      "L1 EGamma E_{T} vs GSF Electron E_{T} (EB); GSF Electron E_{T} (GeV); L1 EGamma E_{T} (GeV)",
0595                      templateETvsET.nbinsX,
0596                      &templateETvsET.binsX[0],
0597                      templateETvsET.nbinsY,
0598                      &templateETvsET.binsY[0]);
0599   h_L1EGammaETvsElectronET_EE_ =
0600       ibooker.book2D("L1EGammaETvsElectronET_EE",
0601                      "L1 EGamma E_{T} vs GSF Electron E_{T} (EE); GSF Electron E_{T} (GeV); L1 EGamma E_{T} (GeV)",
0602                      templateETvsET.nbinsX,
0603                      &templateETvsET.binsX[0],
0604                      templateETvsET.nbinsY,
0605                      &templateETvsET.binsY[0]);
0606   h_L1EGammaETvsElectronET_EB_EE_ =
0607       ibooker.book2D("L1EGammaETvsElectronET_EB_EE",
0608                      "L1 EGamma E_{T} vs GSF Electron E_{T} (EB+EE); GSF Electron E_{T} (GeV); L1 EGamma E_{T} (GeV)",
0609                      templateETvsET.nbinsX,
0610                      &templateETvsET.binsX[0],
0611                      templateETvsET.nbinsY,
0612                      &templateETvsET.binsY[0]);
0613 
0614   dqmoffline::l1t::HistDefinition templatePHIvsPHI = histDefinitions_[PlotConfig::PHIvsPHI];
0615   h_L1EGammaPhivsElectronPhi_EB_ = ibooker.book2D(
0616       "L1EGammaPhivsElectronPhi_EB",
0617       "#phi_{electron}^{L1} vs #phi_{electron}^{offline} (EB); #phi_{electron}^{offline}; #phi_{electron}^{L1}",
0618       templatePHIvsPHI.nbinsX,
0619       templatePHIvsPHI.xmin,
0620       templatePHIvsPHI.xmax,
0621       templatePHIvsPHI.nbinsY,
0622       templatePHIvsPHI.ymin,
0623       templatePHIvsPHI.ymax);
0624   h_L1EGammaPhivsElectronPhi_EE_ = ibooker.book2D(
0625       "L1EGammaPhivsElectronPhi_EE",
0626       "#phi_{electron}^{L1} vs #phi_{electron}^{offline} (EE); #phi_{electron}^{offline}; #phi_{electron}^{L1}",
0627       templatePHIvsPHI.nbinsX,
0628       templatePHIvsPHI.xmin,
0629       templatePHIvsPHI.xmax,
0630       templatePHIvsPHI.nbinsY,
0631       templatePHIvsPHI.ymin,
0632       templatePHIvsPHI.ymax);
0633   h_L1EGammaPhivsElectronPhi_EB_EE_ = ibooker.book2D(
0634       "L1EGammaPhivsElectronPhi_EB_EE",
0635       "#phi_{electron}^{L1} vs #phi_{electron}^{offline} (EB+EE); #phi_{electron}^{offline}; #phi_{electron}^{L1}",
0636       templatePHIvsPHI.nbinsX,
0637       templatePHIvsPHI.xmin,
0638       templatePHIvsPHI.xmax,
0639       templatePHIvsPHI.nbinsY,
0640       templatePHIvsPHI.ymin,
0641       templatePHIvsPHI.ymax);
0642 
0643   h_L1EGammaEtavsElectronEta_ = ibooker.book2D("L1EGammaEtavsElectronEta",
0644                                                "L1 EGamma #eta vs GSF Electron #eta; GSF Electron #eta; L1 EGamma #eta",
0645                                                100,
0646                                                -3,
0647                                                3,
0648                                                100,
0649                                                -3,
0650                                                3);
0651 
0652   // electron resolutions
0653   h_resolutionElectronET_EB_ =
0654       ibooker.book1D("resolutionElectronET_EB",
0655                      "electron ET resolution (EB); (L1 EGamma E_{T} - GSF Electron E_{T})/GSF Electron E_{T}; events",
0656                      50,
0657                      -1,
0658                      1.5);
0659   h_resolutionElectronET_EE_ =
0660       ibooker.book1D("resolutionElectronET_EE",
0661                      "electron ET resolution (EE); (L1 EGamma E_{T} - GSF Electron E_{T})/GSF Electron E_{T}; events",
0662                      50,
0663                      -1,
0664                      1.5);
0665   h_resolutionElectronET_EB_EE_ = ibooker.book1D(
0666       "resolutionElectronET_EB_EE",
0667       "electron ET resolution (EB+EE); (L1 EGamma E_{T} - GSF Electron E_{T})/GSF Electron E_{T}; events",
0668       50,
0669       -1,
0670       1.5);
0671 
0672   h_resolutionElectronPhi_EB_ =
0673       ibooker.book1D("resolutionElectronPhi_EB",
0674                      "#phi_{electron} resolution (EB); #phi_{electron}^{L1} - #phi_{electron}^{offline}; events",
0675                      120,
0676                      -0.3,
0677                      0.3);
0678   h_resolutionElectronPhi_EE_ =
0679       ibooker.book1D("resolutionElectronPhi_EE",
0680                      "electron #phi resolution (EE); #phi_{electron}^{L1} - #phi_{electron}^{offline}; events",
0681                      120,
0682                      -0.3,
0683                      0.3);
0684   h_resolutionElectronPhi_EB_EE_ =
0685       ibooker.book1D("resolutionElectronPhi_EB_EE",
0686                      "electron #phi resolution (EB+EE); #phi_{electron}^{L1} - #phi_{electron}^{offline}; events",
0687                      120,
0688                      -0.3,
0689                      0.3);
0690 
0691   h_resolutionElectronEta_ =
0692       ibooker.book1D("resolutionElectronEta",
0693                      "electron #eta resolution  (EB); L1 EGamma #eta - GSF Electron #eta; events",
0694                      120,
0695                      -0.3,
0696                      0.3);
0697 
0698   // electron turn-ons
0699   ibooker.setCurrentFolder(efficiencyFolder_);
0700   std::vector<float> electronBins(electronEfficiencyBins_.begin(), electronEfficiencyBins_.end());
0701   int nBins = electronBins.size() - 1;
0702   float* electronBinArray = &(electronBins[0]);
0703 
0704   for (auto threshold : electronEfficiencyThresholds_) {
0705     std::string str_threshold = std::to_string(int(threshold));
0706     h_efficiencyElectronET_EB_pass_[threshold] =
0707         ibooker.book1D("efficiencyElectronET_EB_threshold_" + str_threshold + "_Num",
0708                        "electron efficiency (EB) (numerator); GSF Electron E_{T} (GeV); events",
0709                        nBins,
0710                        electronBinArray);
0711     h_efficiencyElectronET_EE_pass_[threshold] =
0712         ibooker.book1D("efficiencyElectronET_EE_threshold_" + str_threshold + "_Num",
0713                        "electron efficiency (EE) (numerator); GSF Electron E_{T} (GeV); events",
0714                        nBins,
0715                        electronBinArray);
0716     h_efficiencyElectronET_EB_EE_pass_[threshold] =
0717         ibooker.book1D("efficiencyElectronET_EB_EE_threshold_" + str_threshold + "_Num",
0718                        "electron efficiency (EB+EE) (numerator); GSF Electron E_{T} (GeV); events",
0719                        nBins,
0720                        electronBinArray);
0721     h_efficiencyElectronPhi_vs_Eta_pass_[threshold] =
0722         ibooker.book2D("efficiencyElectronPhi_vs_Eta_threshold_" + str_threshold + "_Num",
0723                        "electron efficiency (numerator); GSF Electron #eta; GSF Electron #phi",
0724                        50,
0725                        -2.5,
0726                        2.5,
0727                        32,
0728                        -3.2,
0729                        3.2);
0730 
0731     h_efficiencyElectronET_EB_total_[threshold] =
0732         ibooker.book1D("efficiencyElectronET_EB_threshold_" + str_threshold + "_Den",
0733                        "electron efficiency (EB) (denominator); GSF Electron E_{T} (GeV); events",
0734                        nBins,
0735                        electronBinArray);
0736     h_efficiencyElectronET_EE_total_[threshold] =
0737         ibooker.book1D("efficiencyElectronET_EE_threshold_" + str_threshold + "_Den",
0738                        "electron efficiency (EE) (denominator); GSF Electron E_{T} (GeV); events",
0739                        nBins,
0740                        electronBinArray);
0741     h_efficiencyElectronET_EB_EE_total_[threshold] =
0742         ibooker.book1D("efficiencyElectronET_EB_EE_threshold_" + str_threshold + "_Den",
0743                        "electron efficiency (EB+EE) (denominator); GSF Electron E_{T} (GeV); events",
0744                        nBins,
0745                        electronBinArray);
0746     h_efficiencyElectronPhi_vs_Eta_total_[threshold] =
0747         ibooker.book2D("efficiencyElectronPhi_vs_Eta_threshold_" + str_threshold + "_Den",
0748                        "electron efficiency (denominator); GSF Electron #eta; GSF Electron #phi",
0749                        50,
0750                        -2.5,
0751                        2.5,
0752                        32,
0753                        -3.2,
0754                        3.2);
0755   }
0756 
0757   for (auto threshold : deepInspectionElectronThresholds_) {
0758     std::string str_threshold = std::to_string(int(threshold));
0759     h_efficiencyElectronEta_pass_[threshold] =
0760         ibooker.book1D("efficiencyElectronEta_threshold_" + str_threshold + "_Num",
0761                        "electron efficiency (numerator); GSF Electron #eta; events",
0762                        50,
0763                        -2.5,
0764                        2.5);
0765     h_efficiencyElectronPhi_pass_[threshold] =
0766         ibooker.book1D("efficiencyElectronPhi_threshold_" + str_threshold + "_Num",
0767                        "electron efficiency (numerator); GSF Electron #phi; events",
0768                        32,
0769                        -3.2,
0770                        3.2);
0771     h_efficiencyElectronNVertex_pass_[threshold] =
0772         ibooker.book1D("efficiencyElectronNVertex_threshold_" + str_threshold + "_Num",
0773                        "electron efficiency (numerator); Nvtx; events",
0774                        30,
0775                        0,
0776                        60);
0777 
0778     h_efficiencyElectronEta_total_[threshold] =
0779         ibooker.book1D("efficiencyElectronEta_threshold_" + str_threshold + "_Den",
0780                        "electron efficiency (denominator); GSF Electron #eta; events",
0781                        50,
0782                        -2.5,
0783                        2.5);
0784     h_efficiencyElectronPhi_total_[threshold] =
0785         ibooker.book1D("efficiencyElectronPhi_threshold_" + str_threshold + "_Den",
0786                        "electron efficiency (denominator); GSF Electron #phi; events",
0787                        32,
0788                        -3.2,
0789                        3.2);
0790     h_efficiencyElectronNVertex_total_[threshold] =
0791         ibooker.book1D("efficiencyElectronNVertex_threshold_" + str_threshold + "_Den",
0792                        "electron efficiency (denominator); Nvtx; events",
0793                        30,
0794                        0,
0795                        60);
0796   }
0797 
0798   ibooker.cd();
0799 }
0800 
0801 void L1TEGammaOffline::bookPhotonHistos(DQMStore::IBooker& ibooker) {
0802   ibooker.cd();
0803   ibooker.setCurrentFolder(histFolder_);
0804 
0805   dqmoffline::l1t::HistDefinition templateETvsET = histDefinitions_[PlotConfig::ETvsET];
0806   h_L1EGammaETvsPhotonET_EB_ =
0807       ibooker.book2D("L1EGammaETvsPhotonET_EB",
0808                      "L1 EGamma E_{T} vs  Photon E_{T} (EB);  Photon E_{T} (GeV); L1 EGamma E_{T} (GeV)",
0809                      templateETvsET.nbinsX,
0810                      &templateETvsET.binsX[0],
0811                      templateETvsET.nbinsY,
0812                      &templateETvsET.binsY[0]);
0813   h_L1EGammaETvsPhotonET_EE_ =
0814       ibooker.book2D("L1EGammaETvsPhotonET_EE",
0815                      "L1 EGamma E_{T} vs  Photon E_{T} (EE);  Photon E_{T} (GeV); L1 EGamma E_{T} (GeV)",
0816                      templateETvsET.nbinsX,
0817                      &templateETvsET.binsX[0],
0818                      templateETvsET.nbinsY,
0819                      &templateETvsET.binsY[0]);
0820   h_L1EGammaETvsPhotonET_EB_EE_ =
0821       ibooker.book2D("L1EGammaETvsPhotonET_EB_EE",
0822                      "L1 EGamma E_{T} vs  Photon E_{T} (EB+EE);  Photon E_{T} (GeV); L1 EGamma E_{T} (GeV)",
0823                      templateETvsET.nbinsX,
0824                      &templateETvsET.binsX[0],
0825                      templateETvsET.nbinsY,
0826                      &templateETvsET.binsY[0]);
0827 
0828   dqmoffline::l1t::HistDefinition templatePHIvsPHI = histDefinitions_[PlotConfig::PHIvsPHI];
0829   h_L1EGammaPhivsPhotonPhi_EB_ =
0830       ibooker.book2D("L1EGammaPhivsPhotonPhi_EB",
0831                      "#phi_{photon}^{L1} vs #phi_{photon}^{offline} (EB); #phi_{photon}^{offline}; #phi_{photon}^{L1}",
0832                      templatePHIvsPHI.nbinsX,
0833                      templatePHIvsPHI.xmin,
0834                      templatePHIvsPHI.xmax,
0835                      templatePHIvsPHI.nbinsY,
0836                      templatePHIvsPHI.ymin,
0837                      templatePHIvsPHI.ymax);
0838   h_L1EGammaPhivsPhotonPhi_EE_ =
0839       ibooker.book2D("L1EGammaPhivsPhotonPhi_EE",
0840                      "#phi_{photon}^{L1} vs #phi_{photon}^{offline} (EE); #phi_{photon}^{offline}; #phi_{photon}^{L1}",
0841                      templatePHIvsPHI.nbinsX,
0842                      templatePHIvsPHI.xmin,
0843                      templatePHIvsPHI.xmax,
0844                      templatePHIvsPHI.nbinsY,
0845                      templatePHIvsPHI.ymin,
0846                      templatePHIvsPHI.ymax);
0847   h_L1EGammaPhivsPhotonPhi_EB_EE_ = ibooker.book2D(
0848       "L1EGammaPhivsPhotonPhi_EB_EE",
0849       "#phi_{photon}^{L1} vs #phi_{photon}^{offline} (EB+EE); #phi_{photon}^{offline}; #phi_{photon}^{L1}",
0850       templatePHIvsPHI.nbinsX,
0851       templatePHIvsPHI.xmin,
0852       templatePHIvsPHI.xmax,
0853       templatePHIvsPHI.nbinsY,
0854       templatePHIvsPHI.ymin,
0855       templatePHIvsPHI.ymax);
0856 
0857   h_L1EGammaEtavsPhotonEta_ = ibooker.book2D(
0858       "L1EGammaEtavsPhotonEta", "L1 EGamma #eta vs  Photon #eta;  Photon #eta; L1 EGamma #eta", 100, -3, 3, 100, -3, 3);
0859 
0860   // photon resolutions
0861   h_resolutionPhotonET_EB_ =
0862       ibooker.book1D("resolutionPhotonET_EB",
0863                      "photon ET resolution (EB); (L1 EGamma E_{T} -  Photon E_{T})/ Photon E_{T}; events",
0864                      50,
0865                      -1,
0866                      1.5);
0867   h_resolutionPhotonET_EE_ =
0868       ibooker.book1D("resolutionPhotonET_EE",
0869                      "photon ET resolution (EE); (L1 EGamma E_{T} -  Photon E_{T})/ Photon E_{T}; events",
0870                      50,
0871                      -1,
0872                      1.5);
0873   h_resolutionPhotonET_EB_EE_ =
0874       ibooker.book1D("resolutionPhotonET_EB_EE",
0875                      "photon ET resolution (EB+EE); (L1 EGamma E_{T} -  Photon E_{T})/ Photon E_{T}; events",
0876                      50,
0877                      -1,
0878                      1.5);
0879 
0880   h_resolutionPhotonPhi_EB_ =
0881       ibooker.book1D("resolutionPhotonPhi_EB",
0882                      "#phi_{photon} resolution (EB); #phi_{photon}^{L1} - #phi_{photon}^{offline}; events",
0883                      120,
0884                      -0.3,
0885                      0.3);
0886   h_resolutionPhotonPhi_EE_ =
0887       ibooker.book1D("resolutionPhotonPhi_EE",
0888                      "photon #phi resolution (EE); #phi_{photon}^{L1} - #phi_{photon}^{offline}; events",
0889                      120,
0890                      -0.3,
0891                      0.3);
0892   h_resolutionPhotonPhi_EB_EE_ =
0893       ibooker.book1D("resolutionPhotonPhi_EB_EE",
0894                      "photon #phi resolution (EB+EE); #phi_{photon}^{L1} - #phi_{photon}^{offline}; events",
0895                      120,
0896                      -0.3,
0897                      0.3);
0898 
0899   h_resolutionPhotonEta_ = ibooker.book1D(
0900       "resolutionPhotonEta", "photon #eta resolution  (EB); L1 EGamma #eta -  Photon #eta; events", 120, -0.3, 0.3);
0901 
0902   // photon turn-ons
0903   ibooker.setCurrentFolder(efficiencyFolder_);
0904   std::vector<float> photonBins(photonEfficiencyBins_.begin(), photonEfficiencyBins_.end());
0905   int nBins = photonBins.size() - 1;
0906   float* photonBinArray = &(photonBins[0]);
0907 
0908   for (auto threshold : photonEfficiencyThresholds_) {
0909     std::string str_threshold = std::to_string(int(threshold));
0910     h_efficiencyPhotonET_EB_pass_[threshold] =
0911         ibooker.book1D("efficiencyPhotonET_EB_threshold_" + str_threshold + "_Num",
0912                        "photon efficiency (EB) (numerator);  Photon E_{T} (GeV); events",
0913                        nBins,
0914                        photonBinArray);
0915     h_efficiencyPhotonET_EE_pass_[threshold] =
0916         ibooker.book1D("efficiencyPhotonET_EE_threshold_" + str_threshold + "_Num",
0917                        "photon efficiency (EE) (numerator);  Photon E_{T} (GeV); events",
0918                        nBins,
0919                        photonBinArray);
0920     h_efficiencyPhotonET_EB_EE_pass_[threshold] =
0921         ibooker.book1D("efficiencyPhotonET_EB_EE_threshold_" + str_threshold + "_Num",
0922                        "photon efficiency (EB+EE) (numerator);  Photon E_{T} (GeV); events",
0923                        nBins,
0924                        photonBinArray);
0925 
0926     h_efficiencyPhotonET_EB_total_[threshold] =
0927         ibooker.book1D("efficiencyPhotonET_EB_threshold_" + str_threshold + "_Den",
0928                        "photon efficiency (EB) (denominator);  Photon E_{T} (GeV); events",
0929                        nBins,
0930                        photonBinArray);
0931     h_efficiencyPhotonET_EE_total_[threshold] =
0932         ibooker.book1D("efficiencyPhotonET_EE_threshold_" + str_threshold + "_Den",
0933                        "photon efficiency (EE) (denominator);  Photon E_{T} (GeV); events",
0934                        nBins,
0935                        photonBinArray);
0936     h_efficiencyPhotonET_EB_EE_total_[threshold] =
0937         ibooker.book1D("efficiencyPhotonET_EB_EE_threshold_" + str_threshold + "_Den",
0938                        "photon efficiency (EB+EE) (denominator);  Photon E_{T} (GeV); events",
0939                        nBins,
0940                        photonBinArray);
0941   }
0942 
0943   ibooker.cd();
0944 }
0945 
0946 void L1TEGammaOffline::normalise2DHistogramsToBinArea() {
0947   std::vector<MonitorElement*> monElementstoNormalize = {h_L1EGammaETvsElectronET_EB_,
0948                                                          h_L1EGammaETvsElectronET_EE_,
0949                                                          h_L1EGammaETvsElectronET_EB_EE_,
0950                                                          h_L1EGammaPhivsElectronPhi_EB_,
0951                                                          h_L1EGammaPhivsElectronPhi_EE_,
0952                                                          h_L1EGammaPhivsElectronPhi_EB_EE_,
0953                                                          h_L1EGammaEtavsElectronEta_,
0954                                                          h_L1EGammaETvsPhotonET_EB_,
0955                                                          h_L1EGammaETvsPhotonET_EE_,
0956                                                          h_L1EGammaETvsPhotonET_EB_EE_,
0957                                                          h_L1EGammaPhivsPhotonPhi_EB_,
0958                                                          h_L1EGammaPhivsPhotonPhi_EE_,
0959                                                          h_L1EGammaPhivsPhotonPhi_EB_EE_,
0960                                                          h_L1EGammaEtavsPhotonEta_};
0961 
0962   for (auto mon : monElementstoNormalize) {
0963     if (mon != nullptr) {
0964       auto h = mon->getTH2F();
0965       if (h != nullptr) {
0966         h->Scale(1, "width");
0967       }
0968     }
0969   }
0970 }
0971 
0972 //define this as a plug-in
0973 DEFINE_FWK_MODULE(L1TEGammaOffline);