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