ATLAS_2016_I1458270.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/FinalState.hh" 00004 #include "Rivet/Projections/PromptFinalState.hh" 00005 #include "Rivet/Projections/FastJets.hh" 00006 #include "Rivet/Projections/Sphericity.hh" 00007 #include "Rivet/Projections/SmearedParticles.hh" 00008 #include "Rivet/Projections/SmearedJets.hh" 00009 #include "Rivet/Projections/SmearedMET.hh" 00010 #include "Rivet/Tools/Cutflow.hh" 00011 00012 namespace Rivet { 00013 00014 00015 /// @brief ATLAS 0-lepton SUSY search with 3.2/fb of 13 TeV pp data 00016 class ATLAS_2016_I1458270 : public Analysis { 00017 public: 00018 00019 /// Constructor 00020 DEFAULT_RIVET_ANALYSIS_CTOR(ATLAS_2016_I1458270); 00021 00022 00023 /// @name Analysis methods 00024 //@{ 00025 00026 /// Book histograms and initialise projections before the run 00027 void init() { 00028 00029 // Initialise and register projections 00030 FinalState calofs(Cuts::abseta < 4.8); 00031 FastJets fj(calofs, FastJets::ANTIKT, 0.4); 00032 declare(fj, "TruthJets"); 00033 declare(SmearedJets(fj, JET_SMEAR_ATLAS_RUN2, JET_BTAG_ATLAS_RUN2_MV2C20), "RecoJets"); 00034 00035 MissingMomentum mm(calofs); 00036 declare(mm, "TruthMET"); 00037 declare(SmearedMET(mm, MET_SMEAR_ATLAS_RUN2), "RecoMET"); 00038 00039 PromptFinalState es(Cuts::abseta < 2.47 && Cuts::abspid == PID::ELECTRON, true, true); 00040 declare(es, "TruthElectrons"); 00041 declare(SmearedParticles(es, ELECTRON_EFF_ATLAS_RUN2, ELECTRON_SMEAR_ATLAS_RUN2), "RecoElectrons"); 00042 00043 PromptFinalState mus(Cuts::abseta < 2.7 && Cuts::abspid == PID::MUON, true); 00044 declare(mus, "TruthMuons"); 00045 declare(SmearedParticles(mus, MUON_EFF_ATLAS_RUN2, MUON_SMEAR_ATLAS_RUN2), "RecoMuons"); 00046 00047 00048 // Book histograms/counters 00049 _h_2jl = bookCounter("2jl"); 00050 _h_2jm = bookCounter("2jm"); 00051 _h_2jt = bookCounter("2jt"); 00052 _h_4jt = bookCounter("4jt"); 00053 _h_5j = bookCounter("5j"); 00054 _h_6jm = bookCounter("6jm"); 00055 _h_6jt = bookCounter("6jt"); 00056 00057 00058 // Book cut-flows 00059 const vector<string> cuts2j = {"Pre-sel+MET+pT1", "Njet", "Dphi_min(j,MET)", "pT2", "MET/sqrtHT", "m_eff(incl)"}; 00060 _flows.addCutflow("2jl", cuts2j); 00061 _flows.addCutflow("2jm", cuts2j); 00062 _flows.addCutflow("2jt", cuts2j); 00063 const vector<string> cutsXj = {"Pre-sel+MET+pT1", "Njet", "Dphi_min(j,MET)", "pT2", "pT4", "Aplanarity", "MET/m_eff(Nj)", "m_eff(incl)"}; 00064 _flows.addCutflow("4jt", cutsXj); 00065 _flows.addCutflow("5j", cutsXj); 00066 _flows.addCutflow("6jm", cutsXj); 00067 _flows.addCutflow("6jt", cutsXj); 00068 00069 } 00070 00071 00072 /// Perform the per-event analysis 00073 void analyze(const Event& event) { 00074 00075 _flows.fillinit(); 00076 00077 // Same MET cut for all signal regions 00078 //const Vector3 vmet = -apply<MissingMomentum>(event, "TruthMET").vectorEt(); 00079 const Vector3 vmet = -apply<SmearedMET>(event, "RecoMET").vectorEt(); 00080 const double met = vmet.mod(); 00081 if (met < 200*GeV) vetoEvent; 00082 00083 // Get baseline electrons, muons, and jets 00084 Particles elecs = apply<ParticleFinder>(event, "RecoElectrons").particles(Cuts::pT > 10*GeV); 00085 Particles muons = apply<ParticleFinder>(event, "RecoMuons").particles(Cuts::pT > 10*GeV); 00086 Jets jets = apply<JetAlg>(event, "RecoJets").jetsByPt(Cuts::pT > 20*GeV && Cuts::abseta < 2.8); ///< @todo Pile-up subtraction 00087 00088 // Jet/electron/muons overlap removal and selection 00089 // Remove any |eta| < 2.8 jet within dR = 0.2 of a baseline electron 00090 for (const Particle& e : elecs) 00091 ifilter_discard(jets, deltaRLess(e, 0.2, RAPIDITY)); 00092 // Remove any electron or muon with dR < 0.4 of a remaining (Nch > 3) jet 00093 for (const Jet& j : jets) { 00094 /// @todo Add track efficiency random filtering 00095 ifilter_discard(elecs, deltaRLess(j, 0.4, RAPIDITY)); 00096 if (j.particles(Cuts::abscharge > 0 && Cuts::pT > 500*MeV).size() >= 3) 00097 ifilter_discard(muons, deltaRLess(j, 0.4, RAPIDITY)); 00098 } 00099 // Discard the softer of any electrons within dR < 0.05 00100 for (size_t i = 0; i < elecs.size(); ++i) { 00101 const Particle& e1 = elecs[i]; 00102 /// @todo Would be nice to pass a "tail view" for the filtering, but awkward without range API / iterator guts 00103 ifilter_discard(elecs, [&](const Particle& e2){ return e2.pT() < e1.pT() && deltaR(e1,e2) < 0.05; }); 00104 } 00105 00106 // Loose electron selection 00107 ifilter_discard(elecs, ParticleEffFilter(ELECTRON_IDEFF_ATLAS_RUN2_LOOSE)); 00108 00109 // Veto the event if there are any remaining baseline leptons 00110 if (!elecs.empty()) vetoEvent; 00111 if (!muons.empty()) vetoEvent; 00112 00113 // Signal jets have pT > 50 GeV 00114 const Jets jets50 = filter_select(jets, Cuts::pT > 50*GeV); 00115 if (jets50.size() < 2) vetoEvent; 00116 vector<double> jetpts; transform(jets, jetpts, pT); 00117 vector<double> jetpts50; transform(jets50, jetpts50, pT); 00118 const double j1pt = jetpts50[0]; 00119 const double j2pt = jetpts50[1]; 00120 if (j1pt < 200*GeV) vetoEvent; 00121 00122 // Construct multi-jet observables 00123 const double ht = sum(jetpts, 0.0); 00124 const double met_sqrt_ht = met / sqrt(ht); 00125 const double meff_incl = sum(jetpts50, met); 00126 00127 // Get dphis between MET and jets 00128 vector<double> dphimets50; transform(jets50, dphimets50, deltaPhiWRT(vmet)); 00129 const double min_dphi_met_2 = min(head(dphimets50, 2)); 00130 const double min_dphi_met_3 = min(head(dphimets50, 3)); 00131 MSG_DEBUG(dphimets50 << ", " << min_dphi_met_2 << ", " << min_dphi_met_3); 00132 00133 // Jet aplanarity 00134 Sphericity sph; sph.calc(jets); 00135 const double aplanarity = sph.aplanarity(); 00136 00137 00138 // Fill SR counters 00139 // 2-jet SRs 00140 if (_flows["2jl"].filltail({true, true, min_dphi_met_2 > 0.8, j2pt > 200*GeV, 00141 met_sqrt_ht > 15*sqrt(GeV), meff_incl > 1200*GeV})) _h_2jl->fill(event.weight()); 00142 if (_flows["2jm"].filltail({j1pt > 300*GeV, true, min_dphi_met_2 > 0.4, j2pt > 50*GeV, 00143 met_sqrt_ht > 15*sqrt(GeV), meff_incl > 1600*GeV})) _h_2jm->fill(event.weight()); 00144 if (_flows["2jt"].filltail({true, true, min_dphi_met_2 > 0.8, j2pt > 200*GeV, 00145 met_sqrt_ht > 20*sqrt(GeV), meff_incl > 2000*GeV})) _h_2jt->fill(event.weight()); 00146 00147 // Upper multiplicity SRs 00148 const double j4pt = jets50.size() > 3 ? jetpts50[3] : -1; 00149 const double j5pt = jets50.size() > 4 ? jetpts50[4] : -1; 00150 const double j6pt = jets50.size() > 5 ? jetpts50[5] : -1; 00151 const double meff_4 = jets50.size() > 3 ? sum(head(jetpts50, 4), 0.0) : -1; 00152 const double meff_5 = jets50.size() > 4 ? meff_4 + jetpts50[4] : -1; 00153 const double meff_6 = jets50.size() > 5 ? meff_5 + jetpts50[5] : -1; 00154 const double met_meff_4 = met / meff_4; 00155 const double met_meff_5 = met / meff_5; 00156 const double met_meff_6 = met / meff_6; 00157 const double min_dphi_met_more = jets50.size() > 3 ? min(tail(dphimets50, -3)) : -1; 00158 00159 if (_flows["4jt"].filltail({true, jets50.size() >= 4, min_dphi_met_3 > 0.4 && min_dphi_met_more > 0.2, 00160 jetpts[1] > 200*GeV, j4pt > 100*GeV, aplanarity > 0.04, met_meff_4 > 0.20, meff_incl > 2200*GeV})) 00161 _h_4jt->fill(event.weight()); 00162 if (_flows["5j"].filltail({true, jets50.size() >= 5, min_dphi_met_3 > 0.4 && min_dphi_met_more > 0.2, 00163 jetpts[1] > 200*GeV, j4pt > 100*GeV && j5pt > 50*GeV, aplanarity > 0.04, met_meff_5 > 0.25, meff_incl > 1600*GeV})) 00164 _h_5j->fill(event.weight()); 00165 if (_flows["6jm"].filltail({true, jets50.size() >= 6, min_dphi_met_3 > 0.4 && min_dphi_met_more > 0.2, 00166 jetpts[1] > 200*GeV, j4pt > 100*GeV && j6pt > 50*GeV, aplanarity > 0.04, met_meff_6 > 0.25, meff_incl > 1600*GeV})) 00167 _h_6jm->fill(event.weight()); 00168 if (_flows["6jt"].filltail({true, jets50.size() >= 6, min_dphi_met_3 > 0.4 && min_dphi_met_more > 0.2, 00169 jetpts[1] > 200*GeV, j4pt > 100*GeV && j6pt > 50*GeV, aplanarity > 0.04, met_meff_6 > 0.20, meff_incl > 2000*GeV})) 00170 _h_6jt->fill(event.weight()); 00171 00172 } 00173 00174 00175 /// Normalise histograms etc., after the run 00176 void finalize() { 00177 00178 const double sf = 3.2*crossSection()/femtobarn/sumOfWeights(); 00179 scale({_h_2jl, _h_2jl, _h_2jl}, sf); 00180 scale({_h_4jt, _h_5j}, sf); 00181 scale({_h_6jm, _h_6jt}, sf); 00182 00183 MSG_INFO("CUTFLOWS:\n\n" << _flows); 00184 00185 } 00186 00187 //@} 00188 00189 00190 private: 00191 00192 /// @name Histograms 00193 //@{ 00194 CounterPtr _h_2jl, _h_2jm, _h_2jt; 00195 CounterPtr _h_4jt, _h_5j; 00196 CounterPtr _h_6jm, _h_6jt; 00197 //@} 00198 00199 /// Cut-flows 00200 Cutflows _flows; 00201 00202 }; 00203 00204 00205 00206 // The hook for the plugin system 00207 DECLARE_RIVET_PLUGIN(ATLAS_2016_I1458270); 00208 00209 00210 } Generated on Tue Dec 13 2016 16:32:36 for The Rivet MC analysis system by ![]() |