rivet is hosted by Hepforge, IPPP Durham
MC_JetAnalysis.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analyses/MC_JetAnalysis.hh"
00003 #include "Rivet/Projections/FastJets.hh"
00004 #include "Rivet/Tools/Logging.hh"
00005 #include "Rivet/RivetYODA.hh"
00006 
00007 namespace Rivet {
00008 
00009 
00010   MC_JetAnalysis::MC_JetAnalysis(const string& name,
00011                                  size_t njet,
00012                                  const string& jetpro_name,
00013                                  double jetptcut)
00014     : Analysis(name), m_njet(njet), m_jetpro_name(jetpro_name), m_jetptcut(jetptcut),
00015       _h_log10_d(njet), _h_log10_R(njet+1), _h_pT_jet(njet),
00016       _h_eta_jet(njet), _h_eta_jet_plus(njet), _h_eta_jet_minus(njet),
00017       _h_rap_jet(njet), _h_rap_jet_plus(njet), _h_rap_jet_minus(njet),
00018      _h_mass_jet(njet)
00019   {
00020     setNeedsCrossSection(true); // legitimate use, since a base class has no .info file!
00021   }
00022 
00023 
00024 
00025   // Book histograms
00026   void MC_JetAnalysis::init() {
00027 
00028     for (size_t i=0; i < m_njet; ++i) {
00029       stringstream dname;
00030       dname << "log10_d_" << i << i+1;
00031 
00032       _h_log10_d[i] = bookHisto1D(dname.str(), 50, 0.2, log10(0.5*sqrtS()));
00033 
00034       stringstream Rname;
00035       Rname << "log10_R_" << i;
00036       _h_log10_R[i] = bookScatter2D(Rname.str(), 50, 0.2, log10(0.5*sqrtS()));
00037 
00038       stringstream pTname;
00039       pTname << "jet_pT_" << i+1;
00040       double pTmax = 1.0/(double(i)+2.0) * sqrtS()/GeV/2.0;
00041       int nbins_pT = 100/(i+1);
00042       _h_pT_jet[i] = bookHisto1D(pTname.str(), logspace(nbins_pT, 10.0, pTmax));
00043 
00044       stringstream massname;
00045       massname << "jet_mass_" << i+1;
00046       double mmax = 100.0;
00047       int nbins_m = 100/(i+1);
00048       _h_mass_jet[i] = bookHisto1D(massname.str(), logspace(nbins_m, 1.0, mmax));
00049 
00050       stringstream etaname;
00051       etaname << "jet_eta_" << i+1;
00052       _h_eta_jet[i] = bookHisto1D(etaname.str(), i > 1 ? 25 : 50, -5.0, 5.0);
00053       _h_eta_jet_plus[i].reset(new Histo1D(i > 1 ? 15 : 25, 0, 5));
00054       _h_eta_jet_minus[i].reset(new Histo1D(i > 1 ? 15 : 25, 0, 5));
00055 
00056       stringstream rapname;
00057       rapname << "jet_y_" << i+1;
00058       _h_rap_jet[i] = bookHisto1D(rapname.str(), i>1 ? 25 : 50, -5.0, 5.0);
00059       _h_rap_jet_plus[i].reset(new Histo1D(i > 1 ? 15 : 25, 0, 5));
00060       _h_rap_jet_minus[i].reset(new Histo1D(i > 1 ? 15 : 25, 0, 5));
00061 
00062       for (size_t j = i+1; j < min(size_t(3),m_njet); ++j) {
00063         std::pair<size_t, size_t> ij = std::make_pair(i, j);
00064 
00065         stringstream detaname;
00066         detaname << "jets_deta_" << i+1 << j+1;
00067         _h_deta_jets.insert(make_pair(ij, bookHisto1D(detaname.str(), 25, -5.0, 5.0)));
00068 
00069         stringstream dphiname;
00070         dphiname << "jets_dphi_" << i+1 << j+1;
00071         _h_dphi_jets.insert(make_pair(ij, bookHisto1D(dphiname.str(), 25, 0.0, M_PI)));
00072 
00073         stringstream dRname;
00074         dRname << "jets_dR_" << i+1 << j+1;
00075         _h_dR_jets.insert(make_pair(ij, bookHisto1D(dRname.str(), 25, 0.0, 5.0)));
00076       }
00077     }
00078     stringstream Rname;
00079     Rname << "log10_R_" << m_njet;
00080     _h_log10_R[m_njet] = bookScatter2D(Rname.str(), 50, 0.2, log10(0.5*sqrtS()));
00081 
00082     _h_jet_multi_exclusive = bookHisto1D("jet_multi_exclusive", m_njet+3, -0.5, m_njet+3-0.5);
00083     _h_jet_multi_inclusive = bookHisto1D("jet_multi_inclusive", m_njet+3, -0.5, m_njet+3-0.5);
00084     _h_jet_multi_ratio = bookScatter2D("jet_multi_ratio", m_njet+2, 0.5, m_njet+3-0.5);
00085     _h_jet_HT = bookHisto1D("jet_HT", logspace(50, m_jetptcut, sqrtS()/GeV/2.0));
00086   }
00087 
00088 
00089 
00090   // Do the analysis
00091   void MC_JetAnalysis::analyze(const Event & e) {
00092     const double weight = e.weight();
00093 
00094     const FastJets& jetpro = applyProjection<FastJets>(e, m_jetpro_name);
00095 
00096     // Jet resolutions and integrated jet rates
00097     const fastjet::ClusterSequence* seq = jetpro.clusterSeq();
00098     if (seq != NULL) {
00099       double previous_dij = 10.0;
00100       for (size_t i = 0; i < m_njet; ++i) {
00101         // Jet resolution i -> j
00102         double d_ij = log10(sqrt(seq->exclusive_dmerge_max(i)));
00103 
00104         // Fill differential jet resolution
00105         _h_log10_d[i]->fill(d_ij, weight);
00106 
00107         // Fill integrated jet resolution
00108         for (size_t ibin = 0; ibin < _h_log10_R[i]->numPoints(); ++ibin) {
00109           Point2D & dp = _h_log10_R[i]->point(ibin);
00110           double dcut = dp.x();
00111           if (d_ij < dcut && previous_dij > dcut) {
00112             dp.setY(dp.y() + weight);
00113           }
00114         }
00115         previous_dij = d_ij;
00116       }
00117       // One remaining integrated jet resolution
00118       for (size_t ibin = 0; ibin<_h_log10_R[m_njet]->numPoints(); ++ibin) {
00119         Point2D & dp = _h_log10_R[m_njet]->point(ibin);
00120         double dcut = dp.x();
00121         if (previous_dij > dcut) {
00122           dp.setY(dp.y() + weight);
00123         }
00124       }
00125     }
00126 
00127     const Jets& jets = jetpro.jetsByPt(m_jetptcut);
00128 
00129     // The remaining direct jet observables
00130     for (size_t i = 0; i < m_njet; ++i) {
00131       if (jets.size() < i+1) continue;
00132       _h_pT_jet[i]->fill(jets[i].momentum().pT()/GeV, weight);
00133       // Check for numerical precision issues with jet masses
00134       double m2_i = jets[i].momentum().mass2();
00135       if (m2_i < 0) {
00136         if (m2_i < -1e-4) {
00137           MSG_WARNING("Jet mass2 is negative: " << m2_i << " GeV^2. "
00138                       << "Truncating to 0.0, assuming numerical precision is to blame.");
00139         }
00140         m2_i = 0.0;
00141       }
00142 
00143       // Jet mass
00144       _h_mass_jet[i]->fill(sqrt(m2_i)/GeV, weight);
00145 
00146       // Jet eta
00147       const double eta_i = jets[i].momentum().eta();
00148       _h_eta_jet[i]->fill(eta_i, weight);
00149       if (eta_i > 0.0) {
00150         _h_eta_jet_plus[i]->fill(eta_i, weight);
00151       } else {
00152         _h_eta_jet_minus[i]->fill(fabs(eta_i), weight);
00153       }
00154 
00155       // Jet rapidity
00156       const double rap_i = jets[i].momentum().rapidity();
00157       _h_rap_jet[i]->fill(rap_i, weight);
00158       if (rap_i > 0.0) {
00159         _h_rap_jet_plus[i]->fill(rap_i, weight);
00160       } else {
00161         _h_rap_jet_minus[i]->fill(fabs(rap_i), weight);
00162       }
00163 
00164       // Inter-jet properties
00165       for (size_t j = i+1; j < min(size_t(3),m_njet); ++j) {
00166         if (jets.size() < j+1) continue;
00167         std::pair<size_t, size_t> ij = std::make_pair(i, j);
00168         double deta = jets[i].momentum().eta()-jets[j].momentum().eta();
00169         double dphi = deltaPhi(jets[i].momentum(),jets[j].momentum());
00170         double dR = deltaR(jets[i].momentum(), jets[j].momentum());
00171         _h_deta_jets[ij]->fill(deta, weight);
00172         _h_dphi_jets[ij]->fill(dphi, weight);
00173         _h_dR_jets[ij]->fill(dR, weight);
00174       }
00175     }
00176     _h_jet_multi_exclusive->fill(jets.size(), weight);
00177 
00178     for (size_t i = 0; i < m_njet+2; ++i) {
00179       if (jets.size() >= i) {
00180         _h_jet_multi_inclusive->fill(i, weight);
00181       }
00182     }
00183 
00184     double HT=0.0;
00185     foreach (const Jet& jet, jets) {
00186       HT += jet.momentum().pT();
00187     }
00188     _h_jet_HT->fill(HT, weight);
00189   }
00190 
00191 
00192   // Finalize
00193   void MC_JetAnalysis::finalize() {
00194     for (size_t i = 0; i < m_njet; ++i) {
00195       scale(_h_log10_d[i], crossSection()/sumOfWeights());
00196       for (size_t ibin = 0; ibin<_h_log10_R[i]->numPoints(); ++ibin) {
00197         Point2D & dp = _h_log10_R[i]->point(ibin);
00198         dp.setY(dp.y()*crossSection()/sumOfWeights());
00199       }
00200 
00201       scale(_h_pT_jet[i], crossSection()/sumOfWeights());
00202       scale(_h_mass_jet[i], crossSection()/sumOfWeights());
00203       scale(_h_eta_jet[i], crossSection()/sumOfWeights());
00204       scale(_h_rap_jet[i], crossSection()/sumOfWeights());
00205 
00206       // Create eta/rapidity ratio plots
00207       stringstream etaname;
00208       etaname << "jet_eta_pmratio_" << i+1;
00209       // \todo YODA divide
00210       // histogramFactory().divide(histoPath(etaname.str()), *_h_eta_jet_plus[i], *_h_eta_jet_minus[i]);
00211       stringstream rapname;
00212       rapname << "jet_y_pmratio_" << i+1;
00213       // histogramFactory().divide(histoPath(rapname.str()), *_h_rap_jet_plus[i], *_h_rap_jet_minus[i]);
00214     }
00215 
00216     for (size_t ibin = 0; ibin < _h_log10_R[m_njet]->numPoints(); ++ibin) {
00217       Point2D & dp =_h_log10_R[m_njet]->point(ibin);
00218       dp.setY(dp.y()*crossSection()/sumOfWeights());
00219     }
00220 
00221     // Scale the d{eta,R} histograms
00222     map<pair<size_t, size_t>, Histo1DPtr>::iterator it;
00223     for (it = _h_deta_jets.begin(); it != _h_deta_jets.end(); ++it) {
00224       scale(it->second, crossSection()/sumOfWeights());
00225     }
00226     for (it = _h_dphi_jets.begin(); it != _h_dphi_jets.end(); ++it) {
00227       scale(it->second, crossSection()/sumOfWeights());
00228     }
00229     for (it = _h_dR_jets.begin(); it != _h_dR_jets.end(); ++it) {
00230       scale(it->second, crossSection()/sumOfWeights());
00231     }
00232 
00233     // Fill inclusive jet multi ratio
00234     int Nbins = _h_jet_multi_inclusive->numBins();
00235     for (int i = 0; i < Nbins-1; ++i) {
00236       if (_h_jet_multi_inclusive->bin(i).area() > 0.0 && _h_jet_multi_inclusive->bin(i+1).area() > 0.0) {
00237         double ratio = _h_jet_multi_inclusive->bin(i+1).area()/_h_jet_multi_inclusive->bin(i).area();
00238         double relerr_i = _h_jet_multi_inclusive->bin(i).areaErr()/_h_jet_multi_inclusive->bin(i).area();
00239         double relerr_j = _h_jet_multi_inclusive->bin(i+1).areaErr()/_h_jet_multi_inclusive->bin(i+1).area();
00240         double err = ratio * (relerr_i + relerr_j);
00241 
00242     Point2D & pt = _h_jet_multi_ratio->point(i);
00243     pt.setY(ratio);
00244     pt.setYErr(err);
00245       }
00246     }
00247 
00248     scale(_h_jet_multi_exclusive, crossSection()/sumOfWeights());
00249     scale(_h_jet_multi_inclusive, crossSection()/sumOfWeights());
00250     scale(_h_jet_HT, crossSection()/sumOfWeights());
00251   }
00252 
00253 
00254 }