rivet is hosted by Hepforge, IPPP Durham
ATLAS_2016_I1419652.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Projections/ChargedFinalState.hh"
00004 
00005 namespace Rivet {
00006 
00007 
00008   class ATLAS_2016_I1419652 : public Analysis {
00009   public:
00010 
00011     /// Particle types included
00012     enum PartTypes {
00013       k_NoStrange,
00014       k_AllCharged,
00015       kNPartTypes
00016     };
00017 
00018     /// Phase space regions
00019     enum RegionID {
00020       k_pt500_nch1_eta25,
00021       k_pt500_nch1_eta08,
00022       kNregions
00023     };
00024 
00025     /// Nch cut for each region
00026     const static int nchCut[kNregions];
00027 
00028 
00029     /// Default constructor
00030     ATLAS_2016_I1419652() : Analysis("ATLAS_2016_I1419652") {
00031       for (int iT = 0; iT < kNPartTypes; ++iT)  {
00032         for (int iR = 0; iR < kNregions; ++iR)  {
00033           _sumW[iT][iR]  = 0.;
00034         }
00035       }
00036     }
00037 
00038 
00039     /// Initialization, called once before running
00040     void init() {
00041 
00042       // Projections
00043       const ChargedFinalState cfs500_25(-2.5, 2.5, 500.0*MeV);
00044       declare(cfs500_25, "CFS500_25");
00045 
00046       const ChargedFinalState cfs500_08(-0.8, 0.8, 500.0*MeV);
00047       declare(cfs500_08, "CFS500_08");
00048 
00049       for (int iT = 0; iT < kNPartTypes; ++iT)  {
00050         for (int iR = 0; iR < kNregions; ++iR)  {
00051           _hist_nch  [iT][iR] = bookHisto1D  ( 1, iR + 1, iT + 1);
00052           _hist_pt   [iT][iR] = bookHisto1D  ( 2, iR + 1, iT + 1);
00053           _hist_eta  [iT][iR] = bookHisto1D  ( 3, iR + 1, iT + 1);
00054           _hist_ptnch[iT][iR] = bookProfile1D( 4, iR + 1, iT + 1);
00055         }
00056       }
00057     }
00058 
00059 
00060     void analyze(const Event& event) {
00061       string fsName;
00062       for (int iR = 0; iR < kNregions; ++iR)  {
00063         switch (iR) {
00064         case k_pt500_nch1_eta25:  fsName = "CFS500_25"; break;
00065         case k_pt500_nch1_eta08:  fsName = "CFS500_08"; break;
00066         }
00067 
00068         const ChargedFinalState& cfs = apply<ChargedFinalState>(event, fsName);
00069 
00070         /// What's the benefit in separating this code which is only called from one place?!
00071         fillPtEtaNch(cfs, iR, event.weight());
00072       }
00073     }
00074 
00075 
00076 
00077     void finalize() {
00078       // Standard histograms
00079       for (int iT = 0; iT < kNPartTypes; ++iT)  {
00080         for (int iR = 0; iR < kNregions; ++iR)  {
00081 
00082           double etaRangeSize = -999.0; //intentionally crazy
00083           switch (iR) {
00084             case k_pt500_nch1_eta25  : etaRangeSize = 5.0 ;  break;
00085             case k_pt500_nch1_eta08  : etaRangeSize = 1.6 ;  break;
00086             default: etaRangeSize = -999.0; break; //intentionally crazy
00087           }
00088 
00089           if (_sumW[iT][iR] > 0) {
00090             scale(_hist_nch[iT][iR], 1.0/_sumW[iT][iR]);
00091             scale(_hist_pt [iT][iR], 1.0/_sumW[iT][iR]/TWOPI/etaRangeSize);
00092             scale(_hist_eta[iT][iR], 1.0/_sumW[iT][iR]);
00093           } else {
00094             MSG_WARNING("Sum of weights is zero (!) in type/region: " << iT << " " << iR);
00095           }
00096         }
00097       }
00098     }
00099 
00100 
00101     /// Helper for collectively filling Nch, pT, eta, and pT vs. Nch histograms
00102     void fillPtEtaNch(const ChargedFinalState& cfs, int iRegion, double weight) {
00103 
00104       // Get number of particles
00105       int nch[kNPartTypes];
00106       int nch_noStrange = 0;
00107       foreach (const Particle& p, cfs.particles()) {
00108         PdgId pdg = p.abspid ();
00109         if ( pdg == 3112 || // Sigma-
00110              pdg == 3222 || // Sigma+
00111              pdg == 3312 || // Xi-
00112              pdg == 3334 )  // Omega-
00113             continue;
00114           nch_noStrange++;
00115       }
00116       nch[k_AllCharged] = cfs.size();
00117       nch[k_NoStrange ] = nch_noStrange;
00118 
00119       // Skip if event fails cut for all charged (noStrange will always be less)
00120       if (nch[k_AllCharged] < nchCut[iRegion]) return;
00121 
00122       // Fill event weight info
00123       _sumW[k_AllCharged][iRegion] += weight;
00124       if (nch[k_NoStrange ] >= nchCut[iRegion]) {
00125         _sumW[k_NoStrange][iRegion] += weight;
00126       }
00127 
00128       // Fill nch
00129       _hist_nch[k_AllCharged][iRegion]->fill(nch[k_AllCharged], weight);
00130       if (nch[k_NoStrange ] >= nchCut[iRegion]) {
00131         _hist_nch [k_NoStrange][iRegion]->fill(nch[k_NoStrange ], weight);
00132       }
00133 
00134       // Loop over particles, fill pT, eta and ptnch
00135       foreach (const Particle& p, cfs.particles())  {
00136         const double pt  = p.pT()/GeV;
00137         const double eta = p.eta();
00138         _hist_pt     [k_AllCharged][iRegion]->fill(pt , weight/pt);
00139         _hist_eta    [k_AllCharged][iRegion]->fill(eta, weight);
00140         _hist_ptnch  [k_AllCharged][iRegion]->fill(nch[k_AllCharged], pt, weight);
00141 
00142         // Make sure nch cut is passed for nonStrange particles!
00143         if (nch[k_NoStrange ] >= nchCut[iRegion])  {
00144           PdgId pdg = p.abspid ();
00145           if ( pdg == 3112 || // Sigma-
00146                pdg == 3222 || // Sigma+
00147                pdg == 3312 || // Xi-
00148                pdg == 3334 )  // Omega-
00149               continue;
00150           // Here we don't have strange particles anymore
00151           _hist_pt   [k_NoStrange][iRegion]->fill(pt , weight/pt);
00152           _hist_eta  [k_NoStrange][iRegion]->fill(eta, weight);
00153           _hist_ptnch[k_NoStrange][iRegion]->fill(nch[k_NoStrange], pt, weight);
00154         }
00155       }
00156     }
00157 
00158 
00159   private:
00160 
00161     double _sumW[kNPartTypes][kNregions];
00162 
00163     Histo1DPtr   _hist_nch  [kNPartTypes][kNregions];
00164     Histo1DPtr   _hist_pt   [kNPartTypes][kNregions];
00165     Histo1DPtr   _hist_eta  [kNPartTypes][kNregions];
00166     Profile1DPtr _hist_ptnch[kNPartTypes][kNregions];
00167 
00168   };
00169 
00170 
00171   // Constants: pT & eta regions
00172   const int ATLAS_2016_I1419652::nchCut[] = {1, 1};
00173 
00174 
00175   // The hook for the plugin system
00176   DECLARE_RIVET_PLUGIN(ATLAS_2016_I1419652);
00177 
00178 }