1 // main21.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2010 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
6 // This is a simple test program.
7 // It illustrates how to feed in a single particle
8 // or a toy parton-level configurations.
11 using namespace Pythia8;
13 //==========================================================================
15 // Single-particle gun. The particle must be a colour singlet.
16 // Input: flavour, energy, direction (theta, phi).
17 // If theta < 0 then random choice over solid angle.
19 void fillParticle(int id, double ee, double thetaIn, double phiIn,
20 Event& event, ParticleData& pdt, Rndm& rndm) {
22 // Reset event record to allow for new event.
25 // Select particle mass; where relevant according to Breit-Wigner.
26 double mm = pdt.mass(id);
27 double pp = sqrtpos(ee*ee - mm*mm);
29 // Angles as input or uniform in solid angle.
30 double cThe, sThe, phi;
36 cThe = 2. * rndm.flat() - 1.;
37 sThe = sqrtpos(1. - cThe * cThe);
38 phi = 2. * M_PI * rndm.flat();
41 // Store the particle in the event record.
42 event.append( id, 1, 0, 0, pp * sThe * cos(phi), pp * sThe * sin(phi),
46 //==========================================================================
48 // Simple method to do the filling of partons into the event record.
50 void fillPartons(int type, double ee, Event& event, ParticleData& pdt,
53 // Reset event record to allow for new event.
56 // Information on a q qbar system, to be hadronized.
59 double mm = pdt.m0(id);
60 double pp = sqrtpos(ee*ee - mm*mm);
61 event.append( id, 23, 101, 0, 0., 0., pp, ee, mm);
62 event.append( -id, 23, 0, 101, 0., 0., -pp, ee, mm);
64 // Information on a g g system, to be hadronized.
65 } else if (type == 2) {
66 event.append( 21, 23, 101, 102, 0., 0., ee, ee);
67 event.append( 21, 23, 102, 101, 0., 0., -ee, ee);
69 // Information on a g g g system, to be hadronized.
70 } else if (type == 3) {
71 event.append( 21, 23, 101, 102, 0., 0., ee, ee);
72 event.append( 21, 23, 102, 103, 0.8 * ee, 0., -0.6 * ee, ee);
73 event.append( 21, 23, 103, 101, -0.8 * ee, 0., -0.6 * ee, ee);
75 // Information on a q q q junction system, to be hadronized.
76 } else if (type == 4 || type == 5) {
78 // Need a colour singlet mother parton to define junction origin.
79 event.append( 1000022, -21, 0, 0, 2, 4, 0, 0,
80 0., 0., 1.01 * ee, 1.01 * ee);
82 // The three endpoint q q q; the minimal system.
83 double rt75 = sqrt(0.75);
84 event.append( 2, 23, 1, 0, 0, 0, 101, 0,
85 0., 0., 1.01 * ee, 1.01 * ee);
86 event.append( 2, 23, 1, 0, 0, 0, 102, 0,
87 rt75 * ee, 0., -0.5 * ee, ee );
88 event.append( 1, 23, 1, 0, 0, 0, 103, 0,
89 -rt75 * ee, 0., -0.5 * ee, ee );
91 // Define the qqq configuration as starting point for adding gluons.
93 int colNow[4] = {0, 101, 102, 103};
95 pQ[1] = Vec4(0., 0., 1., 0.);
96 pQ[2] = Vec4( rt75, 0., -0.5, 0.);
97 pQ[3] = Vec4(-rt75, 0., -0.5, 0.);
99 // Minimal cos(q-g opening angle), allows more or less nasty events.
100 double cosThetaMin =0.;
102 // Add a few gluons (almost) at random.
103 for (int nglu = 0; nglu < 5; ++nglu) {
104 int iq = 1 + int( 2.99999 * rndm.flat() );
105 double px, py, pz, e, prod;
107 e = ee * rndm.flat();
108 double cThe = 2. * rndm.flat() - 1.;
109 double phi = 2. * M_PI * rndm.flat();
110 px = e * sqrt(1. - cThe*cThe) * cos(phi);
111 py = e * sqrt(1. - cThe*cThe) * sin(phi);
113 prod = ( px * pQ[iq].px() + py * pQ[iq].py() + pz * pQ[iq].pz() )
115 } while (prod < cosThetaMin);
116 int colNew = 104 + nglu;
117 event.append( 21, 23, 1, 0, 0, 0, colNew, colNow[iq],
121 // Update daughter range of mother.
122 event[1].daughters(1, event.size() - 1);
126 // Information on a q q qbar qbar dijunction system, to be hadronized.
127 } else if (type >= 6) {
129 // The two fictitious beam remnant particles; needed for junctions.
130 event.append( 2212, -12, 0, 0, 3, 5, 0, 0, 0., 0., ee, ee, 0.);
131 event.append(-2212, -12, 0, 0, 6, 8, 0, 0, 0., 0., ee, ee, 0.);
133 // Opening angle between "diquark" legs.
135 double cThe = cos(theta);
136 double sThe = sin(theta);
138 // Set one colour depending on whether more gluons or not.
139 int acol = (type == 6) ? 103 : 106;
141 // The four endpoint q q qbar qbar; the minimal system.
142 // Two additional fictitious partons to make up original beams.
143 event.append( 2, 23, 1, 0, 0, 0, 101, 0,
144 ee * sThe, 0., ee * cThe, ee, 0.);
145 event.append( 1, 23, 1, 0, 0, 0, 102, 0,
146 -ee * sThe, 0., ee * cThe, ee, 0.);
147 event.append( 2, -21, 1, 0, 0, 0, 103, 0,
148 0., 0., ee , ee, 0.);
149 event.append( -2, 23, 2, 0, 0, 0, 0, 104,
150 ee * sThe, 0., -ee * cThe, ee, 0.);
151 event.append( -1, 23, 2, 0, 0, 0, 0, 105,
152 -ee * sThe, 0., -ee * cThe, ee, 0.);
153 event.append( -2, -21, 2, 0, 0, 0, 0, acol,
154 0., 0., -ee , ee, 0.);
156 // Add extra gluons on string between junctions.
158 event.append( 21, 23, 5, 8, 0, 0, 103, 106, 0., ee, 0., ee, 0.);
159 } else if (type == 8) {
160 event.append( 21, 23, 5, 8, 0, 0, 103, 108, 0., ee, 0., ee, 0.);
161 event.append( 21, 23, 5, 8, 0, 0, 108, 106, 0.,-ee, 0., ee, 0.);
162 } else if (type == 9) {
163 event.append( 21, 23, 5, 8, 0, 0, 103, 107, 0., ee, 0., ee, 0.);
164 event.append( 21, 23, 5, 8, 0, 0, 107, 108, ee, 0., 0., ee, 0.);
165 event.append( 21, 23, 5, 8, 0, 0, 108, 106, 0.,-ee, 0., ee, 0.);
166 } else if (type == 10) {
167 event.append( 21, 23, 5, 8, 0, 0, 103, 107, 0., ee, 0., ee, 0.);
168 event.append( 21, 23, 5, 8, 0, 0, 107, 108, ee, 0., 0., ee, 0.);
169 event.append( 21, 23, 5, 8, 0, 0, 108, 109, 0.,-ee, 0., ee, 0.);
170 event.append( 21, 23, 5, 8, 0, 0, 109, 106,-ee, 0., 0., ee, 0.);
173 // No more cases: done.
177 //==========================================================================
181 // Pick kind of events to generate:
182 // 0 = single-particle gun.
186 // 4 = minimal q q q junction topology.
187 // 5 = q q q junction topology with gluons on the strings.
188 // 6 = q q qbar qbar dijunction topology, no gluons.
189 // 7 - 10 : ditto, but with 1 - 4 gluons on string between junctions.
192 // Set particle species and energy for single-particle gun.
196 // Set typical energy per parton.
199 // Set number of events to generate and to list.
203 // Generator; shorthand for event and particleData.
205 Event& event = pythia.event;
206 ParticleData& pdt = pythia.particleData;
208 // Key requirement: switch off ProcessLevel, and thereby also PartonLevel.
209 pythia.readString("ProcessLevel:all = off");
211 // Optionally switch off decays.
212 //pythia.readString("HadronLevel:Decay = off");
214 // Provide printout of initial information.
215 pythia.settings.listChanged();
221 Hist epCons("deviation from energy-momentum conservation",100,0.,1e-4);
222 Hist chgCons("deviation from charge conservation",57,-9.5,9.5);
223 Hist nFinal("final particle multiplicity",100,-0.5,99.5);
224 Hist dnparticledp("dn/dp for particles",100,0.,ee);
225 Hist status85("multiplicity status code 85",50,-0.5,49.5);
226 Hist status86("multiplicity status code 86",50,-0.5,49.5);
227 Hist status83("multiplicity status code 83",50,-0.5,49.5);
228 Hist status84("multiplicity status code 84",50,-0.5,49.5);
229 Hist dndtheta("particle flow in event plane",100,-M_PI,M_PI);
230 Hist dedtheta("energy flow in event plane",100,-M_PI,M_PI);
231 Hist dpartondtheta("parton flow in event plane",100,-M_PI,M_PI);
232 Hist dndyAnti("dn/dy primaries antijunction",100, -10., 10.);
233 Hist dndyJun("dn/dy primaries junction",100, -10., 10.);
234 Hist dndySum("dn/dy all primaries",100, -10., 10.);
236 // Begin of event loop.
237 for (int iEvent = 0; iEvent < nEvent; ++iEvent) {
238 if (iEvent%(max(1,nEvent/20)) == 0) cout << " Now begin event "
241 // Set up single particle, with random direction in solid angle.
242 if (type == 0) fillParticle( idGun, eeGun, -1., 0., event, pdt, pythia.rndm);
244 // Set up parton-level configuration.
245 else fillPartons( type, ee, event, pdt, pythia.rndm);
247 // Generate events. Quit if failure.
248 if (!pythia.next()) {
249 cout << " Event generation aborted prematurely, owing to error!\n";
253 // List first few events.
254 if (iEvent < nList) {
256 // Also list junctions.
257 event.listJunctions();
260 // Initialize statistics.
261 Vec4 pSum = - event[0].p();
262 double chargeSum = 0.;
263 if (type == 0) chargeSum = -event[1].charge();
264 if (type == 4 || type == 5) chargeSum = -1;
271 // Loop over all particles.
272 for (int i = 0; i < event.size(); ++i) {
273 int status = event[i].statusAbs();
275 // Find any unrecognized particle codes.
276 int id = event[i].id();
277 if (id == 0 || !pdt.isParticle(id))
278 cout << " Error! Unknown code id = " << id << "\n";
280 // Find particles with E-p mismatch.
281 double eCalc = event[i].eCalc();
282 if (abs(eCalc/event[i].e() - 1.) > 1e-6) cout << " e mismatch, i = "
283 << i << " e_nominal = " << event[i].e() << " e-from-p = "
284 << eCalc << " m-from-e " << event[i].mCalc() << "\n";
286 // Parton flow in event plane.
287 if (status == 71 || status == 72) {
288 double thetaXZ = event[i].thetaXZ();
289 dpartondtheta.fill(thetaXZ);
292 // Origin of primary hadrons.
293 if (status == 85) ++n85;
294 if (status == 86) ++n86;
295 if (status == 83) ++n83;
296 if (status == 84) ++n84;
298 // Flow of primary hadrons in the event plane.
299 if (status > 80 && status < 90) {
300 double eAbs = event[i].e();
301 if (eAbs < 0.) {cout << " e < 0 line " << i; event.list();}
302 double thetaXZ = event[i].thetaXZ();
303 dndtheta.fill(thetaXZ);
304 dedtheta.fill(thetaXZ, eAbs);
306 // Rapidity distribution of primary hadrons.
307 double y = event[i].y();
310 int motherId = event[event[i].mother1()].id();
311 if (motherId > 0 ) dndyJun.fill(event[i].y());
312 else dndyAnti.fill(event[i].y());
316 // Study final-state particles.
317 if (event[i].isFinal()) {
318 pSum += event[i].p();
319 chargeSum += event[i].charge();
321 double pAbs = event[i].pAbs();
322 dnparticledp.fill(pAbs);
326 // Fill histograms once for each event.
327 double epDev = abs(pSum.e()) + abs(pSum.px()) + abs(pSum.py())
330 chgCons.fill(chargeSum);
336 if (epDev > 1e-3 || abs(chargeSum) > 0.1) event.list();
338 // End of event loop.
341 // Print statistics, histograms and done.
343 cout << epCons << chgCons << nFinal << dnparticledp
344 << dndtheta << dedtheta << dpartondtheta << dndySum;
345 if (type >= 4) cout << status85 << status86 << status83
347 if (type >= 6) cout << dndyJun << dndyAnti;