Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4LevelReader.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//
29// GEANT4 header file
30//
31// File name: G4NucLevel
32//
33// Author: V.Ivanchenko (M.Kelsey reading method is used)
34//
35// Creation date: 4 January 2012
36//
37// Modifications:
38//
39// -------------------------------------------------------------------
40
41#include "G4LevelReader.hh"
42#include "G4NucleiProperties.hh"
43#include "G4NucLevel.hh"
44#include "G4NuclearLevelData.hh"
46#include "G4SystemOfUnits.hh"
47#include "G4Pow.hh"
48#include <fstream>
49#include <sstream>
50
51namespace
52{
53 const G4int countmax = 4;
54 const G4int nfloting = 13;
55 const G4double eTolarence = 2*CLHEP::eV;
56 const G4String fFloatingLevels[13] = {
57 "-", "+X", "+Y", "+Z", "+U", "+V", "+W", "+R", "+S", "+T", "+A", "+B", "+C"};
58}
59
61 : fData(ptr)
62{
63 fAlphaMax = (G4float)1.e15;
64 fTimeFactor = CLHEP::second/G4Pow::GetInstance()->logZ(2);
65 fDirectory = G4String(G4FindDataDir("G4LEVELGAMMADATA"));
66 if (fDirectory.empty()) {
67 G4Exception("G4LevelReader::G4LevelReader()", "had014", FatalException,
68 "G4LEVELGAMMADATA environment variable not set");
69 }
70
71 vTrans.resize(fTransMax,0);
72 vRatio.resize(fTransMax,0.0f);
73 vGammaCumProbability.resize(fTransMax,0.0f);
74 vGammaProbability.resize(fTransMax,0.0f);
75 vShellProbability.resize(fTransMax,nullptr);
76
77 vEnergy.resize(fLevelMax,0.0);
78 vSpin.resize(fLevelMax,0);
79 vLevel.resize(fLevelMax,nullptr);
80}
81
82G4bool G4LevelReader::ReadData(std::istringstream& stream, G4double& x)
83{
84 stream >> x;
85 return !stream.fail();
86}
87
88G4bool G4LevelReader::ReadDataItem(std::istream& dataFile, G4double& x)
89{
90 x = 0.0;
91 for(G4int i=0; i<nbufmax; ++i) { buffer[i] = ' '; }
92 G4bool okay = true;
93 dataFile >> buffer;
94 if(dataFile.fail()) { okay = false; }
95 else { x = std::strtod(buffer, 0); }
96 return okay;
97}
98
99G4bool G4LevelReader::ReadDataItem(std::istream& dataFile, G4float& x)
100{
101 x = 0.0f;
102 for(G4int i=0; i<nbuf1; ++i) { buff1[i] = ' '; }
103 G4bool okay = true;
104 dataFile >> buff1;
105 if(dataFile.fail()) { okay = false; }
106 else { x = std::atof(buff1); }
107
108 return okay;
109}
110
111G4bool G4LevelReader::ReadDataItem(std::istream& dataFile, G4int& ix)
112{
113 ix = 0;
114 for(G4int i=0; i<nbuf2; ++i) { buff2[i] = ' '; }
115 G4bool okay = true;
116 dataFile >> buff2;
117 if(dataFile.fail()) { okay = false; }
118 else { ix = std::atoi(buff2); }
119
120 return okay;
121}
122
123const std::vector<G4float>* G4LevelReader::NormalizedICCProbability(G4int Z)
124{
125 std::vector<G4float>* vec = nullptr;
126 G4int LL = 3;
127 G4int M = 5;
128 G4int N = 1;
129 G4int Kmax = 9;
130 if(Z <= 27) {
131 M = N = 0;
132 if(Z <= 4) {
133 LL = 1;
134 Kmax = 2;
135 } else if(Z <= 6) {
136 LL = 2;
137 Kmax = 3;
138 } else if(Z <= 10) {
139 Kmax = 4;
140 } else if(Z <= 12) {
141 M = 1;
142 Kmax = 8;
143 } else if(Z <= 17) {
144 M = 2;
145 Kmax = 8;
146 } else if(Z == 18) {
147 M = 3;
148 Kmax = 8;
149 } else if(Z <= 20) {
150 M = 3;
151 N = 1;
152 } else {
153 M = 4;
154 N = 1;
155 }
156 if(LL < 3) { for(G4int i=LL+1; i<=4; ++i) { fICC[i] = 0.0f; } }
157 if(M < 5) { for(G4int i=M+4; i<=8; ++i) { fICC[i] = 0.0f; } }
158 if(N < 1) { fICC[9] = 0.0f; }
159 }
160 G4float norm = 0.0f;
161 for (G4int i = 0; i <= Kmax; ++i) {
162 norm += fICC[i];
163 fICC[i] = norm;
164 }
165 if (norm > 0.0f) {
166 norm = 1.0f/norm;
167 }
168 vec = new std::vector<G4float>(Kmax + 1, 0.0f);
169 for (G4int i = 0; i < Kmax; ++i) {
170 (*vec)[i] = fICC[i]*norm;
171 }
172 (*vec)[Kmax] = 1.0f;
173 if (fVerbose > 3) {
174 G4long prec = G4cout.precision(3);
175 G4cout << "# InternalConv: ";
176 for (G4int i = 0; i <= Kmax; ++i) { G4cout << " " << (*vec)[i]; }
177 G4cout << G4endl;
178 G4cout.precision(prec);
179 }
180 return vec;
181}
182
183const G4LevelManager*
185{
186 std::ostringstream ss;
187 ss << fDirectory << "/z" << Z << ".a" << A;
188 std::ifstream infile(ss.str(), std::ios::in);
189
190 // file is not opened
191 if (!infile.is_open()) {
192 if(fVerbose > 1) {
194 ed << "Regular file " << ss.str() << " is not opened! Z="
195 << Z << " A=" << A;
196 G4Exception("G4LevelReader::LevelManager(..)","had014",
197 JustWarning, ed, "Check file path");
198 }
199 return nullptr;
200 }
201 // file is opened
202 if (fVerbose > 1) {
203 G4cout << "G4LevelReader: open file " << ss.str() << " for Z= "
204 << Z << " A= " << A << G4endl;
205 }
206 return LevelManager(Z, A, infile);
207}
208
209const G4LevelManager*
211{
212 std::ifstream infile(filename, std::ios::in);
213
214 // file is not opened
215 if (!infile.is_open()) {
216 if(fVerbose > 1) {
218 ed << "External file " << filename << " is not opened! Z="
219 << Z << " A=" << A;
220 G4Exception("G4LevelReader::LevelManager(..)","had014",
221 FatalException, ed, "Check file path");
222 }
223 return nullptr;
224 }
225 // file is opened
226 if (fVerbose > 1) {
227 G4cout << "G4LevelReader: open external file " << filename
228 << " for Z= " << Z << " A= " << A << G4endl;
229 }
230 return LevelManager(Z, A, infile);
231}
232
233const G4LevelManager*
234G4LevelReader::LevelManager(G4int Z, G4int A, std::ifstream& infile)
235{
236 G4bool allLevels = fData->GetParameters()->StoreICLevelData();
237 fPol = " ";
238 G4int i = 0;
239 for (;;) {
240 infile >> i1 >> fPol; // Level number and floating level
241 // normal end of file
242 if (infile.eof()) {
243 if (fVerbose > 1) {
244 G4cout << "### End of file Z= " << Z << " A= " << A
245 << " Nlevels= " << i << G4endl;
246 }
247 break;
248 }
249 // start reading new level data
250#ifdef G4VERBOSE
251 if(fVerbose > 2) {
252 G4cout << "New line: i1= " << i1 << " fPol= <" << fPol << "> " << G4endl;
253 }
254#endif
255 // read new level data
256 if (!(ReadDataItem(infile, fEnergy) &&
257 ReadDataItem(infile, fTime) &&
258 ReadDataItem(infile, fSpin) &&
259 ReadDataItem(infile, ntrans))) {
260 if (fVerbose > 1) {
261 G4cout << "### Incomplete end of file Z= " << Z << " A= " << A
262 << " Nlevels= " << i << G4endl;
263 }
264 break;
265 }
266 fEnergy *= CLHEP::keV;
267 for (k=0; k<nfloting; ++k) {
268 if (fPol == fFloatingLevels[k]) {
269 break;
270 }
271 }
272 // if a previous level has higher energy the current should be ignored
273 // data with wrong level should red anyway
274 if (0 < i) {
275 if (fEnergy < vEnergy[i-1]) {
276#ifdef G4VERBOSE
277 ++count1;
278 if (count1 < countmax && fVerbose > 0) {
279 G4cout << "### G4LevelReader: broken level " << i
280 << " E(MeV)= " << fEnergy << " < " << vEnergy[i-1]
281 << " for isotope Z= " << Z << " A= "
282 << A << " level energy increased" << G4endl;
283 }
284#endif
285 // for any case
286 fEnergy = vEnergy[i-1] + eTolarence;
287 }
288 }
289 vEnergy[i] = fEnergy;
290 if (fTime > 0.0) { fTime *= fTimeFactor; }
291 else if (fTime < 0.0) { fTime = DBL_MAX; }
292
293 G4int twos = G4lrint(fSpin + fSpin);
294 twos = std::max(twos, -100);
295 vSpin[i] = 100 + twos + k*100000;
296#ifdef G4VERBOSE
297 if (fVerbose > 2) {
298 G4cout << " Level #" << i1 << " E(MeV)=" << fEnergy/CLHEP::MeV
299 << " LTime(s)=" << fTime << " 2S=" << vSpin[i]
300 << " meta=" << vSpin[i]/100000 << " idx=" << i
301 << " ntr=" << ntrans << G4endl;
302 }
303#endif
304 vLevel[i] = nullptr;
305 if (ntrans == 0) {
306 vLevel[i] = new G4NucLevel(0, fTime, vTrans,
307 vGammaCumProbability,
308 vGammaProbability,
309 vRatio,
310 vShellProbability);
311 } else if (ntrans > 0) {
312
313 G4bool isTransOK = true;
314 if (ntrans > fTransMax) {
315 fTransMax = ntrans;
316 vTrans.resize(fTransMax);
317 vRatio.resize(fTransMax);
318 vGammaCumProbability.resize(fTransMax);
319 vGammaProbability.resize(fTransMax);
320 vShellProbability.resize(fTransMax);
321 }
322 fNorm1 = 0.0f;
323 for (G4int j=0; j<ntrans; ++j) {
324
325 if (!(ReadDataItem(infile, i2) &&
326 ReadDataItem(infile, fTransEnergy) &&
327 ReadDataItem(infile, fProb) &&
328 ReadDataItem(infile, tnum) &&
329 ReadDataItem(infile, vRatio[j]) &&
330 ReadDataItem(infile, fAlpha))) {
331#ifdef G4VERBOSE
332 ++count2;
333 if (count2 < countmax && fVerbose > 0) {
334 G4cout << "### Fail to read transition j=" << j
335 << " j=" << j << " i2=" << i2
336 << " Z=" << Z << " A=" << A << G4endl;
337 }
338#endif
339 isTransOK = false;
340 }
341 if (i2 >= i) {
342#ifdef G4VERBOSE
343 ++count2;
344 if (count2 < countmax) {
345 G4cout << "### G4LevelReader: broken transition " << j
346 << " from level " << i << " to " << i2
347 << " for isotope Z= " << Z << " A= "
348 << A << "; the transition probability set to zero" << G4endl;
349 }
350#endif
351 isTransOK = false;
352 fProb = 0.0f;
353 }
354 vTrans[j] = i2*10000 + tnum;
355 fAlpha = std::min(std::max(fAlpha,0.f), fAlphaMax);
356 G4float x = 1.0f + fAlpha;
357 fNorm1 += x*fProb;
358 vGammaCumProbability[j] = fNorm1;
359 vGammaProbability[j] = 1.0f/x;
360 vShellProbability[j] = nullptr;
361 if (fVerbose > 2) {
362 G4long prec = G4cout.precision(4);
363 G4cout << "### Transition #" << j << " to level " << i2
364 << " i2= " << i2 << " Etrans(MeV)= " << fTransEnergy*CLHEP::keV
365 << " fProb= " << fProb << " MultiP= " << tnum
366 << " fMpRatio= " << fRatio << " fAlpha= " << fAlpha
367 << G4endl;
368 G4cout.precision(prec);
369 }
370 if (fAlpha > 0.0f) {
371 for (k=0; k<10; ++k) {
372 if (!ReadDataItem(infile,fICC[k])) {
373 isTransOK = false;
374#ifdef G4VERBOSE
375 ++count2;
376 if (count2 < countmax) {
377 G4cout << "### G4LevelReader: fail to read conversion coeff k= " << k
378 << " for transition j= " << j
379 << " Z= " << Z << " A= " << A << G4endl;
380 }
381#endif
382 for(kk=k; kk<10; ++kk) { fICC[kk] = 0.f; }
383 }
384 }
385 if (allLevels) {
386 vShellProbability[j] = NormalizedICCProbability(Z);
387 }
388 }
389 }
390 if (ntrans > 0) {
391 G4int nt = ntrans - 1;
392 if (fVerbose > 2) {
393 G4cout << "=== New G4NucLevel: Ntrans=" << ntrans
394 << " Time(ns)=" << fTime
395 << " IdxTrans=" << vTrans[nt]/10000
396 << " isOK=" << isTransOK
397 << G4endl;
398 }
399 fNorm1 = (FLT_MIN < fNorm1) ? 1.0f/fNorm1 : 0.0f;
400 for (k=0; k<nt; ++k) {
401 vGammaCumProbability[k] *= fNorm1;
402#ifdef G4VERBOSE
403 if (fVerbose > 3) {
404 G4cout << "Probabilities[" << k
405 << "]= " << vGammaCumProbability[k]
406 << " " << vGammaProbability[k]
407 << " idxTrans= " << vTrans[k]/10000
408 << G4endl;
409 }
410#endif
411 }
412 vGammaCumProbability[nt] = 1.0f;
413 vLevel[i] = new G4NucLevel((std::size_t)ntrans, fTime, vTrans,
414 vGammaCumProbability,
415 vGammaProbability,
416 vRatio,
417 vShellProbability);
418 }
419 }
420 ++i;
421 if (i == fLevelMax) {
422 fLevelMax += 10;
423 vEnergy.resize(fLevelMax, 0.0);
424 vSpin.resize(fLevelMax, 0);
425 vLevel.resize(fLevelMax, nullptr);
426 }
427 }
428 G4LevelManager* lman = nullptr;
429 if (1 <= i) {
430 lman = new G4LevelManager(Z, A, (std::size_t)i, vEnergy, vSpin, vLevel);
431 if (fVerbose > 1) {
432 G4cout << "=== Reader: new manager for Z=" << Z << " A=" << A
433 << " Nlevels=" << i << " E[0]="
434 << vEnergy[0]/CLHEP::MeV << " MeV E1="
435 << vEnergy[i-1]/CLHEP::MeV << " MeV"
436 << " count1,2=" << count1 << ", " << count2 << G4endl;
437 }
438 }
439 return lman;
440}
const char * G4FindDataDir(const char *)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define M(row, col)
float G4float
Definition G4Types.hh:84
double G4double
Definition G4Types.hh:83
long G4long
Definition G4Types.hh:87
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
const G4double A[17]
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
const G4LevelManager * MakeLevelManager(G4int Z, G4int A, const G4String &filename)
const G4LevelManager * CreateLevelManager(G4int Z, G4int A)
G4LevelReader(G4NuclearLevelData *)
G4DeexPrecoParameters * GetParameters()
static G4Pow * GetInstance()
Definition G4Pow.cc:41
G4double logZ(G4int Z) const
Definition G4Pow.hh:137
#define N
Definition crc32.c:57
int G4lrint(double ad)
Definition templates.hh:134
#define FLT_MIN
Definition templates.hh:70
#define DBL_MAX
Definition templates.hh:62