rivet is hosted by Hepforge, IPPP Durham
ATLAS_2012_CONF_2012_001.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_CONF_2012_001 : public Analysis {
00018   public:
00019 
00020     /// @name Constructors etc.
00021     //@{
00022 
00023     /// Constructor
00024     ATLAS_2012_CONF_2012_001()
00025       : Analysis("ATLAS_2012_CONF_2012_001")
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.push_back(bookHisto1D(1,1,1));
00068       _hist_leptonpT.push_back(bookHisto1D(2,1,1));
00069       _hist_leptonpT.push_back(bookHisto1D(3,1,1));
00070       _hist_leptonpT.push_back(bookHisto1D(4,1,1));
00071       _hist_njet   = bookHisto1D(5,1,1);
00072       _hist_etmiss = bookHisto1D(6,1,1);
00073       _hist_mSFOS  = bookHisto1D(7,1,1);
00074       _hist_meff   = bookHisto1D(8,1,1);
00075 
00076       _hist_leptonpT_MC.push_back(bookHisto1D("hist_lepton_pT_1", 26, 0., 260));
00077       _hist_leptonpT_MC.push_back(bookHisto1D("hist_lepton_pT_2", 15, 0., 150));
00078       _hist_leptonpT_MC.push_back(bookHisto1D("hist_lepton_pT_3", 20, 0., 100));
00079       _hist_leptonpT_MC.push_back(bookHisto1D("hist_lepton_pT_4", 20, 0., 100));
00080       _hist_njet_MC   = bookHisto1D("hist_njet", 7, -0.5, 6.5);
00081       _hist_etmiss_MC = bookHisto1D("hist_etmiss",11,0.,220.);
00082       _hist_mSFOS_MC  = bookHisto1D("hist_m_SFOS",13,0.,260.);
00083       _hist_meff_MC   = bookHisto1D("hist_m_eff",19,0.,950.);
00084 
00085       _count_SR1 = bookHisto1D("count_SR1", 1, 0., 1.);
00086       _count_SR2 = bookHisto1D("count_SR2", 1, 0., 1.);
00087     }
00088 
00089 
00090     /// Perform the per-event analysis
00091     void analyze(const Event& event) {
00092       const double weight = event.weight();
00093       // get the jet candidates
00094       Jets cand_jets;
00095       foreach (const Jet& jet,
00096                applyProjection<FastJets>(event, "AntiKtJets04").jetsByPt(20.0*GeV) ) {
00097         if ( fabs( jet.momentum().eta() ) < 2.8 ) {
00098           cand_jets.push_back(jet);
00099         }
00100       }
00101 
00102       // candidate muons
00103       ParticleVector cand_mu;
00104       ParticleVector chg_tracks =
00105         applyProjection<ChargedFinalState>(event, "cfs").particles();
00106       foreach ( const Particle & mu,
00107                 applyProjection<IdentifiedFinalState>(event, "muons").particlesByPt() ) {
00108         double pTinCone = -mu.momentum().pT();
00109         foreach ( const Particle & track, chg_tracks ) {
00110           if ( deltaR(mu.momentum(),track.momentum()) <= 0.2 )
00111             pTinCone += track.momentum().pT();
00112         }
00113         if ( pTinCone < 1.8*GeV )
00114           cand_mu.push_back(mu);
00115       }
00116 
00117       // candidate electrons
00118       ParticleVector cand_e;
00119       foreach ( const Particle & e,
00120                 applyProjection<IdentifiedFinalState>(event, "elecs").particlesByPt() ) {
00121         double eta = e.momentum().eta();
00122         // remove electrons with pT<15 in old veto region
00123         if( fabs(eta)>1.37 && fabs(eta) < 1.52 && e.momentum().perp()< 15.*GeV)
00124           continue;
00125         double pTinCone = -e.momentum().perp();
00126         foreach ( const Particle & track, chg_tracks ) {
00127           if ( deltaR(e.momentum(),track.momentum()) <= 0.2 )
00128             pTinCone += track.momentum().pT();
00129         }
00130         if (pTinCone/e.momentum().perp()<0.1) {
00131           cand_e.push_back(e);
00132         }
00133       }
00134 
00135       // resolve jet/lepton ambiguity
00136       Jets recon_jets;
00137       foreach ( const Jet& jet, cand_jets ) {
00138         bool away_from_e = true;
00139         foreach ( const Particle & e, cand_e ) {
00140           if ( deltaR(e.momentum(),jet.momentum()) <= 0.2 ) {
00141             away_from_e = false;
00142             break;
00143           }
00144         }
00145         if ( away_from_e )
00146           recon_jets.push_back( jet );
00147       }
00148 
00149       // only keep electrons more than R=0.4 from jets
00150       ParticleVector cand2_e;
00151       for(unsigned int ie=0;ie<cand_e.size();++ie) {
00152         const Particle & e = cand_e[ie];
00153         // at least 0.4 from any jets
00154         bool away = true;
00155         foreach ( const Jet& jet, recon_jets ) {
00156           if ( deltaR(e.momentum(),jet.momentum()) < 0.4 ) {
00157             away = false;
00158             break;
00159           }
00160         }
00161         // and 0.1 from any muons
00162         if ( away ) {
00163           foreach ( const Particle & mu, cand_mu ) {
00164             if ( deltaR(mu.momentum(),e.momentum()) < 0.1 ) {
00165               away = false;
00166               break;
00167             }
00168           }
00169         }
00170         // and 0.1 from electrons
00171         for(unsigned int ie2=0;ie2<cand_e.size();++ie2) {
00172           if(ie==ie2) continue;
00173           if ( deltaR(e.momentum(),cand_e[ie2].momentum()) < 0.1 ) {
00174             away = false;
00175             break;
00176           }
00177         }
00178         // if isolated keep it
00179         if ( away ) cand2_e.push_back( e );
00180       }
00181       // remove e+e- pairs with mass < 20.
00182       ParticleVector recon_e;
00183       for(unsigned int ie=0;ie<cand2_e.size();++ie) {
00184     bool pass = true;
00185     for(unsigned int ie2=0;ie2<cand2_e.size();++ie2) {
00186       if(cand2_e[ie].pdgId()*cand2_e[ie2].pdgId()>0) continue;
00187       double mtest = (cand2_e[ie].momentum()+cand2_e[ie2].momentum()).mass();
00188       if(mtest<=20.) {
00189         pass = false;
00190         break;
00191       }
00192     }
00193     if(pass) recon_e.push_back(cand2_e[ie]);
00194       }
00195 
00196       // only keep muons more than R=0.4 from jets
00197       ParticleVector cand2_mu;
00198       for(unsigned int imu=0;imu<cand_mu.size();++imu) {
00199         const Particle & mu = cand_mu[imu];
00200         bool away = true;
00201         // at least 0.4 from any jets
00202         foreach ( const Jet& jet, recon_jets ) {
00203           if ( deltaR(mu.momentum(),jet.momentum()) < 0.4 ) {
00204             away = false;
00205             break;
00206           }
00207         }
00208         // and 0.1 from any electrona
00209         if ( away ) {
00210           foreach ( const Particle & e, cand_e ) {
00211             if ( deltaR(mu.momentum(),e.momentum()) < 0.1 ) {
00212               away = false;
00213               break;
00214             }
00215           }
00216         }
00217         // and 0.1 from muons
00218         for(unsigned int imu2=0;imu2<cand_mu.size();++imu2) {
00219           if(imu==imu2) continue;
00220           if ( deltaR(mu.momentum(),cand_mu[imu2].momentum()) < 0.1 ) {
00221             away = false;
00222             break;
00223           }
00224         }
00225         if ( away )
00226           cand2_mu.push_back( mu );
00227       }
00228 
00229       // remove mu+mu- pairs with mass < 20.
00230       ParticleVector recon_mu;
00231       for(unsigned int imu=0;imu<cand2_mu.size();++imu) {
00232     bool pass = true;
00233     for(unsigned int imu2=0;imu2<cand2_mu.size();++imu2) {
00234       if(cand2_mu[imu].pdgId()*cand2_mu[imu2].pdgId()>0) continue;
00235       double mtest = (cand2_mu[imu].momentum()+cand2_mu[imu2].momentum()).mass();
00236       if(mtest<=20.) {
00237         pass = false;
00238         break;
00239       }
00240     }
00241     if(pass) recon_mu.push_back(cand2_mu[imu]);
00242       }
00243 
00244       // pTmiss
00245       ParticleVector vfs_particles =
00246         applyProjection<VisibleFinalState>(event, "vfs").particles();
00247       FourMomentum pTmiss;
00248       foreach ( const Particle & p, vfs_particles ) {
00249         pTmiss -= p.momentum();
00250       }
00251       double eTmiss = pTmiss.pT();
00252 
00253       // now only use recon_jets, recon_mu, recon_e
00254 
00255       // reject events with less than 4 electrons and muons
00256       if ( recon_mu.size() + recon_e.size() < 4 ) {
00257         MSG_DEBUG("To few charged leptons left after selection");
00258         vetoEvent;
00259       }
00260 
00261       // ATLAS calo problem
00262       if(rand()/static_cast<double>(RAND_MAX)<=0.42) {
00263         foreach ( const Particle & e, recon_e ) {
00264           double eta = e.momentum().eta();
00265           double phi = e.momentum().azimuthalAngle(MINUSPI_PLUSPI);
00266           if(eta>-0.1&&eta<1.5&&phi>-0.9&&phi<-0.5)
00267             vetoEvent;
00268         }
00269         foreach ( const Jet & jet, recon_jets ) {
00270           double eta = jet.momentum().rapidity();
00271           double phi = jet.momentum().azimuthalAngle(MINUSPI_PLUSPI);
00272           if(jet.momentum().perp()>40 && eta>-0.1&&eta<1.5&&phi>-0.9&&phi<-0.5)
00273             vetoEvent;
00274         }
00275       }
00276 
00277       // check at least one e/mu passing trigger
00278       if( !( !recon_e .empty() && recon_e[0] .momentum().perp()>25.)  &&
00279           !( !recon_mu.empty() && recon_mu[0].momentum().perp()>20.) ) {
00280         MSG_DEBUG("Hardest lepton fails trigger");
00281         vetoEvent;
00282       }
00283 
00284       // calculate meff
00285       double meff = eTmiss;
00286       foreach ( const Particle & e , recon_e  )
00287         meff += e.momentum().perp();
00288       foreach ( const Particle & mu, recon_mu )
00289         meff += mu.momentum().perp();
00290       foreach ( const Jet & jet, recon_jets ) {
00291         double pT = jet.momentum().perp();
00292         if(pT>40.) meff += pT;
00293       }
00294 
00295       double mSFOS=1e30, mdiff=1e30;
00296       // mass of SFOS pairs closest to the Z mass
00297       for(unsigned int ix=0;ix<recon_e.size();++ix) {
00298         for(unsigned int iy=ix+1;iy<recon_e.size();++iy) {
00299           if(recon_e[ix].pdgId()*recon_e[iy].pdgId()>0) continue;
00300           double mtest = (recon_e[ix].momentum()+recon_e[iy].momentum()).mass();
00301           if(fabs(mtest-90.)<mdiff) {
00302             mSFOS = mtest;
00303             mdiff = fabs(mtest-90.);
00304           }
00305         }
00306       }
00307       for(unsigned int ix=0;ix<recon_mu.size();++ix) {
00308         for(unsigned int iy=ix+1;iy<recon_mu.size();++iy) {
00309           if(recon_mu[ix].pdgId()*recon_mu[iy].pdgId()>0) continue;
00310           double mtest = (recon_mu[ix].momentum()+recon_mu[iy].momentum()).mass();
00311           if(fabs(mtest-91.118)<mdiff) {
00312             mSFOS = mtest;
00313             mdiff = fabs(mtest-91.118);
00314           }
00315         }
00316       }
00317 
00318       // make the control plots
00319       // lepton pT
00320       unsigned int ie=0,imu=0;
00321       for(unsigned int ix=0;ix<4;++ix) {
00322         double pTe  = ie <recon_e .size() ?
00323           recon_e [ie ].momentum().perp() : -1*GeV;
00324         double pTmu = imu<recon_mu.size() ?
00325           recon_mu[imu].momentum().perp() : -1*GeV;
00326         if(pTe>pTmu) {
00327           _hist_leptonpT   [ix]->fill(pTe ,weight);
00328           _hist_leptonpT_MC[ix]->fill(pTe ,weight);
00329           ++ie;
00330         }
00331         else {
00332           _hist_leptonpT   [ix]->fill(pTmu,weight);
00333           _hist_leptonpT_MC[ix]->fill(pTmu,weight);
00334           ++imu;
00335         }
00336       }
00337       // njet
00338       _hist_njet   ->fill(recon_jets.size(),weight);
00339       _hist_njet_MC->fill(recon_jets.size(),weight);
00340       // etmiss
00341       _hist_etmiss   ->fill(eTmiss,weight);
00342       _hist_etmiss_MC->fill(eTmiss,weight);
00343       if(mSFOS<1e30) {
00344         _hist_mSFOS   ->fill(mSFOS,weight);
00345         _hist_mSFOS_MC->fill(mSFOS,weight);
00346       }
00347       _hist_meff   ->fill(meff,weight);
00348       _hist_meff_MC->fill(meff,weight);
00349 
00350       // finally the counts
00351       if(eTmiss>50.) {
00352         _count_SR1->fill(0.5,weight);
00353         if(mdiff>10.) _count_SR2->fill(0.5,weight);
00354       }
00355     }
00356 
00357     //@}
00358 
00359     void finalize() {
00360       double norm = crossSection()/femtobarn*2.06/sumOfWeights();
00361       // these are number of events at 2.06fb^-1 per 10 GeV
00362       scale(_hist_leptonpT   [0],norm*10.);
00363       scale(_hist_leptonpT   [1],norm*10.);
00364       scale(_hist_leptonpT_MC[0],norm*10.);
00365       scale(_hist_leptonpT_MC[1],norm*10.);
00366       // these are number of events at 2.06fb^-1 per 5 GeV
00367       scale(_hist_leptonpT   [2],norm*5.);
00368       scale(_hist_leptonpT   [3],norm*5.);
00369       scale(_hist_leptonpT_MC[2],norm*5.);
00370       scale(_hist_leptonpT_MC[3],norm*5.);
00371       // these are number of events at 2.06fb^-1 per 20 GeV
00372       scale(_hist_etmiss      ,norm*20.);
00373       scale(_hist_mSFOS       ,norm*20.);
00374       scale(_hist_etmiss_MC   ,norm*20.);
00375       scale(_hist_mSFOS_MC    ,norm*20.);
00376       // these are number of events at 2.06fb^-1 per 50 GeV
00377       scale(_hist_meff        ,norm*50.);
00378       scale(_hist_meff_MC     ,norm*50.);
00379       // these are number of events at 2.06fb^-1
00380       scale(_hist_njet        ,norm);
00381       scale(_hist_njet_MC     ,norm);
00382       scale(_count_SR1,norm);
00383       scale(_count_SR2,norm);
00384     }
00385 
00386   private:
00387 
00388     /// @name Histograms
00389     //@{
00390     vector<Histo1DPtr> _hist_leptonpT,_hist_leptonpT_MC;
00391     Histo1DPtr _hist_njet;
00392     Histo1DPtr _hist_njet_MC;
00393     Histo1DPtr _hist_etmiss;
00394     Histo1DPtr _hist_etmiss_MC;
00395     Histo1DPtr _hist_mSFOS;
00396     Histo1DPtr _hist_mSFOS_MC;
00397     Histo1DPtr _hist_meff;
00398     Histo1DPtr _hist_meff_MC;
00399     Histo1DPtr _count_SR1;
00400     Histo1DPtr _count_SR2;
00401     //@}
00402 
00403   };
00404 
00405   // The hook for the plugin system
00406   DECLARE_RIVET_PLUGIN(ATLAS_2012_CONF_2012_001);
00407 
00408 }