rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

MC_ZVBF

Monte Carlo validation observables for VBF $Z[\ell^+ \, \ell^-]$ + 2 jet production
Experiment: ()
Status: VALIDATED
Authors:
  • Christian Gutschow
No references listed
Beams: * *
Beam energies: ANY
Run details:
  • $\ell^+ \ell^-$ + 2 jets analysis. Needs mass cut on lepton pair to avoid photon singularity, e.g. a min range of $66 < m_{ll} < 116$ GeV

Available observables are the pT of jets 1-4, jet multiplicity, $\Delta\eta(Z, \text{jet1})$, $\Delta R(\text{jet2}, \text{jet3})$, $m_{jj}$, $H_\text{T}$ and third-jet centrality.

Source code: MC_ZVBF.cc
  1// -*- C++ -*-
  2#include "Rivet/Analysis.hh"
  3#include "Rivet/Projections/DileptonFinder.hh"
  4#include "Rivet/Projections/FastJets.hh"
  5
  6namespace Rivet {
  7
  8
  9  /// @brief MC validation analysis for Zjj events
 10  class MC_ZVBF : public Analysis {
 11  public:
 12
 13    /// Default constructor
 14    RIVET_DEFAULT_ANALYSIS_CTOR(MC_ZVBF);
 15
 16    /// @name Analysis methods
 17    /// @{
 18
 19    /// Initialize
 20    void init() {
 21      _dR=0.1;
 22      if (getOption("SCHEME") == "BARE")  _dR = 0.0;
 23      _lepton=PID::ELECTRON;
 24      if (getOption("LMODE") == "MU")  _lepton = PID::MUON;
 25
 26      Cut cut = Cuts::abseta < 3.5 && Cuts::pT > 25*GeV;
 27      DileptonFinder zfinder(91.2*GeV, _dR, cut && Cuts::abspid == _lepton, Cuts::massIn(65*GeV, 115*GeV));
 28      declare(zfinder, "DileptonFinder");
 29      FastJets jetpro(zfinder.remainingFinalState(), JetAlg::ANTIKT, 0.4);
 30      declare(jetpro, "Jets");
 31
 32      const double sqrts = sqrtS() ? sqrtS() : 14*TeV;
 33      book(_h["gap_inc"], "N_gapjets_inclusive", 8, -0.5, 7.5);
 34      book(_h["gap_exc"], "N_gapjets_exclusive", 8, -0.5, 7.5);
 35      book(_h["Z_jet1_deta"], "Z_jet1_deta", 50, -5, 5);
 36      book(_h["Z_jet1_dR"], "Z_jet1_dR", 25, 0.5, 7.0);
 37      book(_h["HT"], "jets_HT", logspace(40, 50, sqrts/GeV/2.0));
 38      book(_h["mjj"], "m_jj", 40, 200.0, sqrts/GeV/2.0);
 39      book(_h["jve_mjj"], "_jve_mjj", 40, 200.0, sqrts/GeV/2.0);
 40      book(_h["pTV"] ,"Z_pT", logspace(100, 1.0, 0.5*sqrts/GeV));
 41      book(_h["dphi"], "dphi_jj", 20., -1., 1.);
 42      book(_h["drap"], "drap_jj", 20., -10., 10.);
 43      book(_h["3JC"], "jet_3_centrality", 25., -2.5, 2.5);
 44
 45      book(_s["jve_mjj"], "jet_veto_efficiency_mjj");
 46
 47      for (size_t i = 0; i < 4; ++i) {
 48        const string pTname = "jet_pT_" + to_str(i+1);
 49        const double pTmax = 1.0/(double(i)+2.0) * sqrts/GeV/2.0;
 50        const int nbins_pT = 100/(i+1);
 51        if (pTmax > 10) { // Protection aginst logspace exception, needed for LEP
 52          book(_h[pTname], pTname, logspace(nbins_pT, 10.0, pTmax));
 53        }
 54        const string etaname = "jet_eta_" + to_str(i+1);
 55        book(_h[etaname], etaname, (i > 1 ? 25 : 50), -5.0, 5.0);
 56        const string rapname = "jet_y_" + to_str(i+1);
 57        book(_h[rapname], rapname, (i > 1 ? 25 : 50), -5.0, 5.0);
 58        const string phiname = "jet_phi_" + to_str(i+1);
 59        book(_h[phiname], phiname, (i > 1 ? 25 : 50), -1.0, 1.0);
 60      }
 61    }
 62
 63
 64    /// Do the analysis
 65    void analyze(const Event & e) {
 66      MSG_TRACE("MC_ZVBF: running DileptonFinder");
 67      const DileptonFinder& zfinder = apply<DileptonFinder>(e, "DileptonFinder");
 68      if (zfinder.bosons().size() != 1) vetoEvent;
 69      const FourMomentum& zmom = zfinder.bosons()[0].momentum();
 70      MSG_TRACE("MC_ZVBF: have exactly one Z boson candidate");
 71
 72      const Jets& jets = apply<FastJets>(e, "Jets").jetsByPt(Cuts::absrap < 5 && Cuts::pT > 30*GeV);
 73      if (jets.size() < 2) {
 74        MSG_TRACE("MC_ZVBF: does not have at least two valid jets");
 75        vetoEvent;
 76      }
 77
 78      Jet tag1 = jets.at(0);
 79      Jet tag2 = jets.at(1);
 80      const double mjj = (tag1.mom() + tag2.mom()).mass()/GeV;
 81      if (mjj < 200.) {
 82        MSG_TRACE("MC_ZVBF: should have at least 200 GeV in Mjj");
 83        vetoEvent;
 84      }
 85
 86      // jet kinematics
 87      for (size_t i = 0; i < min(4u, jets.size()); ++i) {
 88        const string pTname  = "jet_pT_"  + to_str(i+1);
 89        const string etaname = "jet_eta_" + to_str(i+1);
 90        const string rapname = "jet_y_"   + to_str(i+1);
 91        const string phiname = "jet_phi_" + to_str(i+1);
 92        _h[pTname]->fill(jets[i].pT()/GeV);
 93        _h[etaname]->fill(jets[i].eta());
 94        _h[rapname]->fill(jets[i].rap());
 95        _h[phiname]->fill(mapAngleMPiToPi(jets[i].phi())/M_PI);
 96      }
 97
 98      size_t n_gap = 0;
 99      // start loop at the 3rd hardest pT jet
100      for (size_t i = 2; i < jets.size(); ++i) {
101        const Jet j = jets.at(i);
102        if (isBetween(j, tag1, tag2))  ++n_gap;
103      }
104
105      // gap-jet multiplicities
106      _h["gap_exc"]->fill(n_gap);
107      for (size_t i = 0; i <= 7; ++i) {
108        if (n_gap >= i) {
109          _h["gap_inc"]->fill(i);
110        }
111      }
112
113      _h["jve_mjj"]->fill(mjj);
114      if (n_gap) {
115        // third-jet centrality
116        const double rap1 = jets[0].rap();
117        const double rap2 = jets[1].rap();
118        const double rap3 = jets[2].rap();
119        const double JC = (rap3 - 0.5*(rap1 + rap2))/(rap1 - rap2);
120        _h["3JC"]->fill(JC);
121      }
122      else {
123        MSG_TRACE("MC_ZVBF: should satisfy a CJV");
124        const double HT = sum(jets, Kin::pT, 0.0)/GeV;
125        _h["HT"]->fill(HT);
126        _h["mjj"]->fill(mjj);
127        _h["pTV"]->fill(zmom.pT()/GeV);
128        _h["dphi"]->fill(signedDeltaPhi(tag1, tag2));
129        _h["drap"]->fill(tag1.rap() - tag2.rap());
130
131        // Z tagging jet correlations
132        _h["Z_jet1_deta"]->fill(zmom.eta()-jets[0].eta());
133        _h["Z_jet1_dR"]->fill(deltaR(zmom, jets[0].momentum()));
134      }
135    }
136
137
138    /// Finalize
139    void finalize() {
140      scale(_h, crossSection()/femtobarn/sumOfWeights());
141      efficiency(_h["mjj"], _h["jve_mjj"], _s["jve_mjj"]);
142    }
143
144    /// @}
145
146
147    /// Check if jet is between tagging jets
148    bool isBetween(const Jet &probe, const Jet &boundary1, const Jet &boundary2) {
149      double y_p = probe.rapidity();
150      double y_b1 = boundary1.rapidity();
151      double y_b2 = boundary2.rapidity();
152
153      double y_min = std::min(y_b1, y_b2);
154      double y_max = std::max(y_b1, y_b2);
155
156      return  (y_p > y_min && y_p < y_max);
157    }
158
159    double signedDeltaPhi(Jet &j1, Jet &j2) {
160      double dphijj = 0.;
161      if (j1.rap() > j2.rap())  dphijj = j1.phi() - j2.phi();
162      else                      dphijj = j2.phi() - j1.phi();
163      return mapAngleMPiToPi(dphijj)/M_PI;
164    }
165
166
167  private:
168
169    /// @name Parameters for specialised e/mu and dressed/bare subclassing
170    /// @{
171    double _dR;
172    PdgId _lepton;
173    /// @}
174
175    /// @name Histograms
176    /// @{
177    map<string,Histo1DPtr> _h;
178    map<string,Estimate1DPtr> _s;
179    /// @}
180
181  };
182
183
184  RIVET_DECLARE_PLUGIN(MC_ZVBF);
185
186}