00001 00002 /* \class HiggsTo4LeptonsSkimEff 00003 * 00004 * Consult header file for description 00005 * 00006 * author: Dominique Fortin - UC Riverside 00007 * 00008 */ 00009 00010 00011 // system include files 00012 #include <HiggsAnalysis/Skimming/interface/HiggsToZZ4LeptonsSkimEff.h> 00013 00014 // User include files 00015 #include <FWCore/ParameterSet/interface/ParameterSet.h> 00016 00017 // Muons: 00018 #include <DataFormats/TrackReco/interface/Track.h> 00019 00020 // Electrons 00021 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h" 00022 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h" 00023 00024 // Candidate handling 00025 #include "DataFormats/Candidate/interface/Candidate.h" 00026 #include "DataFormats/Candidate/interface/CandMatchMap.h" 00027 #include "DataFormats/Common/interface/AssociationVector.h" 00028 #include "DataFormats/HepMCCandidate/interface/GenParticle.h" 00029 00030 00031 // C++ 00032 #include <iostream> 00033 #include <vector> 00034 00035 using namespace std; 00036 using namespace edm; 00037 using namespace reco; 00038 00039 00040 // Constructor 00041 HiggsToZZ4LeptonsSkimEff::HiggsToZZ4LeptonsSkimEff(const edm::ParameterSet& pset) { 00042 00043 // Local Debug flag 00044 debug = pset.getParameter<bool>("DebugHiggsToZZ4LeptonsSkim"); 00045 00046 // Reconstructed objects 00047 recTrackLabel = pset.getParameter<edm::InputTag>("RecoTrackLabel"); 00048 theGLBMuonLabel = pset.getParameter<edm::InputTag>("GlobalMuonCollectionLabel"); 00049 thePixelGsfELabel = pset.getParameter<edm::InputTag>("ElectronCollectionLabel"); 00050 00051 // Minimum Pt for leptons for skimming 00052 // Minimum Pt for leptons for skimming 00053 stiffMinPt = pset.getParameter<double>("stiffMinimumPt"); 00054 softMinPt = pset.getParameter<double>("softMinimumPt"); 00055 nStiffLeptonMin = pset.getParameter<int>("nStiffLeptonMinimum"); 00056 nLeptonMin = pset.getParameter<int>("nLeptonMinimum"); 00057 00058 nEvents = 0; 00059 nSelFourE = nSelFourM = nSelTwoETwoM = nSelFourL = nSelTau = 0; 00060 nFourE = nFourM = nTwoETwoM = nFourL = nTau = 0; 00061 00062 } 00063 00064 00065 // Destructor 00066 HiggsToZZ4LeptonsSkimEff::~HiggsToZZ4LeptonsSkimEff() { 00067 00068 std::cout << "Number of events read " << nEvents << std::endl; 00069 std::cout << "*** Efficiency for the various subsamples *** " << endl; 00070 00071 std::cout << "Four leptons: " 00072 << " pres " << nFourL 00073 << " kept " << nSelFourL 00074 << " eff " << ((double)nSelFourL)/((double) nFourL + 0.0001) << std::endl; 00075 std::cout << "Four muons: " 00076 << " pres " << nFourM 00077 << " kept " << nSelFourM 00078 << " eff " << ((double)nSelFourM)/((double) nFourM + 0.0001) << std::endl; 00079 std::cout << "Four elecs: " 00080 << " pres " << nFourE 00081 << " kept " << nSelFourE 00082 << " eff " << ((double)nSelFourE)/((double) nFourE + 0.0001) << std::endl; 00083 std::cout << "2 elec 2 mu: " 00084 << " pres " << nTwoETwoM 00085 << " kept " << nSelTwoETwoM 00086 << " eff " << ((double)nSelTwoETwoM)/((double) nTwoETwoM + 0.0001) << std::endl; 00087 std::cout << "with taus: " 00088 << " pres " << nTau 00089 << " kept " << nSelTau 00090 << " eff " << ((double)nSelTau)/((double) nTau + 0.0001) << std::endl; 00091 00092 } 00093 00094 00095 00096 // Filter event 00097 void HiggsToZZ4LeptonsSkimEff::analyze(const edm::Event& event, const edm::EventSetup& setup ) { 00098 00099 nEvents++; 00100 00101 using reco::TrackCollection; 00102 00103 bool keepEvent = false; 00104 00105 // First, pre-selection: 00106 int nMuon = 0; 00107 int nElec = 0; 00108 int nTau = 0; 00109 00110 bool isFourE = false; 00111 bool isFourM = false; 00112 bool isTwoETwoM = false; 00113 bool isFourL = false; 00114 bool isTau = false; 00115 00116 // get gen particle candidates 00117 edm::Handle<CandidateCollection> genCandidates; 00118 event.getByLabel("genParticleCandidates", genCandidates); 00119 00120 for ( CandidateCollection::const_iterator mcIter=genCandidates->begin(); mcIter!=genCandidates->end(); ++mcIter ) { 00121 00122 // Muons: 00123 if ( mcIter->pdgId() == 13 || mcIter->pdgId() == -13) { 00124 // Mother is a Z 00125 if ( mcIter->mother()->pdgId() == 23 ) { 00126 // In fiducial volume: 00127 if ( mcIter->eta() > -2.4 && mcIter->eta() < 2.4 ) nMuon++; 00128 } 00129 } 00130 // Electrons: 00131 if ( mcIter->pdgId() == 11 || mcIter->pdgId() == -11) { 00132 // Mother is a Z 00133 if ( mcIter->mother()->pdgId() == 23 ) { 00134 // In fiducial volume: 00135 if ( mcIter->eta() > -2.5 && mcIter->eta() < 2.5 ) nElec++; 00136 } 00137 } 00138 // Taus: 00139 if ( mcIter->pdgId() == 15 || mcIter->pdgId() == -15) { 00140 // Mother is a Z 00141 if ( mcIter->mother()->pdgId() == 23 ) { 00142 // In fiducial volume: 00143 if ( mcIter->eta() > -2.5 && mcIter->eta() < 2.5 ) nTau++; 00144 } 00145 } 00146 00147 } 00148 00149 if (nElec > 3) { 00150 isFourE = true; 00151 nFourE++; 00152 } 00153 if (nMuon > 3) { 00154 isFourM = true; 00155 nFourM++; 00156 } 00157 if (nMuon > 1 && nElec > 1) { 00158 isTwoETwoM = true; 00159 nTwoETwoM++; 00160 } 00161 if ( isFourE || isFourM || isTwoETwoM ) { 00162 isFourL = true; 00163 nFourL++; 00164 } 00165 if (nTau > 1) { 00166 isTau = true; 00167 nTau++; 00168 } 00169 00170 if ( isFourL ) { 00171 keepEvent = true; 00172 } else { 00173 return; 00174 } 00175 00176 00177 int nStiffLeptons = 0; 00178 int nLeptons = 0; 00179 00180 // First look at muons: 00181 00182 // Get the muon track collection from the event 00183 edm::Handle<reco::TrackCollection> muTracks; 00184 event.getByLabel(theGLBMuonLabel.label(), muTracks); 00185 00186 if ( muTracks.isValid() ) { 00187 reco::TrackCollection::const_iterator muons; 00188 00189 // Loop over muon collections and count how many muons there are, 00190 // and how many are above threshold 00191 for ( muons = muTracks->begin(); muons != muTracks->end(); ++muons ) { 00192 float pt_mu = muons->pt(); 00193 if ( pt_mu > stiffMinPt ) nStiffLeptons++; 00194 if ( pt_mu > softMinPt ) nLeptons++; 00195 } 00196 } 00197 00198 00199 // Now look at electrons: 00200 00201 // Get the electron track collection from the event 00202 edm::Handle<reco::PixelMatchGsfElectronCollection> pTracks; 00203 event.getByLabel(thePixelGsfELabel.label(),pTracks); 00204 00205 if ( pTracks.isValid() ) { 00206 00207 const reco::PixelMatchGsfElectronCollection* eTracks = pTracks.product(); 00208 00209 reco::PixelMatchGsfElectronCollection::const_iterator electrons; 00210 00211 // Loop over electron collections and count how many muons there are, 00212 // and how many are above threshold 00213 for ( electrons = eTracks->begin(); electrons != eTracks->end(); ++electrons ) { 00214 float pt_e = electrons->pt(); 00215 if ( pt_e > stiffMinPt ) nStiffLeptons++; 00216 if ( pt_e > softMinPt ) nLeptons++; 00217 } 00218 } 00219 00220 00221 // Make decision: 00222 if ( nStiffLeptons >= nStiffLeptonMin && nLeptons >= nLeptonMin) { 00223 keepEvent = true; 00224 } else { 00225 keepEvent = false; 00226 } 00227 00228 if ( keepEvent ) { 00229 if (isFourE) nSelFourE++; 00230 if (isFourM) nSelFourM++; 00231 if (isTwoETwoM) nSelTwoETwoM++; 00232 if (isFourL) nSelFourL++; 00233 if (isTau) nSelTau++; 00234 } 00235 00236 }