rivet is hosted by Hepforge, IPPP Durham
CDF_2008_LEADINGJETS.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/RivetYODA.hh"
00004 #include "Rivet/Tools/Logging.hh"
00005 #include "Rivet/Projections/FinalState.hh"
00006 #include "Rivet/Projections/ChargedFinalState.hh"
00007 #include "Rivet/Projections/FastJets.hh"
00008 
00009 namespace Rivet {
00010 
00011 
00012   /// @brief CDF Run II underlying event in leading jet events
00013   /// @author Hendrik Hoeth
00014   ///
00015   /// Rick Field's measurement of the underlying event in "leading jet" events.
00016   /// The leading jet (CDF midpoint \f$ R = 0.7 \f$) must be within \f$|\eta| < 2 \f$
00017   /// and defines the "toward" phi direction. Particles are selected in
00018   /// \f$ |\eta| < 1 \f$. For the \f$ p_\perp \f$-related observables there
00019   /// is a \f$ p_\perp > 0.5 \f$ GeV cut. For \f$ \sum E_\perp \f$ there is no
00020   /// \f$ p_\perp \f$ cut.
00021   ///
00022   /// @par Run conditions
00023   ///
00024   /// @arg \f$ \sqrt{s} = \f$ 1960 GeV
00025   /// @arg Run with generic QCD events.
00026   /// @arg Set particles with c*tau > 10 mm stable
00027   /// @arg Several \f$ p_\perp^\text{min} \f$ cutoffs are probably required to fill the profile histograms:
00028   /// @arg \f$ p_\perp^\text{min} = \f$ 0 (min bias), 10, 20, 50, 100, 150 GeV
00029   /// @arg The corresponding merging points are at \f$ p_T = \f$ 0, 30, 50, 80, 130, 180 GeV
00030   class CDF_2008_LEADINGJETS : public Analysis {
00031   public:
00032 
00033     /// Constructor
00034     CDF_2008_LEADINGJETS()
00035       : Analysis("CDF_2008_LEADINGJETS")
00036     {
00037     }
00038 
00039 
00040     /// @name Analysis methods
00041     //@{
00042 
00043     void init() {
00044       // Final state for the jet finding
00045       const FinalState fsj(-4.0, 4.0, 0.0*GeV);
00046       addProjection(fsj, "FSJ");
00047       addProjection(FastJets(fsj, FastJets::CDFMIDPOINT, 0.7), "MidpointJets");
00048 
00049       // Final state for the sum(ET) distributions
00050       const FinalState fs(-1.0, 1.0, 0.0*GeV);
00051       addProjection(fs, "FS");
00052 
00053       // Charged final state for the distributions
00054       const ChargedFinalState cfs(-1.0, 1.0, 0.5*GeV);
00055       addProjection(cfs, "CFS");
00056 
00057       // Book histograms
00058       _hist_pnchg      = bookProfile1D( 1, 1, 1);
00059       _hist_pmaxnchg   = bookProfile1D( 2, 1, 1);
00060       _hist_pminnchg   = bookProfile1D( 3, 1, 1);
00061       _hist_pdifnchg   = bookProfile1D( 4, 1, 1);
00062       _hist_pcptsum    = bookProfile1D( 5, 1, 1);
00063       _hist_pmaxcptsum = bookProfile1D( 6, 1, 1);
00064       _hist_pmincptsum = bookProfile1D( 7, 1, 1);
00065       _hist_pdifcptsum = bookProfile1D( 8, 1, 1);
00066       _hist_pcptave    = bookProfile1D( 9, 1, 1);
00067       //_hist_onchg   = bookProfile1D( 1, 1, 1, "Overall number of charged particles");
00068       //_hist_ocptsum = bookProfile1D( 2, 1, 1, "Overall charged $p_\\perp$ sum");
00069       //_hist_oetsum  = bookProfile1D( 3, 1, 1, "Overall $E_\\perp$ sum");
00070     }
00071 
00072 
00073     // Do the analysis
00074     void analyze(const Event& e) {
00075       /// @todo Implement Run II min bias trigger cf. CDF_2009?
00076 
00077       const FinalState& fsj = applyProjection<FinalState>(e, "FSJ");
00078       if (fsj.particles().size() < 1) {
00079         MSG_DEBUG("Failed multiplicity cut");
00080         vetoEvent;
00081       }
00082 
00083       const Jets& jets = applyProjection<FastJets>(e, "MidpointJets").jetsByPt();
00084       MSG_DEBUG("Jet multiplicity = " << jets.size());
00085 
00086       // We require the leading jet to be within |eta|<2
00087       if (jets.size() < 1 || fabs(jets[0].momentum().eta()) >= 2) {
00088         MSG_DEBUG("Failed leading jet cut");
00089         vetoEvent;
00090       }
00091 
00092       const double jetphi = jets[0].momentum().phi();
00093       const double jeteta = jets[0].momentum().eta();
00094       const double jetpT  = jets[0].momentum().pT();
00095       MSG_DEBUG("Leading jet: pT = " << jetpT
00096                 << ", eta = " << jeteta << ", phi = " << jetphi);
00097 
00098       // Get the event weight
00099       const double weight = e.weight();
00100 
00101       // Get the final states to work with for filling the distributions
00102       const FinalState& cfs = applyProjection<ChargedFinalState>(e, "CFS");
00103 
00104       size_t numOverall(0),     numToward(0),      numAway(0)  ;
00105       long int    numTrans1(0),     numTrans2(0);
00106       double ptSumOverall(0.0), ptSumToward(0.0), ptSumTrans1(0.0), ptSumTrans2(0.0), ptSumAway(0.0);
00107       //double EtSumOverall(0.0), EtSumToward(0.0), EtSumTrans1(0.0), EtSumTrans2(0.0), EtSumAway(0.0);
00108       double ptMaxOverall(0.0), ptMaxToward(0.0), ptMaxTrans1(0.0), ptMaxTrans2(0.0), ptMaxAway(0.0);
00109 
00110       // Calculate all the charged stuff
00111       foreach (const Particle& p, cfs.particles()) {
00112         const double dPhi = deltaPhi(p.momentum().phi(), jetphi);
00113         const double pT = p.momentum().pT();
00114         const double phi = p.momentum().phi();
00115         double rotatedphi = phi - jetphi;
00116         while (rotatedphi < 0) rotatedphi += 2*PI;
00117 
00118         ptSumOverall += pT;
00119         ++numOverall;
00120         if (pT > ptMaxOverall) {
00121           ptMaxOverall = pT;
00122         }
00123 
00124         if (dPhi < PI/3.0) {
00125           ptSumToward += pT;
00126           ++numToward;
00127           if (pT > ptMaxToward) ptMaxToward = pT;
00128         }
00129         else if (dPhi < 2*PI/3.0) {
00130           if (rotatedphi <= PI) {
00131             ptSumTrans1 += pT;
00132             ++numTrans1;
00133             if (pT > ptMaxTrans1) ptMaxTrans1 = pT;
00134           } else {
00135             ptSumTrans2 += pT;
00136             ++numTrans2;
00137             if (pT > ptMaxTrans2) ptMaxTrans2 = pT;
00138           }
00139         }
00140         else {
00141           ptSumAway += pT;
00142           ++numAway;
00143           if (pT > ptMaxAway) ptMaxAway = pT;
00144         }
00145       } // end charged particle loop
00146 
00147 
00148       #if 0
00149       /// @todo Enable this part when we have the numbers from Rick Field
00150 
00151       // And now the same business for all particles (including neutrals)
00152       foreach (const Particle& p, fs.particles()) {
00153         const double dPhi = deltaPhi(p.momentum().phi(), jetphi);
00154         const double ET = p.momentum().Et();
00155         const double phi = p.momentum().phi();
00156         double rotatedphi = phi - jetphi;
00157         while (rotatedphi < 0) rotatedphi += 2*PI;
00158 
00159         EtSumOverall += ET;
00160 
00161         if (dPhi < PI/3.0) {
00162           EtSumToward += ET;
00163         }
00164         else if (dPhi < 2*PI/3.0) {
00165           if (rotatedphi <= PI) {
00166             EtSumTrans1 += ET;
00167           }
00168           else {
00169             EtSumTrans2 += ET;
00170           }
00171         }
00172         else {
00173           EtSumAway += ET;
00174         }
00175       } // end all particle loop
00176       #endif
00177 
00178 
00179       // Fill the histograms
00180       //_hist_tnchg->fill(jetpT/GeV, numToward/(4*PI/3), weight);
00181       _hist_pnchg->fill(jetpT/GeV, (numTrans1+numTrans2)/(4*PI/3), weight);
00182       _hist_pmaxnchg->fill(jetpT/GeV, (numTrans1>numTrans2 ? numTrans1 : numTrans2)/(2*PI/3), weight);
00183       _hist_pminnchg->fill(jetpT/GeV, (numTrans1<numTrans2 ? numTrans1 : numTrans2)/(2*PI/3), weight);
00184       _hist_pdifnchg->fill(jetpT/GeV, abs(numTrans1-numTrans2)/(2*PI/3), weight);
00185       //_hist_anchg->fill(jetpT/GeV, numAway/(4*PI/3), weight);
00186 
00187       //_hist_tcptsum->fill(jetpT/GeV, ptSumToward/GeV/(4*PI/3), weight);
00188       _hist_pcptsum->fill(jetpT/GeV, (ptSumTrans1+ptSumTrans2)/GeV/(4*PI/3), weight);
00189       _hist_pmaxcptsum->fill(jetpT/GeV, (ptSumTrans1>ptSumTrans2 ? ptSumTrans1 : ptSumTrans2)/GeV/(2*PI/3), weight);
00190       _hist_pmincptsum->fill(jetpT/GeV, (ptSumTrans1<ptSumTrans2 ? ptSumTrans1 : ptSumTrans2)/GeV/(2*PI/3), weight);
00191       _hist_pdifcptsum->fill(jetpT/GeV, fabs(ptSumTrans1-ptSumTrans2)/GeV/(2*PI/3), weight);
00192       //_hist_acptsum->fill(jetpT/GeV, ptSumAway/GeV/(4*PI/3), weight);
00193 
00194       //if (numToward > 0) {
00195       //  _hist_tcptave->fill(jetpT/GeV, ptSumToward/GeV/numToward, weight);
00196       //  _hist_tcptmax->fill(jetpT/GeV, ptMaxToward/GeV, weight);
00197       //}
00198       if ((numTrans1+numTrans2) > 0) {
00199         _hist_pcptave->fill(jetpT/GeV, (ptSumTrans1+ptSumTrans2)/GeV/(numTrans1+numTrans2), weight);
00200         //_hist_pcptmax->fill(jetpT/GeV, (ptMaxTrans1 > ptMaxTrans2 ? ptMaxTrans1 : ptMaxTrans2)/GeV, weight);
00201       }
00202       //if (numAway > 0) {
00203       //  _hist_acptave->fill(jetpT/GeV, ptSumAway/GeV/numAway, weight);
00204       //  _hist_acptmax->fill(jetpT/GeV, ptMaxAway/GeV, weight);
00205       //}
00206     }
00207 
00208 
00209     void finalize() {
00210       //
00211     }
00212 
00213     //@}
00214 
00215 
00216   private:
00217 
00218     Profile1DPtr _hist_pnchg;
00219     Profile1DPtr _hist_pmaxnchg;
00220     Profile1DPtr _hist_pminnchg;
00221     Profile1DPtr _hist_pdifnchg;
00222     Profile1DPtr _hist_pcptsum;
00223     Profile1DPtr _hist_pmaxcptsum;
00224     Profile1DPtr _hist_pmincptsum;
00225     Profile1DPtr _hist_pdifcptsum;
00226     Profile1DPtr _hist_pcptave;
00227 
00228   };
00229 
00230 
00231 
00232   // The hook for the plugin system
00233   DECLARE_RIVET_PLUGIN(CDF_2008_LEADINGJETS);
00234 
00235 }