Rivet analyses referenceATLAS_2011_I944826$K_S^0$ and $\Lambda$ production at 0.9 and 7 TeV with ATLASExperiment: ATLAS (LHC) Inspire ID: 944826 Status: VALIDATED Authors:
Beam energies: (450.0, 450.0); (3500.0, 3500.0) GeV Run details:
The production of $K_S$ and $\Lambda$ hadrons is studied in inelastic $pp$ collisions at $\sqrt{s} = 0.9$ and 7 TeV collected with the ATLAS detector at the LHC using a minimum-bias trigger. The observed distributions of transverse momentum, rapidity, and multiplicity are corrected to hadron level in a model-independent way within well defined phase-space regions. The distribution of the production ratio of $\bar{\Lambda}$ to $\Lambda$ baryons is also measured. The results are compared with various Monte Carlo simulation models. Although most of these models agree with data to within 15 percent in the $K_S$ distributions, substantial disagreements with data are found in the $\Lambda$ distributions of transverse momentum. Beam energy must be specified (in GeV) as analysis option "ENERGY" when rivet-merging samples. Source code: ATLAS_2011_I944826.cc 1// -*- C++ -*-
2#include "Rivet/Analysis.hh"
3#include "Rivet/Projections/ChargedFinalState.hh"
4#include "Rivet/Projections/IdentifiedFinalState.hh"
5#include "Rivet/Projections/UnstableParticles.hh"
6
7namespace Rivet {
8
9
10 class ATLAS_2011_I944826 : public Analysis {
11 public:
12
13 /// Constructor
14 ATLAS_2011_I944826()
15 : Analysis("ATLAS_2011_I944826")
16 {}
17
18
19 /// Book histograms and initialise projections before the run
20 void init() {
21
22 book(_sum_w_ks , "ks");
23 book(_sum_w_lambda, "lambda");
24 book(_sum_w_passed, "passed");
25
26 UnstableParticles ufs(Cuts::pT > 100*MeV);
27 declare(ufs, "UFS");
28
29 ChargedFinalState mbts(Cuts::absetaIn(2.09, 3.84));
30 declare(mbts, "MBTS");
31
32 IdentifiedFinalState nstable(Cuts::abseta < 2.5 && Cuts::pT >= 100*MeV);
33 nstable.acceptIdPair(PID::ELECTRON)
34 .acceptIdPair(PID::MUON)
35 .acceptIdPair(PID::PIPLUS)
36 .acceptIdPair(PID::KPLUS)
37 .acceptIdPair(PID::PROTON);
38 declare(nstable, "nstable");
39
40
41 if (isCompatibleWithSqrtS(7000)) {
42 book(_hist_Ks_pT ,1, 1, 1);
43 book(_hist_Ks_y ,2, 1, 1);
44 book(_hist_Ks_mult ,3, 1, 1);
45 book(_hist_L_pT ,7, 1, 1);
46 book(_hist_L_y ,8, 1, 1);
47 book(_hist_L_mult ,9, 1, 1);
48 book(_hist_Ratio_v_y ,13, 1, 1);
49 book(_hist_Ratio_v_pT,14, 1, 1);
50 //
51 book(_temp_lambda_v_y, "TMP/lambda_v_y", 10, 0.0, 2.5);
52 book(_temp_lambdabar_v_y, "TMP/lambdabar_v_y", 10, 0.0, 2.5);
53 book(_temp_lambda_v_pT, "TMP/lambda_v_pT", 18, 0.5, 4.1);
54 book(_temp_lambdabar_v_pT, "TMP/lambdabar_v_pT", 18, 0.5, 4.1);
55 }
56 else if (isCompatibleWithSqrtS(900)) {
57 book(_hist_Ks_pT ,4, 1, 1);
58 book(_hist_Ks_y ,5, 1, 1);
59 book(_hist_Ks_mult ,6, 1, 1);
60 book(_hist_L_pT ,10, 1, 1);
61 book(_hist_L_y ,11, 1, 1);
62 book(_hist_L_mult ,12, 1, 1);
63 book(_hist_Ratio_v_y ,15, 1, 1);
64 book(_hist_Ratio_v_pT,16, 1, 1);
65 //
66 book(_temp_lambda_v_y, "TMP/lambda_v_y", 5, 0.0, 2.5);
67 book(_temp_lambdabar_v_y, "TMP/lambdabar_v_y", 5, 0.0, 2.5);
68 book(_temp_lambda_v_pT, "TMP/lambda_v_pT", 8, 0.5, 3.7);
69 book(_temp_lambdabar_v_pT, "TMP/lambdabar_v_pT", 8, 0.5, 3.7);
70 }
71 }
72
73
74 // This function is required to impose the flight time cuts on Kaons and Lambdas
75 double getPerpFlightDistance(const Rivet::Particle& p) {
76 ConstGenParticlePtr genp = p.genParticle();
77 ConstGenVertexPtr prodV = genp->production_vertex();
78 ConstGenVertexPtr decV = genp->end_vertex();
79 RivetHepMC::FourVector prodPos = prodV->position();
80 if (decV) {
81 const RivetHepMC::FourVector decPos = decV->position();
82 double dy = prodPos.y() - decPos.y();
83 double dx = prodPos.x() - decPos.x();
84 return add_quad(dx, dy);
85 }
86 return numeric_limits<double>::max();
87 }
88
89
90 bool daughtersSurviveCuts(const Rivet::Particle& p) {
91 // We require the Kshort or Lambda to decay into two charged
92 // particles with at least pT = 100 MeV inside acceptance region
93 ConstGenParticlePtr genp = p.genParticle();
94 ConstGenVertexPtr decV = genp->end_vertex();
95 bool decision = true;
96
97 if (!decV) return false;
98 if (HepMCUtils::particles(decV, Relatives::CHILDREN).size() == 2) {
99 std::vector<double> pTs;
100 std::vector<int> charges;
101 std::vector<double> etas;
102 for(ConstGenParticlePtr gp: HepMCUtils::particles(decV, Relatives::CHILDREN)) {
103 pTs.push_back(gp->momentum().perp());
104 etas.push_back(fabs(gp->momentum().eta()));
105 charges.push_back( Rivet::PID::charge3(gp->pdg_id()) );
106 // gp->print();
107 }
108 if ( (pTs[0]/Rivet::GeV < 0.1) || (pTs[1]/Rivet::GeV < 0.1) ) {
109 decision = false;
110 MSG_DEBUG("Failed pT cut: " << pTs[0]/Rivet::GeV << " " << pTs[1]/Rivet::GeV);
111 }
112 if ( etas[0] > 2.5 || etas[1] > 2.5 ) {
113 decision = false;
114 MSG_DEBUG("Failed eta cut: " << etas[0] << " " << etas[1]);
115 }
116 if ( charges[0] * charges[1] >= 0 ) {
117 decision = false;
118 MSG_DEBUG("Failed opposite charge cut: " << charges[0] << " " << charges[1]);
119 }
120 }
121 else {
122 decision = false;
123 MSG_DEBUG("Failed nDaughters cut: " << HepMCUtils::particles(decV, Relatives::CHILDREN).size());
124 }
125
126 return decision;
127 }
128
129 /// Perform the per-event analysis
130 void analyze(const Event& event) {
131
132 // ATLAS MBTS trigger requirement of at least one hit in either hemisphere
133 if (apply<FinalState>(event, "MBTS").size() < 1) {
134 MSG_DEBUG("Failed trigger cut");
135 vetoEvent;
136 }
137
138 // Veto event also when we find less than 2 particles in the acceptance region of type 211,2212,11,13,321
139 if (apply<FinalState>(event, "nstable").size() < 2) {
140 MSG_DEBUG("Failed stable particle cut");
141 vetoEvent;
142 }
143 _sum_w_passed->fill();
144
145 // This ufs holds all the Kaons and Lambdas
146 const UnstableParticles& ufs = apply<UnstableParticles>(event, "UFS");
147
148 // Some conters
149 int n_KS0 = 0;
150 int n_LAMBDA = 0;
151
152 // Particle loop
153 for (const Particle& p : ufs.particles()) {
154
155 // General particle quantities
156 const double pT = p.pT();
157 const double y = p.rapidity();
158 const PdgId apid = p.abspid();
159
160 double flightd = 0.0;
161
162 // Look for Kaons, Lambdas
163 switch (apid) {
164
165 case PID::K0S:
166 flightd = getPerpFlightDistance(p);
167 if (!inRange(flightd/mm, 4., 450.) ) {
168 MSG_DEBUG("Kaon failed flight distance cut:" << flightd);
169 break;
170 }
171 if (daughtersSurviveCuts(p) ) {
172 _hist_Ks_y ->fill(y);
173 _hist_Ks_pT->fill(pT/GeV);
174 _sum_w_ks->fill();
175 n_KS0++;
176 }
177 break;
178
179 case PID::LAMBDA:
180 if (pT < 0.5*GeV) { // Lambdas have an additional pT cut of 500 MeV
181 MSG_DEBUG("Lambda failed pT cut:" << pT/GeV << " GeV");
182 break;
183 }
184 flightd = getPerpFlightDistance(p);
185 if (!inRange(flightd/mm, 17., 450.)) {
186 MSG_DEBUG("Lambda failed flight distance cut:" << flightd/mm << " mm");
187 break;
188 }
189 if ( daughtersSurviveCuts(p) ) {
190 if (p.pid() == PID::LAMBDA) {
191 _temp_lambda_v_y->fill(fabs(y));
192 _temp_lambda_v_pT->fill(pT/GeV);
193 _hist_L_y->fill(y);
194 _hist_L_pT->fill(pT/GeV);
195 _sum_w_lambda->fill();
196 n_LAMBDA++;
197 } else if (p.pid() == -PID::LAMBDA) {
198 _temp_lambdabar_v_y->fill(fabs(y));
199 _temp_lambdabar_v_pT->fill(pT/GeV);
200 }
201 }
202 break;
203
204 }
205 }
206
207 // Fill multiplicity histos
208 _hist_Ks_mult->fill(n_KS0);
209 _hist_L_mult->fill(n_LAMBDA);
210 }
211
212
213
214 /// Normalise histograms etc., after the run
215 void finalize() {
216 MSG_DEBUG("# Events that pass the trigger: " << dbl(*_sum_w_passed));
217 MSG_DEBUG("# Kshort events: " << dbl(*_sum_w_ks));
218 MSG_DEBUG("# Lambda events: " << dbl(*_sum_w_lambda));
219
220 /// @todo Replace with normalize()?
221 scale(_hist_Ks_pT, 1.0 / *_sum_w_ks);
222 scale(_hist_Ks_y, 1.0 / *_sum_w_ks);
223 scale(_hist_Ks_mult, 1.0 / *_sum_w_passed);
224
225 /// @todo Replace with normalize()?
226 scale(_hist_L_pT, 1.0 / *_sum_w_lambda);
227 scale(_hist_L_y, 1.0 / *_sum_w_lambda);
228 scale(_hist_L_mult, 1.0 / *_sum_w_passed);
229
230 // Division of histograms to obtain lambda_bar/lambda ratios
231 divide(_temp_lambdabar_v_y, _temp_lambda_v_y, _hist_Ratio_v_y);
232 divide(_temp_lambdabar_v_pT, _temp_lambda_v_pT, _hist_Ratio_v_pT);
233 }
234
235
236 private:
237
238 /// Counters
239 CounterPtr _sum_w_ks, _sum_w_lambda, _sum_w_passed;
240
241 /// @name Persistent histograms
242 //@{
243 Histo1DPtr _hist_Ks_pT, _hist_Ks_y, _hist_Ks_mult;
244 Histo1DPtr _hist_L_pT, _hist_L_y, _hist_L_mult;
245 Scatter2DPtr _hist_Ratio_v_pT, _hist_Ratio_v_y;
246 //@}
247
248 /// @name Temporary histograms
249 //@{
250 Histo1DPtr _temp_lambda_v_y, _temp_lambdabar_v_y;
251 Histo1DPtr _temp_lambda_v_pT, _temp_lambdabar_v_pT;
252 //@}
253
254 };
255
256
257 // The hook for the plugin system
258 RIVET_DECLARE_PLUGIN(ATLAS_2011_I944826);
259
260}
|