Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Geant4/PoPI.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 # <<BEGIN-copyright>>
0003 # Copyright 2019, Lawrence Livermore National Security, LLC.
0004 # This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
0005 # gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
0006 # SPDX-License-Identifier: MIT
0007 # <<END-copyright>>
0008 */
0009 
0010 #ifndef PoPI_hpp_included
0011 #define PoPI_hpp_included 1
0012 
0013 #include <string>
0014 #include <map>
0015 #include <vector>
0016 #include <list>
0017 #include <iostream>
0018 #include <stdexcept>
0019 #include <typeinfo>
0020 #include <fstream>
0021 #include <exception>
0022 #include <utility>
0023 #include <stddef.h>
0024 
0025 #include <LUPI.hpp>
0026 #include <HAPI.hpp>
0027 
0028 namespace PoPI {
0029 
0030 #define PoPI_AMU2MeV_c2 931.494028
0031 #define PoPI_electronMass_MeV_c2 0.5109989461
0032 
0033 #define PoPI_formatVersion_0_1_Chars "0.1"
0034 #define PoPI_formatVersion_1_10_Chars "1.10"
0035 #define PoPI_formatVersion_2_0_LLNL_3_Chars "2.0.LLNL_3"
0036 
0037 #define PoPI_PoPsChars "PoPs"
0038 
0039 #define PoPI_idChars "id"
0040 #define PoPI_symbolChars "symbol"
0041 #define PoPI_chemicalElementsChars "chemicalElements"
0042 #define PoPI_chemicalElementChars "chemicalElement"
0043 #define PoPI_isotopesChars "isotopes"
0044 #define PoPI_isotopeChars "isotope"
0045 #define PoPI_gaugeBosonChars "gaugeBoson"
0046 #define PoPI_leptonChars "lepton"
0047 #define PoPI_baryonChars "baryon"
0048 #define PoPI_nuclidesChars "nuclides"
0049 #define PoPI_nuclideChars "nuclide"
0050 #define PoPI_nucleusChars "nucleus"
0051 #define PoPI_unorthodoxChars "unorthodox"
0052 #define PoPI_aliasesChars "aliases"
0053 
0054 /*! \enum Particle_class
0055  * This enum represents the various type of allowed particle types.
0056  */
0057 
0058 enum class Particle_class { nuclide,                /**< Specifies that the particle is a nuclide. */
0059                             nucleus,                /**< Specifies that the particle is a nucleus. */
0060                             gaugeBoson,             /**< Specifies that the particle is a gauge boson. */
0061                             lepton,                 /**< Specifies that the particle is a lepton. */
0062                             baryon,                 /**< Specifies that the particle is a baryon. */
0063                             nuclideMetaStable,      /**< Specifies that the particle is a nuclide meta-stable alias. */
0064                             nucleusMetaStable,      /**< Specifies that the particle is a nucleus meta-stable alias. */
0065                             TNSL,                   /**< Specifies that the particle is a TNSL target. Currently not used. */
0066                             ENDL_fissionProduct,    /**< Specifies that the particle is an ENDL fissiont product (e.g., 99120, 99125). */
0067                             unorthodox,             /**< Specifies that the particle is an unorthodox. */
0068                             alias,                  /**< Specifies that the particle is a alias. */
0069                             chemicalElement,        /**< Specifies that the particle is a chemicalElement. */
0070                             isotope,                /**< Specifies that the particle is a isotope. */
0071                             unknown                 /**< Specifies that the particle is a unknown. */ };
0072 
0073 #define PoPI_massChars "mass"
0074 #define PoPI_spinChars "spin"
0075 #define PoPI_parityChars "parity"
0076 #define PoPI_chargeChars "charge"
0077 #define PoPI_halflifeChars "halflife"
0078 
0079 #define PoPI_doubleChars "double"
0080 #define PoPI_integerChars "integer"
0081 #define PoPI_fractionChars "fraction"
0082 #define PoPI_stringChars "string"
0083 #define PoPI_shellChars "shell"
0084 #define PoPI_decayDataChars "decayData"
0085 #define PoPI_gammaDecayDataChars "gammaDecayData"
0086 
0087 #define PoPI_decayModeElectroMagnetic "electroMagnetic"
0088 
0089 #define PoPI_formatChars "format"
0090 #define PoPI_labelChars "label"
0091 #define PoPI_indexChars "index"
0092 #define PoPI_pidChars "pid"
0093 #define PoPI_nameChars "name"
0094 #define PoPI_versionChars "version"
0095 #define PoPI_aliasChars "alias"
0096 #define PoPI_metaStableChars "metaStable"
0097 #define PoPI_particleChars "particle"
0098 #define PoPI_discreteChars "discrete"
0099 #define PoPI_continuumChars "continuum"
0100 
0101 /*! \enum PQ_class
0102  * This enum represents the various type of allowed physcial quantity types.
0103  */
0104 
0105 enum class PQ_class { Double,       /**< Specifies that the physcial quantity is a double. */
0106                       integer,      /**< Specifies that the physcial quantity is an integer. */
0107                       fraction,     /**< Specifies that the physcial quantity is a fraction. */
0108                       string,       /**< Specifies that the physcial quantity is a string. */
0109                       shell         /**< Specifies that the physcial quantity is a shell. */ };
0110 
0111 /*! \enum SpecialParticleID_mode
0112  * This enum specifies how the light charged particle ids are handled. The light charged particles ids are familiarly known as
0113  * p, d, t, h and a.
0114  */
0115 
0116 enum class SpecialParticleID_mode { familiar,   /**< Treat ids as the familiar p, d, t, h and a. */
0117                                     nuclide,    /**< Treat ids as the familiar p, d, t, h and a as h1, h2, h3, he3 and he4, respectively. */
0118                                     nucleus     /**< Treat ids as the familiar p, d, t, h and a as H1, H2, H3, He3 and He4, respectively. */ };
0119 
0120 class NuclideGammaBranchStateInfos;
0121 class Base;
0122 class SymbolBase;
0123 class Decay;
0124 class DecayMode;
0125 class DecayData;
0126 class Particle;
0127 class MetaStable;
0128 class Alias;
0129 class Baryon;
0130 class GaugeBoson;
0131 class Lepton;
0132 class Nuclide;
0133 class Nucleus;
0134 class Unorthodox;
0135 
0136 class Isotope;
0137 class ChemicalElement;
0138 class Database;
0139 
0140 void appendXMLEnd( std::vector<std::string> &a_XMLList, std::string const &a_label );
0141 
0142 int particleZ( Base const &a_particle, bool a_isNeutronProtonANucleon = false );
0143 int particleZ( Database const &a_pops, std::size_t a_index, bool a_isNeutronProtonANucleon = false );
0144 int particleZ( Database const &a_pops, std::string const &a_id, bool a_isNeutronProtonANucleon = false );
0145 
0146 int particleA( Base const &a_particle, bool a_isNeutronProtonANucleon = false );
0147 int particleA( Database const &a_pops, std::size_t a_index, bool a_isNeutronProtonANucleon = false );
0148 int particleA( Database const &a_pops, std::string const &a_id, bool a_isNeutronProtonANucleon = false );
0149 
0150 int particleZA( Base const &a_particle, bool a_isNeutronProtonANucleon = false );
0151 int particleZA( Database const &a_pops, std::size_t a_index, bool a_isNeutronProtonANucleon = false );
0152 int particleZA( Database const &a_pops, std::string const &a_id, bool a_isNeutronProtonANucleon = false );
0153 
0154 int particleMetaStableIndex( Base const &a_particle );
0155 int particleMetaStableIndex( Database const &a_pops, std::size_t a_index );
0156 int particleMetaStableIndex( Database const &a_pops, std::string const &a_id );
0157 
0158 std::string specialParticleID( SpecialParticleID_mode a_mode, std::string const &a_id );
0159 bool compareSpecialParticleIDs( std::string const &a_id1, std::string const &a_id2 );
0160 
0161 struct IDs {
0162     static std::string const photon;
0163     static std::string const electron;
0164     static std::string const neutron;
0165     static std::string const proton;
0166     static std::string const familiarPhoton;
0167     static std::string const familiarDeuteron;
0168     static std::string const familiarTriton;
0169     static std::string const familiarHelion;
0170     static std::string const familiarAlpha;
0171     static std::string const FissionProductENDL99120;
0172     static std::string const FissionProductENDL99125;
0173     static std::string const anti;
0174 };
0175 
0176 struct Intids {
0177     static int constexpr neutron = 1020000000;
0178     static int constexpr photon = 1000000000;
0179     static int constexpr electron = 1010000000;
0180     static int constexpr FissionProductENDL99120 = 1990099120;
0181     static int constexpr FissionProductENDL99125 = 1990099125;
0182 };
0183 
0184 extern std::map<std::string, std::string> supportedNucleusAliases;
0185 
0186 typedef std::vector<Base *> ParticleList;
0187 typedef std::vector<SymbolBase *> SymbolList;
0188 
0189 /*
0190 ============================================================
0191 ======================== Exception =========================
0192 ============================================================
0193 */
0194 
0195 class Exception : public std::runtime_error {
0196 
0197     public :
0198         explicit Exception( std::string const &a_message );
0199 
0200 };
0201 
0202 /*
0203 ============================================================
0204 ====================== ParseIntidInfo ======================
0205 ============================================================
0206 */
0207 
0208 class ParseIntidInfo {
0209 
0210     private:
0211         int m_intid;                        /**< The intid for the rest of the data. */
0212         Particle_class m_family;            /**< The family of the particle. */
0213         bool m_isAnti;                      /**< **true** if particle is an anti-particle and **false** otherwise. */
0214 // The following are for nuclear like particles.
0215         bool m_isNuclear;                   /**< *true* if the particle is a nuclear particle and *false* otherwise. */
0216         int m_AAA;                          /**< For a nuclear particle, its AAA value (i.e., atomic mass number). */
0217         int m_ZZZ;                          /**< For a nuclear particle, its ZZZ value (i.e., atomic number). */
0218         int m_III;                          /**< For a nuclear particle, its III value (nuclear excitation level index or meta-stable index. */
0219         int m_nuclearLevelIndex;            /**< For a nuclear particle, nuclear excitation level index. */
0220         int m_metaStableIndex;              /**< For a nuclear meta-stable particle, its meta-stable index. */
0221 // The following are for leptons.
0222         int m_generation;                   /**< For a lepton, its generation. */
0223         bool m_isNeutrino;                  /**< For a lepton, **true** if leption is a neutrino and **false** otherwise. */
0224 // The follow are for baryons.
0225         int m_baryonGroup;                  /**< For a baryon, its baryon group. */
0226         int m_baryonId;                     /**< For a baryon, its id within a baryon group. */
0227 // Other data.
0228         int m_familyId;                     /**< For non-nuclear particles, the particle's indentifier within its family. */
0229 
0230     public:
0231         ParseIntidInfo( int a_intid, bool a_GRIN_mode = false );
0232 
0233         int intid( ) { return( m_intid ); }                     /**< Returns the value of the *m_intid* member. */
0234         Particle_class family( ) { return( m_family ); }        /**< Returns the value of the *m_family* member. */
0235         bool isAnti( ) { return( m_isAnti ); }                  /**< Returns the value of the *m_isAnti * member. */
0236 
0237         bool isNuclear( ) { return( m_isNuclear ); }            /**< Returns the value of the *m_isNuclear* member. */
0238         int AAA( ) { return( m_AAA ); }                         /**< Returns the value of the *m_AAA* member. */
0239         int ZZZ( ) { return( m_ZZZ ); }                         /**< Returns the value of the *m_ZZZ* member. */
0240         int III( ) { return( m_III ); }                         /**< Returns the value of the *m_III* member. */
0241         bool isNuclearMetaStable( ) { return( ( m_family == Particle_class::nuclideMetaStable ) || ( m_family == Particle_class::nucleusMetaStable ) ); }
0242                                                                 /**< Returns **true** if particle is a nuclear meta-stable alias. */
0243         int metaStableIndex( ) { return( m_metaStableIndex ); } /**< Returns the value of the *m_metaStableIndex* member. */
0244 
0245         int generation( ) { return( m_generation ); }           /**< Returns the value of the *m_generation* member. */
0246         bool isNeutrino( ) { return( m_isNeutrino ); }          /**< Returns the value of the *m_isNeutrino* member. */
0247 
0248         int baryonGroup( ) { return( m_baryonGroup ); }         /**< Returns the value of the *m_baryonGroup* member. */
0249         int baryonId( ) { return( m_baryonId ); }               /**< Returns the value of the *m_baryonId * member. */
0250 
0251         int familyId( ) { return( m_familyId ); }               /**< Returns the value of the *m_familyId* member. */
0252 
0253         std::string id( );
0254 };
0255 
0256 /*
0257 ============================================================
0258 ======================= ParseIdInfo ========================
0259 ============================================================
0260 */
0261 
0262 class ParseIdInfo{
0263 
0264     private:
0265         bool m_isSupported;                                 /**< If **true** the particle's id was parsed and the other member of *this* are valid. Otherwise, parsing of the particle's id is currently not supported. */
0266         std::string m_id;                                   /**< The id for the particles. */
0267         bool m_isNuclear;                                   /**< **true** if particle is a valid nuclear name (i.e., nuclide, nucleus of meta-stable) and **false** otherwise. */
0268         bool m_isNucleus;                                   /**< **true** if particle is a nucleus and **false** otherwise. */
0269         bool m_isChemicalElement;                           /**< **true** if id is only a chemical element symbol. */
0270         bool m_isAnti;                                      /**< **true** if particle is an anti-particle and **false** otherwise. */
0271         bool m_isMetaStable;                                /**< **true** if particle is a meta-stable alias and **false** otherwise. */
0272         std::string m_symbol;                               /**< The chemical element symbol part of *m_id*. This will always be the nuclide symbol even if *m_id* is for a nucleus. */
0273         int m_Z;                                            /**< The atomic number of the *m_id*. */
0274         int m_A;                                            /**< The atomic mass number of the *m_id*. */
0275         int m_index;                                        /**< The nuclear level index of *m_id*. */
0276         std::string m_qualifier;
0277 
0278         std::string boolToString( bool a_value, std::string const &a_prefix ) const;
0279 
0280     public:
0281         ParseIdInfo( std::string const &a_id );
0282 
0283         bool isSupported( ) { return( m_isSupported ); }                /**< Returns the value of the *m_isSupported. */
0284         std::string const &Id( ) { return( m_id ); }                    /**< Returns a reference to the *m_id* member. */
0285         bool isNuclear( ) { return( m_isNuclear ); }                    /**< Returns the value of the *m_isNuclear* member. */
0286         bool isNucleus( ) { return( m_isNucleus ); }                    /**< Returns the value of the *m_isNucleus* member. */
0287         bool isChemicalElement( ) { return( m_isChemicalElement ); }    /**< Returns the value of the *m_isChemicalElement* member. */
0288         bool isAnti( ) { return( m_isAnti ); }                          /**< Returns the value of the *m_isAnti* member. */
0289         std::string const &symbol( ) { return( m_symbol); }             /**< Returns a reference to the *m_symbol* member. */
0290         int Z( ) { return( m_Z ); }                                     /**< Returns the value of the *m_Z* member. */
0291         int A( ) { return( m_A ); }                                     /**< Returns the value of the *m_A* member. */
0292         int index( ) { return( m_index ); }                             /**< Returns the value of the *m_index* member. */
0293         std::string const &qualifier( ) { return( m_qualifier ); }      /**< Returns a reference to the *m_qualifier* member. */
0294 
0295         void print( bool a_terse, std::string const &a_indent = "" ) const ;
0296 };
0297 
0298 /*! \class Suite
0299  * This is the base class for all suite like members.
0300  */
0301 
0302 /*
0303 ============================================================
0304 ========================== Suite ===========================
0305 ============================================================
0306 */
0307 
0308 template <class T, class T2>
0309 class Suite {
0310 
0311     private:
0312         std::string m_moniker;                                  /**< The moniker (i.e., name) of the suite. */
0313         std::vector<T *> m_items;                               /**< The list of all items in the suite. */
0314 
0315     public:
0316         Suite( std::string const &a_moniker ) : m_moniker( a_moniker ) { }
0317         ~Suite( );
0318         void appendFromParentNode( HAPI::Node const &a_node, Database *a_DB, T2 *a_parent );
0319         void appendFromParentNode2( HAPI::Node const &a_node, T2 *a_parent );
0320 
0321         std::string::size_type size( void ) const { return( m_items.size( ) ); }        /**< Returns the number of items in the suite. */
0322         T &operator[]( std::size_t a_index ) const { return( *m_items[a_index] ); }     /**< Returns the item at index *a_index*. */
0323         std::string const &moniker( void ) { return( m_moniker ); }                     /**< Returns the value of the *m_moniker* member. */
0324 
0325         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0326 };
0327 
0328 /* *********************************************************************************************************//**
0329  ***********************************************************************************************************/
0330 
0331 template <class T, class T2>
0332 Suite<T, T2>::~Suite( ) {
0333 
0334     std::string::size_type i1, _size = m_items.size( );
0335 
0336     for( i1 = 0; i1 < _size; ++i1 ) delete m_items[i1];
0337 
0338 // Ask Adam why next line does not work.
0339 //    for( std::vector<T *>::iterator iter = m_items.begin( ); iter != m_items.end( ); ++iter ) delete *iter;
0340 }
0341 
0342 /* *********************************************************************************************************//**
0343  * Adds the children of *a_node* to the suite and to *a_DB*.
0344  *
0345  * @param a_node            [in]    The **HAPI::Node** to be parsed.
0346  * @param a_DB              [in]    The **PoPI::Database** instance to add the constructed items to.
0347  * @param a_parent          [in]    The parent suite that will contain *this*.
0348  ***********************************************************************************************************/
0349 
0350 template <class T, class T2>
0351 void Suite<T, T2>::appendFromParentNode( HAPI::Node const &a_node, Database *a_DB, T2 *a_parent ) {
0352 
0353     for( HAPI::Node child = a_node.first_child( ); !child.empty( ); child.to_next_sibling( ) ) {
0354         T *item = new T( child, a_DB, a_parent );
0355         m_items.push_back( item );
0356     }
0357 }
0358 
0359 /* *********************************************************************************************************//**
0360  * Adds the children of *a_node* to the suite.
0361  *
0362  * @param a_node            [in]    The **HAPI::Node** to be parsed.
0363  * @param a_parent          [in]    The parent suite that will contain *this*.
0364  ***********************************************************************************************************/
0365 
0366 template <class T, class T2>
0367 void Suite<T, T2>::appendFromParentNode2( HAPI::Node const &a_node, T2 *a_parent ) {
0368 
0369     for( HAPI::Node child = a_node.first_child( ); !child.empty( ); child.to_next_sibling( ) ) {
0370         T *item = new T( child, a_parent );
0371         m_items.push_back( item );
0372     }
0373 }
0374 
0375 /* *********************************************************************************************************//**
0376  * Creates an XML representation of the suite.
0377  *
0378  * @param a_XMLList         [in]    The list the XML lines are added to.
0379  * @param a_indent1         [in]    The amount to indent the XML text.
0380  ***********************************************************************************************************/
0381 
0382 template <class T, class T2>
0383 void Suite<T, T2>::toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const {
0384 
0385     std::string::size_type _size = m_items.size( );
0386     std::string indent2 = a_indent1 + "  ";
0387 
0388     if( _size == 0 ) return;
0389 
0390     std::string header = a_indent1 + "<" + m_moniker + ">";
0391     a_XMLList.push_back( std::move( header ) );
0392     for( std::string::size_type i1 = 0; i1 < _size; ++i1 ) m_items[i1]->toXMLList( a_XMLList, indent2 );
0393 
0394     appendXMLEnd( a_XMLList, m_moniker );
0395 }
0396 
0397 /*
0398 ============================================================
0399 ===================== PhysicalQuantity =====================
0400 ============================================================
0401 */
0402 
0403 class PhysicalQuantity {
0404 
0405     private:
0406         PQ_class m_class;                           /**< The class for the physical quanity. */
0407         std::string m_tag;                          /**< The name of the physical quanity. */
0408         std::string m_label;                        /**< The label for the physical quanity. */
0409         std::string m_valueString;                  /**< The string value of the physical quanity. */
0410         std::string m_unit;                         /**< The unit of the physical quanity. */
0411 
0412     public:
0413         PhysicalQuantity( HAPI::Node const &a_node, PQ_class a_class );
0414         virtual ~PhysicalQuantity( );
0415 
0416         PQ_class Class( void ) const { return( m_class ); }                         /**< Returns the value of the *m_class* member. */
0417         std::string const &tag( void ) const { return( m_tag ); }                   /**< Returns the value of the *m_tag* member. */
0418         std::string const &label( void ) const { return( m_label ); }               /**< Returns the value of the *m_label* member. */
0419         std::string const &valueString( void ) const { return( m_valueString ); }   /**< Returns the value of the *valueString* member. */
0420         std::string const &unit( void ) const { return( m_unit ); }                 /**< Returns the value of the *m_unit* member. */
0421 
0422         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0423         virtual std::string valueToString( void ) const = 0;
0424 };
0425 
0426 /*
0427 ============================================================
0428 ========================= PQ_double ========================
0429 ============================================================
0430 */
0431 
0432 class PQ_double : public PhysicalQuantity {
0433 
0434     private:
0435         double m_value;                         /**< The double value of the physical quanity. */
0436         void initialize( );
0437 
0438     public:
0439         PQ_double( HAPI::Node const &a_node );
0440         PQ_double( HAPI::Node const &a_node, PQ_class a_class );
0441         virtual ~PQ_double( );
0442 
0443         double value( void ) const { return( m_value ); }                           /**< Returns the value of the *m_value* member. */
0444         double value( char const *a_unit ) const ;
0445         double value( std::string const &a_unit ) const { return( value( a_unit.c_str( ) ) ); }
0446                                                                                     /**< Returns the value of the *m_value* member in units of *a_unit*. */
0447         virtual std::string valueToString( void ) const ;
0448 };
0449 
0450 /*
0451 ============================================================
0452 ========================= PQ_integer =======================
0453 ============================================================
0454 */
0455 
0456 class PQ_integer : public PhysicalQuantity {
0457 
0458     private:
0459         int m_value;                            /**< The integer value of the physical quanity. */
0460 
0461     public:
0462         PQ_integer ( HAPI::Node const &a_node );
0463         virtual ~PQ_integer( );
0464 
0465         int value( void ) const { return( m_value ); }                              /**< Returns the value of the *m_value* member. */
0466         int value( char const *a_unit ) const ;
0467         int value( std::string const &a_unit ) const { return( value( a_unit.c_str( ) ) ); }
0468         virtual std::string valueToString( void ) const ;
0469 };
0470 
0471 /*
0472 ==============================================================
0473 ========================= PQ_fraction ========================
0474 ==============================================================
0475 */
0476 
0477 class PQ_fraction : public PhysicalQuantity {
0478 
0479     public:
0480         PQ_fraction( HAPI::Node const &a_node );
0481         virtual ~PQ_fraction( );
0482 
0483         std::string value( void ) const ;
0484         std::string value( char const *a_unit ) const ;
0485         std::string value( std::string const &a_unit ) const { return( value( a_unit.c_str( ) ) ); }
0486                                                                                     /**< Returns the value of the *m_value* member in units of *a_unit*. */
0487         virtual std::string valueToString( void ) const ;
0488 };
0489 
0490 /*
0491 ============================================================
0492 ========================= PQ_string ========================
0493 ============================================================
0494 */
0495 
0496 class PQ_string : public PhysicalQuantity {
0497 
0498     public:
0499         PQ_string( HAPI::Node const &a_node );
0500         virtual ~PQ_string( );
0501 
0502         std::string value( void ) const { return( valueString( ) ); }               /**< Returns the value returned by calling the **valueString** methods. */
0503         std::string value( char const *a_unit ) const ;
0504         std::string value( std::string const &a_unit ) const { return( value( a_unit.c_str( ) ) ); }
0505                                                                                     /**< Returns the value of the *m_value* member in units of *a_unit*. */
0506         virtual std::string valueToString( void ) const ;
0507 };
0508 
0509 /*
0510 ============================================================
0511 ========================= PQ_shell =========================
0512 ============================================================
0513 */
0514 
0515 class PQ_shell : public PQ_double {
0516 
0517     public:
0518         PQ_shell( HAPI::Node const &a_node );
0519         ~PQ_shell( );
0520 };
0521 
0522 /*
0523 ============================================================
0524 ========================= PQ_suite =========================
0525 ============================================================
0526 */
0527 
0528 class PQ_suite : public std::vector<PhysicalQuantity *> {
0529 
0530     private:
0531         std::string m_label;
0532 
0533     public:
0534         PQ_suite( HAPI::Node const &a_node );
0535         ~PQ_suite( );
0536 
0537         std::string &label( void ) { return( m_label ); }
0538 
0539         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0540 };
0541 
0542 /*
0543 ============================================================
0544 ================== NuclideGammaBranchInfo ==================
0545 ============================================================
0546 */
0547 
0548 class NuclideGammaBranchInfo {
0549 
0550     private:
0551         double m_probability;                               /**< The probability that the level decays to state *m_residualState*. */
0552         double m_photonEmissionProbability;                 /**< The conditional probability the the decay emitted a photon. */
0553         double m_gammaEnergy;                               /**< The energy of the emitted photon. */
0554         std::string m_residualState;                        /**< The state the residual is left in after photon decay. */
0555 
0556     public:
0557         NuclideGammaBranchInfo( double a_probability, double a_photonEmissionProbability, double a_gammaEnergy, std::string const &a_residualState );
0558         NuclideGammaBranchInfo( NuclideGammaBranchInfo const &a_nuclideGammaBranchInfo );
0559 
0560         double probability( ) const { return( m_probability ); }                        /**< Returns the value of the *m_probability* member. */
0561         double photonEmissionProbability( ) const { return( m_photonEmissionProbability ); }
0562                                                                                         /**< Returns the value of the *m_photonEmissionProbability* member. */
0563         double gammaEnergy( ) const { return( m_gammaEnergy ); }                        /**< Returns the value of the *m_gammaEnergy* member. */
0564         std::string const &residualState( ) const { return( m_residualState ); }        /**< Returns the value of the *m_residualState* member. */
0565 };      
0566 
0567 /*
0568 ==============================================================
0569 ================= NuclideGammaBranchStateInfo ================
0570 ==============================================================
0571 */
0572 
0573 class NuclideGammaBranchStateInfo {
0574 
0575     private:
0576         std::string m_state;                                    /**< The inital state the decay starts from. */
0577         int m_intid;                                            /**< The intid for the inital state. */
0578         std::string m_kind;                                     /**< The kind of the particle. Currently can be 'discrete' or 'continuum'. */
0579         double m_nuclearLevelEnergy;                            /**< The nuclear level excitation energy of the level (state). */
0580         double m_nuclearLevelEnergyWidth;                       /**< This is 0.0 except for GRIN realized continuum levels where this is the energy width from this level to the next higher level. */
0581         bool m_derivedCalculated;                               /**< For internal use to determine if other members have been set or not. */
0582         double m_multiplicity;                                  /**< The average number of photons emitted when transitioning from the initial to the final state. Data derived from m_branches data. */
0583         double m_averageGammaEnergy;                            /**< The average energy per decay from the initial to the final state. Data derived from m_branches data. */
0584         std::vector<NuclideGammaBranchInfo> m_branches;
0585 
0586     public:
0587         NuclideGammaBranchStateInfo( std::string const &a_state, int a_intid, std::string const &a_kind, double a_nuclearLevelEnergy );
0588 
0589         std::string const &state( ) const { return( m_state ); }                /**< Returns the value of the *m_state* member. */
0590         int intid( ) const { return( m_intid ); }                               /**< Returns the value of the *m_intid* member. */
0591         std::string const &kind( ) const { return( m_kind ); }                  /**< Returns the value of the *m_kind* member. */
0592         double nuclearLevelEnergy( ) const { return( m_nuclearLevelEnergy ); }  /**< Returns the value of the *m_nuclearLevelEnergy* member. */
0593         double nuclearLevelEnergyWidth( ) const { return( m_nuclearLevelEnergyWidth ); }
0594                                                                                 /**< Returns the value of the *m_nuclearLevelEnergyWidth* member. */
0595         void setNuclearLevelEnergyWidth( double a_nuclearLevelEnergyWidth ) { m_nuclearLevelEnergyWidth = a_nuclearLevelEnergyWidth; }
0596                                                                                 /**< Set the value of the *m_nuclearLevelEnergyWidth* member to *a_nuclearLevelEnergyWidth*. */
0597         bool derivedCalculated( ) const { return( m_derivedCalculated ); }      /**< Returns the value of the *m_derivedCalculated* member. */
0598         double multiplicity( ) const { return( m_multiplicity ); }              /**< Returns the value of the *m_multiplicity* member. */
0599         double averageGammaEnergy( ) const { return( m_averageGammaEnergy ); }  /**< Returns the value of the *m_averageGammaEnergy* member. */
0600         std::vector<NuclideGammaBranchInfo> const &branches( ) const { return( m_branches ); }
0601                                                                                 /**< Returns a reference to the *m_branches* member. */
0602 
0603         void add( NuclideGammaBranchInfo const &a_nuclideGammaBranchInfo );
0604         void calculateDerivedData( NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos );
0605 };
0606 
0607 /*
0608 ==============================================================
0609 ================ NuclideGammaBranchStateInfos ================
0610 ==============================================================
0611 */
0612 
0613 class NuclideGammaBranchStateInfos {
0614 
0615     private:
0616         std::vector<NuclideGammaBranchStateInfo *> m_nuclideGammaBranchStateInfos;
0617 
0618     public:
0619         NuclideGammaBranchStateInfos( );
0620         ~NuclideGammaBranchStateInfos( );
0621 
0622         std::size_t size( ) const { return( m_nuclideGammaBranchStateInfos.size( ) ); }
0623         NuclideGammaBranchStateInfo *operator[]( std::size_t a_index ) { return( m_nuclideGammaBranchStateInfos[a_index] ); }
0624         NuclideGammaBranchStateInfo const *operator[]( std::size_t a_index ) const { return( m_nuclideGammaBranchStateInfos[a_index] ); }
0625         std::vector<NuclideGammaBranchStateInfo *> &nuclideGammaBranchStateInfos( ) { return( m_nuclideGammaBranchStateInfos ); }
0626         void add( NuclideGammaBranchStateInfo *a_nuclideGammaBranchStateInfo );
0627         NuclideGammaBranchStateInfo *find( std::string const &a_state );
0628         NuclideGammaBranchStateInfo const *find( std::string const &a_state ) const ;
0629 };
0630 
0631 /*
0632 ============================================================
0633 =========================== Base ===========================
0634 ============================================================
0635 */
0636 
0637 class Base {
0638 
0639     private:
0640         std::string m_id;                               /**< The **PoPs** id for the particle or **PoPs** symbol for a chemicalElement or isotope. */
0641         Particle_class m_class;                         /**< The **Particle_class** for the particle, chemicalElement or isotope. */
0642         std::size_t m_index;                            /**< The for the particle, chemicalElement or isotope. */
0643         int m_intid;                                    /**< The unique integer id for a particle or a meta-stable alias. For a non meta-stable alias, an isotope or chemical element, this is -1. */
0644 
0645         void setIntid( int a_intid ) { m_intid = a_intid; }                                 /**< Sets the value of the *m_intid* member to *a_intid*. */
0646 
0647     public:
0648         Base( std::string const &a_id, Particle_class a_class );
0649         Base( HAPI::Node const &a_node, std::string const &a_label, Particle_class a_class );
0650         virtual ~Base( );
0651 
0652         std::string const &ID( void ) const { return( m_id ); }                             /**< Returns a *const* reference to the *m_id* member of *this*. */
0653         std::size_t index( void ) const { return( m_index ); }                              /**< Returns the value of the *m_index* member of *this*. */
0654         void setIndex( std::size_t a_index ) { m_index = a_index; }                         /**< Sets the value of the *m_index* member of *this* to *a_index*. */
0655         int intid( ) const { return( m_intid ); }                                           /**< Returns the value of the *m_intid* member. */
0656         Particle_class Class( void ) const { return( m_class ); }                           /**< Returns the value of the *m_class* member of *this*. */
0657         virtual bool isParticle( ) const { return( true ); }                                /**< Returns **true** if *this* is a **Particle** and **false** it *this* is a **ChemicalElement** or **Isotope** instance. */
0658         bool isAlias( void ) const { return( ( m_class == Particle_class::alias ) || isMetaStableAlias( ) ); }
0659                                                                                             /**< Returns **true** if *this* is an **Alias** or **MetaStable** instance and **false** otherwise. */
0660         bool isMetaStableAlias( void ) const { return( ( m_class == Particle_class::nuclideMetaStable ) || ( m_class ==  Particle_class::nucleusMetaStable ) ); }
0661                                                                                             /**< Returns **true** if *this* is a **MetaStable** instance and **false** otherwise. */
0662 
0663         bool isGaugeBoson( ) const { return( m_class == Particle_class::gaugeBoson ); }     /**< Returns **true** if *this* is a **GaugeBoson** instance and **false** otherwise. */
0664         bool isLepton( ) const { return( m_class == Particle_class::lepton ); }             /**< Returns **true** if *this* is a **Lepton** instance and **false** otherwise. */
0665         bool isBaryon( ) const { return( m_class == Particle_class::baryon ); }             /**< Returns **true** if *this* is a **Baryon** instance and **false** otherwise. */
0666         bool isUnorthodox( ) const { return( m_class == Particle_class::unorthodox ); }     /**< Returns **true** if *this* is a **Unorthodox** instance and **false** otherwise. */
0667         bool isNucleus( ) const { return( m_class == Particle_class::nucleus ); }           /**< Returns **true** if *this* is a **Nucleus** instance and **false** otherwise. */
0668         bool isNuclide( ) const { return( m_class == Particle_class::nuclide ); }           /**< Returns **true** if *this* is a **Nuclide** instance and **false** otherwise. */
0669         bool isIsotope( ) const { return( m_class == Particle_class::isotope ); }           /**< Returns **true** if *this* is a **Isotope** instance and **false** otherwise. */
0670         bool isChemicalElement( ) const { return( m_class == Particle_class::chemicalElement ); }
0671                                                                                             /**< Returns **true** if *this* is a **ChemicalElement** instance and **false** otherwise. */
0672 
0673         friend MetaStable;
0674         friend Alias;
0675         friend Baryon;
0676         friend GaugeBoson;
0677         friend Lepton;
0678         friend Nucleus;
0679         friend Nuclide;
0680         friend Unorthodox;
0681 };
0682 
0683 /*
0684 ============================================================
0685 ========================== IDBase ==========================
0686 ============================================================
0687 */
0688 
0689 class IDBase : public Base {
0690 
0691     public:
0692         IDBase( std::string const &a_id, Particle_class a_class );
0693         IDBase( HAPI::Node const &a_node, Particle_class a_class );
0694         virtual ~IDBase( );       // BRB This should be virtual but I cannot get it to work without crashing.
0695 
0696         std::size_t addToDatabase( Database *a_DB );
0697         double massValue2( Database const &a_DB, std::string const &a_unit ) const ;
0698 };
0699 
0700 /*
0701 ============================================================
0702 ======================== SymbolBase ========================
0703 ============================================================
0704 */
0705 
0706 class SymbolBase : public Base {
0707 
0708     public:
0709         SymbolBase( HAPI::Node const &a_node, Particle_class a_class );
0710         ~SymbolBase( );
0711 
0712         std::string const &symbol( ) const { return( ID( ) ); }                             /**< Returns the value of the symbol. */
0713 
0714         std::size_t addToSymbols( Database *a_DB );
0715         bool isParticle( ) const { return( false ); }
0716 };
0717 
0718 /*
0719 ============================================================
0720 ========================= Product ==========================
0721 ============================================================
0722 */
0723 
0724 class Product {
0725 
0726     private:
0727         int m_id;
0728         std::string m_pid;
0729         std::string m_label;
0730 
0731     public:
0732         Product( HAPI::Node const &a_node, Decay *a_DB );
0733         ~Product( );
0734 
0735         int ID( ) const { return( m_id ); }
0736         std::string const &pid( ) const { return( m_pid ); }
0737         std::string const &label( ) const { return( m_label ); }
0738 
0739         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0740 };
0741 
0742 /*
0743 ============================================================
0744 ========================== Decay ===========================
0745 ============================================================
0746 */
0747 
0748 class Decay {
0749 
0750     private:
0751         int m_index;
0752         std::string m_mode;
0753         bool m_complete;
0754         Suite<Product, Decay> m_products;
0755 
0756     public:
0757         Decay( HAPI::Node const &a_node, DecayMode const *a_decayMode );
0758         ~Decay( );
0759 
0760         int index( void ) const { return( m_index ); }
0761         std::string const &mode( ) const { return( m_mode ); }
0762         bool complete( ) const { return( m_complete ); }
0763         Suite<Product, Decay> const &products( void ) const { return( m_products ); }
0764         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0765 };
0766 
0767 /*
0768 ============================================================
0769 ======================== DecayMode =========================
0770 ============================================================
0771 */
0772 
0773 class DecayMode {
0774 
0775     private:
0776         std::string m_label;
0777         std::string m_mode;
0778         PQ_suite m_probability;
0779         PQ_suite m_photonEmissionProbabilities;
0780         Suite<Decay, DecayMode> m_decayPath;
0781 
0782     public:
0783         DecayMode( HAPI::Node const &a_node, DecayData const *a_decayData );
0784         ~DecayMode( );
0785 
0786         std::string const &label( ) const { return( m_label ); }
0787         std::string const &mode( ) const { return( m_mode ); }
0788         PQ_suite const &probability( ) const { return( m_probability ); }
0789         PQ_suite const &photonEmissionProbabilities( ) const { return( m_photonEmissionProbabilities ); }
0790         Suite<Decay, DecayMode> const &decayPath( ) const { return( m_decayPath ); }
0791 
0792         void calculateNuclideGammaBranchStateInfo( PoPI::Database const &a_pops, NuclideGammaBranchStateInfo &a_nuclideGammaBranchStateInfo ) const ;
0793         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0794 };
0795 
0796 /*
0797 ============================================================
0798 ======================== DecayData =========================
0799 ============================================================
0800 */
0801 
0802 class DecayData {
0803 
0804     private:
0805         Suite<DecayMode, DecayData> m_decayModes;
0806 
0807     public:
0808         DecayData( HAPI::Node const &a_node );
0809         ~DecayData( );
0810 
0811         Suite<DecayMode, DecayData> const &decayModes( void ) const { return( m_decayModes ); }
0812 
0813         void calculateNuclideGammaBranchStateInfo( PoPI::Database const &a_pops, NuclideGammaBranchStateInfo &a_nuclideGammaBranchStateInfo ) const ;
0814         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0815 };
0816 
0817 /*
0818 ============================================================
0819 ====================== GammaDecayData ======================
0820 ============================================================
0821 */
0822 
0823 class GammaDecayData {
0824 
0825     private:
0826         std::string m_kind;                                     /**< The kind of the particle. Currently can be 'discrete' or 'continuum' but may be 'experimental', 'evaluated' or 'modelled' in the future. */
0827         int m_rows;                                             /**< The number of nuclides listed. */
0828         int m_columns;                                          /**< The number of items in a row. */
0829         std::vector<std::string> m_ids;                         /**< The list of nulcides. */
0830         std::vector<double> m_probabilities;                    /**< The list of probabilities for each nuclide. This must sum to 1. */
0831         std::vector<double> m_photonEmissionProbabilities;      /**< The list of photon emission probabilities for each nuclide. */
0832 
0833     public:
0834         GammaDecayData( HAPI::Node const &a_node );
0835         ~GammaDecayData( );
0836 
0837         std::string const &kind( ) const { return( m_kind ); }              /**< Returns a const reference to the *m_kind* member. */
0838         int rows( ) const { return( m_rows ); }
0839         int colunms( ) const { return( m_columns ); }
0840         std::vector<std::string> const &ids( ) const { return( m_ids ); }
0841         std::vector<double> const &probabilities( ) const { return( m_probabilities ); }
0842         std::vector<double> const &photonEmissionProbabilities( ) const { return( m_photonEmissionProbabilities ); }
0843 
0844         void calculateNuclideGammaBranchStateInfo( PoPI::Database const &a_pops, NuclideGammaBranchStateInfo &nuclideGammaBranchStateInfo ) const ;
0845 };
0846 
0847 /*
0848 ============================================================
0849 ========================= Particle =========================
0850 ============================================================
0851 */
0852 
0853 class Particle : public IDBase {
0854 
0855     private:
0856         std::string m_baseId;                           /**< The base part of the id (i.e., without the anti and quailifier). */
0857         std::string m_family;                           /**< The family of the particle. */
0858         std::string m_anti;                             /**< The string "_anti" if particle is an anti-particle and an empty string otherwise. */
0859         int m_hasNucleus;                               /**< Indicates if the particle is or contains a nucleus. 0 = no, -1 = yes and 1 = is nucleus. */
0860         PQ_suite m_mass;                                /**< A suite storing the mass physical quantities for the particle. */
0861         PQ_suite m_spin;                                /**< A suite storing the spin physical quantities for the particle. */
0862         PQ_suite m_parity;                              /**< A suite storing the parity physical quantities for the particle. */
0863         PQ_suite m_charge;                              /**< A suite storing the charge physical quantities for the particle. */
0864         PQ_suite m_halflife;                            /**< A suite storing the halflife physical quantities for the particle. */
0865         DecayData m_decayData;                          /**< Stores the decay data for the particle. */
0866 
0867         void setHasNucleus( bool a_hasNucleus ) { m_hasNucleus = a_hasNucleus; }
0868 
0869     public:
0870         Particle( HAPI::Node const &a_node, Particle_class a_class, std::string const &a_family, int a_hasNucleus = 0 );
0871         virtual ~Particle( );
0872 
0873         std::string const &baseId( void ) const { return( m_baseId ); }         /**< Returns a *const* reference to the *m_baseId* member. */
0874         std::string const &family( void ) const { return( m_family ); }         /**< Returns a *const* reference to the *m_family* member. */
0875         bool isAnti( ) const { return( m_anti == IDs::anti ); }                              /**< Returns the value of the *m_anti* member. */
0876         int hasNucleus( void ) const { return( m_hasNucleus ); }                /**< Returns the value of the *m_hasNucleus* member. */
0877 
0878         virtual PQ_suite const &mass( void ) const { return( m_mass ); }        /**< Returns a *const* reference to the *m_mass* member. */
0879         virtual double massValue( char const *a_unit ) const ;
0880         double massValue( std::string const &a_unit ) const { return( massValue( a_unit.c_str( ) ) ); }
0881                                                                                 /**< Returns the value of massValue( a_unit.c_str( ) ). */
0882 
0883         PQ_suite const &spin( ) const { return( m_spin ); }                     /**< Returns a *const* reference to the *m_spin* member. */
0884         PQ_suite const &parity( ) const { return( m_parity ); }                 /**< Returns a *const* reference to the *m_parity* member. */
0885         PQ_suite const &charge( ) const { return( m_charge ); }                 /**< Returns a *const* reference to the *m_charge* member. */
0886         PQ_suite const &halflife( ) const { return( m_halflife ); }             /**< Returns a *const* reference to the *m_halflife* member. */
0887         DecayData const &decayData( ) const { return( m_decayData ); }          /**< Returns a *const* reference to the *m_decayData* member. */
0888 
0889         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0890         virtual std::string toXMLListExtraAttributes( void ) const ;
0891         virtual void toXMLListExtraElements( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0892 
0893         friend class Unorthodox;
0894 };
0895 
0896 /*
0897 ============================================================
0898 ======================== GaugeBoson ========================
0899 ============================================================
0900 */
0901 
0902 class GaugeBoson : public Particle {
0903 
0904     public:
0905         GaugeBoson( HAPI::Node const &a_node, Database *a_DB, Database *a_parent );
0906         virtual ~GaugeBoson( );
0907 };
0908 
0909 /*
0910 ============================================================
0911 ========================== Lepton ==========================
0912 ============================================================
0913 */
0914 
0915 class Lepton : public Particle {
0916 
0917     private:
0918         std::string m_generation;                                               /**< The generation of the lepton (i.e., electronic, muonic or tauonic). */
0919 
0920     public:
0921         Lepton( HAPI::Node const &a_node, Database *a_DB, Database *a_parent );
0922         virtual ~Lepton( );
0923 
0924         std::string const &generation( void ) const { return( m_generation ); }
0925         virtual std::string toXMLListExtraAttributes( void ) const ;
0926 };
0927 
0928 /*
0929 ============================================================
0930 ========================== Baryon ==========================
0931 ============================================================
0932 */
0933 
0934 class Baryon : public Particle {
0935 
0936     public:
0937         Baryon( HAPI::Node const &a_node, Database *a_DB, Database *a_parent );
0938         virtual ~Baryon( );
0939 };
0940 
0941 /*
0942 ============================================================
0943 ======================== Unorthodox ========================
0944 ============================================================
0945 */
0946 
0947 class Unorthodox : public Particle {
0948 
0949     public:
0950         Unorthodox( HAPI::Node const &a_node, Database *a_DB, Database *a_parent );
0951         virtual ~Unorthodox( );
0952 };
0953 
0954 /*
0955 ============================================================
0956 ========================== Nucleus =========================
0957 ============================================================
0958 */
0959 
0960 class Nucleus : public Particle {
0961 
0962     private:
0963         Nuclide *m_nuclide;                                 /**< The parent nuclide of *this*. */
0964         int m_Z;                                            /**< The atomic number of the parent nuclide. */
0965         int m_A;                                            /**< The atomic mass number of the parent nuclide. */
0966         std::string m_levelName;                            /**< The string representationn of *m_levelIndex*. */
0967         int m_levelIndex;                                   /**< The index of the excited nucleus state. */
0968         PQ_suite m_energy;                                  /**< A suite storing the physical quantities representing the nucleus excited energy for the particle.. */
0969 
0970     public:
0971         Nucleus( HAPI::Node const &node, Database *a_DB, Nuclide *a_parent );
0972         virtual ~Nucleus( );
0973 
0974         Nuclide const *nuclide( ) const { return( m_nuclide ); }                    /**< Returns a *const* reference to the *m_nuclide* member. */
0975         int Z( void ) const { return( m_Z ); }                                      /**< Returns a *const* reference to the *m_Z* member. */
0976         int A( void ) const { return( m_A ); }                                      /**< Returns a *const* reference to the *m_A* member. */
0977         std::string const &levelName( ) const { return( m_levelName ); }            /**< Returns a *const* reference to the *m_levelName* member of *this*. */
0978         int levelIndex( void ) const { return( m_levelIndex ); }                    /**< Returns a *const* reference to the *m_levelIndex* member. */
0979         std::string const &atomsID( void ) const ;
0980 
0981         double massValue( char const *a_unit ) const ;
0982         PQ_suite const &energy( void ) const { return( m_energy ); }                /**< Returns a *const* reference to the *m_energy* member. */
0983         double energy( std::string const &a_unit ) const ;
0984         virtual std::string toXMLListExtraAttributes( void ) const ;
0985         virtual void toXMLListExtraElements( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
0986 };
0987 
0988 /*
0989 ============================================================
0990 ========================== Nuclide =========================
0991 ============================================================
0992 */
0993 
0994 class Nuclide : public Particle {
0995 
0996     private:
0997         Isotope *m_isotope;                                 /**< A pointer to the parent isotope. */
0998         Nucleus m_nucleus;                                  /**< The nucleus for *this* nuclide. */
0999         GammaDecayData m_gammaDecayData;                    /**< . */
1000 
1001     public:
1002         Nuclide( HAPI::Node const &a_node, Database *a_DB, Isotope *a_parent );
1003         virtual ~Nuclide( );
1004 
1005         int Z( void ) const;
1006         int A( void ) const;
1007         std::string const &levelName( void ) const { return( m_nucleus.levelName( ) ); }
1008                                                                                 /**< Returns the result of calling m_nucleus.levelName( ). */
1009         int levelIndex( void ) const { return( m_nucleus.levelIndex( ) ); }     /**< Returns the result of calling m_nucleus.levelIndex( ). */
1010         std::string const &atomsID( ) const ;
1011         std::string const &kind( ) const { return( m_gammaDecayData.kind( ) ); }
1012         GammaDecayData const &gammaDecayData( ) const { return( m_gammaDecayData ); }
1013 
1014         Isotope const *isotope( ) const { return( m_isotope ); }                /**< Returns a *const* reference to the *m_isotope* member. */
1015         Nucleus const &nucleus( ) const { return( m_nucleus ); }                /**< Returns a *const* reference to the *m_nucleus* member. */
1016 
1017         PQ_suite const &baseMass( void ) const ;
1018         double massValue( char const *a_unit ) const ;
1019         double levelEnergy( std::string const &a_unit ) const { return( m_nucleus.energy( a_unit ) ); }
1020                                                                                 /**< Returns the result of calling m_nucleus.energy( a_unit ). */
1021 
1022         void calculateNuclideGammaBranchStateInfos( PoPI::Database const &a_pops, NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos,
1023                 bool a_alwaysAdd = false ) const ;
1024         virtual void toXMLListExtraElements( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
1025 };
1026 
1027 /*
1028 ============================================================
1029 ========================= Isotope ==========================
1030 ============================================================
1031 */
1032 
1033 class Isotope : public SymbolBase {
1034 
1035     private:
1036         ChemicalElement *m_chemicalElement;         /**< A pointer to the parent chemical element. */
1037         int m_Z;                                    /**< A atomic number for the isotope. */
1038         int m_A;                                    /**< The atomic mass number for the isotope. */
1039         Suite<Nuclide, Isotope> m_nuclides;         /**< The suite of nuclides for this isotope. */
1040 
1041     public:
1042         Isotope( HAPI::Node const &a_node, Database *a_DB, ChemicalElement *a_parent );
1043         virtual ~Isotope( );
1044 
1045         ChemicalElement const *chemicalElement( ) const { return( m_chemicalElement ); }    /**< Returns a *const* reference to the *m_isotope* member. */
1046         int Z( void ) const { return( m_Z ); }                                  /**< Returns the value of the *m_Z* member. */
1047         int A( void ) const { return( m_A ); }                                  /**< Returns the value of the *m_A* member. */
1048         Suite<Nuclide, Isotope> const &nuclides( ) const { return( m_nuclides ); }          /**< Returns a *const* reference to the *m_nuclides* member. */
1049 
1050         void calculateNuclideGammaBranchStateInfos( PoPI::Database const &a_pops, NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos ) const ;
1051         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
1052 };
1053 
1054 /*
1055 ============================================================
1056 ===================== ChemicalElement ======================
1057 ============================================================
1058 */
1059 
1060 class ChemicalElement : public SymbolBase {
1061 
1062     private:
1063         int m_Z;                                        /**< A atomic number for all isotopes in *thie* chemical element. */
1064         std::string m_name;                             /**< The name of the chemical element. */
1065         Suite<Isotope, ChemicalElement> m_isotopes;     /**< The suite of isotopes for this chemical element. */
1066 
1067     public:
1068        ChemicalElement( HAPI::Node const &a_node, Database *a_DB, Database *a_parent );
1069         virtual ~ChemicalElement( );
1070 
1071         int Z( void ) const { return( m_Z ); }                          /**< Returns the value of the *m_Z* member. */
1072         std::string const &name( void ) const { return( m_name ); }     /**< Returns the value of the *m_name* member. */
1073 
1074         Suite<Isotope, ChemicalElement> const &isotopes( ) const { return( m_isotopes ); }  /**< Returns a *const* reference to the *m_isotopes* member. */
1075 
1076         void calculateNuclideGammaBranchStateInfos( PoPI::Database const &a_pops, NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos ) const ;
1077         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
1078 };
1079 
1080 /*
1081 ============================================================
1082 =========================== Alias ==========================        // FIXME, there should be an alias base class that Alias and MetaStable inherit from.
1083 ============================================================
1084 */
1085 
1086 class Alias : public IDBase {
1087 
1088     private:
1089         std::string m_pid;                      /**< The id of the particle *this* is an alias for. */
1090         std::size_t m_pidIndex;                         /**< The index of the particle with id *m_pid*. */
1091 
1092     public:
1093         Alias( HAPI::Node const &a_node, Database *a_DB, Particle_class a_class = Particle_class::alias );
1094         virtual ~Alias( );
1095 
1096         std::string const &pid( void ) const { return( m_pid ); }       /**< Returns a *const* reference to the *m_pid* member of *this*. */
1097         std::size_t pidIndex( void ) const { return( m_pidIndex ); }            /**< Returns a *const* reference to the *m_pidIndex* member of *this*. */
1098         void setPidIndex( std::size_t a_index ) { m_pidIndex = a_index; }       /**< Set the member *m_pidIndex* to *a_index*. */
1099 
1100         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
1101 };
1102 
1103 /*
1104 ============================================================
1105 ======================== MetaStable ========================
1106 ============================================================
1107 */
1108 
1109 class MetaStable : public Alias {
1110 
1111     private:
1112         int m_metaStableIndex;                  /**< The meta-stable index for *this*. */
1113 
1114     public:
1115         MetaStable( HAPI::Node const &a_node, Database *a_DB );
1116         virtual ~MetaStable( );
1117 
1118         int metaStableIndex( void ) const { return( m_metaStableIndex ); }                          /**< Returns the value of the *m_metaStableIndex* member. */
1119         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
1120 };
1121 
1122 /*
1123 ============================================================
1124 ========================= Database =========================
1125 ============================================================
1126 */
1127 
1128 class Database {
1129 
1130     private:
1131         LUPI::FormatVersion m_formatVersion;                            /**< The **GNDS** **format** attribute of the first file read. */
1132         std::string m_name;                                             /**< The **GNDS** **name** of the first file read in. */
1133         std::string m_version;                                          /**< The **GNDS** **version** of the first file read in. */
1134         ParticleList m_list;                                            /**< The internal list of the particles. */
1135         std::map<std::string, std::size_t> m_idsMap;    // Be careful with this as a map[key] will add key if it is not in the map.
1136         std::map<int, std::size_t> m_intidsMap;         // Be careful with this as a map[key] will add key if it is not in the map.
1137                                                                         /**< This maps each particle id to a unique index. */
1138         SymbolList m_symbolList;                                        /**< The internal list of the symbols. */
1139         std::map<std::string, std::size_t> m_symbolMap; // Be careful with this as a map[key] will add key if it is not in the map.
1140                                                                         /**< This maps each symbol to a unique index. */
1141 
1142         std::vector<Alias *> m_unresolvedAliases;                       /**< This is used internally to store aliases when a **PoPs** node is being parsed as the aliases onde is parsed before the particles are parsed. */
1143         std::vector<Alias *> m_aliases;                                 /**< Represents the **PoPs** *aliases* node which contains a list of the **PoPs** **alias** and **metaStable** nodes. */
1144 
1145         Suite<GaugeBoson, Database> m_gaugeBosons;                      /**< Represents the **PoPs** **gaugeBosons** node which contains a list of the **PoPs** **gaugeBoson** nodes. */
1146         Suite<Lepton, Database> m_leptons;                              /**< Represents the **PoPs** **leptons** node which contains a list of the **PoPs** **lepton** nodes. */
1147         Suite<Baryon, Database> m_baryons;                              /**< Represents the **PoPs** **baryons** node which contains a list of the **PoPs** **baryon** nodes. */
1148         Suite<ChemicalElement, Database> m_chemicalElements;            /**< Represents the **PoPs** **chemicalElements** node which contains a list of the **PoPs** **chemicalElement** nodes. */
1149         Suite<Unorthodox, Database> m_unorthodoxes;                     /**< Represents the **PoPs** **unorthodoxes** node which contains a list of the **PoPs** **unorthodox** nodes. */
1150 
1151     public:
1152         Database( );
1153         Database( std::string const &a_fileName );
1154         Database( HAPI::Node const &a_database );
1155         ~Database( );
1156 
1157         LUPI::FormatVersion const &formatVersion( void ) const { return( m_formatVersion ); }   /**< Returns a *const* *reference* to the *m_formatVersion* variable of *this*. */
1158         std::string const &name( void ) const { return( m_name ); }                         /**< Returns a *const* *reference* to the *m_name* variable of *this*. */
1159         std::string const &version( void ) const { return( m_version ); }                   /**< Returns a *const* *reference* to the *m_version* variable of *this*. */
1160 
1161         std::vector<Alias *> unresolvedAliases( ) { return( m_unresolvedAliases ); }      /**< Returns a *reference* to the *m_unresolvedAliases* member of *this*. */
1162         std::size_t numberOfUnresolvedAliases( ) { return( m_unresolvedAliases.size( ) ); }     /**< Returns the number of unresolved aliases. */
1163         std::vector<std::string> unresolvedAliasIds( ) const ;
1164         std::vector<Alias *> &aliases( ) { return( m_aliases ); }                            /**< Returns a *const* *reference* to the *m_aliases* variable of *this*. */
1165 
1166         void addFile( char const *a_fileName, bool a_warnIfDuplicate );
1167         void addFile( std::string const &a_fileName, bool a_warnIfDuplicate );
1168         void addDatabase( std::string const &a_string, bool a_warnIfDuplicate );
1169         void addDatabase( HAPI::Node const &a_database, bool a_warnIfDuplicate );
1170         void addAlias( Alias *a_alias ) { m_aliases.push_back( a_alias ); }                 /**< Added the **Alias** *a_alias* to *this*. */
1171 
1172         std::string::size_type size( void ) const { return( m_list.size( ) ); }             /**< Returns the number of particle in *this*. */
1173         ParticleList const &list( ) { return( m_list ); }                                    /**< Returns a *const* *reference* to the *m_list* member. */
1174         SymbolList const &symbolList( ) { return( m_symbolList ); }                          /**< Returns a *const* *reference* to the *m_symbolList* member. */
1175         std::size_t operator[]( std::string const &a_id ) const ;
1176         template<typename T> T const &get( std::string const &a_id ) const ;
1177         template<typename T> T const &get( std::size_t a_index ) const ;
1178         Particle const &particle( std::string const &a_id ) const { return( get<Particle>( a_id ) ); }  /**< Returns a *const* *reference* to the particle with id *a_id*. */
1179         Particle const &particle( std::size_t a_index ) const { return( get<Particle>( a_index ) ); }   /**< Returns a *const* *reference* to the particle with index *a_index*. */
1180         IDBase const &idBase( std::string const &a_id ) const { return( get<IDBase>( a_id ) ); }        /**< Returns a *const* *reference* to a **IDBase** instance with id *a_id*. */
1181         IDBase const &idBase( std::size_t &a_index ) const { return( get<IDBase>( a_index ) ); }        /**< Returns a *const* *reference* to a **IDBase** instance with id *a_index*. */
1182         ParticleList const &particleList( ) const { return( m_list ); }                                 /**< Returns a *const* *reference* to the *m_list* variable of *this*. */
1183         SymbolList symbolList( ) const { return( m_symbolList ); }                                      /**< Returns a *const* *reference* to the *m_symbolList* variable of *this*. */
1184 
1185         bool exists( std::string const &a_id ) const ;
1186         bool exists( std::size_t a_index ) const ;
1187         bool existsIntid( int a_intid ) const ;
1188 
1189         Suite<ChemicalElement, Database> const &chemicalElements( ) const { return( m_chemicalElements ); }
1190                                                                                             /**< Returns a *const* *reference* to the *m_chemicalElements* variable of *this*. */
1191 
1192         bool isParticle( std::string const &a_id ) const { return( get<Base>( a_id ).isParticle( ) ); } /**< Returns **true** if *a_id* is a particle and **false** otherwise. */
1193         bool isParticle( std::size_t a_index ) const { return( m_list[a_index]->isParticle( ) ); }      /**< Returns **true** if *a_index* is a particle and **false** otherwise. */
1194         bool isAlias( std::string const &a_id ) const { return( get<Base>( a_id ).isAlias( ) ); }       /**< Returns **true** if *a_id* is an alias and **false** otherwise. */
1195         bool isAlias( std::size_t a_index ) const { return( m_list[a_index]->isAlias( ) ); }            /**< Returns **true** if *a_index* is an alias and **false** otherwise. */
1196         bool isMetaStableAlias( std::string const &a_id ) const { return( get<Base>( a_id ).isMetaStableAlias( ) ); }
1197                                                                                                         /**< Returns **true** if *a_id* is a meta-stable and **false** otherwise. */
1198         bool isMetaStableAlias( std::size_t a_index ) const { return( m_list[a_index]->isMetaStableAlias( ) ); }
1199                                                                                                         /**< Returns **true** if *a_index* is a meta-stable and **false** otherwise. */
1200         std::vector<std::string> aliasReferences( std::string const &a_id );
1201 
1202         std::string final( std::string const &a_id, bool a_returnAtMetaStableAlias = false ) const ;
1203         std::size_t final( std::size_t a_index, bool a_returnAtMetaStableAlias = false ) const ;
1204 
1205         std::string chemicalElementSymbol( std::string const &a_id ) const ;
1206         std::string isotopeSymbol( std::string const &a_id ) const ;
1207         int intid( std::string const &a_id ) const ;
1208         int intid( std::size_t a_index ) const ;
1209         std::size_t indexFromIntid( int a_intid ) const ;
1210 
1211         std::size_t add( Base *a_item );
1212         std::size_t addSymbol( SymbolBase *a_item );
1213 
1214         void calculateNuclideGammaBranchStateInfos( NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos, Database const *a_pops2,
1215                 std::vector<std::string> &a_extraGammaBranchStates ) const ;
1216         void calculateNuclideGammaBranchStateInfos2( NuclideGammaBranchStateInfos &a_nuclideGammaBranchStateInfos ) const ;
1217 
1218         double massValue( std::string const &a_id, std::string const &a_unit ) const ;
1219 
1220         void saveAs( std::string const &a_fileName ) const ;
1221         void toXMLList( std::vector<std::string> &a_XMLList, std::string const &a_indent1 ) const ;
1222         void print( bool a_printIndices );
1223 };
1224 
1225 /* *********************************************************************************************************//**
1226  * Returns the partile in *this* that has index *a_index*.
1227  *
1228  * @param a_index                       [in]    The index of the particle to return.
1229  *
1230  * @return                                      A *const* reference to the particle at index *a_index*.
1231  ***********************************************************************************************************/
1232 
1233 template<typename T> T const &Database::get( std::size_t a_index ) const {
1234 
1235     Base *particle = m_list[a_index];
1236     if( particle == nullptr ) throw std::range_error( std::string( "particle not in database" ) );
1237     T const *object = dynamic_cast<T const *>( particle );
1238     if( object == nullptr ) throw std::bad_cast( );
1239 
1240     return( *object );
1241 }
1242 
1243 /* *********************************************************************************************************//**
1244  * Returns the partile in *this* that has index *a_index*.
1245  *
1246  * @param a_id                          [in]    The **PoPs** id of the particle to return.
1247  *
1248  * @return                                      A *const* reference to the particle with id *a_id*.
1249  ***********************************************************************************************************/
1250 
1251 template<typename T> T const &Database::get( std::string const &a_id ) const {
1252 
1253     auto index = (*this)[a_id];
1254     Base *particle = m_list[index];
1255     T const *object = dynamic_cast<T const *>( particle );
1256     if( object == nullptr ) throw std::bad_cast( );
1257 
1258     return( *object );
1259 }
1260 
1261 double getPhysicalQuantityAsDouble( PhysicalQuantity const &a_physicalQuantity );
1262 double getPhysicalQuantityOfSuiteAsDouble( PQ_suite const &a_suite, bool a_allowEmpty = false, double a_emptyValue = 0.0 );
1263 bool supportedFormat( LUPI::FormatVersion const &a_formatVersion );
1264 std::string baseAntiQualifierFromID( std::string const &a_id, std::string &a_anti, std::string *a_qualifier = nullptr );
1265 
1266 int maximumChemicalElementZ( );
1267 std::string chemicalElementInfoFromZ( int a_Z, bool a_wantSymbol, bool a_asNucleus = false );
1268 std::string const &chemicalElementSymbolFromZ( int a_Z );
1269 int Z_FromChemicalElementSymbol( std::string const &a_symbol );
1270 
1271 int family2Integer( Particle_class a_family );
1272 int intidHelper( bool a_isAnti, Particle_class a_family, int a_SSSSSSS );
1273 
1274 }
1275 
1276 #endif      // End of PoPI_hpp_included