rivet is hosted by Hepforge, IPPP Durham
ATLAS_2012_I1112263.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Tools/BinnedHistogram.hh"
00004 #include "Rivet/RivetYODA.hh"
00005 #include "Rivet/Tools/Logging.hh"
00006 #include "Rivet/Projections/FinalState.hh"
00007 #include "Rivet/Projections/ChargedFinalState.hh"
00008 #include "Rivet/Projections/VisibleFinalState.hh"
00009 #include "Rivet/Projections/VetoedFinalState.hh"
00010 #include "Rivet/Projections/IdentifiedFinalState.hh"
00011 #include "Rivet/Projections/FastJets.hh"
00012 #include "Rivet/Tools/RivetMT2.hh"
00013 
00014 namespace Rivet {
00015 
00016   /// @author Peter Richardson
00017   class ATLAS_2012_I1112263 : public Analysis {
00018   public:
00019 
00020     /// @name Constructors etc.
00021     //@{
00022 
00023     /// Constructor
00024     ATLAS_2012_I1112263()
00025       : Analysis("ATLAS_2012_I1112263")
00026     {    }
00027 
00028     //@}
00029 
00030 
00031   public:
00032 
00033     /// @name Analysis methods
00034     //@{
00035 
00036     /// Book histograms and initialise projections before the run
00037     void init() {
00038 
00039       // projection to find the electrons
00040       std::vector<std::pair<double, double> > eta_e;
00041       eta_e.push_back(make_pair(-2.47,2.47));
00042       IdentifiedFinalState elecs(eta_e, 10.0*GeV);
00043       elecs.acceptIdPair(ELECTRON);
00044       addProjection(elecs, "elecs");
00045 
00046       // projection to find the muons
00047       std::vector<std::pair<double, double> > eta_m;
00048       eta_m.push_back(make_pair(-2.4,2.4));
00049       IdentifiedFinalState muons(eta_m, 10.0*GeV);
00050       muons.acceptIdPair(MUON);
00051       addProjection(muons, "muons");
00052 
00053       // for pTmiss
00054       addProjection(VisibleFinalState(-4.9,4.9),"vfs");
00055 
00056       VetoedFinalState vfs;
00057       vfs.addVetoPairId(MUON);
00058 
00059       /// Jet finder
00060       addProjection(FastJets(vfs, FastJets::ANTIKT, 0.4),
00061                     "AntiKtJets04");
00062 
00063       // all tracks (to do deltaR with leptons)
00064       addProjection(ChargedFinalState(-3.0,3.0),"cfs");
00065 
00066       // Book histograms
00067       _hist_leptonpT_SR1.push_back(bookHisto1D("hist_lepton_pT_1_SR1",11,0.,220.));
00068       _hist_leptonpT_SR1.push_back(bookHisto1D("hist_lepton_pT_2_SR1", 7,0.,140.));
00069       _hist_leptonpT_SR1.push_back(bookHisto1D("hist_lepton_pT_3_SR1", 8,0.,160.));
00070       _hist_leptonpT_SR2.push_back(bookHisto1D("hist_lepton_pT_1_SR2",11,0.,220.));
00071       _hist_leptonpT_SR2.push_back(bookHisto1D("hist_lepton_pT_2_SR2", 7,0.,140.));
00072       _hist_leptonpT_SR2.push_back(bookHisto1D("hist_lepton_pT_3_SR2", 8,0.,160.));
00073       _hist_etmiss_SR1_A = bookHisto1D("hist_etmiss_SR1_A",15,10.,310.);
00074       _hist_etmiss_SR1_B = bookHisto1D("hist_etmiss_SR1_B", 9,10.,190.);
00075       _hist_etmiss_SR2_A = bookHisto1D("hist_etmiss_SR2_A",15,10.,310.);
00076       _hist_etmiss_SR2_B = bookHisto1D("hist_etmiss_SR2_B", 9,10.,190.);
00077       _hist_mSFOS= bookHisto1D("hist_mSFOF",9,0.,180.);
00078 
00079       _count_SR1 = bookHisto1D("count_SR1", 1, 0., 1.);
00080       _count_SR2 = bookHisto1D("count_SR2", 1, 0., 1.);
00081     }
00082 
00083 
00084     /// Perform the per-event analysis
00085     void analyze(const Event& event) {
00086       const double weight = event.weight();
00087       // get the jet candidates
00088       Jets cand_jets;
00089       foreach (const Jet& jet,
00090                applyProjection<FastJets>(event, "AntiKtJets04").jetsByPt(20.0*GeV) ) {
00091         if ( fabs( jet.momentum().eta() ) < 2.8 ) {
00092           cand_jets.push_back(jet);
00093         }
00094       }
00095 
00096       // candidate muons
00097       ParticleVector cand_mu;
00098       ParticleVector chg_tracks =
00099         applyProjection<ChargedFinalState>(event, "cfs").particles();
00100       foreach ( const Particle & mu,
00101                 applyProjection<IdentifiedFinalState>(event, "muons").particlesByPt() ) {
00102         double pTinCone = -mu.momentum().pT();
00103         foreach ( const Particle & track, chg_tracks ) {
00104           if ( deltaR(mu.momentum(),track.momentum()) <= 0.2 )
00105             pTinCone += track.momentum().pT();
00106         }
00107         if ( pTinCone < 1.8*GeV )
00108           cand_mu.push_back(mu);
00109       }
00110 
00111       // candidate electrons
00112       ParticleVector cand_e;
00113       foreach ( const Particle & e,
00114                 applyProjection<IdentifiedFinalState>(event, "elecs").particlesByPt() ) {
00115         double eta = e.momentum().eta();
00116         // remove electrons with pT<15 in old veto region
00117         // (NOT EXPLICIT IN THIS PAPER BUT IN SIMILAR 4 LEPTON PAPER and THIS DESCRPITION
00118         //  IS MUCH WORSE SO ASSUME THIS IS DONE)
00119         if( fabs(eta)>1.37 && fabs(eta) < 1.52 && e.momentum().perp()< 15.*GeV)
00120           continue;
00121         double pTinCone = -e.momentum().perp();
00122         foreach ( const Particle & track, chg_tracks ) {
00123           if ( deltaR(e.momentum(),track.momentum()) <= 0.2 )
00124             pTinCone += track.momentum().pT();
00125         }
00126         if (pTinCone/e.momentum().perp()<0.1) {
00127           cand_e.push_back(e);
00128         }
00129       }
00130 
00131       // resolve jet/lepton ambiguity
00132       // (NOT EXPLICIT IN THIS PAPER BUT IN SIMILAR 4 LEPTON PAPER and THIS DESCRPITION
00133       //  IS MUCH WORSE SO ASSUME THIS IS DONE)
00134       Jets recon_jets;
00135       foreach ( const Jet& jet, cand_jets ) {
00136         bool away_from_e = true;
00137         foreach ( const Particle & e, cand_e ) {
00138           if ( deltaR(e.momentum(),jet.momentum()) <= 0.2 ) {
00139             away_from_e = false;
00140             break;
00141           }
00142         }
00143         if ( away_from_e )
00144           recon_jets.push_back( jet );
00145       }
00146 
00147       // only keep electrons more than R=0.4 from jets
00148       ParticleVector recon_e;
00149       foreach ( const Particle & e, cand_e ) {
00150         bool away = true;
00151         foreach ( const Jet& jet, recon_jets ) {
00152           if ( deltaR(e.momentum(),jet.momentum()) < 0.4 ) {
00153             away = false;
00154             break;
00155           }
00156         }
00157         // and 0.1 from any muons
00158         if ( ! away ) {
00159           foreach ( const Particle & mu, cand_e ) {
00160             if ( deltaR(mu.momentum(),e.momentum()) < 0.1 ) {
00161               away = false;
00162               break;
00163             }
00164           }
00165         }
00166         if ( away )
00167           recon_e.push_back( e );
00168       }
00169       // only keep muons more than R=0.4 from jets
00170       ParticleVector recon_mu;
00171       foreach ( const Particle & mu, cand_mu ) {
00172         bool away = true;
00173         foreach ( const Jet& jet, recon_jets ) {
00174           if ( deltaR(mu.momentum(),jet.momentum()) < 0.4 ) {
00175             away = false;
00176             break;
00177           }
00178         }
00179         // and 0.1 from any electrona
00180         if ( ! away ) {
00181           foreach ( const Particle & e, cand_e ) {
00182             if ( deltaR(mu.momentum(),e.momentum()) < 0.1 ) {
00183               away = false;
00184               break;
00185             }
00186           }
00187         }
00188         if ( away )
00189           recon_mu.push_back( mu );
00190       }
00191 
00192       // pTmiss
00193       ParticleVector vfs_particles =
00194         applyProjection<VisibleFinalState>(event, "vfs").particles();
00195       FourMomentum pTmiss;
00196       foreach ( const Particle & p, vfs_particles ) {
00197         pTmiss -= p.momentum();
00198       }
00199       double eTmiss = pTmiss.pT();
00200 
00201       // now only use recon_jets, recon_mu, recon_e
00202 
00203       // reject events with wrong number of leptons
00204       if ( recon_mu.size() + recon_e.size() != 3 ) {
00205         MSG_DEBUG("To few charged leptons left after selection");
00206         vetoEvent;
00207       }
00208 
00209       // ATLAS calo problem
00210       if(rand()/static_cast<double>(RAND_MAX)<=0.42) {
00211         foreach ( const Particle & e, recon_e ) {
00212           double eta = e.momentum().eta();
00213           double phi = e.momentum().azimuthalAngle(MINUSPI_PLUSPI);
00214           if(eta>-0.1&&eta<1.5&&phi>-0.9&&phi<-0.5)
00215             vetoEvent;
00216         }
00217         foreach ( const Jet & jet, recon_jets ) {
00218           double eta = jet.momentum().rapidity();
00219           double phi = jet.momentum().azimuthalAngle(MINUSPI_PLUSPI);
00220           if(jet.momentum().perp()>40 && eta>-0.1&&eta<1.5&&phi>-0.9&&phi<-0.5)
00221             vetoEvent;
00222         }
00223       }
00224 
00225       // check at least one e/mu passing trigger
00226       if( !( !recon_e .empty() && recon_e[0] .momentum().perp()>25.)  &&
00227           !( !recon_mu.empty() && recon_mu[0].momentum().perp()>20.) ) {
00228         MSG_DEBUG("Hardest lepton fails trigger");
00229         vetoEvent;
00230       }
00231 
00232       // eTmiss cut
00233       if(eTmiss<50.) vetoEvent;
00234 
00235       // check at least 1 SFOS pair
00236       double mSFOS=1e30, mdiff=1e30;
00237       unsigned int nSFOS=0;
00238       for(unsigned int ix=0;ix<recon_e.size();++ix) {
00239         for(unsigned int iy=ix+1;iy<recon_e.size();++iy) {
00240           if(recon_e[ix].pdgId()*recon_e[iy].pdgId()>0) continue;
00241           ++nSFOS;
00242           double mtest = (recon_e[ix].momentum()+recon_e[iy].momentum()).mass();
00243           // veto is mass<20
00244           if(mtest<20.) vetoEvent;
00245           if(fabs(mtest-90.)<mdiff) {
00246             mSFOS = mtest;
00247             mdiff = fabs(mtest-90.);
00248           }
00249         }
00250       }
00251       for(unsigned int ix=0;ix<recon_mu.size();++ix) {
00252         for(unsigned int iy=ix+1;iy<recon_mu.size();++iy) {
00253           if(recon_mu[ix].pdgId()*recon_mu[iy].pdgId()>0) continue;
00254           ++nSFOS;
00255           double mtest = (recon_mu[ix].momentum()+recon_mu[iy].momentum()).mass();
00256           // veto is mass<20
00257           if(mtest<20.) vetoEvent;
00258           if(fabs(mtest-90.)<mdiff) {
00259             mSFOS = mtest;
00260             mdiff = fabs(mtest-90.);
00261           }
00262         }
00263       }
00264       // require at least 1 SFOS pair
00265       if(nSFOS==0) vetoEvent;
00266       // b-jet veto in SR!
00267       if(mdiff>10.) {
00268         foreach (const Jet & jet, recon_jets ) {
00269           if(jet.containsBottom() &&
00270              rand()/static_cast<double>(RAND_MAX)<=0.60)
00271             vetoEvent;
00272         }
00273       }
00274       // region SR1, Z depleted
00275       if(mdiff>10.) {
00276         _count_SR1->fill(0.5,weight);
00277         _hist_etmiss_SR1_A->fill(eTmiss,weight);
00278         _hist_etmiss_SR1_B->fill(eTmiss,weight);
00279         _hist_mSFOS->fill(mSFOS,weight);
00280       }
00281       // region SR2, Z enriched
00282       else {
00283         _count_SR2->fill(0.5,weight);
00284         _hist_etmiss_SR2_A->fill(eTmiss,weight);
00285         _hist_etmiss_SR2_B->fill(eTmiss,weight);
00286       }
00287       // make the control plots
00288       // lepton pT
00289       unsigned int ie=0,imu=0;
00290       for(unsigned int ix=0;ix<3;++ix) {
00291         Histo1DPtr hist = mdiff>10. ?
00292           _hist_leptonpT_SR1[ix] :  _hist_leptonpT_SR2[ix];
00293         double pTe  = ie <recon_e .size() ?
00294           recon_e [ie ].momentum().perp() : -1*GeV;
00295         double pTmu = imu<recon_mu.size() ?
00296           recon_mu[imu].momentum().perp() : -1*GeV;
00297         if(pTe>pTmu) {
00298           hist->fill(pTe ,weight);
00299           ++ie;
00300         }
00301         else {
00302           hist->fill(pTmu,weight);
00303           ++imu;
00304         }
00305       }
00306     }
00307 
00308     //@}
00309 
00310     void finalize() {
00311       double norm = crossSection()/femtobarn*2.06/sumOfWeights();
00312       // these are number of events at 2.06fb^-1 per 20 GeV
00313       for(unsigned int ix=0;ix<3;++ix) {
00314         scale(_hist_leptonpT_SR1[ix],norm*20.);
00315         scale(_hist_leptonpT_SR2[ix],norm*20.);
00316       }
00317       scale(_hist_etmiss_SR1_A,norm*20.);
00318       scale(_hist_etmiss_SR1_B,norm*20.);
00319       scale(_hist_etmiss_SR2_A,norm*20.);
00320       scale(_hist_etmiss_SR2_B,norm*20.);
00321       scale(_hist_mSFOS    ,norm*20.);
00322       // these are number of events at 2.06fb^-1
00323       scale(_count_SR1,norm);
00324       scale(_count_SR2,norm);
00325     }
00326 
00327   private:
00328 
00329   /// @name Histograms
00330   //@{
00331   vector<Histo1DPtr> _hist_leptonpT_SR1;
00332   vector<Histo1DPtr> _hist_leptonpT_SR2;
00333   Histo1DPtr _hist_etmiss_SR1_A;
00334   Histo1DPtr _hist_etmiss_SR1_B;
00335   Histo1DPtr _hist_etmiss_SR2_A;
00336   Histo1DPtr _hist_etmiss_SR2_B;
00337   Histo1DPtr _hist_mSFOS;
00338   Histo1DPtr _count_SR1;
00339   Histo1DPtr _count_SR2;
00340   //@}
00341 
00342   };
00343 
00344   // The hook for the plugin system
00345   DECLARE_RIVET_PLUGIN(ATLAS_2012_I1112263);
00346 
00347 }