33 #define INCLXX_IN_GEANT4_MODE 1
44 #ifdef INCLXX_IN_GEANT4_MODE
52 const NaturalIsotopicDistributions *ParticleTable::theNaturalIsotopicDistributions = NULL;
61 const G4double ParticleTable::theINCLNucleonMass = 938.2796;
62 const G4double ParticleTable::theINCLPionMass = 138.0;
63 G4double ParticleTable::protonMass = 0.0;
64 G4double ParticleTable::neutronMass = 0.0;
65 G4double ParticleTable::piPlusMass = 0.0;
66 G4double ParticleTable::piMinusMass = 0.0;
67 G4double ParticleTable::piZeroMass = 0.0;
73 G4double ParticleTable::theRealProtonMass = 938.27203;
74 G4double ParticleTable::theRealNeutronMass = 939.56536;
75 G4double ParticleTable::theRealChargedPiMass = 139.57018;
76 G4double ParticleTable::theRealPiZeroMass = 134.9766;
78 const G4double ParticleTable::mediumDiffuseness[mediumNucleiTableSize] =
79 {0.0,0.0,0.0,0.0,0.0,1.78,1.77,1.77,1.77,1.71,
80 1.69,1.69,1.635,1.730,1.81,1.833,1.798,
81 1.841,0.567,0.571, 0.560,0.549,0.550,0.551,
82 0.580,0.575,0.569,0.537,0.0,0.0};
83 const G4double ParticleTable::mediumRadius[mediumNucleiTableSize] =
84 {0.0,0.0,0.0,0.0,0.0,0.334,0.327,0.479,0.631,0.838,
85 0.811,1.07,1.403,1.335,1.25,1.544,1.498,1.513,
86 2.58,2.77, 2.775,2.78,2.88,2.98,3.22,3.03,2.84,
88 const G4double ParticleTable::positionRMS[clusterTableZSize][clusterTableASize] = {
90 {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},
91 {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},
92 {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},
93 {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},
94 {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},
95 {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},
96 {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},
97 {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},
98 {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}
101 const G4double ParticleTable::momentumRMS[clusterTableZSize][clusterTableASize] = {
103 {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},
104 {0.00, 0.00, 77.0, 110., 153., 100., 100., 100., 0.00, 0.00, 0.00, 0.00, 0.00},
105 {0.00, 0.00, 0.00, 110., 153., 100., 100., 100., 100., 100., 100., 0.00, 0.00},
106 {0.00, 0.00, 0.00, 0.00, 153., 100., 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, 100., 100., 100., 100., 100., 100., 100.},
109 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100.},
110 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100.},
111 {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.}
115 const std::string ParticleTable::elementTable[elementTableSize] = {
232 const std::string ParticleTable::elementIUPACDigits =
"nubtqphsoe";
246 {StableCluster, StableCluster, NeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
247 {StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
248 {StableCluster, StableCluster, ProtonDecay, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound},
249 {StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay},
250 {StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, TwoProtonDecay, StableCluster, AlphaDecay, StableCluster, StableCluster, StableCluster, StableCluster},
251 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, TwoProtonDecay, ProtonDecay, StableCluster, ProtonDecay, StableCluster, StableCluster, StableCluster},
252 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, TwoProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster},
253 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster},
254 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay}
275 0.0082645, 0.0069444};
277 const G4int ParticleTable::clusterZMin[maxClusterMass+1] = {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3};
278 const G4int ParticleTable::clusterZMax[maxClusterMass+1] = {0, 0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8};
290 ParticleTable::theRealNeutronMass + ParticleTable::theRealChargedPiMass
292 const G4double ParticleTable::theINCLProtonSeparationEnergy = 6.83;
293 const G4double ParticleTable::theINCLNeutronSeparationEnergy = ParticleTable::theINCLProtonSeparationEnergy;
294 G4double ParticleTable::protonSeparationEnergy = theINCLProtonSeparationEnergy;
295 G4double ParticleTable::neutronSeparationEnergy = theINCLNeutronSeparationEnergy;
297 #ifdef INCLXX_IN_GEANT4_MODE
300 std::vector< std::vector <G4bool> > ParticleTable::massTableMask;
301 std::vector< std::vector <G4double> > ParticleTable::massTable;
305 protonMass = theINCLNucleonMass;
306 neutronMass = theINCLNucleonMass;
307 piPlusMass = theINCLPionMass;
308 piMinusMass = theINCLPionMass;
309 piZeroMass = theINCLPionMass;
311 #ifndef INCLXX_IN_GEANT4_MODE
312 std::string dataFilePath;
315 readRealMasses(dataFilePath);
325 #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.745
e-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
607 #endif // 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);
656 massTableIn >> A >> Z >> excess;
659 if(Z>=massTable.size()) {
660 massTable.resize(Z+1);
661 massTableMask.resize(Z+1);
663 if(A>=massTable[Z].size()) {
664 massTable[
Z].resize(A+1, 0.);
665 massTableMask[
Z].resize(A+1,
false);
668 massTable.at(Z).at(A) = A*amu + excess - Z*eMass;
669 massTableMask.at(Z).at(A) =
true;
671 massTableIn >> A >> Z >> excess;
672 }
while(massTableIn.good());
678 std::stringstream elementStream;
680 std::string elementName = elementStream.str();
681 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::intToIUPAC);
682 elementName[0] = std::toupper(elementName.at(0));
688 std::string elementName(s);
689 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
691 if(elementName.find_first_not_of(elementIUPACDigits)!=std::string::npos)
693 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::iupacToInt);
694 std::stringstream elementStream(elementName);