35#define INCLXX_IN_GEANT4_MODE 1
51 const NaturalIsotopicDistributions *ParticleTable::theNaturalIsotopicDistributions = NULL;
60 const G4double ParticleTable::theINCLNucleonMass = 938.2796;
61 const G4double ParticleTable::theINCLPionMass = 138.0;
62 G4double ParticleTable::protonMass = 0.0;
63 G4double ParticleTable::neutronMass = 0.0;
64 G4double ParticleTable::piPlusMass = 0.0;
65 G4double ParticleTable::piMinusMass = 0.0;
66 G4double ParticleTable::piZeroMass = 0.0;
72 G4double ParticleTable::theRealProtonMass = 938.27203;
73 G4double ParticleTable::theRealNeutronMass = 939.56536;
74 G4double ParticleTable::theRealChargedPiMass = 139.57018;
75 G4double ParticleTable::theRealPiZeroMass = 134.9766;
77 const G4double ParticleTable::mediumDiffuseness[mediumNucleiTableSize] =
78 {0.0,0.0,0.0,0.0,0.0,1.78,1.77,1.77,1.77,1.71,
79 1.69,1.69,1.635,1.730,1.81,1.833,1.798,
80 1.841,0.567,0.571, 0.560,0.549,0.550,0.551,
81 0.580,0.575,0.569,0.537,0.0,0.0};
82 const G4double ParticleTable::mediumRadius[mediumNucleiTableSize] =
83 {0.0,0.0,0.0,0.0,0.0,0.334,0.327,0.479,0.631,0.838,
84 0.811,1.07,1.403,1.335,1.25,1.544,1.498,1.513,
85 2.58,2.77, 2.775,2.78,2.88,2.98,3.22,3.03,2.84,
87 const G4double ParticleTable::positionRMS[clusterTableZSize][clusterTableASize] = {
89 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
90 {0.00, 0.00, 2.10, 1.80, 1.70, 1.83, 2.60, 2.50, 0.00, 0.00, 0.00, 0.00, 0.00},
91 {0.00, 0.00, 0.00, 1.80, 1.68, 1.70, 2.60, 2.50, 2.50, 2.50, 2.50, 0.00, 0.00},
92 {0.00, 0.00, 0.00, 0.00, 1.70, 1.83, 2.56, 2.40, 2.50, 2.50, 2.50, 2.50, 2.50},
93 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.60, 2.50, 2.50, 2.51, 2.50, 2.50, 2.50},
94 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50, 2.50, 2.50, 2.50, 2.45, 2.40, 2.50},
95 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50, 2.50, 2.50, 2.50, 2.47},
96 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50, 2.50, 2.50},
97 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50}
100 const G4double ParticleTable::momentumRMS[clusterTableZSize][clusterTableASize] = {
102 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
103 {0.00, 0.00, 77.0, 110., 153., 100., 100., 100., 0.00, 0.00, 0.00, 0.00, 0.00},
104 {0.00, 0.00, 0.00, 110., 153., 100., 100., 100., 100., 100., 100., 0.00, 0.00},
105 {0.00, 0.00, 0.00, 0.00, 153., 100., 100., 100., 100., 100., 100., 100., 100.},
106 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100., 100., 100.},
107 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100., 100., 100.},
108 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100.},
109 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100.},
110 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100.}
114 const std::string ParticleTable::elementTable[elementTableSize] = {
231 const std::string ParticleTable::elementIUPACDigits =
"nubtqphsoe";
245 {StableCluster, StableCluster, NeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
246 {StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
247 {StableCluster, StableCluster, ProtonDecay, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound},
248 {StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay},
249 {StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, TwoProtonDecay, StableCluster, AlphaDecay, StableCluster, StableCluster, StableCluster, StableCluster},
250 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, TwoProtonDecay, ProtonDecay, StableCluster, ProtonDecay, StableCluster, StableCluster, StableCluster},
251 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, TwoProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster},
252 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster},
253 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay}
274 0.0082645, 0.0069444};
276 const G4int ParticleTable::clusterZMin[maxClusterMass+1] = {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3};
277 const G4int ParticleTable::clusterZMax[maxClusterMass+1] = {0, 0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8};
289 ParticleTable::theRealNeutronMass + ParticleTable::theRealChargedPiMass
291 const G4double ParticleTable::theINCLProtonSeparationEnergy = 6.83;
292 const G4double ParticleTable::theINCLNeutronSeparationEnergy = ParticleTable::theINCLProtonSeparationEnergy;
293 G4double ParticleTable::protonSeparationEnergy = theINCLProtonSeparationEnergy;
294 G4double ParticleTable::neutronSeparationEnergy = theINCLNeutronSeparationEnergy;
296#ifdef INCLXX_IN_GEANT4_MODE
299 std::vector< std::vector <G4bool> > ParticleTable::massTableMask;
300 std::vector< std::vector <G4double> > ParticleTable::massTable;
304 protonMass = theINCLNucleonMass;
305 neutronMass = theINCLNucleonMass;
306 piPlusMass = theINCLPionMass;
307 piMinusMass = theINCLPionMass;
308 piZeroMass = theINCLPionMass;
310#ifndef INCLXX_IN_GEANT4_MODE
311 std::string dataFilePath;
314 readRealMasses(dataFilePath);
324#ifdef INCLXX_IN_GEANT4_MODE
369 ERROR(
"Requested isospin of an unknown particle!");
388 std::stringstream stream;
394 std::stringstream stream;
403 return std::string(
"proton");
405 return std::string(
"neutron");
407 return std::string(
"delta++");
409 return std::string(
"delta+");
411 return std::string(
"delta0");
413 return std::string(
"delta-");
415 return std::string(
"pi+");
417 return std::string(
"pi0");
419 return std::string(
"pi-");
421 return std::string(
"composite");
423 return std::string(
"unknown");
428 return std::string(
"p");
430 return std::string(
"n");
432 return std::string(
"d++");
434 return std::string(
"d+");
436 return std::string(
"d0");
438 return std::string(
"d-");
440 return std::string(
"pi+");
442 return std::string(
"pi0");
444 return std::string(
"pi-");
446 return std::string(
"comp");
448 return std::string(
"unknown");
463 ERROR(
"ParticleTable::getMass : Unknown particle type." << std::endl);
471 return theRealProtonMass;
474 return theRealNeutronMass;
478 return theRealChargedPiMass;
481 return theRealPiZeroMass;
484 ERROR(
"Particle::getRealMass : Unknown particle type." << std::endl);
502#ifndef INCLXX_IN_GEANT4_MODE
503 if(ParticleTable::hasMassTable(A,Z))
504 return ParticleTable::massTable.at(Z).at(A);
506 DEBUG(
"Real mass unavailable for isotope A=" << A <<
", Z=" << Z
507 <<
", using Weizsaecker's formula"
509 return getWeizsaeckerMass(A,Z);
526 return Z*(protonMass - protonSeparationEnergy) + (A-Z)*(neutronMass - neutronSeparationEnergy);
527 else if(A==1 && Z==0)
529 else if(A==1 && Z==1)
537 if(A >= 19 || (A < 6 && A >= 2)) {
542 const G4double thisRMS = positionRMS[Z][A];
546 ERROR(
"ParticleTable::getRadiusParameter : Radius for nucleus A = " << A <<
" Z = " << Z <<
" is ==0.0" << std::endl);
554 return 1.581*theDiffusenessParameter*
555 (2.+5.*theRadiusParameter)/(2.+3.*theRadiusParameter);
557 ERROR(
"ParticleTable::getNuclearRadius: No radius for nucleus A = " << A <<
" Z = " << Z << std::endl);
566 return (2.745e-4 * A + 1.063) * std::pow(A, 1.0/3.0);
567 }
else if(A < 6 && A >= 2) {
569 const G4double thisRMS = positionRMS[Z][A];
573 ERROR(
"ParticleTable::getRadiusParameter : Radius for nucleus A = " << A <<
" Z = " << Z <<
" is ==0.0" << std::endl);
577 ERROR(
"ParticleTable::getRadiusParameter : No radius for nucleus A = " << A <<
" Z = " << Z << std::endl);
580 }
else if(A < 28 && A >= 6) {
581 return mediumRadius[A-1];
584 ERROR(
"ParticleTable::getRadiusParameter: No radius for nucleus A = " << A <<
" Z = " << Z << std::endl);
593 }
else if(A < 19 && A >= 6) {
594 return 5.5 + 0.3 * (
G4double(A) - 6.0)/12.0;
598 ERROR(
"ParticleTable::getMaximumNuclearRadius : No maximum radius for nucleus A = " << A <<
" Z = " << Z << std::endl);
603#ifdef INCLXX_IN_GEANT4_MODE
610 return 1.63e-4 * A + 0.510;
611 }
else if(A < 28 && A >= 19) {
612 return mediumDiffuseness[A-1];
613 }
else if(A < 19 && A >= 6) {
614 return mediumDiffuseness[A-1];
615 }
else if(A < 6 && A >= 2) {
616 ERROR(
"ParticleTable::getSurfaceDiffuseness: was called for A = " << A <<
" Z = " << Z << std::endl);
619 ERROR(
"ParticleTable::getSurfaceDiffuseness: No diffuseness for nucleus A = " << A <<
" Z = " << Z << std::endl);
626 WARN(
"getElementName called with Z<1" << std::endl);
627 return elementTable[0];
629 return elementTable[Z];
634#ifndef INCLXX_IN_GEANT4_MODE
635 void ParticleTable::readRealMasses(std::string
const &path) {
637 massTableMask.clear();
641 std::string fileName(path +
"/walletlifetime.dat");
642 DEBUG(
"Reading real nuclear masses from file " << fileName << std::endl);
645 std::ifstream massTableIn(fileName.c_str());
646 if(!massTableIn.good()) {
647 FATAL(
"Cannot open " << fileName <<
" data file." << std::endl);
648 std::exit(EXIT_FAILURE);
657 massTableIn >> A >> Z >> excess;
660 if(Z>=massTable.size()) {
661 massTable.resize(Z+1);
662 massTableMask.resize(Z+1);
664 if(A>=massTable[Z].size()) {
665 massTable[Z].resize(A+1, 0.);
666 massTableMask[Z].resize(A+1,
false);
669 massTable.at(Z).at(A) = A*amu + excess - Z*eMass;
670 massTableMask.at(Z).at(A) =
true;
672 massTableIn >> A >> Z >> excess;
673 }
while(massTableIn.good());
679 std::stringstream elementStream;
681 std::string elementName = elementStream.str();
682 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::intToIUPAC);
683 elementName[0] = std::toupper(elementName.at(0));
689 std::string elementName(s);
690 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
692 if(elementName.find_first_not_of(elementIUPACDigits)!=std::string::npos)
694 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::iupacToInt);
695 std::stringstream elementStream(elementName);
SeparationEnergyType getSeparationEnergyType() const
Get the separation-energy type.
std::string const & getINCLXXDataFilePath() const
G4bool getUseRealMasses() const
Whether to use real masses.
static const G4double clusterPosFact2[maxClusterMass+1]
static G4double getINCLMass(const G4int A, const G4int Z)
Get INCL nuclear mass (in MeV/c^2)
static NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
static const G4int clusterZMin[maxClusterMass+1]
static const G4double eSquared
Coulomb conversion factor, in MeV*fm.
static G4double getRadiusParameter(const G4int A, const G4int Z)
static void initialize(Config const *const theConfig=0)
Initialize the particle table.
static const G4double effectiveDeltaMass
static SeparationEnergyFn getSeparationEnergy
Static pointer to the separation-energy function.
static ParticleMassFn getTableParticleMass
Static pointer to the mass function for particles.
static const G4double clusterPosFact[maxClusterMass+1]
static const G4int clusterTableZSize
static G4double getNuclearRadius(const G4int A, const G4int Z)
G4double(* NuclearMassFn)(const G4int, const G4int)
static G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
static G4IonTable * theG4IonTable
G4double(* ParticleMassFn)(const ParticleType)
static G4double getMaximumNuclearRadius(const G4int A, const G4int Z)
static const G4double effectiveDeltaDecayThreshold
static G4double getSeparationEnergyReal(const ParticleType t, const G4int A, const G4int Z)
Return the real separation energy.
static G4int parseIUPACElement(std::string const &pS)
Parse a IUPAC element name.
static std::string getName(const ParticleType t)
Get the native INCL name of the particle.
G4double(* SeparationEnergyFn)(const ParticleType, const G4int, const G4int)
static const G4int elementTableSize
static const G4double effectiveNucleonMass2
static std::string getIUPACElementName(const G4int Z)
Get the name of an unnamed element from the IUPAC convention.
static G4double getSeparationEnergyRealForLight(const ParticleType t, const G4int A, const G4int Z)
Return the real separation energy only for light nuclei.
static G4int getIsospin(const ParticleType t)
Get the isospin of a particle.
static const G4double effectiveNucleonMass
static const G4double effectivePionMass
static const G4int clusterTableASize
static const G4double clusterPhaseSpaceCut[maxClusterMass+1]
static const G4int clusterZMax[maxClusterMass+1]
static G4double getSeparationEnergyINCL(const ParticleType t, const G4int, const G4int)
Return INCL's default separation energy.
static std::string getShortName(const ParticleType t)
Get the short INCL name of the particle.
static G4double getSurfaceDiffuseness(const G4int A, const G4int Z)
static std::string getElementName(const G4int Z)
Get the name of the element from the atomic number.
static const ClusterDecayType clusterDecayMode[clusterTableZSize][clusterTableASize]
G4double GetNucleusMass(G4int Z, G4int A, G4int L=0) const
G4double GetPDGMass() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
G4IonTable * GetIonTable()
@ RealForLightSeparationEnergy