G4INCLParticleSpecies.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // INCL++ intra-nuclear cascade model
00027 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
00028 // Davide Mancusi, CEA
00029 // Alain Boudard, CEA
00030 // Sylvie Leray, CEA
00031 // Joseph Cugnon, University of Liege
00032 //
00033 #define INCLXX_IN_GEANT4_MODE 1
00034 
00035 #include "globals.hh"
00036 
00037 /*
00038  * G4INCLParticleSpecies.cc
00039  *
00040  *  \date Nov 25, 2011
00041  * \author Davide Mancusi
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     // Normalise the string to lower case
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     // Allowed characters
00125     const std::string separators("-_");
00126     std::string allowed("0123456789abcdefghijklmnopqrstuvwxyz");
00127     allowed += separators;
00128 
00129     // There must be at least one character
00130     if(pS.find_first_not_of(allowed)!=std::string::npos) {
00131       // Malformed input string
00132       // Setting unknown particle species
00133       (*this) = ParticleSpecies(UnknownParticle);
00134       return;
00135     }
00136     if(pS.size()<1) {
00137       // Malformed input string
00138       // Setting unknown particle species
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       // Several separators in malformed input string
00147       // Setting unknown particle species
00148       (*this) = ParticleSpecies(UnknownParticle);
00149       return;
00150     }
00151 
00152     // Identify the type of the first character
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       // Non-alphanumeric character in string
00161       // Setting unknown particle species
00162       (*this) = ParticleSpecies(UnknownParticle);
00163       return;
00164     }
00165 
00166     G4bool hasIsotope = true;
00167     size_t endFirstSection, beginSecondSection;
00168     if(firstSeparator==std::string::npos) {
00169       // No separator, Fe56 or 56Fe style
00170       // Identify the end of the first section
00171 
00172       // Find the first character that is not of the same type as the first one
00173       beginSecondSection = std::find_if(pS.begin()+1, pS.end(), predicate) - pS.begin();
00174 
00175       if(beginSecondSection>=pS.size()) {
00176         if(startsWithAlpha) {
00177           // Only alphabetic characters are present -- must be an element name
00178           hasIsotope = false;
00179         } else {
00180           // Only numeric characters in the string
00181           // Setting unknown particle species
00182           (*this) = ParticleSpecies(UnknownParticle);
00183           return;
00184         }
00185       }
00186 
00187       endFirstSection = beginSecondSection;
00188 
00189     } else {
00190       // One separator, Fe-56 or 56-Fe style
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     // Parse the sections
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       // Couldn't parse the element section
00210       // Setting unknown particle species
00211       (*this) = ParticleSpecies(UnknownParticle);
00212       return;
00213     }
00214 
00215     if(hasIsotope) {
00216       parsingStream >> theA;
00217       if(parsingStream.fail()) {
00218         // Couldn't parse the mass section
00219         // Setting unknown particle species
00220         (*this) = ParticleSpecies(UnknownParticle);
00221         return;
00222       }
00223     } else
00224       theA = 0;
00225 
00226     // Check that Z<=A
00227     if(theZ>theA && hasIsotope) {
00228       // Setting unknown particle species
00229       (*this) = ParticleSpecies(UnknownParticle);
00230       return;
00231     }
00232 
00233     // Special particle type for protons
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       // Normalize the element name
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 

Generated on Mon May 27 17:48:36 2013 for Geant4 by  doxygen 1.4.7