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