132 using namespace G4InuclParticleNames;
133 using namespace G4InuclSpecialFunctions;
140 nucleusA(0), nucleusZ(0) {;}
149 G4cout <<
" >>> G4ElementaryParticleCollider::collide" <<
G4endl;
152 G4cerr <<
" ElementaryParticleCollider -> can collide only particle with particle "
157 #ifdef G4CASCADE_DEBUG_SAMPLER
158 static G4bool doPrintTables =
true;
161 doPrintTables =
false;
174 if (!particle1 || !particle2) {
175 G4cerr <<
" ElementaryParticleCollider -> can only collide hadrons"
185 G4cerr <<
" ElementaryParticleCollider -> cannot collide "
210 if (pionNucleonAbsorption(ekin)) {
211 generateSCMpionNAbsorption(etot_scm, particle1, particle2);
213 generateSCMfinalState(ekin, etot_scm, particle1, particle2);
221 G4cerr <<
" ElementaryParticleCollider -> can only collide pi,mu,gamma with"
222 <<
" dibaryons " <<
G4endl;
227 generateSCMmuonAbsorption(etot_scm, particle1, particle2);
229 generateSCMpionAbsorption(etot_scm, particle1, particle2);
233 if (particles.empty()) {
235 G4cerr <<
" ElementaryParticleCollider -> failed to collide "
246 for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
248 ipart->setMomentum(mom);
253 G4cout <<
" incoming particles: \n" << *particle1 << G4endl
254 << *particle2 << G4endl
255 <<
" outgoing particles: " <<
G4endl;
256 for(ipart = particles.begin(); ipart != particles.end(); ipart++)
257 G4cout << *ipart << G4endl;
259 G4cout <<
" <<< Non-conservation in G4ElementaryParticleCollider"
269 G4ElementaryParticleCollider::generateMultiplicity(
G4int is,
278 G4cerr <<
" G4ElementaryParticleCollider: Unknown interaction channel "
279 << is <<
" - multiplicity not generated " <<
G4endl;
283 G4cout <<
" G4ElementaryParticleCollider::generateMultiplicity: "
284 <<
" multiplicity = " << mul <<
G4endl;
292 G4ElementaryParticleCollider::generateOutgoingPartTypes(
G4int is,
G4int mult,
295 particle_kinds.clear();
302 G4cerr <<
" G4ElementaryParticleCollider: Unknown interaction channel "
303 << is <<
" - outgoing kinds not generated " <<
G4endl;
311 G4ElementaryParticleCollider::generateSCMfinalState(
G4double ekin,
316 G4cout <<
" >>> G4ElementaryParticleCollider::generateSCMfinalState"
322 const G4int itry_max = 10;
327 G4int is = type1 * type2;
331 G4int multiplicity = 0;
335 while (generate && itry++ < itry_max) {
337 particle_kinds.clear();
340 multiplicity = generateMultiplicity(is, ekin);
342 generateOutgoingPartTypes(is, multiplicity, ekin);
343 if (particle_kinds.empty()) {
345 G4cout <<
" generateOutgoingPartTypes failed mult " << multiplicity
351 fillOutgoingMasses();
354 fsGenerator.
Configure(particle1, particle2, particle_kinds);
355 generate = !fsGenerator.
Generate(etot_scm, masses, scm_momentums);
358 if (itry >= itry_max) {
360 G4cout <<
" generateSCMfinalState failed " << itry <<
" attempts"
367 particles.resize(multiplicity);
368 for (
G4int i=0; i<multiplicity; i++) {
369 particles[i].fill(scm_momentums[i], particle_kinds[i],
374 G4cout <<
" <<< G4ElementaryParticleCollider::generateSCMfinalState"
384 void G4ElementaryParticleCollider::fillOutgoingMasses() {
385 G4int mult = particle_kinds.size();
387 masses.resize(mult,0.);
388 masses2.resize(mult,0.);
390 for (
G4int i = 0; i < mult; i++) {
392 masses2[i] = masses[i] * masses[i];
401 G4ElementaryParticleCollider::generateSCMpionAbsorption(
G4double etot_scm,
405 G4cout <<
" >>> G4ElementaryParticleCollider::generateSCMpionAbsorption"
411 particle_kinds.clear();
418 G4cerr <<
" pion absorption: "
425 if (!splitQuasiDeuteron(type2))
return;
427 fillOutgoingMasses();
429 G4double a = 0.5 * (etot_scm * etot_scm - masses2[0] - masses2[1]);
431 G4double pmod = std::sqrt((a*a - masses2[0]*masses2[1])
432 / (etot_scm*etot_scm) );
446 G4ElementaryParticleCollider::generateSCMmuonAbsorption(
G4double etot_scm,
451 G4cout <<
" >>> G4ElementaryParticleCollider::generateSCMmuonAbsorption"
459 scm_momentums.clear();
460 scm_momentums.resize(3);
462 particle_kinds.clear();
471 G4cerr <<
" mu- absorption: "
478 if (!splitQuasiDeuteron(type2))
return;
479 particle_kinds.push_back(
mnu);
481 fillOutgoingMasses();
483 G4GDecay3 breakup(etot_scm, masses[0], masses[1], masses[2]);
484 std::vector<G4ThreeVector> theMomenta = breakup.GetThreeBodyMomenta();
486 if (theMomenta.empty()) {
487 G4cerr <<
" generateSCMmuonAbsorption: GetThreeBodyMomenta() failed"
488 <<
" for " << type2 <<
" dibaryon" <<
G4endl;
489 particle_kinds.clear();
494 for (
size_t i=0; i<3; i++) {
495 scm_momentums[i].setVectM(theMomenta[i], masses[i]);
504 G4ElementaryParticleCollider::generateSCMpionNAbsorption(
G4double ,
508 G4cout <<
" >>> G4ElementaryParticleCollider::generateSCMpionNAbsorption"
514 particle_kinds.clear();
520 if ((type1*type2 !=
pim*
pro && type1*type2 !=
pip*
neu)) {
521 G4cerr <<
" pion-nucleon absorption: "
531 G4int outType = 3 - ntype;
532 particle_kinds.push_back(outType);
534 fillOutgoingMasses();
539 G4double mRecoil2 = mRecoil*mRecoil;
548 G4double a = 0.5 * (esq_scm - masses2[0] - mRecoil2);
550 G4double pmod = std::sqrt((a*a - masses2[0]*mRecoil2) / esq_scm );
554 G4cout <<
" outgoing type " << outType <<
" recoiling on nuclear mass "
555 << mRecoil <<
"\n a " << a <<
" p " << pmod <<
" Ekin "
556 << mom1.
e()-masses[0] <<
G4endl;
562 G4cout <<
" in original pi-N frame p(SCM) " << mom1.
rho() <<
" Ekin "
563 << mom1.
e()-masses[0] <<
G4endl;
574 G4ElementaryParticleCollider::pionNucleonAbsorption(
G4double ekin)
const {
576 G4cout <<
" >>> G4ElementaryParticleCollider::pionNucleonAbsorption ?"
594 G4bool G4ElementaryParticleCollider::splitQuasiDeuteron(
G4int qdtype) {
596 G4cerr <<
" type " << qdtype <<
" not dibaryon!" <<
G4endl;
600 G4int b2 = qdtype % 10;
601 G4int b1 = (qdtype/10) % 10;
603 particle_kinds.push_back(b1);
604 particle_kinds.push_back(b2);
Hep3Vector boostVector() const
static const G4CascadeChannel * GetTable(G4int initialState)
G4bool Generate(G4double initialMass, const std::vector< G4double > &masses, std::vector< G4LorentzVector > &finalState)
G4LorentzVector getMomentum() const
virtual G4bool useEPCollider(G4InuclParticle *bullet, G4InuclParticle *target) const
virtual void getOutgoingParticleTypes(std::vector< G4int > &kinds, G4int mult, G4double ke) const =0
std::vector< ExP01TrackerHit * > a
static G4double piNAbsorption()
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
const G4ParticleDefinition * getDefinition() const
static G4bool useQuasiDeuteron(G4int ptype, G4int qdtype=0)
static G4double getParticleMass(G4int type)
void setBullet(const G4InuclParticle *bullet)
G4double getTotalSCMEnergy() const
G4LorentzVector backToTheLab(const G4LorentzVector &mom) const
const G4String & GetParticleName() const
void setVectM(const Hep3Vector &spatial, double mass)
G4ElementaryParticleCollider()
G4GLOB_DLL std::ostream G4cout
void setVerbose(G4int vb=0)
HepLorentzVector & boost(double, double, double)
G4double getNucleiMass() const
void Configure(G4InuclElementaryParticle *bullet, G4InuclElementaryParticle *target, const std::vector< G4int > &particle_kinds)
G4LorentzVector generateWithRandomAngles(G4double p, G4double mass=0.)
G4double getKinEnergyInTheTRS() const
G4InteractionCase interCase
static void Print(std::ostream &os=G4cout)
void addOutgoingParticles(const std::vector< G4InuclElementaryParticle > &particles)
void set(G4InuclParticle *part1, G4InuclParticle *part2)
void generate(const G4double sqrtS, ParticleList &particles)
Generate an event in the CM system.
void SetVerboseLevel(G4int verbose)
virtual G4bool validateOutput(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
std::vector< G4InuclElementaryParticle >::iterator particleIterator
G4bool quasi_deutron() const
virtual G4int getMultiplicity(G4double ke) const =0
G4double getMomModule() const
G4GLOB_DLL std::ostream G4cerr
G4bool isNeutrino() const
void setTarget(const G4InuclParticle *target)