00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #define INCLXX_IN_GEANT4_MODE 1
00034
00035 #include "globals.hh"
00036
00037 #include "G4INCLParticleTable.hh"
00038 #include <algorithm>
00039
00040 #include <cmath>
00041 #include <cctype>
00042 #include <sstream>
00043
00044 #ifdef INCLXX_IN_GEANT4_MODE
00045 #include "G4PhysicalConstants.hh"
00046 #include "G4SystemOfUnits.hh"
00047 #endif
00048
00049 namespace G4INCL {
00050
00052 const NaturalIsotopicDistributions *ParticleTable::theNaturalIsotopicDistributions = NULL;
00053
00055 ParticleTable::NuclearMassFn ParticleTable::getTableMass;
00057 ParticleTable::ParticleMassFn ParticleTable::getTableParticleMass;
00059 ParticleTable::SeparationEnergyFn ParticleTable::getSeparationEnergy;
00060
00061 const G4double ParticleTable::theINCLNucleonMass = 938.2796;
00062 const G4double ParticleTable::theINCLPionMass = 138.0;
00063 G4double ParticleTable::protonMass = 0.0;
00064 G4double ParticleTable::neutronMass = 0.0;
00065 G4double ParticleTable::piPlusMass = 0.0;
00066 G4double ParticleTable::piMinusMass = 0.0;
00067 G4double ParticleTable::piZeroMass = 0.0;
00068
00069
00070 const G4double ParticleTable::eSquared = 1.439964;
00071
00072
00073 G4double ParticleTable::theRealProtonMass = 938.27203;
00074 G4double ParticleTable::theRealNeutronMass = 939.56536;
00075 G4double ParticleTable::theRealChargedPiMass = 139.57018;
00076 G4double ParticleTable::theRealPiZeroMass = 134.9766;
00077
00078 const G4double ParticleTable::mediumDiffuseness[mediumNucleiTableSize] =
00079 {0.0,0.0,0.0,0.0,0.0,1.78,1.77,1.77,1.77,1.71,
00080 1.69,1.69,1.635,1.730,1.81,1.833,1.798,
00081 1.841,0.567,0.571, 0.560,0.549,0.550,0.551,
00082 0.580,0.575,0.569,0.537,0.0,0.0};
00083 const G4double ParticleTable::mediumRadius[mediumNucleiTableSize] =
00084 {0.0,0.0,0.0,0.0,0.0,0.334,0.327,0.479,0.631,0.838,
00085 0.811,1.07,1.403,1.335,1.25,1.544,1.498,1.513,
00086 2.58,2.77, 2.775,2.78,2.88,2.98,3.22,3.03,2.84,
00087 3.14,0.0,0.0};
00088 const G4double ParticleTable::positionRMS[clusterTableZSize][clusterTableASize] = {
00089
00090 {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},
00091 {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},
00092 {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},
00093 {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},
00094 {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},
00095 {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},
00096 {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},
00097 {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},
00098 {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}
00099 };
00100
00101 const G4double ParticleTable::momentumRMS[clusterTableZSize][clusterTableASize] = {
00102
00103 {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},
00104 {0.00, 0.00, 77.0, 110., 153., 100., 100., 100., 0.00, 0.00, 0.00, 0.00, 0.00},
00105 {0.00, 0.00, 0.00, 110., 153., 100., 100., 100., 100., 100., 100., 0.00, 0.00},
00106 {0.00, 0.00, 0.00, 0.00, 153., 100., 100., 100., 100., 100., 100., 100., 100.},
00107 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100., 100., 100.},
00108 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100., 100., 100.},
00109 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100.},
00110 {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100.},
00111 {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.}
00112 };
00113
00115 const std::string ParticleTable::elementTable[elementTableSize] = {
00116 "",
00117 "H",
00118 "He",
00119 "Li",
00120 "Be",
00121 "B",
00122 "C",
00123 "N",
00124 "O",
00125 "F",
00126 "Ne",
00127 "Na",
00128 "Mg",
00129 "Al",
00130 "Si",
00131 "P",
00132 "S",
00133 "Cl",
00134 "Ar",
00135 "K",
00136 "Ca",
00137 "Sc",
00138 "Ti",
00139 "V",
00140 "Cr",
00141 "Mn",
00142 "Fe",
00143 "Co",
00144 "Ni",
00145 "Cu",
00146 "Zn",
00147 "Ga",
00148 "Ge",
00149 "As",
00150 "Se",
00151 "Br",
00152 "Kr",
00153 "Rb",
00154 "Sr",
00155 "Y",
00156 "Zr",
00157 "Nb",
00158 "Mo",
00159 "Tc",
00160 "Ru",
00161 "Rh",
00162 "Pd",
00163 "Ag",
00164 "Cd",
00165 "In",
00166 "Sn",
00167 "Sb",
00168 "Te",
00169 "I",
00170 "Xe",
00171 "Cs",
00172 "Ba",
00173 "La",
00174 "Ce",
00175 "Pr",
00176 "Nd",
00177 "Pm",
00178 "Sm",
00179 "Eu",
00180 "Gd",
00181 "Tb",
00182 "Dy",
00183 "Ho",
00184 "Er",
00185 "Tm",
00186 "Yb",
00187 "Lu",
00188 "Hf",
00189 "Ta",
00190 "W",
00191 "Re",
00192 "Os",
00193 "Ir",
00194 "Pt",
00195 "Au",
00196 "Hg",
00197 "Tl",
00198 "Pb",
00199 "Bi",
00200 "Po",
00201 "At",
00202 "Rn",
00203 "Fr",
00204 "Ra",
00205 "Ac",
00206 "Th",
00207 "Pa",
00208 "U",
00209 "Np",
00210 "Pu",
00211 "Am",
00212 "Cm",
00213 "Bk",
00214 "Cf",
00215 "Es",
00216 "Fm",
00217 "Md",
00218 "No",
00219 "Lr",
00220 "Rf",
00221 "Db",
00222 "Sg",
00223 "Bh",
00224 "Hs",
00225 "Mt",
00226 "Ds",
00227 "Rg",
00228 "Cn"
00229 };
00230
00232 const std::string ParticleTable::elementIUPACDigits = "nubtqphsoe";
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 const ParticleTable::ClusterDecayType ParticleTable::clusterDecayMode[clusterTableZSize][clusterTableASize] =
00244 {
00245
00246 {StableCluster, StableCluster, NeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
00247 {StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
00248 {StableCluster, StableCluster, ProtonDecay, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound},
00249 {StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay},
00250 {StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, TwoProtonDecay, StableCluster, AlphaDecay, StableCluster, StableCluster, StableCluster, StableCluster},
00251 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, TwoProtonDecay, ProtonDecay, StableCluster, ProtonDecay, StableCluster, StableCluster, StableCluster},
00252 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, TwoProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster},
00253 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster},
00254 {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay}
00255 };
00256
00260 const G4double ParticleTable::clusterPosFact[maxClusterMass+1] = {0.0, 1.0, 0.5,
00261 0.33333, 0.25,
00262 0.2, 0.16667,
00263 0.14286, 0.125,
00264 0.11111, 0.1,
00265 0.09091, 0.083333};
00266
00270 const G4double ParticleTable::clusterPosFact2[maxClusterMass+1] = {0.0, 1.0, 0.25,
00271 0.11111, 0.0625,
00272 0.04, 0.0277778,
00273 0.020408, 0.015625,
00274 0.012346, 0.01,
00275 0.0082645, 0.0069444};
00276
00277 const G4int ParticleTable::clusterZMin[maxClusterMass+1] = {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3};
00278 const G4int ParticleTable::clusterZMax[maxClusterMass+1] = {0, 0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8};
00279 const G4double ParticleTable::clusterPhaseSpaceCut[maxClusterMass+1] = {0.0, 70000.0, 180000.0,
00280 90000.0, 90000.0,
00281 128941.0 ,145607.0,
00282 161365.0, 176389.0,
00283 190798.0, 204681.0,
00284 218109.0, 231135.0};
00285 const G4double ParticleTable::effectiveNucleonMass = 938.2796;
00286 const G4double ParticleTable::effectiveNucleonMass2 = 8.8036860777616e5;
00287 const G4double ParticleTable::effectiveDeltaMass = 1232.0;
00288 const G4double ParticleTable::effectivePionMass = 138.0;
00289 const G4double ParticleTable::effectiveDeltaDecayThreshold =
00290 ParticleTable::theRealNeutronMass + ParticleTable::theRealChargedPiMass
00291 + 0.5;
00292 const G4double ParticleTable::theINCLProtonSeparationEnergy = 6.83;
00293 const G4double ParticleTable::theINCLNeutronSeparationEnergy = ParticleTable::theINCLProtonSeparationEnergy;
00294 G4double ParticleTable::protonSeparationEnergy = theINCLProtonSeparationEnergy;
00295 G4double ParticleTable::neutronSeparationEnergy = theINCLNeutronSeparationEnergy;
00296
00297 #ifdef INCLXX_IN_GEANT4_MODE
00298 G4IonTable *ParticleTable::theG4IonTable;
00299 #else
00300 std::vector< std::vector <G4bool> > ParticleTable::massTableMask;
00301 std::vector< std::vector <G4double> > ParticleTable::massTable;
00302 #endif
00303
00304 void ParticleTable::initialize(Config const * const theConfig ) {
00305 protonMass = theINCLNucleonMass;
00306 neutronMass = theINCLNucleonMass;
00307 piPlusMass = theINCLPionMass;
00308 piMinusMass = theINCLPionMass;
00309 piZeroMass = theINCLPionMass;
00310
00311 #ifndef INCLXX_IN_GEANT4_MODE
00312 std::string dataFilePath;
00313 if(theConfig)
00314 dataFilePath = theConfig->getINCLXXDataFilePath();
00315 readRealMasses(dataFilePath);
00316 #endif
00317
00318 if(theConfig && theConfig->getUseRealMasses()) {
00319 getTableMass = ParticleTable::getRealMass;
00320 getTableParticleMass = ParticleTable::getRealMass;
00321 } else {
00322 getTableMass = ParticleTable::getINCLMass;
00323 getTableParticleMass = ParticleTable::getINCLMass;
00324 }
00325 #ifdef INCLXX_IN_GEANT4_MODE
00326 G4ParticleTable *theG4ParticleTable = G4ParticleTable::GetParticleTable();
00327 theG4IonTable = theG4ParticleTable->GetIonTable();
00328 theRealProtonMass = theG4ParticleTable->FindParticle("proton")->GetPDGMass() / MeV;
00329 theRealNeutronMass = theG4ParticleTable->FindParticle("neutron")->GetPDGMass() / MeV;
00330 theRealChargedPiMass = theG4ParticleTable->FindParticle("pi+")->GetPDGMass() / MeV;
00331 theRealPiZeroMass = theG4ParticleTable->FindParticle("pi0")->GetPDGMass() / MeV;
00332 #endif
00333
00334
00335 if(!theConfig || theConfig->getSeparationEnergyType()==INCLSeparationEnergy)
00336 getSeparationEnergy = ParticleTable::getSeparationEnergyINCL;
00337 else if(theConfig->getSeparationEnergyType()==RealSeparationEnergy)
00338 getSeparationEnergy = ParticleTable::getSeparationEnergyReal;
00339 else if(theConfig->getSeparationEnergyType()==RealForLightSeparationEnergy)
00340 getSeparationEnergy = ParticleTable::getSeparationEnergyRealForLight;
00341 else {
00342 FATAL("Unrecognized separation-energy type in ParticleTable initialization: " << theConfig->getSeparationEnergyType() << std::endl);
00343 }
00344
00345 }
00346
00347 G4int ParticleTable::getIsospin(const ParticleType t) {
00348
00349 if(t == Proton) {
00350 return 1;
00351 } else if(t == Neutron) {
00352 return -1;
00353 } else if(t == PiPlus) {
00354 return 2;
00355 } else if(t == PiMinus) {
00356 return -2;
00357 } else if(t == PiZero) {
00358 return 0;
00359 } else if(t == DeltaPlusPlus) {
00360 return 3;
00361 } else if(t == DeltaPlus) {
00362 return 1;
00363 } else if(t == DeltaZero) {
00364 return -1;
00365 } else if(t == DeltaMinus) {
00366 return -3;
00367 }
00368
00369 ERROR("Requested isospin of an unknown particle!");
00370 return -10;
00371 }
00372
00373 std::string ParticleTable::getShortName(const ParticleSpecies s) {
00374 if(s.theType==Composite)
00375 return getShortName(s.theA,s.theZ);
00376 else
00377 return getShortName(s.theType);
00378 }
00379
00380 std::string ParticleTable::getName(const ParticleSpecies s) {
00381 if(s.theType==Composite)
00382 return getName(s.theA,s.theZ);
00383 else
00384 return getName(s.theType);
00385 }
00386
00387 std::string ParticleTable::getName(const G4int A, const G4int Z) {
00388 std::stringstream stream;
00389 stream << getElementName(Z) << "-" << A;
00390 return stream.str();
00391 }
00392
00393 std::string ParticleTable::getShortName(const G4int A, const G4int Z) {
00394 std::stringstream stream;
00395 stream << getElementName(Z);
00396 if(A>0)
00397 stream << A;
00398 return stream.str();
00399 }
00400
00401 std::string ParticleTable::getName(const ParticleType p) {
00402 if(p == G4INCL::Proton) {
00403 return std::string("proton");
00404 } else if(p == G4INCL::Neutron) {
00405 return std::string("neutron");
00406 } else if(p == G4INCL::DeltaPlusPlus) {
00407 return std::string("delta++");
00408 } else if(p == G4INCL::DeltaPlus) {
00409 return std::string("delta+");
00410 } else if(p == G4INCL::DeltaZero) {
00411 return std::string("delta0");
00412 } else if(p == G4INCL::DeltaMinus) {
00413 return std::string("delta-");
00414 } else if(p == G4INCL::PiPlus) {
00415 return std::string("pi+");
00416 } else if(p == G4INCL::PiZero) {
00417 return std::string("pi0");
00418 } else if(p == G4INCL::PiMinus) {
00419 return std::string("pi-");
00420 } else if(p == G4INCL::Composite) {
00421 return std::string("composite");
00422 }
00423 return std::string("unknown");
00424 }
00425
00426 std::string ParticleTable::getShortName(const ParticleType p) {
00427 if(p == G4INCL::Proton) {
00428 return std::string("p");
00429 } else if(p == G4INCL::Neutron) {
00430 return std::string("n");
00431 } else if(p == G4INCL::DeltaPlusPlus) {
00432 return std::string("d++");
00433 } else if(p == G4INCL::DeltaPlus) {
00434 return std::string("d+");
00435 } else if(p == G4INCL::DeltaZero) {
00436 return std::string("d0");
00437 } else if(p == G4INCL::DeltaMinus) {
00438 return std::string("d-");
00439 } else if(p == G4INCL::PiPlus) {
00440 return std::string("pi+");
00441 } else if(p == G4INCL::PiZero) {
00442 return std::string("pi0");
00443 } else if(p == G4INCL::PiMinus) {
00444 return std::string("pi-");
00445 } else if(p == G4INCL::Composite) {
00446 return std::string("comp");
00447 }
00448 return std::string("unknown");
00449 }
00450
00451 G4double ParticleTable::getINCLMass(const ParticleType pt) {
00452 if(pt == Proton) {
00453 return protonMass;
00454 } else if(pt == Neutron) {
00455 return neutronMass;
00456 } else if(pt == PiPlus) {
00457 return piPlusMass;
00458 } else if(pt == PiMinus) {
00459 return piMinusMass;
00460 } else if(pt == PiZero) {
00461 return piZeroMass;
00462 } else {
00463 ERROR("ParticleTable::getMass : Unknown particle type." << std::endl);
00464 return 0.0;
00465 }
00466 }
00467
00468 G4double ParticleTable::getRealMass(const ParticleType t) {
00469 switch(t) {
00470 case Proton:
00471 return theRealProtonMass;
00472 break;
00473 case Neutron:
00474 return theRealNeutronMass;
00475 break;
00476 case PiPlus:
00477 case PiMinus:
00478 return theRealChargedPiMass;
00479 break;
00480 case PiZero:
00481 return theRealPiZeroMass;
00482 break;
00483 default:
00484 ERROR("Particle::getRealMass : Unknown particle type." << std::endl);
00485 return 0.0;
00486 break;
00487 }
00488 }
00489
00490 G4double ParticleTable::getRealMass(const G4int A, const G4int Z) {
00491
00492
00493 if(Z<0)
00494 return A*neutronMass - Z*getRealMass(PiMinus);
00495 else if(Z>A)
00496 return A*protonMass + (A-Z)*getRealMass(PiPlus);
00497 else if(Z==0)
00498 return A*getRealMass(Neutron);
00499 else if(A==Z)
00500 return A*getRealMass(Proton);
00501 else if(A>1) {
00502 #ifndef INCLXX_IN_GEANT4_MODE
00503 if(ParticleTable::hasMassTable(A,Z))
00504 return ParticleTable::massTable.at(Z).at(A);
00505 else {
00506 DEBUG("Real mass unavailable for isotope A=" << A << ", Z=" << Z
00507 << ", using Weizsaecker's formula"
00508 << std::endl);
00509 return getWeizsaeckerMass(A,Z);
00510 }
00511 #else
00512 return theG4IonTable->GetNucleusMass(Z,A) / MeV;
00513 #endif
00514 } else
00515 return 0.;
00516 }
00517
00518 G4double ParticleTable::getINCLMass(const G4int A, const G4int Z) {
00519
00520
00521 if(Z<0)
00522 return A*neutronMass - Z*getINCLMass(PiMinus);
00523 else if(Z>A)
00524 return A*protonMass + (A-Z)*getINCLMass(PiPlus);
00525 else if(A>1)
00526 return Z*(protonMass - protonSeparationEnergy) + (A-Z)*(neutronMass - neutronSeparationEnergy);
00527 else if(A==1 && Z==0)
00528 return getINCLMass(Neutron);
00529 else if(A==1 && Z==1)
00530 return getINCLMass(Proton);
00531 else
00532 return 0.;
00533 }
00534
00535 G4double ParticleTable::getNuclearRadius(const G4int A, const G4int Z) {
00536
00537 if(A >= 19 || (A < 6 && A >= 2)) {
00538
00539
00540 return getRadiusParameter(A,Z);
00541 } else if(A < clusterTableASize && Z < clusterTableZSize && A >= 6) {
00542 const G4double thisRMS = positionRMS[Z][A];
00543 if(thisRMS>0.0)
00544 return thisRMS;
00545 else {
00546 ERROR("ParticleTable::getRadiusParameter : Radius for nucleus A = " << A << " Z = " << Z << " is ==0.0" << std::endl);
00547 return 0.0;
00548 }
00549 } else if(A < 19) {
00550 const G4double theRadiusParameter = getRadiusParameter(A, Z);
00551 const G4double theDiffusenessParameter = getSurfaceDiffuseness(A, Z);
00552
00553
00554 return 1.581*theDiffusenessParameter*
00555 (2.+5.*theRadiusParameter)/(2.+3.*theRadiusParameter);
00556 } else {
00557 ERROR("ParticleTable::getNuclearRadius: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
00558 return 0.0;
00559 }
00560 }
00561
00562 G4double ParticleTable::getRadiusParameter(const G4int A, const G4int Z) {
00563
00564 if(A >= 28) {
00565
00566 return (2.745e-4 * A + 1.063) * std::pow(A, 1.0/3.0);
00567 } else if(A < 6 && A >= 2) {
00568 if(Z<clusterTableZSize) {
00569 const G4double thisRMS = positionRMS[Z][A];
00570 if(thisRMS>0.0)
00571 return thisRMS;
00572 else {
00573 ERROR("ParticleTable::getRadiusParameter : Radius for nucleus A = " << A << " Z = " << Z << " is ==0.0" << std::endl);
00574 return 0.0;
00575 }
00576 } else {
00577 ERROR("ParticleTable::getRadiusParameter : No radius for nucleus A = " << A << " Z = " << Z << std::endl);
00578 return 0.0;
00579 }
00580 } else if(A < 28 && A >= 6) {
00581 return mediumRadius[A-1];
00582
00583 } else {
00584 ERROR("ParticleTable::getRadiusParameter: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
00585 return 0.0;
00586 }
00587 }
00588
00589 G4double ParticleTable::getMaximumNuclearRadius(const G4int A, const G4int Z) {
00590 const G4double XFOISA = 8.0;
00591 if(A >= 19) {
00592 return getNuclearRadius(A,Z) + XFOISA * getSurfaceDiffuseness(A,Z);
00593 } else if(A < 19 && A >= 6) {
00594 return 5.5 + 0.3 * (G4double(A) - 6.0)/12.0;
00595 } else if(A >= 2) {
00596 return ParticleTable::getNuclearRadius(A, Z) + 4.5;
00597 } else {
00598 ERROR("ParticleTable::getMaximumNuclearRadius : No maximum radius for nucleus A = " << A << " Z = " << Z << std::endl);
00599 return 0.0;
00600 }
00601 }
00602
00603 #ifdef INCLXX_IN_GEANT4_MODE
00604 G4double ParticleTable::getSurfaceDiffuseness(const G4int A, const G4int ) {
00605 #else
00606 G4double ParticleTable::getSurfaceDiffuseness(const G4int A, const G4int Z) {
00607 #endif // INCLXX_IN_GEANT4_MODE
00608
00609 if(A >= 28) {
00610 return 1.63e-4 * A + 0.510;
00611 } else if(A < 28 && A >= 19) {
00612 return mediumDiffuseness[A-1];
00613 } else if(A < 19 && A >= 6) {
00614 return mediumDiffuseness[A-1];
00615 } else if(A < 6 && A >= 2) {
00616 ERROR("ParticleTable::getSurfaceDiffuseness: was called for A = " << A << " Z = " << Z << std::endl);
00617 return 0.0;
00618 } else {
00619 ERROR("ParticleTable::getSurfaceDiffuseness: No diffuseness for nucleus A = " << A << " Z = " << Z << std::endl);
00620 return 0.0;
00621 }
00622 }
00623
00624 std::string ParticleTable::getElementName(const G4int Z) {
00625 if(Z<1) {
00626 WARN("getElementName called with Z<1" << std::endl);
00627 return elementTable[0];
00628 } else if(Z<elementTableSize)
00629 return elementTable[Z];
00630 else
00631 return getIUPACElementName(Z);
00632 }
00633
00634 #ifndef INCLXX_IN_GEANT4_MODE
00635 void ParticleTable::readRealMasses(std::string const &path) {
00636
00637 massTableMask.clear();
00638 massTable.clear();
00639
00640
00641 std::string fileName(path + "/walletlifetime.dat");
00642 DEBUG("Reading real nuclear masses from file " << fileName << std::endl);
00643
00644
00645 std::ifstream massTableIn(fileName.c_str());
00646 if(!massTableIn.good()) {
00647 FATAL("Cannot open " << fileName << " data file." << std::endl);
00648 return;
00649 }
00650
00651
00652 unsigned int Z, A;
00653 const G4double amu = 931.494061;
00654 const G4double eMass = 0.5109988;
00655 G4double excess;
00656 massTableIn >> A >> Z >> excess;
00657 do {
00658
00659 if(Z>=massTable.size()) {
00660 massTable.resize(Z+1);
00661 massTableMask.resize(Z+1);
00662 }
00663 if(A>=massTable[Z].size()) {
00664 massTable[Z].resize(A+1, 0.);
00665 massTableMask[Z].resize(A+1, false);
00666 }
00667
00668 massTable.at(Z).at(A) = A*amu + excess - Z*eMass;
00669 massTableMask.at(Z).at(A) = true;
00670
00671 massTableIn >> A >> Z >> excess;
00672 } while(massTableIn.good());
00673
00674 }
00675 #endif
00676
00677 std::string ParticleTable::getIUPACElementName(const G4int Z) {
00678 std::stringstream elementStream;
00679 elementStream << Z;
00680 std::string elementName = elementStream.str();
00681 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::intToIUPAC);
00682 elementName[0] = std::toupper(elementName.at(0));
00683 return elementName;
00684 }
00685
00686 G4int ParticleTable::parseIUPACElement(std::string const &s) {
00687
00688 std::string elementName(s);
00689 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
00690
00691 if(elementName.find_first_not_of(elementIUPACDigits)!=std::string::npos)
00692 return 0;
00693 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::iupacToInt);
00694 std::stringstream elementStream(elementName);
00695 G4int Z;
00696 elementStream >> Z;
00697 return Z;
00698 }
00699
00700 }