G4ElementaryParticleCollider.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id$
00027 //
00028 // 20100114  M. Kelsey -- Remove G4CascadeMomentum, use G4LorentzVector directly
00029 // 20100316  D. Wright (restored by M. Kelsey) -- Replace original (incorrect)
00030 //              pp, pn, nn 2-body to 2-body scattering angular distributions
00031 //              with a new parametrization of elastic scattering data using
00032 //              the sum of two exponentials.
00033 // 20100319  M. Kelsey -- Use new generateWithRandomAngles for theta,phi stuff;
00034 //              eliminate some unnecessary std::pow()
00035 // 20100407  M. Kelsey -- Replace std::vector<>::resize(0) with ::clear()
00036 //              Eliminate return-by-value std::vector<> by creating buffers
00037 //              buffers for particles, momenta, and particle types.
00038 //              The following functions now return void and are non-const:
00039 //                ::generateSCMfinalState()
00040 //                ::generateMomModules()
00041 //                ::generateStrangeChannelPartTypes()
00042 //                ::generateSCMpionAbsorption()
00043 // 20100408  M. Kelsey -- Follow changes to G4*Sampler to pass particle_kinds
00044 //              as input buffer.
00045 // 20100413  M. Kelsey -- Pass G4CollisionOutput by ref to ::collide()
00046 // 20100428  M. Kelsey -- Use G4InuclParticleNames enum
00047 // 20100429  M. Kelsey -- Change "photon()" to "isPhoton()"
00048 // 20100507  M. Kelsey -- Rationalize multiplicity returns to be actual value
00049 // 20100511  M. Kelsey -- Replace G4PionSampler and G4NucleonSampler with new
00050 //              pi-N and N-N classes, reorganize if-cascades 
00051 // 20100511  M. Kelsey -- Eliminate three residual random-angles blocks.
00052 // 20100511  M. Kelsey -- Bug fix: pi-N two-body final states not correctly
00053 //              tested for charge-exchange case.
00054 // 20100512  M. Kelsey -- Rationalize multiplicity returns to be actual value
00055 // 20100512  M. Kelsey -- Add some additional debugging messages for 2-to-2
00056 // 20100512  M. Kelsey -- Replace "if (is==)" cascades with switch blocks.
00057 //              Use G4CascadeInterpolator for angular distributions.
00058 // 20100517  M. Kelsey -- Inherit from common base class, make arrays static
00059 // 20100519  M. Kelsey -- Use G4InteractionCase to compute "is" values.
00060 // 20100625  M. Kelsey -- Two bugs in n-body momentum, last particle recoil
00061 // 20100713  M. Kelsey -- Bump collide start message up to verbose > 1
00062 // 20100714  M. Kelsey -- Move conservation checking to base class
00063 // 20100714  M. Kelsey -- Add sanity check for two-body final state, to ensure
00064 //              that final state total mass is below etot_scm; also compute
00065 //              kinematics without "rescaling" (which led to non-conservation)
00066 // 20100726  M. Kelsey -- Move remaining std::vector<> buffers to .hh file
00067 // 20100804  M. Kelsey -- Add printing of final-state tables, protected by
00068 //              G4CASCADE_DEBUG_SAMPLER preprocessor flag
00069 // 20101019  M. Kelsey -- CoVerity report: check dynamic_cast<> for null
00070 // 20110214  M. Kelsey -- Follow G4InuclParticle::Model enumerator migration
00071 // 20110718  V. Uzhinskiy -- Drop IL,IM reset for multiplicity-three collisions
00072 // 20110718  M. Kelsey -- Use enum names in switch blocks (c.f. G4NucleiModel)
00073 // 20110720  M. Kelsey -- Follow interface change for cross-section tables,
00074 //              eliminating switch blocks.
00075 // 20110806  M. Kelsey -- Pre-allocate buffers to avoid memory churn
00076 // 20110922  M. Kelsey -- Follow G4InuclParticle::print(ostream&) migration
00077 // 20110926  M. Kelsey -- Protect sampleCMcosFor2to2 from unphysical arguments
00078 // 20111003  M. Kelsey -- Prepare for gamma-N interactions by checking for
00079 //              final-state tables instead of particle "isPhoton()"
00080 // 20111007  M. Kelsey -- Add gamma-N final-state tables to printFinalState
00081 // 20111107  M. Kelsey -- In sampleCMmomentumFor2to2(), hide message about
00082 //              unrecognized gamma-N initial state behind verbosity.
00083 // 20111216  M. Kelsey -- Add diagnostics to generateMomModulesFor2toMany(),
00084 //              defer allocation of buffer in generateSCMfinalState() so that
00085 //              multiplicity failures return zero output, and can be trapped.
00086 // 20120308  M. Kelsey -- Allow photons to interact with dibaryons (see
00087 //              changes in G4NucleiModel).
00088 // 20120608  M. Kelsey -- Fix variable-name "shadowing" compiler warnings.
00089 
00090 #include "G4ElementaryParticleCollider.hh"
00091 #include "G4CascadeChannel.hh"
00092 #include "G4CascadeChannelTables.hh"
00093 #include "G4CascadeInterpolator.hh"
00094 #include "G4CollisionOutput.hh"
00095 #include "G4InuclParticleNames.hh"
00096 #include "G4InuclSpecialFunctions.hh"
00097 #include "G4LorentzConvertor.hh"
00098 #include "G4ParticleLargerEkin.hh"
00099 #include "Randomize.hh"
00100 #include <algorithm>
00101 #include <cfloat>
00102 #include <vector>
00103 
00104 using namespace G4InuclParticleNames;
00105 using namespace G4InuclSpecialFunctions;
00106 
00107 typedef std::vector<G4InuclElementaryParticle>::iterator particleIterator;
00108 
00109 
00110 G4ElementaryParticleCollider::G4ElementaryParticleCollider()
00111   : G4CascadeColliderBase("G4ElementaryParticleCollider") {}
00112 
00113 
00114 void
00115 G4ElementaryParticleCollider::collide(G4InuclParticle* bullet,
00116                                       G4InuclParticle* target,
00117                                       G4CollisionOutput& output) 
00118 {
00119   if (verboseLevel > 1)
00120     G4cout << " >>> G4ElementaryParticleCollider::collide" << G4endl;
00121 
00122   if (!useEPCollider(bullet,target)) {          // Sanity check
00123     G4cerr << " ElementaryParticleCollider -> can collide only particle with particle " 
00124            << G4endl;
00125     return;
00126   }
00127 
00128 #ifdef G4CASCADE_DEBUG_SAMPLER
00129   static G4bool doPrintTables = true;   // Once and only once per job
00130   if (doPrintTables) {
00131     printFinalStateTables();            // For diagnostic reporting
00132     doPrintTables = false;
00133   }
00134 #endif
00135 
00136   interCase.set(bullet, target);        // To identify kind of collision
00137 
00138   if (verboseLevel > 1) G4cout << *bullet << G4endl << *target << G4endl;
00139 
00140   G4InuclElementaryParticle* particle1 =
00141     dynamic_cast<G4InuclElementaryParticle*>(bullet);
00142   G4InuclElementaryParticle* particle2 =        
00143     dynamic_cast<G4InuclElementaryParticle*>(target);
00144 
00145   if (!particle1 || !particle2) {       // Redundant with useEPCollider()
00146     G4cerr << " ElementaryParticleCollider -> can only collide hadrons"
00147            << G4endl;
00148     return;
00149   }
00150 
00151   // Check for available interaction, or pion+dibaryon special case
00152   if (!G4CascadeChannelTables::GetTable(interCase.hadrons()) &&
00153       !particle1->quasi_deutron() && !particle2->quasi_deutron()) {
00154     G4cerr << " ElementaryParticleCollider -> cannot collide " 
00155            << particle1->getDefinition()->GetParticleName() << " with "
00156            << particle2->getDefinition()->GetParticleName() << G4endl;
00157     return;
00158   }
00159   // Generate nucleon or pion collision with nucleon
00160   // or pion with quasi-deuteron
00161 
00162   if (particle1->nucleon() || particle2->nucleon()) { // ok
00163     G4LorentzConvertor convertToSCM;
00164     if(particle2->nucleon()) {
00165       convertToSCM.setBullet(particle1);
00166       convertToSCM.setTarget(particle2);
00167     } else {
00168       convertToSCM.setBullet(particle2);
00169       convertToSCM.setTarget(particle1);
00170     };
00171 
00172     convertToSCM.setVerbose(verboseLevel);
00173 
00174     convertToSCM.toTheCenterOfMass();
00175     G4double ekin = convertToSCM.getKinEnergyInTheTRS();
00176     G4double etot_scm = convertToSCM.getTotalSCMEnergy();
00177     G4double pscm = convertToSCM.getSCMMomentum();
00178 
00179     generateSCMfinalState(ekin, etot_scm, pscm, particle1, particle2,
00180                           &convertToSCM);
00181 
00182     if (particles.empty()) {    // No final state possible, pass bullet through
00183       if (verboseLevel) {
00184         G4cerr << " ElementaryParticleCollider -> failed to collide " 
00185                << particle1->getMomModule() << " GeV/c " 
00186                << particle1->getDefinition()->GetParticleName() << " with "
00187                << particle2->getDefinition()->GetParticleName() << G4endl;
00188       }
00189     } else {                     // convert back to Lab
00190       G4LorentzVector mom;              // Buffer to avoid memory churn
00191       particleIterator ipart;
00192       for(ipart = particles.begin(); ipart != particles.end(); ipart++) {       
00193         mom = convertToSCM.backToTheLab(ipart->getMomentum());
00194         ipart->setMomentum(mom); 
00195       };
00196 
00197       // Check conservation in multibody final state
00198       if (verboseLevel && !validateOutput(bullet, target, particles)) {
00199         G4cout << " incoming particles: \n" << *particle1 << G4endl
00200                << *particle2 << G4endl
00201                << " outgoing particles: " << G4endl;
00202         for(ipart = particles.begin(); ipart != particles.end(); ipart++)
00203           G4cout << *ipart << G4endl;
00204 
00205         G4cout << " <<< Non-conservation in G4ElementaryParticleCollider"
00206                << G4endl;
00207       }
00208 
00209       std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
00210       output.addOutgoingParticles(particles);
00211     }
00212   } else {      // neither particle is nucleon: pion on quasideuteron
00213     if (particle1->quasi_deutron() || particle2->quasi_deutron()) {
00214       if (particle1->pion() || particle2->pion() ||
00215           particle1->isPhoton() || particle2->isPhoton()) {
00216         G4LorentzConvertor convertToSCM;
00217         if(particle2->quasi_deutron()) {        // Quasideuteron is target
00218           convertToSCM.setBullet(particle1);
00219           convertToSCM.setTarget(particle2);
00220         } else {
00221           convertToSCM.setBullet(particle2);
00222           convertToSCM.setTarget(particle1);
00223         }; 
00224         convertToSCM.toTheCenterOfMass(); 
00225         G4double etot_scm = convertToSCM.getTotalSCMEnergy();
00226         
00227         generateSCMpionAbsorption(etot_scm, particle1, particle2);
00228 
00229         if (particles.empty()) {        // Failed to generate final state
00230           if (verboseLevel) {
00231             G4cerr << " ElementaryParticleCollider -> failed to collide " 
00232                    << particle1->getMomModule() << " GeV/c " 
00233                    << particle1->getDefinition()->GetParticleName() << " with "
00234                    << particle2->getDefinition()->GetParticleName() << G4endl;
00235           }
00236         } else {                        // convert back to Lab
00237           G4LorentzVector mom;  // Buffer to avoid memory churn
00238           particleIterator ipart;
00239           for(ipart = particles.begin(); ipart != particles.end(); ipart++) {
00240             mom = convertToSCM.backToTheLab(ipart->getMomentum());
00241             ipart->setMomentum(mom); 
00242           };
00243 
00244           validateOutput(bullet, target, particles);    // Check conservation
00245 
00246           std::sort(particles.begin(), particles.end(), G4ParticleLargerEkin());
00247           output.addOutgoingParticles(particles);
00248         };
00249       } else {
00250         G4cerr << " ElementaryParticleCollider -> can only collide pions with dibaryons " 
00251                << G4endl;
00252       };
00253     } else {
00254       G4cerr << " ElementaryParticleCollider -> can only collide something with nucleon or dibaryon " 
00255              << G4endl;
00256     };
00257   };  
00258 }
00259 
00260 
00261 G4int 
00262 G4ElementaryParticleCollider::generateMultiplicity(G4int is, 
00263                                                    G4double ekin) const 
00264 {
00265   G4int mul = 0;
00266 
00267   const G4CascadeChannel* xsecTable = G4CascadeChannelTables::GetTable(is);
00268 
00269   if (xsecTable) mul = xsecTable->getMultiplicity(ekin);
00270   else {
00271     G4cerr << " G4ElementaryParticleCollider: Unknown interaction channel "
00272            << is << " - multiplicity not generated " << G4endl;
00273   }
00274 
00275   if(verboseLevel > 3){
00276     G4cout << " G4ElementaryParticleCollider::generateMultiplicity: "  
00277            << " multiplicity = " << mul << G4endl; 
00278   }
00279 
00280   return mul;
00281 }
00282 
00283  
00284 void
00285 G4ElementaryParticleCollider::generateSCMfinalState(G4double ekin, 
00286                                      G4double etot_scm, 
00287                                      G4double pscm,
00288                                      G4InuclElementaryParticle* particle1,
00289                                      G4InuclElementaryParticle* particle2, 
00290                                      G4LorentzConvertor* toSCM) {
00291   if (verboseLevel > 3) {
00292     G4cout << " >>> G4ElementaryParticleCollider::generateSCMfinalState" 
00293            << G4endl;
00294   }
00295 
00296   const G4double ang_cut = 0.9999;
00297   const G4double difr_const = 0.3678794;   
00298   const G4int itry_max = 10;
00299   G4InuclElementaryParticle dummy;
00300 
00301   G4int type1 = particle1->type();
00302   G4int type2 = particle2->type();
00303 
00304   G4int is = type1 * type2;
00305 
00306   if(verboseLevel > 3){
00307     G4cout << " is " << is << G4endl;
00308   }
00309 
00310   G4int multiplicity = 0;
00311   G4bool generate = true;
00312 
00313   while (generate) {
00314     particles.clear();          // Initialize buffers for this event
00315     particle_kinds.clear();
00316 
00317     // Generate list of final-state particles
00318     multiplicity = generateMultiplicity(is, ekin);
00319 
00320     generateOutgoingPartTypes(is, multiplicity, ekin);
00321     if (particle_kinds.empty()) {
00322       if (verboseLevel > 3) {
00323         G4cout << " generateOutgoingPartTypes failed mult " << multiplicity
00324                << G4endl;
00325       }
00326       continue;
00327     }
00328 
00329     if (multiplicity == 2) {
00330       // Identify charge or strangeness exchange (non-elastic scatter)
00331       G4int finaltype = particle_kinds[0]*particle_kinds[1];
00332       G4int kw = (finaltype != is) ? 2 : 1;
00333 
00334       G4double pmod = pscm;     // Elastic scattering preserves CM momentum
00335 
00336       if (kw == 2) {            // Non-elastic needs new CM momentum value
00337         G4double mone = dummy.getParticleMass(particle_kinds[0]);
00338         G4double mtwo = dummy.getParticleMass(particle_kinds[1]);
00339 
00340         if (etot_scm < mone+mtwo) {             // Can't produce final state
00341           if (verboseLevel > 2) {
00342             G4cerr << " bad final state " << particle_kinds[0]
00343                    << " , " << particle_kinds[1] << " etot_scm " << etot_scm
00344                    << " < mone+mtwo " << mone+mtwo << " , but ekin " << ekin
00345                    << G4endl;
00346           }
00347           continue;
00348         }
00349 
00350         G4double ecm_sq = etot_scm*etot_scm;
00351         G4double msumsq = mone+mtwo; msumsq *= msumsq;
00352         G4double mdifsq = mone-mtwo; mdifsq *= mdifsq;
00353 
00354         G4double a = (ecm_sq - msumsq) * (ecm_sq - mdifsq);
00355 
00356         pmod = std::sqrt(a)/(2.*etot_scm);
00357       }
00358 
00359       G4LorentzVector mom = sampleCMmomentumFor2to2(is, kw, ekin, pmod);
00360 
00361       if (verboseLevel > 3) {
00362         G4cout << " Particle kinds = " << particle_kinds[0] << " , "
00363                << particle_kinds[1] << G4endl
00364                << " pscm " << pscm << " pmod " << pmod << G4endl
00365                << " before rotation px " << mom.x() << " py " << mom.y()
00366                << " pz " << mom.z() << G4endl;
00367       }
00368 
00369       mom = toSCM->rotate(mom); 
00370 
00371       if (verboseLevel > 3){
00372         G4cout << " after rotation px " << mom.x() << " py " << mom.y() <<
00373           " pz " << mom.z() << G4endl;
00374       }
00375       G4LorentzVector mom1(-mom.vect(), mom.e());
00376 
00377       particles.resize(multiplicity);           // Preallocate buffer
00378       particles[0].fill(mom, particle_kinds[0], G4InuclParticle::EPCollider);
00379       particles[1].fill(mom1, particle_kinds[1], G4InuclParticle::EPCollider);
00380       generate = false;
00381     } else {                     // 2 -> many
00382       G4int itry = 0;
00383       G4bool bad = true;
00384       G4int knd_last = particle_kinds[multiplicity - 1];
00385       G4double mass_last = dummy.getParticleMass(knd_last);
00386 
00387       if (verboseLevel > 3){
00388         G4cout << " knd_last " << knd_last << " mass " << mass_last << G4endl;
00389       }
00390 
00391       while (bad && itry < itry_max) {
00392         itry++;
00393 
00394         if (verboseLevel > 3){
00395           G4cout << " itry in generateSCMfinalState " << itry << G4endl;
00396         }
00397 
00398         generateMomModules(multiplicity, is, ekin, etot_scm);
00399         if (G4int(modules.size()) != multiplicity) {
00400           if (verboseLevel > 3) {
00401             G4cerr << " generateMomModule failed at mult " << multiplicity
00402                    << " ekin " << ekin << " etot_scm " << etot_scm << G4endl;
00403           }
00404           continue;
00405         }
00406 
00407         if (multiplicity == 3) { 
00408           G4LorentzVector mom3 = 
00409             particleSCMmomentumFor2to3(is, knd_last, ekin, modules[2]);
00410           
00411           mom3 = toSCM->rotate(mom3);
00412           
00413           // generate the momentum of first
00414           G4double ct = -0.5 * (modules[2] * modules[2] + 
00415                                 modules[0] * modules[0] - 
00416                                 modules[1] * modules[1]) /
00417             modules[2] / modules[0];   
00418           
00419           if(std::fabs(ct) < ang_cut) {
00420             
00421             if(verboseLevel > 2){
00422               G4cout << " ok for mult " << multiplicity << G4endl;
00423             }
00424             
00425             G4LorentzVector mom1 = generateWithFixedTheta(ct, modules[0]);
00426             mom1 = toSCM->rotate(mom3, mom1);
00427 
00428             // Second particle recoils off 1 & 3
00429             G4LorentzVector mom2(etot_scm);
00430             mom2 -= mom1+mom3;
00431             
00432             bad = false;
00433             generate = false;
00434 
00435             particles.resize(multiplicity);             // Preallocate buffer
00436    
00437             particles[0].fill(mom1, particle_kinds[0], G4InuclParticle::EPCollider);
00438             particles[1].fill(mom2, particle_kinds[1], G4InuclParticle::EPCollider);
00439             particles[2].fill(mom3, particle_kinds[2], G4InuclParticle::EPCollider);
00440           };
00441         } else { // multiplicity > 3
00442           // generate first mult - 2 momentums
00443           G4LorentzVector tot_mom;
00444           scm_momentums.clear();
00445           
00446           for (G4int i = 0; i < multiplicity - 2; i++) {
00447             G4double p0 = particle_kinds[i] < 3 ? 0.36 : 0.25;
00448             G4double alf = 1.0 / p0 / (p0 - (modules[i] + p0) *
00449                                        std::exp(-modules[i] / p0));
00450             G4double st = 2.0;
00451             G4int itry1 = 0;
00452             
00453             while (std::fabs(st) > ang_cut && itry1 < itry_max) {
00454               itry1++;
00455               G4double s1 = modules[i] * inuclRndm();
00456               G4double s2 = alf * difr_const * p0 * inuclRndm();
00457               
00458               if(verboseLevel > 3){
00459                 G4cout << " s1 * alf * std::exp(-s1 / p0) "
00460                        << s1 * alf * std::exp(-s1 / p0) 
00461                        << " s2 " << s2 << G4endl;
00462               }
00463               
00464               if(s1 * alf * std::exp(-s1 / p0) > s2) st = s1 / modules[i];
00465             };
00466             
00467             if(verboseLevel > 3){
00468               G4cout << " itry1 " << itry1 << " i " << i << " st " << st
00469                      << G4endl;
00470             }
00471             
00472             if(itry1 == itry_max) {
00473               if(verboseLevel > 2){
00474                 G4cout << " high energy angles generation: itry1 " << itry1
00475                        << G4endl;
00476               }
00477               
00478               st = 0.5 * inuclRndm();
00479             };
00480 
00481             G4double ct = std::sqrt(1.0 - st * st);
00482             if (inuclRndm() > 0.5) ct = -ct;
00483             
00484             G4LorentzVector mom = generateWithFixedTheta(ct,modules[i]);
00485 
00486             tot_mom += mom;
00487             
00488             scm_momentums.push_back(mom);
00489           }; 
00490           
00491           // handle last two
00492           G4double tot_mod = tot_mom.rho(); 
00493           G4double ct = -0.5 * (tot_mod * tot_mod + 
00494                                 modules[multiplicity - 2] * modules[multiplicity - 2] -
00495                                 modules[multiplicity - 1] * modules[multiplicity - 1]) / tot_mod /
00496             modules[multiplicity - 2];  
00497           
00498           if (verboseLevel > 2){
00499             G4cout << " ct last " << ct << G4endl;
00500           }            
00501           
00502           if (std::fabs(ct) < ang_cut) {
00503             G4int i(0);
00504             for (i = 0; i < multiplicity - 2; i++) 
00505               scm_momentums[i] = toSCM->rotate(scm_momentums[i]);
00506             
00507             tot_mom = toSCM->rotate(tot_mom);  
00508             
00509             G4LorentzVector mom = 
00510               generateWithFixedTheta(ct, modules[multiplicity - 2]);
00511             
00512             mom = toSCM->rotate(tot_mom, mom);
00513             scm_momentums.push_back(mom);
00514 
00515             // Last particle recoils off everything else
00516             G4LorentzVector mom1(etot_scm);
00517             mom1 -= mom+tot_mom;
00518             
00519             scm_momentums.push_back(mom1);  
00520             bad = false;
00521             generate = false;
00522             
00523             if (verboseLevel > 2){
00524               G4cout << " ok for mult " << multiplicity << G4endl;
00525             }
00526 
00527             particles.resize(multiplicity);             // Preallocate buffer
00528             for (i = 0; i < multiplicity; i++) {
00529               particles[i].fill(scm_momentums[i], particle_kinds[i],
00530                                 G4InuclParticle::EPCollider);
00531             }
00532           }     // |ct| < ang_cut
00533         }       // multiplicity > 3
00534       }         // while (bad && itry < itry_max)
00535 
00536       if (itry == itry_max) {
00537         if (verboseLevel > 2) {
00538           G4cout << " cannot generate the distr. for mult " << multiplicity
00539                  << G4endl;
00540         }
00541         break;
00542       }
00543     }   // multiplicity > 2
00544   }     // while (generate) 
00545 
00546   if (verboseLevel > 3) {
00547     G4cout << " <<< G4ElementaryParticleCollider::generateSCMfinalState"
00548            << G4endl;
00549   }
00550 
00551   return;       // Particles buffer filled
00552 }
00553 
00554 void 
00555 G4ElementaryParticleCollider::generateMomModules(G4int mult, 
00556                                                  G4int is, 
00557                                                  G4double ekin, 
00558                                                  G4double etot_cm) {
00559   if (verboseLevel > 3) {
00560     G4cout << " >>> G4ElementaryParticleCollider::generateMomModules" 
00561            << G4endl;
00562   }
00563 
00564   if (verboseLevel > 2){
00565     G4cout << " mult " << mult << " is " << is << " ekin " << ekin
00566            << " etot_cm " << etot_cm << G4endl;
00567   }
00568 
00569   const G4int itry_max = 10;
00570   const G4double small = 1.e-10;
00571   G4InuclElementaryParticle dummy;
00572   G4int itry = 0;
00573 
00574   modules.clear();                      // Initialize buffer for this attempt
00575   modules.resize(mult,0.);
00576 
00577   masses2.clear();
00578   masses2.resize(mult,0.);              // Allows direct [i] setting
00579 
00580   for (G4int i = 0; i < mult; i++) {
00581     G4double mass = dummy.getParticleMass(particle_kinds[i]);
00582     masses2[i] = mass * mass;
00583   };
00584 
00585   G4double mass_last = std::sqrt(masses2[mult - 1]);
00586 
00587   if (verboseLevel > 3){
00588     G4cout << " knd_last " << particle_kinds[mult - 1] << " mass_last " 
00589            << mass_last << G4endl;
00590   }
00591 
00592   while (itry < itry_max) {
00593     itry++;
00594     if(verboseLevel > 3){
00595       G4cout << " itry in generateMomModules " << itry << G4endl;
00596     }
00597 
00598     G4int ilast = -1;
00599     G4double eleft = etot_cm;
00600 
00601     for (G4int i = 0; i < mult - 1; i++) {
00602       G4double pmod = 
00603         getMomModuleFor2toMany(is, mult, particle_kinds[i], ekin);
00604 
00605       if (pmod < small) break;
00606       eleft -= std::sqrt(pmod * pmod + masses2[i]);
00607 
00608       if (verboseLevel > 3){
00609         G4cout << " kp " << particle_kinds[i] << " pmod " << pmod
00610                << " mass2 " << masses2[i] << " eleft " << eleft
00611                << "\n x1 " << eleft - mass_last << G4endl;
00612       }
00613 
00614       if (eleft <= mass_last) break;
00615       ilast++;
00616       modules[i] = pmod;
00617     };
00618 
00619     if (ilast == mult - 2) {
00620       G4double plast = eleft * eleft - masses2[mult - 1];
00621       if (verboseLevel > 2){
00622         G4cout << " plast ** 2 " << plast << G4endl;
00623       }
00624 
00625       if (plast > small) {
00626         plast = std::sqrt(plast);
00627         modules[mult - 1] = plast;      
00628 
00629         if (mult == 3) { 
00630           if (satisfyTriangle(modules)) return;
00631         } else return;
00632       }
00633     }
00634   }     // while (itry < itry_max)
00635 
00636   if (verboseLevel > 2)
00637     G4cerr << " Unable to generate momenta for multiplicity " << mult << G4endl;
00638 
00639   modules.clear();              // Something went wrong, throw away partial
00640   return;    
00641 }
00642 
00643 
00644 G4bool 
00645 G4ElementaryParticleCollider::satisfyTriangle(
00646                         const std::vector<G4double>& pmod) const 
00647 {
00648   if (verboseLevel > 3) {
00649     G4cout << " >>> G4ElementaryParticleCollider::satisfyTriangle" 
00650            << G4endl;
00651   }
00652 
00653   G4bool good = ( (pmod.size() != 3) ||
00654                   !(std::fabs(pmod[1] - pmod[2]) > pmod[0] || 
00655                     pmod[0] > pmod[1] + pmod[2] ||
00656                     std::fabs(pmod[0] - pmod[2]) > pmod[1] ||
00657                     pmod[1] > pmod[0] + pmod[2] ||
00658                     std::fabs(pmod[0] - pmod[1]) > pmod[2] ||
00659                     pmod[2] > pmod[1] + pmod[0]));
00660 
00661   return good;
00662 }
00663 
00664 
00665 void 
00666 G4ElementaryParticleCollider::generateOutgoingPartTypes(G4int is, G4int mult,
00667                                                         G4double ekin)
00668 {
00669   particle_kinds.clear();       // Initialize buffer for generation
00670 
00671   const G4CascadeChannel* xsecTable = G4CascadeChannelTables::GetTable(is);
00672 
00673   if (xsecTable)
00674     xsecTable->getOutgoingParticleTypes(particle_kinds, mult, ekin);
00675   else {
00676     G4cerr << " G4ElementaryParticleCollider: Unknown interaction channel "
00677            << is << " - outgoing kinds not generated " << G4endl;
00678   }
00679 
00680   return;
00681 }
00682 
00683 
00684 G4double 
00685 G4ElementaryParticleCollider::getMomModuleFor2toMany(G4int is, G4int /*mult*/, 
00686                                                      G4int knd, 
00687                                                      G4double ekin) const 
00688 {
00689   if (verboseLevel > 2) {
00690     G4cout << " >>> G4ElementaryParticleCollider::getMomModuleFor2toMany "
00691            << " is " << is << " knd " << knd << " ekin " << ekin << G4endl;
00692   }
00693 
00694   G4double S = inuclRndm();
00695   G4double PS = 0.0;
00696   G4double PR = 0.0;
00697   G4double PQ = 0.0;
00698   G4int KM = 2;
00699   G4int IL = 4;
00700   G4int JK = 4;
00701   G4int JM = 2;
00702   G4int IM = 3;
00703 
00704   if (is == 1 || is == 2 || is == 4) KM = 1;
00705   if (knd == 1 || knd == 2) JK = 0;
00706 
00707   if (verboseLevel > 3) {
00708     G4cout << " S " << S << " KM " << KM << " IL " << IL << " JK " << JK
00709            << " JM " << JM << " IM " << IM << G4endl;
00710   }
00711 
00712   for(G4int i = 0; i < 4; i++) {
00713     G4double V = 0.0;
00714     for(G4int k = 0; k < 4; k++) {
00715       if (verboseLevel > 3) {
00716         G4cout << " k " << k << " : rmn[k+JK][i+IL][KM-1] "
00717                << rmn[k+JK][i+IL][KM-1] << " ekin^k " << std::pow(ekin, k)
00718                << G4endl;
00719       }
00720 
00721       V += rmn[k + JK][i + IL][KM - 1] * std::pow(ekin, k);
00722     }
00723 
00724     if (verboseLevel > 3) {
00725       G4cout << " i " << i << " : V " << V << " S^i " << std::pow(S, i)
00726              << G4endl;
00727     }
00728 
00729     PR += V * std::pow(S, i);
00730     PQ += V;
00731   }
00732 
00733   if (verboseLevel > 3) G4cout << " PR " << PR << " PQ " << PQ << G4endl;
00734 
00735   if (knd == 1 || knd == 2) JM = 1;
00736   if (verboseLevel > 3) G4cout << " JM " << JM << G4endl;
00737 
00738   for(G4int im = 0; im < 3; im++) {
00739     if (verboseLevel >3) {
00740       G4cout << " im " << im << " : rmn[8+IM+im][7+JM][KM-1] "
00741              << rmn[8+IM+im][7+JM][KM-1] << " ekin^im " << std::pow(ekin, im)
00742              << G4endl;
00743     }
00744     PS += rmn[8 + IM + im][7 + JM][KM - 1] * std::pow(ekin, im);
00745   }
00746   
00747   G4double PRA = PS * std::sqrt(S) * (PR + (1 - PQ) * (S*S*S*S));
00748 
00749   if (verboseLevel > 3) 
00750     G4cout << " PS " << PS << " PRA = PS*sqrt(S)*(PR+(1-PQ)*S^4) " << PRA
00751            << G4endl;
00752 
00753   return std::fabs(PRA);
00754 }
00755 
00756 
00757 G4LorentzVector 
00758 G4ElementaryParticleCollider::particleSCMmomentumFor2to3(
00759                            G4int is, 
00760                            G4int knd, 
00761                            G4double ekin, 
00762                            G4double pmod) const 
00763 {
00764   if (verboseLevel > 3) {
00765     G4cout << " >>> G4ElementaryParticleCollider::particleSCMmomentumFor2to3" 
00766            << G4endl;
00767   }
00768 
00769   const G4int itry_max = 100;
00770   G4double ct = 2.0;
00771   G4int K = 3;
00772   G4int J = 1;
00773 
00774   if(is == 1 || is == 2 || is == 4) K = 1;
00775 
00776   if(knd == 1 || knd == 2) J = 0;
00777 
00778   G4int itry = 0;
00779 
00780   while(std::fabs(ct) > 1.0 && itry < itry_max) {
00781     itry++;
00782     G4double S = inuclRndm();
00783     G4double U = 0.0;
00784     G4double W = 0.0;
00785 
00786     for(G4int l = 0; l < 4; l++) {
00787       G4double V = 0.0;
00788 
00789       for(G4int im = 0; im < 4; im++) {
00790         V += abn[im][l][K+J-1] * std::pow(ekin, im);
00791       };
00792 
00793       U += V;
00794       W += V * std::pow(S, l);
00795     };  
00796     ct = 2.0 * std::sqrt(S) * (W + (1.0 - U) * (S*S*S*S)) - 1.0;
00797   };
00798 
00799   if(itry == itry_max) {
00800 
00801     if(verboseLevel > 2){
00802       G4cout << " particleSCMmomentumFor2to3 -> itry = itry_max " << itry << G4endl;
00803     }
00804 
00805     ct = 2.0 * inuclRndm() - 1.0;
00806   };
00807 
00808   return generateWithFixedTheta(ct, pmod);
00809 }
00810 
00811 
00812 G4LorentzVector 
00813 G4ElementaryParticleCollider::sampleCMmomentumFor2to2(G4int is, G4int kw, 
00814                                                       G4double ekin, 
00815                                                       G4double pscm) const 
00816 {
00817   if (verboseLevel > 3)
00818     G4cout << " >>> G4ElementaryParticleCollider::sampleCMmomentumFor2to2" 
00819            << " is " << is << " kw " << kw << " ekin " << ekin << " pscm "
00820            << pscm << G4endl;
00821 
00822   G4double pA=0.0, pC=0.0, pCos=0.0, pFrac=0.0;         // Angular parameters
00823 
00824   // Arrays below are parameters for two-exponential sampling of angular
00825   // distributions of two-body scattering in the specified channels
00826 
00827   if (is == 1 || is == 2 || is == 4 ||
00828       is == 21 || is == 23 || is == 25 || is == 27 || is ==29 || is == 31 ||
00829       is == 42 || is == 46 || is == 50 || is == 54 || is ==58 || is == 62) {
00830     // nucleon-nucleon or hyperon-nucleon
00831     if (verboseLevel > 3) G4cout << " nucleon/hyperon elastic" << G4endl;
00832 
00833     static const G4double nnke[9] =  { 0.0,   0.44, 0.59,   0.80,   1.00,   2.24,   4.40,   6.15,  10.00};
00834     static const G4double nnA[9] =   { 0.0,   0.34, 2.51,   4.59,   4.2,    5.61,   6.38,   7.93,   8.7};
00835     static const G4double nnC[9] =   { 0.0,   0.0,  1.21,   1.54,   1.88,   1.24,   1.91,   4.04,   8.7};
00836     static const G4double nnCos[9] = {-1.0,  -1.0, 0.4226, 0.4226, 0.4384, 0.7193, 0.8788, 0.9164,  0.95};
00837     static const G4double nnFrac[9] = {1.0,   1.0, 0.4898, 0.7243, 0.7990, 0.8892, 0.8493, 0.9583,  1.0};
00838 
00839     static G4CascadeInterpolator<9> interp(nnke);       // Only need one!
00840     pA = interp.interpolate(ekin, nnA);
00841     pC = interp.interpolate(ekin, nnC);
00842     pCos = interp.interpolate(ekin, nnCos);
00843     pFrac = interp.interpolate(ekin, nnFrac);
00844 
00845   } else if (kw == 2 && (is == 9 || is == 18)) {
00846     // gamma p -> pi+ n, gamma p -> pi0 p, gamma p -> K Y (and isospin variants)
00847     // for now and due to lack of better data, use the gamma p -> pi+ n angular
00848     // distribution for all of these channels
00849     if (verboseLevel > 3)
00850       G4cout << " gamma-nucleon inelastic with 2-body final state" << G4endl;
00851 
00852     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};
00853     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};
00854     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};
00855     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};
00856     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};
00857 
00858     static G4CascadeInterpolator<10> interp(gnke);
00859     pA = interp.interpolate(ekin, gnA);
00860     pC = interp.interpolate(ekin, gnC);
00861     pCos = interp.interpolate(ekin, gnCos);
00862     pFrac = interp.interpolate(ekin, gnFrac);
00863 
00864   } else if (kw == 2) {
00865     // pi- p -> pi0 n, pi0 p -> pi+ n, pi- p -> K Y, pi0 p -> K Y (and isospin variants)
00866     // includes charge and strangeness exchange  
00867     if (verboseLevel > 3)
00868       G4cout << " pion-nucleon inelastic with 2-body final state " << G4endl;
00869 
00870     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};
00871     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};
00872     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};
00873     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};
00874     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};
00875 
00876     static G4CascadeInterpolator<10> interp(qxke);      // Only need one!
00877     pA = interp.interpolate(ekin, qxA);
00878     pC = interp.interpolate(ekin, qxC);
00879     pCos = interp.interpolate(ekin, qxCos);
00880     pFrac = interp.interpolate(ekin, qxFrac);
00881 
00882   } else if (is == 3 || is == 7 || is == 9 || is == 11 || is == 17 ||
00883              is == 10 || is == 14 || is == 18 || is == 26 || is == 30) {
00884     // pi+p, pi0p, gammap, k+p, k0bp, pi-n, pi0n, gamman, k-n, or k0n
00885     if (verboseLevel > 3) G4cout << " meson-nucleon elastic (1)" << G4endl;
00886 
00887     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};
00888     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};
00889     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};
00890     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};
00891     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};
00892 
00893     static G4CascadeInterpolator<10> interp(hn1ke);     // Only need one!
00894     pA = interp.interpolate(ekin, hn1A);
00895     pC = interp.interpolate(ekin, hn1C);
00896     pCos = interp.interpolate(ekin, hn1Cos);
00897     pFrac = interp.interpolate(ekin, hn1Frac);
00898 
00899   } else if (is == 5 || is == 6 || is == 13 || is == 34 || is == 22 ||
00900              is == 15) {
00901     // pi-p, pi+n, k-p, k0bn, k+n, or k0p
00902     if (verboseLevel > 3) G4cout << " meson-nucleon elastic (2)" << G4endl;
00903 
00904     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};
00905     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};
00906     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};
00907     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};
00908     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};
00909 
00910     static G4CascadeInterpolator<10> interp(hn2ke);     // Only need one!
00911     pA = interp.interpolate(ekin, hn2A);
00912     pC = interp.interpolate(ekin, hn2C);
00913     pCos = interp.interpolate(ekin, hn2Cos);
00914     pFrac = interp.interpolate(ekin, hn2Frac);
00915 
00916   } else {
00917     if (verboseLevel)
00918       G4cerr << " G4ElementaryParticleCollider::sampleCMmomentumFor2to2:"
00919              << " interaction is=" << is << " not recognized " << G4endl;
00920   } 
00921 
00922   // Bound parameters by their physical ranges
00923   pCos = std::max(-1.,std::min(pCos,1.));
00924   pFrac = std::max(0.,std::min(pFrac,1.));
00925 
00926   // Use parameters determined above to get polar angle
00927   G4double ct = sampleCMcosFor2to2(pscm, pFrac, pA, pC, pCos);
00928 
00929   return generateWithFixedTheta(ct, pscm);
00930 }
00931 
00932 
00933 G4double
00934 G4ElementaryParticleCollider::sampleCMcosFor2to2(G4double pscm, G4double pFrac,
00935                                                  G4double pA, G4double pC,
00936                                                  G4double pCos) const 
00937 {
00938   if (verboseLevel>3) {
00939     G4cout << " sampleCMcosFor2to2: pscm " << pscm << " pFrac " << pFrac
00940            << " pA " << pA << " pC " << pC << " pCos " << pCos << G4endl;
00941   }
00942 
00943   G4bool smallAngle = (G4UniformRand() < pFrac);        // 0 < theta < theta0
00944 
00945   G4double term1 = 2.0 * pscm*pscm * (smallAngle ? pA : pC);
00946 
00947   if (std::abs(term1) < 1e-7) return 1.0;       // No actual scattering here!
00948   if (term1 > DBL_MAX_EXP) return 1.0;
00949 
00950   G4double term2 = std::exp(-2.0*term1);
00951   G4double randScale = (std::exp(-term1*(1.0 - pCos)) - term2)/(1.0 - term2);
00952 
00953   G4double randVal;
00954   if (smallAngle) randVal = (1.0 - randScale)*G4UniformRand() + randScale;
00955   else randVal = randScale*G4UniformRand();
00956 
00957   G4double costheta = 1.0 + std::log(randVal*(1.0 - term2) + term2)/term1;
00958 
00959   if (verboseLevel>3) {
00960     G4cout << " term1 " << term1 << " term2 " << term2 << " randVal "
00961            << randVal << " => costheta " << costheta << G4endl;
00962   }
00963 
00964   return costheta;
00965 }
00966 
00967 
00968 void
00969 G4ElementaryParticleCollider::generateSCMpionAbsorption(G4double etot_scm,
00970                                      G4InuclElementaryParticle* particle1,
00971                                      G4InuclElementaryParticle* particle2) {
00972   if (verboseLevel > 3)
00973     G4cout << " >>> G4ElementaryParticleCollider::generateSCMpionAbsorption" 
00974            << G4endl;
00975 
00976   // generate nucleons momenta for pion or photon absorption
00977   // the nucleon distribution assumed to be isotropic in SCM
00978 
00979   particles.clear();            // Initialize buffers for this event
00980   particles.resize(2);
00981 
00982   particle_kinds.clear();
00983 
00984   G4int type1 = particle1->type();
00985   G4int type2 = particle2->type();
00986 
00987   // generate kinds
00988 
00989   if (type1 == pionPlus) {
00990     if (type2 == diproton) {            // pi+ + PP -> ? 
00991       G4cerr << " pion absorption: pi+ + PP -> ? " << G4endl;
00992       return;
00993     } else if (type2 == unboundPN) {    // pi+ + PN -> PP
00994       particle_kinds.push_back(proton);
00995       particle_kinds.push_back(proton);
00996     } else if (type2 == dineutron) {    // pi+ + NN -> PN
00997       particle_kinds.push_back(proton);
00998       particle_kinds.push_back(neutron);
00999     }
01000   } else if (type1 == pionMinus) { 
01001     if (type2 == diproton) {            // pi- + PP -> PN 
01002       particle_kinds.push_back(proton);
01003       particle_kinds.push_back(neutron);
01004     } else if (type2 == unboundPN) {     // pi- + PN -> NN
01005       particle_kinds.push_back(neutron);
01006       particle_kinds.push_back(neutron);
01007     } else if (type2 == dineutron) {    // pi- + NN -> ?
01008       G4cerr << " pion absorption: pi- + NN -> ? " << G4endl;
01009       return;
01010     }
01011   } else if (type1 == pionZero || type1 == photon) {
01012     if (type2 == diproton) {            // pi0/gamma + PP -> PP 
01013       particle_kinds.push_back(proton);
01014       particle_kinds.push_back(proton);
01015     } else if (type2 == unboundPN) {    // pi0/gamma + PN -> PN
01016       particle_kinds.push_back(proton);
01017       particle_kinds.push_back(neutron);
01018     } else if (type2 == dineutron) {    // pi0/gamma + NN -> ?
01019       particle_kinds.push_back(neutron);
01020       particle_kinds.push_back(neutron);
01021     }
01022   }
01023     
01024   G4InuclElementaryParticle dummy;
01025 
01026   G4double mone = dummy.getParticleMass(particle_kinds[0]);
01027   G4double m1sq = mone*mone;
01028 
01029   G4double mtwo = dummy.getParticleMass(particle_kinds[1]);
01030   G4double m2sq = mtwo*mtwo;
01031 
01032   G4double a = 0.5 * (etot_scm * etot_scm - m1sq - m2sq);
01033 
01034   G4double pmod = std::sqrt((a * a - m1sq * m2sq) / (m1sq + m2sq + 2.0 * a));
01035   G4LorentzVector mom1 = generateWithRandomAngles(pmod, mone);
01036   G4LorentzVector mom2;
01037   mom2.setVectM(-mom1.vect(), mtwo);
01038 
01039   particles[0].fill(mom1, particle_kinds[0], G4InuclParticle::EPCollider);
01040   particles[1].fill(mom2, particle_kinds[1], G4InuclParticle::EPCollider);
01041 
01042   return;
01043 }
01044 
01045 
01046 // Dump lookup tables for N-body final states
01047 
01048 void G4ElementaryParticleCollider::
01049 printFinalStateTables(std::ostream& os) const {
01050   G4CascadeChannelTables::PrintTable(pro*pro, os);
01051   G4CascadeChannelTables::PrintTable(neu*pro, os);
01052   G4CascadeChannelTables::PrintTable(neu*neu, os);
01053   G4CascadeChannelTables::PrintTable(kmi*neu, os);
01054   G4CascadeChannelTables::PrintTable(kmi*pro, os);
01055   G4CascadeChannelTables::PrintTable(kpl*neu, os);
01056   G4CascadeChannelTables::PrintTable(kpl*pro, os);
01057   G4CascadeChannelTables::PrintTable(k0b*neu, os);
01058   G4CascadeChannelTables::PrintTable(k0b*pro, os);
01059   G4CascadeChannelTables::PrintTable(k0*neu, os);
01060   G4CascadeChannelTables::PrintTable(k0*pro, os);
01061   G4CascadeChannelTables::PrintTable(lam*neu, os);
01062   G4CascadeChannelTables::PrintTable(lam*pro, os);
01063   G4CascadeChannelTables::PrintTable(pim*neu, os);
01064   G4CascadeChannelTables::PrintTable(pim*pro, os);
01065   G4CascadeChannelTables::PrintTable(pip*neu, os);
01066   G4CascadeChannelTables::PrintTable(pip*pro, os);
01067   G4CascadeChannelTables::PrintTable(pi0*neu, os);
01068   G4CascadeChannelTables::PrintTable(pi0*pro, os);
01069   G4CascadeChannelTables::PrintTable(sm*neu, os);
01070   G4CascadeChannelTables::PrintTable(sm*pro, os);
01071   G4CascadeChannelTables::PrintTable(sp*neu, os);
01072   G4CascadeChannelTables::PrintTable(sp*pro, os);
01073   G4CascadeChannelTables::PrintTable(s0*neu, os);
01074   G4CascadeChannelTables::PrintTable(s0*pro, os);
01075   G4CascadeChannelTables::PrintTable(xim*neu, os);
01076   G4CascadeChannelTables::PrintTable(xim*pro, os);
01077   G4CascadeChannelTables::PrintTable(xi0*neu, os);
01078   G4CascadeChannelTables::PrintTable(xi0*pro, os);
01079 
01080   os << " * * * PRELIMINARY -- GAMMA-NUCLEON TABLES * * *" << G4endl;
01081   G4CascadeChannelTables::PrintTable(gam*neu, os);
01082   G4CascadeChannelTables::PrintTable(gam*pro, os);
01083 }
01084 
01085 
01086 // Parameter array for momentum calculation of many body final states
01087 const G4double G4ElementaryParticleCollider::rmn[14][10][2] = {
01088   {{0.5028,   0.6305}, {3.1442, -3.7333}, {-7.8172,  13.464}, {8.1667, -18.594}, 
01089    {1.6208,   1.9439}, {-4.3139, -4.6268}, {12.291,  9.7879}, {-15.288, -9.6074}, 
01090    {   0.0,     0.0}, {   0.0,      0.0}},     
01091 
01092   {{0.9348,   2.1801}, {-10.59,  1.5163}, { 29.227,  -16.38}, {-34.55,  27.944}, 
01093    {-0.2009, -0.3464}, {1.3641,   1.1093}, {-3.403, -1.9313}, { 3.8559,  1.7064}, 
01094    {   0.0,     0.0}, {    0.0,     0.0}},    
01095   
01096   {{-0.0967, -1.2886}, {4.7335,  -2.457}, {-14.298,  15.129}, {17.685, -23.295}, 
01097    { 0.0126,  0.0271}, {-0.0835, -0.1164}, { 0.186,  0.2697}, {-0.2004, -0.3185}, 
01098    {   0.0,     0.0}, {    0.0,     0.0}},    
01099   
01100   {{-0.025,   0.2091}, {-0.6248, 0.5228}, { 2.0282, -2.8687}, {-2.5895, 4.2688}, 
01101    {-0.0002, -0.0007}, {0.0014,   0.0051}, {-0.0024, -0.015}, { 0.0022,  0.0196}, 
01102    {    0.0,    0.0}, {    0.0,     0.0}},     
01103   
01104   {{1.1965,   0.9336}, {-0.8289,-1.8181}, { 1.0426,  5.5157}, { -1.909,-8.5216}, 
01105    { 1.2419,  1.8693}, {-4.3633, -5.5678}, { 13.743, 14.795}, {-18.592, -16.903}, 
01106    {    0.0,    0.0}, {    0.0,     0.0}},     
01107   
01108   {{0.287,    1.7811}, {-4.9065,-8.2927}, { 16.264,  20.607}, {-19.904,-20.827}, 
01109    {-0.244,  -0.4996}, {1.3158,   1.7874}, {-3.5691, -4.133}, { 4.3867,  3.8393}, 
01110    {    0.0,    0.0}, {   0.0,      0.0}}, 
01111   
01112   {{-0.2449, -1.5264}, { 2.9191, 6.8433}, {-9.5776, -16.067}, { 11.938, 16.845}, 
01113    {0.0157,   0.0462}, {-0.0826, -0.1854}, { 0.2143, 0.4531}, {-0.2585, -0.4627}, 
01114    {    0.0,    0.0}, {   0.0,      0.0}},
01115   
01116   {{0.0373,   0.2713}, {-0.422, -1.1944}, { 1.3883,  2.7495}, {-1.7476,-2.9045}, 
01117    {-0.0003, -0.0013}, {0.0014,   0.0058}, {-0.0034,-0.0146}, { 0.0039,  0.0156}, 
01118    {    0.0,    0.0}, {    0.0,     0.0}},     
01119   
01120   {{   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, {    0.0,     0.0},
01121    {    0.0,     0.0}, {   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, 
01122    { 0.1451,  0.0929},{ 0.1538,  0.1303}},  
01123   
01124   {{   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, {    0.0,     0.0},
01125    {    0.0,     0.0}, {   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, 
01126    { 0.4652,  0.5389},{ 0.2744,  0.4071}},  
01127   
01128   {{   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, {    0.0,     0.0},
01129    {    0.0,     0.0}, {   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0},
01130    { -0.033, -0.0545},{-0.0146, -0.0288}},  
01131   
01132   {{   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, {    0.0,     0.0},
01133    {    0.0,     0.0}, {   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0},
01134    { 0.6296,  0.1491},{ 0.8381,  0.1802}},  
01135   
01136   {{   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, {    0.0,     0.0},
01137    {    0.0,     0.0}, {   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0},
01138    { 0.1787,   0.385},{ 0.0086,  0.3302}},  
01139   
01140   {{   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0}, {    0.0,     0.0},
01141    {    0.0,     0.0}, {   0.0,      0.0}, {    0.0,    0.0}, {    0.0,     0.0},
01142    {-0.0026, -0.0128},{ 0.0033, -0.0094}}
01143 };
01144 
01145 const G4double G4ElementaryParticleCollider::abn[4][4][4] = {
01146   {{0.0856,  0.0716,  0.1729,  0.0376},  {5.0390,  3.0960,  7.1080,  1.4331},
01147    {-13.782, -11.125, -17.961, -3.1350},  {14.661,  18.130,  16.403,  6.4864}},
01148   {{0.0543,  0.0926, -0.1450,  0.2383}, {-9.2324, -3.2186, -13.032,  1.8253},
01149    {36.397,  20.273,  41.781,  1.7648}, {-42.962, -33.245, -40.799, -16.735}},
01150   {{-0.0511, -0.0515,  0.0454, -0.1541}, {4.6003,  0.8989,  8.3515, -1.5201},
01151    {-20.534, -7.5084, -30.260, -1.5692},  {27.731,  13.188,  32.882,  17.185}},
01152   {{0.0075,  0.0058, -0.0048,  0.0250}, {-0.6253, -0.0017, -1.4095,  0.3059},
01153    {2.9159,  0.7022,  5.3505,  0.3252}, {-4.1101, -1.4854, -6.0946, -3.5277}} 
01154 };

Generated on Mon May 27 17:48:07 2013 for Geant4 by  doxygen 1.4.7