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 #include "Rivet/Projections/ClusteredPhotons.hh"
00011 
00012 
00013 namespace Rivet {
00014 
00015 
00016   class ATLAS_2011_I945498 : public Analysis {
00017   public:
00018 
00019     /// @name Constructors etc.
00020     //@{
00021 
00022     /// Constructor
00023     ATLAS_2011_I945498()
00024       : Analysis("ATLAS_2011_I945498")
00025     {
00026       setNeedsCrossSection(true);
00027       for (size_t chn = 0; chn < 3; ++chn) {
00028         weights_nj0[chn] = 0.0;
00029         weights_nj1[chn] = 0.0;
00030         weights_nj2[chn] = 0.0;
00031         weights_nj3[chn] = 0.0;
00032         weights_nj4[chn] = 0.0;
00033       }
00034     }
00035 
00036     //@}
00037 
00038 
00039   public:
00040 
00041     /// Book histograms and initialise projections before the run
00042     void init() {
00043 
00044       // Set up projections
00045       ZFinder zfinder_mu(-2.4, 2.4, 20, PID::MUON, 66.0*GeV, 116.0*GeV, 0.1, true, false);
00046       addProjection(zfinder_mu, "ZFinder_mu");
00047 
00048       std::vector<std::pair<double, double> > eta_e;
00049       eta_e.push_back(make_pair(-2.47, -1.52));
00050       eta_e.push_back(make_pair(-1.37, 1.37));
00051       eta_e.push_back(make_pair(1.52, 2.47));
00052       ZFinder zfinder_el(eta_e, 20, PID::ELECTRON, 66.0*GeV, 116.0*GeV, 0.1, true, false);
00053       addProjection(zfinder_el, "ZFinder_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 
00060       FastJets jets(remfs, FastJets::ANTIKT, 0.4);
00061       jets.useInvisibles();
00062       addProjection(jets, "jets");
00063 
00064       // 0=el, 1=mu, 2=comb
00065       for (size_t chn = 0; chn < 3; ++chn) {
00066         _h_njet_incl[chn]  = bookHisto1D(1, 1, chn+1);
00067         _h_njet_ratio[chn] = bookScatter2D(2, 1, chn+1);
00068         _h_ptjet[chn]      = bookHisto1D(3, 1, chn+1);
00069         _h_ptlead[chn]     = bookHisto1D(4, 1, chn+1);
00070         _h_ptseclead[chn]  = bookHisto1D(5, 1, chn+1);
00071         _h_yjet[chn]       = bookHisto1D(6, 1, chn+1);
00072         _h_ylead[chn]      = bookHisto1D(7, 1, chn+1);
00073         _h_yseclead[chn]   = bookHisto1D(8, 1, chn+1);
00074         _h_mass[chn]       = bookHisto1D(9, 1, chn+1);
00075         _h_deltay[chn]     = bookHisto1D(10, 1, chn+1);
00076         _h_deltaphi[chn]   = bookHisto1D(11, 1, chn+1);
00077         _h_deltaR[chn]     = bookHisto1D(12, 1, chn+1);
00078       }
00079     }
00080 
00081 
00082     // Jet selection criteria universal for electron and muon channel
00083     /// @todo Replace with a Cut passed to jetsByPt
00084     Jets selectJets(const ZFinder* zf, const Event& event) {
00085       FourMomentum l1 = zf->constituents()[0].momentum();
00086       FourMomentum l2 = zf->constituents()[1].momentum();
00087       Jets jets;
00088       foreach (const Jet& jet, applyProjection<FastJets>(event, "jets").jetsByPt(30.0*GeV)) {
00089         FourMomentum jmom = jet.momentum();
00090         if (fabs(jmom.rapidity()) < 4.4 && deltaR(l1, jmom) > 0.5  && deltaR(l2, jmom) > 0.5) {
00091           jets.push_back(jet);
00092         }
00093       }
00094       return jets;
00095     }
00096 
00097 
00098     /// Perform the per-event analysis
00099     void analyze(const Event& event) {
00100 
00101       const double weight = event.weight();
00102 
00103       vector<const ZFinder*> zfs;
00104       zfs.push_back(& (applyProjection<ZFinder>(event, "ZFinder_el")));
00105       zfs.push_back(& (applyProjection<ZFinder>(event, "ZFinder_mu")));
00106 
00107       // Require exactly one electronic or muonic Z-decay in the event
00108       if (!( (zfs[0]->bosons().size() == 1 && zfs[1]->bosons().size() != 1) ||
00109              (zfs[1]->bosons().size() == 1 && zfs[0]->bosons().size() != 1) )) vetoEvent;
00110       int chn = zfs[0]->bosons().size() == 1 ? 0 : 1;
00111 
00112       Jets jets = selectJets(zfs[chn], event);
00113 
00114       /// @todo Holger wrote in his commit message that the njet_ratio
00115       /// histograms need fixing/checking, and therefore the analysis
00116       /// is marked unvalidated!
00117 
00118       // Some silly weight counters for the njet-ratio histo
00119       // --- not sure about the njet=0 case, the Figure caption says
00120       // that selected events require at least one jet with 20 GeV
00121       switch (jets.size()) {
00122       case 0:
00123         weights_nj0[chn] += weight;
00124         break;
00125       case 1:
00126         weights_nj0[chn] += weight;
00127         weights_nj1[chn] += weight;
00128         break;
00129       case 2:
00130         weights_nj0[chn] += weight;
00131         weights_nj1[chn] += weight;
00132         weights_nj2[chn] += weight;
00133         break;
00134       case 3:
00135         weights_nj0[chn] += weight;
00136         weights_nj1[chn] += weight;
00137         weights_nj2[chn] += weight;
00138         weights_nj3[chn] += weight;
00139         break;
00140       default: // >= 4
00141         weights_nj0[chn] += weight;
00142         weights_nj1[chn] += weight;
00143         weights_nj2[chn] += weight;
00144         weights_nj3[chn] += weight;
00145         weights_nj4[chn] += weight;
00146       }
00147 
00148       // Require at least one jet
00149       if (jets.size() < 1) vetoEvent;
00150 
00151       // Fill jet multiplicities
00152       _h_njet_incl[chn]->fill(jets.size(), weight);
00153       _h_njet_incl[2]->fill(jets.size(), weight);
00154 
00155       // Loop over selected jets, fill inclusive jet distributions
00156       for (size_t ijet = 0; ijet < jets.size(); ++ijet) {
00157         _h_ptjet[chn]->fill(jets[ijet].pT()/GeV, weight);
00158         _h_ptjet[2]  ->fill(jets[ijet].pT()/GeV, weight);
00159         _h_yjet[chn] ->fill(fabs(jets[ijet].rapidity()), weight);
00160         _h_yjet[2]   ->fill(fabs(jets[ijet].rapidity()), weight);
00161       }
00162 
00163       // Leading jet histos
00164       const double ptlead = jets[0].pT()/GeV;
00165       const double yabslead = fabs(jets[0].rapidity());
00166       _h_ptlead[chn]->fill(ptlead,   weight);
00167       _h_ptlead[2]  ->fill(ptlead,   weight);
00168       _h_ylead[chn] ->fill(yabslead, weight);
00169       _h_ylead[2]   ->fill(yabslead, weight);
00170 
00171       if (jets.size() >= 2) {
00172         // Second jet histos
00173         const double pt2ndlead   = jets[1].pT()/GeV;
00174         const double yabs2ndlead = fabs(jets[1].rapidity());
00175         _h_ptseclead[chn] ->fill(pt2ndlead,   weight);
00176         _h_ptseclead[2]   ->fill(pt2ndlead,   weight);
00177         _h_yseclead[chn]  ->fill(yabs2ndlead, weight);
00178         _h_yseclead[2]    ->fill(yabs2ndlead, weight);
00179 
00180         // Dijet histos
00181         const double deltaphi = fabs(deltaPhi(jets[1], jets[0]));
00182         const double deltarap = fabs(jets[0].rapidity() - jets[1].rapidity()) ;
00183         const double deltar   = fabs(deltaR(jets[0], jets[1], RAPIDITY));
00184         const double mass     = (jets[0].momentum() + jets[1].momentum()).mass();
00185         _h_mass[chn]    ->fill(mass,     weight);
00186         _h_mass[2]      ->fill(mass,     weight);
00187         _h_deltay[chn]  ->fill(deltarap, weight);
00188         _h_deltay[2]    ->fill(deltarap, weight);
00189         _h_deltaphi[chn]->fill(deltaphi, weight);
00190         _h_deltaphi[2]  ->fill(deltaphi, weight);
00191         _h_deltaR[chn]  ->fill(deltar,   weight);
00192         _h_deltaR[2]    ->fill(deltar,   weight);
00193       }
00194 
00195     }
00196 
00197 
00198     /// @name Ratio calculator util functions
00199     //@{
00200 
00201     /// Calculate the ratio, being careful about div-by-zero
00202     double ratio(double a, double b) {
00203       return (b != 0) ? a/b : 0;
00204     }
00205 
00206     /// Calculate the ratio error, being careful about div-by-zero
00207     double ratio_err(double a, double b) {
00208       return (b != 0) ? sqrt(a/sqr(b) + sqr(a)/(b*b*b)) : 0;
00209     }
00210 
00211     /// Calculate combined ratio from muon and electron channels
00212     double comb_ratio(double* as, double* bs) {
00213       return ratio(as[0]+as[1], bs[0]+bs[1]);
00214     }
00215 
00216     /// Calculate combined ratio error from muon and electron channels
00217     double comb_ratio_err(double* as, double* bs) {
00218       return ratio_err(as[0]+as[1], bs[0]+bs[1]);
00219     }
00220 
00221     //@}
00222 
00223 
00224     void finalize() {
00225 
00226       // Fill ratio histograms
00227       for (size_t chn = 0; chn < 2; ++chn) {
00228         _h_njet_ratio[chn]->addPoint(1, ratio(weights_nj1[chn], weights_nj0[chn]), 0, ratio_err(weights_nj1[chn], weights_nj0[chn]));
00229         _h_njet_ratio[chn]->addPoint(2, ratio(weights_nj2[chn], weights_nj1[chn]), 0, ratio_err(weights_nj2[chn], weights_nj1[chn]));
00230         _h_njet_ratio[chn]->addPoint(3, ratio(weights_nj3[chn], weights_nj2[chn]), 0, ratio_err(weights_nj3[chn], weights_nj2[chn]));
00231         _h_njet_ratio[chn]->addPoint(4, ratio(weights_nj4[chn], weights_nj3[chn]), 0, ratio_err(weights_nj4[chn], weights_nj3[chn]));
00232       }
00233       _h_njet_ratio[2]->addPoint(1, comb_ratio(weights_nj1, weights_nj0), 0, comb_ratio_err(weights_nj1, weights_nj0));
00234       _h_njet_ratio[2]->addPoint(2, comb_ratio(weights_nj2, weights_nj1), 0, comb_ratio_err(weights_nj2, weights_nj1));
00235       _h_njet_ratio[2]->addPoint(3, comb_ratio(weights_nj3, weights_nj2), 0, comb_ratio_err(weights_nj3, weights_nj2));
00236       _h_njet_ratio[2]->addPoint(4, comb_ratio(weights_nj4, weights_nj3), 0, comb_ratio_err(weights_nj4, weights_nj3));
00237 
00238       // Scale other histos
00239       const double xs = crossSectionPerEvent()/picobarn;
00240       for (size_t chn = 0; chn < 3; ++chn) {
00241         scale(_h_njet_incl[chn], xs);
00242         scale(_h_ptjet[chn]    , xs);
00243         scale(_h_ptlead[chn]   , xs);
00244         scale(_h_ptseclead[chn], xs);
00245         scale(_h_yjet[chn]     , xs);
00246         scale(_h_ylead[chn]    , xs);
00247         scale(_h_yseclead[chn] , xs);
00248         scale(_h_deltaphi[chn] , xs);
00249         scale(_h_deltay[chn]   , xs);
00250         scale(_h_deltaR[chn]   , xs);
00251         scale(_h_mass[chn]     , xs);
00252       }
00253 
00254     }
00255 
00256     //@}
00257 
00258 
00259   private:
00260 
00261     double weights_nj0[3];
00262     double weights_nj1[3];
00263     double weights_nj2[3];
00264     double weights_nj3[3];
00265     double weights_nj4[3];
00266 
00267     Scatter2DPtr _h_njet_ratio[3];
00268     Histo1DPtr _h_njet_incl[3];
00269     Histo1DPtr _h_ptjet[3];
00270     Histo1DPtr _h_ptlead[3];
00271     Histo1DPtr _h_ptseclead[3];
00272     Histo1DPtr _h_yjet[3];
00273     Histo1DPtr _h_ylead[3];
00274     Histo1DPtr _h_yseclead[3];
00275     Histo1DPtr _h_deltaphi[3];
00276     Histo1DPtr _h_deltay[3];
00277     Histo1DPtr _h_deltaR[3];
00278     Histo1DPtr _h_mass[3];
00279 
00280   };
00281 
00282 
00283   DECLARE_RIVET_PLUGIN(ATLAS_2011_I945498);
00284 
00285 
00286 }