rivet is hosted by Hepforge, IPPP Durham
ATLAS_2011_S9212183.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/IdentifiedFinalState.hh"
00010 #include "Rivet/Projections/FastJets.hh"
00011 
00012 namespace Rivet {
00013 
00014 
00015   /// @author Chris Wymant
00016   class ATLAS_2011_S9212183 : public Analysis {
00017   public:
00018 
00019     /// @name Constructors etc.
00020     //@{
00021 
00022     /// Constructor
00023     ATLAS_2011_S9212183()
00024       : Analysis("ATLAS_2011_S9212183")
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       std::vector<std::pair<double, double> > eta_e;
00040       eta_e.push_back(make_pair(-2.47,2.47));
00041       IdentifiedFinalState elecs(eta_e, 20.0*GeV);
00042       elecs.acceptIdPair(ELECTRON);
00043       addProjection(elecs, "elecs");
00044 
00045       // Projection to find the muons
00046       std::vector<std::pair<double, double> > eta_m;
00047       eta_m.push_back(make_pair(-2.4,2.4));
00048       IdentifiedFinalState muons(eta_m, 10.0*GeV);
00049       muons.acceptIdPair(MUON);
00050       addProjection(muons, "muons");
00051 
00052       // Jet finder
00053       addProjection(FastJets(FinalState(), FastJets::ANTIKT, 0.4), "AntiKtJets04");
00054 
00055       // All tracks (to do deltaR with leptons)
00056       addProjection(ChargedFinalState(-3.0,3.0),"cfs");
00057 
00058       // Used for pTmiss (N.B. the real 'vfs' extends beyond 4.5 to |eta| = 4.9)
00059       addProjection(VisibleFinalState(-4.5,4.5),"vfs");
00060 
00061 
00062       // Book histograms
00063       _count_2j   = bookHisto1D("count_2j",   1, 0., 1.);
00064       _count_3j   = bookHisto1D("count_3j",   1, 0., 1.);
00065       _count_4j5  = bookHisto1D("count_4j5",  1, 0., 1.);
00066       _count_4j10 = bookHisto1D("count_4j10", 1, 0., 1.);
00067       _count_HM   = bookHisto1D("count_HM",   1, 0., 1.);
00068 
00069       _hist_meff_2j  = bookHisto1D(1, 1, 1);
00070       _hist_meff_3j  = bookHisto1D(2, 1, 1);
00071       _hist_meff_4j  = bookHisto1D(3, 1, 1);
00072       _hist_meff_HM  = bookHisto1D(4, 1, 1);
00073 
00074       _hist_eTmiss  = bookHisto1D("Et_miss", 20, 0., 1000.);
00075     }
00076 
00077 
00078     /// Perform the per-event analysis
00079     void analyze(const Event& event) {
00080       const double weight = event.weight();
00081 
00082       Jets cand_jets;
00083       const Jets jets = applyProjection<FastJets>(event, "AntiKtJets04").jetsByPt(20.0*GeV);
00084       foreach (const Jet& jet, jets) {
00085         if ( fabs( jet.momentum().eta() ) < 4.9 ) {
00086           cand_jets.push_back(jet);
00087         }
00088       }
00089 
00090       const ParticleVector cand_e  = applyProjection<IdentifiedFinalState>(event, "elecs").particlesByPt();
00091 
00092       // Muon isolation not mentioned in hep-exp 1109.6572, unlike in 1102.5290,
00093       // but assumed to still be applicable
00094       ParticleVector cand_mu;
00095       const ParticleVector chg_tracks = applyProjection<ChargedFinalState>(event, "cfs").particles();
00096       const ParticleVector muons = applyProjection<IdentifiedFinalState>(event, "muons").particlesByPt();
00097       foreach (const Particle& mu, muons) {
00098         double pTinCone = -mu.momentum().pT();
00099         foreach (const Particle& track, chg_tracks) {
00100           if ( deltaR(mu.momentum(),track.momentum()) <= 0.2 ) {
00101             pTinCone += track.momentum().pT();
00102           }
00103         }
00104         if ( pTinCone < 1.8*GeV ) cand_mu.push_back(mu);
00105       }
00106 
00107       // Resolve jet-lepton overlap for jets with |eta| < 2.8
00108       Jets cand_jets_2;
00109       foreach ( const Jet& jet, cand_jets ) {
00110         if ( fabs( jet.momentum().eta() ) >= 2.8 ) {
00111           cand_jets_2.push_back( jet );
00112         } else {
00113           bool away_from_e = true;
00114           foreach ( const Particle & e, cand_e ) {
00115             if ( deltaR(e.momentum(),jet.momentum()) <= 0.2 ) {
00116               away_from_e = false;
00117               break;
00118             }
00119           }
00120           if ( away_from_e ) cand_jets_2.push_back( jet );
00121         }
00122       }
00123 
00124 
00125       ParticleVector recon_e, recon_mu;
00126 
00127       foreach ( const Particle & e, cand_e ) {
00128         bool away = true;
00129         foreach ( const Jet& jet, cand_jets_2 ) {
00130           if ( deltaR(e.momentum(),jet.momentum()) < 0.4 ) {
00131             away = false;
00132             break;
00133           }
00134         }
00135         if ( away ) recon_e.push_back( e );
00136       }
00137 
00138       foreach ( const Particle & mu, cand_mu ) {
00139         bool away = true;
00140         foreach ( const Jet& jet, cand_jets_2 ) {
00141           if ( deltaR(mu.momentum(),jet.momentum()) < 0.4 ) {
00142             away = false;
00143             break;
00144           }
00145         }
00146         if ( away ) recon_mu.push_back( mu );
00147       }
00148 
00149 
00150       // pTmiss
00151       // Based on all candidate electrons, muons and jets, plus everything else with |eta| < 4.5
00152       // i.e. everything in our projection "vfs" plus the jets with |eta| > 4.5
00153       ParticleVector vfs_particles = applyProjection<VisibleFinalState>(event, "vfs").particles();
00154       FourMomentum pTmiss;
00155       foreach ( const Particle & p, vfs_particles ) {
00156         pTmiss -= p.momentum();
00157       }
00158       foreach ( const Jet& jet, cand_jets_2 ) {
00159         if ( fabs( jet.momentum().eta() ) > 4.5 ) pTmiss -= jet.momentum();
00160       }
00161       double eTmiss = pTmiss.pT();
00162 
00163 
00164       // Final jet filter
00165       Jets recon_jets;
00166       foreach ( const Jet& jet, cand_jets_2 ) {
00167         if ( fabs( jet.momentum().eta() ) <= 2.8 ) recon_jets.push_back( jet );
00168       }
00169       // NB. It seems that jets with |eta| > 2.8 could have been thrown away at
00170       // the start; we don't do so, in order to follow both the structure of
00171       // the paper and the similar Rivet analysis ATLAS_2011_S8983313
00172 
00173       // 'candidate' muons needed only 10 GeV, to cause a veto they need 20 GeV
00174       ParticleVector veto_mu;
00175       foreach ( const Particle & mu, cand_mu ) {
00176         if ( mu.momentum().pT() >= 20.0*GeV ) veto_mu.push_back(mu);
00177       }
00178 
00179       if ( ! ( veto_mu.empty() && recon_e.empty() ) ) {
00180         MSG_DEBUG("Charged leptons left after selection");
00181         vetoEvent;
00182       }
00183 
00184       if ( eTmiss <= 130 * GeV ) {
00185         MSG_DEBUG("Not enough eTmiss: " << eTmiss << " < 130");
00186         vetoEvent;
00187       }
00188 
00189       if ( recon_jets.empty() || recon_jets[0].momentum().pT() <= 130.0 * GeV ) {
00190         MSG_DEBUG("No hard leading jet in " << recon_jets.size() << " jets");
00191         vetoEvent;
00192       }
00193 
00194       // ==================== observables ====================
00195 
00196       int Njets = 0;
00197       double min_dPhi = 999.999;
00198       double pTmiss_phi = pTmiss.phi();
00199       foreach ( const Jet& jet, recon_jets ) {
00200         if ( jet.momentum().pT() > 40 * GeV ) {
00201           if ( Njets < 3 ) {
00202             min_dPhi = min( min_dPhi, deltaPhi( pTmiss_phi, jet.momentum().phi() ) );
00203           }
00204           ++Njets;
00205         }
00206       }
00207 
00208       int NjetsHighMass = 0;
00209       foreach ( const Jet& jet, recon_jets ) {
00210         if ( jet.momentum().pT() > 80.0 * GeV ) {
00211           ++NjetsHighMass;
00212         }
00213       }
00214 
00215       if ( Njets < 2 ) {
00216         MSG_DEBUG("Only " << Njets << " >40 GeV jets left");
00217         vetoEvent;
00218       }
00219 
00220       if ( min_dPhi <= 0.4 ) {
00221         MSG_DEBUG("dPhi too small");
00222         vetoEvent;
00223       }
00224 
00225       // m_eff
00226       double m_eff_2j = eTmiss + recon_jets[0].momentum().pT() + recon_jets[1].momentum().pT();
00227       double m_eff_3j = recon_jets.size() < 3 ? -999.0 : m_eff_2j + recon_jets[2].momentum().pT();
00228       double m_eff_4j = recon_jets.size() < 4 ? -999.0 : m_eff_3j + recon_jets[3].momentum().pT();
00229       double m_eff_HM = eTmiss;
00230       foreach ( const Jet& jet, recon_jets ) {
00231         if ( jet.momentum().pT() > 40.0 * GeV ) m_eff_HM += jet.momentum().pT();
00232       }
00233 
00234       double et_meff_2j = eTmiss / m_eff_2j;
00235       double et_meff_3j = eTmiss / m_eff_3j;
00236       double et_meff_4j = eTmiss / m_eff_4j;
00237       double et_meff_HM = eTmiss / m_eff_HM;
00238 
00239 
00240       // ==================== FILL ====================
00241 
00242       MSG_DEBUG( "Trying to fill "
00243                  << Njets << ' '
00244                  << m_eff_2j << ' '
00245                  << et_meff_2j << ' '
00246                  << m_eff_3j << ' '
00247                  << et_meff_3j << ' '
00248                  << m_eff_4j << ' '
00249                  << et_meff_4j << ' '
00250                  << m_eff_HM << ' '
00251                  << et_meff_HM );
00252 
00253 
00254       _hist_eTmiss->fill(eTmiss, weight);
00255 
00256 
00257       // 2j region
00258       if ( et_meff_2j > 0.3 ) {
00259         _hist_meff_2j->fill(m_eff_2j, weight);
00260         if ( m_eff_2j > 1000 * GeV ) {
00261           MSG_DEBUG("Hits 2j");
00262           _count_2j->fill(0.5, weight);
00263         }
00264       }
00265 
00266 
00267       // 3j region
00268       if ( Njets >= 3 && et_meff_3j > 0.25 ) {
00269         _hist_meff_3j->fill(m_eff_3j, weight);
00270         if ( m_eff_3j > 1000 * GeV ) {
00271           MSG_DEBUG("Hits 3j");
00272           _count_3j->fill(0.5, weight);
00273         }
00274       }
00275 
00276 
00277       // 4j5 & 4j10 regions
00278       if ( Njets >= 4 && et_meff_4j > 0.25 ) {
00279         _hist_meff_4j->fill(m_eff_4j, weight);
00280         if ( m_eff_4j > 500 * GeV ) {
00281           MSG_DEBUG("Hits 4j5");
00282           _count_4j5->fill(0.5, weight);
00283         }
00284         if ( m_eff_4j > 1000 * GeV ) {
00285           MSG_DEBUG("Hits 4j10");
00286           _count_4j10->fill(0.5, weight);
00287         }
00288       }
00289 
00290 
00291       // High mass region
00292       if ( NjetsHighMass >= 4 && et_meff_HM > 0.2 ) {
00293         _hist_meff_HM->fill(m_eff_HM, weight);
00294         if ( m_eff_HM > 1100 * GeV ) {
00295           MSG_DEBUG("Hits HM");
00296           _count_HM->fill(0.5, weight);
00297         }
00298       }
00299 
00300     }
00301 
00302 
00303     void finalize() {
00304       // Two, three and four jet channels have bin width = 100 (GeV)
00305       // High mass channel has bin width = 150 (GeV)
00306       // Integrated luminosity = 1040 (pb)
00307       scale( _hist_meff_2j, 100. * 1040 * crossSection()/sumOfWeights() );
00308       scale( _hist_meff_3j, 100. * 1040 * crossSection()/sumOfWeights() );
00309       scale( _hist_meff_4j, 100. * 1040 * crossSection()/sumOfWeights() );
00310       scale( _hist_meff_HM, 150. * 1040 * crossSection()/sumOfWeights() );
00311     }
00312 
00313     //@}
00314 
00315 
00316   private:
00317 
00318     Histo1DPtr _count_2j;
00319     Histo1DPtr _count_3j;
00320     Histo1DPtr _count_4j5;
00321     Histo1DPtr _count_4j10;
00322     Histo1DPtr _count_HM;
00323     Histo1DPtr _hist_meff_2j;
00324     Histo1DPtr _hist_meff_3j;
00325     Histo1DPtr _hist_meff_4j;
00326     Histo1DPtr _hist_meff_HM;
00327     Histo1DPtr _hist_eTmiss;
00328 
00329   };
00330 
00331 
00332   // This global object acts as a hook for the plugin system
00333   DECLARE_RIVET_PLUGIN(ATLAS_2011_S9212183);
00334 
00335 }