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