rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

CMS_2012_I1298807

Inclusive ZZ production cross section and constraints on anomalous triple gauge couplings at 8 TeV
Experiment: CMS (LHC)
Inspire ID: 1298807
Status: VALIDATED
Authors:
  • Alexander Savin
  • Ian Ross
References: Beams: p+ p+
Beam energies: (4000.0, 4000.0) GeV
Run details:
  • ZZ production, leptonic Z decays

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/ZFinder.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 electrons(Cuts::abseta < 2.5 && Cuts::abspid == PID::ELECTRON);
 24      // FinalState muons(Cuts::abseta < 2.4 && Cuts::abspid == PID::MUON);
 25      // MergedFinalState leptons(electrons, muons);
 26      FinalState leptons((Cuts::abspid == PID::ELECTRON && Cuts::abseta < 2.5) ||
 27                         (Cuts::abspid == PID::MUON && Cuts::abseta < 2.4));
 28      declare(leptons, "Leptons");
 29
 30      Cut cut_el = Cuts::abseta < 2.5 && Cuts::pT > 7.0*GeV;
 31      Cut cut_mu = Cuts::abseta < 2.4 && Cuts::pT > 5.0*GeV;
 32
 33      ZFinder zeefinder(FinalState(), cut_el, PID::ELECTRON, 60*GeV, 120*GeV, 0.1, ZFinder::ClusterPhotons::NODECAY, ZFinder::AddPhotons::YES);
 34      declare(zeefinder, "ZeeFinder");
 35      ZFinder zmmfinder(FinalState(), cut_mu, PID::MUON, 60*GeV, 120*GeV, 0.1, ZFinder::ClusterPhotons::NODECAY, ZFinder::AddPhotons::YES);
 36      declare(zmmfinder, "ZmmFinder");
 37
 38      VetoedFinalState fs_woZmm;
 39      fs_woZmm.addVetoOnThisFinalState(zmmfinder);
 40      VetoedFinalState fs_woZee;
 41      fs_woZee.addVetoOnThisFinalState(zeefinder);
 42
 43      ZFinder zeefinder_woZee(fs_woZee, cut_el, PID::ELECTRON, 60*GeV, 120*GeV, 0.1, ZFinder::ClusterPhotons::NODECAY);
 44      declare(zeefinder_woZee, "Zeefinder_WoZee");
 45      ZFinder zmmfinder_woZmm(fs_woZmm, cut_mu, PID::MUON, 60*GeV, 120*GeV, 0.1, ZFinder::ClusterPhotons::NODECAY);
 46      declare(zmmfinder_woZmm, "Zmmfinder_WoZmm");
 47
 48      // Book histograms
 49      book(_hist_pt_l1  , 1, 1, 1);
 50      book(_hist_pt_z1  , 1, 1, 2);
 51      book(_hist_pt_zz  , 1, 1, 3);
 52      book(_hist_m_zz   , 1, 1, 4);
 53      book(_hist_dphi_zz, 1, 1, 5);
 54      book(_hist_dR_zz  , 1, 1, 6);
 55
 56    }
 57
 58
 59    // Perform the per-event analysis
 60    void analyze(const Event& evt) {
 61
 62      // Find leading leptons and apply cuts
 63      const Particles& leptons = apply<FinalState>(evt, "Leptons").particlesByPt();
 64      if (leptons.size() < 2) vetoEvent;
 65      const double leading_l_pt = leptons[0].pT();
 66      const double second_l_pt = leptons[1].pT();
 67      if (leading_l_pt < 20*GeV || second_l_pt < 10*GeV) vetoEvent;
 68
 69      // Find acceptable ZZ combinations and build four-momenta, otherwise veto
 70      const ZFinder& zeefinder = applyProjection<ZFinder>(evt, "ZeeFinder");
 71      const ZFinder& zeefinder_woZee = applyProjection<ZFinder>(evt, "Zeefinder_WoZee");
 72      const ZFinder& zmmfinder = applyProjection<ZFinder>(evt, "ZmmFinder");
 73      const ZFinder& zmmfinder_woZmm = applyProjection<ZFinder>(evt, "Zmmfinder_WoZmm");
 74
 75      FourMomentum pZ_a, pZ_b, pZ_1, pZ_2;
 76      FourMomentum pZZ, Z_a_l1, Z_a_l2, Z_b_l1, Z_b_l2;
 77      if (zeefinder.bosons().size() > 0 && zmmfinder.bosons().size() > 0) {
 78        pZ_a = zeefinder.bosons()[0];
 79        pZ_b = zmmfinder.bosons()[0];
 80        pZZ = pZ_a + pZ_b;
 81        pZ_1 = pZ_a;
 82        pZ_2 = pZ_b;
 83        Z_a_l1 = zeefinder.constituents()[0];
 84        Z_a_l2 = zeefinder.constituents()[1];
 85        Z_b_l1 = zmmfinder.constituents()[0];
 86        Z_b_l2 = zmmfinder.constituents()[1];
 87      } else if (zeefinder.bosons().size() > 0 && zeefinder_woZee.bosons().size() > 0) {
 88        pZ_a = zeefinder.bosons()[0];
 89        pZ_b = zeefinder_woZee.bosons()[0];
 90        pZZ = pZ_a + pZ_b;
 91        pZ_1 = pZ_a;
 92        pZ_2 = pZ_b;
 93        Z_a_l1 = zeefinder.constituents()[0];
 94        Z_a_l2 = zeefinder.constituents()[1];
 95        Z_b_l1 = zeefinder_woZee.constituents()[0];
 96        Z_b_l2 = zeefinder_woZee.constituents()[1];
 97      } else if (zmmfinder.bosons().size() > 0 && zmmfinder_woZmm.bosons().size() > 0) {
 98        pZ_a = zmmfinder.bosons()[0];
 99        pZ_b = zmmfinder_woZmm.bosons()[0];
100        pZZ = pZ_a + pZ_b;
101        pZ_1 = pZ_a;
102        pZ_2 = pZ_b;
103        Z_a_l1 = zmmfinder.constituents()[0];
104        Z_a_l2 = zmmfinder.constituents()[1];
105        Z_b_l1 = zmmfinder_woZmm.constituents()[0];
106        Z_b_l2 = zmmfinder_woZmm.constituents()[1];
107      } else {
108        vetoEvent;
109      }
110
111      // Set ordered pT variables
112      /// @todo Looks like there should be a nicer way than this
113      double pt_l1 = Z_a_l1.pT();
114      if (Z_a_l2.pT() > pt_l1) pt_l1 = Z_a_l2.pT();
115      if (Z_b_l1.pT() > pt_l1) pt_l1 = Z_b_l1.pT();
116      if (Z_b_l2.pT() > pt_l1) pt_l1 = Z_b_l2.pT();
117
118      // Leading Z pT
119      double pt_z1 = pZ_a.pT();
120      if (pZ_b.pT() > pZ_a.pT()) {
121        pt_z1 = pZ_b.pT();
122        pZ_1 = pZ_b;
123        pZ_2 = pZ_a;
124      }
125
126      // Fill histograms
127      const double weight = 1.0;
128      _hist_pt_zz->fill(pZZ.pT()/GeV, weight);
129      _hist_m_zz->fill(pZZ.mass()/GeV, weight);
130      _hist_dphi_zz->fill(deltaPhi(pZ_a, pZ_b), weight);
131      _hist_dR_zz->fill(deltaR(pZ_a, pZ_b, PSEUDORAPIDITY), weight);
132      _hist_pt_z1->fill(pt_z1/GeV, weight);
133      _hist_pt_l1->fill(pt_l1/GeV, weight);
134
135    }
136
137
138    /// Scale histograms
139    /// @note This is all needed to undo bin width factor -- WHY DO PEOPLE USE UNPHYSICAL HISTOGRAMS?!?
140    /// @todo If we introduce a "bar plot" or similar, it'd work better here
141    void finalize() {
142
143      double sum_height_pt_zz = 0;
144      for (size_t i = 0; i < _hist_pt_zz->numBins(); i++) {
145        _hist_pt_zz->bin(i).scaleW(1. / _hist_pt_zz->bin(i).width());
146        sum_height_pt_zz += _hist_pt_zz->bin(i).height();
147      }
148      scale(_hist_pt_zz, 1. / sum_height_pt_zz);
149
150      double sum_height_m_zz = 0;
151      for (size_t i = 0; i < _hist_m_zz->numBins(); i++) {
152        _hist_m_zz->bin(i).scaleW(1. / _hist_m_zz->bin(i).width());
153        sum_height_m_zz += _hist_m_zz->bin(i).height();
154      }
155      scale(_hist_m_zz, 1. / sum_height_m_zz);
156
157      double sum_height_dphi_zz = 0;
158      for (size_t i = 0; i < _hist_dphi_zz->numBins(); i++) {
159        _hist_dphi_zz->bin(i).scaleW(1. / _hist_dphi_zz->bin(i).width());
160        sum_height_dphi_zz += _hist_dphi_zz->bin(i).height();
161      }
162      scale(_hist_dphi_zz, 1. / sum_height_dphi_zz);
163
164      double sum_height_dR_zz = 0;
165      for (size_t i = 0; i < _hist_dR_zz->numBins(); i++) {
166        _hist_dR_zz->bin(i).scaleW(1. / _hist_dR_zz->bin(i).width());
167        sum_height_dR_zz += _hist_dR_zz->bin(i).height();
168      }
169      scale(_hist_dR_zz, 1. / sum_height_dR_zz);
170
171      double sum_height_pt_z1 = 0;
172      for (size_t i = 0; i < _hist_pt_z1->numBins(); i++) {
173        _hist_pt_z1->bin(i).scaleW(1. / _hist_pt_z1->bin(i).width());
174        sum_height_pt_z1 += _hist_pt_z1->bin(i).height();
175      }
176      scale(_hist_pt_z1, 1. / sum_height_pt_z1);
177
178      double sum_height_pt_l1 = 0;
179      for (size_t i = 0; i < _hist_pt_l1->numBins(); i++) {
180        _hist_pt_l1->bin(i).scaleW(1. / _hist_pt_l1->bin(i).width());
181        sum_height_pt_l1 += _hist_pt_l1->bin(i).height();
182      }
183      scale(_hist_pt_l1, 1. / sum_height_pt_l1);
184    }
185
186
187    /// Histograms
188    Histo1DPtr _hist_pt_zz, _hist_m_zz, _hist_dphi_zz, _hist_dR_zz, _hist_pt_z1, _hist_pt_l1;
189
190  };
191
192
193  // The hook for the plugin system
194  RIVET_DECLARE_PLUGIN(CMS_2012_I1298807);
195
196}