Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 "G4String.hh"
44 #include "globals.hh"
45 #include "G4PhysicalConstants.hh"
46 #include "G4SystemOfUnits.hh"
47 #include <iomanip>
48 #include <fstream>
49 #include <sstream>
50 
51 // const G4double G4NuclideTable::levelTolerance =
52 // torelance for excitation energy
53 
54 
57  static G4NuclideTable instance;
58  return &instance;
59 }
60 
62 G4NuclideTable::G4NuclideTable()
63  :G4VIsotopeTable("Isomer"),
64  threshold_of_half_life(1000.0*ns),
65  minimum_threshold_of_half_life(DBL_MAX),
66  fUserDefinedList(NULL),
67  fIsotopeList(NULL),
68  flevelTolerance(1.0*eV)
69 {
70  //SetVerboseLevel(G4ParticleTable::GetParticleTable()->GetVerboseLevel());
71  //FillHardCodeList();
72  fMessenger = new G4NuclideTableMessenger(this);
73  fIsotopeList = new G4IsotopeList();
75 }
76 
79 {
80 
81  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
82  it = map_pre_load_list.begin(); it != map_pre_load_list.end(); it++ ) {
83  it->second.clear();
84  }
85  map_pre_load_list.clear();
86 
87 
88  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
89  it = map_full_list.begin(); it != map_full_list.end(); it++ ) {
90  it->second.clear();
91  }
92  map_full_list.clear();
93 
94  if (fIsotopeList!=0) {
95  for (size_t i = 0 ; i<fIsotopeList->size(); i++) {
96  //G4IsotopeProperty* fProperty = (*fIsotopeList)[i]; std::cout << fProperty->GetAtomicNumber() << " " << fProperty->GetAtomicMass() << " " << fProperty->GetEnergy() << std::endl;
97  delete (*fIsotopeList)[i];
98  }
99  fIsotopeList->clear();
100  delete fIsotopeList;
101  fIsotopeList = 0;
102  }
103 
104 }
105 
107 //
110 {
111 
112  G4IsotopeProperty* fProperty = nullptr;
113 
114  // At first searching UserDefined
115  if ( fUserDefinedList ) {
116  for ( G4IsotopeList::iterator it = fUserDefinedList->begin() ; it != fUserDefinedList->end() ; it++ ) {
117 
118  if ( Z == (*it)->GetAtomicNumber() && A == (*it)->GetAtomicMass() ) {
119  G4double levelE = (*it)->GetEnergy();
120  if ( levelE - flevelTolerance/2 <= E && E < levelE + flevelTolerance/2 ) {
121  if( flb == (*it)->GetFloatLevelBase() )
122  { return *it; } //found
123  }
124  }
125  }
126  }
127 
128  //Serching pre-load
129  //Note: isomer level is properly set only for pre_load_list.
130  //
131  G4int ionCode = 1000*Z + A;
132  std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator itf = map_pre_load_list.find( ionCode );
133 
134  if ( itf != map_pre_load_list.end() ) {
135  std::multimap< G4double , G4IsotopeProperty* >::iterator lower_bound_itr = itf -> second.lower_bound ( E - flevelTolerance/2 );
136  G4double levelE = DBL_MAX;
137 /*
138  if ( lower_bound_itr != itf -> second.end() ) {
139  levelE = lower_bound_itr->first;
140  if ( levelE - flevelTolerance/2 <= E && E < levelE + flevelTolerance/2 ) {
141  if( flb == (lower_bound_itr->second)->GetFloatLevelBase() )
142  { return lower_bound_itr->second; } // found
143  }
144  }
145 */
146  while ( lower_bound_itr != itf -> second.end() ) {
147  levelE = lower_bound_itr->first;
148  if ( levelE - flevelTolerance/2 <= E && E < levelE + flevelTolerance/2 ) {
149  if ( flb == (lower_bound_itr->second)->GetFloatLevelBase() ) return lower_bound_itr->second; // found
150  } else {
151  break;
152  }
153  lower_bound_itr++;
154  }
155 
156  }
157 
158  return fProperty; // not found
159 }
160 
164 {
165  if(lvl==0) return GetIsotope(Z,A,0.0);
166  return (G4IsotopeProperty*)0;
167 }
168 
171 {
172  ;
173 }
174 
177 {
178 
179  if ( threshold_of_half_life < minimum_threshold_of_half_life ) {
180 
181  // Need to update full list
182 
183  char* path = getenv("G4ENSDFSTATEDATA");
184 
185  if ( !path ) {
186  G4Exception("G4NuclideTable", "PART70000",
187  FatalException, "G4ENSDFSTATEDATA environment variable must be set");
188  return;
189  }
190 
191  std::ifstream ifs;
192  G4String filename(path);
193  filename += "/ENSDFSTATE.dat";
194 
195  ifs.open( filename.c_str() );
196 
197  if ( !ifs.good() ) {
198  G4Exception("G4NuclideTable", "PART70001",
199  FatalException, "ENSDFSTATE.dat is not found.");
200  return;
201  }
202 
203 
204  G4int ionCode=0;
205  G4int iLevel=0;
206 
207  G4int ionZ;
208  G4int ionA;
209  G4double ionE;
210  G4String ionFL;
211  G4double ionLife;
212  G4int ionJ;
213  G4double ionMu;
214 
215  //ifs >> ionZ >> ionA >> ionE >> ionLife >> ionJ >> ionMu;
216  ifs >> ionZ >> ionA >> ionE >> ionFL >> ionLife >> ionJ >> ionMu;
217 
218  while ( ifs.good() ) {// Loop checking, 09.08.2015, K.Kurashige
219 
220  if ( ionCode != 1000*ionZ + ionA ) {
221  iLevel = 0;
222  ionCode = 1000*ionZ + ionA;
223  }
224 
225  ionE *= keV;
226  //G4int flbIndex = 0;
227  //ionE = StripFloatLevelBase( ionE, flbIndex );
228  G4Ions::G4FloatLevelBase flb = StripFloatLevelBase( ionFL );
229  ionLife *= ns;
230  ionMu *= (joule/tesla);
231 
232  //if ( ( ionE == 0 && minimum_threshold_of_half_life == DBL_MAX ) // ground state is alwyas build in very first attempt
233  // || ( threshold_of_half_life <= ionLife*std::log(2.0) && ionLife*std::log(2.0) < minimum_threshold_of_half_life && ionE != 0 ) ) {
234 
235  if ( ( ionE == 0 && flb == G4Ions::G4FloatLevelBase::no_Float ) //
236  || ( threshold_of_half_life <= ionLife*std::log(2.0) && ionLife*std::log(2.0) < minimum_threshold_of_half_life ) ) {
237 
238  if ( ionE > 0 ) iLevel++;
239  if ( iLevel > 9 ) iLevel=9;
240 
241  G4IsotopeProperty* fProperty = new G4IsotopeProperty();
242 
243  // Set Isotope Property
244  fProperty->SetAtomicNumber(ionZ);
245  fProperty->SetAtomicMass(ionA);
246  fProperty->SetIsomerLevel(iLevel);
247  fProperty->SetEnergy(ionE);
248  fProperty->SetiSpin(ionJ);
249  fProperty->SetLifeTime(ionLife);
250  fProperty->SetDecayTable(0);
251  fProperty->SetMagneticMoment(ionMu);
252  fProperty->SetFloatLevelBase( flb );
253 
254  fIsotopeList->push_back(fProperty);
255 
256  std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator itf = map_full_list.find( ionCode );
257  if ( itf == map_full_list.end() ) {
258  std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
259  //itf = map_full_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) );
260  itf = ( map_full_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) ) ).first;
261  }
262  itf -> second.insert( std::pair< G4double, G4IsotopeProperty* >( ionE , fProperty ) );
263  }
264 
265  ifs >> ionZ >> ionA >> ionE >> ionFL >> ionLife >> ionJ >> ionMu;
266  }
267 
268  minimum_threshold_of_half_life = threshold_of_half_life;
269 
270  }
271 
272 
273  // Clear current map
274  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
275  it = map_pre_load_list.begin(); it != map_pre_load_list.end(); it++ ) {
276  it->second.clear();
277  }
278  map_pre_load_list.clear();
279 
280  // Build map based on current threshold value
281  for ( std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator
282  it = map_full_list.begin(); it != map_full_list.end(); it++ ) {
283 
284  G4int ionCode = it->first;
285  std::map< G4int , std::multimap< G4double , G4IsotopeProperty* > >::iterator itf = map_pre_load_list.find( ionCode );
286  if ( itf == map_pre_load_list.end() ) {
287  std::multimap<G4double, G4IsotopeProperty*> aMultiMap;
288  itf = ( map_pre_load_list.insert( std::pair< G4int , std::multimap< G4double , G4IsotopeProperty* > > ( ionCode , aMultiMap ) ) ).first;
289  }
290  G4int iLevel = 0;
291  for ( std::multimap< G4double , G4IsotopeProperty* >::iterator
292  itt = it->second.begin(); itt != it->second.end(); itt++ ) {
293 
294  G4double exEnergy = itt->first;
295  G4double meanLife = itt->second->GetLifeTime();
296 
297  if ( exEnergy == 0.0
298  || meanLife*std::log(2.0) > threshold_of_half_life ) {
299 
300  if ( itt->first != 0.0 ) iLevel++;
301  if ( iLevel > 9 ) iLevel=9;
302  itt->second->SetIsomerLevel( iLevel );
303 
304  itf -> second.insert( std::pair< G4double, G4IsotopeProperty* >( exEnergy , itt->second ) );
305  }
306  }
307  }
308 
309 }
310 
311 void G4NuclideTable::AddState( G4int ionZ, G4int ionA, G4double ionE, G4double ionLife, G4int ionJ, G4double ionMu )
312 {
313  if ( G4Threading::IsMasterThread() ) {
314  G4int flbIndex = 0;
315  ionE = StripFloatLevelBase( ionE, flbIndex );
316  AddState(ionZ,ionA,ionE,flbIndex,ionLife,ionJ,ionMu);
317  }
318 }
319 
321  G4int flbIndex, G4double ionLife, G4int ionJ, G4double ionMu )
322 {
323  if ( G4Threading::IsMasterThread() ) {
324 
325  if ( fUserDefinedList == NULL ) fUserDefinedList = new G4IsotopeList();
326 
327  G4IsotopeProperty* fProperty = new G4IsotopeProperty();
328 
329  // Set Isotope Property
330  fProperty->SetAtomicNumber(ionZ);
331  fProperty->SetAtomicMass(ionA);
332  fProperty->SetIsomerLevel(9);
333  fProperty->SetEnergy(ionE);
334  fProperty->SetiSpin(ionJ);
335  fProperty->SetLifeTime(ionLife);
336  fProperty->SetDecayTable(0);
337  fProperty->SetMagneticMoment(ionMu);
338  fProperty->SetFloatLevelBase(flbIndex);
339 
340  fUserDefinedList->push_back(fProperty);
341  fIsotopeList->push_back(fProperty);
342 
343  }
344 }
345 
347  G4Ions::G4FloatLevelBase flb, G4double ionLife, G4int ionJ, G4double ionMu )
348 {
349  if ( G4Threading::IsMasterThread() ) {
350 
351  if ( fUserDefinedList == NULL ) fUserDefinedList = new G4IsotopeList();
352 
353  G4IsotopeProperty* fProperty = new G4IsotopeProperty();
354 
355  // Set Isotope Property
356  fProperty->SetAtomicNumber(ionZ);
357  fProperty->SetAtomicMass(ionA);
358  fProperty->SetIsomerLevel(9);
359  fProperty->SetEnergy(ionE);
360  fProperty->SetiSpin(ionJ);
361  fProperty->SetLifeTime(ionLife);
362  fProperty->SetDecayTable(0);
363  fProperty->SetMagneticMoment(ionMu);
364  fProperty->SetFloatLevelBase( flb );
365 
366  fUserDefinedList->push_back(fProperty);
367  fIsotopeList->push_back(fProperty);
368 
369  }
370 }
371 
372 //#include "G4Threading.hh"
374 {
375  if ( G4Threading::IsMasterThread() ) {
376  threshold_of_half_life=t;
377  GenerateNuclide();
378  }
379 }
380 
381 G4double G4NuclideTable::StripFloatLevelBase(G4double E, G4int& flbIndex)
382 {
383  G4double rem = std::fmod(E/(1.0E-3*eV),10.0);
384  flbIndex = int(rem);
385  return E-rem;
386 }
387 
388 G4Ions::G4FloatLevelBase G4NuclideTable::StripFloatLevelBase( G4String sFLB )
389 {
390  if ( sFLB.size() < 1 || 2 < sFLB.size() ) {
391  G4String text;
392  text += sFLB;
393  text += " is not valid indicator of G4Ions::G4FloatLevelBase. You may use a wrong version of ENSDFSTATE data. Please use G4ENSDFSTATE2.0 or later.";
394 
395  G4Exception( "G4NuclideTable" , "PART70002" ,
396  FatalException , text );
397  }
399  if ( !(sFLB == '-') ) {
400  flb = G4Ions::FloatLevelBase( sFLB.back() );
401  }
402  return flb;
403 }
static constexpr double tesla
Definition: G4SIunits.hh:268
void SetThresholdOfHalfLife(G4double)
void SetAtomicMass(G4int A)
std::vector< G4IsotopeProperty * > G4IsotopeList
static constexpr double second
Definition: G4SIunits.hh:157
int G4int
Definition: G4Types.hh:78
void SetiSpin(G4int J)
virtual G4IsotopeProperty * GetIsotopeByIsoLvl(G4int Z, G4int A, G4int lvl=0)
void SetMagneticMoment(G4double M)
virtual G4IsotopeProperty * GetIsotope(G4int Z, G4int A, G4double E, G4Ions::G4FloatLevelBase flb=G4Ions::G4FloatLevelBase::no_Float)
void SetLifeTime(G4double T)
static G4Ions::G4FloatLevelBase FloatLevelBase(char flbChar)
Definition: G4Ions.hh:189
void AddState(G4int, G4int, G4double, G4double, G4int ionJ=0, G4double ionMu=0.0)
double A(double temperature)
G4double GetEnergy() const
void SetFloatLevelBase(G4Ions::G4FloatLevelBase flb)
typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData)
static constexpr double eV
Definition: G4SIunits.hh:215
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
void SetEnergy(G4double E)
void SetDecayTable(G4DecayTable *table)
static constexpr double joule
Definition: G4SIunits.hh:204
static G4NuclideTable * GetInstance()
G4bool IsMasterThread()
Definition: G4Threading.cc:146
static MCTruthManager * instance
double G4double
Definition: G4Types.hh:76
#define DBL_MAX
Definition: templates.hh:83
static constexpr double keV
Definition: G4SIunits.hh:216
virtual ~G4NuclideTable()
void SetAtomicNumber(G4int Z)
#define ns
Definition: xmlparse.cc:614
#define noFloat
Definition: G4Ions.hh:118
G4FloatLevelBase
Definition: G4Ions.hh:95
void SetIsomerLevel(G4int level)