rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

ATLAS_2017_I1604029

ttbar + gamma at 8 TeV
Experiment: ATLAS (LHC)
Inspire ID: 1604029
Status: VALIDATED
Authors:
  • Yichen Li
  • Christian Gutschow
References: Beams: p+ p+
Beam energies: (4000.0, 4000.0) GeV
Run details:
  • non-allhadronic top-quark pair production associated with a photon

The cross section of a top-quark pair produced in association with a photon is measured in proton-proton collisions at a centre-of-mass energy of $\sqrt{s} = 8$ TeV with 20.2 fb${}^{-1}$ of data collected by the ATLAS detector at the Large Hadron Collider in 2012. The measurement is performed by selecting events that contain a photon with transverse momentum $p_\text{T} > 15$ GeV, an isolated lepton with large transverse momentum, large missing transverse momentum, and at least four jets, where at least one is identified as originating from a $b$-quark. The production cross section is measured in a fiducial region close to the selection requirements. It is found to be $139 \pm 7$ (stat.) $\pm 17$ (syst.) fb, in good agreement with the theoretical prediction at next-to-leading order of $151 \pm 24$ fb. In addition, differential cross sections in the fiducial region are measured as a function of the transverse momentum and pseudorapidity of the photon.

Source code: ATLAS_2017_I1604029.cc
  1// -*- C++ -*-
  2#include "Rivet/Analysis.hh"
  3#include "Rivet/Projections/FastJets.hh"
  4#include "Rivet/Projections/FinalState.hh"
  5#include "Rivet/Projections/LeptonFinder.hh"
  6#include "Rivet/Projections/PromptFinalState.hh"
  7#include "Rivet/Projections/UnstableParticles.hh"
  8
  9namespace Rivet {
 10
 11
 12  /// @brief ttbar + gamma at 8 TeV
 13  class ATLAS_2017_I1604029 : public Analysis {
 14  public:
 15
 16    // Constructor
 17    RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2017_I1604029);
 18
 19    // Book histograms and initialise projections before the run
 20    void init() {
 21
 22      const FinalState fs;
 23
 24      // signal photons
 25      PromptFinalState prompt_ph(Cuts::abspid == PID::PHOTON && Cuts::pT > 15*GeV && Cuts::abseta < 2.37);
 26      declare(prompt_ph, "photons");
 27
 28      // bare leptons
 29      Cut base_cuts = (Cuts::abseta < 2.7) && (Cuts::pT > 10*GeV);
 30      IdentifiedFinalState bare_leps(base_cuts);
 31      bare_leps.acceptIdPair(PID::MUON);
 32      bare_leps.acceptIdPair(PID::ELECTRON);
 33      declare(bare_leps, "bare_leptons");
 34
 35      // dressed leptons
 36      Cut dressed_cuts = (Cuts::abseta < 2.5) && (Cuts::pT > 25*GeV);
 37      PromptFinalState prompt_mu(base_cuts && Cuts::abspid == PID::MUON);
 38      PromptFinalState prompt_el(base_cuts && Cuts::abspid == PID::ELECTRON);
 39      IdentifiedFinalState all_photons(fs, PID::PHOTON);
 40      LeptonFinder elecs(prompt_el, all_photons, 0.1, dressed_cuts);
 41      declare(elecs, "elecs");
 42      LeptonFinder muons(prompt_mu, all_photons, 0.1, dressed_cuts);
 43      declare(muons, "muons");
 44
 45      // auxiliary projections for 'single-lepton ttbar filter'
 46      PromptFinalState prompt_lep(Cuts::abspid == PID::MUON || Cuts::abspid == PID::ELECTRON);
 47      declare(prompt_lep, "prompt_leps");
 48      declare(UnstableParticles(), "ufs");
 49
 50      // jets
 51      FastJets jets(fs, JetAlg::ANTIKT, 0.4, JetMuons::NONE, JetInvisibles::NONE);
 52      declare(jets, "jets");
 53
 54
 55      // BOOK HISTOGRAMS
 56      book(_h["pt"],  2,1,1);
 57      book(_h["eta"], 3,1,1);
 58
 59    }
 60
 61
 62    // Perform the per-event analysis
 63    void analyze(const Event& event) {
 64
 65      // analysis extrapolated to 1-lepton-plus-jets channel, where "lepton" cannot be a tau
 66      // (i.e. contribution from dileptonic ttbar where one of the leptons is outside
 67      // the detector acceptance has been subtracted as a background)
 68      if (apply<PromptFinalState>(event, "prompt_leps").particles().size() != 1)  vetoEvent;
 69      for (const auto& p : apply<UnstableParticles>(event, "ufs").particles()) {
 70        if (p.fromPromptTau())  vetoEvent;
 71      }
 72
 73      // photon selection
 74      Particles photons = apply<PromptFinalState>(event, "photons").particlesByPt();
 75      Particles bare_leps  = apply<IdentifiedFinalState>(event, "bare_leptons").particles();
 76      for (const Particle& lep : bare_leps)
 77        idiscard(photons, deltaRLess(lep, 0.1));
 78      if (photons.size() != 1)  vetoEvent;
 79      const Particle& photon = photons[0];
 80
 81      // jet selection
 82      Jets jets = apply<JetFinder>(event, "jets").jetsByPt(Cuts::abseta < 2.5 && Cuts::pT > 25*GeV);
 83
 84      // lepton selection
 85      const DressedLeptons& elecs = apply<LeptonFinder>(event, "elecs").dressedLeptons();
 86      const DressedLeptons& all_muons = apply<LeptonFinder>(event, "muons").dressedLeptons();
 87
 88      // jet photon/electron overlap removal
 89      for (const DressedLepton& e : elecs)
 90        idiscard(jets, deltaRLess(e, 0.2, RAPIDITY));
 91      for (const Particle& ph : photons)
 92        idiscard(jets, deltaRLess(ph, 0.1, RAPIDITY));
 93	    if (jets.size() < 4)  vetoEvent;
 94
 95      // photon-jet minimum deltaR
 96      double mindR_phjet = 999.;
 97      for (Jet jet : jets) {
 98        const double dR_phjet = deltaR(photon, jet);
 99        if (dR_phjet < mindR_phjet) mindR_phjet = dR_phjet;
100      }
101      if (mindR_phjet < 0.5)  vetoEvent;
102
103      // muon jet overlap removal
104      DressedLeptons muons;
105      for (const DressedLepton& mu : all_muons) {
106        bool overlaps = false;
107        for (const Jet& jet : jets) {
108          if (deltaR(mu, jet) < 0.4) {
109            overlaps = true;
110            break;
111          }
112        }
113        if (overlaps) continue;
114        muons.push_back(mu);
115      }
116
117      // one electron XOR one muon
118      bool isEl = elecs.size() == 1 && muons.size() == 0;
119      bool isMu = muons.size() == 1 && elecs.size() == 0;
120      if (!isEl && !isMu)  vetoEvent;
121
122      // photon-lepton deltaR
123      double mindR_phlep = deltaR(photon, isEl? elecs[0] : muons[0]);
124      if (mindR_phlep < 0.7)  vetoEvent;
125
126      // b-tagging
127      Jets bjets;
128      for (const Jet& jet : jets) {
129        if (jet.bTagged(Cuts::pT > 5*GeV)) bjets +=jet;
130      }
131      if (bjets.empty())  vetoEvent;
132
133      _h["pt"]->fill(photon.pT()/GeV);
134      _h["eta"]->fill(photon.abseta());
135    }
136
137
138    // Normalise histograms etc., after the run
139    void finalize() {
140      const double normto(crossSection() / femtobarn / sumOfWeights());
141      for (auto &hist : _h) {  scale(hist.second, normto);  }
142    }
143
144
145  private:
146
147    map<string, Histo1DPtr> _h;
148
149  };
150
151  RIVET_DECLARE_PLUGIN(ATLAS_2017_I1604029);
152}