Rivet analyses referenceATLAS_2019_I1720438Measurement of the $WZ$ production cross section at 13 TeVExperiment: ATLAS (LHC) Inspire ID: 1720438 Status: UNVALIDATED Authors:
Beam energies: (6500.0, 6500.0) GeV Run details:
The production of $W^\pm Z$ events in proton--proton collisions at a centre-of-mass energy of 13 TeV is measured with the ATLAS detector at the LHC. The collected data correspond to an integrated luminosity of 36.1 fb${}^{-1}$ . The $W^\pm Z$ candidates are reconstructed using leptonic decays of the gauge bosons into electrons or muons. The measured inclusive cross section in the detector fiducial region for leptonic decay modes is $\sigma(W^\pm Z\to\ell^\prime\nu\ell\ell \text{fid.}) = 63.7\pm 3.2$(stat.)$\pm 1.0$(sys.)$\pm 1.4$(lumi.) fb. In comparison, the next-to-leading-order Standard Model prediction is 61.5-1.3+1.4 fb. Cross sections for $W^+Z$ and $W^-Z$ production and their ratio are presented as well as differentialcross sections for several kinematic observable. Users should note that explicit matching of lepton flavour between individual SM neutrinos and charged leptons is used in this analysis routine, to match the MC-based correction to the fiducial region applied in the paper. The data are therefore only valid under the assumption of the Standard Model and cannot be used for BSM reinterpretation. Uses SM neutrino-lepton flavour matching and a resonant shape algorithm assuming the Standard Model, to match the MC-based correction to the fiducial region applied in the paper. This routine is therefore only valid under the assumption of the Standard Model and cannot be used for BSM reinterpretation Source code: ATLAS_2019_I1720438.cc 1// -*- C++ -*-
2#include "Rivet/Analysis.hh"
3#include "Rivet/Projections/FinalState.hh"
4#include "Rivet/Projections/FastJets.hh"
5#include "Rivet/Projections/IdentifiedFinalState.hh"
6#include "Rivet/Projections/PromptFinalState.hh"
7#include "Rivet/Projections/LeptonFinder.hh"
8#include "Rivet/Projections/VetoedFinalState.hh"
9
10namespace Rivet {
11
12
13 /// @brief WZ production cross-section at 13 TeV
14 class ATLAS_2019_I1720438 : public Analysis {
15 public:
16
17 /// Constructor
18 RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2019_I1720438);
19
20 /// @name Analysis methods
21 /// @{
22
23 /// Book histograms and initialise projections before the run
24 void init() {
25
26 PromptFinalState photons(Cuts::abspid == PID::PHOTON);
27
28 // Electrons and muons in Fiducial PS
29 PromptFinalState leptons(Cuts::abspid == PID::ELECTRON || Cuts::abspid == PID::MUON);
30 leptons.acceptTauDecays(false);
31 LeptonFinder dressedleptons(leptons, photons, 0.1);
32 declare(dressedleptons, "LeptonFinder");
33
34 // Prompt neutrinos (yikes!)
35 IdentifiedFinalState nu_id;
36 nu_id.acceptNeutrinos();
37 PromptFinalState neutrinos(nu_id);
38 neutrinos.acceptTauDecays(false);
39 declare(neutrinos, "Neutrinos");
40 MSG_WARNING("\033[91;1mLIMITED VALIDITY - check info file for details!\033[m");
41
42 // Muons
43 PromptFinalState bare_mu(Cuts::abspid == PID::MUON, TauDecaysAs::PROMPT);
44 LeptonFinder all_dressed_mu(bare_mu, photons, 0.1, Cuts::abseta < 2.5);
45
46 // Electrons
47 PromptFinalState bare_el(Cuts::abspid == PID::ELECTRON, TauDecaysAs::PROMPT);
48 LeptonFinder all_dressed_el(bare_el, photons, 0.1, Cuts::abseta < 2.5);
49
50 //Jet forming
51 VetoedFinalState vfs(FinalState(Cuts::abseta < 5.0));
52 vfs.addVetoOnThisFinalState(all_dressed_el);
53 vfs.addVetoOnThisFinalState(all_dressed_mu);
54
55 FastJets jets(vfs, JetAlg::ANTIKT, 0.4, JetMuons::ALL, JetInvisibles::DECAY);
56 declare(jets, "Jets");
57
58 // Book auxiliary histograms
59 book(_h["pTZ"], "_pTZ", refData( 8, 1, 1));
60 book(_h["pTW"], "_pTW", refData(10, 1, 1));
61 book(_h["mTWZ"], "_mTWZ", refData(12, 1, 1));
62 book(_h["dPhiWZ"], "_dPhiWZ", refData(14, 1, 1));
63 book(_h["pTv"], "_pTV", refData(16, 1, 1));
64 book(_h["dRapWZ"], "_drapWZ", refData(18, 1, 1));
65 book(_h["Mjj"], "_mjj", refData(22, 1, 1));
66
67 // Book discrete histogram
68 book(_d, 20, 1, 1);
69
70 // book output bar charts
71 book(_s["pTZ"], 8, 1, 1);
72 book(_s["pTW"], 10, 1, 1);
73 book(_s["mTWZ"], 12, 1, 1);
74 book(_s["dPhiWZ"], 14, 1, 1);
75 book(_s["pTv"], 16, 1, 1);
76 book(_s["dRapWZ"], 18, 1, 1);
77 book(_s["Mjj"], 22, 1, 1);
78
79 }
80
81
82 void analyze(const Event& event) {
83
84 if (sedges.empty()) sedges = _d->xEdges();
85
86 const Particles& dressedleptons = apply<LeptonFinder>(event, "LeptonFinder").particlesByPt();
87 const Particles& neutrinos = apply<PromptFinalState>(event, "Neutrinos").particlesByPt();
88 Jets jets = apply<FastJets>(event, "Jets").jetsByPt(Cuts::pT > 25*GeV && Cuts::abseta < 4.5);
89 int i, j, k;
90 double MassZ01 = 0., MassZ02 = 0., MassZ12 = 0.;
91 double MassW0 = 0., MassW1 = 0., MassW2 = 0.;
92 double WeightZ1, WeightZ2, WeightZ3;
93 double WeightW1, WeightW2, WeightW3;
94 double M1, M2, M3;
95 double WeightTotal1, WeightTotal2, WeightTotal3;
96
97 //---Fiducial PS: assign leptons to W and Z bosons using Resonant shape algorithm
98 if (dressedleptons.size() < 3 || neutrinos.size() < 1) vetoEvent;
99
100 int icomb=0;
101 // try Z pair of leptons 01
102 if ( (dressedleptons[0].pid() ==-(dressedleptons[1].pid())) &&
103 (dressedleptons[2].pid()*neutrinos[0].pid()< 0) &&
104 (dressedleptons[2].abspid()==neutrinos[0].abspid()-1)) {
105 MassZ01 = (dressedleptons[0].momentum() + dressedleptons[1].momentum()).mass();
106 MassW2 = (dressedleptons[2].momentum() + neutrinos[0].momentum()).mass();
107 icomb = 1;
108 }
109
110 // try Z pair of leptons 02
111 if ( (dressedleptons[0].pid()==-(dressedleptons[2].pid())) &&
112 (dressedleptons[1].pid()*neutrinos[0].pid()< 0) &&
113 (dressedleptons[1].abspid()==neutrinos[0].abspid()-1)) {
114 MassZ02 = (dressedleptons[0].momentum() + dressedleptons[2].momentum()).mass();
115 MassW1 = (dressedleptons[1].momentum() + neutrinos[0].momentum()).mass();
116 icomb = 2;
117 }
118 // try Z pair of leptons 12
119 if ( (dressedleptons[1].pid()==-(dressedleptons[2].pid())) &&
120 (dressedleptons[0].pid()*neutrinos[0].pid()< 0) &&
121 (dressedleptons[0].abspid()==neutrinos[0].abspid()-1)) {
122 MassZ12 = (dressedleptons[1].momentum() + dressedleptons[2].momentum()).mass();
123 MassW0 = (dressedleptons[0].momentum() + neutrinos[0].momentum()).mass();
124 icomb = 3;
125 }
126
127 if (icomb<=0) vetoEvent;
128
129
130 WeightZ1 = 1/(pow(MassZ01*MassZ01 - MZ_PDG*MZ_PDG,2) + pow(MZ_PDG*GammaZ_PDG,2));
131 WeightW1 = 1/(pow(MassW2*MassW2 - MW_PDG*MW_PDG,2) + pow(MW_PDG*GammaW_PDG,2));
132 WeightTotal1 = WeightZ1*WeightW1;
133 M1 = -1*WeightTotal1;
134
135 WeightZ2 = 1/(pow(MassZ02*MassZ02- MZ_PDG*MZ_PDG,2) + pow(MZ_PDG*GammaZ_PDG,2));
136 WeightW2 = 1/(pow(MassW1*MassW1- MW_PDG*MW_PDG,2) + pow(MW_PDG*GammaW_PDG,2));
137 WeightTotal2 = WeightZ2*WeightW2;
138 M2 = -1*WeightTotal2;
139
140 WeightZ3 = 1/(pow(MassZ12*MassZ12 - MZ_PDG*MZ_PDG,2) + pow(MZ_PDG*GammaZ_PDG,2));
141 WeightW3 = 1/(pow(MassW0*MassW0 - MW_PDG*MW_PDG,2) + pow(MW_PDG*GammaW_PDG,2));
142 WeightTotal3 = WeightZ3*WeightW3;
143 M3 = -1*WeightTotal3;
144
145 if( (M1 < M2 && M1 < M3) || (MassZ01 != 0 && MassW2 != 0 && MassZ02 == 0 && MassZ12 == 0) ) {
146 i = 0; j = 1; k = 2;
147 }
148 if((M2 < M1 && M2 < M3) || (MassZ02 != 0 && MassW1 != 0 && MassZ01 == 0 && MassZ12 == 0) ) {
149 i = 0; j = 2; k = 1;
150 }
151 if((M3 < M1 && M3 < M2) || (MassZ12 != 0 && MassW0 != 0 && MassZ01 == 0 && MassZ02 == 0) ) {
152 i = 1; j = 2; k = 0;
153 }
154
155 FourMomentum Zlepton1 = dressedleptons[i].mom();
156 FourMomentum Zlepton2 = dressedleptons[j].mom();
157 FourMomentum Wlepton = dressedleptons[k].mom();
158 FourMomentum Zboson = dressedleptons[i].mom()+dressedleptons[j].mom();
159 FourMomentum Wboson = dressedleptons[k].mom()+neutrinos[0].mom();
160
161 double cosLepNeut;
162 double Wboson_mT = 0;
163 double norm = Wlepton.pT() * neutrinos[0].pt();
164 if (norm != 0) {
165 cosLepNeut = ( Wlepton.px()*neutrinos[0].px() + Wlepton.py()*neutrinos[0].py() )/norm;
166 if ( 1-cosLepNeut >= 0 ) Wboson_mT = sqrt( 2 * Wlepton.pT() * neutrinos[0].pt() * (1-cosLepNeut ) );
167 }
168
169 //---- CUTS (based on Table 1 WZ: 36.1 fb-1)----//
170 if (Wlepton.pT() <= 20*GeV || Zlepton1.pT() <= 15*GeV || Zlepton2.pT() <= 15*GeV) vetoEvent;
171 if (Wlepton.abseta() >= 2.5 || Zlepton1.abseta() >= 2.5 || Zlepton2.abseta() >= 2.5) vetoEvent;
172 if (fabs(Zboson.mass()/GeV - MZ_PDG) >= 10.) vetoEvent;
173 if (Wboson_mT <= 30*GeV) vetoEvent;
174 if (deltaR(Zlepton1, Zlepton2) <= 0.2) vetoEvent;
175 if (deltaR(Zlepton1, Wlepton) <= 0.3) vetoEvent;
176 if (deltaR(Zlepton2, Wlepton) <= 0.3) vetoEvent;
177
178 double pTZ = Zboson.pT()/GeV;
179 double WZ_pt = (Zlepton1.pt() + Zlepton2.pt() + Wlepton.pt() + neutrinos[0].pt())/GeV;
180 double WZ_px = (Zlepton1.px() + Zlepton2.px() + Wlepton.px() + neutrinos[0].px())/GeV;
181 double WZ_py = (Zlepton1.py() + Zlepton2.py() + Wlepton.py() + neutrinos[0].py())/GeV;
182 double mTWZ = sqrt( pow(WZ_pt, 2) - ( pow(WZ_px, 2) + pow(WZ_py,2) ));
183
184 double dPhiWZTruth = acos(cos(Zboson.phi()-Wboson.phi()));
185 double pTW = Wboson.pT()/GeV;
186 double pTv = neutrinos[0].pT()/GeV;
187 double AbsDeltay = fabs(Zboson.rapidity()-Wlepton.rapidity());
188
189 idiscard(jets, [&](const Jet& j) {
190 return deltaR(j, Zlepton1) < 0.3 || deltaR(j, Zlepton2) < 0.3 || deltaR(j, Wlepton) < 0.3;
191 });
192
193 size_t njets = jets.size()>5? 5 : jets.size();
194 _d->fill(sedges[njets]);
195
196 if (njets > 1) {
197 double mjj = (jets[0].mom() + jets[1].mom()).mass()/GeV;
198 if (mjj > 800.) mjj = 800.;
199 _h["Mjj"]->fill(mjj);
200 }
201
202 if (pTZ > 220.) pTZ = 220.;
203 _h["pTZ"]->fill(pTZ);
204
205 if (pTW > 220.) pTW = 220.;
206 _h["pTW"]->fill(pTW);
207
208 if (mTWZ > 600.) mTWZ = 600.;
209 _h["mTWZ"]->fill(mTWZ);
210
211 _h["dPhiWZ"]->fill(dPhiWZTruth);
212
213 if (pTv > 90.) pTv = 90.;
214 _h["pTv"]->fill(pTv);
215
216 _h["dRapWZ"]->fill(AbsDeltay);
217
218 }
219
220
221 void finalize() {
222
223 scale(_h, 0.25 * crossSectionPerEvent() / femtobarn); // data values are for _single_ lepton channel
224 scale(_d, 0.25 * crossSectionPerEvent() / femtobarn); // data values are for _single_ lepton channel
225 // unfortunately, no differential cross-sections were measured in this analysis
226 for (auto &item : _h) barchart(item.second, _s[item.first]);
227
228 }
229
230 /// @}
231
232
233 private:
234
235
236 /// @name Histograms
237 /// @{
238 BinnedHistoPtr<string> _d;
239 map<string, Histo1DPtr> _h;
240 map<string, Estimate1DPtr> _s;
241 vector<string> sedges;
242 /// @}
243
244 const double MZ_PDG = 91.1876;
245 const double MW_PDG = 80.385;
246 const double GammaZ_PDG = 2.4952;
247 const double GammaW_PDG = 2.085;
248
249 };
250
251
252 RIVET_DECLARE_PLUGIN(ATLAS_2019_I1720438);
253
254}
|