ATLAS_2012_I1199269.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/IdentifiedFinalState.hh" 00004 #include "Rivet/Projections/FastJets.hh" 00005 /// @todo These should be unnecessary from 2.2.0 onward when Rivet::Jet is rewritten 00006 #include "fastjet/internal/base.hh" 00007 #include "fastjet/JetDefinition.hh" 00008 #include "fastjet/AreaDefinition.hh" 00009 #include "fastjet/ClusterSequence.hh" 00010 #include "fastjet/ClusterSequenceArea.hh" 00011 #include "fastjet/PseudoJet.hh" 00012 00013 namespace Rivet { 00014 00015 00016 /// @brief Measurement of isolated diphoton + X differential cross-sections 00017 /// 00018 /// Inclusive isolated gamma gamma cross-sections, differential in M(gg), pT(gg), 00019 /// dphi(gg), cos(theta*)_CS 00020 /// 00021 /// @author Giovanni Marchiori 00022 /// 00023 class ATLAS_2012_I1199269 : public Analysis { 00024 public: 00025 00026 /// Constructor 00027 ATLAS_2012_I1199269() 00028 : Analysis("ATLAS_2012_I1199269") 00029 { 00030 _eta_bins_areaoffset += 0.0, 1.5, 3.0; 00031 } 00032 00033 00034 /// Book histograms and initialise projections before the run 00035 void init() { 00036 00037 FinalState fs; 00038 addProjection(fs, "FS"); 00039 00040 /// @todo Clean-up when jets are better 00041 FastJets fj(fs, FastJets::KT, 0.5); 00042 _area_def = new fastjet::AreaDefinition(fastjet::VoronoiAreaSpec()); 00043 fj.useJetArea(_area_def); 00044 addProjection(fj, "KtJetsD05"); 00045 00046 IdentifiedFinalState photonfs(Cuts::abseta < 2.37 && Cuts::pT > 22*GeV); 00047 photonfs.acceptId(PID::PHOTON); 00048 addProjection(photonfs, "Photon"); 00049 00050 _h_M = bookHisto1D(1, 1, 1); 00051 _h_pT = bookHisto1D(2, 1, 1); 00052 _h_dPhi = bookHisto1D(3, 1, 1); 00053 _h_cosThetaStar = bookHisto1D(4, 1, 1); 00054 } 00055 00056 00057 // int getBinIndex(double x, const vector<double>& binedges) const { 00058 // /// @todo Add linear and log bin guessing, use binary split if sufficiently large, etc. 00059 // for (size_t i = 0; i < _binedges.size()-1; ++i) 00060 // if (inRange(x, binedges[i], binedges[i+1])) return (int) i; 00061 // return -1; 00062 // } 00063 00064 00065 /// Perform the per-event analysis 00066 void analyze(const Event& event) { 00067 const double weight = event.weight(); 00068 00069 /// Require at least 2 photons in final state 00070 const Particles photons = applyProjection<IdentifiedFinalState>(event, "Photon").particlesByPt(); 00071 if (photons.size() < 2) vetoEvent; 00072 00073 /// Compute the median energy density 00074 _ptDensity.clear(); 00075 _sigma.clear(); 00076 _Njets.clear(); 00077 /// @todo Nicer way to do this... in C++11? 00078 vector<vector<double> > ptDensities; 00079 vector<double> emptyVec; 00080 ptDensities.assign(_eta_bins_areaoffset.size()-1, emptyVec); 00081 00082 // Get jets, and corresponding jet areas 00083 const fastjet::ClusterSequenceArea* clust_seq_area = applyProjection<FastJets>(event, "KtJetsD05").clusterSeqArea(); 00084 foreach (const fastjet::PseudoJet& jet, applyProjection<FastJets>(event, "KtJetsD05").pseudoJets(0.0*GeV)) { 00085 const double aeta = fabs(jet.eta()); 00086 const double pt = jet.perp(); 00087 const double area = clust_seq_area->area(jet); 00088 if (area < 1e-3) continue; 00089 const int ieta = binIndex(aeta, _eta_bins_areaoffset); 00090 if (ieta != -1) ptDensities[ieta].push_back(pt/area); 00091 } 00092 00093 // Compute median jet properties over the jets in the event 00094 for (size_t b = 0; b < _eta_bins_areaoffset.size()-1; ++b) { 00095 double median = 0.0; 00096 double sigma = 0.0; 00097 int Njets = 0; 00098 if (ptDensities[b].size() > 0) { 00099 std::sort(ptDensities[b].begin(), ptDensities[b].end()); 00100 int nDens = ptDensities[b].size(); 00101 median = (nDens % 2 == 0) ? (ptDensities[b][nDens/2]+ptDensities[b][(nDens-2)/2])/2 : ptDensities[b][(nDens-1)/2]; 00102 sigma = ptDensities[b][(int)(.15865*nDens)]; 00103 Njets = nDens; 00104 } 00105 _ptDensity.push_back(median); 00106 _sigma.push_back(sigma); 00107 _Njets.push_back(Njets); 00108 } 00109 00110 00111 // Loop over photons and fill vector of isolated ones 00112 Particles isolated_photons; 00113 foreach (const Particle& photon, photons) { 00114 /// Remove photons in ECAL crack region 00115 if (inRange(photon.abseta(), 1.37, 1.52)) continue; 00116 const double eta_P = photon.eta(); 00117 const double phi_P = photon.phi(); 00118 00119 // Compute isolation via particles within an R=0.4 cone of the photon 00120 Particles fs = applyProjection<FinalState>(event, "FS").particles(); 00121 FourMomentum mom_in_EtCone; 00122 foreach (const Particle& p, fs) { 00123 // Reject if not in cone 00124 if (deltaR(photon.momentum(), p.momentum()) > 0.4) continue; 00125 // Reject if in the 5x7 cell central core 00126 if (fabs(eta_P - p.eta()) < 0.025 * 5 * 0.5 && 00127 fabs(phi_P - p.phi()) < PI/128. * 7 * 0.5) continue; 00128 // Sum momentum 00129 mom_in_EtCone += p.momentum(); 00130 } 00131 // Now figure out the correction (area*density) 00132 const double EtCone_area = PI*sqr(0.4) - (7*.025)*(5*PI/128.); // cone area - central core rectangle 00133 const double correction = _ptDensity[binIndex(fabs(eta_P), _eta_bins_areaoffset)] * EtCone_area; 00134 00135 // Discard the photon if there is more than 4 GeV of cone activity 00136 // NOTE: Shouldn't need to subtract photon itself (it's in the central core) 00137 // NOTE: using expected cut at hadron/particle level, not at reco level 00138 if (mom_in_EtCone.Et() - correction > 4*GeV) continue; 00139 // Add isolated photon to list 00140 isolated_photons.push_back(photon); 00141 } 00142 00143 // Require at least two isolated photons and select leading pT pair 00144 if (isolated_photons.size() < 2) vetoEvent; 00145 sortByPt(isolated_photons); 00146 FourMomentum y1 = isolated_photons[0].momentum(); 00147 FourMomentum y2 = isolated_photons[1].momentum(); 00148 00149 // Leading photon should have pT > 25 GeV 00150 if (y1.pT() < 25*GeV) vetoEvent; 00151 00152 // Require the two photons to be separated by dR > 0.4 00153 if (deltaR(y1, y2) < 0.4) vetoEvent; 00154 00155 FourMomentum yy = y1 + y2; 00156 const double Myy = yy.mass(); 00157 _h_M->fill(Myy/GeV, weight); 00158 const double pTyy = yy.pT(); 00159 _h_pT->fill(pTyy/GeV, weight); 00160 const double dPhiyy = mapAngle0ToPi(y1.phi() - y2.phi()); 00161 _h_dPhi->fill(dPhiyy, weight); 00162 const double costhetayy = 2 * y1.pT() * y2.pT() * sinh(y1.eta() - y2.eta()) / Myy / add_quad(Myy, pTyy); 00163 _h_cosThetaStar->fill(costhetayy, weight); 00164 } 00165 00166 00167 /// Normalise histograms etc., after the run 00168 void finalize() { 00169 scale(_h_M, crossSection()/sumOfWeights()); 00170 scale(_h_pT, crossSection()/sumOfWeights()); 00171 scale(_h_dPhi, crossSection()/sumOfWeights()); 00172 scale(_h_cosThetaStar, crossSection()/sumOfWeights()); 00173 } 00174 00175 00176 private: 00177 00178 Histo1DPtr _h_M, _h_pT, _h_dPhi, _h_cosThetaStar; 00179 00180 fastjet::AreaDefinition* _area_def; 00181 00182 vector<double> _eta_bins; 00183 vector<double> _eta_bins_areaoffset; 00184 00185 vector<double> _ptDensity; 00186 vector<double> _sigma; 00187 vector<double> _Njets; 00188 }; 00189 00190 00191 DECLARE_RIVET_PLUGIN(ATLAS_2012_I1199269); 00192 00193 } Generated on Wed Oct 7 2015 12:09:10 for The Rivet MC analysis system by ![]() |