rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

CMS_2018_I1646260

Search for BSM with 2 soft leptons + MET at 13 TeV
Experiment: ATLAS (LHC)
Inspire ID: 1646260
Status: VALIDATED NOHEPDATA
Authors:
  • Andy Buckley
  • Derek Yeung
References: Beams: p+ p+
Beam energies: (6500.0, 6500.0) GeV
Run details:
  • Low-mass l^+ l^- + pTmiss (l = el, mu)

A search is presented for new physics in events with two low-momentum, oppositely charged leptons (electrons or muons) and missing transverse momentum in proton-proton collisions at a centre-of-mass energy of 13 TeV. The data collected using the CMS detector at the LHC correspond to an integrated luminosity of 35.9/fb. The observed event yields are consistent with the expectations from the Standard Model. The analysis is optimised for study of pair production of charginos and neutralinos with nearly degenerate masses, as expected in natural supersymmetry models with light higgsinos, as well as in terms of the pair production of top squarks, when the lightest neutralino and the top squark have similar masses.

Source code: CMS_2018_I1646260.cc
  1// -*- C++ -*-
  2#include "Rivet/Analysis.hh"
  3#include "Rivet/Projections/FinalState.hh"
  4#include "Rivet/Projections/DirectFinalState.hh"
  5#include "Rivet/Projections/IndirectFinalState.hh"
  6#include "Rivet/Projections/TauFinder.hh"
  7#include "Rivet/Projections/FastJets.hh"
  8#include "Rivet/Projections/MissingMomentum.hh"
  9#include "Rivet/Projections/Smearing.hh"
 10#include "Rivet/Tools/Cutflow.hh"
 11
 12namespace Rivet {
 13
 14
 15  /// CMS 2 soft-lepton + MET in 36/fb of 13 TeV pp
 16  class CMS_2018_I1646260 : public Analysis {
 17  public:
 18
 19    /// Constructor
 20    RIVET_DEFAULT_ANALYSIS_CTOR(CMS_2018_I1646260);
 21
 22
 23    /// @name Analysis methods
 24    /// @{
 25
 26    /// Book histograms and initialise projections before the run
 27    void init() {
 28
 29      PromptFinalState electrons(Cuts::abspid == PID::ELECTRON);
 30      SmearedParticles recoelectrons(electrons, [](const Particle& e) -> double {
 31          static const vector<double> ptedges = { 5., 10., 15., 20., 25., 30. };
 32          static const vector<double> etaedges = { 0.0, 0.8, 1.442, 1.556, 2.0, 2.5 };
 33          static const vector<vector<double>> effs = { { 0.336, 0.344, 0.233, 0.309, 0.243 },
 34                                                       { 0.412, 0.402, 0.229, 0.359, 0.287 },
 35                                                       { 0.465, 0.448, 0.250, 0.394, 0.327 },
 36                                                       { 0.496, 0.476, 0.261, 0.408, 0.341 },
 37                                                       { 0.503, 0.482, 0.255, 0.418, 0.352 } };
 38          const int ipt = binIndex(e.pT()/GeV, ptedges);
 39          const int ieta = binIndex(e.abseta(), etaedges);
 40          if (ipt < 0 || ieta < 0) return 0;
 41          return effs[ipt][ieta];
 42        }, ELECTRON_SMEAR_CMS_RUN2);
 43      declare(recoelectrons, "Electrons");
 44
 45      PromptFinalState muons(Cuts::abspid == PID::MUON);
 46      SmearedParticles recomuons(muons, [](const Particle& m) -> double {
 47          static const vector<double> ptedges = { 3.5, 10., 15., 20., 25., 30. };
 48          static const vector<double> etaedges = { 0.0, 0.9, 1.2, 2.1, 2.4 };
 49          static const vector<vector<double>> effs = { { 0.647, 0.627, 0.610, 0.566 },
 50                                                       { 0.718, 0.662, 0.660, 0.629 },
 51                                                       { 0.739, 0.694, 0.678, 0.655 },
 52                                                       { 0.760, 0.725, 0.685, 0.670 },
 53                                                       { 0.763, 0.733, 0.723, 0.696 } };
 54          const int ipt = binIndex(m.pT()/GeV, ptedges);
 55          const int ieta = binIndex(m.abseta(), etaedges);
 56          if (ipt < 0 || ieta < 0) return 0;
 57          return effs[ipt][ieta];
 58        }, MUON_SMEAR_CMS_RUN2);
 59      declare(recomuons, "Muons");
 60
 61      TauFinder taus(TauDecay::LEPTONIC);
 62      declare(taus, "Taus");
 63
 64      FastJets jets4(IndirectFinalState(Cuts::abseta < 4.9), JetAlg::ANTIKT, 0.4);
 65      SmearedJets recojets4(jets4, JET_SMEAR_CMS_RUN2, JET_BTAG_EFFS(0.8, 0.1, 0.4));
 66      declare(recojets4, "Jets");
 67
 68      // MissingMomentum met(FinalState(Cuts::abseta < 4.9));
 69      // SmearedMET recomet(met, MET_SMEAR_CMS_RUN2);
 70      // declare(recomet, "MET");
 71
 72
 73      // Book SR counters
 74      for (size_t i = 0; i < 3; ++i) {
 75        for (size_t j = 0; j < 4; ++j)
 76          book(_srcounts_ewino[i][j], "sr_ewino_" + toString(i) + "_" + toString(j));
 77        for (size_t j = 0; j < 3; ++j)
 78          book(_srcounts_stop[i][j],   "sr_stop_" + toString(i) + "_" + toString(j));
 79      }
 80
 81      // Cut-flow setup
 82      const strings cfnames = {"2mu", "mu+mu-", "pTmumu > 3 GeV", "Mmumu in [4,50] GeV",
 83                               "Mmumu not in [9,10.5] GeV", "pTmiss in [125, 200] GeV",
 84                               "mu+pTmiss trigger", "ISR jet", "HT > 100 GeV",
 85                               "pTmiss/HT in [0.6, 1.4]", "b-tag veto", "Mtautau veto"};
 86      book(_cutflows, {"EW", "St"}, {cfnames+strings{"MT < 70 GeV"}, cfnames});
 87
 88    }
 89
 90
 91    /// Perform the per-event analysis
 92    void analyze(const Event& event) {
 93
 94      _cutflows->groupfillinit();
 95
 96      // Leptons
 97      const Particles elecs = apply<ParticleFinder>(event, "Electrons").particlesByPt(Cuts::pT > 5*GeV && Cuts::abseta < 2.5);
 98      const Particles muons = apply<ParticleFinder>(event, "Muons").particlesByPt(Cuts::pT > 5*GeV && Cuts::pT < 30*GeV && Cuts::abseta < 2.4);
 99      const Particles leptons = sortByPt(elecs + muons);
100      if (leptons.empty()) vetoEvent;
101      _nevtMu += 1;
102
103      if (leptons.size() != 2) vetoEvent;
104      _cutflows->groupfillnext();
105      if (leptons[0].charge() * leptons[1].charge() >= 0) vetoEvent;
106      _cutflows->groupfillnext();
107
108      // Dilepton cuts
109      const FourMomentum pll = leptons[0].mom() + leptons[1].mom();
110      if (pll.pT() < 3*GeV) vetoEvent;
111      _cutflows->groupfillnext();
112      const bool sameflav = (leptons[0].abspid() == leptons[1].abspid());
113      if (sameflav) {
114        if (!inRange(pll.mass()/GeV, 4, 50)) vetoEvent;
115        _cutflows->groupfillnext();
116        if (inRange(pll.mass()/GeV, 9, 10.5)) vetoEvent;
117        _cutflows->groupfillnext();
118      } else {
119        _cutflows->groupfillnext();
120        _cutflows->groupfillnext();
121      }
122
123      // Jets
124      Jets jets = apply<SmearedJets>(event, "Jets").jetsByPt(Cuts::pT > 25*GeV && Cuts::abseta < 2.4);
125
126      // MET
127      FourMomentum p4miss;
128      for (const Jet& j : jets) p4miss -= j;
129      for (const Particle& e : elecs) p4miss -= e;
130      const double ptmiss = p4miss.pT();
131      for (const Particle& m : muons) p4miss -= m;
132      const double ptmiss_mu = p4miss.pT();
133      const bool mumu = (muons.size() == 2);
134      if (ptmiss < (mumu ? 125*GeV : 200*GeV)) vetoEvent;
135      if (ptmiss_mu < (mumu ? 125*GeV : 200*GeV)) vetoEvent;
136      _cutflows->groupfillnext();
137
138      // mu+pTmiss trigger (65% efficient in low-ETmiss region)
139      double triggerSF = 1.0;
140      if (mumu && ptmiss < 200*GeV) triggerSF = 0.65;
141      _cutflows->groupfillnext(triggerSF);
142
143      // ISR jet
144      if (jets.empty()) vetoEvent;
145      _cutflows->groupfillnext(triggerSF);
146
147      // MET/HT
148      const double ht = sum(jets, Kin::pT, 0.0);
149      if (ht < 100*GeV) vetoEvent;
150      _cutflows->groupfillnext(triggerSF);
151      if (!inRange(ptmiss/ht, 0.6, 1.4)) vetoEvent;
152      _cutflows->groupfillnext(triggerSF);
153
154      // b-jet veto
155      if (any(jets, hasBTag(Cuts::pT > 5*GeV))) vetoEvent; //< b-jet veto with ad hoc tagging threshold
156      _cutflows->groupfillnext(triggerSF);
157
158      // Tau veto
159      const Particles taus = apply<ParticleFinder>(event, "Taus").particlesByPt();
160      if (taus.size() >= 2) {
161        const double mtt = (taus[0].mom() + taus[1].mom()).mass();
162        if (mtt < 160*GeV) vetoEvent;
163      }
164      _cutflows->groupfillnext(triggerSF);
165
166      // EWino SR (ee, mumu)
167      if (sameflav) {
168        for (const Particle& l : leptons) {
169          if (l.abspid() == PID::MUON and l.pT() < 5*GeV) vetoEvent;
170          if (mT(l.mom(), p4miss) > 70*GeV) vetoEvent;
171        }
172        _cutflows->fillnext("EW", triggerSF);
173        static const vector<double> ptmissedges_ewino = {125., 200., 250., DBL_MAX};
174        static const vector<double> mlledges_ewino = {4., 9., 10.5, 20., 30., 50.};
175        const int iptm = binIndex(ptmiss/GeV, ptmissedges_ewino);
176        const int imll = binIndex(pll.mass()/GeV, mlledges_ewino);
177        _srcounts_ewino[iptm][imll < 1 ? 0 : imll-1]->fill(triggerSF);
178
179      } else {
180
181        // Stop SR
182        if (leptons[0].abspid() == PID::MUON and leptons[0].pT() < 5*GeV) vetoEvent;
183        _cutflows->fillnext("St", triggerSF);
184        static const vector<double> ptmissedges_stop = {125., 200., 300., DBL_MAX};
185        static const vector<double> ptledges_stop = {5., 12., 20., 30.};
186        const int iptm = binIndex(ptmiss/GeV, ptmissedges_stop);
187        const int iptl = binIndex(leptons[0].pT()/GeV, ptledges_stop);
188        _srcounts_stop[iptm][iptl]->fill(triggerSF);
189      }
190
191    }
192
193
194    /// Normalise histograms etc., after the run
195    void finalize() {
196      MSG_INFO("Num events with >= 1 muon = " << _nevtMu << " / " << numEvents());
197
198      const double sf = 35.9*crossSection()/femtobarn/sumOfWeights();
199      for (size_t i = 0; i < 3; ++i) {
200        scale(_srcounts_ewino[i], sf);
201        scale(_srcounts_stop[i], sf);
202      }
203      scale(_cutflows, sf);
204      MSG_INFO("CUTFLOWS:\n\n" << _cutflows);
205    }
206
207    /// @}
208
209
210    /// @name Histograms
211    /// @{
212    CounterPtr _srcounts_ewino[3][4], _srcounts_stop[3][3];
213    /// @}
214
215    /// Cut-flows
216    int _nevtMu = 0;
217    CutflowsPtr _cutflows;
218
219
220  };
221
222
223  RIVET_DECLARE_PLUGIN(CMS_2018_I1646260);
224
225
226}