ATLAS_2015_I1345452.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/FinalState.hh" 00004 #include "Rivet/Projections/VetoedFinalState.hh" 00005 #include "Rivet/Projections/IdentifiedFinalState.hh" 00006 #include "Rivet/Projections/PromptFinalState.hh" 00007 #include "Rivet/Projections/DressedLeptons.hh" 00008 #include "Rivet/Projections/FastJets.hh" 00009 00010 namespace Rivet { 00011 00012 /// @brief ATLAS 7 TeV pseudo-top analysis 00013 /// 00014 /// @author K .Finelli <kevin.finelli@cern.ch> 00015 /// @author A. Saavedra <a.saavedra@physics.usyd.edu.au> 00016 /// @author L. Lan <llan@physics.usyd.edu.au> 00017 class ATLAS_2015_I1345452 : public Analysis { 00018 public: 00019 00020 /// Constructor 00021 ATLAS_2015_I1345452() 00022 : Analysis("ATLAS_2015_I1345452") 00023 { 00024 setNeedsCrossSection(true); 00025 } 00026 00027 00028 void init() { 00029 // Eta ranges 00030 Cut eta_full = (Cuts::abseta < 5.0) & (Cuts::pT >= 1.0*MeV); 00031 Cut eta_lep = (Cuts::abseta < 2.5); 00032 00033 // All final state particles 00034 FinalState fs(eta_full); 00035 00036 // Get photons to dress leptons 00037 IdentifiedFinalState photons(fs); 00038 photons.acceptIdPair(PID::PHOTON); 00039 00040 // Projection to find the electrons 00041 IdentifiedFinalState el_id(fs); 00042 el_id.acceptIdPair(PID::ELECTRON); 00043 00044 PromptFinalState electrons(el_id); 00045 electrons.acceptTauDecays(true); 00046 addProjection(electrons, "electrons"); 00047 00048 DressedLeptons dressedelectrons(photons, electrons, 0.1, eta_lep & (Cuts::pT >= 25.0*GeV), true, true); 00049 addProjection(dressedelectrons, "dressedelectrons"); 00050 00051 DressedLeptons ewdressedelectrons(photons, electrons, 0.1, eta_full, true, true); 00052 addProjection(ewdressedelectrons, "ewdressedelectrons"); 00053 00054 DressedLeptons vetodressedelectrons(photons, electrons, 0.1, eta_lep & (Cuts::pT >= 15.0*GeV), true, true); 00055 addProjection(vetodressedelectrons, "vetodressedelectrons"); 00056 00057 // Projection to find the muons 00058 IdentifiedFinalState mu_id(fs); 00059 mu_id.acceptIdPair(PID::MUON); 00060 PromptFinalState muons(mu_id); 00061 muons.acceptTauDecays(true); 00062 addProjection(muons, "muons"); 00063 DressedLeptons dressedmuons(photons, muons, 0.1, eta_lep & (Cuts::pT >= 25.0*GeV), true, true); 00064 addProjection(dressedmuons, "dressedmuons"); 00065 DressedLeptons ewdressedmuons(photons, muons, 0.1, eta_full, true, true); 00066 addProjection(ewdressedmuons, "ewdressedmuons"); 00067 DressedLeptons vetodressedmuons(photons, muons, 0.1, eta_lep & (Cuts::pT >= 15.0*GeV), true, true); 00068 addProjection(vetodressedmuons, "vetodressedmuons"); 00069 00070 // Projection to find neutrinos and produce MET 00071 IdentifiedFinalState nu_id; 00072 nu_id.acceptNeutrinos(); 00073 PromptFinalState neutrinos(nu_id); 00074 neutrinos.acceptTauDecays(true); 00075 addProjection(neutrinos, "neutrinos"); 00076 00077 // Jet clustering. 00078 VetoedFinalState vfs; 00079 vfs.addVetoOnThisFinalState(ewdressedelectrons); 00080 vfs.addVetoOnThisFinalState(ewdressedmuons); 00081 vfs.addVetoOnThisFinalState(neutrinos); 00082 FastJets jets(vfs, FastJets::ANTIKT, 0.4); 00083 jets.useInvisibles(); 00084 addProjection(jets, "jets"); 00085 00086 //pseudotop leptons and hadrons 00087 _h["ptpseudotophadron_mu"] = bookHisto1D( 1, 1, 2); 00088 _h["ptpseudotophadron_el"] = bookHisto1D( 2, 1, 2); 00089 _h["absrappseudotophadron_mu"] = bookHisto1D( 3, 1, 2); 00090 _h["absrappseudotophadron_el"] = bookHisto1D( 4, 1, 2); 00091 _h["ptpseudotoplepton_mu"] = bookHisto1D( 5, 1, 2); 00092 _h["ptpseudotoplepton_el"] = bookHisto1D( 6, 1, 2); 00093 _h["absrappseudotoplepton_mu"] = bookHisto1D( 7, 1, 2); 00094 _h["absrappseudotoplepton_el"] = bookHisto1D( 8, 1, 2); 00095 _h["ptttbar_mu"] = bookHisto1D( 9, 1, 2); 00096 _h["ptttbar_el"] = bookHisto1D(10, 1, 2); 00097 _h["absrapttbar_mu"] = bookHisto1D(11, 1, 2); 00098 _h["absrapttbar_el"] = bookHisto1D(12, 1, 2); 00099 _h["ttbarmass_mu"] = bookHisto1D(13, 1, 2); 00100 _h["ttbarmass_el"] = bookHisto1D(14, 1, 2); 00101 _h["ptpseudotophadron"] = bookHisto1D(15, 1, 2); 00102 _h["absrappseudotophadron"] = bookHisto1D(16, 1, 2); 00103 _h["ptpseudotoplepton"] = bookHisto1D(17, 1, 2); 00104 _h["absrappseudotoplepton"] = bookHisto1D(18, 1, 2); 00105 _h["ptttbar"] = bookHisto1D(19, 1, 2); 00106 _h["absrapttbar"] = bookHisto1D(20, 1, 2); 00107 _h["ttbarmass"] = bookHisto1D(21, 1, 2); 00108 00109 } 00110 00111 void analyze(const Event& event) { 00112 00113 // Get the selected objects, using the projections. 00114 _dressedelectrons = applyProjection<DressedLeptons>( event, "dressedelectrons").dressedLeptons(); 00115 _vetodressedelectrons = applyProjection<DressedLeptons>( event, "vetodressedelectrons").dressedLeptons(); 00116 _dressedmuons = applyProjection<DressedLeptons>( event, "dressedmuons").dressedLeptons(); 00117 _vetodressedmuons = applyProjection<DressedLeptons>( event, "vetodressedmuons").dressedLeptons(); 00118 _neutrinos = applyProjection<PromptFinalState>(event, "neutrinos").particlesByPt(); 00119 const Jets& all_jets = applyProjection<FastJets>( event, "jets").jetsByPt(Cuts::pT > 25.0*GeV && Cuts::abseta < 2.5); 00120 00121 //get true l+jets events by removing events with more than 1 electron||muon neutrino 00122 unsigned int n_elmu_neutrinos = 0; 00123 foreach (const Particle p, _neutrinos) { 00124 if (p.abspid() == 12 || p.abspid() == 14) ++n_elmu_neutrinos; 00125 } 00126 if (n_elmu_neutrinos != 1) vetoEvent; 00127 00128 DressedLepton *lepton; 00129 if ( _dressedelectrons.size()) lepton = &_dressedelectrons[0]; 00130 else if (_dressedmuons.size()) lepton = &_dressedmuons[0]; 00131 else vetoEvent; 00132 00133 // Calculate the missing ET, using the prompt neutrinos only (really?) 00134 /// @todo Why not use MissingMomentum? 00135 FourMomentum met; 00136 foreach (const Particle& p, _neutrinos) met += p.momentum(); 00137 00138 //remove jets if they are within dR < 0.2 of lepton 00139 Jets jets; 00140 foreach(const Jet& jet, all_jets) { 00141 bool keep = true; 00142 foreach (const DressedLepton& el, _vetodressedelectrons) { 00143 keep &= deltaR(jet, el) >= 0.2; 00144 } 00145 if (keep) jets += jet; 00146 } 00147 00148 bool overlap = false; 00149 Jets bjets, lightjets; 00150 for (unsigned int i = 0; i < jets.size(); ++i) { 00151 const Jet& jet = jets[i]; 00152 foreach (const DressedLepton& el, _dressedelectrons) overlap |= deltaR(jet, el) < 0.4; 00153 foreach (const DressedLepton& mu, _dressedmuons) overlap |= deltaR(jet, mu) < 0.4; 00154 for (unsigned int j = i + 1; j < jets.size(); ++j) { 00155 overlap |= deltaR(jet, jets[j]) < 0.5; 00156 } 00157 //// Count the number of b-tags 00158 bool b_tagged = false; // This is closer to the 00159 Particles bTags = jet.bTags(); // analysis. Something 00160 foreach ( Particle b, bTags ) { // about ghost-associated 00161 b_tagged |= b.pT() > 5*GeV; // B-hadrons 00162 } // 00163 if ( b_tagged ) bjets += jet; 00164 else lightjets += jet; 00165 } 00166 00167 // remove events with object overlap 00168 if (overlap) vetoEvent; 00169 00170 if (bjets.size() < 2 || lightjets.size() < 2) vetoEvent; 00171 00172 FourMomentum pbjet1; //Momentum of bjet1 00173 FourMomentum pbjet2; //Momentum of bjet2 00174 if ( deltaR(bjets[0], *lepton) <= deltaR(bjets[1], *lepton) ) { 00175 pbjet1 = bjets[0].momentum(); 00176 pbjet2 = bjets[1].momentum(); 00177 } else { 00178 pbjet1 = bjets[1].momentum(); 00179 pbjet2 = bjets[0].momentum(); 00180 } 00181 00182 FourMomentum pjet1; // Momentum of jet1 00183 if (lightjets.size()) pjet1 = lightjets[0].momentum(); 00184 00185 FourMomentum pjet2; // Momentum of jet 2 00186 if (lightjets.size() > 1) pjet2 = lightjets[1].momentum(); 00187 00188 double pz = computeneutrinoz(lepton->momentum(), met); 00189 FourMomentum ppseudoneutrino( sqrt(sqr(met.px()) + sqr(met.py()) + sqr(pz)), met.px(), met.py(), pz); 00190 00191 //compute leptonic, hadronic, combined pseudo-top 00192 FourMomentum ppseudotoplepton = lepton->momentum() + ppseudoneutrino + pbjet1; 00193 FourMomentum ppseudotophadron = pbjet2 + pjet1 + pjet2; 00194 FourMomentum pttbar = ppseudotoplepton + ppseudotophadron; 00195 00196 // Evaluate basic event selection 00197 bool pass_eljets = (_dressedelectrons.size() == 1) && 00198 (_vetodressedelectrons.size() < 2) && 00199 (_vetodressedmuons.empty()) && 00200 (met.pT() > 30*GeV) && 00201 (_mT(_dressedelectrons[0].momentum(), met) > 35*GeV) && 00202 (jets.size() >= 4); 00203 bool pass_mujets = (_dressedmuons.size() == 1) && 00204 (_vetodressedmuons.size() < 2) && 00205 (_vetodressedelectrons.empty()) && 00206 (met.pT() > 30*GeV) && 00207 (_mT(_dressedmuons[0].momentum(), met) > 35*GeV) && 00208 (jets.size() >= 4); 00209 00210 // basic event selection requirements 00211 if (!pass_eljets && !pass_mujets) vetoEvent; 00212 00213 // Fill histograms 00214 const double weight = event.weight(); 00215 00216 //pseudotop hadrons and leptons fill histogram 00217 _h["ptpseudotoplepton"]->fill( ppseudotoplepton.pt(), weight); //pT of pseudo top lepton 00218 _h["absrappseudotoplepton"]->fill(ppseudotoplepton.absrap(), weight); //absolute rapidity of pseudo top lepton 00219 _h["ptpseudotophadron"]->fill( ppseudotophadron.pt(), weight); //pT of pseudo top hadron 00220 _h["absrappseudotophadron"]->fill(ppseudotophadron.absrap(), weight); //absolute rapidity of pseudo top hadron 00221 _h["absrapttbar"]->fill( pttbar.absrap(), weight); //absolute rapidity of ttbar 00222 _h["ttbarmass"]->fill( pttbar.mass(), weight); //mass of ttbar 00223 _h["ptttbar"]->fill( pttbar.pt(), weight); //fill pT of ttbar in combined channel 00224 00225 if (pass_eljets) { // electron channel fill histogram 00226 _h["ptpseudotoplepton_el"]->fill( ppseudotoplepton.pt(), weight); //pT of pseudo top lepton 00227 _h["absrappseudotoplepton_el"]->fill(ppseudotoplepton.absrap(), weight); //absolute rapidity of pseudo top lepton 00228 _h["ptpseudotophadron_el"]->fill( ppseudotophadron.pt(), weight); //pT of pseudo top hadron 00229 _h["absrappseudotophadron_el"]->fill(ppseudotophadron.absrap(), weight); //absolute rapidity of pseudo top hadron 00230 _h["absrapttbar_el"]->fill( pttbar.absrap(), weight); //absolute rapidity of ttbar 00231 _h["ttbarmass_el"]->fill( pttbar.mass(), weight); // fill electron channel ttbar mass 00232 _h["ptttbar_el"]->fill( pttbar.pt(), weight); //fill pT of ttbar in electron channel 00233 } 00234 else { // muon channel fill histogram 00235 _h["ptpseudotoplepton_mu"]->fill( ppseudotoplepton.pt(), weight); //pT of pseudo top lepton 00236 _h["absrappseudotoplepton_mu"]->fill(ppseudotoplepton.absrap(), weight); //absolute rapidity of pseudo top lepton 00237 _h["ptpseudotophadron_mu"]->fill( ppseudotophadron.pt(), weight); //pT of pseudo top hadron 00238 _h["absrappseudotophadron_mu"]->fill(ppseudotophadron.absrap(), weight); //absolute rapidity of pseudo top hadron 00239 _h["absrapttbar_mu"]->fill( pttbar.absrap(), weight); //absolute rapidity of ttbar 00240 _h["ttbarmass_mu"]->fill( pttbar.mass(), weight); //fill muon channel histograms 00241 _h["ptttbar_mu"]->fill( pttbar.pt(), weight); //fill pT of ttbar in electron channel 00242 } 00243 } 00244 00245 void finalize() { 00246 // Normalize to cross-section 00247 const double scalefactor(crossSection() / sumOfWeights()); 00248 for (map<string, Histo1DPtr>::iterator hit = _h.begin(); hit != _h.end(); ++hit) { 00249 double sf = scalefactor; 00250 if ( (hit->first).find("_") == std::string::npos ) sf *= 0.5; 00251 scale(hit->second, sf); 00252 } 00253 } 00254 00255 private: 00256 00257 00258 double computeneutrinoz(const FourMomentum& lepton, FourMomentum& met) const { 00259 //computing z component of neutrino momentum given lepton and met 00260 double pzneutrino; 00261 double m_W = 80.399; // in GeV, given in the paper 00262 double k = (( sqr( m_W ) - sqr( lepton.mass() ) ) / 2 ) + (lepton.px() * met.px() + lepton.py() * met.py()); 00263 double a = sqr ( lepton.E() )- sqr ( lepton.pz() ); 00264 double b = -2*k*lepton.pz(); 00265 double c = sqr( lepton.E() ) * sqr( met.pT() ) - sqr( k ); 00266 double discriminant = sqr(b) - 4 * a * c; 00267 double quad[2] = { (- b - sqrt(discriminant)) / (2 * a), (- b + sqrt(discriminant)) / (2 * a) }; //two possible quadratic solns 00268 if (discriminant < 0) pzneutrino = - b / (2 * a); //if the discriminant is negative 00269 else { //if the discriminant is greater than or equal to zero, take the soln with smallest absolute value 00270 double absquad[2]; 00271 for (int n=0; n<2; ++n) absquad[n] = fabs(quad[n]); 00272 if (absquad[0] < absquad[1]) pzneutrino = quad[0]; 00273 else pzneutrino = quad[1]; 00274 } 00275 if ( !std::isfinite(pzneutrino) ) std::cout << "Found non-finite value" << std::endl; 00276 return pzneutrino; 00277 } 00278 00279 double _mT(const FourMomentum &l, FourMomentum &nu) const { 00280 return sqrt( 2 * l.pT() * nu.pT() * (1 - cos(deltaPhi(l, nu))) ); 00281 } 00282 00283 /// @name Objects that are used by the event selection decisions 00284 vector<DressedLepton> _dressedelectrons, _vetodressedelectrons, _dressedmuons, _vetodressedmuons; 00285 Particles _neutrinos; 00286 map<string, Histo1DPtr> _h; 00287 }; 00288 00289 // The hook for the plugin system 00290 DECLARE_RIVET_PLUGIN(ATLAS_2015_I1345452); 00291 00292 } Generated on Wed Oct 7 2015 12:09:11 for The Rivet MC analysis system by ![]() |