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