Geant4  10.01.p03
G4NuclearLevelManager.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 // $Id: G4NuclearLevelManager.cc 87163 2014-11-26 08:46:54Z gcosmo $
27 //
28 // -------------------------------------------------------------------
29 // GEANT 4 class file
30 //
31 // CERN, Geneva, Switzerland
32 //
33 // File name: G4NuclearLevelManager
34 //
35 // Author: Maria Grazia Pia (pia@genova.infn.it)
36 //
37 // Creation date: 24 October 1998
38 //
39 // Modifications:
40 //
41 // 15 April 1999, Alessandro Brunengo (Alessandro.Brunengo@ge.infn.it)
42 // Added half-life, angular momentum, parity, emissioni type
43 // reading from experimental data.
44 // 02 May 2003, Vladimir Ivanchenko remove rublic copy constructor
45 // 06 Oct 2010, M. Kelsey -- Use object storage, not pointers, drop
46 // public access to list, simplify list construction
47 // -------------------------------------------------------------------
48 #include <stdlib.h>
49 #include <fstream>
50 #include <sstream>
51 #include <algorithm>
52 
53 #include "G4NuclearLevelManager.hh"
54 
55 #include "globals.hh"
56 #include "G4SystemOfUnits.hh"
57 #include "G4NuclearLevel.hh"
58 #include "G4ios.hh"
59 #include "G4HadronicException.hh"
60 #include "G4HadTmpUtil.hh"
61 #include "G4NucleiProperties.hh"
62 #include "G4PhysicalConstants.hh"
63 
81 
83  const G4String& filename) :
84  _nucleusA(A), _nucleusZ(Z), _validity(false),
85  _levels(0)
86 {
87  if (A <= 0 || Z <= 0 || Z > A ) {
88  throw G4HadronicException(__FILE__, __LINE__,
89  "==== G4NuclearLevelManager ==== (Z,A) <0, or Z>A");
90  }
91  MakeLevels(filename);
92 }
93 
95 {
96  ClearLevels();
97 }
98 
100 {
101  if (A <= 0 || Z <= 0 || Z > A ) {
102  throw G4HadronicException(__FILE__, __LINE__,
103  "==== G4NuclearLevelManager ==== (Z,A) <0, or Z>A");
104  }
105  if (_nucleusZ != Z || _nucleusA != A)
106  {
107  _nucleusA = A;
108  _nucleusZ = Z;
109  MakeLevels(filename);
110  }
111 }
112 
114  return (i>=0 && i<NumberOfLevels()) ? (*_levels)[i] : 0;
115 }
116 
117 const G4NuclearLevel*
119 {
120  if (NumberOfLevels() <= 0) return 0;
121 
122  G4int iNear = -1;
123 
124  //G4cout << "G4NuclearLevelManager::NearestLevel E(MeV)= "
125  // << energy/MeV << " dEmax(MeV)= " << eDiffMax/MeV << G4endl;
126 
127  G4double diff = 1.e+10;
128  for (unsigned int i=0; i<_levels->size(); ++i)
129  {
130  G4double e = GetLevel(i)->Energy();
131  G4double eDiff = std::fabs(e - energy);
132  //G4cout << i << ". eDiff(MeV)= " << eDiff/MeV << G4endl;
133  if (eDiff <= diff)
134  {
135  diff = eDiff;
136  iNear = i;
137  }
138  }
139 
140  return GetLevel(iNear); // Includes range checking on iNear
141 }
142 
144 {
145  return (NumberOfLevels() > 0) ? _levels->front()->Energy() : 9999.*GeV;
146 }
147 
149 {
150  return (NumberOfLevels() > 0) ? _levels->back()->Energy() : 0.*GeV;
151 }
152 
154 {
155  return (NumberOfLevels() > 0) ? _levels->front() : 0;
156 }
157 
159 {
160  return (NumberOfLevels() > 0) ? _levels->back() : 0;
161 }
162 
163 G4bool G4NuclearLevelManager::Read(std::ifstream& dataFile)
164 {
165  G4bool goodRead = ReadDataLine(dataFile);
166 
167  if (goodRead) ProcessDataLine();
168  return goodRead;
169 }
170 
171 // NOTE: Standard stream I/O generates a 45 byte std::string per item!
172 
173 G4bool G4NuclearLevelManager::ReadDataLine(std::ifstream& dataFile) {
174  /***** DO NOT USE REGULAR STREAM I/O
175  G4bool result = true;
176  if (dataFile >> _levelEnergy)
177  {
178  dataFile >> _gammaEnergy >> _probability >> _polarity >> _halfLife
179  >> _angularMomentum >> _totalCC >> _kCC >> _l1CC >> _l2CC
180  >> _l3CC >> _m1CC >> _m2CC >> _m3CC >> _m4CC >> _m5CC
181  >> _nPlusCC;
182  }
183  else result = false;
184  *****/
185 
186  // Each item will return iostream status
187  return (ReadDataItem(dataFile, _levelEnergy) &&
188  ReadDataItem(dataFile, _gammaEnergy) &&
189  ReadDataItem(dataFile, _probability) &&
190  ReadDataItem(dataFile, _polarity) &&
191  ReadDataItem(dataFile, _halfLife) &&
192  ReadDataItem(dataFile, _angularMomentum) &&
193  ReadDataItem(dataFile, _totalCC) &&
194  ReadDataItem(dataFile, _kCC) &&
195  ReadDataItem(dataFile, _l1CC) &&
196  ReadDataItem(dataFile, _l2CC) &&
197  ReadDataItem(dataFile, _l3CC) &&
198  ReadDataItem(dataFile, _m1CC) &&
199  ReadDataItem(dataFile, _m2CC) &&
200  ReadDataItem(dataFile, _m3CC) &&
201  ReadDataItem(dataFile, _m4CC) &&
202  ReadDataItem(dataFile, _m5CC) &&
203  ReadDataItem(dataFile, _nPlusCC) );
204 }
205 
206 G4bool
207 G4NuclearLevelManager::ReadDataItem(std::istream& dataFile, G4double& x)
208 {
209  // G4bool okay = (dataFile >> buffer) != 0; // Get next token
210  // if (okay) x = strtod(buffer, NULL);
211  char buffer[30];
212  for(G4int i=0; i<30; ++i) { buffer[i] = 0; }
213  G4bool okay = true;
214  dataFile >> buffer;
215  if(dataFile.fail()) { okay = false; }
216  else { x = strtod(buffer, NULL); }
217 
218  return okay;
219 }
220 
222 {
223  const G4double minProbability = 1e-8;
224 
225  // Assign units for dimensional quantities
226  _levelEnergy *= keV;
227  _gammaEnergy *= keV;
228  _halfLife *= second;
229 
230  // The following adjustment is needed to take care of anomalies in
231  // data files, where some transitions show up with relative probability
232  // zero
233  if (_probability < minProbability) _probability = minProbability;
234  // the folowwing is to convert icc probability to accumulative ones
235  _l1CC += _kCC;
236  _l2CC += _l1CC;
237  _l3CC += _l2CC;
238  _m1CC += _l3CC;
239  _m2CC += _m1CC;
240  _m3CC += _m2CC;
241  _m4CC += _m3CC;
242  _m5CC += _m4CC;
243  _nPlusCC += _m5CC;
244 
245  if (_nPlusCC!=0) { // Normalize to probabilities
246  _kCC /= _nPlusCC;
247  _l1CC /= _nPlusCC;
248  _l2CC /= _nPlusCC;
249  _l3CC /= _nPlusCC;
250  _m1CC /= _nPlusCC;
251  _m2CC /= _nPlusCC;
252  _m3CC /= _nPlusCC;
253  _m4CC /= _nPlusCC;
254  _m5CC /= _nPlusCC;
255  _nPlusCC /= _nPlusCC;
256  } else { // Total was zero, reset to unity
257  _kCC = 1;
258  _l1CC = 1;
259  _l2CC = 1;
260  _l3CC = 1;
261  _m1CC = 1;
262  _m2CC = 1;
263  _m3CC = 1;
264  _m4CC = 1;
265  _m5CC = 1;
266  _nPlusCC = 1;
267  }
268 
269  // G4cout << "Read " << _levelEnergy << " " << _gammaEnergy << " " << _probability << G4endl;
270 }
271 
273 {
274  _validity = false;
275 
276  if (NumberOfLevels() > 0) {
277  std::for_each(_levels->begin(), _levels->end(), DeleteLevel());
278  _levels->clear();
279  }
280 
281  delete _levels;
282  _levels = 0;
283 }
284 
286 {
287  _validity = false;
288  if (NumberOfLevels() > 0) ClearLevels(); // Discard existing data
289 
290  std::ifstream inFile(filename, std::ios::in);
291  if (! inFile)
292  {
293 #ifdef GAMMAFILEWARNING
294  if (_nucleusZ > 10) G4cout << " G4NuclearLevelManager: nuclide ("
295  << _nucleusZ << "," << _nucleusA
296  << ") does not have a gamma levels file" << G4endl;
297 #endif
298  return;
299  }
300 
302 
303  // Read individual gamma data and fill levels for this nucleus
304 
305  G4NuclearLevel* thisLevel = 0;
306  G4int nData = 0;
307 
308  while (Read(inFile)) {
309  thisLevel = UseLevelOrMakeNew(thisLevel); // May create new pointer
310  AddDataToLevel(thisLevel);
311  nData++; // For debugging purposes
312  }
313 
314  FinishLevel(thisLevel); // Final must be completed by hand
315 
316  // ---- MGP ---- Don't forget to close the file
317  inFile.close();
318 
319  // G4cout << " ==== MakeLevels ===== " << nData << " data read " << G4endl;
320 
321  G4PtrSort<G4NuclearLevel>(_levels);
322 
323  _validity = true;
324 
325  return;
326 }
327 
330 {
331  if (level && _levelEnergy == level->Energy()) return level; // No change
332 
333  if (level) FinishLevel(level); // Save what we have up to now
334 
335  // G4cout << "Making a new level... " << _levelEnergy << G4endl;
337 }
338 
340 {
341  if (!level) return; // Sanity check
342 
343  level->_energies.push_back(_gammaEnergy);
344  level->_weights.push_back(_probability);
345  level->_polarities.push_back(_polarity);
346  level->_kCC.push_back(_kCC);
347  level->_l1CC.push_back(_l1CC);
348  level->_l2CC.push_back(_l2CC);
349  level->_l3CC.push_back(_l3CC);
350  level->_m1CC.push_back(_m1CC);
351  level->_m2CC.push_back(_m2CC);
352  level->_m3CC.push_back(_m3CC);
353  level->_m4CC.push_back(_m4CC);
354  level->_m5CC.push_back(_m5CC);
355  level->_nPlusCC.push_back(_nPlusCC);
356  level->_totalCC.push_back(_totalCC);
357 }
358 
360 {
361  if (!level || !_levels) return; // Sanity check
362 
363  level->Finalize();
364  _levels->push_back(level);
365 }
366 
367 
369 {
370  G4int nLevels = NumberOfLevels();
371 
372  G4cout << " ==== G4NuclearLevelManager ==== (" << _nucleusZ << ", " << _nucleusA
373  << ") has " << nLevels << " levels" << G4endl
374  << "Highest level is at energy " << MaxLevelEnergy() << " MeV "
375  << G4endl << "Lowest level is at energy " << MinLevelEnergy()
376  << " MeV " << G4endl;
377 
378  for (G4int i=0; i<nLevels; ++i) {
379  GetLevel(i)->PrintAll();
380  }
381 }
382 
384 {
385  G4int nLevels = NumberOfLevels();
387  + neutron_mass_c2 -
389 
390  G4cout << "Z= " << _nucleusZ << " A= " << _nucleusA
391  << " " << nLevels << " levels"
392  << " Efermi(MeV)= " << efermi << G4endl;
393 
394  for (G4int i=0; i<nLevels; ++i) {
395  GetLevel(i)->PrintLevels();
396  }
397 }
398 
400 {
401  _nucleusA = right._nucleusA;
402  _nucleusZ = right._nucleusZ;
403  _validity = right._validity;
404 
405  if (right._levels != 0)
406  {
408  G4int n = right._levels->size();
409  G4int i;
410  for (i=0; i<n; ++i)
411  {
412  _levels->push_back(new G4NuclearLevel(*(right.GetLevel(i))));
413  }
414  G4PtrSort<G4NuclearLevel>(_levels);
415  }
416  else
417  {
418  _levels = 0;
419  }
420 }
421 
std::vector< G4double > _m3CC
static G4double GetNuclearMass(const G4double A, const G4double Z)
std::vector< G4double > _m1CC
G4NuclearLevelManager(G4int Z, G4int A, const G4String &filename)
G4double Energy() const
const G4NuclearLevel * HighestLevel() const
G4double MinLevelEnergy() const
std::vector< G4double > _l3CC
#define buffer
Definition: xmlparse.cc:611
G4NuclearLevel * UseLevelOrMakeNew(G4NuclearLevel *level)
std::vector< G4double > _weights
std::vector< G4double > _polarities
G4bool Read(std::ifstream &aDataFile)
int G4int
Definition: G4Types.hh:78
G4bool ReadDataItem(std::istream &dataFile, G4double &x)
std::vector< G4NuclearLevel * > G4PtrLevelVector
std::vector< G4double > _m5CC
G4GLOB_DLL std::ostream G4cout
std::vector< G4double > _l1CC
void PrintAll() const
void SetNucleus(G4int Z, G4int A, const G4String &filename)
const G4NuclearLevel * LowestLevel() const
const G4NuclearLevel * GetLevel(G4int i) const
bool G4bool
Definition: G4Types.hh:79
std::vector< G4double > _nPlusCC
std::vector< G4double > _energies
void MakeLevels(const G4String &filename)
std::vector< G4double > _m2CC
static const double second
Definition: G4SIunits.hh:138
static const double GeV
Definition: G4SIunits.hh:196
const G4int n
G4bool ReadDataLine(std::ifstream &dataFile)
static const G4double A[nN]
std::vector< G4double > _kCC
G4double energy(const ThreeVector &p, const G4double m)
void FinishLevel(G4NuclearLevel *level)
#define G4endl
Definition: G4ios.hh:61
static const double keV
Definition: G4SIunits.hh:195
std::vector< G4double > _m4CC
double G4double
Definition: G4Types.hh:76
void AddDataToLevel(G4NuclearLevel *level)
std::vector< G4double > _l2CC
G4double MaxLevelEnergy() const
const G4NuclearLevel * NearestLevel(G4double energy, G4double eDiffMax=1.e+8) const
std::vector< G4double > _totalCC
void PrintLevels() const