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 setName("CMS_2018_I1620050::SpecialLeptonFinder");
163 IdentifiedFinalState ifs(fs);
164 ifs.acceptIdPair(PID::PHOTON);
165 ifs.acceptIdPair(PID::ELECTRON);
166 ifs.acceptIdPair(PID::MUON);
167 declare(FastJets(ifs, JetAlg::ANTIKT, 0.1), "LeptonJets");
168 }
169
170 /// Clone on the heap
171 RIVET_DEFAULT_PROJ_CLONE(SpecialLeptonFinder);
172
173 /// Import to avoid warnings about overload-hiding
174 using Projection::operator =;
175
176 /// Retrieve the dressed leptons
177 const DressedLeptons& dressedLeptons() const { return _clusteredLeptons; }
178
179 /// Compare projections
180 CmpState compare(const Projection& p) const {
181 const PCmp fscmp = mkNamedPCmp(p, "LeptonJets");
182 if (fscmp != CmpState::EQ) return fscmp;
183 const SpecialLeptonFinder& other = dynamic_cast<const SpecialLeptonFinder&>(p);
184 const bool cutcmp = _cuts == other._cuts;
185 if (!cutcmp) return CmpState::NEQ;
186 return CmpState::EQ;
187 }
188
189 /// Perform the calculation
190 void project(const Event& e) {
191 _theParticles.clear();
192 _clusteredLeptons.clear();
193
194 DressedLeptons allClusteredLeptons;
195 const Jets jets = apply<FastJets>(e, "LeptonJets").jetsByPt(Cuts::pT > 5*GeV);
196 for (const Jet& jet : jets) {
197 Particle lepCand;
198 for (const Particle& cand : jet.particles()) {
199 const int absPdgId = cand.abspid();
200 if (absPdgId == PID::ELECTRON || absPdgId == PID::MUON) {
201 if (cand.pt() > lepCand.pt()) lepCand = cand;
202 }
203 }
204
205 if (!lepCand.isChargedLepton()) continue;
206
207 DressedLepton lepton = DressedLepton(lepCand);
208 for (const Particle& cand : jet.particles()) {
209 if (isSame(cand, lepCand)) continue;
210 lepton.addConstituent(cand, true);
211 }
212 allClusteredLeptons.push_back(lepton);
213 }
214
215 for (const DressedLepton& lepton : allClusteredLeptons) {
216 if (_cuts->accept(static_cast<const Particle&>(lepton))) {
217 _clusteredLeptons.push_back(lepton);
218 _theParticles.push_back(lepton.bareLepton());
219 _theParticles += lepton.photons();
220 }
221 }
222 }
223
224 protected:
225
226 /// Container which stores the clustered lepton objects
227 DressedLeptons _clusteredLeptons;
228
229 };
230
231 private:
232
233 Histo1DPtr _hist_lep_pt;
234 Histo1DPtr _hist_jet_pt;
235 Histo1DPtr _hist_top_pt;
236 Histo1DPtr _hist_top_y;
237 Histo1DPtr _hist_tt_pt;
238 Histo1DPtr _hist_tt_y;
239 Histo1DPtr _hist_tt_m;
240 Histo1DPtr _hist_tt_dphi;
241
242 };
243
244
245 RIVET_DECLARE_PLUGIN(CMS_2018_I1620050);
246
247}
|