CDF_2008_LEADINGJETS.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/RivetAIDA.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    *
00031    */
00032   class CDF_2008_LEADINGJETS : public Analysis {
00033   public:
00034 
00035     /// Constructor
00036     CDF_2008_LEADINGJETS()
00037       : Analysis("CDF_2008_LEADINGJETS")
00038     {
00039       setBeams(PROTON, ANTIPROTON);
00040     }
00041 
00042 
00043     /// @name Analysis methods
00044     //@{
00045 
00046     void init() {
00047       // Final state for the jet finding
00048       const FinalState fsj(-4.0, 4.0, 0.0*GeV);
00049       addProjection(fsj, "FSJ");
00050       addProjection(FastJets(fsj, FastJets::CDFMIDPOINT, 0.7), "MidpointJets");
00051 
00052       // Final state for the sum(ET) distributions
00053       const FinalState fs(-1.0, 1.0, 0.0*GeV);
00054       addProjection(fs, "FS");
00055 
00056       // Charged final state for the distributions
00057       const ChargedFinalState cfs(-1.0, 1.0, 0.5*GeV);
00058       addProjection(cfs, "CFS");
00059 
00060       // Book histograms
00061       _hist_pnchg      = bookProfile1D( 1, 1, 1);
00062       _hist_pmaxnchg   = bookProfile1D( 2, 1, 1);
00063       _hist_pminnchg   = bookProfile1D( 3, 1, 1);
00064       _hist_pdifnchg   = bookProfile1D( 4, 1, 1);
00065       _hist_pcptsum    = bookProfile1D( 5, 1, 1);
00066       _hist_pmaxcptsum = bookProfile1D( 6, 1, 1);
00067       _hist_pmincptsum = bookProfile1D( 7, 1, 1);
00068       _hist_pdifcptsum = bookProfile1D( 8, 1, 1);
00069       _hist_pcptave    = bookProfile1D( 9, 1, 1);
00070       //_hist_onchg   = bookProfile1D( 1, 1, 1, "Overall number of charged particles");
00071       //_hist_ocptsum = bookProfile1D( 2, 1, 1, "Overall charged $p_\\perp$ sum");
00072       //_hist_oetsum  = bookProfile1D( 3, 1, 1, "Overall $E_\\perp$ sum");
00073     }
00074 
00075 
00076     // Do the analysis
00077     void analyze(const Event& e) {
00078       /// @todo Implement Run II min bias trigger cf. CDF_2009?
00079 
00080       const FinalState& fsj = applyProjection<FinalState>(e, "FSJ");
00081       if (fsj.particles().size() < 1) {
00082         getLog() << Log::DEBUG << "Failed multiplicity cut" << endl;
00083         vetoEvent;
00084       }
00085 
00086       const Jets& jets = applyProjection<FastJets>(e, "MidpointJets").jetsByPt();
00087       getLog() << Log::DEBUG << "Jet multiplicity = " << jets.size() << endl;
00088 
00089       // We require the leading jet to be within |eta|<2
00090       if (jets.size() < 1 || fabs(jets[0].momentum().eta()) >= 2) {
00091         getLog() << Log::DEBUG << "Failed leading jet cut" << endl;
00092         vetoEvent;
00093       }
00094 
00095       const double jetphi = jets[0].momentum().phi();
00096       const double jeteta = jets[0].momentum().eta();
00097       const double jetpT  = jets[0].momentum().pT();
00098       getLog() << Log::DEBUG << "Leading jet: pT = " << jetpT
00099                << ", eta = " << jeteta << ", phi = " << jetphi << endl;
00100 
00101       // Get the event weight
00102       const double weight = e.weight();
00103 
00104       // Get the final states to work with for filling the distributions
00105       const FinalState& cfs = applyProjection<ChargedFinalState>(e, "CFS");
00106 
00107       size_t numOverall(0),     numToward(0),     numTrans1(0),     numTrans2(0),     numAway(0)  ;
00108       double ptSumOverall(0.0), ptSumToward(0.0), ptSumTrans1(0.0), ptSumTrans2(0.0), ptSumAway(0.0);
00109       //double EtSumOverall(0.0), EtSumToward(0.0), EtSumTrans1(0.0), EtSumTrans2(0.0), EtSumAway(0.0);
00110       double ptMaxOverall(0.0), ptMaxToward(0.0), ptMaxTrans1(0.0), ptMaxTrans2(0.0), ptMaxAway(0.0);
00111 
00112       // Calculate all the charged stuff
00113       foreach (const Particle& p, cfs.particles()) {
00114         const double dPhi = deltaPhi(p.momentum().phi(), jetphi);
00115         const double pT = p.momentum().pT();
00116         const double phi = p.momentum().phi();
00117         double rotatedphi = phi - jetphi;
00118         while (rotatedphi < 0) rotatedphi += 2*PI;
00119 
00120         ptSumOverall += pT;
00121         ++numOverall;
00122         if (pT > ptMaxOverall) {
00123           ptMaxOverall = pT;
00124         }
00125 
00126         if (dPhi < PI/3.0) {
00127           ptSumToward += pT;
00128           ++numToward;
00129           if (pT > ptMaxToward) ptMaxToward = pT;
00130         }
00131         else if (dPhi < 2*PI/3.0) {
00132           if (rotatedphi <= PI) {
00133             ptSumTrans1 += pT;
00134             ++numTrans1;
00135             if (pT > ptMaxTrans1) ptMaxTrans1 = pT;
00136           } else {
00137             ptSumTrans2 += pT;
00138             ++numTrans2;
00139             if (pT > ptMaxTrans2) ptMaxTrans2 = pT;
00140           }
00141         }
00142         else {
00143           ptSumAway += pT;
00144           ++numAway;
00145           if (pT > ptMaxAway) ptMaxAway = pT;
00146         }
00147       } // end charged particle loop
00148 
00149 
00150       #if 0
00151       /// @todo Enable this part when we have the numbers from Rick Field
00152 
00153       // And now the same business for all particles (including neutrals)
00154       foreach (const Particle& p, fs.particles()) {
00155         const double dPhi = deltaPhi(p.momentum().phi(), jetphi);
00156         const double ET = p.momentum().Et();
00157         const double phi = p.momentum().phi();
00158         double rotatedphi = phi - jetphi;
00159         while (rotatedphi < 0) rotatedphi += 2*PI;
00160 
00161         EtSumOverall += ET;
00162 
00163         if (dPhi < PI/3.0) {
00164           EtSumToward += ET;
00165         }
00166         else if (dPhi < 2*PI/3.0) {
00167           if (rotatedphi <= PI) {
00168             EtSumTrans1 += ET;
00169           }
00170           else {
00171             EtSumTrans2 += ET;
00172           }
00173         }
00174         else {
00175           EtSumAway += ET;
00176         }
00177       } // end all particle loop
00178       #endif
00179 
00180 
00181       // Fill the histograms
00182       //_hist_tnchg->fill(jetpT/GeV, numToward/(4*PI/3), weight);
00183       _hist_pnchg->fill(jetpT/GeV, (numTrans1+numTrans2)/(4*PI/3), weight);
00184       _hist_pmaxnchg->fill(jetpT/GeV, (numTrans1>numTrans2 ? numTrans1 : numTrans2)/(2*PI/3), weight);
00185       _hist_pminnchg->fill(jetpT/GeV, (numTrans1<numTrans2 ? numTrans1 : numTrans2)/(2*PI/3), weight);
00186       _hist_pdifnchg->fill(jetpT/GeV, abs(numTrans1-numTrans2)/(2*PI/3), weight);
00187       //_hist_anchg->fill(jetpT/GeV, numAway/(4*PI/3), weight);
00188 
00189       //_hist_tcptsum->fill(jetpT/GeV, ptSumToward/GeV/(4*PI/3), weight);
00190       _hist_pcptsum->fill(jetpT/GeV, (ptSumTrans1+ptSumTrans2)/GeV/(4*PI/3), weight);
00191       _hist_pmaxcptsum->fill(jetpT/GeV, (ptSumTrans1>ptSumTrans2 ? ptSumTrans1 : ptSumTrans2)/GeV/(2*PI/3), weight);
00192       _hist_pmincptsum->fill(jetpT/GeV, (ptSumTrans1<ptSumTrans2 ? ptSumTrans1 : ptSumTrans2)/GeV/(2*PI/3), weight);
00193       _hist_pdifcptsum->fill(jetpT/GeV, fabs(ptSumTrans1-ptSumTrans2)/GeV/(2*PI/3), weight);
00194       //_hist_acptsum->fill(jetpT/GeV, ptSumAway/GeV/(4*PI/3), weight);
00195 
00196       //if (numToward > 0) {
00197       //  _hist_tcptave->fill(jetpT/GeV, ptSumToward/GeV/numToward, weight);
00198       //  _hist_tcptmax->fill(jetpT/GeV, ptMaxToward/GeV, weight);
00199       //}
00200       if ((numTrans1+numTrans2) > 0) {
00201         _hist_pcptave->fill(jetpT/GeV, (ptSumTrans1+ptSumTrans2)/GeV/(numTrans1+numTrans2), weight);
00202         //_hist_pcptmax->fill(jetpT/GeV, (ptMaxTrans1 > ptMaxTrans2 ? ptMaxTrans1 : ptMaxTrans2)/GeV, weight);
00203       }
00204       //if (numAway > 0) {
00205       //  _hist_acptave->fill(jetpT/GeV, ptSumAway/GeV/numAway, weight);
00206       //  _hist_acptmax->fill(jetpT/GeV, ptMaxAway/GeV, weight);
00207       //}
00208     }
00209 
00210 
00211     void finalize() {
00212       //
00213     }
00214 
00215     //@}
00216 
00217 
00218   private:
00219 
00220     AIDA::IProfile1D *_hist_pnchg;
00221     AIDA::IProfile1D *_hist_pmaxnchg;
00222     AIDA::IProfile1D *_hist_pminnchg;
00223     AIDA::IProfile1D *_hist_pdifnchg;
00224     AIDA::IProfile1D *_hist_pcptsum;
00225     AIDA::IProfile1D *_hist_pmaxcptsum;
00226     AIDA::IProfile1D *_hist_pmincptsum;
00227     AIDA::IProfile1D *_hist_pdifcptsum;
00228     AIDA::IProfile1D *_hist_pcptave;
00229 
00230   };
00231 
00232 
00233 
00234   // This global object acts as a hook for the plugin system
00235   AnalysisBuilder<CDF_2008_LEADINGJETS> plugin_CDF_2008_LEADINGJETS;
00236 
00237 }