Rivet analyses referenceATLAS_2022_I2593322Zyy cross-section measurement at 13 TeVExperiment: ATLAS (LHC) Inspire ID: 2593322 Status: VALIDATED Authors:
Beam energies: (6500.0, 6500.0) GeV Run details:
Cross-sections for the production of a $Z$ boson in association with two photons are measured in proton-proton collisions at a centre-of-mass energy of $13 \, \mathrm{TeV}$. The data used correspond to an integrated luminosity of $139 \, \mathrm{fb}^{-1}$ recorded by the ATLAS experiment during Run 2 of the LHC. The measurements use the electron and muon decay channels of the $Z$ boson, and a fiducial phase-space region where the photons are not radiated from the leptons. The integrated $Z(\rightarrow\ell\ell)\gamma\gamma$ cross-section is measured with a precision of $12\%$ and differential cross-sections are measured as a function of six kinematic variables of the $Z\gamma\gamma$ system. The data are compared with predictions from MC event generators which are accurate to up to next-to-leading order in QCD. The cross-section measurements are used to set limits on the coupling strengths of dimension-8 operators in the framework of an effective field theory. Source code: ATLAS_2022_I2593322.cc 1// -*- C++ -*-
2#include "Rivet/Analysis.hh"
3#include "Rivet/Projections/FinalState.hh"
4#include "Rivet/Projections/LeptonFinder.hh"
5#include "Rivet/Projections/PromptFinalState.hh"
6#include "Rivet/Projections/VetoedFinalState.hh"
7#include "Rivet/Projections/VisibleFinalState.hh"
8#include "Rivet/Projections/IdentifiedFinalState.hh"
9
10namespace Rivet {
11
12
13 /// @brief ATLAS 13 TeV Z(->ll)yy analysis
14 class ATLAS_2022_I2593322 : public Analysis {
15 public:
16
17 /// Constructor
18 RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2022_I2593322);
19
20 /// @name Analysis methods
21 ///@{
22
23 /// Book histograms and initialise projections before the run
24 void init() {
25
26 // Prompt photons
27 const Cut photoncut = Cuts::abspid == PID::PHOTON && Cuts::pT > 20*GeV && Cuts::abseta < 2.37;
28 PromptFinalState photon_fs(photoncut);
29 declare(photon_fs, "Photons");
30
31 // Prompt leptons
32 const PromptFinalState bareelectron_fs = Cuts::abspid == PID::ELECTRON;
33 const PromptFinalState baremuon_fs = Cuts::abspid == PID::MUON;
34
35 // Dressed leptons
36 const IdentifiedFinalState allphoton_fs(PID::PHOTON); // photons used for lepton dressing
37 const Cut leptoncut = Cuts::pT > 20*GeV && Cuts::abseta < 2.47;
38 const LeptonFinder dressedelectron_fs(bareelectron_fs, allphoton_fs, 0.1, leptoncut);
39 const LeptonFinder dressedmuon_fs(baremuon_fs, allphoton_fs, 0.1, leptoncut);
40
41 declare(dressedelectron_fs, "Electrons");
42 declare(dressedmuon_fs, "Muons");
43
44 IdentifiedFinalState neutrinos;
45 neutrinos.acceptNeutrinos();
46
47 // FS for photon isolation
48 FinalState all_fs;
49 VetoedFinalState veto_fs(all_fs);
50 veto_fs.addVetoOnThisFinalState(photon_fs);
51 veto_fs.addVetoOnThisFinalState(dressedmuon_fs);
52 veto_fs.addVetoOnThisFinalState(neutrinos);
53 declare(veto_fs, "vetoFS");
54
55 // book histograms
56 book(_h["y1_pt"], 2, 1, 1);
57 book(_h["y2_pt"], 3, 1, 1);
58 book(_h["ll_pt"], 4, 1, 1);
59 book(_h["llyy_pt"], 5, 1, 1);
60 book(_h["yy_m"], 6, 1, 1);
61 book(_h["llyy_m"], 7, 1, 1);
62
63 }
64
65 /// Perform the per-event analysis
66 void analyze(const Event& event) {
67
68 DressedLeptons electrons = apply<LeptonFinder>(event, "Electrons").dressedLeptons();
69 DressedLeptons muons = apply<LeptonFinder>(event, "Muons").dressedLeptons();
70 const Particles& photons = apply<PromptFinalState>(event, "Photons").particlesByPt();
71
72 if ( (electrons.size() < 2 && muons.size() < 2) ) vetoEvent;
73 if ( photons.size() < 2 ) vetoEvent;
74
75 DressedLepton *lep_1, *lep_2;
76
77 if (muons.size() >= 2){
78 if (muons[0].pT()/GeV < 30) vetoEvent;
79 lep_1 = &muons[0];
80 lep_2 = &muons[1];
81 }
82 else{
83 if (electrons[0].pT()/GeV < 30) vetoEvent;
84 lep_1 = &electrons[0];
85 lep_2 = &electrons[1];
86 }
87
88 if ( (lep_1->charge() == lep_2->charge()) || (lep_1->abspid() != lep_2->abspid()) ) vetoEvent;
89
90 Particles veto_particles = apply<VetoedFinalState>(event, "vetoFS").particles();
91 Particles selPhotons;
92 for (size_t i = 0; i < photons.size(); ++i){
93 if ( deltaR(photons[i], *lep_1) < 0.4 ) continue;
94 if ( deltaR(photons[i], *lep_2) < 0.4 ) continue;
95 double coneEnergy = 0;
96 for (const Particle &p : veto_particles){
97 if ( deltaR(photons[i], p) < 0.2 ) coneEnergy += p.Et();
98 }
99 if (coneEnergy/photons[i].Et() > 0.07) continue;
100 selPhotons.push_back(photons[i]);
101 }
102
103 if (selPhotons.size() < 2) vetoEvent;
104
105 if (deltaR(selPhotons[0], selPhotons[1]) < 0.4) vetoEvent;
106
107 if ( (lep_1->momentum() + lep_2->momentum()).mass()/GeV < 40 ) vetoEvent;
108
109 FourMomentum ll_p4 = lep_1->mom()+lep_2->mom();
110 const double m_ll = ll_p4.mass();
111 const bool lly0 = (ll_p4+selPhotons[0].mom()).mass() > (ll_p4+selPhotons[1].mom()).mass();
112 const double m_ll_y = lly0? (ll_p4+selPhotons[1].mom()).mass() : (ll_p4+selPhotons[0].mom()).mass();
113
114 if ( (m_ll + m_ll_y) < 182*GeV) vetoEvent;
115
116 FourMomentum yy_p4 = selPhotons[0].momentum()+selPhotons[1].momentum();
117
118 _h["y1_pt"]->fill(selPhotons[0].pt()/GeV);
119 _h["y2_pt"]->fill(selPhotons[1].pt()/GeV);
120 _h["ll_pt"]->fill(ll_p4.pt()/GeV);
121 _h["llyy_pt"]->fill( (ll_p4+yy_p4).pt()/GeV );
122 _h["yy_m"]->fill(yy_p4.mass()/GeV);
123 _h["llyy_m"]->fill( (ll_p4+yy_p4).mass()/GeV );
124
125 }
126
127 void finalize() {
128
129 const double sf = crossSection()/femtobarn/sumW();
130 scale(_h, sf);
131
132 }
133
134 ///@}
135
136 /// @name Histograms
137 ///@{
138 map<string, Histo1DPtr> _h;
139 ///@}
140
141
142 };
143
144
145 RIVET_DECLARE_PLUGIN(ATLAS_2022_I2593322);
146
147}
|