rivet is hosted by Hepforge, IPPP Durham
ATLAS_2016_I1452559.cc
Go to the documentation of this file.
00001 #include "Rivet/Analysis.hh"
00002 #include "Rivet/Projections/FinalState.hh"
00003 #include "Rivet/Projections/IdentifiedFinalState.hh"
00004 #include "Rivet/Projections/VisibleFinalState.hh"
00005 #include "Rivet/Projections/FastJets.hh"
00006 #include "Rivet/Projections/MissingMomentum.hh"
00007 #include "Rivet/Projections/SmearedParticles.hh"
00008 #include "Rivet/Projections/SmearedJets.hh"
00009 #include "Rivet/Projections/SmearedMET.hh"
00010 
00011 namespace Rivet {
00012 
00013 
00014   /// ATLAS 13 TeV monojet search with 3.2/fb of pp data
00015   class ATLAS_2016_I1452559 : public Analysis {
00016   public:
00017 
00018     DEFAULT_RIVET_ANALYSIS_CTOR(ATLAS_2016_I1452559);
00019 
00020     void init() {
00021 
00022       FastJets jets(FinalState(Cuts::abseta < 4.9), FastJets::ANTIKT, 0.4);
00023       SmearedJets recojets(jets, JET_SMEAR_ATLAS_RUN1);
00024       declare(recojets, "Jets");
00025 
00026       FinalState electrons(Cuts::abspid == PID::ELECTRON && Cuts::abseta < 2.47 && Cuts::pT > 20*GeV);
00027       SmearedParticles recoelectrons(electrons, ELECTRON_EFF_ATLAS_RUN2);
00028       declare(recoelectrons, "Electrons");
00029 
00030       FinalState muons(Cuts::abspid == PID::MUON && Cuts::abseta < 2.50 && Cuts::pT > 10*GeV);
00031       SmearedParticles recomuons(muons, MUON_EFF_ATLAS_RUN2);
00032       declare(recomuons, "Muons");
00033 
00034       VisibleFinalState calofs(Cuts::abseta < 4.9 && Cuts::abspid != PID::MUON);
00035       MissingMomentum met(calofs);
00036       SmearedMET recomet(met, MET_SMEAR_ATLAS_RUN2);
00037       declare(recomet, "MET");
00038 
00039 
00040       /// Book histograms
00041       for (size_t i = 0; i < 7; ++i)
00042         _count_IM[i] = bookCounter("count_IM" + toString(i+1));
00043       for (size_t i = 0; i < 6; ++i)
00044         _count_EM[i] = bookCounter("count_EM" + toString(i+1));
00045 
00046     }
00047 
00048 
00049     void analyze(const Event& event) {
00050 
00051       const Jets jets = apply<JetAlg>(event, "Jets").jetsByPt(Cuts::pT > 20*GeV && Cuts::abseta < 2.8);
00052       const Particles elecs = apply<ParticleFinder>(event, "Electrons").particlesByPt();
00053       const Particles mus = apply<ParticleFinder>(event, "Muons").particlesByPt();
00054       MSG_DEBUG("Number of raw jets, electrons, muons = "
00055                 << jets.size() << ", " << elecs.size() << ", " << mus.size());
00056 
00057       // Discard jets very close to electrons, or with low track multiplicity and close to muons
00058       const Jets isojets = filter_discard(jets, [&](const Jet& j) {
00059           /// @todo Add track efficiency random filtering
00060           if (any(elecs, deltaRLess(j, 0.2))) return true;
00061           if (j.particles(Cuts::abscharge > 0 && Cuts::pT > 0.4*GeV).size() < 3 &&
00062               any(mus, deltaRLess(j, 0.4))) return true;
00063           return false;
00064         });
00065 
00066       // Discard electrons close to remaining jets
00067       const Particles isoelecs = filter_discard(elecs, [&](const Particle& e) {
00068           return any(isojets, deltaRLess(e, 0.4));
00069         });
00070 
00071       // Discard muons close to remaining jets
00072       const Particles isomus = filter_discard(mus, [&](const Particle& m) {
00073           for (const Jet& j : isojets) {
00074             if (deltaR(j,m) > 0.4) continue;
00075             if (j.particles(Cuts::abscharge > 0 && Cuts::pT > 0.4*GeV).size() > 3) return true;
00076           }
00077           return false;
00078         });
00079 
00080       // Calculate ETmiss
00081       //const Vector3& vet = apply<MissingMomentum>(event, "MET").vectorEt();
00082       const Vector3& vet = apply<SmearedMET>(event, "MET").vectorEt();
00083       const double etmiss = vet.perp();
00084 
00085 
00086       // Event selection cuts
00087       if (etmiss < 250*GeV) vetoEvent;
00088       // Require at least one jet with pT > 250 GeV and |eta| < 2.4
00089       if (filter_select(isojets, Cuts::pT > 250*GeV && Cuts::abseta < 2.4).empty()) vetoEvent;
00090       // Require at most 4 jets with pT > 30 GeV and |eta| < 2.8
00091       if (filter_select(isojets, Cuts::pT > 30*GeV).size() > 4) vetoEvent;
00092       // Require no isolated jets within |dphi| < 0.4 of the MET vector
00093       if (any(isojets, deltaPhiLess(-vet, 0.4))) vetoEvent;
00094       // Require no isolated electrons or muons
00095       if (!isoelecs.empty() || !isomus.empty()) vetoEvent;
00096 
00097 
00098       ////////////////////
00099 
00100 
00101       const double weight = event.weight();
00102 
00103       // Get ETmiss bin number and fill counters
00104       const int i_etmiss = binIndex(etmiss/GeV, ETMISS_CUTS);
00105       // Inclusive ETmiss bins
00106       for (int ibin = 0; ibin < 7; ++ibin)
00107         if (i_etmiss >= ibin) _count_IM[ibin]->fill(weight);
00108       // Exclusive ETmiss bins
00109       if (inRange(i_etmiss, 0, 6)) _count_EM[i_etmiss]->fill(weight);
00110 
00111     }
00112 
00113 
00114     void finalize() {
00115       const double norm = 3.2*crossSection()/femtobarn;
00116       scale(_count_IM, norm/sumOfWeights());
00117       scale(_count_EM, norm/sumOfWeights());
00118     }
00119 
00120 
00121   private:
00122 
00123     const vector<double> ETMISS_CUTS = { 250, 300, 350, 400, 500, 600, 700, 13000 };
00124     CounterPtr _count_IM[7], _count_EM[6];
00125 
00126   };
00127 
00128 
00129   // The hook for the plugin system
00130   DECLARE_RIVET_PLUGIN(ATLAS_2016_I1452559);
00131 
00132 }