Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ElementaryParticleCollider.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// $Id$
27//
28// 20100114 M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
29// 20100316 D. Wright (restored by M. Kelsey) -- Replace original (incorrect)
30// pp, pn, nn 2-body to 2-body scattering angular distributions
31// with a new parametrization of elastic scattering data using
32// the sum of two exponentials.
33// 20100319 M. Kelsey -- Use new generateWithRandomAngles for theta,phi stuff;
34// eliminate some unnecessary std::pow()
35// 20100407 M. Kelsey -- Replace std::vector<>::resize(0) with ::clear()
36// Eliminate return-by-value std::vector<> by creating buffers
37// buffers for particles, momenta, and particle types.
38// The following functions now return void and are non-const:
39// ::generateSCMfinalState()
40// ::generateMomModules()
41// ::generateStrangeChannelPartTypes()
42// ::generateSCMpionAbsorption()
43// 20100408 M. Kelsey -- Follow changes to G4*Sampler to pass particle_kinds
44// as input buffer.
45// 20100413 M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
46// 20100428 M. Kelsey -- Use G4InuclParticleNames enum
47// 20100429 M. Kelsey -- Change "photon()" to "isPhoton()"
48// 20100507 M. Kelsey -- Rationalize multiplicity returns to be actual value
49// 20100511 M. Kelsey -- Replace G4PionSampler and G4NucleonSampler with new
50// pi-N and N-N classes, reorganize if-cascades
51// 20100511 M. Kelsey -- Eliminate three residual random-angles blocks.
52// 20100511 M. Kelsey -- Bug fix: pi-N two-body final states not correctly
53// tested for charge-exchange case.
54// 20100512 M. Kelsey -- Rationalize multiplicity returns to be actual value
55// 20100512 M. Kelsey -- Add some additional debugging messages for 2-to-2
56// 20100512 M. Kelsey -- Replace "if (is==)" cascades with switch blocks.
57// Use G4CascadeInterpolator for angular distributions.
58// 20100517 M. Kelsey -- Inherit from common base class, make arrays static
59// 20100519 M. Kelsey -- Use G4InteractionCase to compute "is" values.
60// 20100625 M. Kelsey -- Two bugs in n-body momentum, last particle recoil
61// 20100713 M. Kelsey -- Bump collide start message up to verbose > 1
62// 20100714 M. Kelsey -- Move conservation checking to base class
63// 20100714 M. Kelsey -- Add sanity check for two-body final state, to ensure
64// that final state total mass is below etot_scm; also compute
65// kinematics without "rescaling" (which led to non-conservation)
66// 20100726 M. Kelsey -- Move remaining std::vector<> buffers to .hh file
67// 20100804 M. Kelsey -- Add printing of final-state tables, protected by
68// G4CASCADE_DEBUG_SAMPLER preprocessor flag
69// 20101019 M. Kelsey -- CoVerity report: check dynamic_cast<> for null
70// 20110214 M. Kelsey -- Follow G4InuclParticle::Model enumerator migration
71// 20110718 V. Uzhinskiy -- Drop IL,IM reset for multiplicity-three collisions
72// 20110718 M. Kelsey -- Use enum names in switch blocks (c.f. G4NucleiModel)
73// 20110720 M. Kelsey -- Follow interface change for cross-section tables,
74// eliminating switch blocks.
75// 20110806 M. Kelsey -- Pre-allocate buffers to avoid memory churn
76// 20110922 M. Kelsey -- Follow G4InuclParticle::print(ostream&) migration
77// 20110926 M. Kelsey -- Protect sampleCMcosFor2to2 from unphysical arguments
78// 20111003 M. Kelsey -- Prepare for gamma-N interactions by checking for
79// final-state tables instead of particle "isPhoton()"
80// 20111007 M. Kelsey -- Add gamma-N final-state tables to printFinalState
81// 20111107 M. Kelsey -- In sampleCMmomentumFor2to2(), hide message about
82// unrecognized gamma-N initial state behind verbosity.
83// 20111216 M. Kelsey -- Add diagnostics to generateMomModulesFor2toMany(),
84// defer allocation of buffer in generateSCMfinalState() so that
85// multiplicity failures return zero output, and can be trapped.
86// 20120308 M. Kelsey -- Allow photons to interact with dibaryons (see
87// changes in G4NucleiModel).
88// 20120608 M. Kelsey -- Fix variable-name "shadowing" compiler warnings.
89
91#include "G4CascadeChannel.hh"
94#include "G4CollisionOutput.hh"
97#include "G4LorentzConvertor.hh"
99#include "Randomize.hh"
100#include <algorithm>
101#include <cfloat>
102#include <vector>
103
104using namespace G4InuclParticleNames;
105using namespace G4InuclSpecialFunctions;
106
107typedef std::vector<G4InuclElementaryParticle>::iterator particleIterator;
108
109
111 : G4CascadeColliderBase("G4ElementaryParticleCollider") {}
112
113
114void
116 G4InuclParticle* target,
117 G4CollisionOutput& output)
118{
119 if (verboseLevel > 1)
120 G4cout << " >>> G4ElementaryParticleCollider::collide" << G4endl;
121
122 if (!useEPCollider(bullet,target)) { // Sanity check
123 G4cerr << " ElementaryParticleCollider -> can collide only particle with particle "
124 << G4endl;
125 return;
126 }
127
128#ifdef G4CASCADE_DEBUG_SAMPLER
129 static G4bool doPrintTables = true; // Once and only once per job
130 if (doPrintTables) {
131 printFinalStateTables(); // For diagnostic reporting
132 doPrintTables = false;
133 }
134#endif
135
136 interCase.set(bullet, target); // To identify kind of collision
137
138 if (verboseLevel > 1) G4cout << *bullet << G4endl << *target << G4endl;
139
140 G4InuclElementaryParticle* particle1 =
141 dynamic_cast<G4InuclElementaryParticle*>(bullet);
142 G4InuclElementaryParticle* particle2 =
143 dynamic_cast<G4InuclElementaryParticle*>(target);
144
145 if (!particle1 || !particle2) { // Redundant with useEPCollider()
146 G4cerr << " ElementaryParticleCollider -> can only collide hadrons"
147 << G4endl;
148 return;
149 }
150
151 // Check for available interaction, or pion+dibaryon special case
153 !particle1->quasi_deutron() && !particle2->quasi_deutron()) {
154 G4cerr << " ElementaryParticleCollider -> cannot collide "
155 << particle1->getDefinition()->GetParticleName() << " with "
156 << particle2->getDefinition()->GetParticleName() << G4endl;
157 return;
158 }
159 // Generate nucleon or pion collision with nucleon
160 // or pion with quasi-deuteron
161
162 if (particle1->nucleon() || particle2->nucleon()) { // ok
163 G4LorentzConvertor convertToSCM;
164 if(particle2->nucleon()) {
165 convertToSCM.setBullet(particle1);
166 convertToSCM.setTarget(particle2);
167 } else {
168 convertToSCM.setBullet(particle2);
169 convertToSCM.setTarget(particle1);
170 };
171
172 convertToSCM.setVerbose(verboseLevel);
173
174 convertToSCM.toTheCenterOfMass();
175 G4double ekin = convertToSCM.getKinEnergyInTheTRS();
176 G4double etot_scm = convertToSCM.getTotalSCMEnergy();
177 G4double pscm = convertToSCM.getSCMMomentum();
178
179 generateSCMfinalState(ekin, etot_scm, pscm, particle1, particle2,
180 &convertToSCM);
181
182 if (particles.empty()) { // No final state possible, pass bullet through
183 if (verboseLevel) {
184 G4cerr << " ElementaryParticleCollider -> failed to collide "
185 << particle1->getMomModule() << " GeV/c "
186 << particle1->getDefinition()->GetParticleName() << " with "
187 << particle2->getDefinition()->GetParticleName() << G4endl;
188 }
189 } else { // convert back to Lab
190 G4LorentzVector mom; // Buffer to avoid memory churn
191 particleIterator ipart;
192 for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
193 mom = convertToSCM.backToTheLab(ipart->getMomentum());
194 ipart->setMomentum(mom);
195 };
196
197 // Check conservation in multibody final state
198 if (verboseLevel && !validateOutput(bullet, target, particles)) {
199 G4cout << " incoming particles: \n" << *particle1 << G4endl
200 << *particle2 << G4endl
201 << " outgoing particles: " << G4endl;
202 for(ipart = particles.begin(); ipart != particles.end(); ipart++)
203 G4cout << *ipart << G4endl;
204
205 G4cout << " <<< Non-conservation in G4ElementaryParticleCollider"
206 << G4endl;
207 }
208
209 std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
210 output.addOutgoingParticles(particles);
211 }
212 } else { // neither particle is nucleon: pion on quasideuteron
213 if (particle1->quasi_deutron() || particle2->quasi_deutron()) {
214 if (particle1->pion() || particle2->pion() ||
215 particle1->isPhoton() || particle2->isPhoton()) {
216 G4LorentzConvertor convertToSCM;
217 if(particle2->quasi_deutron()) { // Quasideuteron is target
218 convertToSCM.setBullet(particle1);
219 convertToSCM.setTarget(particle2);
220 } else {
221 convertToSCM.setBullet(particle2);
222 convertToSCM.setTarget(particle1);
223 };
224 convertToSCM.toTheCenterOfMass();
225 G4double etot_scm = convertToSCM.getTotalSCMEnergy();
226
227 generateSCMpionAbsorption(etot_scm, particle1, particle2);
228
229 if (particles.empty()) { // Failed to generate final state
230 if (verboseLevel) {
231 G4cerr << " ElementaryParticleCollider -> failed to collide "
232 << particle1->getMomModule() << " GeV/c "
233 << particle1->getDefinition()->GetParticleName() << " with "
234 << particle2->getDefinition()->GetParticleName() << G4endl;
235 }
236 } else { // convert back to Lab
237 G4LorentzVector mom; // Buffer to avoid memory churn
238 particleIterator ipart;
239 for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
240 mom = convertToSCM.backToTheLab(ipart->getMomentum());
241 ipart->setMomentum(mom);
242 };
243
244 validateOutput(bullet, target, particles); // Check conservation
245
246 std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
247 output.addOutgoingParticles(particles);
248 };
249 } else {
250 G4cerr << " ElementaryParticleCollider -> can only collide pions with dibaryons "
251 << G4endl;
252 };
253 } else {
254 G4cerr << " ElementaryParticleCollider -> can only collide something with nucleon or dibaryon "
255 << G4endl;
256 };
257 };
258}
259
260
261G4int
262G4ElementaryParticleCollider::generateMultiplicity(G4int is,
263 G4double ekin) const
264{
265 G4int mul = 0;
266
268
269 if (xsecTable) mul = xsecTable->getMultiplicity(ekin);
270 else {
271 G4cerr << " G4ElementaryParticleCollider: Unknown interaction channel "
272 << is << " - multiplicity not generated " << G4endl;
273 }
274
275 if(verboseLevel > 3){
276 G4cout << " G4ElementaryParticleCollider::generateMultiplicity: "
277 << " multiplicity = " << mul << G4endl;
278 }
279
280 return mul;
281}
282
283
284void
285G4ElementaryParticleCollider::generateSCMfinalState(G4double ekin,
286 G4double etot_scm,
287 G4double pscm,
288 G4InuclElementaryParticle* particle1,
289 G4InuclElementaryParticle* particle2,
290 G4LorentzConvertor* toSCM) {
291 if (verboseLevel > 3) {
292 G4cout << " >>> G4ElementaryParticleCollider::generateSCMfinalState"
293 << G4endl;
294 }
295
296 const G4double ang_cut = 0.9999;
297 const G4double difr_const = 0.3678794;
298 const G4int itry_max = 10;
300
301 G4int type1 = particle1->type();
302 G4int type2 = particle2->type();
303
304 G4int is = type1 * type2;
305
306 if(verboseLevel > 3){
307 G4cout << " is " << is << G4endl;
308 }
309
310 G4int multiplicity = 0;
311 G4bool generate = true;
312
313 while (generate) {
314 particles.clear(); // Initialize buffers for this event
315 particle_kinds.clear();
316
317 // Generate list of final-state particles
318 multiplicity = generateMultiplicity(is, ekin);
319
320 generateOutgoingPartTypes(is, multiplicity, ekin);
321 if (particle_kinds.empty()) {
322 if (verboseLevel > 3) {
323 G4cout << " generateOutgoingPartTypes failed mult " << multiplicity
324 << G4endl;
325 }
326 continue;
327 }
328
329 if (multiplicity == 2) {
330 // Identify charge or strangeness exchange (non-elastic scatter)
331 G4int finaltype = particle_kinds[0]*particle_kinds[1];
332 G4int kw = (finaltype != is) ? 2 : 1;
333
334 G4double pmod = pscm; // Elastic scattering preserves CM momentum
335
336 if (kw == 2) { // Non-elastic needs new CM momentum value
337 G4double mone = dummy.getParticleMass(particle_kinds[0]);
338 G4double mtwo = dummy.getParticleMass(particle_kinds[1]);
339
340 if (etot_scm < mone+mtwo) { // Can't produce final state
341 if (verboseLevel > 2) {
342 G4cerr << " bad final state " << particle_kinds[0]
343 << " , " << particle_kinds[1] << " etot_scm " << etot_scm
344 << " < mone+mtwo " << mone+mtwo << " , but ekin " << ekin
345 << G4endl;
346 }
347 continue;
348 }
349
350 G4double ecm_sq = etot_scm*etot_scm;
351 G4double msumsq = mone+mtwo; msumsq *= msumsq;
352 G4double mdifsq = mone-mtwo; mdifsq *= mdifsq;
353
354 G4double a = (ecm_sq - msumsq) * (ecm_sq - mdifsq);
355
356 pmod = std::sqrt(a)/(2.*etot_scm);
357 }
358
359 G4LorentzVector mom = sampleCMmomentumFor2to2(is, kw, ekin, pmod);
360
361 if (verboseLevel > 3) {
362 G4cout << " Particle kinds = " << particle_kinds[0] << " , "
363 << particle_kinds[1] << G4endl
364 << " pscm " << pscm << " pmod " << pmod << G4endl
365 << " before rotation px " << mom.x() << " py " << mom.y()
366 << " pz " << mom.z() << G4endl;
367 }
368
369 mom = toSCM->rotate(mom);
370
371 if (verboseLevel > 3){
372 G4cout << " after rotation px " << mom.x() << " py " << mom.y() <<
373 " pz " << mom.z() << G4endl;
374 }
375 G4LorentzVector mom1(-mom.vect(), mom.e());
376
377 particles.resize(multiplicity); // Preallocate buffer
378 particles[0].fill(mom, particle_kinds[0], G4InuclParticle::EPCollider);
379 particles[1].fill(mom1, particle_kinds[1], G4InuclParticle::EPCollider);
380 generate = false;
381 } else { // 2 -> many
382 G4int itry = 0;
383 G4bool bad = true;
384 G4int knd_last = particle_kinds[multiplicity - 1];
385 G4double mass_last = dummy.getParticleMass(knd_last);
386
387 if (verboseLevel > 3){
388 G4cout << " knd_last " << knd_last << " mass " << mass_last << G4endl;
389 }
390
391 while (bad && itry < itry_max) {
392 itry++;
393
394 if (verboseLevel > 3){
395 G4cout << " itry in generateSCMfinalState " << itry << G4endl;
396 }
397
398 generateMomModules(multiplicity, is, ekin, etot_scm);
399 if (G4int(modules.size()) != multiplicity) {
400 if (verboseLevel > 3) {
401 G4cerr << " generateMomModule failed at mult " << multiplicity
402 << " ekin " << ekin << " etot_scm " << etot_scm << G4endl;
403 }
404 continue;
405 }
406
407 if (multiplicity == 3) {
408 G4LorentzVector mom3 =
409 particleSCMmomentumFor2to3(is, knd_last, ekin, modules[2]);
410
411 mom3 = toSCM->rotate(mom3);
412
413 // generate the momentum of first
414 G4double ct = -0.5 * (modules[2] * modules[2] +
415 modules[0] * modules[0] -
416 modules[1] * modules[1]) /
417 modules[2] / modules[0];
418
419 if(std::fabs(ct) < ang_cut) {
420
421 if(verboseLevel > 2){
422 G4cout << " ok for mult " << multiplicity << G4endl;
423 }
424
425 G4LorentzVector mom1 = generateWithFixedTheta(ct, modules[0]);
426 mom1 = toSCM->rotate(mom3, mom1);
427
428 // Second particle recoils off 1 & 3
429 G4LorentzVector mom2(etot_scm);
430 mom2 -= mom1+mom3;
431
432 bad = false;
433 generate = false;
434
435 particles.resize(multiplicity); // Preallocate buffer
436
437 particles[0].fill(mom1, particle_kinds[0], G4InuclParticle::EPCollider);
438 particles[1].fill(mom2, particle_kinds[1], G4InuclParticle::EPCollider);
439 particles[2].fill(mom3, particle_kinds[2], G4InuclParticle::EPCollider);
440 };
441 } else { // multiplicity > 3
442 // generate first mult - 2 momentums
443 G4LorentzVector tot_mom;
444 scm_momentums.clear();
445
446 for (G4int i = 0; i < multiplicity - 2; i++) {
447 G4double p0 = particle_kinds[i] < 3 ? 0.36 : 0.25;
448 G4double alf = 1.0 / p0 / (p0 - (modules[i] + p0) *
449 std::exp(-modules[i] / p0));
450 G4double st = 2.0;
451 G4int itry1 = 0;
452
453 while (std::fabs(st) > ang_cut && itry1 < itry_max) {
454 itry1++;
455 G4double s1 = modules[i] * inuclRndm();
456 G4double s2 = alf * difr_const * p0 * inuclRndm();
457
458 if(verboseLevel > 3){
459 G4cout << " s1 * alf * std::exp(-s1 / p0) "
460 << s1 * alf * std::exp(-s1 / p0)
461 << " s2 " << s2 << G4endl;
462 }
463
464 if(s1 * alf * std::exp(-s1 / p0) > s2) st = s1 / modules[i];
465 };
466
467 if(verboseLevel > 3){
468 G4cout << " itry1 " << itry1 << " i " << i << " st " << st
469 << G4endl;
470 }
471
472 if(itry1 == itry_max) {
473 if(verboseLevel > 2){
474 G4cout << " high energy angles generation: itry1 " << itry1
475 << G4endl;
476 }
477
478 st = 0.5 * inuclRndm();
479 };
480
481 G4double ct = std::sqrt(1.0 - st * st);
482 if (inuclRndm() > 0.5) ct = -ct;
483
484 G4LorentzVector mom = generateWithFixedTheta(ct,modules[i]);
485
486 tot_mom += mom;
487
488 scm_momentums.push_back(mom);
489 };
490
491 // handle last two
492 G4double tot_mod = tot_mom.rho();
493 G4double ct = -0.5 * (tot_mod * tot_mod +
494 modules[multiplicity - 2] * modules[multiplicity - 2] -
495 modules[multiplicity - 1] * modules[multiplicity - 1]) / tot_mod /
496 modules[multiplicity - 2];
497
498 if (verboseLevel > 2){
499 G4cout << " ct last " << ct << G4endl;
500 }
501
502 if (std::fabs(ct) < ang_cut) {
503 G4int i(0);
504 for (i = 0; i < multiplicity - 2; i++)
505 scm_momentums[i] = toSCM->rotate(scm_momentums[i]);
506
507 tot_mom = toSCM->rotate(tot_mom);
508
509 G4LorentzVector mom =
510 generateWithFixedTheta(ct, modules[multiplicity - 2]);
511
512 mom = toSCM->rotate(tot_mom, mom);
513 scm_momentums.push_back(mom);
514
515 // Last particle recoils off everything else
516 G4LorentzVector mom1(etot_scm);
517 mom1 -= mom+tot_mom;
518
519 scm_momentums.push_back(mom1);
520 bad = false;
521 generate = false;
522
523 if (verboseLevel > 2){
524 G4cout << " ok for mult " << multiplicity << G4endl;
525 }
526
527 particles.resize(multiplicity); // Preallocate buffer
528 for (i = 0; i < multiplicity; i++) {
529 particles[i].fill(scm_momentums[i], particle_kinds[i],
531 }
532 } // |ct| < ang_cut
533 } // multiplicity > 3
534 } // while (bad && itry < itry_max)
535
536 if (itry == itry_max) {
537 if (verboseLevel > 2) {
538 G4cout << " cannot generate the distr. for mult " << multiplicity
539 << G4endl;
540 }
541 break;
542 }
543 } // multiplicity > 2
544 } // while (generate)
545
546 if (verboseLevel > 3) {
547 G4cout << " <<< G4ElementaryParticleCollider::generateSCMfinalState"
548 << G4endl;
549 }
550
551 return; // Particles buffer filled
552}
553
554void
555G4ElementaryParticleCollider::generateMomModules(G4int mult,
556 G4int is,
557 G4double ekin,
558 G4double etot_cm) {
559 if (verboseLevel > 3) {
560 G4cout << " >>> G4ElementaryParticleCollider::generateMomModules"
561 << G4endl;
562 }
563
564 if (verboseLevel > 2){
565 G4cout << " mult " << mult << " is " << is << " ekin " << ekin
566 << " etot_cm " << etot_cm << G4endl;
567 }
568
569 const G4int itry_max = 10;
570 const G4double small = 1.e-10;
572 G4int itry = 0;
573
574 modules.clear(); // Initialize buffer for this attempt
575 modules.resize(mult,0.);
576
577 masses2.clear();
578 masses2.resize(mult,0.); // Allows direct [i] setting
579
580 for (G4int i = 0; i < mult; i++) {
581 G4double mass = dummy.getParticleMass(particle_kinds[i]);
582 masses2[i] = mass * mass;
583 };
584
585 G4double mass_last = std::sqrt(masses2[mult - 1]);
586
587 if (verboseLevel > 3){
588 G4cout << " knd_last " << particle_kinds[mult - 1] << " mass_last "
589 << mass_last << G4endl;
590 }
591
592 while (itry < itry_max) {
593 itry++;
594 if(verboseLevel > 3){
595 G4cout << " itry in generateMomModules " << itry << G4endl;
596 }
597
598 G4int ilast = -1;
599 G4double eleft = etot_cm;
600
601 for (G4int i = 0; i < mult - 1; i++) {
602 G4double pmod =
603 getMomModuleFor2toMany(is, mult, particle_kinds[i], ekin);
604
605 if (pmod < small) break;
606 eleft -= std::sqrt(pmod * pmod + masses2[i]);
607
608 if (verboseLevel > 3){
609 G4cout << " kp " << particle_kinds[i] << " pmod " << pmod
610 << " mass2 " << masses2[i] << " eleft " << eleft
611 << "\n x1 " << eleft - mass_last << G4endl;
612 }
613
614 if (eleft <= mass_last) break;
615 ilast++;
616 modules[i] = pmod;
617 };
618
619 if (ilast == mult - 2) {
620 G4double plast = eleft * eleft - masses2[mult - 1];
621 if (verboseLevel > 2){
622 G4cout << " plast ** 2 " << plast << G4endl;
623 }
624
625 if (plast > small) {
626 plast = std::sqrt(plast);
627 modules[mult - 1] = plast;
628
629 if (mult == 3) {
630 if (satisfyTriangle(modules)) return;
631 } else return;
632 }
633 }
634 } // while (itry < itry_max)
635
636 if (verboseLevel > 2)
637 G4cerr << " Unable to generate momenta for multiplicity " << mult << G4endl;
638
639 modules.clear(); // Something went wrong, throw away partial
640 return;
641}
642
643
644G4bool
645G4ElementaryParticleCollider::satisfyTriangle(
646 const std::vector<G4double>& pmod) const
647{
648 if (verboseLevel > 3) {
649 G4cout << " >>> G4ElementaryParticleCollider::satisfyTriangle"
650 << G4endl;
651 }
652
653 G4bool good = ( (pmod.size() != 3) ||
654 !(std::fabs(pmod[1] - pmod[2]) > pmod[0] ||
655 pmod[0] > pmod[1] + pmod[2] ||
656 std::fabs(pmod[0] - pmod[2]) > pmod[1] ||
657 pmod[1] > pmod[0] + pmod[2] ||
658 std::fabs(pmod[0] - pmod[1]) > pmod[2] ||
659 pmod[2] > pmod[1] + pmod[0]));
660
661 return good;
662}
663
664
665void
666G4ElementaryParticleCollider::generateOutgoingPartTypes(G4int is, G4int mult,
667 G4double ekin)
668{
669 particle_kinds.clear(); // Initialize buffer for generation
670
672
673 if (xsecTable)
674 xsecTable->getOutgoingParticleTypes(particle_kinds, mult, ekin);
675 else {
676 G4cerr << " G4ElementaryParticleCollider: Unknown interaction channel "
677 << is << " - outgoing kinds not generated " << G4endl;
678 }
679
680 return;
681}
682
683
685G4ElementaryParticleCollider::getMomModuleFor2toMany(G4int is, G4int /*mult*/,
686 G4int knd,
687 G4double ekin) const
688{
689 if (verboseLevel > 2) {
690 G4cout << " >>> G4ElementaryParticleCollider::getMomModuleFor2toMany "
691 << " is " << is << " knd " << knd << " ekin " << ekin << G4endl;
692 }
693
694 G4double S = inuclRndm();
695 G4double PS = 0.0;
696 G4double PR = 0.0;
697 G4double PQ = 0.0;
698 G4int KM = 2;
699 G4int IL = 4;
700 G4int JK = 4;
701 G4int JM = 2;
702 G4int IM = 3;
703
704 if (is == 1 || is == 2 || is == 4) KM = 1;
705 if (knd == 1 || knd == 2) JK = 0;
706
707 if (verboseLevel > 3) {
708 G4cout << " S " << S << " KM " << KM << " IL " << IL << " JK " << JK
709 << " JM " << JM << " IM " << IM << G4endl;
710 }
711
712 for(G4int i = 0; i < 4; i++) {
713 G4double V = 0.0;
714 for(G4int k = 0; k < 4; k++) {
715 if (verboseLevel > 3) {
716 G4cout << " k " << k << " : rmn[k+JK][i+IL][KM-1] "
717 << rmn[k+JK][i+IL][KM-1] << " ekin^k " << std::pow(ekin, k)
718 << G4endl;
719 }
720
721 V += rmn[k + JK][i + IL][KM - 1] * std::pow(ekin, k);
722 }
723
724 if (verboseLevel > 3) {
725 G4cout << " i " << i << " : V " << V << " S^i " << std::pow(S, i)
726 << G4endl;
727 }
728
729 PR += V * std::pow(S, i);
730 PQ += V;
731 }
732
733 if (verboseLevel > 3) G4cout << " PR " << PR << " PQ " << PQ << G4endl;
734
735 if (knd == 1 || knd == 2) JM = 1;
736 if (verboseLevel > 3) G4cout << " JM " << JM << G4endl;
737
738 for(G4int im = 0; im < 3; im++) {
739 if (verboseLevel >3) {
740 G4cout << " im " << im << " : rmn[8+IM+im][7+JM][KM-1] "
741 << rmn[8+IM+im][7+JM][KM-1] << " ekin^im " << std::pow(ekin, im)
742 << G4endl;
743 }
744 PS += rmn[8 + IM + im][7 + JM][KM - 1] * std::pow(ekin, im);
745 }
746
747 G4double PRA = PS * std::sqrt(S) * (PR + (1 - PQ) * (S*S*S*S));
748
749 if (verboseLevel > 3)
750 G4cout << " PS " << PS << " PRA = PS*sqrt(S)*(PR+(1-PQ)*S^4) " << PRA
751 << G4endl;
752
753 return std::fabs(PRA);
754}
755
756
758G4ElementaryParticleCollider::particleSCMmomentumFor2to3(
759 G4int is,
760 G4int knd,
761 G4double ekin,
762 G4double pmod) const
763{
764 if (verboseLevel > 3) {
765 G4cout << " >>> G4ElementaryParticleCollider::particleSCMmomentumFor2to3"
766 << G4endl;
767 }
768
769 const G4int itry_max = 100;
770 G4double ct = 2.0;
771 G4int K = 3;
772 G4int J = 1;
773
774 if(is == 1 || is == 2 || is == 4) K = 1;
775
776 if(knd == 1 || knd == 2) J = 0;
777
778 G4int itry = 0;
779
780 while(std::fabs(ct) > 1.0 && itry < itry_max) {
781 itry++;
782 G4double S = inuclRndm();
783 G4double U = 0.0;
784 G4double W = 0.0;
785
786 for(G4int l = 0; l < 4; l++) {
787 G4double V = 0.0;
788
789 for(G4int im = 0; im < 4; im++) {
790 V += abn[im][l][K+J-1] * std::pow(ekin, im);
791 };
792
793 U += V;
794 W += V * std::pow(S, l);
795 };
796 ct = 2.0 * std::sqrt(S) * (W + (1.0 - U) * (S*S*S*S)) - 1.0;
797 };
798
799 if(itry == itry_max) {
800
801 if(verboseLevel > 2){
802 G4cout << " particleSCMmomentumFor2to3 -> itry = itry_max " << itry << G4endl;
803 }
804
805 ct = 2.0 * inuclRndm() - 1.0;
806 };
807
808 return generateWithFixedTheta(ct, pmod);
809}
810
811
813G4ElementaryParticleCollider::sampleCMmomentumFor2to2(G4int is, G4int kw,
814 G4double ekin,
815 G4double pscm) const
816{
817 if (verboseLevel > 3)
818 G4cout << " >>> G4ElementaryParticleCollider::sampleCMmomentumFor2to2"
819 << " is " << is << " kw " << kw << " ekin " << ekin << " pscm "
820 << pscm << G4endl;
821
822 G4double pA=0.0, pC=0.0, pCos=0.0, pFrac=0.0; // Angular parameters
823
824 // Arrays below are parameters for two-exponential sampling of angular
825 // distributions of two-body scattering in the specified channels
826
827 if (is == 1 || is == 2 || is == 4 ||
828 is == 21 || is == 23 || is == 25 || is == 27 || is ==29 || is == 31 ||
829 is == 42 || is == 46 || is == 50 || is == 54 || is ==58 || is == 62) {
830 // nucleon-nucleon or hyperon-nucleon
831 if (verboseLevel > 3) G4cout << " nucleon/hyperon elastic" << G4endl;
832
833 static const G4double nnke[9] = { 0.0, 0.44, 0.59, 0.80, 1.00, 2.24, 4.40, 6.15, 10.00};
834 static const G4double nnA[9] = { 0.0, 0.34, 2.51, 4.59, 4.2, 5.61, 6.38, 7.93, 8.7};
835 static const G4double nnC[9] = { 0.0, 0.0, 1.21, 1.54, 1.88, 1.24, 1.91, 4.04, 8.7};
836 static const G4double nnCos[9] = {-1.0, -1.0, 0.4226, 0.4226, 0.4384, 0.7193, 0.8788, 0.9164, 0.95};
837 static const G4double nnFrac[9] = {1.0, 1.0, 0.4898, 0.7243, 0.7990, 0.8892, 0.8493, 0.9583, 1.0};
838
839 static G4CascadeInterpolator<9> interp(nnke); // Only need one!
840 pA = interp.interpolate(ekin, nnA);
841 pC = interp.interpolate(ekin, nnC);
842 pCos = interp.interpolate(ekin, nnCos);
843 pFrac = interp.interpolate(ekin, nnFrac);
844
845 } else if (kw == 2 && (is == 9 || is == 18)) {
846 // gamma p -> pi+ n, gamma p -> pi0 p, gamma p -> K Y (and isospin variants)
847 // for now and due to lack of better data, use the gamma p -> pi+ n angular
848 // distribution for all of these channels
849 if (verboseLevel > 3)
850 G4cout << " gamma-nucleon inelastic with 2-body final state" << G4endl;
851
852 static const G4double gnke[10] = {0.0, 0.11, 0.22, 0.26, 0.30, 0.34, 0.42, 0.59, 0.79, 10.0};
853 static const G4double gnA[10] = {0.0, 0.0, 5.16, 5.55, 5.33, 7.40, 13.55, 13.44, 13.31, 7.3};
854 static const G4double gnC[10] = {0.0, -10.33, -5.44, -5.92, -4.27, -0.66, 1.37, 1.07, 0.52, 7.3};
855 static const G4double gnCos[10] = {1.0, 1.0, 0.906, 0.940, 0.940, 0.906, 0.906, 0.91, 0.91, 0.94};
856 static const G4double gnFrac[10] = {0.0, 0.0, 0.028, 0.012, 0.014, 0.044, 0.087, 0.122, 0.16, 1.0};
857
858 static G4CascadeInterpolator<10> interp(gnke);
859 pA = interp.interpolate(ekin, gnA);
860 pC = interp.interpolate(ekin, gnC);
861 pCos = interp.interpolate(ekin, gnCos);
862 pFrac = interp.interpolate(ekin, gnFrac);
863
864 } else if (kw == 2) {
865 // pi- p -> pi0 n, pi0 p -> pi+ n, pi- p -> K Y, pi0 p -> K Y (and isospin variants)
866 // includes charge and strangeness exchange
867 if (verboseLevel > 3)
868 G4cout << " pion-nucleon inelastic with 2-body final state " << G4endl;
869
870 static const G4double qxke[10] = {0.0, 0.062, 0.12, 0.217, 0.533, 0.873, 1.34, 2.86, 5.86, 10.0};
871 static const G4double qxA[10] = {0.0, 0.0, 2.48, 7.93, 10.0, 9.78, 5.08, 8.13, 8.13, 8.13};
872 static const G4double qxC[10] = {0.0, -39.58, -12.55, -4.38, 1.81, -1.99, -0.33, 1.2, 1.43, 8.13};
873 static const G4double qxCos[10] = {1.0, 1.0, 0.604, -0.033, 0.25, 0.55, 0.65, 0.80, 0.916, 0.916};
874 static const G4double qxFrac[10] = {0.0, 0.0, 0.1156, 0.5832, 0.8125, 0.3357, 0.3269, 0.7765, 0.8633, 1.0};
875
876 static G4CascadeInterpolator<10> interp(qxke); // Only need one!
877 pA = interp.interpolate(ekin, qxA);
878 pC = interp.interpolate(ekin, qxC);
879 pCos = interp.interpolate(ekin, qxCos);
880 pFrac = interp.interpolate(ekin, qxFrac);
881
882 } else if (is == 3 || is == 7 || is == 9 || is == 11 || is == 17 ||
883 is == 10 || is == 14 || is == 18 || is == 26 || is == 30) {
884 // pi+p, pi0p, gammap, k+p, k0bp, pi-n, pi0n, gamman, k-n, or k0n
885 if (verboseLevel > 3) G4cout << " meson-nucleon elastic (1)" << G4endl;
886
887 static const G4double hn1ke[10] = {0.0, 0.062, 0.12, 0.217, 0.533, 0.873, 1.34, 2.86, 5.86, 10.0};
888 static const G4double hn1A[10] = {0.0, 0.0, 27.58, 19.83, 6.46, 4.59, 6.47, 6.68, 6.43, 6.7};
889 static const G4double hn1C[10] = {0.0, -26.4, -30.55, -19.42, -5.05, -5.24, -1.00, 2.14, 2.9, 6.7};
890 static const G4double hn1Cos[10] = {1.0, 1.0, 0.174, -0.174, -0.7, -0.295, 0.5, 0.732, 0.837, 0.89};
891 static const G4double hn1Frac[10] = {0.0, 0.0, 0.2980, 0.7196, 0.9812, 0.8363, 0.5602, 0.9601, 0.9901, 1.0};
892
893 static G4CascadeInterpolator<10> interp(hn1ke); // Only need one!
894 pA = interp.interpolate(ekin, hn1A);
895 pC = interp.interpolate(ekin, hn1C);
896 pCos = interp.interpolate(ekin, hn1Cos);
897 pFrac = interp.interpolate(ekin, hn1Frac);
898
899 } else if (is == 5 || is == 6 || is == 13 || is == 34 || is == 22 ||
900 is == 15) {
901 // pi-p, pi+n, k-p, k0bn, k+n, or k0p
902 if (verboseLevel > 3) G4cout << " meson-nucleon elastic (2)" << G4endl;
903
904 static const G4double hn2ke[10] = {0.0, 0.062, 0.12, 0.217, 0.533, 0.873, 1.34, 2.86, 5.86, 10.0};
905 static const G4double hn2A[10] = {0.0, 27.08, 19.32, 9.92, 7.74, 9.86, 5.51, 7.25, 7.23, 7.3};
906 static const G4double hn2C[10] = {0.0, 0.0, -19.49, -15.78, -9.78, -2.74, -1.16, 2.31, 2.96, 7.3};
907 static const G4double hn2Cos[10] = {-1.0, -1.0, -0.235, -0.259, -0.276, 0.336, 0.250, 0.732, 0.875, 0.9};
908 static const G4double hn2Frac[10] = {1.0, 1.0, 0.6918, 0.6419, 0.7821, 0.6542, 0.8382, 0.9722, 0.9784, 1.0};
909
910 static G4CascadeInterpolator<10> interp(hn2ke); // Only need one!
911 pA = interp.interpolate(ekin, hn2A);
912 pC = interp.interpolate(ekin, hn2C);
913 pCos = interp.interpolate(ekin, hn2Cos);
914 pFrac = interp.interpolate(ekin, hn2Frac);
915
916 } else {
917 if (verboseLevel)
918 G4cerr << " G4ElementaryParticleCollider::sampleCMmomentumFor2to2:"
919 << " interaction is=" << is << " not recognized " << G4endl;
920 }
921
922 // Bound parameters by their physical ranges
923 pCos = std::max(-1.,std::min(pCos,1.));
924 pFrac = std::max(0.,std::min(pFrac,1.));
925
926 // Use parameters determined above to get polar angle
927 G4double ct = sampleCMcosFor2to2(pscm, pFrac, pA, pC, pCos);
928
929 return generateWithFixedTheta(ct, pscm);
930}
931
932
934G4ElementaryParticleCollider::sampleCMcosFor2to2(G4double pscm, G4double pFrac,
935 G4double pA, G4double pC,
936 G4double pCos) const
937{
938 if (verboseLevel>3) {
939 G4cout << " sampleCMcosFor2to2: pscm " << pscm << " pFrac " << pFrac
940 << " pA " << pA << " pC " << pC << " pCos " << pCos << G4endl;
941 }
942
943 G4bool smallAngle = (G4UniformRand() < pFrac); // 0 < theta < theta0
944
945 G4double term1 = 2.0 * pscm*pscm * (smallAngle ? pA : pC);
946
947 if (std::abs(term1) < 1e-7) return 1.0; // No actual scattering here!
948 if (term1 > DBL_MAX_EXP) return 1.0;
949
950 G4double term2 = std::exp(-2.0*term1);
951 G4double randScale = (std::exp(-term1*(1.0 - pCos)) - term2)/(1.0 - term2);
952
953 G4double randVal;
954 if (smallAngle) randVal = (1.0 - randScale)*G4UniformRand() + randScale;
955 else randVal = randScale*G4UniformRand();
956
957 G4double costheta = 1.0 + std::log(randVal*(1.0 - term2) + term2)/term1;
958
959 if (verboseLevel>3) {
960 G4cout << " term1 " << term1 << " term2 " << term2 << " randVal "
961 << randVal << " => costheta " << costheta << G4endl;
962 }
963
964 return costheta;
965}
966
967
968void
969G4ElementaryParticleCollider::generateSCMpionAbsorption(G4double etot_scm,
970 G4InuclElementaryParticle* particle1,
971 G4InuclElementaryParticle* particle2) {
972 if (verboseLevel > 3)
973 G4cout << " >>> G4ElementaryParticleCollider::generateSCMpionAbsorption"
974 << G4endl;
975
976 // generate nucleons momenta for pion or photon absorption
977 // the nucleon distribution assumed to be isotropic in SCM
978
979 particles.clear(); // Initialize buffers for this event
980 particles.resize(2);
981
982 particle_kinds.clear();
983
984 G4int type1 = particle1->type();
985 G4int type2 = particle2->type();
986
987 // generate kinds
988
989 if (type1 == pionPlus) {
990 if (type2 == diproton) { // pi+ + PP -> ?
991 G4cerr << " pion absorption: pi+ + PP -> ? " << G4endl;
992 return;
993 } else if (type2 == unboundPN) { // pi+ + PN -> PP
994 particle_kinds.push_back(proton);
995 particle_kinds.push_back(proton);
996 } else if (type2 == dineutron) { // pi+ + NN -> PN
997 particle_kinds.push_back(proton);
998 particle_kinds.push_back(neutron);
999 }
1000 } else if (type1 == pionMinus) {
1001 if (type2 == diproton) { // pi- + PP -> PN
1002 particle_kinds.push_back(proton);
1003 particle_kinds.push_back(neutron);
1004 } else if (type2 == unboundPN) { // pi- + PN -> NN
1005 particle_kinds.push_back(neutron);
1006 particle_kinds.push_back(neutron);
1007 } else if (type2 == dineutron) { // pi- + NN -> ?
1008 G4cerr << " pion absorption: pi- + NN -> ? " << G4endl;
1009 return;
1010 }
1011 } else if (type1 == pionZero || type1 == photon) {
1012 if (type2 == diproton) { // pi0/gamma + PP -> PP
1013 particle_kinds.push_back(proton);
1014 particle_kinds.push_back(proton);
1015 } else if (type2 == unboundPN) { // pi0/gamma + PN -> PN
1016 particle_kinds.push_back(proton);
1017 particle_kinds.push_back(neutron);
1018 } else if (type2 == dineutron) { // pi0/gamma + NN -> ?
1019 particle_kinds.push_back(neutron);
1020 particle_kinds.push_back(neutron);
1021 }
1022 }
1023
1025
1026 G4double mone = dummy.getParticleMass(particle_kinds[0]);
1027 G4double m1sq = mone*mone;
1028
1029 G4double mtwo = dummy.getParticleMass(particle_kinds[1]);
1030 G4double m2sq = mtwo*mtwo;
1031
1032 G4double a = 0.5 * (etot_scm * etot_scm - m1sq - m2sq);
1033
1034 G4double pmod = std::sqrt((a * a - m1sq * m2sq) / (m1sq + m2sq + 2.0 * a));
1035 G4LorentzVector mom1 = generateWithRandomAngles(pmod, mone);
1036 G4LorentzVector mom2;
1037 mom2.setVectM(-mom1.vect(), mtwo);
1038
1039 particles[0].fill(mom1, particle_kinds[0], G4InuclParticle::EPCollider);
1040 particles[1].fill(mom2, particle_kinds[1], G4InuclParticle::EPCollider);
1041
1042 return;
1043}
1044
1045
1046// Dump lookup tables for N-body final states
1047
1048void G4ElementaryParticleCollider::
1049printFinalStateTables(std::ostream& os) const {
1079
1080 os << " * * * PRELIMINARY -- GAMMA-NUCLEON TABLES * * *" << G4endl;
1083}
1084
1085
1086// Parameter array for momentum calculation of many body final states
1087const G4double G4ElementaryParticleCollider::rmn[14][10][2] = {
1088 {{0.5028, 0.6305}, {3.1442, -3.7333}, {-7.8172, 13.464}, {8.1667, -18.594},
1089 {1.6208, 1.9439}, {-4.3139, -4.6268}, {12.291, 9.7879}, {-15.288, -9.6074},
1090 { 0.0, 0.0}, { 0.0, 0.0}},
1091
1092 {{0.9348, 2.1801}, {-10.59, 1.5163}, { 29.227, -16.38}, {-34.55, 27.944},
1093 {-0.2009, -0.3464}, {1.3641, 1.1093}, {-3.403, -1.9313}, { 3.8559, 1.7064},
1094 { 0.0, 0.0}, { 0.0, 0.0}},
1095
1096 {{-0.0967, -1.2886}, {4.7335, -2.457}, {-14.298, 15.129}, {17.685, -23.295},
1097 { 0.0126, 0.0271}, {-0.0835, -0.1164}, { 0.186, 0.2697}, {-0.2004, -0.3185},
1098 { 0.0, 0.0}, { 0.0, 0.0}},
1099
1100 {{-0.025, 0.2091}, {-0.6248, 0.5228}, { 2.0282, -2.8687}, {-2.5895, 4.2688},
1101 {-0.0002, -0.0007}, {0.0014, 0.0051}, {-0.0024, -0.015}, { 0.0022, 0.0196},
1102 { 0.0, 0.0}, { 0.0, 0.0}},
1103
1104 {{1.1965, 0.9336}, {-0.8289,-1.8181}, { 1.0426, 5.5157}, { -1.909,-8.5216},
1105 { 1.2419, 1.8693}, {-4.3633, -5.5678}, { 13.743, 14.795}, {-18.592, -16.903},
1106 { 0.0, 0.0}, { 0.0, 0.0}},
1107
1108 {{0.287, 1.7811}, {-4.9065,-8.2927}, { 16.264, 20.607}, {-19.904,-20.827},
1109 {-0.244, -0.4996}, {1.3158, 1.7874}, {-3.5691, -4.133}, { 4.3867, 3.8393},
1110 { 0.0, 0.0}, { 0.0, 0.0}},
1111
1112 {{-0.2449, -1.5264}, { 2.9191, 6.8433}, {-9.5776, -16.067}, { 11.938, 16.845},
1113 {0.0157, 0.0462}, {-0.0826, -0.1854}, { 0.2143, 0.4531}, {-0.2585, -0.4627},
1114 { 0.0, 0.0}, { 0.0, 0.0}},
1115
1116 {{0.0373, 0.2713}, {-0.422, -1.1944}, { 1.3883, 2.7495}, {-1.7476,-2.9045},
1117 {-0.0003, -0.0013}, {0.0014, 0.0058}, {-0.0034,-0.0146}, { 0.0039, 0.0156},
1118 { 0.0, 0.0}, { 0.0, 0.0}},
1119
1120 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1121 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1122 { 0.1451, 0.0929},{ 0.1538, 0.1303}},
1123
1124 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1125 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1126 { 0.4652, 0.5389},{ 0.2744, 0.4071}},
1127
1128 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1129 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1130 { -0.033, -0.0545},{-0.0146, -0.0288}},
1131
1132 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1133 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1134 { 0.6296, 0.1491},{ 0.8381, 0.1802}},
1135
1136 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1137 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1138 { 0.1787, 0.385},{ 0.0086, 0.3302}},
1139
1140 {{ 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1141 { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0}, { 0.0, 0.0},
1142 {-0.0026, -0.0128},{ 0.0033, -0.0094}}
1143};
1144
1145const G4double G4ElementaryParticleCollider::abn[4][4][4] = {
1146 {{0.0856, 0.0716, 0.1729, 0.0376}, {5.0390, 3.0960, 7.1080, 1.4331},
1147 {-13.782, -11.125, -17.961, -3.1350}, {14.661, 18.130, 16.403, 6.4864}},
1148 {{0.0543, 0.0926, -0.1450, 0.2383}, {-9.2324, -3.2186, -13.032, 1.8253},
1149 {36.397, 20.273, 41.781, 1.7648}, {-42.962, -33.245, -40.799, -16.735}},
1150 {{-0.0511, -0.0515, 0.0454, -0.1541}, {4.6003, 0.8989, 8.3515, -1.5201},
1151 {-20.534, -7.5084, -30.260, -1.5692}, {27.731, 13.188, 32.882, 17.185}},
1152 {{0.0075, 0.0058, -0.0048, 0.0250}, {-0.6253, -0.0017, -1.4095, 0.3059},
1153 {2.9159, 0.7022, 5.3505, 0.3252}, {-4.1101, -1.4854, -6.0946, -3.5277}}
1154};
std::vector< G4InuclElementaryParticle >::iterator particleIterator
Definition: G4BigBanger.cc:60
@ photon
@ neutron
std::vector< G4InuclElementaryParticle >::iterator particleIterator
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
void setVectM(const Hep3Vector &spatial, double mass)
Hep3Vector vect() const
static const G4CascadeChannel * GetTable(G4int initialState)
static void PrintTable(G4int initialState, std::ostream &os=G4cout)
virtual G4int getMultiplicity(G4double ke) const =0
virtual void getOutgoingParticleTypes(std::vector< G4int > &kinds, G4int mult, G4double ke) const =0
virtual G4bool useEPCollider(G4InuclParticle *bullet, G4InuclParticle *target) const
virtual G4bool validateOutput(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
void addOutgoingParticles(const std::vector< G4InuclElementaryParticle > &particles)
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
G4int hadrons() const
void set(G4InuclParticle *part1, G4InuclParticle *part2)
static G4double getParticleMass(G4int type)
G4ParticleDefinition * getDefinition() const
G4double getMomModule() const
G4double getTotalSCMEnergy() const
void setVerbose(G4int vb=0)
void setBullet(const G4InuclParticle *bullet)
G4double getSCMMomentum() const
G4LorentzVector backToTheLab(const G4LorentzVector &mom) const
G4LorentzVector rotate(const G4LorentzVector &mom) const
G4double getKinEnergyInTheTRS() const
void setTarget(const G4InuclParticle *target)
const G4String & GetParticleName() const
G4LorentzVector generateWithFixedTheta(G4double ct, G4double p, G4double mass=0.)
G4LorentzVector generateWithRandomAngles(G4double p, G4double mass=0.)