Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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 // Alain Boudard, CEA-Saclay, France
28 // Joseph Cugnon, University of Liege, Belgium
29 // Jean-Christophe David, CEA-Saclay, France
30 // Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
31 // Sylvie Leray, CEA-Saclay, France
32 // Davide Mancusi, CEA-Saclay, France
33 //
34 #define INCLXX_IN_GEANT4_MODE 1
35 
36 #include "globals.hh"
37 
38 /*
39  * G4INCLParticleSpecies.cc
40  *
41  * \date Nov 25, 2011
42  * \author Davide Mancusi
43  */
44 
45 #include "G4INCLParticleSpecies.hh"
46 #include "G4INCLParticleTable.hh"
47 #include <algorithm>
48 #include <cctype>
49 #include <sstream>
50 #include <algorithm>
51 
52 namespace G4INCL {
53 
54  ParticleSpecies::ParticleSpecies(std::string const &pS) {
55  // Normalise the string to lower case
56  if(pS=="p" || pS=="proton") {
57  theA = 1;
58  theZ = 1;
60  } else if(pS=="n" || pS=="neutron") {
61  theA = 1;
62  theZ = 0;
64  } else if(pS=="delta++" || pS=="deltaplusplus") {
65  theA = 1;
66  theZ = 2;
68  } else if(pS=="delta+" || pS=="deltaplus") {
69  theA = 1;
70  theZ = 1;
72  } else if(pS=="delta0" || pS=="deltazero") {
73  theA = 1;
74  theZ = 0;
76  } else if(pS=="delta-" || pS=="deltaminus") {
77  theA = 1;
78  theZ = -1;
80  } else if(pS=="pi+" || pS=="pion+" || pS=="piplus" || pS=="pionplus") {
81  theA = 0;
82  theZ = 1;
84  } else if(pS=="pi0" || pS=="pion0" || pS=="pizero" || pS=="pionzero") {
85  theA = 0;
86  theZ = 0;
88  } else if(pS=="pi-" || pS=="pion-" || pS=="piminus" || pS=="pionminus") {
89  theA = 0;
90  theZ = -1;
92  } else if(pS=="d" || pS=="deuteron") {
93  theA = 2;
94  theZ = 1;
96  } else if(pS=="t" || pS=="triton") {
97  theA = 3;
98  theZ = 1;
100  } else if(pS=="a" || pS=="alpha") {
101  theA = 4;
102  theZ = 2;
104  } else if(pS=="eta") {
105  theA = 0;
106  theZ = 0;
108  } else if(pS=="omega") {
109  theA = 0;
110  theZ = 0;
112  } else if(pS=="etaprime" || pS=="etap") {
113  theA = 0;
114  theZ = 0;
116  } else if(pS=="photon") {
117  theA = 0;
118  theZ = 0;
120  } else
121  parseNuclide(pS);
122  }
123 
125  theType(t),
126  theA(ParticleTable::getMassNumber(theType)),
127  theZ(ParticleTable::getChargeNumber(theType))
128  {}
129 
131  theType(Composite),
132  theA(A),
133  theZ(Z)
134  {}
135 
136  void ParticleSpecies::parseNuclide(std::string const &pS) {
137  theType = Composite;
138 
139  // Allowed characters
140  const std::string separators("-_");
141  std::string allowed("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
142  allowed += separators;
143 
144  // There must be at least one character
145  if(pS.find_first_not_of(allowed)!=std::string::npos) {
146  // Malformed input string
147  // Setting unknown particle species
148  (*this) = ParticleSpecies(UnknownParticle);
149  return;
150  }
151  if(pS.size()<1) {
152  // Malformed input string
153  // Setting unknown particle species
154  (*this) = ParticleSpecies(UnknownParticle);
155  return;
156  }
157 
158  std::size_t firstSeparator = pS.find_first_of(separators);
159  std::size_t lastSeparator = pS.find_last_of(separators);
160  if(firstSeparator!=std::string::npos && firstSeparator!=lastSeparator) {
161  // Several separators in malformed input string
162  // Setting unknown particle species
163  (*this) = ParticleSpecies(UnknownParticle);
164  return;
165  }
166 
167  // Identify the type of the first character
168  G4int (*predicate)(G4int);
169  G4bool startsWithAlpha = std::isalpha(pS.at(0));
170  if(startsWithAlpha) {
171  predicate=std::isdigit;
172  } else if(std::isdigit(pS.at(0))) {
173  predicate=std::isalpha;
174  } else {
175  // Non-alphanumeric character in string
176  // Setting unknown particle species
177  (*this) = ParticleSpecies(UnknownParticle);
178  return;
179  }
180 
181  G4bool hasIsotope = true;
182  size_t endFirstSection, beginSecondSection;
183  if(firstSeparator==std::string::npos) {
184  // No separator, Fe56 or 56Fe style
185  // Identify the end of the first section
186 
187  // Find the first character that is not of the same type as the first one
188  beginSecondSection = std::find_if(pS.begin()+1, pS.end(), predicate) - pS.begin();
189 
190  if(beginSecondSection>=pS.size()) {
191  if(startsWithAlpha) {
192  // Only alphabetic characters are present -- must be an element name
193  hasIsotope = false;
194  } else {
195  // Only numeric characters in the string
196  // Setting unknown particle species
197  (*this) = ParticleSpecies(UnknownParticle);
198  return;
199  }
200  }
201 
202  endFirstSection = beginSecondSection;
203 
204  } else {
205  // One separator, Fe-56 or 56-Fe style
206  endFirstSection = firstSeparator;
207  beginSecondSection = firstSeparator+1;
208  }
209 
210  std::string firstSection(pS.substr(0,endFirstSection));
211  std::string secondSection(pS.substr(beginSecondSection,std::string::npos));
212  std::stringstream parsingStream;
213 
214  // Parse the sections
215  G4bool success;
216  if(startsWithAlpha) {
217  parsingStream.str(secondSection);
218  success = parseElement(firstSection);
219  } else {
220  parsingStream.str(firstSection);
221  success = parseElement(secondSection);
222  }
223  if(!success) {
224  // Couldn't parse the element section
225  // Setting unknown particle species
226  (*this) = ParticleSpecies(UnknownParticle);
227  return;
228  }
229 
230  if(hasIsotope) {
231  parsingStream >> theA;
232  if(parsingStream.fail()) {
233  // Couldn't parse the mass section
234  // Setting unknown particle species
235  (*this) = ParticleSpecies(UnknownParticle);
236  return;
237  }
238  } else
239  theA = 0;
240 
241  // Check that Z<=A
242  if(theZ>theA && hasIsotope) {
243  // Setting unknown particle species
244  (*this) = ParticleSpecies(UnknownParticle);
245  return;
246  }
247 
248  // Special particle type for protons
249  if(theZ==1 && theA==1)
250  theType = Proton;
251  }
252 
253  G4bool ParticleSpecies::parseElement(std::string const &s) {
255 
256  if(theZ<0)
258 
259  if(theZ<0)
260  return false;
261  else
262  return true;
263  }
264 
265  G4bool ParticleSpecies::parseIUPACElement(std::string const &s) {
267  if(theZ==0)
268  return false;
269  else
270  return true;
271  }
272 
274  switch (theType) {
275  case Proton:
276  return 2212;
277  break;
278  case Neutron:
279  return 2112;
280  break;
281  case DeltaPlusPlus:
282  return 2224;
283  break;
284  case DeltaPlus:
285  return 2214;
286  break;
287  case DeltaZero:
288  return 2114;
289  break;
290  case DeltaMinus:
291  return 1114;
292  break;
293  case PiPlus:
294  return 211;
295  break;
296  case PiZero:
297  return 111;
298  break;
299  case PiMinus:
300  return -211;
301  break;
302  case Eta:
303  return 221;
304  break;
305  case Omega:
306  return 223;
307  break;
308  case EtaPrime:
309  return 331;
310  break;
311  case Photon:
312  return 22;
313  break;
314  case Composite:
315  return theA+theZ*1000;
316  break;
317  default:
318  INCL_ERROR("ParticleSpecies::getPDGCode: Unknown particle type." << '\n');
319  return 0;
320  break;
321  }
322  }
323 }
324 
#define INCL_ERROR(x)
G4int getChargeNumber(const ParticleType t)
Get charge number from particle type.
int G4int
Definition: G4Types.hh:78
const XML_Char * s
Definition: expat.h:262
G4int getMassNumber(const ParticleType t)
Get mass number from particle type.
double A(double temperature)
G4int parseElement(std::string pS)
Get the name of the element from the atomic number.
bool G4bool
Definition: G4Types.hh:79
ParticleSpecies()
Convert a string to a particle species.
G4int getPDGCode() const
Set a PDG Code (MONTE CARLO PARTICLE NUMBERING)
G4int parseIUPACElement(std::string const &pS)
Parse a IUPAC element name.