Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-25 01:53:23

0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/Common/interface/TriggerNames.h"
0003 #include "FWCore/Utilities/interface/RegexMatch.h"
0004 #include "DataFormats/Common/interface/Handle.h"
0005 #include "DataFormats/Common/interface/TriggerResults.h"
0006 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
0007 #include "DataFormats/VertexReco/interface/Vertex.h"
0008 #include "DataFormats/MuonReco/interface/Muon.h"
0009 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0010 
0011 #include <TLorentzVector.h>
0012 
0013 #include <memory>
0014 
0015 #include "DQMOffline/Lumi/plugins/ZCounting.h"
0016 
0017 //
0018 // -------------------------------------- Constructor --------------------------------------------
0019 //
0020 ZCounting::ZCounting(const edm::ParameterSet& iConfig)
0021     : triggerResultsInputTag_(iConfig.getParameter<edm::InputTag>("TriggerResults")),
0022       fPVName_token(consumes<reco::VertexCollection>(
0023           iConfig.getUntrackedParameter<std::string>("edmPVName", "offlinePrimaryVertices"))),
0024       fMuonName_token(consumes<reco::MuonCollection>(iConfig.getUntrackedParameter<std::string>("edmName", "muons"))),
0025       fTrackName_token(
0026           consumes<reco::TrackCollection>(iConfig.getUntrackedParameter<std::string>("edmTrackName", "generalTracks"))),
0027 
0028       PtCutL1_(iConfig.getUntrackedParameter<double>("PtCutL1")),
0029       PtCutL2_(iConfig.getUntrackedParameter<double>("PtCutL2")),
0030       EtaCutL1_(iConfig.getUntrackedParameter<double>("EtaCutL1")),
0031       EtaCutL2_(iConfig.getUntrackedParameter<double>("EtaCutL2")),
0032 
0033       MassBin_(iConfig.getUntrackedParameter<int>("MassBin")),
0034       MassMin_(iConfig.getUntrackedParameter<double>("MassMin")),
0035       MassMax_(iConfig.getUntrackedParameter<double>("MassMax")),
0036 
0037       LumiBin_(iConfig.getUntrackedParameter<int>("LumiBin")),
0038       LumiMin_(iConfig.getUntrackedParameter<double>("LumiMin")),
0039       LumiMax_(iConfig.getUntrackedParameter<double>("LumiMax")),
0040 
0041       PVBin_(iConfig.getUntrackedParameter<int>("PVBin")),
0042       PVMin_(iConfig.getUntrackedParameter<double>("PVMin")),
0043       PVMax_(iConfig.getUntrackedParameter<double>("PVMax")),
0044 
0045       VtxNTracksFitCut_(iConfig.getUntrackedParameter<double>("VtxNTracksFitMin")),
0046       VtxNdofCut_(iConfig.getUntrackedParameter<double>("VtxNdofMin")),
0047       VtxAbsZCut_(iConfig.getUntrackedParameter<double>("VtxAbsZMax")),
0048       VtxRhoCut_(iConfig.getUntrackedParameter<double>("VtxRhoMax")),
0049 
0050       IDTypestr_(iConfig.getUntrackedParameter<std::string>("IDType")),
0051       IsoTypestr_(iConfig.getUntrackedParameter<std::string>("IsoType")),
0052       IsoCut_(iConfig.getUntrackedParameter<double>("IsoCut")) {
0053   edm::LogInfo("ZCounting") << "Constructor  ZCounting::ZCounting " << std::endl;
0054 
0055   // Trigger settings
0056   triggers = new TriggerTools();
0057   triggers->setTriggerResultsToken(consumes<edm::TriggerResults>(triggerResultsInputTag_));
0058   triggers->setTriggerEventToken(consumes<trigger::TriggerEvent>(iConfig.getParameter<edm::InputTag>("TriggerEvent")));
0059   triggers->setDRMAX(DRMAX);
0060 
0061   edm::LogVerbatim("ZCounting") << "ZCounting::ZCounting set trigger names";
0062   const std::vector<std::string> patterns_ = iConfig.getParameter<std::vector<std::string>>("MuonTriggerNames");
0063   for (const std::string& pattern_ : patterns_) {
0064     triggers->addTriggerRecord(pattern_);
0065   }
0066 
0067   if (IDTypestr_ == "Loose")
0068     IDType_ = LooseID;
0069   else if (IDTypestr_ == "Medium")
0070     IDType_ = MediumID;
0071   else if (IDTypestr_ == "Tight")
0072     IDType_ = TightID;
0073   else if (IDTypestr_ == "CustomTight")
0074     IDType_ = CustomTightID;
0075   else
0076     IDType_ = NoneID;
0077 
0078   if (IsoTypestr_ == "Tracker-based")
0079     IsoType_ = TrackerIso;
0080   else if (IsoTypestr_ == "PF-based")
0081     IsoType_ = PFIso;
0082   else
0083     IsoType_ = NoneIso;
0084 }
0085 
0086 //
0087 //  -------------------------------------- Destructor --------------------------------------------
0088 //
0089 ZCounting::~ZCounting() { edm::LogInfo("ZCounting") << "Destructor ZCounting::~ZCounting " << std::endl; }
0090 
0091 //
0092 // -------------------------------------- beginRun --------------------------------------------
0093 //
0094 void ZCounting::dqmBeginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) {
0095   edm::LogInfo("ZCounting") << "ZCounting::beginRun" << std::endl;
0096 
0097   // initialize triggers
0098 
0099   edm::LogVerbatim("ZCounting") << "ZCounting::dqmBeginRun now at " << iRun.id();
0100   bool hltChanged_ = true;
0101   if (hltConfigProvider_.init(iRun, iSetup, triggerResultsInputTag_.process(), hltChanged_)) {
0102     edm::LogVerbatim("ZCounting") << "ZCounting::dqmBeginRun [TriggerObjMatchValueMapsProducer::beginRun] "
0103                                      "HLTConfigProvider initialized [processName() = \""
0104                                   << hltConfigProvider_.processName() << "\", tableName() = \""
0105                                   << hltConfigProvider_.tableName() << "\", size() = " << hltConfigProvider_.size()
0106                                   << "]";
0107   } else {
0108     edm::LogError("ZCounting") << "ZCounting::dqmBeginRun Initialization of HLTConfigProvider failed for Run="
0109                                << iRun.id() << " (process=\"" << triggerResultsInputTag_.process()
0110                                << "\") -> plugin will not produce outputs for this Run";
0111     return;
0112   }
0113 
0114   triggers->initHLTObjects(hltConfigProvider_);
0115 }
0116 
0117 //
0118 // -------------------------------------- bookHistos --------------------------------------------
0119 //
0120 void ZCounting::bookHistograms(DQMStore::IBooker& ibooker_, edm::Run const&, edm::EventSetup const&) {
0121   edm::LogInfo("ZCounting") << "ZCounting::bookHistograms" << std::endl;
0122   ibooker_.cd();
0123   ibooker_.setCurrentFolder("ZCounting/Histograms");
0124 
0125   // Muon histograms
0126   h_mass_2HLT_BB = ibooker_.book2D("h_mass_2HLT_BB",
0127                                    "Both muon pass HLT in barrel-barrel",
0128                                    LumiBin_,
0129                                    LumiMin_,
0130                                    LumiMax_,
0131                                    MassBin_,
0132                                    MassMin_,
0133                                    MassMax_);
0134   h_mass_2HLT_BE = ibooker_.book2D("h_mass_2HLT_BE",
0135                                    "Both muon pass HLT passing in barrel-endcap",
0136                                    LumiBin_,
0137                                    LumiMin_,
0138                                    LumiMax_,
0139                                    MassBin_,
0140                                    MassMin_,
0141                                    MassMax_);
0142   h_mass_2HLT_EE = ibooker_.book2D("h_mass_2HLT_EE",
0143                                    "Both muon pass HLT passing in endcap-endcap",
0144                                    LumiBin_,
0145                                    LumiMin_,
0146                                    LumiMax_,
0147                                    MassBin_,
0148                                    MassMin_,
0149                                    MassMax_);
0150   h_mass_1HLT_BB = ibooker_.book2D("h_mass_1HLT_BB",
0151                                    "One muon pass HLT in barrel-barrel",
0152                                    LumiBin_,
0153                                    LumiMin_,
0154                                    LumiMax_,
0155                                    MassBin_,
0156                                    MassMin_,
0157                                    MassMax_);
0158   h_mass_1HLT_BE = ibooker_.book2D("h_mass_1HLT_BE",
0159                                    "One muon pass HLT passing in barrel-endcap",
0160                                    LumiBin_,
0161                                    LumiMin_,
0162                                    LumiMax_,
0163                                    MassBin_,
0164                                    MassMin_,
0165                                    MassMax_);
0166   h_mass_1HLT_EE = ibooker_.book2D("h_mass_1HLT_EE",
0167                                    "One muon pass HLT passing in endcap-endcap",
0168                                    LumiBin_,
0169                                    LumiMin_,
0170                                    LumiMax_,
0171                                    MassBin_,
0172                                    MassMin_,
0173                                    MassMax_);
0174 
0175   h_mass_SIT_fail_BB = ibooker_.book2D("h_mass_SIT_fail_BB",
0176                                        "Muon SIT failing barrel-barrel",
0177                                        LumiBin_,
0178                                        LumiMin_,
0179                                        LumiMax_,
0180                                        MassBin_,
0181                                        MassMin_,
0182                                        MassMax_);
0183   h_mass_SIT_fail_BE = ibooker_.book2D("h_mass_SIT_fail_BE",
0184                                        "Muon SIT failing barrel-endcap",
0185                                        LumiBin_,
0186                                        LumiMin_,
0187                                        LumiMax_,
0188                                        MassBin_,
0189                                        MassMin_,
0190                                        MassMax_);
0191 
0192   h_mass_SIT_fail_EE = ibooker_.book2D("h_mass_SIT_fail_EE",
0193                                        "Muon SIT failing endcap-endcap",
0194                                        LumiBin_,
0195                                        LumiMin_,
0196                                        LumiMax_,
0197                                        MassBin_,
0198                                        MassMin_,
0199                                        MassMax_);
0200 
0201   h_mass_Glo_fail_BB = ibooker_.book2D("h_mass_Glo_fail_BB",
0202                                        "Muon Glo failing barrel-barrel",
0203                                        LumiBin_,
0204                                        LumiMin_,
0205                                        LumiMax_,
0206                                        MassBin_,
0207                                        MassMin_,
0208                                        MassMax_);
0209   h_mass_Glo_fail_BE = ibooker_.book2D("h_mass_Glo_fail_BE",
0210                                        "Muon Glo failing barrel-endcap",
0211                                        LumiBin_,
0212                                        LumiMin_,
0213                                        LumiMax_,
0214                                        MassBin_,
0215                                        MassMin_,
0216                                        MassMax_);
0217 
0218   h_mass_Glo_fail_EE = ibooker_.book2D("h_mass_Glo_fail_EE",
0219                                        "Muon Glo failing endcap-endcap",
0220                                        LumiBin_,
0221                                        LumiMin_,
0222                                        LumiMax_,
0223                                        MassBin_,
0224                                        MassMin_,
0225                                        MassMax_);
0226 
0227   h_npv = ibooker_.book2D(
0228       "h_npv", "Events with valid primary vertex", LumiBin_, LumiMin_, LumiMax_, PVBin_, PVMin_, PVMax_);
0229 
0230   // Axis titles
0231   h_mass_2HLT_BB->setAxisTitle("luminosity section", 1);
0232   h_mass_2HLT_BE->setAxisTitle("luminosity section", 1);
0233   h_mass_2HLT_EE->setAxisTitle("luminosity section", 1);
0234   h_mass_1HLT_BB->setAxisTitle("luminosity section", 1);
0235   h_mass_1HLT_BE->setAxisTitle("luminosity section", 1);
0236   h_mass_1HLT_EE->setAxisTitle("luminosity section", 1);
0237   h_mass_SIT_fail_BB->setAxisTitle("luminosity section", 1);
0238   h_mass_SIT_fail_BE->setAxisTitle("luminosity section", 1);
0239   h_mass_SIT_fail_EE->setAxisTitle("luminosity section", 1);
0240   h_mass_Glo_fail_BB->setAxisTitle("luminosity section", 1);
0241   h_mass_Glo_fail_BE->setAxisTitle("luminosity section", 1);
0242   h_mass_Glo_fail_EE->setAxisTitle("luminosity section", 1);
0243   h_mass_2HLT_BB->setAxisTitle("tag and probe mass", 2);
0244   h_mass_2HLT_BE->setAxisTitle("tag and probe mass", 2);
0245   h_mass_2HLT_EE->setAxisTitle("tag and probe mass", 2);
0246   h_mass_1HLT_BB->setAxisTitle("tag and probe mass", 2);
0247   h_mass_1HLT_BE->setAxisTitle("tag and probe mass", 2);
0248   h_mass_1HLT_EE->setAxisTitle("tag and probe mass", 2);
0249   h_mass_SIT_fail_BB->setAxisTitle("tag and probe mass", 2);
0250   h_mass_SIT_fail_BE->setAxisTitle("tag and probe mass", 2);
0251   h_mass_SIT_fail_EE->setAxisTitle("tag and probe mass", 2);
0252   h_mass_Glo_fail_BB->setAxisTitle("tag and probe mass", 2);
0253   h_mass_Glo_fail_BE->setAxisTitle("tag and probe mass", 2);
0254   h_mass_Glo_fail_EE->setAxisTitle("tag and probe mass", 2);
0255   h_npv->setAxisTitle("luminosity section", 1);
0256   h_npv->setAxisTitle("number of primary vertices", 2);
0257 }
0258 
0259 //
0260 // -------------------------------------- Analyze --------------------------------------------
0261 //
0262 //--------------------------------------------------------------------------------------------------
0263 void ZCounting::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {  // Fill event tree on the fly
0264   edm::LogInfo("ZCounting") << "ZCounting::analyze" << std::endl;
0265 
0266   //-------------------------------
0267   //--- Vertex
0268   //-------------------------------
0269   edm::Handle<reco::VertexCollection> hVertexProduct;
0270   iEvent.getByToken(fPVName_token, hVertexProduct);
0271   if (!hVertexProduct.isValid()) {
0272     edm::LogWarning("ZCounting") << "ZCounting::analyze - no valid primary vertex product found" << std::endl;
0273     return;
0274   }
0275 
0276   const reco::Vertex* pv = nullptr;
0277   int nvtx = 0;
0278 
0279   for (auto const& itVtx : *hVertexProduct) {
0280     if (itVtx.isFake())
0281       continue;
0282     if (itVtx.tracksSize() < VtxNTracksFitCut_)
0283       continue;
0284     if (itVtx.ndof() < VtxNdofCut_)
0285       continue;
0286     if (fabs(itVtx.z()) > VtxAbsZCut_)
0287       continue;
0288     if (itVtx.position().Rho() > VtxRhoCut_)
0289       continue;
0290 
0291     if (nvtx == 0) {
0292       pv = &itVtx;
0293     }
0294     nvtx++;
0295   }
0296 
0297   h_npv->Fill(iEvent.luminosityBlock(), nvtx);
0298 
0299   //-------------------------------
0300   //--- Trigger
0301   //-------------------------------
0302   triggers->readEvent(iEvent);
0303 
0304   // Trigger requirement
0305   if (!triggers->pass())
0306     return;
0307 
0308   //-------------------------------
0309   //--- Muons and Tracks
0310   //-------------------------------
0311   edm::Handle<reco::MuonCollection> hMuonProduct;
0312   iEvent.getByToken(fMuonName_token, hMuonProduct);
0313   if (!hMuonProduct.isValid())
0314     return;
0315 
0316   edm::Handle<reco::TrackCollection> hTrackProduct;
0317   iEvent.getByToken(fTrackName_token, hTrackProduct);
0318   if (!hTrackProduct.isValid())
0319     return;
0320 
0321   TLorentzVector vTag(0., 0., 0., 0.);
0322   TLorentzVector vProbe(0., 0., 0., 0.);
0323   TLorentzVector vTrack(0., 0., 0., 0.);
0324 
0325   // Tag loop
0326   for (auto const& itMu1 : *hMuonProduct) {
0327     const float pt1 = itMu1.muonBestTrack()->pt();
0328     const float eta1 = itMu1.muonBestTrack()->eta();
0329     const float phi1 = itMu1.muonBestTrack()->phi();
0330     const float q1 = itMu1.muonBestTrack()->charge();
0331 
0332     // Tag selection: kinematic cuts, lepton selection and trigger matching
0333     if (pt1 < PtCutL1_)
0334       continue;
0335     if (fabs(eta1) > EtaCutL1_)
0336       continue;
0337     if (!(passMuonID(itMu1, pv) && passMuonIso(itMu1)))
0338       continue;
0339     if (!triggers->passObj(eta1, phi1))
0340       continue;
0341 
0342     vTag.SetPtEtaPhiM(pt1, eta1, phi1, MUON_MASS);
0343 
0344     bool isTagCentral = false;
0345     if (fabs(eta1) < MUON_BOUND)
0346       isTagCentral = true;
0347 
0348     // Probe loop over muons
0349     for (auto const& itMu2 : *hMuonProduct) {
0350       if (&itMu2 == &itMu1)
0351         continue;
0352 
0353       const float pt2 = itMu2.muonBestTrack()->pt();
0354       const float eta2 = itMu2.muonBestTrack()->eta();
0355       const float phi2 = itMu2.muonBestTrack()->phi();
0356       const float q2 = itMu2.muonBestTrack()->charge();
0357 
0358       // Probe selection: kinematic cuts and opposite charge requirement
0359       if (pt2 < PtCutL2_)
0360         continue;
0361       if (fabs(eta2) > EtaCutL2_)
0362         continue;
0363       if (q1 == q2)
0364         continue;
0365 
0366       vProbe.SetPtEtaPhiM(pt2, eta2, phi2, MUON_MASS);
0367 
0368       // Mass window
0369       TLorentzVector vDilep = vTag + vProbe;
0370       float dilepMass = vDilep.M();
0371       if ((dilepMass < MassMin_) || (dilepMass > MassMax_))
0372         continue;
0373 
0374       bool isProbeCentral = false;
0375       if (fabs(eta2) < MUON_BOUND)
0376         isProbeCentral = true;
0377 
0378       // Determine event category for efficiency calculation
0379       if (passMuonID(itMu2, pv) && passMuonIso(itMu2)) {
0380         if (triggers->passObj(eta2, phi2)) {
0381           // category 2HLT: both muons passing trigger requirements
0382           if (&itMu1 > &itMu2)
0383             continue;  // make sure we don't double count MuMu2HLT category
0384 
0385           if (isTagCentral && isProbeCentral) {
0386             h_mass_2HLT_BB->Fill(iEvent.luminosityBlock(), dilepMass);
0387           } else if (!isTagCentral && !isProbeCentral) {
0388             h_mass_2HLT_EE->Fill(iEvent.luminosityBlock(), dilepMass);
0389           } else {
0390             h_mass_2HLT_BE->Fill(iEvent.luminosityBlock(), dilepMass);
0391           }
0392         } else {
0393           // category 1HLT: only one muon passes trigger
0394           if (isTagCentral && isProbeCentral) {
0395             h_mass_1HLT_BB->Fill(iEvent.luminosityBlock(), dilepMass);
0396           } else if (!isTagCentral && !isProbeCentral) {
0397             h_mass_1HLT_EE->Fill(iEvent.luminosityBlock(), dilepMass);
0398           } else {
0399             h_mass_1HLT_BE->Fill(iEvent.luminosityBlock(), dilepMass);
0400           }
0401         }
0402       } else if (itMu2.isGlobalMuon()) {
0403         // category Glo: probe is a Global muon but failing selection
0404         if (isTagCentral && isProbeCentral) {
0405           h_mass_SIT_fail_BB->Fill(iEvent.luminosityBlock(), dilepMass);
0406         } else if (!isTagCentral && !isProbeCentral) {
0407           h_mass_SIT_fail_EE->Fill(iEvent.luminosityBlock(), dilepMass);
0408         } else {
0409           h_mass_SIT_fail_BE->Fill(iEvent.luminosityBlock(), dilepMass);
0410         }
0411       } else if (itMu2.isStandAloneMuon()) {
0412         // category Sta: probe is a Standalone muon
0413         if (isTagCentral && isProbeCentral) {
0414           h_mass_Glo_fail_BB->Fill(iEvent.luminosityBlock(), dilepMass);
0415         } else if (!isTagCentral && !isProbeCentral) {
0416           h_mass_Glo_fail_EE->Fill(iEvent.luminosityBlock(), dilepMass);
0417         } else {
0418           h_mass_Glo_fail_BE->Fill(iEvent.luminosityBlock(), dilepMass);
0419         }
0420       } else if (itMu2.innerTrack()->hitPattern().trackerLayersWithMeasurement() >= 6 &&
0421                  itMu2.innerTrack()->hitPattern().numberOfValidPixelHits() >= 1) {
0422         // cateogry Trk: probe is a tracker track
0423         if (isTagCentral && isProbeCentral) {
0424           h_mass_Glo_fail_BB->Fill(iEvent.luminosityBlock(), dilepMass);
0425         } else if (!isTagCentral && !isProbeCentral) {
0426           h_mass_Glo_fail_EE->Fill(iEvent.luminosityBlock(), dilepMass);
0427         } else {
0428           h_mass_Glo_fail_BE->Fill(iEvent.luminosityBlock(), dilepMass);
0429         }
0430       }
0431     }  // End of probe loop over muons
0432 
0433     // Probe loop over tracks, only for standalone efficiency calculation
0434     for (auto const& itTrk : *hTrackProduct) {
0435       // Check track is not a muon
0436       bool isMuon = false;
0437       for (auto const& itMu : *hMuonProduct) {
0438         if (itMu.innerTrack().isNonnull() && itMu.innerTrack().get() == &itTrk) {
0439           isMuon = true;
0440           break;
0441         }
0442       }
0443       if (isMuon)
0444         continue;
0445 
0446       const float pt2 = itTrk.pt();
0447       const float eta2 = itTrk.eta();
0448       const float phi2 = itTrk.phi();
0449       const float q2 = itTrk.charge();
0450 
0451       // Probe selection:  kinematic cuts and opposite charge requirement
0452       if (pt2 < PtCutL2_)
0453         continue;
0454       if (fabs(eta2) > EtaCutL2_)
0455         continue;
0456       if (q1 == q2)
0457         continue;
0458 
0459       vTrack.SetPtEtaPhiM(pt2, eta2, phi2, MUON_MASS);
0460 
0461       TLorentzVector vDilep = vTag + vTrack;
0462       float dilepMass = vDilep.M();
0463       if ((dilepMass < MassMin_) || (dilepMass > MassMax_))
0464         continue;
0465 
0466       bool isTrackCentral = false;
0467       if (fabs(eta2) < MUON_BOUND)
0468         isTrackCentral = true;
0469 
0470       if (itTrk.hitPattern().trackerLayersWithMeasurement() >= 6 && itTrk.hitPattern().numberOfValidPixelHits() >= 1) {
0471         if (isTagCentral && isTrackCentral) {
0472           h_mass_Glo_fail_BB->Fill(iEvent.luminosityBlock(), dilepMass);
0473         } else if (!isTagCentral && !isTrackCentral) {
0474           h_mass_Glo_fail_EE->Fill(iEvent.luminosityBlock(), dilepMass);
0475         } else {
0476           h_mass_Glo_fail_BE->Fill(iEvent.luminosityBlock(), dilepMass);
0477         }
0478       }
0479     }  //End of probe loop over tracks
0480   }    //End of tag loop
0481 }
0482 
0483 //
0484 // -------------------------------------- functions --------------------------------------------
0485 //
0486 
0487 //--------------------------------------------------------------------------------------------------
0488 // Definition of the CustomTightID function
0489 bool ZCounting::isCustomTightMuon(const reco::Muon& muon) {
0490   if (!muon.isPFMuon() || !muon.isGlobalMuon())
0491     return false;
0492 
0493   bool muID = isGoodMuon(muon, muon::GlobalMuonPromptTight) && (muon.numberOfMatchedStations() > 1);
0494 
0495   bool muIdAndHits = muID && muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
0496                      muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
0497 
0498   return muIdAndHits;
0499 }
0500 
0501 //--------------------------------------------------------------------------------------------------
0502 bool ZCounting::passMuonID(const reco::Muon& muon, const reco::Vertex* vtx) {
0503   // Muon ID selection, using internal function "DataFormats/MuonReco/src/MuonSelectors.cc
0504   switch (IDType_) {
0505     case LooseID:
0506       return muon::isLooseMuon(muon);
0507     case MediumID:
0508       return muon::isMediumMuon(muon);
0509     case CustomTightID:
0510       return isCustomTightMuon(muon);
0511     case TightID:
0512       return vtx != nullptr && muon::isTightMuon(muon, *vtx);
0513     case NoneID:
0514       return true;
0515   }
0516   return false;
0517 }
0518 
0519 //--------------------------------------------------------------------------------------------------
0520 bool ZCounting::passMuonIso(const reco::Muon& muon) {
0521   //Muon isolation selection, up-to-date with MUO POG recommendation
0522   switch (IsoType_) {
0523     case TrackerIso:
0524       return muon.isolationR03().sumPt < IsoCut_;
0525     case PFIso:
0526       return muon.pfIsolationR04().sumChargedHadronPt +
0527                  std::max(0.,
0528                           muon.pfIsolationR04().sumNeutralHadronEt + muon.pfIsolationR04().sumPhotonEt -
0529                               0.5 * muon.pfIsolationR04().sumPUPt) <
0530              IsoCut_;
0531     case NoneIso:
0532       return true;
0533   }
0534 
0535   return false;
0536 }
0537 
0538 DEFINE_FWK_MODULE(ZCounting);