Rivet analyses
Jet multiplicity in the top-quark pair lepton+jets final state at $\sqrt{s} = 8~\TeV$
Experiment: CMS (LHC)
Inspire ID: 1476015
Status: VALIDATED
Authors: - Alexis Descroix - Frederik Schaaf - Markus Seidel
References: - Expt page: CMS-PAS-TOP-15-006
Beams: p+ p+
Beam energies: (4000.0, 4000.0)GeV
Run details: - ttbar events at sqrt(s) = 8 TeV (inclusive decay modes)
The top-quark pair differential production cross section in pp collisions at $\sqrt{s}=8~\TeV$ as a function of the number of jets is measured in the lepton+jets (e/mu+jets) final state for an integrated luminosity of 19.7/fb. The cross section is presented in the visible phase space of the measurement.
Source
code:CMS_2016_PAS_TOP_15_006.cc
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/FastJets.hh"
#include "Rivet/Projections/LeptonFinder.hh"
#include "Rivet/Projections/IdentifiedFinalState.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
namespace Rivet {
/// Jet multiplicity in lepton+jets ttbar at 8 TeV
class CMS_2016_PAS_TOP_15_006 : public Analysis {
public:
/// Constructor
RIVET_DEFAULT_ANALYSIS_CTOR(CMS_2016_PAS_TOP_15_006);
/// @name Analysis methods
/// @{
/// Set up projections and book histograms
void init() {
// Complete final state
FinalState fs;
Cut superLooseLeptonCuts = Cuts::pt > 5*GeV;
SpecialLeptonFinder dressedleptons(fs, superLooseLeptonCuts);
declare(dressedleptons, "LeptonFinder");
// Projection for jets
VetoedFinalState fsForJets(fs);
fsForJets.addVetoOnThisFinalState(dressedleptons);
declare(FastJets(fsForJets, JetAlg::ANTIKT, 0.5), "Jets");
// Booking of histograms
book(_normedElectronMuonHisto, "normedElectronMuonHisto", 7, 3.5, 10.5);
book(_absXSElectronMuonHisto , "absXSElectronMuonHisto", 7, 3.5, 10.5);
}
/// Per-event analysis
void analyze(const Event& event) {
// Select ttbar -> lepton+jets
const SpecialLeptonFinder& dressedleptons = apply<SpecialLeptonFinder>(event, "LeptonFinder");
vector<FourMomentum> selleptons;
for (const DressedLepton& dressedlepton : dressedleptons.dressedLeptons()) {
// Select good leptons
if (dressedlepton.pT() > 30*GeV && dressedlepton.abseta() < 2.4) selleptons += dressedlepton.mom();
// Veto loose leptons
else if (dressedlepton.pT() > 15*GeV && dressedlepton.abseta() < 2.5) vetoEvent;
}
if (selleptons.size() != 1) vetoEvent;
// Identify hardest tight lepton
const FourMomentum lepton = selleptons[0];
// Jets
const FastJets& jets = apply<FastJets>(event, "Jets");
const Jets jets30 = jets.jetsByPt(Cuts::pT > 30*GeV);
int nJets = 0, nBJets = 0;
for (const Jet& jet : jets30) {
if (jet.abseta() > 2.5) continue;
if (deltaR(jet.momentum(), lepton) < 0.5) continue;
nJets += 1;
if (jet.bTagged(Cuts::pT > 5*GeV)) nBJets += 1;
}
// Require >= 4 resolved jets, of which two must be b-tagged
if (nJets < 4 || nBJets < 2) vetoEvent;
// Fill histograms
_normedElectronMuonHisto->fill(min(nJets, 10));
_absXSElectronMuonHisto ->fill(min(nJets, 10));
}
void finalize() {
const double ttbarXS = !std::isnan(crossSectionPerEvent()) ? crossSection() : 252.89*picobarn;
if (std::isnan(crossSectionPerEvent()))
MSG_INFO("No valid cross-section given, using NNLO (arXiv:1303.6254; sqrt(s)=8 TeV, m_t=172.5 GeV): " <<
ttbarXS/picobarn << " pb");
const double xsPerWeight = ttbarXS/picobarn / sumOfWeights();
scale(_absXSElectronMuonHisto, xsPerWeight);
normalize(_normedElectronMuonHisto);
}
/// @}
/// @brief Special dressed lepton finder
///
/// Find dressed leptons by clustering all leptons and photons
class SpecialLeptonFinder : public FinalState {
public:
/// Constructor
SpecialLeptonFinder(const FinalState& fs, const Cut& cut)
: FinalState(cut) {
setName("CMS_2016_PAS_TOP_15_006::SpecialLeptonFinder");
IdentifiedFinalState ifs(fs);
ifs.acceptIdPair(PID::PHOTON);
ifs.acceptIdPair(PID::ELECTRON);
ifs.acceptIdPair(PID::MUON);
declare(FastJets(ifs, JetAlg::ANTIKT, 0.1), "LeptonJets");
}
/// Clone on the heap
RIVET_DEFAULT_PROJ_CLONE(SpecialLeptonFinder);
/// Import to avoid warnings about overload-hiding
using Projection::operator =;
/// Retrieve the dressed leptons
const DressedLeptons& dressedLeptons() const { return _clusteredLeptons; }
/// Compare projections
CmpState compare(const Projection& p) const {
const PCmp fscmp = mkNamedPCmp(p, "LeptonJets");
if (fscmp != CmpState::EQ) return fscmp;
const SpecialLeptonFinder& other = dynamic_cast<const SpecialLeptonFinder&>(p);
const bool cutcmp = _cuts == other._cuts;
if (!cutcmp) return CmpState::NEQ;
return CmpState::EQ;
}
/// Perform the calculation
void project(const Event& e) {
_theParticles.clear();
_clusteredLeptons.clear();
DressedLeptons allClusteredLeptons;
const Jets jets = apply<FastJets>(e, "LeptonJets").jetsByPt(Cuts::pT > 5*GeV);
for (const Jet& jet : jets) {
Particle lepCand;
for (const Particle& cand : jet.particles()) {
const int absPdgId = cand.abspid();
if (absPdgId == PID::ELECTRON || absPdgId == PID::MUON) {
if (cand.pt() > lepCand.pt()) lepCand = cand;
}
}
// Central lepton must be the major component
if ((lepCand.pt() < jet.pt()/2.) || (!lepCand.isChargedLepton())) continue;
DressedLepton lepton = DressedLepton(lepCand);
for (const Particle& cand : jet.particles()) {
if (isSame(cand, lepCand)) continue;
lepton.addConstituent(cand, true);
}
allClusteredLeptons.push_back(lepton);
}
for (const DressedLepton& lepton : allClusteredLeptons) {
if (_cuts->accept(static_cast<const Particle&>(lepton))) {
_clusteredLeptons.push_back(lepton);
_theParticles.push_back(lepton.bareLepton());
_theParticles += lepton.photons();
}
}
}
protected:
/// Container which stores the clustered lepton objects
DressedLeptons _clusteredLeptons;
};
private:
/// Histograms
Histo1DPtr _normedElectronMuonHisto, _absXSElectronMuonHisto;
};
RIVET_DECLARE_PLUGIN(CMS_2016_PAS_TOP_15_006);
}