rivet is hosted by Hepforge, IPPP Durham
ATLAS_2011_I945498.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 
00004 #include "Rivet/Projections/ZFinder.hh"
00005 #include "Rivet/Projections/FastJets.hh"
00006 #include "Rivet/Projections/FinalState.hh"
00007 #include "Rivet/Projections/VetoedFinalState.hh"
00008 #include "Rivet/Projections/IdentifiedFinalState.hh"
00009 #include "Rivet/Projections/LeadingParticlesFinalState.hh"
00010 
00011 
00012 namespace Rivet {
00013 
00014 
00015   /// ATLAS Z+jets in pp at 7 TeV
00016   class ATLAS_2011_I945498 : public Analysis {
00017   public:
00018 
00019     /// Constructor
00020     ATLAS_2011_I945498()
00021       : Analysis("ATLAS_2011_I945498")
00022     {    }
00023 
00024 
00025     /// Book histograms and initialise projections before the run
00026     void init() {
00027 
00028       // Variable initialisation
00029       _isZeeSample = false;
00030       _isZmmSample = false;
00031       for (size_t chn = 0; chn < 3; ++chn) {
00032         weights_nj0[chn] = 0;
00033         weights_nj1[chn] = 0;
00034         weights_nj2[chn] = 0;
00035         weights_nj3[chn] = 0;
00036         weights_nj4[chn] = 0;
00037       }
00038 
00039       // Set up projections
00040       ZFinder zfinder_mu(-2.4, 2.4, 20*GeV, PID::MUON, 66*GeV, 116*GeV, 0.1, ZFinder::CLUSTERNODECAY);
00041       addProjection(zfinder_mu, "ZFinder_mu");
00042       vector<pair<double, double> > eta_e; /// @todo Use C++11 {{-2.47, -1.52}, {-1.37, 1.37}, {1.52, 2.47}};
00043       eta_e.push_back(make_pair(-2.47, -1.52));
00044       eta_e.push_back(make_pair(-1.37, 1.37));
00045       eta_e.push_back(make_pair(1.52, 2.47));
00046       ZFinder zfinder_el(eta_e, 20*GeV, PID::ELECTRON, 66*GeV, 116*GeV, 0.1, ZFinder::CLUSTERNODECAY);
00047       addProjection(zfinder_el, "ZFinder_el");
00048 
00049       // For combined cross-sections (combined phase space + dressed level)
00050       ZFinder zfinder_comb_mu(-2.5, 2.5, 20*GeV, PID::MUON, 66.0*GeV, 116.0*GeV, 0.1, ZFinder::CLUSTERNODECAY);
00051       addProjection(zfinder_comb_mu, "ZFinder_comb_mu");
00052       ZFinder zfinder_comb_el(-2.5, 2.5, 20*GeV, PID::ELECTRON, 66.0*GeV, 116.0*GeV, 0.1, ZFinder::CLUSTERNODECAY);
00053       addProjection(zfinder_comb_el, "ZFinder_comb_el");
00054 
00055       // Define veto FS in order to prevent Z-decay products entering the jet algorithm
00056       VetoedFinalState remfs;
00057       remfs.addVetoOnThisFinalState(zfinder_el);
00058       remfs.addVetoOnThisFinalState(zfinder_mu);
00059       VetoedFinalState remfs_comb;
00060       remfs_comb.addVetoOnThisFinalState(zfinder_comb_el);
00061       remfs_comb.addVetoOnThisFinalState(zfinder_comb_mu);
00062 
00063       FastJets jets(remfs, FastJets::ANTIKT, 0.4);
00064       jets.useInvisibles();
00065       addProjection(jets, "jets");
00066       FastJets jets_comb(remfs_comb, FastJets::ANTIKT, 0.4);
00067       jets_comb.useInvisibles();
00068       addProjection(jets_comb, "jets_comb");
00069 
00070       // 0=el, 1=mu, 2=comb
00071       for (size_t chn = 0; chn < 3; ++chn) {
00072         _h_njet_incl[chn]  = bookHisto1D(1, 1, chn+1);
00073         _h_njet_ratio[chn] = bookScatter2D(2, 1, chn+1);
00074         _h_ptjet[chn]      = bookHisto1D(3, 1, chn+1);
00075         _h_ptlead[chn]     = bookHisto1D(4, 1, chn+1);
00076         _h_ptseclead[chn]  = bookHisto1D(5, 1, chn+1);
00077         _h_yjet[chn]       = bookHisto1D(6, 1, chn+1);
00078         _h_ylead[chn]      = bookHisto1D(7, 1, chn+1);
00079         _h_yseclead[chn]   = bookHisto1D(8, 1, chn+1);
00080         _h_mass[chn]       = bookHisto1D(9, 1, chn+1);
00081         _h_deltay[chn]     = bookHisto1D(10, 1, chn+1);
00082         _h_deltaphi[chn]   = bookHisto1D(11, 1, chn+1);
00083         _h_deltaR[chn]     = bookHisto1D(12, 1, chn+1);
00084       }
00085     }
00086 
00087 
00088     // Jet selection criteria universal for electron and muon channel
00089     /// @todo Replace with a Cut passed to jetsByPt
00090     Jets selectJets(const ZFinder* zf, const FastJets* allJets) {
00091       const FourMomentum l1 = zf->constituents()[0].momentum();
00092       const FourMomentum l2 = zf->constituents()[1].momentum();
00093       Jets jets;
00094       foreach (const Jet& jet, allJets->jetsByPt(30*GeV)) {
00095         const FourMomentum jmom = jet.momentum();
00096         if (fabs(jmom.rapidity()) < 4.4 &&
00097             deltaR(l1, jmom) > 0.5  && deltaR(l2, jmom) > 0.5) {
00098           jets.push_back(jet);
00099         }
00100       }
00101       return jets;
00102     }
00103 
00104 
00105     /// Perform the per-event analysis
00106     void analyze(const Event& event) {
00107       const double weight = event.weight();
00108 
00109       vector<const ZFinder*> zfs;
00110       zfs.push_back(& (applyProjection<ZFinder>(event, "ZFinder_el")));
00111       zfs.push_back(& (applyProjection<ZFinder>(event, "ZFinder_mu")));
00112       zfs.push_back(& (applyProjection<ZFinder>(event, "ZFinder_comb_el")));
00113       zfs.push_back(& (applyProjection<ZFinder>(event, "ZFinder_comb_mu")));
00114 
00115       vector<const FastJets*> fjs;
00116       fjs.push_back(& (applyProjection<FastJets>(event, "jets")));
00117       fjs.push_back(& (applyProjection<FastJets>(event, "jets_comb")));
00118 
00119       // Determine what kind of MC sample this is
00120       const bool isZee = (zfs[0]->bosons().size() == 1) || (zfs[2]->bosons().size() == 1);
00121       const bool isZmm = (zfs[1]->bosons().size() == 1) || (zfs[3]->bosons().size() == 1);
00122       if (isZee) _isZeeSample = true;
00123       if (isZmm) _isZmmSample = true;
00124 
00125       // Require exactly one electronic or muonic Z-decay in the event
00126       bool isZeemm = ( (zfs[0]->bosons().size() == 1 && zfs[1]->bosons().size() != 1) ||
00127                        (zfs[1]->bosons().size() == 1 && zfs[0]->bosons().size() != 1) );
00128       bool isZcomb = ( (zfs[2]->bosons().size() == 1 && zfs[3]->bosons().size() != 1) ||
00129                        (zfs[3]->bosons().size() == 1 && zfs[2]->bosons().size() != 1) );
00130       if (!isZeemm && !isZcomb) vetoEvent;
00131 
00132       vector<int> zfIDs;
00133       vector<int> fjIDs;
00134       if (isZeemm) {
00135         int chn = zfs[0]->bosons().size() == 1 ? 0 : 1;
00136         zfIDs.push_back(chn);
00137         fjIDs.push_back(0);
00138       }
00139       if (isZcomb) {
00140         int chn = zfs[2]->bosons().size() == 1 ? 2 : 3;
00141         zfIDs.push_back(chn);
00142         fjIDs.push_back(1);
00143       }
00144 
00145       for (size_t izf = 0; izf < zfIDs.size(); ++izf) {
00146         int zfID = zfIDs[izf];
00147         int fjID = fjIDs[izf];
00148 
00149         int chn = zfID;
00150         if (zfID == 2 || zfID == 3) chn = 2;
00151 
00152         Jets jets = selectJets(zfs[zfID], fjs[fjID]);
00153 
00154         switch (jets.size()) {
00155         case 0:
00156           weights_nj0[chn] += weight;
00157           break;
00158         case 1:
00159           weights_nj0[chn] += weight;
00160           weights_nj1[chn] += weight;
00161           break;
00162         case 2:
00163           weights_nj0[chn] += weight;
00164           weights_nj1[chn] += weight;
00165           weights_nj2[chn] += weight;
00166           break;
00167         case 3:
00168           weights_nj0[chn] += weight;
00169           weights_nj1[chn] += weight;
00170           weights_nj2[chn] += weight;
00171           weights_nj3[chn] += weight;
00172           break;
00173         default: // >= 4
00174           weights_nj0[chn] += weight;
00175           weights_nj1[chn] += weight;
00176           weights_nj2[chn] += weight;
00177           weights_nj3[chn] += weight;
00178           weights_nj4[chn] += weight;
00179         }
00180 
00181         // Require at least one jet
00182         if (jets.empty()) continue;
00183 
00184         // Fill jet multiplicities
00185         for (size_t ijet = 1; ijet <= jets.size(); ++ijet) {
00186           _h_njet_incl[chn]->fill(ijet, weight);
00187         }
00188 
00189         // Loop over selected jets, fill inclusive jet distributions
00190         for (size_t ijet = 0; ijet < jets.size(); ++ijet) {
00191           _h_ptjet[chn]->fill(jets[ijet].momentum().pT()/GeV, weight);
00192           _h_yjet [chn]->fill(fabs(jets[ijet].momentum().rapidity()), weight);
00193         }
00194 
00195         // Leading jet histos
00196         const double ptlead   = jets[0].momentum().pT()/GeV;
00197         const double yabslead = fabs(jets[0].momentum().rapidity());
00198         _h_ptlead[chn]->fill(ptlead,   weight);
00199         _h_ylead [chn]->fill(yabslead, weight);
00200 
00201         if (jets.size() >= 2) {
00202           // Second jet histos
00203           const double pt2ndlead   = jets[1].momentum().pT()/GeV;
00204           const double yabs2ndlead = fabs(jets[1].momentum().rapidity());
00205           _h_ptseclead[chn] ->fill(pt2ndlead,   weight);
00206           _h_yseclead [chn] ->fill(yabs2ndlead, weight);
00207 
00208           // Dijet histos
00209           const double deltaphi = fabs(deltaPhi(jets[1], jets[0]));
00210           const double deltarap = fabs(jets[0].momentum().rapidity() - jets[1].momentum().rapidity()) ;
00211           const double deltar   = fabs(deltaR(jets[0], jets[1], RAPIDITY));
00212           const double mass     = (jets[0].momentum() + jets[1].momentum()).mass();
00213           _h_mass    [chn] ->fill(mass/GeV, weight);
00214           _h_deltay  [chn] ->fill(deltarap, weight);
00215           _h_deltaphi[chn] ->fill(deltaphi, weight);
00216           _h_deltaR  [chn] ->fill(deltar,   weight);
00217         }
00218       }
00219     }
00220 
00221 
00222     /// @name Ratio calculator util functions
00223     //@{
00224 
00225     /// Calculate the ratio, being careful about div-by-zero
00226     double ratio(double a, double b) {
00227       return (b != 0) ? a/b : 0;
00228     }
00229 
00230     /// Calculate the ratio error, being careful about div-by-zero
00231     double ratio_err(double a, double b) {
00232       return (b != 0) ? sqrt(a/sqr(b) + sqr(a)/(b*b*b)) : 0;
00233     }
00234 
00235     //@}
00236 
00237 
00238     void finalize() {
00239       // Fill ratio histograms
00240       for (size_t chn = 0; chn < 3; ++chn) {
00241         _h_njet_ratio[chn]->addPoint(1, ratio(weights_nj1[chn], weights_nj0[chn]), 0, ratio_err(weights_nj1[chn], weights_nj0[chn]));
00242         _h_njet_ratio[chn]->addPoint(2, ratio(weights_nj2[chn], weights_nj1[chn]), 0, ratio_err(weights_nj2[chn], weights_nj1[chn]));
00243         _h_njet_ratio[chn]->addPoint(3, ratio(weights_nj3[chn], weights_nj2[chn]), 0, ratio_err(weights_nj3[chn], weights_nj2[chn]));
00244         _h_njet_ratio[chn]->addPoint(4, ratio(weights_nj4[chn], weights_nj3[chn]), 0, ratio_err(weights_nj4[chn], weights_nj3[chn]));
00245       }
00246 
00247       // Scale other histos
00248       for (size_t chn = 0; chn < 3; ++chn) {
00249         // For ee and mumu channels: normalize to Njet inclusive cross-section
00250         double xs = (chn == 2) ? crossSectionPerEvent()/picobarn : 1 / weights_nj0[chn];
00251         // For inclusive MC sample(ee/mmu channels together) we want the single-lepton-flavor xsec
00252         if (_isZeeSample && _isZmmSample) xs /= 2;
00253 
00254         // Special case histogram: always not normalized
00255         scale(_h_njet_incl[chn], (chn < 2) ? crossSectionPerEvent()/picobarn : xs);
00256 
00257         scale(_h_ptjet[chn]    , xs);
00258         scale(_h_ptlead[chn]   , xs);
00259         scale(_h_ptseclead[chn], xs);
00260         scale(_h_yjet[chn]     , xs);
00261         scale(_h_ylead[chn]    , xs);
00262         scale(_h_yseclead[chn] , xs);
00263         scale(_h_deltaphi[chn] , xs);
00264         scale(_h_deltay[chn]   , xs);
00265         scale(_h_deltaR[chn]   , xs);
00266         scale(_h_mass[chn]     , xs);
00267       }
00268 
00269     }
00270 
00271     //@}
00272 
00273 
00274   private:
00275 
00276     bool _isZeeSample;
00277     bool _isZmmSample;
00278 
00279     double weights_nj0[3];
00280     double weights_nj1[3];
00281     double weights_nj2[3];
00282     double weights_nj3[3];
00283     double weights_nj4[3];
00284 
00285     Scatter2DPtr _h_njet_ratio[3];
00286     Histo1DPtr _h_njet_incl[3];
00287     Histo1DPtr _h_ptjet[3];
00288     Histo1DPtr _h_ptlead[3];
00289     Histo1DPtr _h_ptseclead[3];
00290     Histo1DPtr _h_yjet[3];
00291     Histo1DPtr _h_ylead[3];
00292     Histo1DPtr _h_yseclead[3];
00293     Histo1DPtr _h_deltaphi[3];
00294     Histo1DPtr _h_deltay[3];
00295     Histo1DPtr _h_deltaR[3];
00296     Histo1DPtr _h_mass[3];
00297 
00298   };
00299 
00300 
00301   DECLARE_RIVET_PLUGIN(ATLAS_2011_I945498);
00302 
00303 
00304 }