Rivet analyses referenceCMS_2017_I1608166Measurement of charged pion, kaon, and proton production in proton-proton collisions at 13 TeVExperiment: CMS (LHC) Inspire ID: 1608166 Status: VALIDATED Authors:
Beam energies: (6500.0, 6500.0) GeV Run details:
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}
|