Rivet analyses
Measurement of isolated prompt photon production in pp and pPb collisions at the LHC
Experiment: ALICE (LHC)
Inspire ID: 2895564
Status: VALIDATED
Authors: - Alexander Puck Neuwirth
References: - Eur.Phys.J.C 85 (2025) 12, 1407 - arXiv: 2502.18054 - Expt page: ALICE-11890
Beams: p+ p+, 1000822080 p+, 1000822080 p+
Beam energies: (4000.0, 4000.0); (328000.0, 4000.0); (533000.0, 6500.0)GeV
Run details: - Inclusive photon+X events at $\sqrt{s} = 5.02$~TeV, 8~TeV and, 8.16~TeV at low transverse momentum.
The measurement is performed in pPb collisions at centre-of-mass energies per nucleon pair of $\sqrt{s_{\text{NN}}}=5.02$~TeV and 8.16~TeV, as well as in pp collisions at $\sqrt{s}=5.02$~TeV and 8~TeV. The cross section is obtained at midrapidity (|y| < 0.7) using a charged-track based isolation momentum $p_{\rm T}^{\text{iso,~ch}}<1.5$~GeV/c in a cone with radius R = 0.4.
Source
code:ALICE_2025_I2895564.cc
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
#include "Rivet/Projections/PromptFinalState.hh"
namespace Rivet {
/// @brief Measurement of the inclusive isolated photon production cross section in pp and pPb collisions
class ALICE_2025_I2895564: public Analysis {
public:
/// Constructor
RIVET_DEFAULT_ANALYSIS_CTOR(ALICE_2025_I2895564);
/// @name Analysis methods
/// @{
/// Book histograms and initialise projections before the run
void init() {
// This option exists because JetPhox can not do isolation on charged particles only
_iso_charged = getOption("ISO_CHARGED", true);
_iso_et_cut = _iso_charged ? _iso_et_cut_charged : _iso_et_cut_all;
if (!_iso_charged) MSG_WARNING("LIMITED VALIDITY - measured data was obtained for ISO_CHARGED=true case only.");
const FinalState fs;
// calorimeter particles
VisibleFinalState visFS(fs);
VetoedFinalState calo_fs(visFS);
declare(calo_fs, "calo");
// photon
PromptFinalState photonfs(Cuts::abspid == PID::PHOTON && Cuts::abseta < _abseta);
declare(photonfs, "photons");
// Book histograms
// specify custom binning
// take binning from reference data using HEPData ID (digits in "d01-x01-y01" etc.)
book(_h["pp_8_p_t"], 1, 1, 1);
book(_h["pPb_8_16_p_t"], 2, 1, 1);
book(_h["pPb_5_02_p_t"], 3, 1, 1);
}
/// Perform the per-event analysis
void analyze(const Event& event) {
// Get the photon
const Particles& photons = apply<PromptFinalState>(event, "photons").particlesByPt();
if (photons.empty()) vetoEvent;
// We only look at the hardest/leading photon
const FourMomentum photon = photons[0].momentum();
// Compute photon isolation with a standard ET cone
double mom_in_EtCone = 0.0;
const Particles calo_fs = apply<VetoedFinalState>(event, "calo").particles();
for (const Particle& p : calo_fs) {
// Possibly skip non-charged particles
if (_iso_charged && !p.isCharged()) continue;
// Check if it's in the cone of .4
if (deltaR(p, photon) >= _iso_dr) continue;
// Increment sum
mom_in_EtCone += p.momentum().pT();
}
// photon itself is not charged, so only remove it if we consider all particles
if (!_iso_charged) {
// Remove the photon energy from the isolation
mom_in_EtCone -= photon.pT();
}
if (mom_in_EtCone > _iso_et_cut) vetoEvent;
if (beamsMatch(PID::PROTON, PID::PROTON,4000*GeV,4000*GeV)) {
_h["pp_8_p_t"]->fill(photon.pT()/GeV);
} else if (beamsMatch(PID::LEAD, PID::PROTON,533000*GeV,6500*GeV)) {
_h["pPb_8_16_p_t"]->fill(photon.pT()/GeV);
} else if (beamsMatch(PID::LEAD, PID::PROTON,328000*GeV,4000*GeV)) {
_h["pPb_5_02_p_t"]->fill(photon.pT()/GeV);
}
}
/// Normalise histograms etc., after the run
void finalize() {
scale(_h, crossSection()/nanobarn/sumOfWeights() / (2* _abseta)); // also divide by |eta| range
}
/// @}
// Analysis parameters
bool _iso_charged = true;
const double _abseta = 0.7;
const double _iso_dr = 0.4;
double _iso_et_cut;
const double _iso_et_cut_charged = 1.5*GeV;
const double _iso_et_cut_all = 2.0*GeV;
/// @name Histograms
/// @{
map<string, Histo1DPtr> _h;
/// @}
};
RIVET_DECLARE_PLUGIN(ALICE_2025_I2895564);
}