rivet is hosted by Hepforge, IPPP Durham
MC_SUSY.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/ChargedFinalState.hh"
00005 #include "Rivet/Projections/FastJets.hh"
00006 #include "Rivet/Projections/IdentifiedFinalState.hh"
00007 #include "Rivet/Projections/MissingMomentum.hh"
00008 #include "Rivet/Projections/LeadingParticlesFinalState.hh"
00009 
00010 namespace Rivet {
00011 
00012   
00013 
00014 
00015   /// @brief MC validation analysis for SUSY events
00016   /// @author Andy Buckley
00017   class MC_SUSY : public Analysis {
00018   public:
00019 
00020     /// Constructor
00021     MC_SUSY()
00022       : Analysis("MC_SUSY")
00023     {    }
00024 
00025 
00026     /// @name Analysis methods
00027     //@{
00028 
00029     // Book histograms
00030     void init() {
00031       // Basic final state
00032       const FinalState fs(-4.0, 4.0, 10*GeV);
00033 
00034       // Tracks and jets
00035       addProjection(ChargedFinalState(fs), "Tracks");
00036       addProjection(FastJets(fs, FastJets::ANTIKT, 0.7), "Jets");
00037 
00038       IdentifiedFinalState photonfs(fs);
00039       photonfs.acceptId(PID::PHOTON);
00040       addProjection(photonfs, "AllPhotons");
00041 
00042       IdentifiedFinalState efs(fs);
00043       efs.acceptIdPair(PID::ELECTRON);
00044       addProjection(efs, "Electrons");
00045 
00046       IdentifiedFinalState mufs(fs);
00047       mufs.acceptIdPair(PID::MUON);
00048       addProjection(mufs, "Muons");
00049 
00050       MissingMomentum missing(fs);
00051       addProjection(missing, "MET");
00052 
00053       LeadingParticlesFinalState lpfs(fs);
00054       lpfs.addParticleIdPair(PID::ELECTRON);
00055       lpfs.addParticleIdPair(PID::MUON);
00056       addProjection(lpfs, "LeadingParticles");
00057 
00058       _hist_n_trk   = bookHisto1D("n-trk", 50, 0.5, 300.5);
00059       _hist_phi_trk = bookHisto1D("phi-trk", 50, -PI, PI);
00060       _hist_eta_trk = bookHisto1D("eta-trk", 50, -4, 4);
00061       _hist_pt_trk  = bookHisto1D("pt-trk", 100, 0.0, 1500);
00062 
00063       _hist_n_jet   = bookHisto1D("n-jet", 21, -0.5, 20.5);
00064       _hist_phi_jet = bookHisto1D("phi-jet", 50, -PI, PI);
00065       _hist_eta_jet = bookHisto1D("eta-jet", 50, -4, 4);
00066       _hist_pt_jet  = bookHisto1D("pt-jet", 100, 0.0, 1500);
00067 
00068       _hist_n_e   = bookHisto1D("n-e", 11, -0.5, 10.5);
00069       _hist_phi_e = bookHisto1D("phi-e", 50, -PI, PI);
00070       _hist_eta_e = bookHisto1D("eta-e", 50, -4, 4);
00071       _hist_pt_e  = bookHisto1D("pt-e", 100, 0.0, 500);
00072 
00073       _hist_n_mu   = bookHisto1D("n-mu", 11, -0.5, 10.5);
00074       _hist_phi_mu = bookHisto1D("phi-mu", 50, -PI, PI);
00075       _hist_eta_mu = bookHisto1D("eta-mu", 50, -4, 4);
00076       _hist_pt_mu  = bookHisto1D("pt-mu", 100, 0.0, 500);
00077 
00078       _hist_n_gamma   = bookHisto1D("n-gamma", 11, -0.5, 10.5);
00079       _hist_phi_gamma = bookHisto1D("phi-gamma", 50, -PI, PI);
00080       _hist_eta_gamma = bookHisto1D("eta-gamma", 50, -4, 4);
00081       _hist_pt_gamma  = bookHisto1D("pt-gamma", 100, 0.0, 500);
00082 
00083       _hist_n_gammaiso   = bookHisto1D("n-gamma-iso", 11, -0.5, 10.5);
00084       _hist_phi_gammaiso = bookHisto1D("phi-gamma-iso", 50, -PI, PI);
00085       _hist_eta_gammaiso = bookHisto1D("eta-gamma-iso", 50, -4, 4);
00086       _hist_pt_gammaiso  = bookHisto1D("pt-gamma-iso", 100, 0.0, 500);
00087 
00088       _hist_met = bookHisto1D("Etmiss", 100, 0.0, 1500);
00089 
00090       _hist_mll_ossf_ee   = bookHisto1D("mll-ossf-ee", 50, 0.0, 500);
00091       _hist_mll_ossf_mumu = bookHisto1D("mll-ossf-mumu", 50, 0.0, 500);
00092       _hist_mll_osof_emu  = bookHisto1D("mll-osof-emu", 50, 0.0, 500);
00093 
00094       _hist_mll_all_ossf_ee   = bookHisto1D("mll-all-ossf-ee", 50, 0.0, 500);
00095       _hist_mll_all_ossf_mumu = bookHisto1D("mll-all-ossf-mumu", 50, 0.0, 500);
00096       _hist_mll_all_osof_emu  = bookHisto1D("mll-all-osof-emu", 50, 0.0, 500);
00097 
00098       _hist_mll_2_ossf_ee   = bookHisto1D("mll-2-ossf-ee", 50, 0.0, 500);
00099       _hist_mll_2_ossf_mumu = bookHisto1D("mll-2-ossf-mumu", 50, 0.0, 500);
00100       _hist_mll_2_osof_emu  = bookHisto1D("mll-2-osof-emu", 50, 0.0, 500);
00101 
00102       /// @todo LSP eta, pT, phi, mass: no reliable cross-scenario LSP PID but
00103       /// maybe plot for all of chi^0_1, gravitino, sneutrino, gluino, ... or
00104       /// identify the LSP as any PID::isSUSY (?) particle with status = 1?
00105     }
00106 
00107 
00108     // Do the analysis
00109     void analyze(const Event& evt) {
00110       const FinalState& tracks = applyProjection<FinalState>(evt, "Tracks");
00111       if (tracks.particles().empty()) {
00112         MSG_DEBUG("Failed multiplicity cut");
00113         vetoEvent;
00114       }
00115 
00116       // Get event weight
00117       const double weight = evt.weight();
00118 
00119       // Fill track histos
00120       _hist_n_trk->fill(tracks.size(), weight);
00121       foreach (const Particle& t, tracks.particles()) {
00122         const FourMomentum& p = t.momentum();
00123         _hist_phi_trk->fill(mapAngleMPiToPi(p.phi()), weight);
00124         _hist_eta_trk->fill(p.eta(), weight);
00125         _hist_pt_trk->fill(p.pT()/GeV, weight);
00126       }
00127 
00128       // Get jets and fill jet histos
00129       const FastJets& jetpro = applyProjection<FastJets>(evt, "Jets");
00130       const Jets jets = jetpro.jetsByPt();
00131       MSG_DEBUG("Jet multiplicity = " << jets.size());
00132       _hist_n_jet->fill(jets.size(), weight);
00133       foreach (const Jet& j, jets) {
00134         const FourMomentum& pj = j.momentum();
00135         _hist_phi_jet->fill(mapAngleMPiToPi(pj.phi()), weight);
00136         _hist_eta_jet->fill(pj.eta(), weight);
00137         _hist_pt_jet->fill(pj.pT()/GeV, weight);
00138       }
00139 
00140       /// @todo Resum photons around electrons
00141 
00142       // Fill final state electron/positron histos
00143       const FinalState& efs = applyProjection<FinalState>(evt, "Electrons");
00144       _hist_n_e->fill(efs.size(), weight);
00145       vector<FourMomentum> epluses, eminuses;
00146       foreach (const Particle& e, efs.particles()) {
00147         const FourMomentum& p = e.momentum();
00148         _hist_phi_e->fill(mapAngleMPiToPi(p.phi()), weight);
00149         _hist_eta_e->fill(p.eta(), weight);
00150         _hist_pt_e->fill(p.pT()/GeV, weight);
00151         // Add sufficiently hard leptons to collections for m_ll histo
00152         if (p.pT()/GeV > 20) {
00153           if (PID::threeCharge(e.pid()) > 0) epluses += p; else eminuses += p;
00154         }
00155       }
00156 
00157       /// @todo Resum photons around muons
00158 
00159       // Fill final state muon/antimuon histos
00160       const FinalState& mufs = applyProjection<FinalState>(evt, "Muons");
00161       _hist_n_mu->fill(mufs.size(), weight);
00162       vector<FourMomentum> mupluses, muminuses;
00163       foreach (const Particle& mu, mufs.particles()) {
00164         const FourMomentum& p = mu.momentum();
00165         _hist_phi_mu->fill(mapAngleMPiToPi(p.phi()), weight);
00166         _hist_eta_mu->fill(p.eta(), weight);
00167         _hist_pt_mu->fill(p.pT()/GeV, weight);
00168         // Add sufficiently hard leptons to collections for m_ll histo
00169         if (p.pT()/GeV > 20) {
00170           if (PID::threeCharge(mu.pid()) > 0) mupluses += p; else muminuses += p;
00171         }
00172       }
00173 
00174       // Fill final state non-isolated photon histos
00175       const FinalState& allphotonfs = applyProjection<FinalState>(evt, "AllPhotons");
00176       _hist_n_gamma->fill(allphotonfs.size(), weight);
00177       Particles isolatedphotons;
00178       foreach (const Particle& ph, allphotonfs.particles()) {
00179         const FourMomentum& p = ph.momentum();
00180         _hist_phi_gamma->fill(mapAngleMPiToPi(p.phi()), weight);
00181         _hist_eta_gamma->fill(p.eta(), weight);
00182         _hist_pt_gamma->fill(p.pT()/GeV, weight);
00183         // Select isolated photons
00184         bool isolated = true;
00185         foreach (const Jet& j, jets) {
00186           if (deltaR(j.momentum(), p) < 0.2) {
00187             isolated = false;
00188             break;
00189           }
00190         }
00191         if (isolated) isolatedphotons += ph;
00192       }
00193 
00194 
00195       // Fill final state isolated photon histos
00196       _hist_n_gammaiso->fill(isolatedphotons.size(), weight);
00197       foreach (const Particle& ph_iso, isolatedphotons) {
00198         const FourMomentum& p = ph_iso.momentum();
00199         _hist_phi_gammaiso->fill(mapAngleMPiToPi(p.phi()), weight);
00200         _hist_eta_gammaiso->fill(p.eta(), weight);
00201         _hist_pt_gammaiso->fill(p.pT()/GeV, weight);
00202       }
00203 
00204       // Calculate and fill missing Et histos
00205       const MissingMomentum& met = applyProjection<MissingMomentum>(evt, "MET");
00206       _hist_met->fill(met.vectorEt().mod()/GeV);
00207 
00208       // Choose highest-pT leptons of each sign and flavour for dilepton mass edges
00209       const FinalState& lpfs = applyProjection<FinalState>(evt, "LeadingParticles");
00210       bool eplus_ok(false), eminus_ok(false), muplus_ok(false), muminus_ok(false);
00211       FourMomentum peplus, peminus, pmuplus, pmuminus;
00212       foreach (const Particle& p, lpfs.particles()) {
00213         // Only use leptons above 20 GeV
00214         if (p.pT()/GeV < 20) continue;
00215         // Identify the PID
00216         const PdgId pid = p.pid();
00217         if (pid == PID::ELECTRON) {
00218           eminus_ok = true;
00219           peminus = p.momentum();
00220         } else if (pid == PID::POSITRON) {
00221           eplus_ok = true;
00222           peplus = p.momentum();
00223         } else if (pid == PID::MUON) {
00224           muminus_ok = true;
00225           pmuminus = p.momentum();
00226         } else if (pid == PID::ANTIMUON) {
00227           muplus_ok = true;
00228           pmuplus = p.momentum();
00229         } else {
00230           throw Error("Unexpected particle type in leading particles FS!");
00231         }
00232       }
00233       // m_ee
00234       if (eminus_ok && eplus_ok) {
00235         const double m_ee = FourMomentum(peplus + peminus).mass();
00236         _hist_mll_ossf_ee->fill(m_ee/GeV, weight);
00237         if (epluses.size() == 1 && eminuses.size() == 1)
00238           _hist_mll_2_ossf_ee->fill(m_ee/GeV, weight);
00239       }
00240       // m_mumu
00241       if (muminus_ok && muplus_ok) {
00242         const double m_mumu = FourMomentum(pmuplus + pmuminus).mass();
00243         _hist_mll_ossf_mumu->fill(m_mumu/GeV, weight);
00244         if (mupluses.size() == 1 && muminuses.size() == 1)
00245           _hist_mll_2_ossf_mumu->fill(m_mumu/GeV, weight);
00246       }
00247       // m_emu (both configurations)
00248       if (eminus_ok && muplus_ok) {
00249         const double m_emu = FourMomentum(pmuplus + peminus).mass();
00250         _hist_mll_osof_emu->fill(m_emu/GeV, weight);
00251         if (mupluses.size() == 1 && eminuses.size() == 1)
00252           _hist_mll_2_osof_emu->fill(m_emu/GeV, weight);
00253 
00254       }
00255       if (muminus_ok && eplus_ok) {
00256         const double m_mue = FourMomentum(peplus + pmuminus).mass();
00257         _hist_mll_osof_emu->fill(m_mue/GeV, weight);
00258         if (epluses.size() == 1 && muminuses.size() == 1)
00259           _hist_mll_2_osof_emu->fill(m_mue/GeV, weight);
00260       }
00261 
00262 
00263       // m_ll plots using *all* electrons, positrons, muons and antimuons
00264       // m_ee
00265       foreach (const FourMomentum& peplus, epluses) {
00266         foreach (const FourMomentum& peminus, eminuses) {
00267           const double m_ee = FourMomentum(peplus + peminus).mass();
00268           _hist_mll_all_ossf_ee->fill(m_ee/GeV, weight);
00269         }
00270       }
00271       // m_mumu
00272       foreach (const FourMomentum& pmuplus, mupluses) {
00273         foreach (const FourMomentum& pmuminus, muminuses) {
00274           const double m_mumu = FourMomentum(pmuplus + pmuminus).mass();
00275           _hist_mll_all_ossf_mumu->fill(m_mumu/GeV, weight);
00276         }
00277       }
00278       // m_emu (both configurations)
00279       foreach (const FourMomentum& pmuplus, mupluses) {
00280         foreach (const FourMomentum& peminus, eminuses) {
00281           const double m_emu = FourMomentum(pmuplus + peminus).mass();
00282           _hist_mll_all_osof_emu->fill(m_emu/GeV, weight);
00283         }
00284       }
00285       foreach (const FourMomentum& peplus, epluses) {
00286         foreach (const FourMomentum& pmuminus, muminuses) {
00287           const double m_mue = FourMomentum(peplus + pmuminus).mass();
00288           _hist_mll_all_osof_emu->fill(m_mue/GeV, weight);
00289         }
00290       }
00291 
00292     }
00293 
00294 
00295     void finalize() {
00296       /// @todo Normalisations
00297     }
00298 
00299     //@}
00300 
00301 
00302   private:
00303 
00304     Histo1DPtr _hist_n_trk, _hist_phi_trk, _hist_eta_trk, _hist_pt_trk;
00305     Histo1DPtr _hist_n_jet, _hist_phi_jet, _hist_eta_jet, _hist_pt_jet;
00306     Histo1DPtr _hist_n_e, _hist_phi_e, _hist_eta_e, _hist_pt_e;
00307     Histo1DPtr _hist_n_mu, _hist_phi_mu, _hist_eta_mu, _hist_pt_mu;
00308     Histo1DPtr _hist_n_gamma, _hist_phi_gamma, _hist_eta_gamma, _hist_pt_gamma;
00309     Histo1DPtr _hist_n_gammaiso, _hist_phi_gammaiso, _hist_eta_gammaiso, _hist_pt_gammaiso;
00310     Histo1DPtr _hist_met;
00311     Histo1DPtr _hist_mll_2_ossf_ee, _hist_mll_2_ossf_mumu, _hist_mll_2_osof_emu;
00312     Histo1DPtr _hist_mll_ossf_ee, _hist_mll_ossf_mumu, _hist_mll_osof_emu;
00313     Histo1DPtr _hist_mll_all_ossf_ee, _hist_mll_all_ossf_mumu, _hist_mll_all_osof_emu;
00314   };
00315 
00316 
00317 
00318   // The hook for the plugin system
00319   DECLARE_RIVET_PLUGIN(MC_SUSY);
00320 
00321 }