Rivet analyses referenceCMS_2018_I1620050Measurement of normalized differential ttbar cross sections in the dilepton channel from pp collisions at 13 TeVExperiment: CMS (LHC) Inspire ID: 1620050 Status: VALIDATED Authors:
Beam energies: (6500.0, 6500.0) GeV Run details:
Abstract: Normalized differential cross sections for top quark pair production are measured in the dilepton ($e^{+}e^{-}$, $\mu^{+}\mu^{-}$, and $\mu^{\mp}e^{\pm}$) decay channels in proton-proton collisions at a center-of-mass energy of 13TeV. The measurements are performed with data corresponding to an integrated luminosity of 2.1$fb^{-1}$ using the CMS detector at the LHC. The cross sections are measured differentially as a function of the kinematic properties of the leptons, jets from bottom quark hadronization, top quarks, and top quark pairs at the particle and parton levels. The results are compared to several Monte Carlo generators that implement calculations up to next-to-leading order in perturbative quantum chromodynamics interfaced with parton showering, and also to fixed-order theoretical calculations of top quark pair production up to next-to-next-to-leading order. Rivet: This analysis is to be run on $\text{t}\bar{\text{t}}$ Monte Carlo. The particle-level phase space is defined using the following definitions: \begin{description} \item[lepton]: an electron or muon with $p_\text{T}>30\,\text{GeV}$ and $|\eta|<2.4$, dressed within a cone of radius 0.1, \item[jet]: a jet is reconstructed with the anti-$k_t$ algorithm with a radius of 0.4, after removing the neutrinos and dressed leptons, with $p_\text{T]>30\,\text{GeV}$ and $|\eta|<2.4$, \item[b-jet]: a jet that contains a B-hadron. \end{description} A W boson at the particle level is defined by combining a dressed lepton and a neutrino. In each event, a pair of particle-level W bosons is chosen among the possible combinations such that the sum of the absolute values of the invariant mass differences with respect to the W boson mass is minimal. Similarly, a top quark at the particle level is defined by combining a particle-level W boson and a b jet. The combination of a W boson and a b jet with the minimum invariant mass difference from the correct top quark mass is selected. Source code: CMS_2018_I1620050.cc 1#include "Rivet/Analysis.hh"
2#include "Rivet/Projections/FinalState.hh"
3#include "Rivet/Projections/FastJets.hh"
4#include "Rivet/Projections/PartonicTops.hh"
5#include "Rivet/Projections/LeptonFinder.hh"
6#include "Rivet/Projections/IdentifiedFinalState.hh"
7#include "Rivet/Projections/PromptFinalState.hh"
8#include "Rivet/Projections/VetoedFinalState.hh"
9
10namespace Rivet {
11
12
13 /// Normalized dilepton ttbar differential cross-sections in pp collisions at 13 TeV
14 class CMS_2018_I1620050 : public Analysis {
15 public:
16
17 RIVET_DEFAULT_ANALYSIS_CTOR(CMS_2018_I1620050);
18
19 void init() {
20
21 // Parton level top quark to analyze dilepton channels only
22 declare(PartonicTops(TopDecay::MUON, PromptEMuFromTau::NO), "PartonTopsToMuon"); // Partonic top decaying to mu
23 declare(PartonicTops(TopDecay::ELECTRON, PromptEMuFromTau::NO), "PartonTopsToElectron"); // Partonic top decaying to e
24
25 // Build particle level tops starting from FinalState
26 const FinalState fs(Cuts::pT > 0. && Cuts::abseta < 6.);
27
28 // Neutrinos
29 IdentifiedFinalState neutrinos(fs);
30 neutrinos.acceptNeutrinos();
31 PromptFinalState prompt_neutrinos(neutrinos, TauDecaysAs::PROMPT, MuDecaysAs::PROMPT);
32 declare(prompt_neutrinos, "Neutrinos");
33
34 // Projection for electrons and muons
35 Cut leptonCuts = Cuts::pt > 20*GeV && Cuts::abseta < 2.4;
36
37 PromptFinalState fsLepton(fs);
38 fsLepton.acceptMuonDecays(true);
39 fsLepton.acceptTauDecays(true);
40 SpecialLeptonFinder dressedLeptons(fsLepton, leptonCuts);
41 declare(dressedLeptons, "LeptonFinder");
42
43 // Projection for jets
44 VetoedFinalState fs_jets(fs);
45 fs_jets.addVetoOnThisFinalState(dressedLeptons);
46 fs_jets.vetoNeutrinos();
47 declare(FastJets(fs_jets, JetAlg::ANTIKT, 0.4), "ak4jets");
48
49 // Book hists
50 book(_hist_lep_pt, "d01-x01-y01");
51 book(_hist_jet_pt, "d02-x01-y01");
52 book(_hist_top_pt, "d03-x01-y01");
53 book(_hist_top_y, "d04-x01-y01");
54 book(_hist_tt_pt, "d05-x01-y01");
55 book(_hist_tt_y, "d06-x01-y01");
56 book(_hist_tt_m, "d07-x01-y01");
57 book(_hist_tt_dphi, "d08-x01-y01");
58 }
59
60
61 void analyze(const Event& event) {
62
63 // Do the analysis only for the full-dleptonic channel
64 const Particles partonTopsToMuon = apply<ParticleFinder>(event, "PartonTopsToMuon").particles();
65 //const Particles partonTopsToElectron = apply<ParticleFinder>(event, "PartonTopsToElectron").particles();
66 Particles partonTopsToElectron;
67 for (const Particle& x : apply<ParticleFinder>(event, "PartonTopsToElectron").particles() ) {
68 bool isDuplicated = false;
69 for (const Particle& y : partonTopsToMuon ) {
70 if ( std::abs(x.pt()-y.pt()) < 0.01 and deltaR(x, y) < 0.01 ) {
71 isDuplicated = true;
72 break;
73 }
74 }
75 if ( !isDuplicated ) partonTopsToElectron.push_back(x);
76 }
77 const int nPartonElectrons = partonTopsToElectron.size();
78 const int nPartonMuons = partonTopsToMuon.size();
79 if ( nPartonElectrons+nPartonMuons != 2 ) vetoEvent;
80
81 // Select leptons
82 const DressedLeptons& dressedLeptons = apply<SpecialLeptonFinder>(event, "LeptonFinder").dressedLeptons();
83 if ( dressedLeptons.size() < 2 ) vetoEvent;
84
85 const FourMomentum& lepton1 = dressedLeptons[0].momentum();
86 const FourMomentum& lepton2 = dressedLeptons[1].momentum();
87 const int channel = dressedLeptons[0].abspid() + dressedLeptons[1].abspid();
88 if ( !((channel == 22 and nPartonElectrons == 2) or
89 (channel == 24 and nPartonElectrons == 1 and nPartonMuons == 1) or
90 (channel == 26 and nPartonMuons == 2)) ) vetoEvent;
91
92 // Select neutrinos
93 const Particles neutrinos = apply<PromptFinalState>(event, "Neutrinos").particlesByPt();
94 if ( neutrinos.size() < 2 ) vetoEvent;
95
96 // Select bjets
97 const FastJets& fjJets = apply<FastJets>(event, "ak4jets");
98 const Jets jets = fjJets.jetsByPt(Cuts::abseta < 2.4 && Cuts::pT > 30*GeV);
99 const Jets bJets = select(jets, hasBTag());
100 // There should at least two b jets.
101 if ( bJets.size() < 2 ) vetoEvent;
102
103 // Construct particle level top
104 FourMomentum nu1 = neutrinos[0].momentum();
105 FourMomentum nu2 = neutrinos[1].momentum();
106 if ( std::abs((lepton1+nu1).mass()-80.4) + std::abs((lepton2+nu2).mass()-80.4) >
107 std::abs((lepton1+nu2).mass()-80.4) + std::abs((lepton2+nu1).mass()-80.4) ) {
108 std::swap(nu1, nu2);
109 }
110 const FourMomentum w1 = lepton1 + nu1;
111 const FourMomentum w2 = lepton2 + nu2;
112
113 FourMomentum bjet1 = bJets[0].momentum();
114 FourMomentum bjet2 = bJets[1].momentum();
115 if ( std::abs((w1+bjet1).mass()-172.5) + std::abs((w2+bjet2).mass()-172.5) >
116 std::abs((w1+bjet2).mass()-172.5) + std::abs((w2+bjet1).mass()-172.5) ) {
117 std::swap(bjet1, bjet2);
118 }
119 const FourMomentum t1 = w1 + bjet1;
120 const FourMomentum t2 = w2 + bjet2;
121 const FourMomentum tt = t1+t2;
122
123 _hist_lep_pt->fill(lepton1.pt());
124 _hist_lep_pt->fill(lepton2.pt());
125 _hist_jet_pt->fill(bjet1.pt());
126 _hist_jet_pt->fill(bjet2.pt());
127
128 _hist_top_pt->fill(t1.pt());
129 _hist_top_pt->fill(t2.pt());
130 _hist_top_y->fill(t1.rapidity());
131 _hist_top_y->fill(t2.rapidity());
132
133 _hist_tt_pt->fill(tt.pt());
134 _hist_tt_y->fill(tt.rapidity());
135 _hist_tt_m->fill(tt.mass());
136 _hist_tt_dphi->fill(deltaPhi(t1.phi(), t2.phi()));
137 }
138
139
140 /// Normalise histograms etc., after the run
141 void finalize() {
142 normalize(_hist_lep_pt);
143 normalize(_hist_jet_pt);
144 normalize(_hist_top_pt);
145 normalize(_hist_top_y);
146 normalize(_hist_tt_pt);
147 normalize(_hist_tt_y);
148 normalize(_hist_tt_m);
149 normalize(_hist_tt_dphi);
150 }
151
152
153 /// @brief Special dressed-lepton finder
154 ///
155 /// Find dressed leptons by clustering all leptons and photons
156 class SpecialLeptonFinder : public FinalState {
157 public:
158
159 /// The default constructor. May specify cuts
160 SpecialLeptonFinder(const FinalState& fs, const Cut& cut)
161 : FinalState(cut)
162 {
163 setName("SpecialLeptonFinder");
164 IdentifiedFinalState ifs(fs);
165 ifs.acceptIdPair(PID::PHOTON);
166 ifs.acceptIdPair(PID::ELECTRON);
167 ifs.acceptIdPair(PID::MUON);
168 declare(ifs, "IFS");
169 declare(FastJets(ifs, JetAlg::ANTIKT, 0.1), "LeptonJets");
170 }
171
172 /// Clone on the heap.
173 virtual unique_ptr<Projection> clone() const {
174 return unique_ptr<Projection>(new SpecialLeptonFinder(*this));
175 }
176
177 /// Import to avoid warnings about overload-hiding
178 using Projection::operator =;
179
180 /// Retrieve the dressed leptons
181 const DressedLeptons& dressedLeptons() const { return _clusteredLeptons; }
182
183 /// Perform the calculation
184 void project(const Event& e) {
185 _theParticles.clear();
186 _clusteredLeptons.clear();
187
188 DressedLeptons allClusteredLeptons;
189 const Jets jets = apply<FastJets>(e, "LeptonJets").jetsByPt(Cuts::pT > 5*GeV);
190 for (const Jet& jet : jets) {
191 Particle lepCand;
192 for (const Particle& cand : jet.particles()) {
193 const int absPdgId = cand.abspid();
194 if (absPdgId == PID::ELECTRON || absPdgId == PID::MUON) {
195 if (cand.pt() > lepCand.pt()) lepCand = cand;
196 }
197 }
198
199 if (!lepCand.isChargedLepton()) continue;
200
201 DressedLepton lepton = DressedLepton(lepCand);
202 for (const Particle& cand : jet.particles()) {
203 if (isSame(cand, lepCand)) continue;
204 lepton.addConstituent(cand, true);
205 }
206 allClusteredLeptons.push_back(lepton);
207 }
208
209 for (const DressedLepton& lepton : allClusteredLeptons) {
210 if (accept(lepton)) {
211 _clusteredLeptons.push_back(lepton);
212 _theParticles.push_back(lepton.bareLepton());
213 _theParticles += lepton.photons();
214 }
215 }
216 }
217 private:
218
219 /// Container which stores the clustered lepton objects
220 DressedLeptons _clusteredLeptons;
221
222 };
223
224 private:
225
226 Histo1DPtr _hist_lep_pt;
227 Histo1DPtr _hist_jet_pt;
228 Histo1DPtr _hist_top_pt;
229 Histo1DPtr _hist_top_y;
230 Histo1DPtr _hist_tt_pt;
231 Histo1DPtr _hist_tt_y;
232 Histo1DPtr _hist_tt_m;
233 Histo1DPtr _hist_tt_dphi;
234
235 };
236
237
238 RIVET_DECLARE_PLUGIN(CMS_2018_I1620050);
239
240}
|