ATLAS_2010_CONF_2010_081.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/RivetAIDA.hh"
00004 #include "Rivet/Projections/ChargedFinalState.hh"
00005 #include "Rivet/Tools/Logging.hh"
00006 #include "LWH/Profile1D.h"
00007 #include "LWH/Histogram1D.h"
00008 
00009 namespace Rivet {
00010 
00011   class ATLAS_2010_CONF_2010_081 : public Analysis {
00012   public:
00013 
00014     ATLAS_2010_CONF_2010_081() : Analysis("ATLAS_2010_CONF_2010_081") {
00015       setNeedsCrossSection(false);
00016     }
00017 
00018 
00019     void init() {
00020       ChargedFinalState cfs(-2.5, 2.5, 0.5*GeV);
00021       addProjection(cfs, "CFS");
00022 
00023       // We need at least one track with pT > 1GeV
00024       ChargedFinalState cfslead(-2.5, 2.5, 1.0*GeV);
00025       addProjection(cfslead, "CFSlead");
00026 
00027       int offset;
00028       if (sqrtS()/GeV >= 890 && sqrtS()/GeV <= 910)
00029         offset=0;
00030       else if (sqrtS()/GeV >= 6990 && sqrtS()/GeV <= 7010)
00031         offset=10;
00032       else
00033         return;
00034 
00035       _h_nch_toward    = bookProfile1D(offset+1, 1, 1);
00036       _h_nch_trans     = bookProfile1D(offset+1, 2, 1);
00037       _h_nch_away      = bookProfile1D(offset+1, 3, 1);
00038       _h_sumpt_toward  = bookProfile1D(offset+2, 1, 1);
00039       _h_sumpt_trans   = bookProfile1D(offset+2, 2, 1);
00040       _h_sumpt_away    = bookProfile1D(offset+2, 3, 1);
00041       _h_avgpt_toward  = bookProfile1D(offset+3, 1, 1);
00042       _h_avgpt_trans   = bookProfile1D(offset+3, 2, 1);
00043       _h_avgpt_away    = bookProfile1D(offset+3, 3, 1);
00044       _h_ptnch_toward  = bookProfile1D(offset+4, 1, 1);
00045       _h_ptnch_trans   = bookProfile1D(offset+4, 2, 1);
00046       _h_ptnch_away    = bookProfile1D(offset+4, 3, 1);
00047       for (size_t i=0; i<4; i++) {
00048         _h_n_vs_dphi[i]  = bookProfile1D(offset+5, 1, i+1);
00049         _h_pt_vs_dphi[i] = bookProfile1D(offset+6, 1, i+1);
00050       }
00051     }
00052 
00053 
00054     void analyze(const Event& event) {
00055       const double weight = event.weight();
00056 
00057       // Require at least one track in the event with pT >= 1 GeV
00058       const ChargedFinalState& cfslead = applyProjection<ChargedFinalState>(event, "CFSlead");
00059       if (cfslead.size() < 1) {
00060         vetoEvent;
00061       }
00062 
00063       // These are the charged particles (tracks) with pT > 500 MeV
00064       const ChargedFinalState& charged = applyProjection<ChargedFinalState>(event, "CFS");
00065 
00066       // Identify leading track and its phi and pT
00067       ParticleVector particles = charged.particlesByPt();
00068       Particle p_lead = particles[0];
00069       const double philead = p_lead.momentum().phi();
00070       const double pTlead  = p_lead.momentum().perp();
00071 
00072       size_t numToward(0),     numTrans(0),     numAway(0);
00073       double ptSumToward(0.0), ptSumTrans(0.0), ptSumAway(0.0);
00074 
00075       // Loop over particles
00076       foreach (const Particle& p, particles) {
00077         const double dPhi = deltaPhi(philead, p.momentum().phi());
00078         const double pT = p.momentum().pT();
00079         if (dPhi < PI/3.0) {
00080           ptSumToward += pT;
00081           ++numToward;
00082         }
00083         else if (dPhi < 2*PI/3.0) {
00084           ptSumTrans += pT;
00085           ++numTrans;
00086         }
00087         else {
00088           ptSumAway += pT;
00089           ++numAway;
00090         }
00091       }
00092 
00093       // Temporary histos that bin N_ch in dPhi
00094       std::vector<LWH::Histogram1D> h_n_dphi;
00095       std::vector<LWH::Histogram1D> h_pt_dphi;
00096       for (size_t i=0; i<4; i++) {
00097         h_n_dphi.push_back(LWH::Histogram1D(binEdges(5, 1, i+1)));
00098         h_pt_dphi.push_back(LWH::Histogram1D(binEdges(6, 1, i+1)));
00099       }
00100 
00101       // Iterate over charged particles again - this is neccessary since the <pT> vs Nch
00102       // histos don't fill the Nch of the whole event as it was in the CDF analyses but
00103       // the number of charged particles in the transverse, toward and away region, respectively.
00104       // And these numbers are calculated in the for loop above
00105       double ptmin[4];
00106       if (sqrtS()/GeV >= 890 && sqrtS()/GeV <= 910) {
00107         ptmin[0] = 1.0;
00108         ptmin[1] = 1.5;
00109         ptmin[2] = 2.0;
00110         ptmin[3] = 2.5;
00111       }
00112       else {
00113         ptmin[0] = 1.0;
00114         ptmin[1] = 2.0;
00115         ptmin[2] = 3.0;
00116         ptmin[3] = 5.0;
00117       }
00118 
00119       for (ParticleVector::const_iterator p = particles.begin(); p != particles.end(); ++p) {
00120         const double dPhi = deltaPhi(philead, p->momentum().phi());
00121         const double pT = p->momentum().pT();
00122         if (dPhi < PI/3.0) {
00123           _h_ptnch_toward->fill(numToward, pT/GeV, weight);
00124         }
00125         else if (dPhi < 2*PI/3.0) {
00126           _h_ptnch_trans->fill(numTrans, pT/GeV, weight);
00127         }
00128         else {
00129           _h_ptnch_away->fill(numAway, pT/GeV, weight);
00130         }
00131 
00132         // Fill temp histos to bin N_ch in dPhi
00133         if (p != particles.begin()) { // We don't want to fill all those zeros from the leading track
00134           for (size_t i=0; i<4; i++) {
00135             if (pTlead/GeV >= 1.0) {
00136               h_n_dphi[i].fill( dPhi, 1);
00137               h_n_dphi[i].fill(-dPhi, 1);
00138               h_pt_dphi[i].fill( dPhi, pT/GeV);
00139               h_pt_dphi[i].fill(-dPhi, pT/GeV);
00140             }
00141           }
00142         }
00143       }
00144 
00145       const double avgpt_toward = numToward>0?ptSumToward/numToward:0;
00146       const double avgpt_trans  = numTrans>0?ptSumTrans/numTrans:0;
00147       const double avgpt_away   = numAway>0?ptSumAway/numAway:0;
00148       _h_nch_toward   ->fill(pTlead/GeV, numToward/(2*2.5 * 2*PI/3.0),    weight);
00149       _h_nch_trans    ->fill(pTlead/GeV, numTrans/(2*2.5 * 2*PI/3.0),     weight);
00150       _h_nch_away     ->fill(pTlead/GeV, numAway/(2*2.5 * 2*PI/3.0),      weight);
00151       _h_sumpt_toward ->fill(pTlead/GeV, ptSumToward/(2*2.5 * 2*PI/3.0),  weight);
00152       _h_sumpt_trans  ->fill(pTlead/GeV, ptSumTrans/(2*2.5 * 2*PI/3.0),   weight);
00153       _h_sumpt_away   ->fill(pTlead/GeV, ptSumAway/(2*2.5 * 2*PI/3.0),    weight);
00154       _h_avgpt_toward ->fill(pTlead/GeV, avgpt_toward, weight);
00155       if (numTrans>0) _h_avgpt_trans  ->fill(pTlead/GeV, avgpt_trans,  weight);
00156       if (numAway>0)  _h_avgpt_away   ->fill(pTlead/GeV, avgpt_away,   weight);
00157       _h_ptnch_toward ->fill(numToward,  avgpt_toward, weight);
00158       _h_ptnch_trans  ->fill(numTrans,   avgpt_trans,  weight);
00159       _h_ptnch_away   ->fill(numAway,    avgpt_away,   weight);
00160 
00161       for (size_t i=0; i<4; i++) {
00162         if (pTlead/GeV >= ptmin[i]) { // @todo: Do we need particles.size()>=2?
00163           const size_t nbins = _h_n_vs_dphi[i]->axis().bins();
00164           // deta*dphi, the range is not full 2*PI, thus the "+2". Extra factor of 2 because plot is symmetrised.
00165           const double scale = 2 * 2*2.5 * 2*PI/(nbins+2);
00166           for (size_t n=0; n<nbins; n++) {
00167             _h_n_vs_dphi[i]->fill(h_n_dphi[i].binMean(n), h_n_dphi[i].binHeight(n)/scale, weight);
00168             _h_pt_vs_dphi[i]->fill(h_pt_dphi[i].binMean(n), h_pt_dphi[i].binHeight(n)/scale, weight);
00169           }
00170         }
00171       }
00172     }
00173 
00174     void finalize() {
00175     }
00176 
00177 
00178   private:
00179 
00180     AIDA::IProfile1D* _h_nch_toward;
00181     AIDA::IProfile1D* _h_nch_trans;
00182     AIDA::IProfile1D* _h_nch_away;
00183     AIDA::IProfile1D* _h_sumpt_toward;
00184     AIDA::IProfile1D* _h_sumpt_trans;
00185     AIDA::IProfile1D* _h_sumpt_away;
00186     AIDA::IProfile1D* _h_avgpt_toward;
00187     AIDA::IProfile1D* _h_avgpt_trans;
00188     AIDA::IProfile1D* _h_avgpt_away;
00189     AIDA::IProfile1D* _h_ptnch_toward;
00190     AIDA::IProfile1D* _h_ptnch_trans;
00191     AIDA::IProfile1D* _h_ptnch_away;
00192     AIDA::IProfile1D* _h_n_vs_dphi[4];
00193     AIDA::IProfile1D* _h_pt_vs_dphi[4];
00194   };
00195 
00196   // This global object acts as a hook for the plugin system
00197   AnalysisBuilder<ATLAS_2010_CONF_2010_081> plugin_ATLAS_2010_CONF_2010_081;
00198 
00199 }
00200