MC_SUSY.cc

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