Rivet analyses
title: ALICE_2015_I1395253
Pseudorapidity and transverse-momentum distributions of charged particles in pp collisions at $\sqrt{s} = 13$ TeV
Experiment: ALICE (LHC)
Inspire ID: 1395253
Status: VALIDATED
Authors: - Awais Ahmed
References: - Phys.Lett.B753(2016)319-329 - DOI:10.1016/j.physletb.2015.12.030 - arXiv: 1509.08734
Beams: p+ p+
Beam energies: (6500.0, 6500.0)GeV
Run details: - Measurement of $\mathrm{d}N_{\mathrm{ch}}/\mathrm{d}\eta$ ($|\eta| < 1.8$) and invariant $p_{\mathrm{T}}$ spectra ($|\eta| < 0.8$, $0.15 < p_{\mathrm{T}} < 20$ GeV/$c$) in INEL and INEL${>}0$ pp collisions at $\sqrt{s} = 13$ TeV.
The pseudorapidity ($\eta$) and transverse-momentum ($p_\text{T}$) distributions of charged particles produced in proton-proton collisions are measured at the centre-of-mass energy $\sqrt{S} = 13$ TeV. The pseudorapidity distribution in $|\eta|< 1.8$ is reported for inelastic events and for events with at least one charged particle in $|\eta|< 1$. The pseudorapidity density of charged particles produced in the pseudorapidity region $|\eta|< 0.5$ is $5.31 \pm 0.18$ and $6.46 \pm 0.19$ for the two event classes, respectively. The transverse-momentum distribution of charged particles is measured in the range $0.15 < $p_\mathrm{T}$ < 20$ GeV and $|\eta|< 0.8$ for events with at least one charged particle in $|\eta|< 1$. The correlation between transverse momentum and particle multiplicity is also investigated by studying the evolution of the spectra with event multiplicity. The results are compared with calculations from PYTHIA and EPOS Monte Carlo generators. WARNING: It is unclear whether ALICE applied a 1/pT reweighting per-particle at fill-time, or scaled bin contents post-hoc using a representative bin pT value (bin midpoint), when constructing the invariant pT spectrum (d02/pT_INEL0 and multiplicity-class spectra). Both options are implemented via the PTMODE analysis option (default: XMID). If an ALICE analyser can confirm the correct procedure, we will update this analysis accordingly. For the implementation of PTMODE=PTWEIGHT use rivet -a ALICE_2015_I1395253:PTMODE=PTWEIGHT file.hepmc
Source code:ALICE_2015_I1395253.cc
```c++ // -- C++ --
include "Rivet/Analysis.hh"
include "Rivet/Projections/ChargedFinalState.hh"
namespace Rivet {
/// @brief Pseudorapidity and transverse-momentum distributions of charged particles in pp collisions at 13 TeV class ALICE_2015_I1395253 : public Analysis { public:
/// Constructor
RIVET_DEFAULT_ANALYSIS_CTOR(ALICE_2015_I1395253);
/// @name Analysis methods
/// @{
/// Book histograms and initialise projections before the run
void init() {
// pT reweighting mode: XMID (default, divide bin content by bin
// midpoint pT post-hoc) or PTWEIGHT (weight each particle fill by 1/pT at fill-time).
_ptMode = (getOption("PTMODE") == "PTWEIGHT") ? PTWEIGHT : XMID;
// INEL trigger: OR of V0A, V0C, ADA, ADC acceptances.
declare(ChargedFinalState(Cuts::etaIn(2.8, 5.1) || Cuts::etaIn(-3.7, -1.7) || Cuts::etaIn(4.8, 6.3)
|| Cuts::etaIn(-7.0, -4.9)),
"TrigCFS");
// Final states for kinematic cuts
declare(ChargedFinalState(Cuts::abseta < 1.0), "INEL0CFS");
declare(ChargedFinalState(Cuts::abseta < 1.8), "EtaCFS");
declare(ChargedFinalState(Cuts::abseta < 0.8 && Cuts::pT > 0.15 * GeV && Cuts::pT < 20 * GeV), "PtCFS");
// Book dN/deta and INEL0 pT histograms
book(_h["dNch_deta_INEL"], 1, 1, 1);
book(_h["dNch_deta_INEL0"], 1, 1, 2);
book(_h["pT_INEL0"], 2, 1, 1);
// Book multiplicity class histograms and ratios dynamically
book(_h["pT_incl"], "TMP/pT_incl", refData(4, 1, 1));
for (size_t i = 1; i <= 3; ++i) {
const string mode = to_string(i);
book(_h["pT_c" + mode], "TMP/pT_c" + mode, refData(4, 1, i));
book(_e["ratio_c" + mode], 4, 1, i);
}
// Book event counters
book(_c["INEL"], "TMP/c_INEL");
book(_c["INEL0"], "TMP/c_INEL0");
}
/// Perform the per-event analysis
void analyze(const Event& event) {
const ChargedFinalState& trigCFS = apply<ChargedFinalState>(event, "TrigCFS");
const ChargedFinalState& inel0CFS = apply<ChargedFinalState>(event, "INEL0CFS");
const ChargedFinalState& etaCFS = apply<ChargedFinalState>(event, "EtaCFS");
const ChargedFinalState& ptCFS = apply<ChargedFinalState>(event, "PtCFS");
// INEL Trigger requirement
if (!trigCFS.particles().empty()) {
_c["INEL"]->fill();
for (const Particle& p : etaCFS.particles()) {
_h["dNch_deta_INEL"]->fill(p.eta());
}
}
// INEL > 0 Trigger requirement
if (inel0CFS.particles().empty()) return;
_c["INEL0"]->fill();
// Inclusive distributions
for (const Particle& p : etaCFS.particles()) {
_h["dNch_deta_INEL0"]->fill(p.eta());
}
for (const Particle& p : ptCFS.particles()) {
const double pT = p.pT() / GeV;
const double w = (_ptMode == PTWEIGHT) ? 1.0 / pT : 1.0;
_h["pT_INEL0"]->fill(pT, w);
_h["pT_incl"]->fill(pT, w);
}
// Multiplicity class evaluation is deferred to finalize(), since the
// classification thresholds depend on the sample's own <Nch>
const size_t nch = ptCFS.size();
if (nch >= 1) {
vector<double> pts;
pts.reserve(nch);
for (const Particle& p : ptCFS.particles()) pts.push_back(p.pT() / GeV);
_nchBuffer.push_back(nch);
_ptBuffer.push_back(pts);
_sumNch += nch;
}
}
/// Normalise histograms etc., after the run
void finalize() {
// Classify buffered events by multiplicity, using this sample's own
// <Nch> over INEL>0 events (paper Sec. 5), then fill the per-class pT histograms accordingly.
if (!_nchBuffer.empty()) {
const double meanNch = _sumNch / double(_nchBuffer.size());
for (size_t iEv = 0; iEv < _nchBuffer.size(); ++iEv) {
const size_t nch = _nchBuffer[iEv];
size_t idx;
if (nch < meanNch)
idx = 1;
else if (nch < 2.0 * meanNch)
idx = 2;
else
idx = 3;
const string mode = to_string(idx);
for (const double pT : _ptBuffer[iEv]) {
const double w = (_ptMode == PTWEIGHT) ? 1.0 / pT : 1.0;
_h["pT_c" + mode]->fill(pT, w);
}
}
}
// Normalise dN/deta by number of events
if (_c["INEL"]->val() > 0) scale(_h["dNch_deta_INEL"], 1.0 / _c["INEL"]->val());
if (_c["INEL0"]->val() > 0) scale(_h["dNch_deta_INEL0"], 1.0 / _c["INEL0"]->val());
// Normalise inclusive pT by 1/(Nev * 2pi * pT * deta).
// In PTWEIGHT mode the 1/pT factor was already applied per-particle
// at fill-time, so it must not be divided out again here.
if (_c["INEL0"]->val() > 0) {
const double deta = 2.0 * 0.8;
for (auto& b : _h["pT_INEL0"]->bins()) {
const double norm = (_ptMode == PTWEIGHT)
? 1.0 / (_c["INEL0"]->val() * 2.0 * M_PI * deta)
: 1.0 / (_c["INEL0"]->val() * 2.0 * M_PI * b.xMid() * deta);
b.scaleW(norm);
}
}
// Multiplicity ratios: normalise each spectrum to unit area
normalize(_h["pT_incl"]);
for (size_t i = 1; i <= 3; ++i) {
const string mode = to_string(i);
normalize(_h["pT_c" + mode]);
divide(_h["pT_c" + mode], _h["pT_incl"], _e["ratio_c" + mode]);
}
}
/// @}
private:
// Buffers for deferred multiplicity classification (see finalize()):
// each INEL>0 event's Nacc_ch and per-particle pT list are stored here,
// then classified in finalize() once this sample's own <Nch> is known.
vector<size_t> _nchBuffer;
vector<vector<double>> _ptBuffer;
double _sumNch = 0.0;
// pT reweighting mode (see PTMODE option in init())
enum PtRewMode { XMID, PTWEIGHT };
PtRewMode _ptMode;
/// @name Histograms and Counters
/// @{
map<string, Histo1DPtr> _h;
map<string, Estimate1DPtr> _e;
map<string, CounterPtr> _c;
/// @}
};
RIVET_DECLARE_PLUGIN(ALICE_2015_I1395253);
} ```