Rivet analyses referenceCMS_2012_I1298807Inclusive ZZ production cross section and constraints on anomalous triple gauge couplings at 8 TeVExperiment: CMS (LHC) Inspire ID: 1298807 Status: VALIDATED Authors:
Beam energies: (4000.0, 4000.0) GeV Run details:
A measurement of the inclusive $ZZ$ production cross section and constraints on anomalous triple gauge couplings in proton-proton collisions at $\sqrt{s} = 8 TeV$ are presented. The analysis is based on a data sample, corresponding to an integrated luminosity of 19.6/fb, collected with the CMS experiment at the LHC. The measurements are performed in the leptonic decay modes $ZZ \to lll^\prime l^\prime$, where $l = e,\mu$ and $l^\prime = e, \mu, \tau$. The measured total cross section $ \sigma (pp \to ZZ) = 7.7 \pm 0.5 (\mathrm{stat}) + 0.5 -0.4 (\mathrm{syst}) \pm 0.4 (\mathrm{theo}) \pm 0.2 (\mathrm{lumi}) pb$, for both $Z$ bosons produced in the mass range $60 < m_Z < 120 \text{GeV}$, is consistent with standard model predictions. Differential cross sections, in phase space $p_T(\mu) > 5 \text{GeV}$, $p_T(e) > 7 \text{GeV}$, $|\eta(\mu)|<2.4$ , $|\eta(e)|<2.5$ and the 60--120 \text{GeV} mass requirement, are measured and well described by the theoretical predictions. The invariant mass distribution of the four-lepton system is used to set limits on anomalous $ZZZ$ and $ZZ\gamma$ couplings at the 95\% confidence level, $-0.004 < f4Z < 0.004$, $-0.004 < f5Z < 0.004$, $-0.005 < f4\gamma < 0.005$, and $-0.005 < f5\gamma < 0.005.$ Source code: CMS_2012_I1298807.cc 1// -*- C++ -*-
2#include "Rivet/Analysis.hh"
3#include "Rivet/Projections/FinalState.hh"
4#include "Rivet/Projections/IdentifiedFinalState.hh"
5#include "Rivet/Projections/DileptonFinder.hh"
6#include "Rivet/Projections/VetoedFinalState.hh"
7#include "Rivet/Projections/MergedFinalState.hh"
8
9namespace Rivet {
10
11
12 /// Inclusive ZZ production cross section and constraints on anomalous triple gauge couplings
13 class CMS_2012_I1298807 : public Analysis {
14 public:
15
16 // Constructor
17 RIVET_DEFAULT_ANALYSIS_CTOR(CMS_2012_I1298807);
18
19
20 /// Initialise projections and histograms
21 void init() {
22
23 FinalState leptons((Cuts::abspid == PID::ELECTRON && Cuts::abseta < 2.5) ||
24 (Cuts::abspid == PID::MUON && Cuts::abseta < 2.4));
25 declare(leptons, "Leptons");
26
27 Cut cut_el = Cuts::abseta < 2.5 && Cuts::pT > 7.0*GeV;
28 DileptonFinder zeefinder(91.2*GeV, 0.1, cut_el && Cuts::abspid == PID::ELECTRON,
29 Cuts::massIn(60*GeV, 120*GeV));
30 declare(zeefinder, "ZeeFinder");
31
32 Cut cut_mu = Cuts::abseta < 2.4 && Cuts::pT > 5.0*GeV;
33 DileptonFinder zmmfinder(91.2*GeV, 0.1, cut_mu && Cuts::abspid == PID::MUON,
34 Cuts::massIn(60*GeV, 120*GeV));
35 declare(zmmfinder, "ZmmFinder");
36
37 VetoedFinalState fs_woZmm;
38 fs_woZmm.addVetoOnThisFinalState(zmmfinder);
39 VetoedFinalState fs_woZee;
40 fs_woZee.addVetoOnThisFinalState(zeefinder);
41
42 DileptonFinder zeefinder_woZee(fs_woZee, 91.2*GeV, 0.1,
43 cut_el && Cuts::abspid == PID::ELECTRON, Cuts::massIn(60*GeV, 120*GeV));
44 declare(zeefinder_woZee, "Zeefinder_WoZee");
45 DileptonFinder zmmfinder_woZmm(fs_woZmm, 91.2*GeV, 0.1,
46 cut_mu && Cuts::abspid == PID::MUON, Cuts::massIn(60*GeV, 120*GeV));
47 declare(zmmfinder_woZmm, "Zmmfinder_WoZmm");
48
49 // Book histograms
50 book(_h["pt_l1"], 1, 1, 1);
51 book(_h["pt_z1"], 1, 1, 2);
52 book(_h["pt_zz"], 1, 1, 3);
53 book(_h["m_zz"], 1, 1, 4);
54 book(_h["dphi_zz"], 1, 1, 5);
55 book(_h["dR_zz"], 1, 1, 6);
56
57 }
58
59
60 // Perform the per-event analysis
61 void analyze(const Event& evt) {
62
63 // Find leading leptons and apply cuts
64 const Particles& leptons = apply<FinalState>(evt, "Leptons").particlesByPt();
65 if (leptons.size() < 2) vetoEvent;
66 const double leading_l_pt = leptons[0].pT();
67 const double second_l_pt = leptons[1].pT();
68 if (leading_l_pt < 20*GeV || second_l_pt < 10*GeV) vetoEvent;
69
70 // Find acceptable ZZ combinations and build four-momenta, otherwise veto
71 const DileptonFinder& zeefinder = apply<DileptonFinder>(evt, "ZeeFinder");
72 const DileptonFinder& zeefinder_woZee = apply<DileptonFinder>(evt, "Zeefinder_WoZee");
73 const DileptonFinder& zmmfinder = apply<DileptonFinder>(evt, "ZmmFinder");
74 const DileptonFinder& zmmfinder_woZmm = apply<DileptonFinder>(evt, "Zmmfinder_WoZmm");
75
76 FourMomentum pZ_a, pZ_b, pZ_1, pZ_2;
77 FourMomentum pZZ, Z_a_l1, Z_a_l2, Z_b_l1, Z_b_l2;
78 if (zeefinder.bosons().size() > 0 && zmmfinder.bosons().size() > 0) {
79 pZ_a = zeefinder.boson();
80 pZ_b = zmmfinder.boson();
81 pZZ = pZ_a + pZ_b;
82 pZ_1 = pZ_a;
83 pZ_2 = pZ_b;
84 Z_a_l1 = zeefinder.constituents()[0];
85 Z_a_l2 = zeefinder.constituents()[1];
86 Z_b_l1 = zmmfinder.constituents()[0];
87 Z_b_l2 = zmmfinder.constituents()[1];
88 } else if (zeefinder.bosons().size() > 0 && zeefinder_woZee.bosons().size() > 0) {
89 pZ_a = zeefinder.boson();
90 pZ_b = zeefinder_woZee.boson();
91 pZZ = pZ_a + pZ_b;
92 pZ_1 = pZ_a;
93 pZ_2 = pZ_b;
94 Z_a_l1 = zeefinder.constituents()[0];
95 Z_a_l2 = zeefinder.constituents()[1];
96 Z_b_l1 = zeefinder_woZee.constituents()[0];
97 Z_b_l2 = zeefinder_woZee.constituents()[1];
98 } else if (zmmfinder.bosons().size() > 0 && zmmfinder_woZmm.bosons().size() > 0) {
99 pZ_a = zmmfinder.boson();
100 pZ_b = zmmfinder_woZmm.boson();
101 pZZ = pZ_a + pZ_b;
102 pZ_1 = pZ_a;
103 pZ_2 = pZ_b;
104 Z_a_l1 = zmmfinder.constituents()[0];
105 Z_a_l2 = zmmfinder.constituents()[1];
106 Z_b_l1 = zmmfinder_woZmm.constituents()[0];
107 Z_b_l2 = zmmfinder_woZmm.constituents()[1];
108 } else {
109 vetoEvent;
110 }
111
112 // Set ordered pT variables
113 /// @todo Looks like there should be a nicer way than this
114 double pt_l1 = Z_a_l1.pT();
115 if (Z_a_l2.pT() > pt_l1) pt_l1 = Z_a_l2.pT();
116 if (Z_b_l1.pT() > pt_l1) pt_l1 = Z_b_l1.pT();
117 if (Z_b_l2.pT() > pt_l1) pt_l1 = Z_b_l2.pT();
118
119 // Leading Z pT
120 double pt_z1 = pZ_a.pT();
121 if (pZ_b.pT() > pZ_a.pT()) {
122 pt_z1 = pZ_b.pT();
123 pZ_1 = pZ_b;
124 pZ_2 = pZ_a;
125 }
126
127 // Fill histograms
128 _h["pt_zz"]->fill(pZZ.pT()/GeV);
129 _h["m_zz"]->fill(pZZ.mass()/GeV);
130 _h["dphi_zz"]->fill(deltaPhi(pZ_a, pZ_b));
131 _h["dR_zz"]->fill(deltaR(pZ_a, pZ_b, PSEUDORAPIDITY));
132 _h["pt_z1"]->fill(pt_z1/GeV);
133 _h["pt_l1"]->fill(pt_l1/GeV);
134
135 }
136
137
138 /// Scale histograms
139 /// @todo Why is it scaling by bin width twice??
140 void finalize() {
141
142 for (auto& item : _h) {
143 double area = 0.;
144 for (auto& b : item.second->bins()) {
145 b.scaleW(1.0/b.xWidth());
146 area += b.sumW() / b.dVol();
147 }
148 if (area) scale(item.second, 1.0 / area);
149 }
150 }
151
152
153 /// Histograms
154 map<string, Histo1DPtr> _h;
155
156 };
157
158
159 RIVET_DECLARE_PLUGIN(CMS_2012_I1298807);
160
161}
|