rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

ATLAS_2019_I1746286

K-short and Lambda production in ttbar events at 7 TeV
Experiment: ATLAS (LHC)
Inspire ID: 1746286
Status: VALIDATED
Authors:
  • Sergio Calvente
  • Fernando Barreiro
  • Javier LLorente
References: Beams: p+ p+
Beam energies: (3500.0, 3500.0) GeV
Run details:
  • ttbar production at 7 TeV, c*tau>10mm is stable

Measurements of $K^0_S$ and $\Lambda^0$ production in $t\bar{t}$ final states have been performed. They are based on a data sample with integrated luminosity of 4.6 fb$^{-1}$ from proton-proton collisions at a centre-of-mass energy of 7 TeV, collected in 2011 with the ATLAS detector at the Large Hadron Collider. Neutral strange particles are separated into three classes, depending on whether they are contained in a jet, with or without a $b$-tag, or not associated with a selected jet. The aim is to look for differences in their main kinematic distributions. A comparison of data with several Monte Carlo simulations using different hadronisation and fragmentation schemes, colour reconnection models and different tunes for the underlying event has been made. The production of neutral strange particles in $t\bar{t}$ dileptonic events is found to be well described by current Monte Carlo models for $K^0_S$ ans $\Lambda^0$ production within jets, but not for those produced outside jets.

Source code: ATLAS_2019_I1746286.cc
  1// -*- C++ -*-
  2#include "Rivet/Analysis.hh"
  3#include "Rivet/Projections/FinalState.hh"
  4#include "Rivet/Projections/UnstableParticles.hh"
  5#include "Rivet/Projections/FastJets.hh"
  6#include "Rivet/Projections/HeavyHadrons.hh"
  7
  8namespace Rivet {
  9
 10
 11  class ATLAS_2019_I1746286 : public Analysis {
 12  public:
 13
 14    /// Constructor
 15    RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2019_I1746286);
 16
 17    /// Book histograms and initialise projections before the run
 18    void init() {
 19      // Set up projections
 20      const FinalState fs(Cuts::abseta < 4.5);
 21
 22      /// Get electrons from truth record
 23      FinalState elec_fs(Cuts::abspid == PID::ELECTRON && Cuts::abseta < 2.47 && Cuts::pT > 25*GeV);
 24      declare(elec_fs, "ELEC_FS");
 25
 26      /// Get muons which pass the initial kinematic cuts:
 27      FinalState muon_fs(Cuts::abspid == PID::MUON && Cuts::abseta < 2.5 && Cuts::pT > 20*GeV);
 28      declare(muon_fs, "MUON_FS");
 29
 30      // get b-hadrons
 31      declare(HeavyHadrons(Cuts::pT > 5*GeV), "BHadrons");
 32
 33      UnstableParticles k0_fs(Cuts::abspid == PID::K0S && Cuts::abseta < 2.5 && Cuts::E > 1*GeV);
 34      declare(k0_fs, "K0_FS");
 35
 36      UnstableParticles lambda_fs(Cuts::abspid == PID::LAMBDA && Cuts::abseta < 2.5 && Cuts::E > 1*GeV);
 37      declare(lambda_fs, "LAMBDA_FS");
 38
 39      // Final state used as input for jet-finding.
 40      // We include everything except the muons and neutrinos
 41      FastJets jets(fs, FastJets::ANTIKT, 0.4, JetAlg::Muons::NONE, JetAlg::Invisibles::NONE);
 42      declare(jets, "JETS");
 43
 44      // Book histograms
 45      book(_h["b_k0_pt"],  1, 1, 1);
 46      book(_h["b_k0_x"],   2, 1, 1);
 47      book(_h["b_k0_e"],   3, 1, 1);
 48      book(_h["b_k0_eta"], 4, 1, 1);
 49      book(_h["b_k0_n"],   5, 1, 1);
 50
 51      book(_h["j_k0_pt"],  6, 1, 1);
 52      book(_h["j_k0_x"],   7, 1, 1);
 53      book(_h["j_k0_e"],   8, 1, 1);
 54      book(_h["j_k0_eta"], 9, 1, 1);
 55      book(_h["j_k0_n"],  10, 1, 1);
 56
 57      book(_h["out_k0_pt"],  11, 1, 1);
 58      book(_h["out_k0_e"],   12, 1, 1);
 59      book(_h["out_k0_eta"], 13, 1, 1);
 60      book(_h["out_k0_n"],   14, 1, 1);
 61
 62      book(_h["all_k0_pt"],  15, 1, 1);
 63      book(_h["all_k0_e"],   16, 1, 1);
 64      book(_h["all_k0_eta"], 17, 1, 1);
 65      book(_h["all_k0_n"],   18, 1, 1);
 66
 67      book(_h["all_l_pt"],  19, 1, 1);
 68      book(_h["all_l_e"],   20, 1, 1);
 69      book(_h["all_l_eta"], 21, 1, 1);
 70
 71    }
 72
 73
 74    /// Perform the per-event analysis
 75    void analyze(const Event& event) {
 76
 77      /// Get the various sets of final state particles
 78      const Particles& elecFS = apply<FinalState>(event, "ELEC_FS").particlesByPt();
 79      const Particles& muonFS = apply<FinalState>(event, "MUON_FS").particlesByPt();
 80      const Particles& k0FS = apply<UnstableParticles>(event, "K0_FS").particlesByPt();
 81      const Particles& lambdaFS = apply<UnstableParticles>(event, "LAMBDA_FS").particlesByPt();
 82
 83      // Get all jets with pT > 7 GeV (ATLAS standard jet collection)
 84      Jets jets = apply<FastJets>(event, "JETS").jetsByPt(7*GeV);
 85
 86      // Keep any jets that pass the pt cut
 87      Jets good_jets = filter_select(jets, Cuts::pT > 25*GeV && Cuts::abseta < 2.5);
 88
 89      // Remove jets too close to an electron
 90      idiscardIfAnyDeltaRLess(good_jets, elecFS, 0.2);
 91
 92      // Classify the event type
 93      const size_t nElec = elecFS.size();
 94      const size_t nMuon = muonFS.size();
 95      bool isDilepton = false;
 96      if (nElec == 2 && nMuon == 0) {
 97        if (charge(elecFS[0]) != charge(elecFS[1])) isDilepton = true;
 98      } else if (nElec == 1 && nMuon == 1) {
 99        if (charge(elecFS[0]) != charge(muonFS[0])) isDilepton = true;
100      } else if (nElec == 0 && nMuon == 2) {
101        if (charge(muonFS[0]) != charge(muonFS[1])) isDilepton = true;
102      }
103      const bool isGoodEvent = (isDilepton && good_jets.size() >= 2);
104      if (!isGoodEvent) vetoEvent;
105
106      // Select b-hadrons
107      const Particles& bHadrons = apply<HeavyHadrons>(event, "BHadrons").bHadrons();
108
109      // Select b-jets as those containing a b-hadron
110      Jets bjets = discardIfAnyDeltaRLess(good_jets, bHadrons, 0.3);
111
112      size_t n_k0_all = 0;
113      size_t n_k0_out = 0;
114      size_t n_k0_b = 0;
115      size_t n_k0_j = 0;
116
117      size_t n_k0_all_visible = 0;
118      size_t n_k0_out_visible = 0;
119      size_t n_k0_b_visible = 0;
120      size_t n_k0_j_visible = 0;
121
122      bool isVisible = false;
123      // Loop over all K0s particles
124      for (const Particle& k : k0FS) {
125        if (k.hasStableDescendantWith(Cuts::pid == PID::PIPLUS)) isVisible = true;
126
127        n_k0_all += 1;
128        if (isVisible) n_k0_all_visible += 1;
129        _h["all_k0_pt"]->fill(k.pT()/GeV);
130        _h["all_k0_eta"]->fill(k.abseta());
131        _h["all_k0_e"]->fill(k.E()/GeV);
132
133        bool isJetAssoc = false, isBjet = false;
134        double minDeltaR = 1000., jetAssocE = 0.;
135
136        for (const Jet& j : good_jets) {
137          const double k0_jetdR = deltaR(j, k);
138          if (k0_jetdR < 0.4 && k0_jetdR < minDeltaR) { 
139            isJetAssoc = true;
140            minDeltaR = k0_jetdR;
141            jetAssocE = j.E();
142            isBjet = any(bHadrons, DeltaRLess(j, 0.3));
143          }
144        }
145
146        // K0s not associated to jets
147        if (!isJetAssoc){
148          n_k0_out += 1;
149          if(isVisible) n_k0_out_visible += 1;
150          _h["out_k0_pt"]->fill(k.pT()/GeV);
151          _h["out_k0_eta"]->fill(k.abseta());
152          _h["out_k0_e"]->fill(k.E()/GeV);
153        }
154
155        //K0s associated to b-jets
156        if(isJetAssoc && isBjet){
157          n_k0_b += 1;
158          if(isVisible) n_k0_b_visible += 1;
159          _h["b_k0_pt"]->fill(k.pT()/GeV);
160          _h["b_k0_eta"]->fill(k.abseta());
161          _h["b_k0_e"]->fill(k.E()/GeV);
162          _h["b_k0_x"]->fill(k.E()/jetAssocE);
163        }
164
165        //K0s associated to non b-jets
166        if(isJetAssoc && !isBjet){
167          n_k0_j += 1;
168          if(isVisible) n_k0_j_visible += 1;
169          _h["j_k0_pt"]->fill(k.pT()/GeV);
170          _h["j_k0_eta"]->fill(k.abseta());
171          _h["j_k0_e"]->fill(k.E()/GeV);
172          _h["j_k0_x"]->fill(k.E()/jetAssocE);
173        }
174      }
175
176
177      // K0s multiplicities
178      _h["all_k0_n"]->fill(n_k0_all_visible);
179      _h["out_k0_n"]->fill(n_k0_out_visible);
180      _h["b_k0_n"]->fill(n_k0_b_visible);
181      _h["j_k0_n"]->fill(n_k0_j_visible);
182    
183
184      // Loop over all Lambda particles
185      //size_t n_lambda_all = 0;
186      for(const Particle& l : lambdaFS) {
187        //n_lambda_all += 1;
188        _h["all_l_pt"]->fill(l.pT()/GeV);
189        _h["all_l_eta"]->fill(l.abseta());
190        _h["all_l_e"]->fill(l.E()/GeV);
191      }
192    }
193
194
195    // Histogram normalization to the number of events passing the cuts
196    void finalize(){
197      const double sf = 1.0 / _h["all_k0_n"]->sumW();
198      for (auto& hist : _h) { scale(hist.second, sf); }
199    }
200
201  private:
202
203    // Counters
204    map<string, Histo1DPtr> _h;
205
206  };
207
208  // The hook for the plugin system
209  RIVET_DECLARE_PLUGIN(ATLAS_2019_I1746286);
210}