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