Geant4  10.02.p01
G4NuclideTable.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
27 //
28 // MODULE: G4NuclideTable.cc
29 //
30 // Date: 10/10/13
31 // Author: T.Koi
32 //
33 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 //
35 // HISTORY
36 // Based on G4IsomerTable
38 //
39 #include "G4NuclideTable.hh"
41 
42 #include "G4ios.hh"
43 #include "globals.hh"
44 #include "G4PhysicalConstants.hh"
45 #include "G4SystemOfUnits.hh"
46 #include <iomanip>
47 #include <fstream>
48 #include <sstream>
49 
50 // const G4double G4NuclideTable::levelTolerance =
51 // torelance for excitation energy
52 
53 
56  static G4NuclideTable instance;
57  return &instance;
58 }
59 
62  :G4VIsotopeTable("Isomer"),
63  threshold_of_half_life(1000.0*ns),
64  minimum_threshold_of_half_life(DBL_MAX),
65  fUserDefinedList(NULL),
66  fIsotopeList(NULL),
67  flevelTolerance(1.0*eV)
68 {
69  //SetVerboseLevel(G4ParticleTable::GetParticleTable()->GetVerboseLevel());
70  //FillHardCodeList();
74 }
75 
78 {
79 
80  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
81  it = map_pre_load_list.begin(); it != map_pre_load_list.end(); it++ ) {
82  it->second.clear();
83  }
84  map_pre_load_list.clear();
85 
86 
87  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
88  it = map_full_list.begin(); it != map_full_list.end(); it++ ) {
89  it->second.clear();
90  }
91  map_full_list.clear();
92 
93  if (fIsotopeList!=0) {
94  for (size_t i = 0 ; i<fIsotopeList->size(); i++) {
95  //G4IsotopeProperty* fProperty = (*fIsotopeList)[i]; std::cout << fProperty->GetAtomicNumber() << " " << fProperty->GetAtomicMass() << " " << fProperty->GetEnergy() << std::endl;
96  delete (*fIsotopeList)[i];
97  }
98  fIsotopeList->clear();
99  delete fIsotopeList;
100  fIsotopeList = 0;
101  }
102 
103 }
104 
106 //
108 {
109 
110  G4IsotopeProperty* fProperty = NULL;
111 
112  // At first searching UserDefined
113  if ( fUserDefinedList != NULL ) {
114  for ( G4IsotopeList::iterator it = fUserDefinedList->begin() ; it != fUserDefinedList->end() ; it++ ) {
115 
116  if ( Z == (*it)->GetAtomicNumber() && A == (*it)->GetAtomicMass() ) {
117  G4double levelE = (*it)->GetEnergy();
118  if ( levelE - flevelTolerance/2 <= E && E < levelE + flevelTolerance/2 ) {
119  return *it; //found
120  }
121  }
122 
123  }
124  }
125 
126  //Serching pre-load
127  //Note: isomer level is properly set only for pre_load_list.
128  //
129  G4int ionCode = 1000*Z + A;
130  std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator itf = map_pre_load_list.find( ionCode );
131 
132  if ( itf != map_pre_load_list.end() ) {
133  std::multimap< G4double , G4IsotopeProperty* >::iterator lower_bound_itr = itf -> second.lower_bound ( E - flevelTolerance/2 );
134  G4double levelE = DBL_MAX;
135  if ( lower_bound_itr != itf -> second.end() ) {
136  levelE = lower_bound_itr->first;
137  if ( levelE - flevelTolerance/2 <= E && E < levelE + flevelTolerance/2 ) {
138  return lower_bound_itr->second; // found
139  }
140  }
141  }
142 
143  return fProperty; // not found;
144 }
145 
149 {
150  if(lvl==0) return GetIsotope(Z,A,0.0);
151  return (G4IsotopeProperty*)0;
152 }
153 
156 {
157  ;
158 }
159 
162 {
163 
165 
166  // Need to update full list
167 
168  char* path = getenv("G4ENSDFSTATEDATA");
169 
170  if ( !path ) {
171  G4Exception("G4NuclideTable", "PART70000",
172  FatalException, "G4ENSDFSTATEDATA environment variable must be set");
173  return;
174  }
175 
176  std::ifstream ifs;
177  G4String filename(path);
178  filename += "/ENSDFSTATE.dat";
179 
180  ifs.open( filename.c_str() );
181 
182  if ( !ifs.good() ) {
183  G4Exception("G4NuclideTable", "PART70001",
184  FatalException, "ENSDFSTATE.dat is not found.");
185  return;
186  }
187 
188 
189  G4int ionCode=0;
190  G4int iLevel=0;
191 
192  G4int ionZ;
193  G4int ionA;
194  G4double ionE;
195  G4double ionLife;
196  G4int ionJ;
197  G4double ionMu;
198 
199  ifs >> ionZ >> ionA >> ionE >> ionLife >> ionJ >> ionMu;
200 
201  while ( ifs.good() ) {// Loop checking, 09.08.2015, K.Kurashige
202 
203  if ( ionCode != 1000*ionZ + ionA ) {
204  iLevel = 0;
205  ionCode = 1000*ionZ + ionA;
206  }
207 
208  ionE *= keV;
209  ionLife *= ns;
210  ionMu *= (joule/tesla);
211 
212  if ( ( ionE == 0 && minimum_threshold_of_half_life == DBL_MAX ) // ground state is alwyas build in very first attempt
213  || ( threshold_of_half_life <= ionLife*std::log(2.0) && ionLife*std::log(2.0) < minimum_threshold_of_half_life && ionE != 0 ) ) {
214 
215  if ( ionE > 0 ) iLevel++;
216  if ( iLevel > 9 ) iLevel=9;
217 
218  G4IsotopeProperty* fProperty = new G4IsotopeProperty();
219 
220  // Set Isotope Property
221  fProperty->SetAtomicNumber(ionZ);
222  fProperty->SetAtomicMass(ionA);
223  fProperty->SetIsomerLevel(iLevel);
224  fProperty->SetEnergy(ionE);
225  fProperty->SetiSpin(ionJ);
226  fProperty->SetLifeTime(ionLife);
227  fProperty->SetDecayTable(0);
228  fProperty->SetMagneticMoment(ionMu);
229 
230  fIsotopeList->push_back(fProperty);
231 
232  std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator itf = map_full_list.find( ionCode );
233  if ( itf == map_full_list.end() ) {
234  std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
235  //itf = map_full_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
236  itf = ( map_full_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) ) ).first;
237  }
238  itf -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , fProperty ) );
239  }
240 
241  ifs >> ionZ >> ionA >> ionE >> ionLife >> ionJ >> ionMu;
242  }
243 
245 
246  }
247 
248 
249  // Clear current map
250  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
251  it = map_pre_load_list.begin(); it != map_pre_load_list.end(); it++ ) {
252  it->second.clear();
253  }
254  map_pre_load_list.clear();
255 
256  // Build map based on current threshold value
257  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
258  it = map_full_list.begin(); it != map_full_list.end(); it++ ) {
259 
260  G4int ionCode = it->first;
261  std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator itf = map_pre_load_list.find( ionCode );
262  if ( itf == map_pre_load_list.end() ) {
263  std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
264  itf = ( map_pre_load_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) ) ).first;
265  }
266  G4int iLevel = 0;
267  for ( std::multimap< G4double , G4IsotopeProperty* >::iterator
268  itt = it->second.begin(); itt != it->second.end(); itt++ ) {
269 
270  G4double exEnergy = itt->first;
271  G4double meanLife = itt->second->GetLifeTime();
272 
273  if ( exEnergy == 0.0
274  || meanLife*std::log(2.0) > threshold_of_half_life ) {
275 
276  if ( itt->first != 0.0 ) iLevel++;
277  if ( iLevel > 9 ) iLevel=9;
278  itt->second->SetIsomerLevel( iLevel );
279 
280  itf -> second.insert( std::pair< G4double, G4IsotopeProperty* >( exEnergy , itt->second ) );
281  }
282  }
283  }
284 
285 }
286 
287 void G4NuclideTable::AddState( G4int ionZ, G4int ionA, G4double ionE, G4double ionLife, G4int ionJ, G4double ionMu )
288 {
289  if ( G4Threading::IsMasterThread() ) {
290 
291  if ( fUserDefinedList == NULL ) fUserDefinedList = new G4IsotopeList();
292 
293  G4IsotopeProperty* fProperty = new G4IsotopeProperty();
294 
295  // Set Isotope Property
296  fProperty->SetAtomicNumber(ionZ);
297  fProperty->SetAtomicMass(ionA);
298  fProperty->SetIsomerLevel(9);
299  fProperty->SetEnergy(ionE);
300  fProperty->SetiSpin(ionJ);
301  fProperty->SetLifeTime(ionLife);
302  fProperty->SetDecayTable(0);
303  fProperty->SetMagneticMoment(ionMu);
304 
305  fUserDefinedList->push_back(fProperty);
306  fIsotopeList->push_back(fProperty);
307 
308  }
309 }
310 
311 #include "G4Threading.hh"
313 {
314  if ( G4Threading::IsMasterThread() ) {
316  GenerateNuclide();
317  }
318 }
void SetThresholdOfHalfLife(G4double)
void SetAtomicMass(G4int A)
std::vector< G4IsotopeProperty * > G4IsotopeList
std::map< G4int, std::multimap< G4double, G4IsotopeProperty * > > map_full_list
G4IsotopeList * fUserDefinedList
static const double joule
Definition: G4SIunits.hh:201
G4double threshold_of_half_life
int G4int
Definition: G4Types.hh:78
void SetiSpin(G4int J)
virtual G4IsotopeProperty * GetIsotopeByIsoLvl(G4int Z, G4int A, G4int lvl=0)
void SetMagneticMoment(G4double M)
void SetLifeTime(G4double T)
void AddState(G4int, G4int, G4double, G4double, G4int ionJ=0, G4double ionMu=0.0)
G4IsotopeList * fIsotopeList
double A(double temperature)
G4double GetEnergy() const
static const double second
Definition: G4SIunits.hh:156
virtual G4IsotopeProperty * GetIsotope(G4int Z, G4int A, G4double E)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::map< G4int, std::multimap< G4double, G4IsotopeProperty * > > map_pre_load_list
void SetEnergy(G4double E)
static const double eV
Definition: G4SIunits.hh:212
void SetDecayTable(G4DecayTable *table)
G4double flevelTolerance
G4double minimum_threshold_of_half_life
G4NuclideTableMessenger * fMessenger
static G4NuclideTable * GetInstance()
G4bool IsMasterThread()
Definition: G4Threading.cc:130
static MCTruthManager * instance
static const double keV
Definition: G4SIunits.hh:213
static const double tesla
Definition: G4SIunits.hh:265
double G4double
Definition: G4Types.hh:76
#define DBL_MAX
Definition: templates.hh:83
virtual ~G4NuclideTable()
void SetAtomicNumber(G4int Z)
#define ns
Definition: xmlparse.cc:614
void SetIsomerLevel(G4int level)