rivet is hosted by Hepforge, IPPP Durham
ATLAS_2012_I1126136.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/IdentifiedFinalState.hh"
00010 #include "Rivet/Projections/VetoedFinalState.hh"
00011 #include "Rivet/Projections/FastJets.hh"
00012 #include "Rivet/Tools/ParticleIdUtils.hh"
00013 #include "Rivet/Tools/RivetMT2.hh"
00014 
00015 namespace Rivet {
00016 
00017 
00018   class ATLAS_2012_I1126136 : public Analysis {
00019   public:
00020 
00021     /// @name Constructors etc.
00022     //@{
00023 
00024     /// Constructor
00025 
00026     ATLAS_2012_I1126136()
00027       : Analysis("ATLAS_2012_I1126136")
00028     {    }
00029 
00030     //@}
00031 
00032 
00033   public:
00034 
00035     /// @name Analysis methods
00036     //@{
00037 
00038     /// Book histograms and initialize projections before the run
00039     void init() {
00040 
00041       // projection to find the electrons
00042       vector<pair<double, double> > eta_e;
00043       eta_e.push_back(make_pair(-2.47,2.47));
00044       IdentifiedFinalState elecs(eta_e, 20.0*GeV);
00045       elecs.acceptIdPair(ELECTRON);
00046       addProjection(elecs, "elecs");
00047 
00048       // projection to find the muons
00049       vector<pair<double, double> > eta_m;
00050       eta_m.push_back(make_pair(-2.4,2.4));
00051       IdentifiedFinalState muons(eta_m, 10.0*GeV);
00052       muons.acceptIdPair(MUON);
00053       addProjection(muons, "muons");
00054 
00055       // Jet finder
00056       VetoedFinalState vfs;
00057       vfs.addVetoPairId(MUON);
00058       addProjection(FastJets(vfs, FastJets::ANTIKT, 0.4),
00059             "AntiKtJets04");
00060 
00061       // for pTmiss
00062       addProjection(VisibleFinalState(-4.9,4.9),"vfs");
00063 
00064       // Book histograms
00065       _count_SR_A     = bookHisto1D("count_SR_A"    , 1, 0., 1.);
00066       _count_SR_B     = bookHisto1D("count_SR_B"    , 1, 0., 1.);
00067 
00068       _hist_mjjj1  = bookHisto1D("hist_mjjj1" , 30 , 0.   , 600.  );
00069       _hist_mjjj2  = bookHisto1D("hist_mjjj2" , 30 , 0.   , 600.  );
00070       _hist_ETmiss = bookHisto1D("hist_ETmiss", 20 , 100. , 600.  );
00071       _hist_mT2    = bookHisto1D("hist_mT2"   , 200, 0.   , 1000. );
00072 
00073     }
00074 
00075     /// Perform the per-event analysis
00076     void analyze(const Event& event) {
00077       const double weight = event.weight();
00078 
00079       // pTmiss
00080       FourMomentum pTmiss;
00081       foreach ( const Particle & p,
00082                 applyProjection<VisibleFinalState>(event, "vfs").particles() ) {
00083         pTmiss -= p.momentum();
00084       }
00085       double ETmiss = pTmiss.perp();
00086 
00087       // require eTmiss > 150
00088       if(ETmiss<150.) vetoEvent;
00089 
00090       // get the candiate jets
00091       Jets cand_jets;
00092       foreach ( const Jet& jet,
00093                 applyProjection<FastJets>(event, "AntiKtJets04").jetsByPt(20.0*GeV) ) {
00094         if ( fabs( jet.momentum().eta() ) < 4.5 ) {
00095           cand_jets.push_back(jet);
00096         }
00097       }
00098 
00099       // find the electrons
00100       ParticleVector cand_e;
00101       foreach( const Particle & e,
00102                applyProjection<IdentifiedFinalState>(event, "elecs").particlesByPt()) {
00103         // remove any leptons within 0.4 of any candidate jets
00104         bool e_near_jet = false;
00105         foreach ( const Jet& jet, cand_jets ) {
00106           double dR = deltaR(e.momentum(),jet.momentum());
00107           if ( dR < 0.4 && dR > 0.2 ) {
00108             e_near_jet = true;
00109             break;
00110           }
00111         }
00112         if ( e_near_jet ) continue;
00113         cand_e.push_back(e);
00114       }
00115 
00116       // find the muons
00117       ParticleVector cand_mu;
00118       foreach( const Particle & mu,
00119                applyProjection<IdentifiedFinalState>(event, "muons").particlesByPt()) {
00120         // remove any leptons within 0.4 of any candidate jets
00121         bool mu_near_jet = false;
00122         foreach ( const Jet& jet, cand_jets ) {
00123           if ( deltaR(mu.momentum(),jet.momentum()) < 0.4 ) {
00124             mu_near_jet = true;
00125             break;
00126           }
00127         }
00128         if ( mu_near_jet ) continue;
00129         cand_mu.push_back(mu);
00130       }
00131 
00132       // veto events with leptons
00133       if( ! cand_e.empty() || ! cand_mu.empty() )
00134     vetoEvent;
00135 
00136       // discard jets that overlap with electrons
00137       Jets recon_jets;
00138       foreach ( const Jet& jet, cand_jets ) {
00139         if(fabs(jet.momentum().eta())>2.8 ||
00140            jet.momentum().perp()<30.) continue;
00141         bool away_from_e = true;
00142         foreach ( const Particle & e, cand_e ) {
00143           if ( deltaR(e.momentum(),jet.momentum()) < 0.2 ) {
00144             away_from_e = false;
00145             break;
00146           }
00147         }
00148         if ( away_from_e ) recon_jets.push_back( jet );
00149       }
00150 
00151       // find b jets
00152       Jets tight_bjets,loose_bjets;
00153       foreach(const Jet & jet, recon_jets) {
00154     if(!jet.containsBottom() && jet.momentum().eta()>2.5) continue;
00155     double prob = rand()/static_cast<double>(RAND_MAX);
00156     if(prob <= 0.60) tight_bjets.push_back(jet);
00157     if(prob <= 0.75) loose_bjets.push_back(jet);
00158       }
00159 
00160       // require >=1 tight or >=2 loose b-jets
00161       if( ! ( !tight_bjets.empty() || loose_bjets.size()>=2) )
00162     vetoEvent;
00163 
00164       // must be at least 6 jets with pT>30
00165       if(recon_jets.size()<6 ) vetoEvent;
00166 
00167       // hardest > 130
00168       if(recon_jets[0].momentum().perp() < 130. ) vetoEvent;
00169 
00170       // three hardest jets must be separated from etmiss
00171       for(unsigned int ix=0;ix<3;++ix) {
00172     if(deltaPhi(recon_jets[ix].momentum(),pTmiss)<0.2*PI)
00173       vetoEvent;
00174       }
00175 
00176       // remove events with tau like jets
00177       for(unsigned int ix=3;ix<recon_jets.size();++ix) {
00178     // skip jets seperated from eTmiss
00179     if(deltaPhi(recon_jets[ix].momentum(),pTmiss)>=0.2*PI)
00180       continue;
00181     // check the number of tracks between 1 and 4
00182     unsigned int ncharged=0;
00183     foreach ( const Particle & particle, recon_jets[ix].particles()) {
00184       if(PID::threeCharge(particle.pdgId())!=0) ++ncharged;
00185     }
00186     if(ncharged==0 || ncharged>4) continue;
00187     // calculate transverse mass and reject if < 100
00188     double mT = 2.*recon_jets[ix].momentum().perp()*ETmiss
00189       -recon_jets[ix].momentum().x()*pTmiss.x()
00190       -recon_jets[ix].momentum().y()*pTmiss.y();
00191     if(mT<100.) vetoEvent;
00192       }
00193 
00194       // if 2 loose b-jets apply mT cut
00195       if(loose_bjets.size()>=2) {
00196     // find b-jet closest to eTmiss
00197     double minR(1e30);
00198     unsigned int ijet(0);
00199     for(unsigned int ix=0;ix<loose_bjets.size();++ix) {
00200       double dR = deltaR(loose_bjets[ix].momentum(),pTmiss);
00201       if(dR<minR) {
00202         minR=dR;
00203         ijet = ix;
00204       }
00205     }
00206     double  mT = 2.*loose_bjets[ijet].momentum().perp()*ETmiss
00207       -loose_bjets[ijet].momentum().x()*pTmiss.x()
00208       -loose_bjets[ijet].momentum().y()*pTmiss.y();
00209     if(mT<170.) vetoEvent;
00210       }
00211 
00212       // 1 tight b-jet apply mT cut
00213       if(tight_bjets.size()==1) {
00214     for(unsigned int ix=0;ix<4;++ix) {
00215       double mT = 2.*recon_jets[ix].momentum().perp()*ETmiss
00216         -recon_jets[ix].momentum().x()*pTmiss.x()
00217         -recon_jets[ix].momentum().y()*pTmiss.y();
00218       if(mT<175.) vetoEvent;
00219     }
00220       }
00221 
00222       // find the closest triplet of jets in (eta,phi)
00223       unsigned int j1(0),j2(0),j3(0);
00224       double minR2(1e30);
00225       for(unsigned int i1=0;i1<recon_jets.size();++i1) {
00226     for(unsigned int i2=i1+1;i2<recon_jets.size();++i2) {
00227       for(unsigned int i3=i2+1;i3<recon_jets.size();++i3) {
00228         double delR2 =
00229           sqr(deltaR(recon_jets[i1].momentum(),recon_jets[i2].momentum())) +
00230           sqr(deltaR(recon_jets[i1].momentum(),recon_jets[i3].momentum())) +
00231           sqr(deltaR(recon_jets[i2].momentum(),recon_jets[i3].momentum()));
00232         if(delR2<minR2) {
00233           minR2=delR2;
00234           j1=i1;
00235           j2=i2;
00236           j3=i3;
00237         }
00238       }
00239     }
00240       }
00241       // 4-momentum and mass of first triplet
00242       FourMomentum pjjj1 = recon_jets[j1].momentum() +
00243     recon_jets[j2].momentum()+ recon_jets[j3].momentum();
00244       double mjjj1 = pjjj1.mass();
00245 
00246       // find the second triplet
00247       unsigned int j4(0),j5(0),j6(0);
00248       minR2=0.;
00249       for(unsigned int i1=0;i1<recon_jets.size();++i1) {
00250     if(i1==j1||i1==j2||i1==j3) continue;
00251     for(unsigned int i2=i1+1;i2<recon_jets.size();++i2) {
00252       if(i2==j1||i2==j2||i2==j3) continue;
00253       for(unsigned int i3=i2+1;i3<recon_jets.size();++i3) {
00254         if(i3==j1||i3==j2||i3==j3) continue;
00255         double delR2 =
00256           sqr(deltaR(recon_jets[i1].momentum(),recon_jets[i2].momentum())) +
00257           sqr(deltaR(recon_jets[i1].momentum(),recon_jets[i3].momentum())) +
00258           sqr(deltaR(recon_jets[i2].momentum(),recon_jets[i3].momentum()));
00259         if(delR2<minR2) {
00260           minR2=delR2;
00261           j4=i1;
00262           j5=i2;
00263           j6=i3;
00264         }
00265       }
00266     }
00267       }
00268 
00269       // 4-momentum and mass of first triplet
00270       FourMomentum pjjj2 = recon_jets[j4].momentum() +
00271     recon_jets[j5].momentum()+ recon_jets[j6].momentum();
00272       double mjjj2 = pjjj2.mass();
00273 
00274       _hist_mjjj1->fill(mjjj1,weight);
00275       _hist_mjjj2->fill(mjjj2,weight);
00276       // require triplets in 80<mjjj<270
00277       if(mjjj1<80.||mjjj1>270.||mjjj2<80.||mjjj2>270.)
00278     vetoEvent;
00279 
00280       // counts in signal regions
00281       _count_SR_A->fill(0.5,weight);
00282       if(ETmiss>260.) _count_SR_B->fill(0.5,weight);
00283 
00284       _hist_ETmiss->fill(ETmiss,weight);
00285       double m_T2 = mT2::mT2( pjjj1,pjjj2,
00286                   pTmiss,0.0 ); // zero mass invisibles
00287       _hist_mT2->fill(m_T2,weight);
00288     }
00289     //@}
00290 
00291 
00292     void finalize() {
00293 
00294       double norm = 4.7* crossSection()/sumOfWeights()/femtobarn;
00295       scale(_count_SR_A ,     norm );
00296       scale(_count_SR_B ,     norm );
00297       scale(_hist_mjjj1 , 20.*norm );
00298       scale(_hist_ETmiss, 50.*norm );
00299       scale(_hist_mjjj2 , 20.*norm );
00300       scale(_hist_mT2   ,     norm );
00301 
00302     }
00303 
00304   private:
00305 
00306     /// @name Histograms
00307     //@{
00308     Histo1DPtr _count_SR_A;
00309     Histo1DPtr _count_SR_B;
00310 
00311     Histo1DPtr _hist_mjjj1;
00312     Histo1DPtr _hist_mjjj2;
00313     Histo1DPtr _hist_ETmiss;
00314     Histo1DPtr _hist_mT2;
00315     //@}
00316 
00317   };
00318 
00319   // The hook for the plugin system
00320   DECLARE_RIVET_PLUGIN(ATLAS_2012_I1126136);
00321 
00322 }