Rivet analyses referenceCMS_2018_I1646260Search for BSM with 2 soft leptons + MET at 13 TeVExperiment: ATLAS (LHC) Inspire ID: 1646260 Status: VALIDATED NOHEPDATA Authors:
Beam energies: (6500.0, 6500.0) GeV Run details:
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}
|