Rivet analyses
Measurement of ttbar production with additional jet activity, including b quark jets, in the dilepton decay channel using pp collisions at sqrt(s)=8 TeV
Experiment: CMS (LHC)
Inspire ID: 1397174
Status: VALIDATED
Authors: - Javier Fernandez - Jungwan John Goh - Efe Yazgan - Markus Seidel - James Keaveney - Elvire Bouvier - Benedikt Maier - Andy Buckley
References: - arXiv: 1510.03072
Beams: p+ p+
Beam energies: (4000.0, 4000.0)GeV
Run details: - ttbar events at $=8~. Top quarks are expected in the event record to identify additional jets. Gap fractions require high statistics in a single run or custom merging of the YODA files.
Jet multiplicity distributions in top quark pair (tt̄) events are measured in pp collisions at a centre-of-mass energy of 8~with the CMS detector at the LHC, using a data set corresponding to an integrated luminosity of 19.7/fb. The measurement is performed in the dilepton decay channels e+e−, μ+μ−, and e±μ∓). The absolute and normalized differential cross-sections for tt̄ production are measured as a function of jet multiplicity for different jet transverse momentum thresholds and the kinematic properties of the leading additional jets. The differential tt̄b and tt̄bb̄ cross-sections are presented for the first time as a function of the kinematic properties of the leading additional b-jets. Furthermore, the fraction of events without additional jets above a threshold is measured as a function of the transverse momenta of the leading additional jets and the scalar sum of the transverse momenta of all additional jets.
Source
code:CMS_2015_I1397174.cc
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/PartonicTops.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
#include "Rivet/Projections/FastJets.hh"
namespace Rivet {
/// Fully leptonic partonic ttbar analysis
class CMS_2015_I1397174 : public Analysis {
public:
/// Minimal constructor
RIVET_DEFAULT_ANALYSIS_CTOR(CMS_2015_I1397174);
/// @name Analysis methods
/// @{
/// Set up projections and book histograms
void init() {
// Parton level top quarks
declare(PartonicTops(TopDecay::E_MU, PromptEMuFromTau::NO), "PartonTops");
// Find jets not related to the top/W decays
VetoedFinalState vfs;
vfs.addDecayProductsVeto(PID::WPLUSBOSON);
vfs.addDecayProductsVeto(PID::WMINUSBOSON);
FastJets fj(vfs, JetAlg::ANTIKT, 0.5, JetMuons::ALL, JetInvisibles::ALL);
declare(fj, "Jets");
// Book histograms
book(_hVis_nJet30_abs , 1, 1, 1);
book(_hVis_nJet30 , 2, 1, 1);
book(_hVis_nJet60_abs , 3, 1, 1);
book(_hVis_nJet60 , 4, 1, 1);
book(_hVis_nJet100_abs , 5, 1, 1);
book(_hVis_nJet100 , 6, 1, 1);
book(_hVis_addJet1Pt_abs , 7, 1, 1);
book(_hVis_addJet1Pt , 8, 1, 1);
book(_hVis_addJet1Eta_abs , 9, 1, 1);
book(_hVis_addJet1Eta ,10, 1, 1);
book(_hVis_addJet2Pt_abs ,11, 1, 1);
book(_hVis_addJet2Pt ,12, 1, 1);
book(_hVis_addJet2Eta_abs ,13, 1, 1);
book(_hVis_addJet2Eta ,14, 1, 1);
book(_hVis_addJJMass_abs ,15, 1, 1);
book(_hVis_addJJMass ,16, 1, 1);
book(_hVis_addJJDR_abs ,17, 1, 1);
book(_hVis_addJJDR ,18, 1, 1);
book(_hVis_addJJHT_abs ,19, 1, 1);
book(_hVis_addJJHT ,20, 1, 1);
book(_hFull_addJet1Pt_abs ,21, 1, 1);
book(_hFull_addJet1Pt ,22, 1, 1);
book(_hFull_addJet1Eta_abs ,23, 1, 1);
book(_hFull_addJet1Eta ,24, 1, 1);
book(_hFull_addJet2Pt_abs ,25, 1, 1);
book(_hFull_addJet2Pt ,26, 1, 1);
book(_hFull_addJet2Eta_abs ,27, 1, 1);
book(_hFull_addJet2Eta ,28, 1, 1);
book(_hFull_addJJMass_abs ,29, 1, 1);
book(_hFull_addJJMass ,30, 1, 1);
book(_hFull_addJJDR_abs ,31, 1, 1);
book(_hFull_addJJDR ,32, 1, 1);
book(_hFull_addJJHT_abs ,33, 1, 1);
book(_hFull_addJJHT ,34, 1, 1);
book(_hVis_addBJet1Pt_abs ,35, 1, 1);
book(_hVis_addBJet1Pt ,36, 1, 1);
book(_hVis_addBJet1Eta_abs ,37, 1, 1);
book(_hVis_addBJet1Eta ,38, 1, 1);
book(_hVis_addBJet2Pt_abs ,39, 1, 1);
book(_hVis_addBJet2Pt ,40, 1, 1);
book(_hVis_addBJet2Eta_abs ,41, 1, 1);
book(_hVis_addBJet2Eta ,42, 1, 1);
book(_hVis_addBBMass_abs ,43, 1, 1);
book(_hVis_addBBMass ,44, 1, 1);
book(_hVis_addBBDR_abs ,45, 1, 1);
book(_hVis_addBBDR ,46, 1, 1);
book(_hFull_addBJet1Pt_abs ,47, 1, 1);
book(_hFull_addBJet1Pt ,48, 1, 1);
book(_hFull_addBJet1Eta_abs ,49, 1, 1);
book(_hFull_addBJet1Eta ,50, 1, 1);
book(_hFull_addBJet2Pt_abs ,51, 1, 1);
book(_hFull_addBJet2Pt ,52, 1, 1);
book(_hFull_addBJet2Eta_abs ,53, 1, 1);
book(_hFull_addBJet2Eta ,54, 1, 1);
book(_hFull_addBBMass_abs ,55, 1, 1);
book(_hFull_addBBMass ,56, 1, 1);
book(_hFull_addBBDR_abs ,57, 1, 1);
book(_hFull_addBBDR ,58, 1, 1);
book(_h_gap_addJet1Pt ,59, 1, 1);
book(_h_gap_addJet1Pt_eta0 ,60, 1, 1);
book(_h_gap_addJet1Pt_eta1 ,61, 1, 1);
book(_h_gap_addJet1Pt_eta2 ,62, 1, 1);
book(_h_gap_addJet2Pt ,63, 1, 1);
book(_h_gap_addJet2Pt_eta0 ,64, 1, 1);
book(_h_gap_addJet2Pt_eta1 ,65, 1, 1);
book(_h_gap_addJet2Pt_eta2 ,66, 1, 1);
book(_h_gap_addJetHT ,67, 1, 1);
book(_h_gap_addJetHT_eta0 ,68, 1, 1);
book(_h_gap_addJetHT_eta1 ,69, 1, 1);
book(_h_gap_addJetHT_eta2 ,70, 1, 1);
}
void analyze(const Event& event) {
// The objects used in the PAPER 12-041 are defined as follows (see p.16 for details):
//
// * Leptons : from the W boson decays after FSR
// * Jets : anti-kT R=0.5 to all stable particles
// exclude W->enu, munu, taunu
// * B jet : B-Ghost matched
// * B from top : B hadron from top->b decay
//
// Visible phase space definition:
//
// * Leptons : pT > 20, |eta| < 2.4
// * B jets from top : pT > 30, |eta| < 2.4
// Additional jets : pT > 20, |eta| < 2.4
// *
// Full phase space definition:
//
// * Correction to dilepton BR from W boson BR
// * No cut on top decay products
// * Additional jets : pT > 20, |eta| < 2.4
// Do the analysis only for the ttbar full leptonic channel, removing tau decays
const Particles partontops = apply<ParticleFinder>(event, "PartonTops").particlesByPt();
if (partontops.size() != 2) vetoEvent;
const Particle& t1 = partontops[0];
const Particle& t2 = partontops[1];
// Apply acceptance cuts on top-decay leptons (existence should be guaranteed)
const auto isPromptChLepton = [](const Particle& p){return p.isPrompt() && isChargedLepton(p);};
const Particle lep1 = t1.allDescendants(lastParticleWith(isPromptChLepton)).front();
const Particle lep2 = t2.allDescendants(lastParticleWith(isPromptChLepton)).front();
if (lep1.pT() < 1e-9*GeV || lep2.pT() < 1e-9*GeV) vetoEvent; // sanity check?
const Jets jets = apply<JetFinder>(event, "Jets").jetsByPt(Cuts::pT > 20*GeV && Cuts::abseta < 2.4);
int nJet30 = 0, nJet60 = 0, nJet100 = 0;
Jets topBJets, addJets, addBJets, addJets_eta0, addJets_eta1, addJets_eta2;
for (const Jet& jet : jets) {
if (jet.pT() > 30*GeV) nJet30 += 1;
if (jet.pT() > 60*GeV) nJet60 += 1;
if (jet.pT() > 100*GeV) nJet100 += 1;
const bool isBtagged = jet.bTagged();
const bool isBFromTop = any(jet.bTags(), hasParticleAncestorWith(Cuts::abspid == PID::TQUARK, false));
if (isBFromTop) {
if (jet.pT() > 30*GeV) topBJets.push_back(jet);
} else {
addJets.push_back(jet);
if (isBtagged) addBJets.push_back(jet);
if (jet.abseta() < 0.8 ) addJets_eta0.push_back(jet);
else if (jet.abseta() < 1.5 ) addJets_eta1.push_back(jet);
else if (jet.abseta() < 2.4 ) addJets_eta2.push_back(jet);
}
}
const bool isVisiblePS = topBJets.size() >= 2
&& lep1.pT() > 20*GeV && lep1.abseta() < 2.4 && lep2.pT() > 20*GeV && lep2.abseta() < 2.4;
MSG_DEBUG(isVisiblePS << ": #b(top) = " << topBJets.size()
<< "; l1 = " << lep1.pT() << ", " << lep1.abseta()
<< "; l2 = " << lep2.pT() << ", " << lep2.abseta());
if (isVisiblePS) {
fillWithOF(_hVis_nJet30_abs, nJet30);
fillWithOF(_hVis_nJet30, nJet30);
fillWithOF(_hVis_nJet60_abs, nJet60);
fillWithOF(_hVis_nJet60, nJet60);
fillWithOF(_hVis_nJet100_abs, nJet100);
fillWithOF(_hVis_nJet100, nJet100);
fillGapFractions(addJets, _h_gap_addJet1Pt, _h_gap_addJet2Pt, _h_gap_addJetHT);
fillGapFractions(addJets_eta0, _h_gap_addJet1Pt_eta0, _h_gap_addJet2Pt_eta0, _h_gap_addJetHT_eta0);
fillGapFractions(addJets_eta1, _h_gap_addJet1Pt_eta1, _h_gap_addJet2Pt_eta1, _h_gap_addJetHT_eta1);
fillGapFractions(addJets_eta2, _h_gap_addJet1Pt_eta2, _h_gap_addJet2Pt_eta2, _h_gap_addJetHT_eta2);
}
// Plots with two additional jets
if (addJets.size() >= 1) {
const double ht = sum(addJets, Kin::pT, 0.0);
_hFull_addJJHT_abs->fill(ht/GeV);
_hFull_addJJHT ->fill(ht/GeV);
if (isVisiblePS) {
_hVis_addJJHT_abs->fill(ht/GeV);
_hVis_addJJHT ->fill(ht/GeV);
}
const Jet& j1 = addJets[0];
_hFull_addJet1Pt_abs ->fill(j1.pT()/GeV);
_hFull_addJet1Pt ->fill(j1.pT()/GeV);
_hFull_addJet1Eta_abs->fill(j1.abseta());
_hFull_addJet1Eta ->fill(j1.abseta());
if (isVisiblePS) {
_hVis_addJet1Pt_abs ->fill(j1.pT()/GeV);
_hVis_addJet1Pt ->fill(j1.pT()/GeV);
_hVis_addJet1Eta_abs->fill(j1.abseta());
_hVis_addJet1Eta ->fill(j1.abseta());
}
if (addJets.size() >= 2) {
const Jet& j2 = addJets[1];
_hFull_addJet2Pt_abs ->fill(j2.pT()/GeV);
_hFull_addJet2Pt ->fill(j2.pT()/GeV);
_hFull_addJet2Eta_abs->fill(j2.abseta());
_hFull_addJet2Eta ->fill(j2.abseta());
if (isVisiblePS) {
_hVis_addJet2Pt_abs ->fill(j2.pT()/GeV);
_hVis_addJet2Pt ->fill(j2.pT()/GeV);
_hVis_addJet2Eta_abs->fill(j2.abseta());
_hVis_addJet2Eta ->fill(j2.abseta());
}
const double jjmass = (j1.mom() + j2.mom()).mass();
const double jjdR = deltaR(j1, j2);
_hFull_addJJMass_abs->fill(jjmass/GeV);
_hFull_addJJMass ->fill(jjmass/GeV);
_hFull_addJJDR_abs ->fill(jjdR);
_hFull_addJJDR ->fill(jjdR);
if (isVisiblePS) {
_hVis_addJJMass_abs->fill(jjmass/GeV);
_hVis_addJJMass ->fill(jjmass/GeV);
_hVis_addJJDR_abs ->fill(jjdR);
_hVis_addJJDR ->fill(jjdR);
}
}
}
// Same set of plots if there are additional b-jets
if (addBJets.size() >= 1) {
const Jet& b1 = addBJets[0];
_hFull_addBJet1Pt_abs ->fill(b1.pT()/GeV);
_hFull_addBJet1Pt ->fill(b1.pT()/GeV);
_hFull_addBJet1Eta_abs->fill(b1.abseta());
_hFull_addBJet1Eta ->fill(b1.abseta());
if (isVisiblePS) {
_hVis_addBJet1Pt_abs ->fill(b1.pT()/GeV);
_hVis_addBJet1Pt ->fill(b1.pT()/GeV);
_hVis_addBJet1Eta_abs->fill(b1.abseta());
_hVis_addBJet1Eta ->fill(b1.abseta());
}
if (addBJets.size() >= 2) {
const Jet& b2 = addBJets[1];
_hFull_addBJet2Pt_abs ->fill(b2.pT()/GeV);
_hFull_addBJet2Pt ->fill(b2.pT()/GeV);
_hFull_addBJet2Eta_abs->fill(b2.abseta());
_hFull_addBJet2Eta ->fill(b2.abseta());
if (isVisiblePS) {
_hVis_addBJet2Pt_abs ->fill(b2.pT()/GeV);
_hVis_addBJet2Pt ->fill(b2.pT()/GeV);
_hVis_addBJet2Eta_abs->fill(b2.abseta());
_hVis_addBJet2Eta ->fill(b2.abseta());
}
const double bbmass = (b1.mom() + b2.mom()).mass();
const double bbdR = deltaR(b1, b2);
_hFull_addBBMass_abs->fill(bbmass/GeV);
_hFull_addBBMass ->fill(bbmass/GeV);
_hFull_addBBDR_abs ->fill(bbdR);
_hFull_addBBDR ->fill(bbdR);
if (isVisiblePS) {
_hVis_addBBMass_abs->fill(bbmass/GeV);
_hVis_addBBMass ->fill(bbmass/GeV);
_hVis_addBBDR_abs ->fill(bbdR);
_hVis_addBBDR ->fill(bbdR);
}
}
}
}
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");
normalize(_hVis_nJet30); normalize(_hVis_nJet60); normalize(_hVis_nJet100);
normalize(_hVis_addJet1Pt); normalize(_hVis_addJet1Eta); normalize(_hVis_addJet2Pt);
normalize(_hVis_addJet2Eta); normalize(_hVis_addJJMass); normalize(_hVis_addJJDR);
normalize(_hVis_addJJHT); normalize(_hFull_addJet1Pt); normalize(_hFull_addJet1Eta);
normalize(_hFull_addJet2Pt); normalize(_hFull_addJet2Eta); normalize(_hFull_addJJMass);
normalize(_hFull_addJJDR); normalize(_hFull_addJJHT); normalize(_hVis_addBJet1Pt);
normalize(_hVis_addBJet1Eta); normalize(_hVis_addBJet2Pt); normalize(_hVis_addBJet2Eta);
normalize(_hVis_addBBMass); normalize(_hVis_addBBDR); normalize(_hFull_addBJet1Pt);
normalize(_hFull_addBJet1Eta); normalize(_hFull_addBJet2Pt); normalize(_hFull_addBJet2Eta);
normalize(_hFull_addBBMass); normalize(_hFull_addBBDR);
const double xsPerWeight = ttbarXS/picobarn / sumOfWeights();
scale(_hVis_nJet30_abs, xsPerWeight); scale(_hVis_nJet60_abs, xsPerWeight);
scale(_hVis_nJet100_abs, xsPerWeight); scale(_hVis_addJet1Pt_abs, xsPerWeight);
scale(_hVis_addJet1Eta_abs, xsPerWeight); scale(_hVis_addJet2Pt_abs, xsPerWeight);
scale(_hVis_addJet2Eta_abs, xsPerWeight); scale(_hVis_addJJMass_abs, xsPerWeight);
scale(_hVis_addJJDR_abs, xsPerWeight); scale(_hVis_addJJHT_abs, xsPerWeight);
scale(_hVis_addBJet1Pt_abs, xsPerWeight); scale(_hVis_addBJet1Eta_abs, xsPerWeight);
scale(_hVis_addBJet2Pt_abs, xsPerWeight); scale(_hVis_addBJet2Eta_abs, xsPerWeight);
scale(_hVis_addBBMass_abs, xsPerWeight); scale(_hVis_addBBDR_abs, xsPerWeight);
const double sfull = xsPerWeight / 0.0454; //< correct for dilepton branching fraction
scale(_hFull_addJet1Pt_abs, sfull); scale(_hFull_addJet1Eta_abs, sfull);
scale(_hFull_addJet2Pt_abs, sfull); scale(_hFull_addJet2Eta_abs, sfull);
scale(_hFull_addJJMass_abs, sfull); scale(_hFull_addJJDR_abs, sfull);
scale(_hFull_addJJHT_abs, sfull); scale(_hFull_addBJet1Pt_abs, sfull);
scale(_hFull_addBJet1Eta_abs, sfull); scale(_hFull_addBJet2Pt_abs, sfull);
scale(_hFull_addBJet2Eta_abs, sfull); scale(_hFull_addBBMass_abs, sfull);
scale(_hFull_addBBDR_abs, sfull);
}
/// @}
void fillWithOF(Histo1DPtr h, double x) {
h->fill(std::min(x, h->xMax()-1e-9));
}
void fillGapFractions(const Jets& addJets, Profile1DPtr h_gap_addJet1Pt, Profile1DPtr h_gap_addJet2Pt, Profile1DPtr h_gap_addJetHT) {
const double j1pt = (addJets.size() > 0) ? addJets[0].pT() : 0;
for (size_t i = 1; i <= h_gap_addJet1Pt->numBins(); ++i) {
const double binCenter = h_gap_addJet1Pt->bin(i).xMid();
h_gap_addJet1Pt->fill(binCenter, int(j1pt/GeV < binCenter));
}
const double j2pt = (addJets.size() > 1) ? addJets[1].pT() : 0;
for (size_t i = 1; i <= h_gap_addJet2Pt->numBins(); ++i) {
const double binCenter = h_gap_addJet2Pt->bin(i).xMid();
h_gap_addJet2Pt->fill(binCenter, int(j2pt/GeV < binCenter));
}
const double ht = sum(addJets, Kin::pT, 0.);
for (size_t i = 1; i <= h_gap_addJetHT->numBins(); ++i) {
const double binCenter = h_gap_addJetHT->bin(i).xMid();
h_gap_addJetHT->fill(binCenter, int(ht/GeV < binCenter) );
}
}
// @name Histogram data members
/// @{
Histo1DPtr _hVis_nJet30_abs, _hVis_nJet60_abs, _hVis_nJet100_abs;
Histo1DPtr _hVis_addJet1Pt_abs, _hVis_addJet1Eta_abs, _hVis_addJet2Pt_abs, _hVis_addJet2Eta_abs;
Histo1DPtr _hVis_addJJMass_abs, _hVis_addJJDR_abs, _hVis_addJJHT_abs;
Histo1DPtr _hFull_addJet1Pt_abs, _hFull_addJet1Eta_abs, _hFull_addJet2Pt_abs, _hFull_addJet2Eta_abs;
Histo1DPtr _hFull_addJJMass_abs, _hFull_addJJDR_abs, _hFull_addJJHT_abs;
Histo1DPtr _hVis_addBJet1Pt_abs, _hVis_addBJet1Eta_abs, _hVis_addBJet2Pt_abs, _hVis_addBJet2Eta_abs;
Histo1DPtr _hVis_addBBMass_abs, _hVis_addBBDR_abs;
Histo1DPtr _hFull_addBJet1Pt_abs, _hFull_addBJet1Eta_abs, _hFull_addBJet2Pt_abs, _hFull_addBJet2Eta_abs;
Histo1DPtr _hFull_addBBMass_abs, _hFull_addBBDR_abs;
Histo1DPtr _hVis_nJet30, _hVis_nJet60, _hVis_nJet100;
Histo1DPtr _hVis_addJet1Pt, _hVis_addJet1Eta, _hVis_addJet2Pt, _hVis_addJet2Eta;
Histo1DPtr _hVis_addJJMass, _hVis_addJJDR, _hVis_addJJHT;
Histo1DPtr _hFull_addJet1Pt, _hFull_addJet1Eta, _hFull_addJet2Pt, _hFull_addJet2Eta;
Histo1DPtr _hFull_addJJMass, _hFull_addJJDR, _hFull_addJJHT;
Histo1DPtr _hVis_addBJet1Pt, _hVis_addBJet1Eta, _hVis_addBJet2Pt, _hVis_addBJet2Eta;
Histo1DPtr _hVis_addBBMass, _hVis_addBBDR;
Histo1DPtr _hFull_addBJet1Pt, _hFull_addBJet1Eta, _hFull_addBJet2Pt, _hFull_addBJet2Eta;
Histo1DPtr _hFull_addBBMass, _hFull_addBBDR;
Profile1DPtr _h_gap_addJet1Pt, _h_gap_addJet1Pt_eta0, _h_gap_addJet1Pt_eta1, _h_gap_addJet1Pt_eta2;
Profile1DPtr _h_gap_addJet2Pt, _h_gap_addJet2Pt_eta0, _h_gap_addJet2Pt_eta1, _h_gap_addJet2Pt_eta2;
Profile1DPtr _h_gap_addJetHT, _h_gap_addJetHT_eta0, _h_gap_addJetHT_eta1, _h_gap_addJetHT_eta2;
/// @}
};
RIVET_DECLARE_PLUGIN(CMS_2015_I1397174);
}