rivet is hosted by Hepforge, IPPP Durham
ATLAS_2012_CONF_2012_153.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Tools/BinnedHistogram.hh"
00004 #include "Rivet/Projections/FinalState.hh"
00005 #include "Rivet/Projections/ChargedFinalState.hh"
00006 #include "Rivet/Projections/VisibleFinalState.hh"
00007 #include "Rivet/Projections/VetoedFinalState.hh"
00008 #include "Rivet/Projections/IdentifiedFinalState.hh"
00009 #include "Rivet/Projections/FastJets.hh"
00010 #include "Rivet/Tools/RivetMT2.hh"
00011 
00012 namespace Rivet {
00013 
00014 
00015   class ATLAS_2012_CONF_2012_153 : public Analysis {
00016   public:
00017 
00018     /// @name Constructors etc.
00019     //@{
00020 
00021     /// Constructor
00022     ATLAS_2012_CONF_2012_153()
00023       : Analysis("ATLAS_2012_CONF_2012_153")
00024     {    }
00025 
00026     //@}
00027 
00028     //@}
00029 
00030 
00031 
00032   public:
00033 
00034     /// @name Analysis methods
00035     //@{
00036 
00037     /// Book histograms and initialise projections before the run
00038     void init() {
00039 
00040       // projection to find the electrons
00041       IdentifiedFinalState elecs(EtaIn(-2.47, 2.47) 
00042                  & (Cuts::pT >= 10.0*GeV));
00043       elecs.acceptIdPair(PID::ELECTRON);
00044       addProjection(elecs, "elecs");
00045 
00046 
00047       // projection to find the muons
00048       IdentifiedFinalState muons(EtaIn(-2.4, 2.4) 
00049                  & (Cuts::pT >= 10.0*GeV));
00050       muons.acceptIdPair(PID::MUON);
00051       addProjection(muons, "muons");
00052 
00053       // for pTmiss
00054       addProjection(VisibleFinalState(-4.9,4.9),"vfs");
00055 
00056       VetoedFinalState vfs;
00057       vfs.addVetoPairId(PID::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       vector<double> edges_meff;
00067       edges_meff.push_back(   0);
00068       edges_meff.push_back( 150);
00069       edges_meff.push_back( 300);
00070       edges_meff.push_back( 500);
00071       edges_meff.push_back(1000);
00072       edges_meff.push_back(1500);
00073 
00074       vector<double> edges_eT;
00075       edges_eT.push_back(0);
00076       edges_eT.push_back(50);
00077       edges_eT.push_back(150);
00078       edges_eT.push_back(300);
00079       edges_eT.push_back(500);
00080 
00081       // Book histograms
00082       _hist_electrons = bookHisto1D("hist_electrons_before", 11, -0.5,10.5);
00083       _hist_muons     = bookHisto1D("hist_muons_before"    , 11, -0.5,10.5);
00084       _hist_leptons   = bookHisto1D("hist_leptons_before"  , 11, -0.5,10.5);
00085       _hist_4leptons  = bookHisto1D("hist_4leptons", 1, 0.,1.);
00086       _hist_veto      = bookHisto1D("hist_veto", 1, 0., 1.);
00087       _hist_etmiss    = bookHisto1D("hist_etmiss",edges_eT);
00088       _hist_meff      = bookHisto1D("hist_m_eff",edges_meff);
00089       _count_SR1      = bookHisto1D("count_SR1", 1, 0., 1.);
00090       _count_SR2      = bookHisto1D("count_SR2", 1, 0., 1.);
00091 
00092     }
00093 
00094 
00095     /// Perform the per-event analysis
00096     void analyze(const Event& event) {
00097       const double weight = event.weight();
00098       // get the jet candidates
00099       Jets cand_jets;
00100       foreach (const Jet& jet,
00101                applyProjection<FastJets>(event, "AntiKtJets04").jetsByPt(20.0*GeV) ) {
00102         if ( fabs( jet.eta() ) < 2.5 ) {
00103           cand_jets.push_back(jet);
00104         }
00105       }
00106 
00107       // candidate muons
00108       Particles cand_mu = applyProjection<IdentifiedFinalState>(event, "muons").particlesByPt();
00109 
00110       // candidate electrons
00111       // Discard if two electrons are within R=0.1
00112       Particles temp = applyProjection<IdentifiedFinalState>(event, "elecs").particlesByE();
00113       vector<bool> vetoed(temp.size(),false);
00114       Particles cand_e;
00115       for (unsigned int ix=0; ix<temp.size(); ++ix) {
00116         if(vetoed[ix]) continue;
00117         for (unsigned int iy=ix+1; iy<temp.size(); ++iy) {
00118           if( deltaR(temp[ix].momentum(),temp[iy].momentum()) < 0.1 ) {
00119             vetoed[iy] = true;
00120           }
00121         }
00122         if(!vetoed[ix]) cand_e.push_back(temp[ix]);
00123       }
00124 
00125       // Sort by transverse momentum
00126       std::sort(cand_e.begin(), cand_e.end(), cmpMomByPt);
00127 
00128       // resolve jet/lepton ambiguity
00129       Jets recon_jets;
00130       foreach ( const Jet& jet, cand_jets ) {
00131         bool away_from_e = true;
00132         foreach ( const Particle & e, cand_e ) {
00133           if ( deltaR(e.momentum(),jet.momentum()) <= 0.2 ) {
00134             away_from_e = false;
00135             break;
00136           }
00137         }
00138         if ( away_from_e )
00139           recon_jets.push_back( jet );
00140       }
00141 
00142       // only keep electrons more than R=0.4 from jets
00143       Particles cand2_e;
00144       foreach (const Particle & e, cand_e) {
00145         // at least 0.4 from any jets
00146         bool away = true;
00147         foreach ( const Jet& jet, recon_jets ) {
00148           if ( deltaR(e.momentum(),jet.momentum()) < 0.4 ) {
00149             away = false;
00150             break;
00151           }
00152         }
00153         // if isolated keep it
00154         if ( away )
00155           cand2_e.push_back( e );
00156       }
00157 
00158       // only keep muons more than R=0.4 from jets
00159       Particles cand2_mu;
00160       foreach(const Particle & mu, cand_mu ) {
00161         bool away = true;
00162         // at least 0.4 from any jets
00163         foreach ( const Jet& jet, recon_jets ) {
00164           if ( deltaR(mu.momentum(),jet.momentum()) < 0.4 ) {
00165             away = false;
00166             break;
00167           }
00168         }
00169         if ( away )
00170           cand2_mu.push_back( mu );
00171       }
00172 
00173       // electron and muon more than 0.1 apart
00174       Particles cand3_e;
00175       foreach ( const Particle & e, cand2_e ) {
00176         bool away = true;
00177         foreach( const Particle & mu, cand2_mu ) {
00178           if( deltaR(e.momentum(),mu.momentum()) < 0.1) {
00179             away = false;
00180             break;
00181           }
00182         }
00183         if(away) cand3_e.push_back(e);
00184       }
00185       Particles cand3_mu;
00186       foreach( const Particle & mu, cand2_mu ) {
00187         bool away = true;
00188         foreach ( const Particle & e, cand2_e ) {
00189           if( deltaR(e.momentum(),mu.momentum()) < 0.1) {
00190             away = false;
00191             break;
00192           }
00193         }
00194         if(away) cand3_mu.push_back(mu);
00195       }
00196 
00197       // pTmiss
00198       Particles vfs_particles =
00199         applyProjection<VisibleFinalState>(event, "vfs").particles();
00200       FourMomentum pTmiss;
00201       foreach ( const Particle & p, vfs_particles ) {
00202         pTmiss -= p.momentum();
00203       }
00204       double eTmiss = pTmiss.pT();
00205 
00206       // apply electron isolation
00207       Particles chg_tracks =
00208         applyProjection<ChargedFinalState>(event, "cfs").particles();
00209       Particles cand4_e;
00210       foreach ( const Particle & e, cand3_e ) {
00211         // charge isolation
00212         double pTinCone = -e.momentum().perp();
00213         foreach ( const Particle & track, chg_tracks ) {
00214           if(track.momentum().perp()>0.4 &&
00215              deltaR(e.momentum(),track.momentum()) <= 0.3 )
00216             pTinCone += track.pT();
00217         }
00218         if (pTinCone/e.momentum().perp()>0.16) continue;
00219         // all particles isolation
00220         pTinCone = -e.momentum().perp();
00221         foreach ( const Particle & p, vfs_particles ) {
00222           if(abs(p.pdgId())!=PID::MUON &&
00223              deltaR(e.momentum(),p.momentum()) <= 0.3 )
00224             pTinCone += p.pT();
00225         }
00226         if (pTinCone/e.momentum().perp()<0.18) {
00227           cand4_e.push_back(e);
00228         }
00229       }
00230 
00231       // apply muon isolation
00232       Particles cand4_mu;
00233       foreach ( const Particle & mu, cand3_mu ) {
00234         double pTinCone = -mu.momentum().perp();
00235         foreach ( const Particle & track, chg_tracks ) {
00236           if(track.momentum().perp()>1.0 &&
00237              deltaR(mu.momentum(),track.momentum()) <= 0.3 )
00238             pTinCone += track.pT();
00239         }
00240         if (pTinCone/mu.momentum().perp()<0.12) {
00241           cand4_mu.push_back(mu);
00242         }
00243       }
00244 
00245       // same SOSF pairs m>12.
00246       Particles recon_e;
00247       foreach(const Particle & e, cand4_e) {
00248         bool veto=false;
00249         foreach(const Particle & e2, cand4_e) {
00250           if(e.pdgId()*e2.pdgId()<0&&(e.momentum()+e2.momentum()).mass()<12.) {
00251             veto=true;
00252             break;
00253           }
00254         }
00255         if(!veto) recon_e.push_back(e);
00256       }
00257       Particles recon_mu;
00258       foreach(const Particle & mu, cand4_mu) {
00259         bool veto=false;
00260         foreach(const Particle & mu2, cand4_mu) {
00261           if(mu.pdgId()*mu2.pdgId()<0&&(mu.momentum()+mu2.momentum()).mass()<12.) {
00262             veto=true;
00263             break;
00264           }
00265         }
00266         if(!veto) recon_mu.push_back(mu);
00267       }
00268 
00269       // now only use recon_jets, recon_mu, recon_e
00270       _hist_electrons->fill(recon_e.size(), weight);
00271       _hist_muons->fill(recon_mu.size(), weight);
00272       _hist_leptons->fill(recon_mu.size() + recon_e.size(), weight);
00273       if( recon_mu.size() + recon_e.size() > 3) {
00274         _hist_4leptons->fill(0.5, weight);
00275       }
00276 
00277       // reject events with less than 4 electrons and muons
00278       if ( recon_mu.size() + recon_e.size() < 4 ) {
00279         MSG_DEBUG("To few charged leptons left after selection");
00280         vetoEvent;
00281       }
00282 
00283 
00284       // or two lepton trigger
00285       bool passDouble =
00286         (recon_mu.size()>=2 && ( (recon_mu[1].momentum().perp()>14.) ||
00287                                  (recon_mu[0].momentum().perp()>18. && recon_mu[1].momentum().perp()>10.) )) ||
00288         (recon_e.size() >=2 && ( (recon_e [1].momentum().perp()>14.) ||
00289                                  (recon_e [0].momentum().perp()>25. && recon_e [1].momentum().perp()>10.) )) ||
00290         (!recon_e.empty() && !recon_mu.empty() &&
00291          ( (recon_e[0].momentum().perp()>14. && recon_mu[0].momentum().perp()>10.)||
00292            (recon_e[0].momentum().perp()>10. && recon_mu[0].momentum().perp()>18.) ));
00293 
00294       // must pass a trigger
00295        if(!passDouble ) {
00296          MSG_DEBUG("Hardest lepton fails trigger");
00297          _hist_veto->fill(0.5, weight);
00298          vetoEvent;
00299        }
00300 
00301       // calculate meff
00302       double meff = eTmiss;
00303       foreach ( const Particle & e , recon_e  )
00304         meff += e.momentum().perp();
00305       foreach ( const Particle & mu, recon_mu )
00306         meff += mu.momentum().perp();
00307       foreach ( const Jet & jet, recon_jets ) {
00308         double pT = jet.momentum().perp();
00309         if(pT>40.) meff += pT;
00310       }
00311 
00312       // 2/3 leptons --> find 1 SFOS pair in range and veto event
00313       // 4+  leptons --> find 2 SFOS pairs and in range veto event
00314       for(unsigned int ix=0;ix<recon_e.size();++ix) {
00315         for(unsigned int iy=ix+1;iy<recon_e.size();++iy) {
00316           if(recon_e[ix].pdgId()*recon_e[iy].pdgId()>0) continue;
00317           FourMomentum ppair = recon_e[ix].momentum()+recon_e[iy].momentum();
00318           double mtest = ppair.mass();
00319           if(mtest>81.2 && mtest<101.2) vetoEvent;
00320 
00321           // check triplets with electron
00322           for(unsigned int iz=0;iz<recon_e.size();++iz) {
00323             if(iz==ix||iz==iy) continue;
00324             mtest = (ppair+recon_e[iz].momentum()).mass();
00325             if(mtest>81.2 && mtest<101.2) vetoEvent;
00326           }
00327 
00328           // check triplets with muon
00329           for(unsigned int iz=0;iz<recon_mu.size();++iz) {
00330             mtest = (ppair+recon_mu[iz].momentum()).mass();
00331             if(mtest>81.2 && mtest<101.2) vetoEvent;
00332           }
00333 
00334           // check quadruplets with electrons
00335           for(unsigned int iz=0;iz<recon_e.size();++iz) {
00336             for(unsigned int iw=iz+1;iw<recon_e.size();++iw) {
00337               if(iz==ix||iz==iy||iw==ix||iw==iy) continue;
00338               if(recon_e[iz].pdgId()*recon_e[iw].pdgId()>0) continue;
00339               mtest = (ppair+recon_e[iz].momentum()+recon_e[iw].momentum()).mass();
00340               if(mtest>81.2 && mtest<101.2) vetoEvent;
00341             }
00342           }
00343           // check quadruplets with muons
00344           for(unsigned int iz=0;iz<recon_mu.size();++iz) {
00345             for(unsigned int iw=iz+1;iw<recon_mu.size();++iw) {
00346               if(recon_mu[iz].pdgId()*recon_mu[iw].pdgId()>0) continue;
00347               mtest = (ppair+recon_mu[iz].momentum()+recon_mu[iw].momentum()).mass();
00348               if(mtest>81.2 && mtest<101.2) vetoEvent;
00349             }
00350           }
00351         }
00352       }
00353 
00354       // Muon pairs
00355       for(unsigned int ix=0;ix<recon_mu.size();++ix) {
00356         for(unsigned int iy=ix+1;iy<recon_mu.size();++iy) {
00357           if(recon_mu[ix].pdgId()*recon_mu[iy].pdgId()>0) continue;
00358           FourMomentum ppair = recon_mu[ix].momentum()+recon_mu[iy].momentum();
00359           double mtest = ppair.mass();
00360           if(mtest>81.2 && mtest<101.2) vetoEvent;
00361 
00362          // check triplets with muon
00363           for(unsigned int iz=0;iz<recon_mu.size();++iz) {
00364             if(iz==ix||iz==iy) continue;
00365             mtest = (ppair+recon_mu[iz].momentum()).mass();
00366             if(mtest>81.2 && mtest<101.2) vetoEvent;
00367           }
00368 
00369          // check triplets with electron
00370           for(unsigned int iz=0;iz<recon_e.size();++iz) {
00371             mtest = (ppair+recon_e[iz].momentum()).mass();
00372             if(mtest>81.2 && mtest<101.2) vetoEvent;
00373           }
00374 
00375         // check muon quadruplets
00376           for(unsigned int iz=0;iz<recon_mu.size();++iz) {
00377             for(unsigned int iw=iz+1;iy<recon_mu.size();++iy) {
00378               if(iz==ix||iz==iy||iw==ix||iw==iy) continue;
00379               if(recon_mu[iz].pdgId()*recon_mu[iw].pdgId()>0) continue;
00380               mtest = (ppair+recon_mu[iz].momentum()+recon_mu[iw].momentum()).mass();
00381               if(mtest>81.2 && mtest<101.2) vetoEvent;
00382             }
00383           }
00384         }
00385       }
00386 
00387       //make the control plots
00388       _hist_etmiss ->fill(eTmiss,weight);
00389       _hist_meff   ->fill(meff  ,weight);
00390       // finally the counts
00391       if(eTmiss>50.) _count_SR1->fill(0.5,weight);
00392       if(meff  >0. ) _count_SR2->fill(0.5,weight);
00393 
00394     }
00395 
00396     //@}
00397 
00398     void finalize() {
00399       double norm = crossSection()/femtobarn*13./sumOfWeights();
00400       scale(_hist_etmiss,norm*20.);
00401       scale(_hist_meff  ,norm*20.);
00402       scale(_count_SR1,norm);
00403       scale(_count_SR2,norm);
00404     }
00405 
00406   private:
00407 
00408     /// @name Histograms
00409     //@{
00410     Histo1DPtr _hist_electrons;
00411     Histo1DPtr _hist_muons;
00412     Histo1DPtr _hist_leptons;
00413     Histo1DPtr _hist_4leptons;
00414     Histo1DPtr _hist_veto;
00415     Histo1DPtr _hist_etmiss;
00416     Histo1DPtr _hist_meff;
00417     Histo1DPtr _count_SR1;
00418     Histo1DPtr _count_SR2;
00419     //@}
00420 
00421   };
00422 
00423   // The hook for the plugin system
00424   DECLARE_RIVET_PLUGIN(ATLAS_2012_CONF_2012_153);
00425 
00426 }