Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/particles/management/src/G4NuclideTable.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /particles/management/src/G4NuclideTable.cc (Version 11.3.0) and /particles/management/src/G4NuclideTable.cc (Version 10.1.p2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4NuclideTable class implementation         <<  26 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                                                   >>  27 //
                                                   >>  28 // MODULE:              G4NuclideTable.cc
                                                   >>  29 //
                                                   >>  30 // Date:                10/10/13
                                                   >>  31 // Author:              T.Koi
                                                   >>  32 //
                                                   >>  33 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                                                   >>  34 //
                                                   >>  35 // HISTORY
                                                   >>  36 // Based on G4IsomerTable
                                                   >>  37 ////////////////////////////////////////////////////////////////////////////////
 27 //                                                 38 //
 28 // Author: T.Koi, SLAC - 10 October 2013       << 
 29 // ------------------------------------------- << 
 30                                                << 
 31 #include "G4NuclideTable.hh"                       39 #include "G4NuclideTable.hh"
 32                                                    40 
 33 #include "G4NuclideTableMessenger.hh"          << 
 34 #include "G4PhysicalConstants.hh"              << 
 35 #include "G4String.hh"                         << 
 36 #include "G4SystemOfUnits.hh"                  << 
 37 #include "G4ios.hh"                                41 #include "G4ios.hh"
 38 #include "globals.hh"                              42 #include "globals.hh"
 39                                                <<  43 #include "G4PhysicalConstants.hh"
 40 #include <fstream>                             <<  44 #include "G4SystemOfUnits.hh"
 41 #include <iomanip>                                 45 #include <iomanip>
                                                   >>  46 #include <fstream>
 42 #include <sstream>                                 47 #include <sstream>
 43                                                    48 
 44 G4NuclideTable* G4NuclideTable::GetInstance()  <<  49 const G4double G4NuclideTable::levelTolerance = 1.0*eV;
 45 {                                              <<  50 // const G4double G4NuclideTable::levelTolerance = 1.0e-3*eV;
 46   static G4NuclideTable instance;              <<  51 //  torelance for excitation energy
 47   return &instance;                            <<  52   
 48 }                                              <<  53  
 49                                                <<  54 ///////////////////////////////////////////////////////////////////////////////
 50 G4NuclideTable* G4NuclideTable::GetNuclideTabl <<  55 G4NuclideTable* G4NuclideTable::GetInstance() {
 51 {                                              <<  56    static G4NuclideTable instance;
 52   return GetInstance();                        <<  57    return &instance;
 53 }                                                  58 }
 54                                                    59 
                                                   >>  60 ///////////////////////////////////////////////////////////////////////////////
 55 G4NuclideTable::G4NuclideTable()                   61 G4NuclideTable::G4NuclideTable()
 56   : G4VIsotopeTable("Isomer"), mean_life_thres <<  62   :G4VIsotopeTable("Isomer"),
                                                   >>  63    threshold_of_half_life(1000.0*ns),
                                                   >>  64    fUserDefinedList(NULL), 
                                                   >>  65    fIsotopeList(0) 
 57 {                                                  66 {
 58   fMessenger = new G4NuclideTableMessenger(thi <<  67   //SetVerboseLevel(G4ParticleTable::GetParticleTable()->GetVerboseLevel());
 59   fIsotopeList = new G4IsotopeList();          <<  68   FillHardCodeList();
 60   GenerateNuclide();                           << 
 61 }                                                  69 }
 62                                                    70 
                                                   >>  71 ///////////////////////////////////////////////////////////////////////////////
 63 G4NuclideTable::~G4NuclideTable()                  72 G4NuclideTable::~G4NuclideTable()
 64 {                                                  73 {
 65   for (auto& it : map_pre_load_list) {         <<  74   if (fIsotopeList!=0) {
 66     it.second.clear();                         <<  75     for (size_t i = 0 ; i<fIsotopeList->size(); i++) {
                                                   >>  76       delete (*fIsotopeList)[i];
                                                   >>  77     }
                                                   >>  78     fIsotopeList->clear();
                                                   >>  79     delete fIsotopeList;
                                                   >>  80     fIsotopeList = 0;
 67   }                                                81   }
 68   map_pre_load_list.clear();                   << 
 69                                                    82 
 70   for (auto& it : map_full_list) {             <<  83   for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator 
 71     it.second.clear();                         <<  84      it = map_pre_load_list.begin(); it != map_pre_load_list.end(); it++ ) {
                                                   >>  85      it->second.clear();
 72   }                                                86   }
 73   map_full_list.clear();                       <<  87   map_pre_load_list.clear();
 74                                                    88 
 75   if (fIsotopeList != nullptr) {               <<  89   for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator 
 76     for (const auto& i : *fIsotopeList) {      <<  90      it = map_hard_code_list.begin(); it != map_hard_code_list.end(); it++ ) {
 77       delete i;                                <<  91      for ( std::multimap< G4double , G4IsotopeProperty* >::iterator 
 78     }                                          <<  92         itt = it->second.begin(); itt != it->second.end(); itt++ ) {
 79     fIsotopeList->clear();                     <<  93         delete itt->second;
 80     delete fIsotopeList;                       <<  94      }
 81     fIsotopeList = nullptr;                    <<  95      it->second.clear();
                                                   >>  96   }
                                                   >>  97   map_hard_code_list.clear();
                                                   >>  98 
                                                   >>  99   for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator 
                                                   >> 100      it = map_full_list.begin(); it != map_full_list.end(); it++ ) {
                                                   >> 101      for ( std::multimap< G4double , G4IsotopeProperty* >::iterator 
                                                   >> 102         itt = it->second.begin(); itt != it->second.end(); itt++ ) {
                                                   >> 103         delete itt->second;
                                                   >> 104      }
                                                   >> 105      it->second.clear();
 82   }                                               106   }
 83   delete fMessenger;                           << 107   map_full_list.clear();
 84 }                                                 108 }
 85                                                   109 
 86 G4IsotopeProperty* G4NuclideTable::GetIsotope( << 110 ///////////////////////////////////////////////////////////////////////////////
 87                                                << 111 //
                                                   >> 112 G4IsotopeProperty* G4NuclideTable::GetIsotope(G4int Z, G4int A, G4double E)
 88 {                                                 113 {
 89   G4IsotopeProperty* fProperty = nullptr;      << 
 90                                                   114 
 91   // At first searching UserDefined            << 115    G4IsotopeProperty* fProperty = 0;
 92   if (fUserDefinedList != nullptr) {           << 116    G4int ionCode = 1000*Z + A;
 93     for (const auto it : *fUserDefinedList) {  << 117 
 94       if (Z == it->GetAtomicNumber() && A == i << 118    //Serching pre-load
 95         G4double levelE = it->GetEnergy();     << 119    //Note: isomer level is properly set only for pre_load_list.
 96         if (levelE - flevelTolerance / 2 <= E  << 120    if ( map_pre_load_list.find( ionCode ) !=  map_pre_load_list.end() ) {
 97           if (flb == it->GetFloatLevelBase())  << 121 
 98             return it;                         << 122      std::multimap< G4double , G4IsotopeProperty* >::iterator lower_bound_itr = 
 99           }  // found                          << 123        map_pre_load_list.find( ionCode ) -> second.lower_bound ( E - levelTolerance/2 );
100         }                                      << 124      
                                                   >> 125      //std::multimap< G4double , G4IsotopeProperty* >::iterator upper_bound_itr = 
                                                   >> 126      //map_pre_load_list.find( ionCode ) -> second.upper_bound ( E );
                                                   >> 127      
                                                   >> 128      G4double levelE = DBL_MAX;
                                                   >> 129      if ( lower_bound_itr !=  map_pre_load_list.find( ionCode ) -> second.end() ) {
                                                   >> 130        levelE = lower_bound_itr->first;
                                                   >> 131        if ( levelE - levelTolerance/2 <= E && E < levelE + levelTolerance/2 ) {
                                                   >> 132          return lower_bound_itr->second; // found
                                                   >> 133        } 
                                                   >> 134      }
                                                   >> 135    }
                                                   >> 136      
                                                   >> 137    //Searching hard-code
                                                   >> 138    if ( map_hard_code_list.find( ionCode ) !=  map_hard_code_list.end() ) {
                                                   >> 139       std::multimap< G4double , G4IsotopeProperty* >::iterator lower_bound_itr = 
                                                   >> 140       map_hard_code_list.find( ionCode ) -> second.lower_bound ( E - levelTolerance/2 );
                                                   >> 141 
                                                   >> 142       //std::multimap< G4double , G4IsotopeProperty* >::iterator upper_bound_itr = 
                                                   >> 143       //map_pre_load_list.find( ionCode ) -> second.upper_bound ( E );
                                                   >> 144       
                                                   >> 145       G4double levelE = DBL_MAX;
                                                   >> 146       if ( lower_bound_itr !=  map_hard_code_list.find( ionCode ) -> second.end() ) {
                                                   >> 147          levelE = lower_bound_itr->first;
                                                   >> 148    if ( levelE - levelTolerance/2 <= E && E < levelE + levelTolerance/2 ) {
                                                   >> 149      return lower_bound_itr->second; // found
                                                   >> 150    }
101       }                                           151       }
102     }                                          << 152    }
103   }                                            << 153 
                                                   >> 154    //Searching big-list 
                                                   >> 155    char* path = getenv("G4ENSDFSTATEDATA");
                                                   >> 156 
                                                   >> 157    if ( !path ) {
                                                   >> 158       return fProperty; // not found;
                                                   >> 159    }
                                                   >> 160 
                                                   >> 161    if ( map_full_list.find( ionCode ) ==  map_full_list.end() ) {
                                                   >> 162 
                                                   >> 163       std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
                                                   >> 164       map_full_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
104                                                   165 
105   // Searching pre-load                        << 166       std::fstream ifs;
106   // Note: isomer level is properly set only f << 167       G4String filename(path);
107   //                                           << 168       filename += "/ENSDFSTATE.dat";
108   G4int ionCode = 1000 * Z + A;                << 169       ifs.open( filename.c_str() );
109   auto itf = map_pre_load_list.find(ionCode);  << 170 
110                                                << 171       G4bool reading_target = false; 
111   if (itf != map_pre_load_list.cend()) {       << 172 
112     auto lower_bound_itr = itf->second.lower_b << 173       G4int ionZ;
113     G4double levelE = DBL_MAX;                 << 174       G4int ionA;
114                                                << 175       G4double ionE;
115     while (lower_bound_itr != itf->second.cend << 176       G4double ionLife;
116       levelE = lower_bound_itr->first;         << 177       G4int ionJ;
117       if (levelE - flevelTolerance / 2 <= E && << 178       G4double ionMu;
118         if (flb == (lower_bound_itr->second)-> << 179       
119           return lower_bound_itr->second;  //  << 180       ifs >> ionZ >> ionA >> ionE >> ionLife >> ionJ >> ionMu;
120         }                                      << 181 
                                                   >> 182       while ( ifs.good() ) {
                                                   >> 183 
                                                   >> 184          if ( ionZ == Z && ionA == A ) {
                                                   >> 185 
                                                   >> 186             reading_target = true;
                                                   >> 187 
                                                   >> 188             ionE *= keV;
                                                   >> 189             ionLife *= ns;
                                                   >> 190             ionMu *= (joule/tesla);
                                                   >> 191 
                                                   >> 192             G4IsotopeProperty* property = new G4IsotopeProperty(); 
                                                   >> 193 
                                                   >> 194             G4int iLevel=9;
                                                   >> 195             property->SetAtomicNumber(ionZ);
                                                   >> 196             property->SetAtomicMass(ionA);
                                                   >> 197             property->SetIsomerLevel(iLevel);
                                                   >> 198             property->SetEnergy(ionE);
                                                   >> 199             property->SetiSpin(ionJ);
                                                   >> 200             property->SetLifeTime(ionLife);
                                                   >> 201             property->SetMagneticMoment(ionMu);
                                                   >> 202        
                                                   >> 203             map_full_list.find ( ionCode ) -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , property ) );
                                                   >> 204 
                                                   >> 205          } else if ( reading_target == true ) {
                                                   >> 206             ifs.close();
                                                   >> 207             break;
                                                   >> 208          }
                                                   >> 209          
                                                   >> 210          ifs >> ionZ >> ionA >> ionE >> ionLife >> ionJ >> ionMu;
121       }                                           211       }
122       else {                                   << 212 
123         break;                                 << 213       ifs.close();
                                                   >> 214    }
                                                   >> 215 
                                                   >> 216 
                                                   >> 217    if ( map_full_list.find( ionCode ) !=  map_full_list.end() ) {
                                                   >> 218 
                                                   >> 219       std::multimap< G4double , G4IsotopeProperty* >::iterator lower_bound_itr = 
                                                   >> 220       map_full_list.find( ionCode ) -> second.lower_bound ( E - levelTolerance/2 );
                                                   >> 221 
                                                   >> 222       //std::multimap< G4double , G4IsotopeProperty* >::iterator upper_bound_itr = 
                                                   >> 223       //map_full_list.find( ionCode ) -> second.upper_bound ( E - levelTolerance/2 );
                                                   >> 224       
                                                   >> 225       G4double levelE = DBL_MAX;
                                                   >> 226       if ( lower_bound_itr !=  map_full_list.find( ionCode ) -> second.end() ) {
                                                   >> 227          levelE = lower_bound_itr->first;
                                                   >> 228    if ( levelE - levelTolerance/2 < E && E < levelE + levelTolerance/2 ) {
                                                   >> 229      return lower_bound_itr->second; // found
                                                   >> 230    }
124       }                                           231       }
125       ++lower_bound_itr;                       << 232    }
126     }                                          << 
127   }                                            << 
128                                                   233 
129   return fProperty;  // not found              << 234    return fProperty; // not found;
130 }                                                 235 }
131                                                   236 
132 G4double G4NuclideTable::GetTruncationError(G4 << 237 ///////////////////////////////////////////////////////////////////////
                                                   >> 238 G4IsotopeProperty* 
                                                   >> 239  G4NuclideTable::GetIsotopeByIsoLvl(G4int Z, G4int A, G4int lvl)
133 {                                                 240 {
134   G4double tolerance = G4NuclideTable::GetInst << 241   if(lvl==0) return GetIsotope(Z,A,0.0);
135   return eex - (G4long)(eex / tolerance) * tol << 242   return (G4IsotopeProperty*)0;
136 }                                                 243 }
137                                                   244 
138 G4double G4NuclideTable::Round(G4double eex)   << 245 ///////////////////////////////////////////////////////////////////////////////
                                                   >> 246 void G4NuclideTable::FillHardCodeList()
139 {                                                 247 {
140   G4double tolerance = G4NuclideTable::GetInst << 248    for (size_t i=0; i<nEntries_ground_state; i++) {
141   return round(eex / tolerance) * tolerance;   << 
142 }                                              << 
143                                                   249 
144 G4long G4NuclideTable::Truncate(G4double eex)  << 250       G4int    ionZ     = (G4int)groundStateTable[i][idxZ];
145 {                                              << 251       G4int    ionA     = (G4int)groundStateTable[i][idxA];
146   G4double tolerance = G4NuclideTable::GetInst << 252       G4int    lvl      = 0; // ground state
147   return (G4long)(eex / tolerance);            << 253       G4double ionE     = groundStateTable[i][idxEnergy]*keV;
148 }                                              << 254       G4double ionLife  = groundStateTable[i][idxLife]*ns;
                                                   >> 255       G4int    ionJ     = (G4int)(groundStateTable[i][idxSpin]);
                                                   >> 256       G4double ionMu    = groundStateTable[i][idxMu]*(joule/tesla);
149                                                   257 
150 G4double G4NuclideTable::Tolerance()           << 258       G4int ionCode = 1000*ionZ + ionA;
151 {                                              << 
152   return G4NuclideTable::GetInstance()->GetLev << 
153 }                                              << 
154                                                   259 
155 G4IsotopeProperty* G4NuclideTable::GetIsotopeB << 260       G4IsotopeProperty* fProperty = new G4IsotopeProperty(); 
156 {                                              << 261 
157   if (lvl == 0) return GetIsotope(Z, A, 0.0);  << 262       // Set Isotope Property
158   return nullptr;                              << 263       fProperty->SetAtomicNumber(ionZ);
                                                   >> 264       fProperty->SetAtomicMass(ionA);
                                                   >> 265       fProperty->SetIsomerLevel(lvl);
                                                   >> 266       fProperty->SetEnergy(ionE);
                                                   >> 267       fProperty->SetiSpin(ionJ);
                                                   >> 268       fProperty->SetLifeTime(ionLife);
                                                   >> 269       fProperty->SetDecayTable(0);
                                                   >> 270       fProperty->SetMagneticMoment(ionMu);
                                                   >> 271 
                                                   >> 272       if ( map_hard_code_list.find ( ionCode ) == map_hard_code_list.end() ) {
                                                   >> 273          std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
                                                   >> 274          map_hard_code_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
                                                   >> 275       }
                                                   >> 276       map_hard_code_list.find ( ionCode ) -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , fProperty ) );
                                                   >> 277 
                                                   >> 278    }
                                                   >> 279 
                                                   >> 280    for (size_t i=0; i<nEntries_excite_state; i++) {
                                                   >> 281 
                                                   >> 282       G4int    ionZ     = (G4int)exciteStateTable[i][idxZ];
                                                   >> 283       G4int    ionA     = (G4int)exciteStateTable[i][idxA];
                                                   >> 284       G4double ionE     = exciteStateTable[i][idxEnergy]*keV;
                                                   >> 285       G4double ionLife  = exciteStateTable[i][idxLife]*ns;
                                                   >> 286       G4int    ionJ     = (G4int)(exciteStateTable[i][idxSpin]);
                                                   >> 287       G4double ionMu    = exciteStateTable[i][idxMu]*(joule/tesla);
                                                   >> 288 
                                                   >> 289       G4int ionCode = 1000*ionZ + ionA;
                                                   >> 290 
                                                   >> 291       G4IsotopeProperty* fProperty = new G4IsotopeProperty(); 
                                                   >> 292 
                                                   >> 293       // Set Isotope Property
                                                   >> 294       fProperty->SetAtomicNumber(ionZ);
                                                   >> 295       fProperty->SetAtomicMass(ionA);
                                                   >> 296       fProperty->SetIsomerLevel(9);
                                                   >> 297       fProperty->SetEnergy(ionE);
                                                   >> 298       fProperty->SetiSpin(ionJ);
                                                   >> 299       fProperty->SetLifeTime(ionLife);
                                                   >> 300       fProperty->SetDecayTable(0);
                                                   >> 301       fProperty->SetMagneticMoment(ionMu);
                                                   >> 302 
                                                   >> 303       if ( map_hard_code_list.find ( ionCode ) == map_hard_code_list.end() ) {
                                                   >> 304          std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
                                                   >> 305          map_hard_code_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
                                                   >> 306       }
                                                   >> 307       map_hard_code_list.find ( ionCode ) -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , fProperty ) );
                                                   >> 308 
                                                   >> 309    }
159 }                                                 310 }
160                                                   311 
                                                   >> 312 ///////////////////////////////////////////////////////////////////////////////
161 void G4NuclideTable::GenerateNuclide()            313 void G4NuclideTable::GenerateNuclide()
162 {                                                 314 {
163   if (mean_life_threshold < minimum_mean_life_ << 
164     // Need to update full list                << 
165     const char* path = G4FindDataDir("G4ENSDFS << 
166                                                << 
167     if (path == nullptr) {                     << 
168       G4Exception("G4NuclideTable", "PART70000 << 
169                   "G4ENSDFSTATEDATA environmen << 
170       return;                                  << 
171     }                                          << 
172                                                   315 
173     std::ifstream ifs;                         << 316    if( fIsotopeList !=0 ) return;
174     G4String filename(path);                   << 317    fIsotopeList = new G4IsotopeList();
175     filename += "/ENSDFSTATE.dat";             << 
176                                                << 
177     ifs.open(filename.c_str());                << 
178     if (!ifs.good()) {                         << 
179       G4Exception("G4NuclideTable", "PART70001 << 
180       return;                                  << 
181     }                                          << 
182                                                   318 
183     G4int ionCode = 0;                         << 319    for (size_t i=0; i<nEntries_ground_state; i++) {
184     G4int iLevel = 0;                          << 
185     G4int ionZ;                                << 
186     G4int ionA;                                << 
187     G4double ionE;                             << 
188     G4String ionFL;                            << 
189     G4double ionLife;                          << 
190     G4int ionJ;                                << 
191     G4double ionMu;                            << 
192                                                << 
193     // Lifetimes read from ENSDFSTATE are mean << 
194     ifs >> ionZ >> ionA >> ionE >> ionFL >> io << 
195                                                << 
196     while (ifs.good())  // Loop checking, 09.0 << 
197     {                                          << 
198       if (ionCode != 1000 * ionZ + ionA) {     << 
199         iLevel = 0;                            << 
200         ionCode = 1000 * ionZ + ionA;          << 
201       }                                        << 
202                                                << 
203       ionE *= keV;                             << 
204       G4Ions::G4FloatLevelBase flb = StripFloa << 
205       ionLife *= ns;                           << 
206       ionMu *= (joule / tesla);                << 
207                                                << 
208       if ((ionE == 0 && flb == G4Ions::G4Float << 
209           || (mean_life_threshold <= ionLife & << 
210       {                                        << 
211         if (ionE > 0) ++iLevel;                << 
212         if (iLevel > 9) iLevel = 9;            << 
213                                                << 
214         auto fProperty = new G4IsotopeProperty << 
215                                                << 
216         // Set Isotope Property                << 
217         fProperty->SetAtomicNumber(ionZ);      << 
218         fProperty->SetAtomicMass(ionA);        << 
219         fProperty->SetIsomerLevel(iLevel);     << 
220         fProperty->SetEnergy(ionE);            << 
221         fProperty->SetiSpin(ionJ);             << 
222         fProperty->SetLifeTime(ionLife);       << 
223         fProperty->SetDecayTable(nullptr);     << 
224         fProperty->SetMagneticMoment(ionMu);   << 
225         fProperty->SetFloatLevelBase(flb);     << 
226                                                << 
227         fIsotopeList->push_back(fProperty);    << 
228                                                << 
229         auto itf = map_full_list.find(ionCode) << 
230         if (itf == map_full_list.cend()) {     << 
231           std::multimap<G4double, G4IsotopePro << 
232           itf = (map_full_list.insert(std::pai << 
233                    ionCode, aMultiMap)))       << 
234                   .first;                      << 
235         }                                      << 
236         itf->second.insert(std::pair<G4double, << 
237       }                                        << 
238                                                   320 
239       ifs >> ionZ >> ionA >> ionE >> ionFL >>  << 321       G4int    ionZ     = (G4int)groundStateTable[i][idxZ];
240     }  // End while                            << 322       G4int    ionA     = (G4int)groundStateTable[i][idxA];
                                                   >> 323       G4int    lvl      = 0; // ground state
                                                   >> 324       G4double ionE     = groundStateTable[i][idxEnergy]*keV;
                                                   >> 325       G4double ionLife  = groundStateTable[i][idxLife]*ns;
                                                   >> 326       G4int    ionJ     = (G4int)(groundStateTable[i][idxSpin]);
                                                   >> 327       G4double ionMu    = groundStateTable[i][idxMu]*(joule/tesla);
                                                   >> 328 
                                                   >> 329       if ( ionLife < 0.0 || ionLife*std::log(2.0) > threshold_of_half_life ) {
                                                   >> 330 
                                                   >> 331          G4IsotopeProperty* fProperty = new G4IsotopeProperty(); 
                                                   >> 332 
                                                   >> 333          // Set Isotope Property
                                                   >> 334          fProperty->SetAtomicNumber(ionZ);
                                                   >> 335          fProperty->SetAtomicMass(ionA);
                                                   >> 336          fProperty->SetIsomerLevel(lvl);
                                                   >> 337          fProperty->SetEnergy(ionE);
                                                   >> 338          fProperty->SetiSpin(ionJ);
                                                   >> 339          fProperty->SetLifeTime(ionLife);
                                                   >> 340          fProperty->SetDecayTable(0);
                                                   >> 341          fProperty->SetMagneticMoment(ionMu);
                                                   >> 342     
                                                   >> 343          //G4cout << ionZ << " " << ionA << " " << lvl << " " << ionE/keV << " [keV]" << G4endl;
                                                   >> 344          fIsotopeList->push_back(fProperty);
                                                   >> 345 
                                                   >> 346          G4int ionCode = 1000*ionZ + ionA;
                                                   >> 347          if ( map_pre_load_list.find ( ionCode ) == map_pre_load_list.end() ) {
                                                   >> 348             std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
                                                   >> 349             map_pre_load_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
                                                   >> 350          }
                                                   >> 351          map_pre_load_list.find ( ionCode ) -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , fProperty ) );
241                                                   352 
242     minimum_mean_life_threshold = mean_life_th << 353       }
243   }                                            << 354    }
244                                                   355 
245   // Clear current map                         << 356    if ( threshold_of_half_life >= 1.0*ns ) {
246   for (auto& it : map_pre_load_list) {         << 
247     it.second.clear();                         << 
248   }                                            << 
249   map_pre_load_list.clear();                   << 
250                                                   357 
251   // Build map based on current threshold valu << 358       G4int ionCode=0;
252   for (const auto& it : map_full_list) {       << 359       G4int iLevel=0;
253     G4int ionCode = it.first;                  << 360       G4double previousE=0.0;
254     auto itf = map_pre_load_list.find(ionCode) << 361       
255     if (itf == map_pre_load_list.cend()) {     << 362       for (size_t i=0; i<nEntries_excite_state; i++) {
256       std::multimap<G4double, G4IsotopePropert << 363 
257       itf = (map_pre_load_list.insert(         << 364          G4int    ionZ     = (G4int)exciteStateTable[i][idxZ];
258                std::pair<G4int, std::multimap< << 365          G4int    ionA     = (G4int)exciteStateTable[i][idxA];
259               .first;                          << 366          if ( ionCode != 1000*ionZ + ionA ) {
260     }                                          << 367             previousE=0.0;
                                                   >> 368             iLevel = 0;
                                                   >> 369             ionCode = 1000*ionZ + ionA;
                                                   >> 370          } 
                                                   >> 371 
                                                   >> 372          G4double ionE     = exciteStateTable[i][idxEnergy]*keV;
                                                   >> 373          G4double ionLife  = exciteStateTable[i][idxLife]*ns;
                                                   >> 374          G4int    ionJ     = (G4int)(exciteStateTable[i][idxSpin]);
                                                   >> 375          G4double ionMu    = exciteStateTable[i][idxMu]*(joule/tesla);
                                                   >> 376 
                                                   >> 377          if (( ionLife < 0.0 || ionLife*ionLife*std::log(2.0) > threshold_of_half_life )
                                                   >> 378            && (ionE > levelTolerance+previousE)) {
                                                   >> 379             previousE = ionE;
                                                   >> 380             iLevel++;
                                                   >> 381             if ( iLevel > 9 ) iLevel=9;
                                                   >> 382          //G4cout << ionZ << " " << ionA << " " << iLevel << " " << ionE/keV << " [keV]" << G4endl;
                                                   >> 383 
                                                   >> 384             G4IsotopeProperty* fProperty = new G4IsotopeProperty(); 
                                                   >> 385 
                                                   >> 386             // Set Isotope Property
                                                   >> 387             fProperty->SetAtomicNumber(ionZ);
                                                   >> 388             fProperty->SetAtomicMass(ionA);
                                                   >> 389             fProperty->SetIsomerLevel(iLevel);
                                                   >> 390             fProperty->SetEnergy(ionE);
                                                   >> 391             fProperty->SetiSpin(ionJ);
                                                   >> 392             fProperty->SetLifeTime(ionLife);
                                                   >> 393             fProperty->SetDecayTable(0);
                                                   >> 394             fProperty->SetMagneticMoment(ionMu);
                                                   >> 395        
                                                   >> 396             fIsotopeList->push_back(fProperty);
                                                   >> 397 
                                                   >> 398             if ( map_pre_load_list.find ( ionCode ) == map_pre_load_list.end() ) {
                                                   >> 399                std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
                                                   >> 400                map_pre_load_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
                                                   >> 401             }
                                                   >> 402             map_pre_load_list.find ( ionCode ) -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , fProperty ) );
261                                                   403 
262     G4int iLevel = 0;                          << 404          }
263     for (const auto& itt : it.second) {        << 
264       G4double exEnergy = itt.first;           << 
265       G4double meanLife = itt.second->GetLifeT << 
266       if (exEnergy == 0.0 || meanLife > mean_l << 
267         if (itt.first != 0.0) ++iLevel;        << 
268         if (iLevel > 9) iLevel = 9;            << 
269         itt.second->SetIsomerLevel(iLevel);    << 
270         itf->second.insert(std::pair<G4double, << 
271       }                                           405       }
272     }                                          << 406    } else {
273   }                                            << 
274 }                                              << 
275                                                << 
276 void G4NuclideTable::AddState(G4int ionZ, G4in << 
277                               G4double ionMu)  << 
278 {                                              << 
279   if (G4Threading::IsMasterThread()) {         << 
280     G4int flbIndex = 0;                        << 
281     ionE = StripFloatLevelBase(ionE, flbIndex) << 
282     AddState(ionZ, ionA, ionE, flbIndex, ionLi << 
283   }                                            << 
284 }                                              << 
285                                                   407 
286 void G4NuclideTable::AddState(G4int ionZ, G4in << 408       char* path = getenv("G4ENSDFSTATEDATA");
287                               G4double ionLife << 
288 {                                              << 
289   if (G4Threading::IsMasterThread()) {         << 
290     if (fUserDefinedList == nullptr) fUserDefi << 
291                                                   409 
292     auto fProperty = new G4IsotopeProperty();  << 410       if ( !path ) {
                                                   >> 411          G4Exception("G4NuclideTable", "PART70000",
                                                   >> 412                   FatalException, "G4ENSDFSTATEDATA environment variable must be set");
                                                   >> 413    return;
                                                   >> 414       }
                                                   >> 415    
                                                   >> 416       std::fstream ifs;
                                                   >> 417       G4String filename(path);
                                                   >> 418       filename += "/ENSDFSTATE.dat";
                                                   >> 419 
                                                   >> 420       ifs.open( filename.c_str() );
                                                   >> 421      
                                                   >> 422       if ( !ifs.good() ) {
                                                   >> 423          G4Exception("G4NuclideTable", "PART70001",
                                                   >> 424                   FatalException, "ENSDFSTATE.dat is not found.");
                                                   >> 425    return;
                                                   >> 426       }
                                                   >> 427      
293                                                   428 
294     // Set Isotope Property                    << 429       G4int ionCode=0;
295     fProperty->SetAtomicNumber(ionZ);          << 430       G4int iLevel=0;
296     fProperty->SetAtomicMass(ionA);            << 
297     fProperty->SetIsomerLevel(9);              << 
298     fProperty->SetEnergy(ionE);                << 
299     fProperty->SetiSpin(ionJ);                 << 
300     fProperty->SetLifeTime(ionLife);           << 
301     fProperty->SetDecayTable(nullptr);         << 
302     fProperty->SetMagneticMoment(ionMu);       << 
303     fProperty->SetFloatLevelBase(flbIndex);    << 
304                                                   431 
305     fUserDefinedList->push_back(fProperty);    << 432       G4int ionZ;
306     fIsotopeList->push_back(fProperty);        << 433       G4int ionA;
307   }                                            << 434       G4double ionE;
308 }                                              << 435       G4double ionLife;
                                                   >> 436       G4int ionJ;
                                                   >> 437       G4double ionMu;
                                                   >> 438       
                                                   >> 439       ifs >> ionZ >> ionA >> ionE >> ionLife >> ionJ >> ionMu;
                                                   >> 440 
                                                   >> 441       while ( ifs.good() ) {
                                                   >> 442 
                                                   >> 443          if ( ionCode != 1000*ionZ + ionA ) {
                                                   >> 444             iLevel = 0;
                                                   >> 445             ionCode = 1000*ionZ + ionA;
                                                   >> 446          } 
                                                   >> 447 
                                                   >> 448          ionE *= keV;
                                                   >> 449          ionLife *= ns;
                                                   >> 450          ionMu *= (joule/tesla);
                                                   >> 451 
                                                   >> 452          //if ( ionLife == -1 || ionLife > threshold_of_half_life ) {
                                                   >> 453          if ( ionLife*std::log(2.0) > threshold_of_half_life && ionE != 0 ) {
                                                   >> 454 
                                                   >> 455             iLevel++;
                                                   >> 456             if ( iLevel > 9 ) iLevel=9;
                                                   >> 457             //G4cout << ionZ << " " << ionA << " " << iLevel << " " << ionE/keV << " [keV]" << G4endl;
                                                   >> 458 
                                                   >> 459             G4IsotopeProperty* fProperty = new G4IsotopeProperty(); 
                                                   >> 460 
                                                   >> 461             // Set Isotope Property
                                                   >> 462             fProperty->SetAtomicNumber(ionZ);
                                                   >> 463             fProperty->SetAtomicMass(ionA);
                                                   >> 464             fProperty->SetIsomerLevel(iLevel);
                                                   >> 465             fProperty->SetEnergy(ionE);
                                                   >> 466             fProperty->SetiSpin(ionJ);
                                                   >> 467             fProperty->SetLifeTime(ionLife);
                                                   >> 468             fProperty->SetDecayTable(0);
                                                   >> 469             fProperty->SetMagneticMoment(ionMu);
                                                   >> 470        
                                                   >> 471             fIsotopeList->push_back(fProperty);
                                                   >> 472 
                                                   >> 473             if ( map_pre_load_list.find ( ionCode ) == map_pre_load_list.end() ) {
                                                   >> 474                std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
                                                   >> 475                map_pre_load_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
                                                   >> 476             }
                                                   >> 477             map_pre_load_list.find ( ionCode ) -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , fProperty ) );
309                                                   478 
310 void G4NuclideTable::AddState(G4int ionZ, G4in << 479          }
311                               G4double ionLife << 
312 {                                              << 
313   if (G4Threading::IsMasterThread()) {         << 
314     if (fUserDefinedList == nullptr) fUserDefi << 
315                                                   480 
316     auto fProperty = new G4IsotopeProperty();  << 481          ifs >> ionZ >> ionA >> ionE >> ionLife >> ionJ >> ionMu;
                                                   >> 482       }
317                                                   483 
318     // Set Isotope Property                    << 484    }
319     fProperty->SetAtomicNumber(ionZ);          << 
320     fProperty->SetAtomicMass(ionA);            << 
321     fProperty->SetIsomerLevel(9);              << 
322     fProperty->SetEnergy(ionE);                << 
323     fProperty->SetiSpin(ionJ);                 << 
324     fProperty->SetLifeTime(ionLife);           << 
325     fProperty->SetDecayTable(nullptr);         << 
326     fProperty->SetMagneticMoment(ionMu);       << 
327     fProperty->SetFloatLevelBase(flb);         << 
328                                                   485 
329     fUserDefinedList->push_back(fProperty);    << 486    if ( fUserDefinedList != NULL ) {
330     fIsotopeList->push_back(fProperty);        << 487       for ( G4IsotopeList::iterator it = fUserDefinedList->begin() ; it != fUserDefinedList->end() ; it++ ) {
331   }                                            << 488          fIsotopeList->push_back( *it );
332 }                                              << 489       }
                                                   >> 490    }
333                                                   491 
334 void G4NuclideTable::SetThresholdOfHalfLife(G4 << 
335 {                                              << 
336   if (G4Threading::IsMasterThread()) {         << 
337     mean_life_threshold = t / 0.69314718;      << 
338     GenerateNuclide();                         << 
339   }                                            << 
340 }                                                 492 }
341                                                   493 
342 // Set the mean life threshold for nuclides    << 494 void G4NuclideTable::AddState( G4int ionZ, G4int ionA, G4double ionE, G4double ionLife, G4int ionJ=0, G4double ionMu=0.0)
343 // All nuclides with mean lives greater than t << 
344 // for this run                                << 
345 void G4NuclideTable::SetMeanLifeThreshold(G4do << 
346 {                                                 495 {
347   if (G4Threading::IsMasterThread()) {         << 496    if ( fUserDefinedList == NULL ) fUserDefinedList = new G4IsotopeList();
348     mean_life_threshold = t;                   << 
349     GenerateNuclide();                         << 
350   }                                            << 
351 }                                              << 
352                                                   497 
353 G4double G4NuclideTable::StripFloatLevelBase(G << 498             G4IsotopeProperty* fProperty = new G4IsotopeProperty(); 
354 {                                              << 
355   G4double rem = std::fmod(E / (1.0E-3 * eV),  << 
356   flbIndex = G4int(rem);                       << 
357   return E - rem;                              << 
358 }                                              << 
359                                                   499 
360 G4Ions::G4FloatLevelBase G4NuclideTable::Strip << 500             // Set Isotope Property
361 {                                              << 501             fProperty->SetAtomicNumber(ionZ);
362   if (sFLB.empty() || 2 < sFLB.size()) {       << 502             fProperty->SetAtomicMass(ionA);
363     G4String text;                             << 503             fProperty->SetIsomerLevel(9);
364     text += sFLB;                              << 504             fProperty->SetEnergy(ionE);
365     text += " is not valid indicator of G4Ions << 505             fProperty->SetiSpin(ionJ);
366     text += "You may use a wrong version of EN << 506             fProperty->SetLifeTime(ionLife);
367     text += "Please use G4ENSDFSTATE-2.0 or la << 507             fProperty->SetDecayTable(0);
                                                   >> 508             fProperty->SetMagneticMoment(ionMu);
                                                   >> 509        
                                                   >> 510             fUserDefinedList->push_back(fProperty);
368                                                   511 
369     G4Exception("G4NuclideTable", "PART70002", << 
370   }                                            << 
371   G4Ions::G4FloatLevelBase flb = noFloat;      << 
372   if (!(sFLB == "-")) {                        << 
373     flb = G4Ions::FloatLevelBase(sFLB.back()); << 
374   }                                            << 
375   return flb;                                  << 
376 }                                                 512 }
                                                   >> 513 
377                                                   514