Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4INCLParticleSpecies.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // INCL++ intra-nuclear cascade model
27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28 // Davide Mancusi, CEA
29 // Alain Boudard, CEA
30 // Sylvie Leray, CEA
31 // Joseph Cugnon, University of Liege
32 //
33 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
37 /*
38  * G4INCLParticleSpecies.cc
39  *
40  * \date Nov 25, 2011
41  * \author Davide Mancusi
42  */
43 
44 #include "G4INCLParticleSpecies.hh"
45 #include "G4INCLParticleTable.hh"
46 #include <algorithm>
47 #include <cctype>
48 #include <sstream>
49 #include <algorithm>
50 
51 namespace G4INCL {
52 
53  ParticleSpecies::ParticleSpecies(std::string const &pS) {
54  // Normalise the string to lower case
55  std::string pSNorm = pS;
56  std::transform(pSNorm.begin(), pSNorm.end(), pSNorm.begin(), ::tolower);
57  if(pSNorm=="p" || pSNorm=="proton") {
58  theA = 1;
59  theZ = 1;
61  } else if(pSNorm=="n" || pSNorm=="neutron") {
62  theA = 1;
63  theZ = 0;
65  } else if(pSNorm=="delta++" || pSNorm=="deltaplusplus") {
66  theA = 1;
67  theZ = 2;
69  } else if(pSNorm=="delta+" || pSNorm=="deltaplus") {
70  theA = 1;
71  theZ = 1;
73  } else if(pSNorm=="delta0" || pSNorm=="deltazero") {
74  theA = 1;
75  theZ = 0;
77  } else if(pSNorm=="delta-" || pSNorm=="deltaminus") {
78  theA = 1;
79  theZ = -1;
81  } else if(pSNorm=="pi+" || pSNorm=="pion+" || pSNorm=="piplus" || pSNorm=="pionplus") {
82  theA = 0;
83  theZ = 1;
85  } else if(pSNorm=="pi0" || pSNorm=="pion0" || pSNorm=="pizero" || pSNorm=="pionzero") {
86  theA = 0;
87  theZ = 0;
89  } else if(pSNorm=="pi-" || pSNorm=="pion-" || pSNorm=="piminus" || pSNorm=="pionminus") {
90  theA = 0;
91  theZ = -1;
93  } else if(pSNorm=="d" || pSNorm=="deuteron") {
94  theA = 2;
95  theZ = 1;
97  } else if(pSNorm=="t" || pSNorm=="triton") {
98  theA = 3;
99  theZ = 1;
101  } else if(pSNorm=="a" || pSNorm=="alpha") {
102  theA = 4;
103  theZ = 2;
105  } else
106  parseNuclide(pSNorm);
107  }
108 
110  theType(t),
111  theA(ParticleTable::getMassNumber(theType)),
112  theZ(ParticleTable::getChargeNumber(theType))
113  {}
114 
116  theType(Composite),
117  theA(A),
118  theZ(Z)
119  {}
120 
121  void ParticleSpecies::parseNuclide(std::string const &pS) {
122  theType = Composite;
123 
124  // Allowed characters
125  const std::string separators("-_");
126  std::string allowed("0123456789abcdefghijklmnopqrstuvwxyz");
127  allowed += separators;
128 
129  // There must be at least one character
130  if(pS.find_first_not_of(allowed)!=std::string::npos) {
131  // Malformed input string
132  // Setting unknown particle species
133  (*this) = ParticleSpecies(UnknownParticle);
134  return;
135  }
136  if(pS.size()<1) {
137  // Malformed input string
138  // Setting unknown particle species
139  (*this) = ParticleSpecies(UnknownParticle);
140  return;
141  }
142 
143  std::size_t firstSeparator = pS.find_first_of(separators);
144  std::size_t lastSeparator = pS.find_last_of(separators);
145  if(firstSeparator!=std::string::npos && firstSeparator!=lastSeparator) {
146  // Several separators in malformed input string
147  // Setting unknown particle species
148  (*this) = ParticleSpecies(UnknownParticle);
149  return;
150  }
151 
152  // Identify the type of the first character
153  G4int (*predicate)(G4int);
154  G4bool startsWithAlpha = std::isalpha(pS.at(0));
155  if(startsWithAlpha) {
156  predicate=std::isdigit;
157  } else if(std::isdigit(pS.at(0))) {
158  predicate=std::isalpha;
159  } else {
160  // Non-alphanumeric character in string
161  // Setting unknown particle species
162  (*this) = ParticleSpecies(UnknownParticle);
163  return;
164  }
165 
166  G4bool hasIsotope = true;
167  size_t endFirstSection, beginSecondSection;
168  if(firstSeparator==std::string::npos) {
169  // No separator, Fe56 or 56Fe style
170  // Identify the end of the first section
171 
172  // Find the first character that is not of the same type as the first one
173  beginSecondSection = std::find_if(pS.begin()+1, pS.end(), predicate) - pS.begin();
174 
175  if(beginSecondSection>=pS.size()) {
176  if(startsWithAlpha) {
177  // Only alphabetic characters are present -- must be an element name
178  hasIsotope = false;
179  } else {
180  // Only numeric characters in the string
181  // Setting unknown particle species
182  (*this) = ParticleSpecies(UnknownParticle);
183  return;
184  }
185  }
186 
187  endFirstSection = beginSecondSection;
188 
189  } else {
190  // One separator, Fe-56 or 56-Fe style
191  endFirstSection = firstSeparator;
192  beginSecondSection = firstSeparator+1;
193  }
194 
195  std::string firstSection(pS.substr(0,endFirstSection));
196  std::string secondSection(pS.substr(beginSecondSection,std::string::npos));
197  std::stringstream parsingStream;
198 
199  // Parse the sections
200  G4bool success;
201  if(startsWithAlpha) {
202  parsingStream.str(secondSection);
203  success = parseElement(firstSection);
204  } else {
205  parsingStream.str(firstSection);
206  success = parseElement(secondSection);
207  }
208  if(!success) {
209  // Couldn't parse the element section
210  // Setting unknown particle species
211  (*this) = ParticleSpecies(UnknownParticle);
212  return;
213  }
214 
215  if(hasIsotope) {
216  parsingStream >> theA;
217  if(parsingStream.fail()) {
218  // Couldn't parse the mass section
219  // Setting unknown particle species
220  (*this) = ParticleSpecies(UnknownParticle);
221  return;
222  }
223  } else
224  theA = 0;
225 
226  // Check that Z<=A
227  if(theZ>theA && hasIsotope) {
228  // Setting unknown particle species
229  (*this) = ParticleSpecies(UnknownParticle);
230  return;
231  }
232 
233  // Special particle type for protons
234  if(theZ==1 && theA==1)
235  theType = Proton;
236  }
237 
238  G4bool ParticleSpecies::parseElement(std::string const &s) {
240  std::string elementName = ParticleTable::getElementName(theZ);
241  // Normalize the element name
242  std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
243  if(s.compare(elementName)==0)
244  return true;
245  }
246  return parseIUPACElement(s);
247  }
248 
249  G4bool ParticleSpecies::parseIUPACElement(std::string const &s) {
251  if(theZ==0)
252  return false;
253  else
254  return true;
255  }
256 }
257