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
00038
00039
00040
00041
00042
00043
00044 #include "G4INCLParticleSpecies.hh"
00045 #include "G4INCLParticleTable.hh"
00046 #include <algorithm>
00047 #include <cctype>
00048 #include <sstream>
00049 #include <algorithm>
00050
00051 namespace G4INCL {
00052
00053 ParticleSpecies::ParticleSpecies(std::string const &pS) {
00054
00055 std::string pSNorm = pS;
00056 std::transform(pSNorm.begin(), pSNorm.end(), pSNorm.begin(), ::tolower);
00057 if(pSNorm=="p" || pSNorm=="proton") {
00058 theA = 1;
00059 theZ = 1;
00060 theType = G4INCL::Proton;
00061 } else if(pSNorm=="n" || pSNorm=="neutron") {
00062 theA = 1;
00063 theZ = 0;
00064 theType = G4INCL::Neutron;
00065 } else if(pSNorm=="delta++" || pSNorm=="deltaplusplus") {
00066 theA = 1;
00067 theZ = 2;
00068 theType = G4INCL::DeltaPlusPlus;
00069 } else if(pSNorm=="delta+" || pSNorm=="deltaplus") {
00070 theA = 1;
00071 theZ = 1;
00072 theType = G4INCL::DeltaPlus;
00073 } else if(pSNorm=="delta0" || pSNorm=="deltazero") {
00074 theA = 1;
00075 theZ = 0;
00076 theType = G4INCL::DeltaZero;
00077 } else if(pSNorm=="delta-" || pSNorm=="deltaminus") {
00078 theA = 1;
00079 theZ = -1;
00080 theType = G4INCL::DeltaMinus;
00081 } else if(pSNorm=="pi+" || pSNorm=="pion+" || pSNorm=="piplus" || pSNorm=="pionplus") {
00082 theA = 0;
00083 theZ = 1;
00084 theType = G4INCL::PiPlus;
00085 } else if(pSNorm=="pi0" || pSNorm=="pion0" || pSNorm=="pizero" || pSNorm=="pionzero") {
00086 theA = 0;
00087 theZ = 0;
00088 theType = G4INCL::PiZero;
00089 } else if(pSNorm=="pi-" || pSNorm=="pion-" || pSNorm=="piminus" || pSNorm=="pionminus") {
00090 theA = 0;
00091 theZ = -1;
00092 theType = G4INCL::PiMinus;
00093 } else if(pSNorm=="d" || pSNorm=="deuteron") {
00094 theA = 2;
00095 theZ = 1;
00096 theType = G4INCL::Composite;
00097 } else if(pSNorm=="t" || pSNorm=="triton") {
00098 theA = 3;
00099 theZ = 1;
00100 theType = G4INCL::Composite;
00101 } else if(pSNorm=="a" || pSNorm=="alpha") {
00102 theA = 4;
00103 theZ = 2;
00104 theType = G4INCL::Composite;
00105 } else
00106 parseNuclide(pSNorm);
00107 }
00108
00109 ParticleSpecies::ParticleSpecies(ParticleType const t) :
00110 theType(t),
00111 theA(ParticleTable::getMassNumber(theType)),
00112 theZ(ParticleTable::getChargeNumber(theType))
00113 {}
00114
00115 ParticleSpecies::ParticleSpecies(const G4int A, const G4int Z) :
00116 theType(Composite),
00117 theA(A),
00118 theZ(Z)
00119 {}
00120
00121 void ParticleSpecies::parseNuclide(std::string const &pS) {
00122 theType = Composite;
00123
00124
00125 const std::string separators("-_");
00126 std::string allowed("0123456789abcdefghijklmnopqrstuvwxyz");
00127 allowed += separators;
00128
00129
00130 if(pS.find_first_not_of(allowed)!=std::string::npos) {
00131
00132
00133 (*this) = ParticleSpecies(UnknownParticle);
00134 return;
00135 }
00136 if(pS.size()<1) {
00137
00138
00139 (*this) = ParticleSpecies(UnknownParticle);
00140 return;
00141 }
00142
00143 std::size_t firstSeparator = pS.find_first_of(separators);
00144 std::size_t lastSeparator = pS.find_last_of(separators);
00145 if(firstSeparator!=std::string::npos && firstSeparator!=lastSeparator) {
00146
00147
00148 (*this) = ParticleSpecies(UnknownParticle);
00149 return;
00150 }
00151
00152
00153 G4int (*predicate)(G4int);
00154 G4bool startsWithAlpha = std::isalpha(pS.at(0));
00155 if(startsWithAlpha) {
00156 predicate=std::isdigit;
00157 } else if(std::isdigit(pS.at(0))) {
00158 predicate=std::isalpha;
00159 } else {
00160
00161
00162 (*this) = ParticleSpecies(UnknownParticle);
00163 return;
00164 }
00165
00166 G4bool hasIsotope = true;
00167 size_t endFirstSection, beginSecondSection;
00168 if(firstSeparator==std::string::npos) {
00169
00170
00171
00172
00173 beginSecondSection = std::find_if(pS.begin()+1, pS.end(), predicate) - pS.begin();
00174
00175 if(beginSecondSection>=pS.size()) {
00176 if(startsWithAlpha) {
00177
00178 hasIsotope = false;
00179 } else {
00180
00181
00182 (*this) = ParticleSpecies(UnknownParticle);
00183 return;
00184 }
00185 }
00186
00187 endFirstSection = beginSecondSection;
00188
00189 } else {
00190
00191 endFirstSection = firstSeparator;
00192 beginSecondSection = firstSeparator+1;
00193 }
00194
00195 std::string firstSection(pS.substr(0,endFirstSection));
00196 std::string secondSection(pS.substr(beginSecondSection,std::string::npos));
00197 std::stringstream parsingStream;
00198
00199
00200 G4bool success;
00201 if(startsWithAlpha) {
00202 parsingStream.str(secondSection);
00203 success = parseElement(firstSection);
00204 } else {
00205 parsingStream.str(firstSection);
00206 success = parseElement(secondSection);
00207 }
00208 if(!success) {
00209
00210
00211 (*this) = ParticleSpecies(UnknownParticle);
00212 return;
00213 }
00214
00215 if(hasIsotope) {
00216 parsingStream >> theA;
00217 if(parsingStream.fail()) {
00218
00219
00220 (*this) = ParticleSpecies(UnknownParticle);
00221 return;
00222 }
00223 } else
00224 theA = 0;
00225
00226
00227 if(theZ>theA && hasIsotope) {
00228
00229 (*this) = ParticleSpecies(UnknownParticle);
00230 return;
00231 }
00232
00233
00234 if(theZ==1 && theA==1)
00235 theType = Proton;
00236 }
00237
00238 G4bool ParticleSpecies::parseElement(std::string const &s) {
00239 for(theZ=1; theZ<ParticleTable::elementTableSize; ++theZ) {
00240 std::string elementName = ParticleTable::getElementName(theZ);
00241
00242 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
00243 if(s.compare(elementName)==0)
00244 return true;
00245 }
00246 return parseIUPACElement(s);
00247 }
00248
00249 G4bool ParticleSpecies::parseIUPACElement(std::string const &s) {
00250 theZ = ParticleTable::parseIUPACElement(s);
00251 if(theZ==0)
00252 return false;
00253 else
00254 return true;
00255 }
00256 }
00257