rivet is hosted by Hepforge, IPPP Durham
ATLAS_2011_S8994773.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Projections/FinalState.hh"
00004 
00005 namespace Rivet {
00006 
00007 
00008   /// @author Jinlong Zhang
00009   class ATLAS_2011_S8994773 : public Analysis {
00010   public:
00011 
00012     ATLAS_2011_S8994773()
00013       : Analysis("ATLAS_2011_S8994773") {    }
00014 
00015 
00016     void init() {
00017       const FinalState fs500(-2.5, 2.5, 500*MeV);
00018       addProjection(fs500, "FS500");
00019       const FinalState fslead(-2.5, 2.5, 1.0*GeV);
00020       addProjection(fslead, "FSlead");
00021 
00022       // Get an index for the beam energy
00023       isqrts = -1;
00024       if (fuzzyEquals(sqrtS(), 900*GeV)) isqrts = 0;
00025       else if (fuzzyEquals(sqrtS(), 7*TeV)) isqrts = 1;
00026       assert(isqrts >= 0);
00027 
00028       // N profiles, 500 MeV pT cut
00029       _hist_N_transverse_500 = bookProfile1D(1+isqrts, 1, 1);
00030       // pTsum profiles, 500 MeV pT cut
00031       _hist_ptsum_transverse_500 = bookProfile1D(3+isqrts, 1, 1);
00032       // N vs. Delta(phi) profiles, 500 MeV pT cut
00033       _hist_N_vs_dPhi_1_500 = bookProfile1D(13+isqrts, 1, 1);
00034       _hist_N_vs_dPhi_2_500 = bookProfile1D(13+isqrts, 1, 2);
00035       _hist_N_vs_dPhi_3_500 = bookProfile1D(13+isqrts, 1, 3);
00036     }
00037 
00038 
00039     void analyze(const Event& event) {
00040       const double weight = event.weight();
00041 
00042       // Require at least one cluster in the event with pT >= 1 GeV
00043       const FinalState& fslead = applyProjection<FinalState>(event, "FSlead");
00044       if (fslead.size() < 1) {
00045         vetoEvent;
00046       }
00047 
00048       // These are the particles  with pT > 500 MeV
00049       const FinalState& chargedNeutral500 = applyProjection<FinalState>(event, "FS500");
00050 
00051       // Identify leading object and its phi and pT
00052       Particles particles500 = chargedNeutral500.particlesByPt();
00053       Particle p_lead = particles500[0];
00054       const double philead = p_lead.momentum().phi();
00055       const double etalead = p_lead.eta();
00056       const double pTlead  = p_lead.pT();
00057       MSG_DEBUG("Leading object: pT = " << pTlead << ", eta = " << etalead << ", phi = " << philead);
00058 
00059       // Iterate over all > 500 MeV particles and count particles and scalar pTsum in the three regions
00060       vector<double> num500(3, 0), ptSum500(3, 0.0);
00061       // Temporary histos that bin N in dPhi.
00062       // NB. Only one of each needed since binnings are the same for the energies and pT cuts
00063       Histo1D hist_num_dphi_500(refData(13+isqrts,1,1));
00064       foreach (const Particle& p, particles500) {
00065         const double pT = p.pT();
00066         const double dPhi = deltaPhi(philead, p.momentum().phi());
00067         const int ir = region_index(dPhi);
00068         num500[ir] += 1;
00069         ptSum500[ir] += pT;
00070 
00071         // Fill temp histos to bin N in dPhi
00072         if (p.genParticle() != p_lead.genParticle()) { // We don't want to fill all those zeros from the leading track...
00073           hist_num_dphi_500.fill(dPhi, 1);
00074         }
00075       }
00076 
00077 
00078       // Now fill underlying event histograms
00079       // The densities are calculated by dividing the UE properties by dEta*dPhi
00080       // -- each region has a dPhi of 2*PI/3 and dEta is two times 2.5
00081       const double dEtadPhi = (2*2.5 * 2*PI/3.0);
00082       _hist_N_transverse_500->fill(pTlead/GeV,  num500[1]/dEtadPhi, weight);
00083       _hist_ptsum_transverse_500->fill(pTlead/GeV, ptSum500[1]/GeV/dEtadPhi, weight);
00084 
00085       // Update the "proper" dphi profile histograms
00086       // Note that we fill dN/dEtadPhi: dEta = 2*2.5, dPhi = 2*PI/nBins
00087       // The values tabulated in the note are for an (undefined) signed Delta(phi) rather than
00088       // |Delta(phi)| and so differ by a factor of 2: we have to actually norm for angular range = 2pi
00089       const size_t nbins = refData(13+isqrts,1,1).numPoints();
00090       for (size_t i = 0; i < nbins; ++i) {
00091         double mean = hist_num_dphi_500.bin(i).midpoint();
00092         double value = 0.;
00093         if (hist_num_dphi_500.bin(i).numEntries() > 0) {
00094           mean = hist_num_dphi_500.bin(i).xMean();
00095           value = hist_num_dphi_500.bin(i).area()/hist_num_dphi_500.bin(i).width()/10.0;
00096         }
00097         if (pTlead/GeV >= 1.0) _hist_N_vs_dPhi_1_500->fill(mean, value, weight);
00098         if (pTlead/GeV >= 2.0) _hist_N_vs_dPhi_2_500->fill(mean, value, weight);
00099         if (pTlead/GeV >= 3.0) _hist_N_vs_dPhi_3_500->fill(mean, value, weight);
00100       }
00101 
00102     }
00103 
00104 
00105     void finalize() {
00106     }
00107 
00108 
00109   private:
00110 
00111     // Little helper function to identify Delta(phi) regions
00112     inline int region_index(double dphi) {
00113       assert(inRange(dphi, 0.0, PI, CLOSED, CLOSED));
00114       if (dphi < PI/3.0) return 0;
00115       if (dphi < 2*PI/3.0) return 1;
00116       return 2;
00117     }
00118 
00119 
00120   private:
00121     int isqrts;
00122 
00123     Profile1DPtr _hist_N_transverse_500;
00124 
00125     Profile1DPtr _hist_ptsum_transverse_500;
00126 
00127     Profile1DPtr _hist_N_vs_dPhi_1_500;
00128     Profile1DPtr _hist_N_vs_dPhi_2_500;
00129     Profile1DPtr _hist_N_vs_dPhi_3_500;
00130 
00131   };
00132 
00133 
00134 
00135   // The hook for the plugin system
00136   DECLARE_RIVET_PLUGIN(ATLAS_2011_S8994773);
00137 
00138 }