Rivet analyses
title: ATLAS_2024_I2791854
Jet cross-section ratios at 13 TeV
Experiment: ATLAS (LHC)
Inspire ID: 2791854
Status: VALIDATED
Authors: - Jennifer Roloff
References: - Expt page: ATLAS-STDM-2020-04 - arXiv: 2405.20206
Beams: p+ p+
Beam energies: (6500.0, 6500.0)GeV
Run details: - pp -> jets
Measurements of jet cross-section ratios between inclusive bins of jet multiplicity are performed in 140 fb$^{-1}$ of proton--proton collisions with $\sqrt{s}$=13 TeV center-of-mass energy, recorded with the ATLAS detector at CERN's Large Hadron Collider. Observables that are sensitive the energy-scale and angular distribution of radiation due to the strong interaction in the final state are measured double-differentially, in bins of jet multiplicity, and are unfolded to account for acceptance and detector-related effects. Additionally, the scalar sum of the two leading jets' transverse momenta is measured triple-differentially, in bins of the third jet's transverse momentum as well as bins of jet multiplicity. The measured distributions are used to construct ratios of the inclusive jet-multiplicity bins, which have been shown to be sensitive to the strong coupling $\alpha_\text{s}$ while being less sensitive than other observables to systematic uncertainties and parton distribution functions. The measured distributions are compared with state-of-the-art QCD calculations, including next-to-next-to-leading-order predictions. Studies leading to reduced jet energy scale uncertainties significantly improve the precision of this work, and are documented herein.
Source code:ATLAS_2024_I2791854.cc
```c++ // -- C++ --
include "Rivet/Analysis.hh"
include "Rivet/Projections/FastJets.hh"
include "Rivet/Projections/FinalState.hh"
include "Rivet/Tools/HistoGroup.hh"
namespace Rivet {
/// @brief Jet cross-section ratios at 13 TeV class ATLAS_2024_I2791854 : public Analysis { public:
/// Constructor
RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2024_I2791854);
double maxDY(const Jets& jets) const {
double biggest_y_gap = 0;
for (size_t iJet = 0; iJet < jets.size(); ++iJet) {
for (size_t jJet = iJet + 1; jJet < jets.size(); ++jJet) {
double y_gap = std::abs(jets[iJet].rap() - jets[jJet].rap());
if (y_gap > biggest_y_gap) {
biggest_y_gap = y_gap;
}
}
}
return biggest_y_gap;
}
double maxMjj(const Jets& jets) const {
double maxMass = 0;
for (size_t iJet = 0; iJet < jets.size(); ++iJet) {
for (size_t jJet = iJet + 1; jJet < jets.size(); ++jJet) {
double mass = (jets[iJet].mom() + jets[jJet].mom()).mass();
if (mass > maxMass) {
maxMass = mass;
}
}
}
return maxMass;
}
/// @name Analysis methods
/// @{
/// Book histograms and initialise projections before the run
void init() {
// Initialise and register projections
const FinalState fs(Cuts::abseta < 4.9);
// The final-state particles declared above are clustered using FastJet with
// the anti-kT algorithm and a jet-radius parameter 0.4
// muons and neutrinos are excluded from the clustering
FastJets jet4(fs, JetAlg::ANTIKT, 0.4, JetMuons::NONE, JetInvisibles::NONE);
declare(jet4, "Jets");
// booking pT3-binned HT2 results
for (size_t pt3bin = 0; pt3bin < _pt3_cuts.size(); ++pt3bin) {
HistoGroupPtr<int, double> tmp;
_ht2.emplace_back(book(tmp, {2, 3, 4, 5}));
for (auto& b : _ht2[pt3bin]->bins()) {
book(b, 33 + b.index() + 4 * pt3bin, 1, 1);
}
}
// booking all other results
for (size_t njet = 0; njet < 4; ++njet) {
Histo1DPtr tmp;
size_t hid = 54 + njet;
if (njet < 3) {
_h_ptjet.emplace_back(book(tmp, hid, 1, 1));
}
hid += 3;
_h_mjjmax.emplace_back(book(tmp, hid, 1, 1));
hid += 4;
_h_mjj.emplace_back(book(tmp, hid, 1, 1));
hid += 4;
_h_dy.emplace_back(book(tmp, hid, 1, 1));
hid += 4;
_h_dymax.emplace_back(book(tmp, hid, 1, 1));
}
}
/// Perform the per-event analysis
void analyze(const Event& event) {
// Retrieve clustered jets, sorted by pT, with a minimum pT cut
const Jets jets = apply<FastJets>(event, "Jets").jetsByPt(Cuts::pT > 60 * GeV && Cuts::abseta < 4.5);
if (jets.size() < 2) vetoEvent; // Dijet events
const double mjj = (jets[0].mom() + jets[1].mom()).mass();
const double mjjmax = maxMjj(jets);
const double dy = std::abs(jets[0].rap() - jets[1].rap());
const double dymax = maxDY(jets);
const double ht2 = jets[0].pt() + jets[1].pt();
if (ht2 < 250) vetoEvent;
const double pt3 = jets.size() > 2 ? jets[2].pt() : 0.0;
for (size_t nj = std::min(5ul, jets.size()); nj >= 2; --nj) {
for (size_t pt3bin = 0; pt3bin < _pt3_cuts.size(); ++pt3bin) {
if (nj > 2 && pt3 < _pt3_cuts[pt3bin] * ht2) continue;
_ht2[pt3bin]->fill(nj, ht2);
}
_h_mjj[nj - 2]->fill(mjj / GeV);
_h_mjjmax[nj - 2]->fill(mjjmax / GeV);
_h_dy[nj - 2]->fill(dy);
_h_dymax[nj - 2]->fill(dymax);
}
size_t jetSize = jets.size();
for (size_t j = 0; j < 3; ++j) {
for (int i = std::min(j + 1, jetSize - 1); i >= 0; --i) {
_h_ptjet[j]->fill(jets[i].pt() / GeV);
}
}
}
/// Normalise histograms etc., after the run
void finalize() {
const double sf = crossSectionPerEvent();
scale(_ht2, sf);
scale(_h_dy, sf);
scale(_h_dymax, sf);
scale(_h_mjj, sf);
scale(_h_mjjmax, sf);
scale(_h_ptjet, sf);
Estimate1DPtr ratio;
for (size_t ir = 0; ir < 4; ++ir) {
size_t hid = 10 * ir + 6;
// Temporary hack for missing hepdata
if (ir == 1) hid = 10 + 4;
if (ir == 2) hid = 18 + 3;
if (ir == 3) hid = 25 + 4;
if (ir < 2) {
book(ratio, hid, 1, 1);
divide(_h_ptjet[ir + 1], _h_ptjet[ir], ratio);
}
book(ratio, ++hid, 1, 1);
divide(_h_dy[ir == 3 ? 2 : ir + 1], _h_dy[ir == 3 ? 0 : ir], ratio);
book(ratio, ++hid, 1, 1);
divide(_h_dymax[ir == 3 ? 2 : ir + 1], _h_dymax[ir == 3 ? 0 : ir], ratio);
book(ratio, ++hid, 1, 1);
divide(_h_mjj[ir == 3 ? 2 : ir + 1], _h_mjj[ir == 3 ? 0 : ir], ratio);
book(ratio, ++hid, 1, 1);
divide(_h_mjjmax[ir == 3 ? 2 : ir + 1], _h_mjjmax[ir == 3 ? 0 : ir], ratio);
}
for (size_t pt3bin = 0; pt3bin < _pt3_cuts.size(); ++pt3bin) {
for (size_t ir = 0; ir < 4; ++ir) {
size_t hid = pt3bin + 10 * ir + 1;
if (ir == 2) hid = pt3bin + 10 + 8 + 1;
if (ir == 3) hid = pt3bin + 10 + 8 + 7 + 1;
if ((pt3bin == 1 || pt3bin == 3) && ir > 0) continue;
if (ir > 0 && pt3bin == 2) hid -= 1;
if (ir > 0 && pt3bin == 4) hid -= 2;
book(ratio, hid, 1, 1);
MSG_DEBUG("ratio HT2: " << hid << " for pt3bin = " << pt3bin << " and ir = " << ir);
divide(_ht2[pt3bin]->bin(ir == 3 ? 3 : ir + 2), _ht2[pt3bin]->bin(ir == 3 ? 1 : ir + 1), ratio);
}
}
}
/// @name Histograms
/// @{
// for pT-inclusive histograms
vector<HistoGroupPtr<int, double>> _ht2;
vector<Histo1DPtr> _h_dymax, _h_dy, _h_mjjmax, _h_mjj, _h_ptjet;
const vector<double> _pt3_cuts{0.0, 0.05, 0.1, 0.2, 0.3};
/// @}
};
RIVET_DECLARE_PLUGIN(ATLAS_2024_I2791854);
} ```