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