rivet is hosted by Hepforge, IPPP Durham
ATLAS_2012_I1190891.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   /// @author Peter Richardson
00016   class ATLAS_2012_I1190891 : public Analysis {
00017   public:
00018 
00019     /// Constructor
00020     ATLAS_2012_I1190891()
00021       : Analysis("ATLAS_2012_I1190891")
00022     {    }
00023 
00024 
00025     /// @name Analysis methods
00026     //@{
00027 
00028     /// Book histograms and initialise projections before the run
00029     void init() {
00030 
00031       // projection to find the electrons
00032       IdentifiedFinalState elecs(Cuts::abseta < 2.47 && Cuts::pT > 10*GeV);
00033       elecs.acceptIdPair(PID::ELECTRON);
00034       addProjection(elecs, "elecs");
00035 
00036       // projection to find the muons
00037       IdentifiedFinalState muons(Cuts::abseta < 2.4 && Cuts::pT > 10*GeV);
00038       muons.acceptIdPair(PID::MUON);
00039       addProjection(muons, "muons");
00040 
00041       // for pTmiss
00042       addProjection(VisibleFinalState(Cuts::abseta < 4.9),"vfs");
00043 
00044       VetoedFinalState vfs;
00045       vfs.addVetoPairId(PID::MUON);
00046 
00047       /// Jet finder
00048       addProjection(FastJets(vfs, FastJets::ANTIKT, 0.4), "AntiKtJets04");
00049 
00050       // all tracks (to do deltaR with leptons)
00051       addProjection(ChargedFinalState(-3.0,3.0),"cfs");
00052 
00053       // Book histograms
00054       _hist_etmiss = bookHisto1D("hist_etmiss",10,0.,500.);
00055       _hist_meff   = bookHisto1D("hist_m_eff",7,0.,1050.);
00056       _count_SR1 = bookHisto1D("count_SR1", 1, 0., 1.);
00057       _count_SR2 = bookHisto1D("count_SR2", 1, 0., 1.);
00058     }
00059 
00060 
00061     /// Perform the per-event analysis
00062     void analyze(const Event& event) {
00063       const double weight = event.weight();
00064       // get the jet candidates
00065       Jets cand_jets;
00066       foreach (const Jet& jet,
00067                applyProjection<FastJets>(event, "AntiKtJets04").jetsByPt(20.0*GeV) ) {
00068         if ( fabs( jet.eta() ) < 2.5 ) {
00069           cand_jets.push_back(jet);
00070         }
00071       }
00072 
00073       // candidate muons
00074       Particles cand_mu;
00075       Particles chg_tracks =
00076         applyProjection<ChargedFinalState>(event, "cfs").particles();
00077       foreach ( const Particle & mu,
00078                 applyProjection<IdentifiedFinalState>(event, "muons").particlesByPt() ) {
00079         double pTinCone = -mu.pT();
00080         foreach ( const Particle & track, chg_tracks ) {
00081           if ( deltaR(mu.momentum(),track.momentum()) <= 0.2 )
00082             pTinCone += track.pT();
00083         }
00084         if ( pTinCone < 1.8*GeV )
00085           cand_mu.push_back(mu);
00086       }
00087 
00088       // candidate electrons
00089       Particles cand_e;
00090       foreach ( const Particle & e,
00091                 applyProjection<IdentifiedFinalState>(event, "elecs").particlesByPt() ) {
00092         double pTinCone = -e.perp();
00093         foreach ( const Particle & track, chg_tracks ) {
00094           if ( deltaR(e.momentum(),track.momentum()) <= 0.2 )
00095             pTinCone += track.pT();
00096         }
00097         if (pTinCone/e.perp()<0.1) {
00098           cand_e.push_back(e);
00099         }
00100       }
00101 
00102       // resolve jet/lepton ambiguity
00103       Jets recon_jets;
00104       foreach ( const Jet& jet, cand_jets ) {
00105         bool away_from_e = true;
00106         foreach ( const Particle & e, cand_e ) {
00107           if ( deltaR(e.momentum(),jet.momentum()) <= 0.2 ) {
00108             away_from_e = false;
00109             break;
00110           }
00111         }
00112         if ( away_from_e )
00113           recon_jets.push_back( jet );
00114       }
00115 
00116       // only keep electrons more than R=0.4 from jets
00117       Particles cand2_e;
00118       for(unsigned int ie=0;ie<cand_e.size();++ie) {
00119         const Particle & e = cand_e[ie];
00120         // at least 0.4 from any jets
00121         bool away = true;
00122         foreach ( const Jet& jet, recon_jets ) {
00123           if ( deltaR(e.momentum(),jet.momentum()) < 0.4 ) {
00124             away = false;
00125             break;
00126           }
00127         }
00128         // and 0.1 from any muons
00129         if ( away ) {
00130           foreach ( const Particle & mu, cand_mu ) {
00131             if ( deltaR(mu.momentum(),e.momentum()) < 0.1 ) {
00132               away = false;
00133               break;
00134             }
00135           }
00136         }
00137         // and 0.1 from electrons ( keep higher energy)
00138         for(unsigned int ie2=0;ie2<cand_e.size();++ie2) {
00139           if(ie==ie2) continue;
00140           if ( deltaR(e.momentum(),cand_e[ie2].momentum()) < 0.1 &&
00141                e.E() < cand_e[ie2].E() ) {
00142             away = false;
00143             break;
00144           }
00145         }
00146         // if isolated keep it
00147         if ( away )
00148           cand2_e.push_back( e );
00149       }
00150 
00151       // remove e+e- pairs with mass < 20.
00152       Particles recon_e;
00153       for(unsigned int ie=0;ie<cand2_e.size();++ie) {
00154         bool pass = true;
00155         for(unsigned int ie2=0;ie2<cand2_e.size();++ie2) {
00156           if(cand2_e[ie].pid()*cand2_e[ie2].pid()>0) continue;
00157           double mtest = (cand2_e[ie].momentum()+cand2_e[ie2].momentum()).mass();
00158           if(mtest<=20.) {
00159             pass = false;
00160             break;
00161           }
00162         }
00163         if(pass) recon_e.push_back(cand2_e[ie]);
00164       }
00165 
00166       // only keep muons more than R=0.4 from jets
00167       Particles cand2_mu;
00168       for(unsigned int imu=0;imu<cand_mu.size();++imu) {
00169         const Particle & mu = cand_mu[imu];
00170         bool away = true;
00171         // at least 0.4 from any jets
00172         foreach ( const Jet& jet, recon_jets ) {
00173           if ( deltaR(mu.momentum(),jet.momentum()) < 0.4 ) {
00174             away = false;
00175             break;
00176           }
00177         }
00178         // and 0.1 from any electrona
00179         if ( away ) {
00180           foreach ( const Particle & e, cand_e ) {
00181             if ( deltaR(mu.momentum(),e.momentum()) < 0.1 ) {
00182               away = false;
00183               break;
00184             }
00185           }
00186         }
00187         if ( away )
00188           cand2_mu.push_back( mu );
00189       }
00190 
00191       // remove mu+mu- pairs with mass < 20.
00192       Particles recon_mu;
00193       for(unsigned int imu=0;imu<cand2_mu.size();++imu) {
00194         bool pass = true;
00195         for(unsigned int imu2=0;imu2<cand2_mu.size();++imu2) {
00196           if(cand2_mu[imu].pid()*cand2_mu[imu2].pid()>0) continue;
00197           double mtest = (cand2_mu[imu].momentum()+cand2_mu[imu2].momentum()).mass();
00198           if(mtest<=20.) {
00199             pass = false;
00200             break;
00201           }
00202         }
00203         if(pass) recon_mu.push_back(cand2_mu[imu]);
00204       }
00205 
00206       // pTmiss
00207       Particles vfs_particles =
00208         applyProjection<VisibleFinalState>(event, "vfs").particles();
00209       FourMomentum pTmiss;
00210       foreach ( const Particle & p, vfs_particles ) {
00211         pTmiss -= p.momentum();
00212       }
00213       double eTmiss = pTmiss.pT();
00214 
00215       // now only use recon_jets, recon_mu, recon_e
00216 
00217       // reject events with less than 4 electrons and muons
00218       if ( recon_mu.size() + recon_e.size() < 4 ) {
00219         MSG_DEBUG("To few charged leptons left after selection");
00220         vetoEvent;
00221       }
00222 
00223       // check if passes single lepton trigger
00224       bool passSingle =
00225         ( !recon_e .empty() && recon_e[0] .perp()>25. )||
00226         ( !recon_mu.empty() && recon_mu[0].perp()>20.);
00227 
00228       // or two lepton trigger
00229       bool passDouble =
00230         ( recon_mu.size()>=2 && recon_mu[1].perp()>12.) ||
00231         ( recon_e .size()>=2 && recon_e [1].perp()>17.) ||
00232         ( !recon_e.empty() && !recon_mu.empty() &&
00233           recon_e[0].perp()>15. &&  recon_mu[0].perp()>10.);
00234 
00235       // must pass a trigger
00236       if( !passSingle && !passDouble ) {
00237         MSG_DEBUG("Hardest lepton fails trigger");
00238         vetoEvent;
00239       }
00240 
00241       // calculate meff
00242       double meff = eTmiss;
00243       foreach ( const Particle & e , recon_e  )
00244         meff += e.perp();
00245       foreach ( const Particle & mu, recon_mu )
00246         meff += mu.perp();
00247       foreach ( const Jet & jet, recon_jets ) {
00248         double pT = jet.perp();
00249         if(pT>40.) meff += pT;
00250       }
00251 
00252       // mass of SFOS pairs closest to the Z mass
00253       for(unsigned int ix=0;ix<recon_e.size();++ix) {
00254         for(unsigned int iy=ix+1;iy<recon_e.size();++iy) {
00255           if(recon_e[ix].pid()*recon_e[iy].pid()>0) continue;
00256           double mtest = (recon_e[ix].momentum()+recon_e[iy].momentum()).mass();
00257           if(mtest>81.2 && mtest<101.2) vetoEvent;
00258         }
00259       }
00260       for(unsigned int ix=0;ix<recon_mu.size();++ix) {
00261         for(unsigned int iy=ix+1;iy<recon_mu.size();++iy) {
00262           if(recon_mu[ix].pid()*recon_mu[iy].pid()>0) continue;
00263           double mtest = (recon_mu[ix].momentum()+recon_mu[iy].momentum()).mass();
00264           if(mtest>81.2 && mtest<101.2) vetoEvent;
00265         }
00266       }
00267 
00268       // make the control plots
00269       _hist_etmiss ->fill(eTmiss,weight);
00270       _hist_meff   ->fill(meff  ,weight);
00271       // finally the counts
00272       if(eTmiss>50.) _count_SR1->fill(0.5,weight);
00273       if(meff >300.) _count_SR2->fill(0.5,weight);
00274     }
00275 
00276     //@}
00277 
00278     void finalize() {
00279       double norm = crossSection()/femtobarn*4.7/sumOfWeights();
00280       scale(_hist_etmiss,norm* 50.);
00281       scale(_hist_meff  ,norm*150.);
00282       scale(_count_SR1,norm);
00283       scale(_count_SR2,norm);
00284     }
00285 
00286   private:
00287 
00288     /// @name Histograms
00289     //@{
00290     Histo1DPtr _hist_etmiss;
00291     Histo1DPtr _hist_meff;
00292     Histo1DPtr _count_SR1;
00293     Histo1DPtr _count_SR2;
00294     //@}
00295 
00296   };
00297 
00298   // The hook for the plugin system
00299   DECLARE_RIVET_PLUGIN(ATLAS_2012_I1190891);
00300 
00301 }