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