Rivet analyses
Validate generic SUSY events, including various lepton invariant mass
Experiment: ()
Status: VALIDATED
Authors: - Andy Buckley
References: none listed
Beams: * *
Beam energies: ANY
Run details: - SUSY events at any energy. $\pT$ cutoff at 10 GeV may be advised.
Analysis of generic SUSY events at the LHC, based on Atlas Herwig++ validation analysis contents. Plotted are η, ϕ and $\pT$ observables for charged tracks, photons, isolated photons, electrons, muons, and jets, as well as various dilepton mass `edge’ plots for different event selection criteria.
Source
code:MC_SUSY.cc
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/ChargedFinalState.hh"
#include "Rivet/Projections/FastJets.hh"
#include "Rivet/Projections/IdentifiedFinalState.hh"
#include "Rivet/Projections/MissingMomentum.hh"
#include "Rivet/Projections/LeadingParticlesFinalState.hh"
namespace Rivet {
/// @brief MC validation analysis for SUSY events
/// @author Andy Buckley
class MC_SUSY : public Analysis {
public:
/// Constructor
MC_SUSY()
: Analysis("MC_SUSY")
{ }
/// @name Analysis methods
/// @{
// Book histograms
void init() {
// Basic final state
const FinalState fs((Cuts::etaIn(-4.0, 4.0) && Cuts::pT >= 10*GeV));
// Tracks and jets
declare(ChargedFinalState(fs), "Tracks");
declare(FastJets(fs, JetAlg::ANTIKT, 0.7), "Jets");
IdentifiedFinalState photonfs(fs);
photonfs.acceptId(PID::PHOTON);
declare(photonfs, "AllPhotons");
IdentifiedFinalState efs(fs);
efs.acceptIdPair(PID::ELECTRON);
declare(efs, "Electrons");
IdentifiedFinalState mufs(fs);
mufs.acceptIdPair(PID::MUON);
declare(mufs, "Muons");
MissingMomentum missing(fs);
declare(missing, "MET");
LeadingParticlesFinalState lpfs(fs);
lpfs.addParticleIdPair(PID::ELECTRON);
lpfs.addParticleIdPair(PID::MUON);
declare(lpfs, "LeadingParticles");
book(_hist_n_trk ,"n-trk", 50, 0.5, 300.5);
book(_hist_phi_trk ,"phi-trk", 50, -PI, PI);
book(_hist_eta_trk ,"eta-trk", 50, -4, 4);
book(_hist_pt_trk ,"pt-trk", 100, 0.0, 1500);
book(_hist_n_jet ,"n-jet", 21, -0.5, 20.5);
book(_hist_phi_jet ,"phi-jet", 50, -PI, PI);
book(_hist_eta_jet ,"eta-jet", 50, -4, 4);
book(_hist_pt_jet ,"pt-jet", 100, 0.0, 1500);
book(_hist_n_e ,"n-e", 11, -0.5, 10.5);
book(_hist_phi_e ,"phi-e", 50, -PI, PI);
book(_hist_eta_e ,"eta-e", 50, -4, 4);
book(_hist_pt_e ,"pt-e", 100, 0.0, 500);
book(_hist_n_mu ,"n-mu", 11, -0.5, 10.5);
book(_hist_phi_mu ,"phi-mu", 50, -PI, PI);
book(_hist_eta_mu ,"eta-mu", 50, -4, 4);
book(_hist_pt_mu ,"pt-mu", 100, 0.0, 500);
book(_hist_n_gamma ,"n-gamma", 11, -0.5, 10.5);
book(_hist_phi_gamma ,"phi-gamma", 50, -PI, PI);
book(_hist_eta_gamma ,"eta-gamma", 50, -4, 4);
book(_hist_pt_gamma ,"pt-gamma", 100, 0.0, 500);
book(_hist_n_gammaiso ,"n-gamma-iso", 11, -0.5, 10.5);
book(_hist_phi_gammaiso ,"phi-gamma-iso", 50, -PI, PI);
book(_hist_eta_gammaiso ,"eta-gamma-iso", 50, -4, 4);
book(_hist_pt_gammaiso ,"pt-gamma-iso", 100, 0.0, 500);
book(_hist_met ,"Etmiss", 100, 0.0, 1500);
book(_hist_mll_ossf_ee ,"mll-ossf-ee", 50, 0.0, 500);
book(_hist_mll_ossf_mumu ,"mll-ossf-mumu", 50, 0.0, 500);
book(_hist_mll_osof_emu ,"mll-osof-emu", 50, 0.0, 500);
book(_hist_mll_all_ossf_ee ,"mll-all-ossf-ee", 50, 0.0, 500);
book(_hist_mll_all_ossf_mumu ,"mll-all-ossf-mumu", 50, 0.0, 500);
book(_hist_mll_all_osof_emu ,"mll-all-osof-emu", 50, 0.0, 500);
book(_hist_mll_2_ossf_ee ,"mll-2-ossf-ee", 50, 0.0, 500);
book(_hist_mll_2_ossf_mumu ,"mll-2-ossf-mumu", 50, 0.0, 500);
book(_hist_mll_2_osof_emu ,"mll-2-osof-emu", 50, 0.0, 500);
/// @todo LSP eta, pT, phi, mass: no reliable cross-scenario LSP PID but
/// maybe plot for all of chi^0_1, gravitino, sneutrino, gluino, ... or
/// identify the LSP as any PID::isSUSY (?) particle with status = 1?
}
// Do the analysis
void analyze(const Event& evt) {
const FinalState& tracks = apply<FinalState>(evt, "Tracks");
if (tracks.particles().empty()) {
MSG_DEBUG("Failed multiplicity cut");
vetoEvent;
}
// Fill track histos
_hist_n_trk->fill(tracks.size());
for (const Particle& t : tracks.particles()) {
const FourMomentum& p = t.momentum();
_hist_phi_trk->fill(mapAngleMPiToPi(p.phi()));
_hist_eta_trk->fill(p.eta());
_hist_pt_trk->fill(p.pT()/GeV);
}
// Get jets and fill jet histos
const FastJets& jetpro = apply<FastJets>(evt, "Jets");
const Jets jets = jetpro.jetsByPt();
MSG_DEBUG("Jet multiplicity = " << jets.size());
_hist_n_jet->fill(jets.size());
for (const Jet& j : jets) {
const FourMomentum& pj = j.momentum();
_hist_phi_jet->fill(mapAngleMPiToPi(pj.phi()));
_hist_eta_jet->fill(pj.eta());
_hist_pt_jet->fill(pj.pT()/GeV);
}
/// @todo Resum photons around electrons
// Fill final state electron/positron histos
const FinalState& efs = apply<FinalState>(evt, "Electrons");
_hist_n_e->fill(efs.size());
vector<FourMomentum> epluses, eminuses;
for (const Particle& e : efs.particles()) {
const FourMomentum& p = e.momentum();
_hist_phi_e->fill(mapAngleMPiToPi(p.phi()));
_hist_eta_e->fill(p.eta());
_hist_pt_e->fill(p.pT()/GeV);
// Add sufficiently hard leptons to collections for m_ll histo
if (p.pT()/GeV > 20) {
if (PID::charge3(e.pid()) > 0) epluses += p; else eminuses += p;
}
}
/// @todo Resum photons around muons
// Fill final state muon/antimuon histos
const FinalState& mufs = apply<FinalState>(evt, "Muons");
_hist_n_mu->fill(mufs.size());
vector<FourMomentum> mupluses, muminuses;
for (const Particle& mu : mufs.particles()) {
const FourMomentum& p = mu.momentum();
_hist_phi_mu->fill(mapAngleMPiToPi(p.phi()));
_hist_eta_mu->fill(p.eta());
_hist_pt_mu->fill(p.pT()/GeV);
// Add sufficiently hard leptons to collections for m_ll histo
if (p.pT()/GeV > 20) {
if (PID::charge3(mu.pid()) > 0) mupluses += p; else muminuses += p;
}
}
// Fill final state non-isolated photon histos
const FinalState& allphotonfs = apply<FinalState>(evt, "AllPhotons");
_hist_n_gamma->fill(allphotonfs.size());
Particles isolatedphotons;
for (const Particle& ph : allphotonfs.particles()) {
const FourMomentum& p = ph.momentum();
_hist_phi_gamma->fill(mapAngleMPiToPi(p.phi()));
_hist_eta_gamma->fill(p.eta());
_hist_pt_gamma->fill(p.pT()/GeV);
// Select isolated photons
bool isolated = true;
for (const Jet& j : jets) {
if (deltaR(j.momentum(), p) < 0.2) {
isolated = false;
break;
}
}
if (isolated) isolatedphotons += ph;
}
// Fill final state isolated photon histos
_hist_n_gammaiso->fill(isolatedphotons.size());
for (const Particle& ph_iso : isolatedphotons) {
const FourMomentum& p = ph_iso.momentum();
_hist_phi_gammaiso->fill(mapAngleMPiToPi(p.phi()));
_hist_eta_gammaiso->fill(p.eta());
_hist_pt_gammaiso->fill(p.pT()/GeV);
}
// Calculate and fill missing Et histos
const MissingMomentum& met = apply<MissingMomentum>(evt, "MET");
_hist_met->fill(met.vectorEt().mod()/GeV);
// Choose highest-pT leptons of each sign and flavour for dilepton mass edges
const FinalState& lpfs = apply<FinalState>(evt, "LeadingParticles");
bool eplus_ok(false), eminus_ok(false), muplus_ok(false), muminus_ok(false);
FourMomentum peplus, peminus, pmuplus, pmuminus;
for (const Particle& p : lpfs.particles()) {
// Only use leptons above 20 GeV
if (p.pT()/GeV < 20) continue;
// Identify the PID
const PdgId pid = p.pid();
if (pid == PID::ELECTRON) {
eminus_ok = true;
peminus = p.momentum();
} else if (pid == PID::POSITRON) {
eplus_ok = true;
peplus = p.momentum();
} else if (pid == PID::MUON) {
muminus_ok = true;
pmuminus = p.momentum();
} else if (pid == PID::ANTIMUON) {
muplus_ok = true;
pmuplus = p.momentum();
} else {
throw Error("Unexpected particle type in leading particles FS!");
}
}
// m_ee
if (eminus_ok && eplus_ok) {
const double m_ee = FourMomentum(peplus + peminus).mass();
_hist_mll_ossf_ee->fill(m_ee/GeV);
if (epluses.size() == 1 && eminuses.size() == 1)
_hist_mll_2_ossf_ee->fill(m_ee/GeV);
}
// m_mumu
if (muminus_ok && muplus_ok) {
const double m_mumu = FourMomentum(pmuplus + pmuminus).mass();
_hist_mll_ossf_mumu->fill(m_mumu/GeV);
if (mupluses.size() == 1 && muminuses.size() == 1)
_hist_mll_2_ossf_mumu->fill(m_mumu/GeV);
}
// m_emu (both configurations)
if (eminus_ok && muplus_ok) {
const double m_emu = FourMomentum(pmuplus + peminus).mass();
_hist_mll_osof_emu->fill(m_emu/GeV);
if (mupluses.size() == 1 && eminuses.size() == 1)
_hist_mll_2_osof_emu->fill(m_emu/GeV);
}
if (muminus_ok && eplus_ok) {
const double m_mue = FourMomentum(peplus + pmuminus).mass();
_hist_mll_osof_emu->fill(m_mue/GeV);
if (epluses.size() == 1 && muminuses.size() == 1)
_hist_mll_2_osof_emu->fill(m_mue/GeV);
}
// m_ll plots using *all* electrons, positrons, muons and antimuons
// m_ee
for (const FourMomentum& peplus : epluses) {
for (const FourMomentum& peminus : eminuses) {
const double m_ee = FourMomentum(peplus + peminus).mass();
_hist_mll_all_ossf_ee->fill(m_ee/GeV);
}
}
// m_mumu
for (const FourMomentum& pmuplus : mupluses) {
for (const FourMomentum& pmuminus : muminuses) {
const double m_mumu = FourMomentum(pmuplus + pmuminus).mass();
_hist_mll_all_ossf_mumu->fill(m_mumu/GeV);
}
}
// m_emu (both configurations)
for (const FourMomentum& pmuplus : mupluses) {
for (const FourMomentum& peminus : eminuses) {
const double m_emu = FourMomentum(pmuplus + peminus).mass();
_hist_mll_all_osof_emu->fill(m_emu/GeV);
}
}
for (const FourMomentum& peplus : epluses) {
for (const FourMomentum& pmuminus : muminuses) {
const double m_mue = FourMomentum(peplus + pmuminus).mass();
_hist_mll_all_osof_emu->fill(m_mue/GeV);
}
}
}
void finalize() {
/// @todo Normalisations
}
/// @}
private:
Histo1DPtr _hist_n_trk, _hist_phi_trk, _hist_eta_trk, _hist_pt_trk;
Histo1DPtr _hist_n_jet, _hist_phi_jet, _hist_eta_jet, _hist_pt_jet;
Histo1DPtr _hist_n_e, _hist_phi_e, _hist_eta_e, _hist_pt_e;
Histo1DPtr _hist_n_mu, _hist_phi_mu, _hist_eta_mu, _hist_pt_mu;
Histo1DPtr _hist_n_gamma, _hist_phi_gamma, _hist_eta_gamma, _hist_pt_gamma;
Histo1DPtr _hist_n_gammaiso, _hist_phi_gammaiso, _hist_eta_gammaiso, _hist_pt_gammaiso;
Histo1DPtr _hist_met;
Histo1DPtr _hist_mll_2_ossf_ee, _hist_mll_2_ossf_mumu, _hist_mll_2_osof_emu;
Histo1DPtr _hist_mll_ossf_ee, _hist_mll_ossf_mumu, _hist_mll_osof_emu;
Histo1DPtr _hist_mll_all_ossf_ee, _hist_mll_all_ossf_mumu, _hist_mll_all_osof_emu;
};
RIVET_DECLARE_PLUGIN(MC_SUSY);
}