rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

ATLAS_2017_I1645627

Isolated photon + jets at 13 TeV
Experiment: ATLAS (LHC)
Inspire ID: 1645627
Status: VALIDATED
Authors:
  • Ana Rosario Cueto Gomez
  • Christian Gutschow
References: Beams: p+ p+
Beam energies: (6500.0, 6500.0) GeV
Run details:
  • prompt photon + jets

The dynamics of isolated-photon production in association with a jet in proton--proton collisions at a centre-of-mass energy of 13 TeV are studied with the ATLAS detector at the LHC using a dataset with an integrated luminosity of 3.2 fb${}^{-1}$. Photons are required to have transverse energies above 125 GeV. Jets are identified using the anti-$k_\text{t}$ algorithm with radius parameter $R=0.4$ and required to have transverse momenta above 100 GeV. Measurements of isolated-photon plus jet cross sections are presented as functions of the leading-photon transverse energy, the leading-jet transverse momentum, the azimuthal angular separation between the photon and the jet, the photon--jet invariant mass and the scattering angle in the photonjet centre-of-mass system. Tree-level plus parton-shower predictions from Sherpa and Pythia as well as next-to-leading-order QCD predictions from Jetphox and Sherpa are compared to the measurements.

Source code: ATLAS_2017_I1645627.cc
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/VisibleFinalState.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
#include "Rivet/Projections/PromptFinalState.hh"
#include "Rivet/Projections/FastJets.hh"

namespace Rivet {


  /// @brief Isolated photon + jets at 13 TeV
  class ATLAS_2017_I1645627 : public Analysis {
  public:

    // Constructor
    DEFAULT_RIVET_ANALYSIS_CTOR(ATLAS_2017_I1645627);

    // Book histograms and initialise projections before the run
    void init() {
      const FinalState fs;

      // calorimeter particles
      VisibleFinalState visFS(fs);
      VetoedFinalState calo_fs(visFS);
      calo_fs.addVetoPairId(PID::MUON);
      declare(calo_fs, "calo");

      // Voronoi eta-phi tessellation with KT jets, for ambient energy density calculation
      FastJets fj(fs, FastJets::KT, 0.5, JetAlg::NO_MUONS, JetAlg::NO_INVISIBLES); // E-scheme used by default;
      fj.useJetArea(new fastjet::AreaDefinition(fastjet::voronoi_area, fastjet::VoronoiAreaSpec(1.0)));
      declare(fj, "KtJetsD05");

      // photon
      PromptFinalState photonfs(Cuts::abspid == PID::PHOTON && Cuts::abseta < 2.37 && Cuts::pT > 125*GeV);
      declare(photonfs, "photons");

      // Jets
      FastJets jetpro(fs, FastJets::ANTIKT, 0.4, JetAlg::NO_MUONS, JetAlg::NO_INVISIBLES);
      declare(jetpro, "Jets");
      
      _h_photon_pt      = bookHisto1D(1, 1, 1);
      _h_jet_pt         = bookHisto1D(2, 1, 1);
      _h_phjet_dphi     = bookHisto1D(3, 1, 1);
      _h_phjet_mass     = bookHisto1D(4, 1, 1);
      _h_phjet_costheta = bookHisto1D(5, 1, 1);

    }


     size_t getEtaBin(double eta) const {
      const double abseta = fabs(eta);
      return binIndex(abseta, _eta_bins_areaoffset);
    }
    

    // Perform the per-event analysis
    void analyze(const Event& event) {

      const double weight = event.weight();
      
      // Get the photon
      const Particles& photons = apply<PromptFinalState>(event, "photons").particlesByPt(Cuts::abseta < 1.37 || Cuts::abseta > 1.56);
      if (photons.empty())  vetoEvent;
      const FourMomentum photon = photons[0].momentum();

      // Get the jet
      Jets jets = apply<FastJets>(event, "Jets").jetsByPt(Cuts::pT > 100*GeV && Cuts::absrap < 2.37);
      ifilter_discard(jets, deltaRLess(photon, 0.8));
      if (jets.empty())  vetoEvent;
      FourMomentum leadingJet = jets[0].momentum();
    
      // Compute the jet pT densities
      vector< vector<double> > ptDensities(_eta_bins_areaoffset.size()-1);
      FastJets fastjets = apply<FastJets>(event, "KtJetsD05");
      const auto clust_seq_area = fastjets.clusterSeqArea();
      for (const Jet& jet : fastjets.jets()) {
        const double area = clust_seq_area->area(jet); // Implicit call to pseudojet(). 	
        //const double area2 = (clust_seq_area->area_4vector(jet)).perp(); // Area definition used in egammaTruthParticles. 
        if (area > 1e-3 && jet.abseta() < _eta_bins_areaoffset.back()) {
          ptDensities.at(getEtaBin(jet.abseta())) += jet.pT()/area;
        }
      }

      // Compute the median event energy density
      vector<double> ptDensity;
      for (size_t b = 0; b < _eta_bins_areaoffset.size()-1; ++b) {
        ptDensity += ptDensities[b].empty() ? 0 : median(ptDensities[b]);
      }

      // Compute photon isolation with a standard ET cone
      FourMomentum mom_in_EtCone;
      const Particles calo_fs = apply<VetoedFinalState>(event, "calo").particles();
      const double iso_dr = 0.4;
      for (const Particle& p : calo_fs) {
        // Check if it's in the cone of .4
        if (sqrt(2.0*(cosh(p.eta()-photon.eta()) - cos(p.phi()-photon.phi()))) >= iso_dr) continue;
        // Increment sum
        mom_in_EtCone += p.momentum();
      }
      
      // Remove the photon energy from the isolation
      mom_in_EtCone -= photon;

      // Figure out the correction (area*density)
      const double etcone_area = PI*iso_dr*iso_dr;
      const double correction = ptDensity[getEtaBin(photon.abseta())] * etcone_area;
      // Require photon to be isolated
      if ((mom_in_EtCone.Et()-correction) > (0.0042*photon.pT() + 10*GeV))  vetoEvent;
      
      // Fill histos
      const double photon_pt = photon.pT()/GeV;
      const double jet_pt = leadingJet.pT()/GeV;
      const double phjet_dphi = deltaPhi(photon, leadingJet);
      const double photon_eta = photon.eta();
      const double jet_y = leadingJet.rapidity();
      _h_photon_pt->fill(photon_pt, weight);
      _h_jet_pt->fill(jet_pt, weight);
      _h_phjet_dphi->fill(phjet_dphi, weight);

      double dy = fabs(jet_y-photon_eta);
      double phjet_costheta = tanh(dy/2.);
      double phjet_mass= (photon+leadingJet).mass()/GeV;
      if (phjet_mass <= 450.)  vetoEvent;
      if (fabs(photon_eta + jet_y) >= 2.37)  vetoEvent;
      if (phjet_costheta >= 0.83)  vetoEvent;
      _h_phjet_costheta->fill(phjet_costheta, weight);
      _h_phjet_mass->fill(phjet_mass, weight);
    }


    /// Normalise histograms etc., after the run
    void finalize() {
      const double sf = crossSection() / sumOfWeights();
      scale(_h_photon_pt, sf);
      scale(_h_jet_pt, sf);
      scale(_h_phjet_dphi, sf);
      scale(_h_phjet_mass, sf);
      scale(_h_phjet_costheta, sf);
    }


  private:

    Histo1DPtr _h_photon_pt, _h_jet_pt;
    Histo1DPtr _h_phjet_dphi, _h_phjet_mass, _h_phjet_costheta;

    const vector<double> _eta_bins_areaoffset = {0.0, 1.5, 3.0, 4.0, 5.0};

  };

  // The hook for the plugin system
  DECLARE_RIVET_PLUGIN(ATLAS_2017_I1645627);
}