Rivet analyses
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 α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++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/FastJets.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);
}