rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

CMS_2018_I1620050

Measurement of normalized differential ttbar cross sections in the dilepton channel from pp collisions at 13 TeV
Experiment: CMS (LHC)
Inspire ID: 1620050
Status: VALIDATED
Authors:
  • Youn Jung Roh
  • Suyong Choi
  • Junghwan Goh
  • Dajeong Jeon
  • Jason S. H. Lee
References:
  • JHEP 1804 (2018) 060
  • DOI:10.1007/JHEP04(2018)060
  • arXiv: 1708.07638
  • https://www.hepdata.net/record/81686
  • Public page: CMS-TOP-16-007
Beams: p+ p+
Beam energies: (6500.0, 6500.0) GeV
Run details:
  • pp QCD interactions at $\sqrt{s} = 13$ TeV. Data collected by CMS during the year 2015. Selection of dilepton top pair candidate events at particle level.

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}