rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

CMS_2017_I1608166

Measurement of charged pion, kaon, and proton production in proton-proton collisions at 13 TeV
Experiment: CMS (LHC)
Inspire ID: 1608166
Status: VALIDATED
Authors:
  • Markus Seidel
References: Beams: p+ p+
Beam energies: (6500.0, 6500.0) GeV
Run details:
  • Minimum Bias inelastic collisions

Transverse momentum spectra of charged pions, kaons, and protons are measured in proton-proton collisions at sqrt(s)=13 TeV with the CMS detector at the LHC. The particles, identified via their energy loss in the silicon tracker, are measured in the transverse momentum range of pT = 0.1-1.7 GeV/c and rapidities |y|<1. The pT spectra and integrated yields are compared to previous results at smaller sqrt(s) and to predictions of Monte Carlo event generators. The average pT increases with particle mass and charged particle multiplicity of the event. Comparisons with previous CMS results at s=0.9, 2.76, and 7 TeV show that the average pT and the ratios of hadron yields feature very similar dependences on the particle multiplicity in the event, independently of the center-of-mass energy of the pp collision.

Source code: CMS_2017_I1608166.cc
  1// -*- C++ -*-
  2#include "Rivet/Analysis.hh"
  3#include "Rivet/Projections/ChargedFinalState.hh"
  4#include "Rivet/Tools/ParticleName.hh"
  5
  6namespace Rivet {
  7
  8
  9  /// Measurement of charged pion, kaon, and proton production in 13 TeV pp collisions
 10  class CMS_2017_I1608166 : public Analysis {
 11  public:
 12
 13    /// Constructor
 14    RIVET_DEFAULT_ANALYSIS_CTOR(CMS_2017_I1608166);
 15
 16
 17    /// @name Analysis methods
 18    /// @{
 19
 20    /// Book histograms and initialise projections before the run
 21    void init() {
 22      const ChargedFinalState cfs(Cuts::absrap < 1.);
 23      declare(cfs, "CFS");
 24      //
 25      // pt spectra
 26      book(_h[PID::PIPLUS],  "d01-x01-y01");
 27      book(_h[PID::KPLUS],   "d01-x01-y02");
 28      book(_h[PID::PROTON],  "d01-x01-y03");
 29      book(_h[PID::PIMINUS], "d02-x01-y01");
 30      book(_h[PID::KMINUS],  "d02-x01-y02");
 31      book(_h[PID::PBAR],    "d02-x01-y03");
 32
 33      // negative/positive ratios
 34      book(_s["pi-/pi+"], "d43-x01-y01");
 35      book(_s["k-/k+"],   "d44-x01-y01");
 36      book(_s["p~/p"],    "d45-x01-y01");
 37
 38      // k/pi and p/pi ratios
 39      book(_hkpi[PID::PIPLUS], "TMP/hkpi/pi", refData<YODA::BinnedEstimate<string>>(46, 1, 1));
 40      book(_hkpi[PID::KPLUS],  "TMP/hkpi/k",  refData<YODA::BinnedEstimate<string>>(46, 1, 1));
 41      book(_hppi[PID::PIPLUS], "TMP/hppi/pi", refData<YODA::BinnedEstimate<string>>(47, 1, 1));
 42      book(_hppi[PID::PROTON], "TMP/hppi/p",  refData<YODA::BinnedEstimate<string>>(47, 1, 1));
 43      book(_s["k/pi"],    "d46-x01-y01");
 44      book(_s["p/pi"],    "d47-x01-y01");
 45
 46      _axes[PID::PIPLUS] = YODA::Axis<double>(22, 0.1, 1.2);
 47      _axes[PID::KPLUS]  = YODA::Axis<double>(17, 0.2, 1.05);
 48      _axes[PID::PROTON] = YODA::Axis<double>(26, 0.4, 1.7);
 49      _axes[4] = YODA::Axis<double>(17, 0.2, 1.05);
 50      _axes[5] = YODA::Axis<double>(16, 0.4, 1.2);
 51    }
 52
 53
 54    void analyze(const Event& event) {
 55
 56      if (_edges[PID::PIPLUS].empty())  _edges[PID::PIPLUS] = _h[PID::PIPLUS]->xEdges();
 57      if (_edges[PID::KPLUS].empty())   _edges[PID::KPLUS]  = _h[PID::KPLUS]->xEdges();
 58      if (_edges[PID::PROTON].empty())  _edges[PID::PROTON] = _h[PID::PROTON]->xEdges();
 59      if (_edges[4].empty())  _edges[4] = _hkpi[PID::PIPLUS]->xEdges();
 60      if (_edges[5].empty())  _edges[5] = _hppi[PID::PIPLUS]->xEdges();
 61
 62      const ChargedFinalState& cfs = apply<ChargedFinalState>(event, "CFS");
 63      for (const Particle& p : cfs.particles()) {
 64
 65        // protections against MC generators decaying long-lived particles
 66        if (p.hasAncestorWith(Cuts::pid == 310)  || p.hasAncestorWith(Cuts::pid == -310)  ||  // K0s
 67            p.hasAncestorWith(Cuts::pid == 130)  || p.hasAncestorWith(Cuts::pid == -130)  ||  // K0l
 68            p.hasAncestorWith(Cuts::pid == 3322) || p.hasAncestorWith(Cuts::pid == -3322) ||  // Xi0
 69            p.hasAncestorWith(Cuts::pid == 3122) || p.hasAncestorWith(Cuts::pid == -3122) ||  // Lambda
 70            p.hasAncestorWith(Cuts::pid == 3222) || p.hasAncestorWith(Cuts::pid == -3222) ||  // Sigma+/-
 71            p.hasAncestorWith(Cuts::pid == 3312) || p.hasAncestorWith(Cuts::pid == -3312) ||  // Xi-/+
 72            p.hasAncestorWith(Cuts::pid == 3334) || p.hasAncestorWith(Cuts::pid == -3334))    // Omega-/+
 73          continue;
 74
 75        if (theParticles.find(p.pid()) != theParticles.end()) {
 76          // fill pt spectra
 77          _h[p.pid()]->fill(map2string(p.pt() / GeV, p.abspid()));
 78          // fill tmp histos for ratios
 79          if (p.abspid() != PID::PROTON) {
 80            _hkpi[p.abspid()]->fill(map2string(p.pt() / GeV, 4, true));
 81          }
 82          if (p.abspid() != PID::KPLUS) {
 83            _hppi[p.abspid()]->fill(map2string(p.pt() / GeV, 5, true));
 84          }
 85        }
 86      }
 87
 88    }
 89
 90    string map2string(const double value, const int type, const bool isRatio = false) const {
 91      int id = type;
 92      if (isRatio && id == 4)  id = PID::KPLUS;
 93      else if (isRatio && id == 5)  id = PID::PROTON;
 94      const size_t idx = _axes.at(id).index(value);
 95      if (idx && idx <= _edges.at(type).size()) {
 96        return _edges.at(type)[idx-1];
 97      }
 98      return "OTHER";
 99    }
100
101
102    void finalize() {
103
104      divide(_h[PID::PIMINUS], _h[PID::PIPLUS], _s["pi-/pi+"]);
105      divide(_h[PID::KMINUS],  _h[PID::KPLUS],  _s["k-/k+"]);
106      divide(_h[PID::PBAR],    _h[PID::PROTON], _s["p~/p"]);
107
108      divide(_hkpi[PID::KPLUS],  _hkpi[PID::PIPLUS], _s["k/pi"]);
109      divide(_hppi[PID::PROTON], _hppi[PID::PIPLUS], _s["p/pi"]);
110
111      scale(_h, 1./2./sumOfWeights());
112
113      for (auto& item : _h) {
114        const auto& axis = _axes.at( fabs(item.first) );
115        for (auto& b : item.second->bins()) {
116          b.scaleW( 1.0/axis.width(b.index()) );
117        }
118      }
119
120    }
121
122
123    set<int> theParticles = {PID::PIPLUS, PID::KPLUS, PID::PROTON, PID::PIMINUS, PID::KMINUS, PID::PBAR};
124
125    map<int, BinnedHistoPtr<string>> _h;
126    map<int, BinnedHistoPtr<string>> _hkpi, _hppi;
127    map<string, BinnedEstimatePtr<string>> _s;
128    map<int, YODA::Axis<double>> _axes;
129    map<int, vector<string>> _edges;
130
131  };
132
133
134  RIVET_DECLARE_PLUGIN(CMS_2017_I1608166);
135
136}