ATLAS_2012_I1203852.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/FastJets.hh" 00004 #include "Rivet/Projections/FinalState.hh" 00005 #include "Rivet/Projections/IdentifiedFinalState.hh" 00006 #include "Rivet/Projections/WFinder.hh" 00007 #include "Rivet/Projections/LeadingParticlesFinalState.hh" 00008 #include "Rivet/Projections/UnstableFinalState.hh" 00009 #include "Rivet/Projections/VetoedFinalState.hh" 00010 #include "Rivet/Projections/DressedLeptons.hh" 00011 #include "Rivet/Projections/MergedFinalState.hh" 00012 #include "Rivet/Projections/MissingMomentum.hh" 00013 #include "Rivet/Projections/InvMassFinalState.hh" 00014 00015 #define ZMASS 91.1876 // GeV 00016 00017 namespace Rivet { 00018 00019 00020 /// Generic Z candidate 00021 struct Zstate : public ParticlePair { 00022 Zstate() { } 00023 Zstate(ParticlePair _particlepair) : ParticlePair(_particlepair) { } 00024 FourMomentum mom() const { return first.momentum() + second.momentum(); } 00025 operator FourMomentum() const { return mom(); } 00026 static bool cmppT(const Zstate& lx, const Zstate& rx) { return lx.mom().pT() < rx.mom().pT(); } 00027 }; 00028 00029 00030 /// 4l to ZZ assignment -- algorithm 00031 void identifyZstates(Zstate& Z1, Zstate& Z2, const Particles& leptons_sel4l) { 00032 00033 ///////////////////////////////////////////////////////////////////////////// 00034 /// ZZ->4l pairing 00035 /// - Exactly two same flavour opposite charged leptons 00036 /// - Ambiguities in pairing are resolved by choosing the combination 00037 /// that results in the smaller value of the sum |mll - mZ| for the two pairs 00038 ///////////////////////////////////////////////////////////////////////////// 00039 00040 Particles part_pos_el, part_neg_el, part_pos_mu, part_neg_mu; 00041 foreach (const Particle& l , leptons_sel4l) { 00042 if (l.abspid() == PID::ELECTRON) { 00043 if (l.pid() < 0) part_neg_el.push_back(l); 00044 if (l.pid() > 0) part_pos_el.push_back(l); 00045 } 00046 else if (l.abspid() == PID::MUON) { 00047 if (l.pid() < 0) part_neg_mu.push_back(l); 00048 if (l.pid() > 0) part_pos_mu.push_back(l); 00049 } 00050 } 00051 00052 // ee/mm channel 00053 if ( part_neg_el.size() == 2 || part_neg_mu.size() == 2) { 00054 00055 Zstate Zcand_1, Zcand_2, Zcand_3, Zcand_4; 00056 if (part_neg_el.size() == 2) { // ee 00057 Zcand_1 = Zstate( ParticlePair( part_neg_el[0], part_pos_el[0] ) ); 00058 Zcand_2 = Zstate( ParticlePair( part_neg_el[0], part_pos_el[1] ) ); 00059 Zcand_3 = Zstate( ParticlePair( part_neg_el[1], part_pos_el[0] ) ); 00060 Zcand_4 = Zstate( ParticlePair( part_neg_el[1], part_pos_el[1] ) ); 00061 } else { // mumu 00062 Zcand_1 = Zstate( ParticlePair( part_neg_mu[0], part_pos_mu[0] ) ); 00063 Zcand_2 = Zstate( ParticlePair( part_neg_mu[0], part_pos_mu[1] ) ); 00064 Zcand_3 = Zstate( ParticlePair( part_neg_mu[1], part_pos_mu[0] ) ); 00065 Zcand_4 = Zstate( ParticlePair( part_neg_mu[1], part_pos_mu[1] ) ); 00066 } 00067 00068 // We can have the following pairs: (Z1 + Z4) || (Z2 + Z3) 00069 double minValue_1, minValue_2; 00070 minValue_1 = fabs( Zcand_1.mom().mass() - ZMASS ) + fabs( Zcand_4.mom().mass() - ZMASS); 00071 minValue_2 = fabs( Zcand_2.mom().mass() - ZMASS ) + fabs( Zcand_3.mom().mass() - ZMASS); 00072 if (minValue_1 < minValue_2 ) { 00073 Z1 = Zcand_1; 00074 Z2 = Zcand_4; 00075 } else { 00076 Z1 = Zcand_2; 00077 Z2 = Zcand_3; 00078 } 00079 00080 // emu channel 00081 } else if (part_neg_mu.size() == 1 && part_neg_el.size() == 1) { 00082 Z1 = Zstate ( ParticlePair (part_neg_mu[0], part_pos_mu[0] ) ); 00083 Z2 = Zstate ( ParticlePair (part_neg_el[0], part_pos_el[0] ) ); 00084 } 00085 00086 } 00087 00088 00089 /// @name ZZ analysis 00090 class ATLAS_2012_I1203852 : public Analysis { 00091 public: 00092 00093 /// Default constructor 00094 ATLAS_2012_I1203852() 00095 : Analysis("ATLAS_2012_I1203852") 00096 { } 00097 00098 void init() { 00099 FinalState fs(-5.0, 5.0, 0.0*GeV); 00100 00101 // Final states to form Z bosons 00102 vids.push_back(make_pair(PID::ELECTRON, PID::POSITRON)); 00103 vids.push_back(make_pair(PID::MUON, PID::ANTIMUON)); 00104 00105 vnuids.push_back(make_pair(PID::NU_E, PID::NU_EBAR) ); 00106 vnuids.push_back(make_pair(PID::NU_MU, PID::NU_MUBAR) ); 00107 vnuids.push_back(make_pair(PID::NU_TAU, PID::NU_TAUBAR) ); 00108 00109 IdentifiedFinalState Photon(fs); 00110 Photon.acceptIdPair(PID::PHOTON); 00111 00112 IdentifiedFinalState bare_EL(fs); 00113 bare_EL.acceptIdPair(PID::ELECTRON); 00114 00115 IdentifiedFinalState bare_MU(fs); 00116 bare_MU.acceptIdPair(PID::MUON); 00117 00118 00119 // Selection 1: ZZ-> llll selection 00120 Cut etaranges_lep = Cuts::abseta < 3.16 && Cuts::pT > 7*GeV; 00121 00122 DressedLeptons electron_sel4l(Photon, bare_EL, 0.1, etaranges_lep); 00123 addProjection(electron_sel4l, "ELECTRON_sel4l"); 00124 DressedLeptons muon_sel4l(Photon, bare_MU, 0.1, etaranges_lep); 00125 addProjection(muon_sel4l, "MUON_sel4l"); 00126 00127 00128 // Selection 2: ZZ-> llnunu selection 00129 Cut etaranges_lep2 = Cuts::abseta < 2.5 && Cuts::pT > 10*GeV; 00130 00131 DressedLeptons electron_sel2l2nu(Photon, bare_EL, 0.1, etaranges_lep2); 00132 addProjection(electron_sel2l2nu, "ELECTRON_sel2l2nu"); 00133 DressedLeptons muon_sel2l2nu(Photon, bare_MU, 0.1, etaranges_lep2); 00134 addProjection(muon_sel2l2nu, "MUON_sel2l2nu"); 00135 00136 00137 /// Get all neutrinos. These will not be used to form jets. 00138 /// We'll use the highest 2 pT neutrinos to calculate the MET 00139 IdentifiedFinalState neutrino_fs(Cuts::abseta < 4.5); 00140 neutrino_fs.acceptNeutrinos(); 00141 addProjection(neutrino_fs, "NEUTRINO_FS"); 00142 00143 VetoedFinalState jetinput; 00144 jetinput.addVetoOnThisFinalState(bare_MU); 00145 jetinput.addVetoOnThisFinalState(neutrino_fs); 00146 00147 FastJets jetpro(fs, FastJets::ANTIKT, 0.4); 00148 addProjection(jetpro, "jet"); 00149 00150 // Both ZZ on-shell histos 00151 _h_ZZ_xsect = bookHisto1D(1, 1, 1); 00152 _h_ZZ_ZpT = bookHisto1D(3, 1, 1); 00153 _h_ZZ_phill = bookHisto1D(5, 1, 1); 00154 _h_ZZ_mZZ = bookHisto1D(7, 1, 1); 00155 00156 // One Z off-shell (ZZstar) histos 00157 _h_ZZs_xsect = bookHisto1D(1, 1, 2); 00158 00159 // ZZ -> llnunu histos 00160 _h_ZZnunu_xsect = bookHisto1D(1, 1, 3); 00161 _h_ZZnunu_ZpT = bookHisto1D(4, 1, 1); 00162 _h_ZZnunu_phill = bookHisto1D(6, 1, 1); 00163 _h_ZZnunu_mZZ = bookHisto1D(8, 1, 1); 00164 } 00165 00166 00167 /// Do the analysis 00168 void analyze(const Event& e) { 00169 const double weight = e.weight(); 00170 00171 //////////////////////////////////////////////////////////////////// 00172 // preselection of leptons for ZZ-> llll final state 00173 //////////////////////////////////////////////////////////////////// 00174 00175 Particles leptons_sel4l; 00176 00177 const vector<DressedLepton>& mu_sel4l = applyProjection<DressedLeptons>(e, "MUON_sel4l").dressedLeptons(); 00178 const vector<DressedLepton>& el_sel4l = applyProjection<DressedLeptons>(e, "ELECTRON_sel4l").dressedLeptons(); 00179 00180 vector<DressedLepton> leptonsFS_sel4l; 00181 leptonsFS_sel4l.insert( leptonsFS_sel4l.end(), mu_sel4l.begin(), mu_sel4l.end() ); 00182 leptonsFS_sel4l.insert( leptonsFS_sel4l.end(), el_sel4l.begin(), el_sel4l.end() ); 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // OVERLAP removal dR(l,l)>0.2 00186 //////////////////////////////////////////////////////////////////// 00187 foreach ( const DressedLepton& l1, leptonsFS_sel4l) { 00188 bool isolated = true; 00189 foreach (DressedLepton& l2, leptonsFS_sel4l) { 00190 const double dR = deltaR(l1, l2); 00191 if (dR < 0.2 && l1 != l2) { isolated = false; break; } 00192 } 00193 if (isolated) leptons_sel4l.push_back(l1); 00194 } 00195 00196 ////////////////////////////////////////////////////////////////// 00197 // Exactly two opposite charged leptons 00198 ////////////////////////////////////////////////////////////////// 00199 00200 // calculate total 'flavour' charge 00201 double totalcharge = 0; 00202 foreach (Particle& l, leptons_sel4l) totalcharge += l.pid(); 00203 00204 // Analyze 4 lepton events 00205 if (leptons_sel4l.size() == 4 && totalcharge == 0 ) { 00206 Zstate Z1, Z2; 00207 00208 // Identifies Z states from 4 lepton pairs 00209 identifyZstates(Z1, Z2,leptons_sel4l); 00210 00211 //////////////////////////////////////////////////////////////////////////// 00212 // Z MASS WINDOW 00213 // -ZZ: for both Z: 66<mZ<116 GeV 00214 // -ZZ*: one Z on-shell: 66<mZ<116 GeV, one Z off-shell: mZ>20 GeV 00215 /////////////////////////////////////////////////////////////////////////// 00216 00217 Zstate leadPtZ = std::max(Z1, Z2, Zstate::cmppT); 00218 00219 double mZ1 = Z1.mom().mass(); 00220 double mZ2 = Z2.mom().mass(); 00221 double ZpT = leadPtZ.mom().pT(); 00222 double phill = fabs(deltaPhi(leadPtZ.first, leadPtZ.second)); 00223 if (phill > M_PI) phill = 2*M_PI-phill; 00224 double mZZ = (Z1.mom() + Z2.mom()).mass(); 00225 00226 if (mZ1 > 20*GeV && mZ2 > 20*GeV) { 00227 // ZZ* selection 00228 if (inRange(mZ1, 66*GeV, 116*GeV) || inRange(mZ2, 66*GeV, 116*GeV)) { 00229 _h_ZZs_xsect -> fill(sqrtS()*GeV, weight); 00230 } 00231 00232 // ZZ selection 00233 if (inRange(mZ1, 66*GeV, 116*GeV) && inRange(mZ2, 66*GeV, 116*GeV)) { 00234 _h_ZZ_xsect -> fill(sqrtS()*GeV, weight); 00235 _h_ZZ_ZpT -> fill(ZpT , weight); 00236 _h_ZZ_phill -> fill(phill , weight); 00237 _h_ZZ_mZZ -> fill(mZZ , weight); 00238 } 00239 } 00240 } 00241 00242 //////////////////////////////////////////////////////////////////// 00243 /// preselection of leptons for ZZ-> llnunu final state 00244 //////////////////////////////////////////////////////////////////// 00245 00246 Particles leptons_sel2l2nu; // output 00247 const vector<DressedLepton>& mu_sel2l2nu = applyProjection<DressedLeptons>(e, "MUON_sel2l2nu").dressedLeptons(); 00248 const vector<DressedLepton>& el_sel2l2nu = applyProjection<DressedLeptons>(e, "ELECTRON_sel2l2nu").dressedLeptons(); 00249 00250 vector<DressedLepton> leptonsFS_sel2l2nu; 00251 leptonsFS_sel2l2nu.insert( leptonsFS_sel2l2nu.end(), mu_sel2l2nu.begin(), mu_sel2l2nu.end() ); 00252 leptonsFS_sel2l2nu.insert( leptonsFS_sel2l2nu.end(), el_sel2l2nu.begin(), el_sel2l2nu.end() ); 00253 00254 // Lepton preselection for ZZ-> llnunu 00255 if ((mu_sel2l2nu.empty() || el_sel2l2nu.empty()) // cannot have opposite flavour 00256 && (leptonsFS_sel2l2nu.size() == 2) // exactly two leptons 00257 && (leptonsFS_sel2l2nu[0].charge() * leptonsFS_sel2l2nu[1].charge() < 1 ) // opposite charge 00258 && (deltaR(leptonsFS_sel2l2nu[0], leptonsFS_sel2l2nu[1]) > 0.3) // overlap removal 00259 && (leptonsFS_sel2l2nu[0].pT() > 20*GeV && leptonsFS_sel2l2nu[1].pT() > 20*GeV)) { // trigger requirement 00260 leptons_sel2l2nu.insert(leptons_sel2l2nu.end(), leptonsFS_sel2l2nu.begin(), leptonsFS_sel2l2nu.end()); 00261 } 00262 if (leptons_sel2l2nu.empty()) vetoEvent; // no further analysis, fine to veto 00263 00264 Particles leptons_sel2l2nu_jetveto; 00265 foreach (const DressedLepton& l, mu_sel2l2nu) leptons_sel2l2nu_jetveto.push_back(l.constituentLepton()); 00266 foreach (const DressedLepton& l, el_sel2l2nu) leptons_sel2l2nu_jetveto.push_back(l.constituentLepton()); 00267 double ptll = (leptons_sel2l2nu[0].momentum() + leptons_sel2l2nu[1].momentum()).pT(); 00268 00269 // Find Z1-> ll 00270 FinalState fs2(-3.2, 3.2); 00271 InvMassFinalState imfs(fs2, vids, 20*GeV, sqrtS()); 00272 imfs.calc(leptons_sel2l2nu); 00273 if (imfs.particlePairs().size() != 1) vetoEvent; 00274 const ParticlePair& Z1constituents = imfs.particlePairs()[0]; 00275 FourMomentum Z1 = Z1constituents.first.momentum() + Z1constituents.second.momentum(); 00276 00277 // Find Z2-> nunu 00278 const Particles& neutrinoFS = applyProjection<IdentifiedFinalState>(e, "NEUTRINO_FS").particlesByPt(); 00279 FinalState fs3(-4.5, 4.5); 00280 InvMassFinalState imfs_Znunu(fs3, vnuids, 20*GeV, sqrtS(), ZMASS); 00281 imfs_Znunu.calc(neutrinoFS); 00282 if (imfs_Znunu.particlePairs().size() == 0 ) vetoEvent; 00283 00284 // Z to neutrinos 00285 FourMomentum Z2 = imfs_Znunu.particlePairs()[0].first.momentum() + imfs_Znunu.particlePairs()[0].second.momentum(); 00286 double met_Znunu = Z2.pT(); 00287 00288 // mTZZ 00289 const double mT2_1st_term = add_quad(ZMASS, ptll) + add_quad(ZMASS, met_Znunu); 00290 const double mT2_2nd_term = Z1.px() + Z2.px(); 00291 const double mT2_3rd_term = Z1.py() + Z2.py(); 00292 const double mTZZ = sqrt(sqr(mT2_1st_term) - sqr(mT2_2nd_term) - sqr(mT2_3rd_term)); 00293 00294 if (!inRange(Z2.mass(), 66*GeV, 116*GeV)) vetoEvent; 00295 if (!inRange(Z1.mass(), 76*GeV, 106*GeV)) vetoEvent; 00296 00297 ///////////////////////////////////////////////////////////// 00298 // AXIAL MET < 75 GeV 00299 //////////////////////////////////////////////////////////// 00300 00301 double dPhiZ1Z2 = fabs(deltaPhi(Z1, Z2)); 00302 if (dPhiZ1Z2 > M_PI) dPhiZ1Z2 = 2*M_PI - dPhiZ1Z2; 00303 const double axialEtmiss = -Z2.pT()*cos(dPhiZ1Z2); 00304 if (axialEtmiss < 75*GeV) vetoEvent; 00305 00306 const double ZpT = Z1.pT(); 00307 double phill = fabs(deltaPhi(Z1constituents.first, Z1constituents.second)); 00308 if (phill > M_PI) phill = 2*M_PI - phill; 00309 00310 00311 //////////////////////////////////////////////////////////////////////////// 00312 // JETS 00313 // -"j": found by "jetpro" projection && pT() > 25 GeV && |eta| < 4.5 00314 // -"goodjets": "j" && dR(electron/muon,jet) > 0.3 00315 // 00316 // JETVETO: veto all events with at least one good jet 00317 /////////////////////////////////////////////////////////////////////////// 00318 vector<Jet> good_jets; 00319 foreach (const Jet& j, applyProjection<FastJets>(e, "jet").jetsByPt(25)) { 00320 if (j.abseta() > 4.5) continue; 00321 bool isLepton = 0; 00322 foreach (const Particle& l, leptons_sel2l2nu_jetveto) { 00323 const double dR = deltaR(l.momentum(), j.momentum()); 00324 if (dR < 0.3) { isLepton = true; break; } 00325 } 00326 if (!isLepton) good_jets.push_back(j); 00327 } 00328 size_t n_sel_jets = good_jets.size(); 00329 if (n_sel_jets != 0) vetoEvent; 00330 00331 00332 ///////////////////////////////////////////////////////////// 00333 // Fractional MET and lepton pair difference: "RatioMet"< 0.4 00334 //////////////////////////////////////////////////////////// 00335 double ratioMet = fabs(Z2.pT() - Z1.pT()) / Z1.pT(); 00336 if (ratioMet > 0.4 ) vetoEvent; 00337 00338 00339 // End of ZZllnunu selection: now fill histograms 00340 _h_ZZnunu_xsect->fill(sqrtS()/GeV, weight); 00341 _h_ZZnunu_ZpT ->fill(ZpT, weight); 00342 _h_ZZnunu_phill->fill(phill, weight); 00343 _h_ZZnunu_mZZ ->fill(mTZZ, weight); 00344 00345 } 00346 00347 00348 /// Finalize 00349 void finalize() { 00350 const double norm = crossSection()/sumOfWeights()/femtobarn; 00351 00352 scale(_h_ZZ_xsect, norm); 00353 normalize(_h_ZZ_ZpT); 00354 normalize(_h_ZZ_phill); 00355 normalize(_h_ZZ_mZZ); 00356 00357 scale(_h_ZZs_xsect, norm); 00358 scale(_h_ZZnunu_xsect, norm); 00359 normalize(_h_ZZnunu_ZpT); 00360 normalize(_h_ZZnunu_phill); 00361 normalize(_h_ZZnunu_mZZ); 00362 } 00363 00364 00365 private: 00366 00367 Histo1DPtr _h_ZZ_xsect, _h_ZZ_ZpT, _h_ZZ_phill, _h_ZZ_mZZ; 00368 Histo1DPtr _h_ZZs_xsect; 00369 Histo1DPtr _h_ZZnunu_xsect, _h_ZZnunu_ZpT, _h_ZZnunu_phill, _h_ZZnunu_mZZ; 00370 vector< pair<PdgId,PdgId> > vids, vnuids; 00371 00372 }; 00373 00374 00375 // The hook for the plugin system 00376 DECLARE_RIVET_PLUGIN(ATLAS_2012_I1203852); 00377 00378 } Generated on Thu Mar 10 2016 08:29:47 for The Rivet MC analysis system by ![]() |