Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ENDFTapeRead.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 * File: G4ENDFTapeRead.cc
28 * Author: B. Wendt ([email protected])
29 *
30 * Created on September 6, 2011, 10:01 AM
31 */
32
33#include "G4ENDFTapeRead.hh"
34
37#include "G4FFGDefaultValues.hh"
38#include "G4FFGEnumerations.hh"
40#include "G4TableTemplate.hh"
41#include "globals.hh"
42
43#include <fstream>
44#include <map>
45#include <vector>
46
50 : /* Cause_(WhichCause),*/
51 Verbosity_(G4FFGDefaultValues::Verbosity),
52 YieldType_(WhichYield)
53{
54 // Initialize the class
55 Initialize(FileLocation + FileName);
56}
57
60 G4FFGEnumerations::FissionCause /*WhichCause*/, G4int Verbosity)
61 : /*Cause_(WhichCause),*/
62 Verbosity_(Verbosity),
63 YieldType_(WhichYield)
64{
65 // Initialize the class
66 Initialize(FileLocation + FileName);
67}
68
69G4ENDFTapeRead::G4ENDFTapeRead(std::istringstream& dataStream,
71 G4FFGEnumerations::FissionCause /*WhichCause*/, G4int Verbosity)
72 : /*Cause_(WhichCause),*/
73 Verbosity_(Verbosity),
74 YieldType_(WhichYield)
75{
76 // Initialize the class
77 Initialize(dataStream);
78}
79
81{
82 std::istringstream dataStream(std::ios::in);
83 G4ParticleHPManager::GetInstance()->GetDataStream(dataFile, dataStream);
84
85 Initialize(dataStream);
86}
87
88void G4ENDFTapeRead::Initialize(std::istringstream& dataStream)
89{
91
92 EnergyGroups_ = 0;
93 EnergyGroupValues_ = nullptr;
94
95 YieldContainerTable_ = new G4TableTemplate<G4ENDFYieldDataContainer>;
96
97 try {
98 ReadInData(dataStream);
99 }
100 catch (std::exception& e) {
101 delete YieldContainerTable_;
102
104 throw e;
105 }
106
108}
109
117
125
127{
129
130 auto NumberOfElements = (G4int)YieldContainerTable_->G4GetNumberOfElements();
131
133 return NumberOfElements;
134}
135
137{
139
140 G4ENDFYieldDataContainer* Container = nullptr;
141 if (WhichYield >= 0 && WhichYield < YieldContainerTable_->G4GetNumberOfElements()) {
142 Container = YieldContainerTable_->G4GetContainer(WhichYield);
143 }
144
146 return Container;
147}
148
150{
152
153 this->Verbosity_ = WhatVerbosity;
154
156}
157
158void G4ENDFTapeRead::ReadInData(std::istringstream& dataStream)
159{
161
162 // Check if the file exists
163 if (!dataStream.good()) {
164 G4Exception("G4ENDFTapeRead::ReadInData()", "Illegal file name", JustWarning,
165 "Fission product data not available");
166
167 // TODO create/use a specialized exception
169 throw std::exception();
170 }
171
172 // Code to read in from a pure ENDF data tape.
173 // Commented out while pre-formatted Geant4 ENDF data is being used
174 // G4int CurrentEnergyGroup = -1;
175 // std::vector< G4double > NewDoubleVector;
176 // std::vector< G4double > EnergyPoints;
177 // std::vector< G4int > Product;
178 // std::vector< G4FFGEnumerations::MetaState > MetaState;
179 // std::vector< std::vector< G4double > > Yield;
180 // std::vector< std::vector< G4double > > Error;
181 // G4String DataBlock;
182 // std::size_t InsertExponent;
183 // G4double Parts[6];
184 // G4double dummy;
185 // G4int MAT;
186 // G4int MF;
187 // G4int MT;
188 // G4int LN;
189 // G4int Block;
190 // G4int EmptyProduct;
191 // G4int Location;
192 // G4int ItemCounter = 0;
193 // G4int FirstLineInEnergyGroup = 0;
194 // G4int LastLineInEnergyGroup = 0;
195 // G4bool FoundEnergyGroup = false;
196 // G4bool FoundPID = false;
197 //
198 // while(getline(DataFile, Temp))
199 // {
200 // // Format the string so that it can be interpreted correctly
201 // DataBlock = Temp.substr(0, 66);
202 // Temp = Temp.substr(66);
203 // InsertExponent = 0;
204 // while((InsertExponent = DataBlock.find_first_of("-+", InsertExponent)) !=
205 // G4String::npos)
206 // {
207 // DataBlock.insert(InsertExponent, 1, 'e');
208 // InsertExponent += 2;
209 // }
210 // sscanf(DataBlock.c_str(), "%11le %11le %11le %11le %11le %11le",
211 // &Parts[0], &Parts[1], &Parts[2], &Parts[3], &Parts[4], &Parts[5]);
212 // sscanf(Temp.substr(0, 4).c_str(), "%i", &MAT);
213 // sscanf(Temp.substr(4, 2).c_str(), "%i", &MF);
214 // sscanf(Temp.substr(6, 3).c_str(), "%i", &MT);
215 // sscanf(Temp.substr(9).c_str(), "%i", &LN);
216 //
217 // if(MT == YieldType_)
218 // {
219 // if(LN == 1)
220 // {
221 // if(FoundPID != true)
222 // {
223 // // The first line of an ENDF section for MT = 454 or 459
224 // // always contains the parent PID
225 // // This section can potentially be expanded to check and
226 // // verify that it is the correct nucleus
227 // FoundPID = true;
228 //
229 // continue;
230 // }
231 // } else if(FoundPID == true && FoundEnergyGroup == false)
232 // {
233 // // Skip this line if it is not the energy definition line
234 // if(Parts[1] != 0 || Parts[3] != 0)
235 // {
236 // continue;
237 // }
238 //
239 // // The first block is the incident neutron energy
240 // // information.
241 // // Check to make sure that it is spontaneous or neutron
242 // // induced.
243 // if(Cause_ == G4FFGEnumerations::NEUTRON_INDUCED)
244 // {
245 // if(Parts[0] != 0)
246 // {
247 // FoundEnergyGroup = true;
248 // }
249 // } else if(Cause_ == G4FFGEnumerations::SPONTANEOUS)
250 // {
251 // if(Parts[0] == 0)
252 // {
253 // FoundEnergyGroup = true;
254 // }
255 // } else
256 // { // Maybe more fission causes here if added later
257 // FoundEnergyGroup = false;
258 // }
259 //
260 // if(FoundEnergyGroup == true)
261 // {
262 // // Convert to eV
263 // Parts[0] *= eV;
264 //
265 // // Calculate the parameters
266 // FirstLineInEnergyGroup = LN;
267 // LastLineInEnergyGroup = FirstLineInEnergyGroup +
268 // ceil(Parts[4] / 6.0);
269 // ItemCounter = 0;
270 // EmptyProduct = 0;
271 //
272 // // Initialize the data storage
273 // CurrentEnergyGroup++;
274 // EnergyPoints.push_back(Parts[0]);
275 // Yield.push_back(NewDoubleVector);
276 // Yield.back().resize(Product.size(), 0);
277 // Error.push_back(NewDoubleVector);
278 // Error.back().resize(Product.size(), 0);
279 //
280 // continue;
281 // }
282 // }
283 //
284 // if(LN > FirstLineInEnergyGroup && LN <= LastLineInEnergyGroup)
285 // {
286 // for(Block = 0; Block < 6; Block++)
287 // {
288 // if(EmptyProduct > 0)
289 // {
290 // EmptyProduct--;
291 //
292 // continue;
293 // }
294 // switch(ItemCounter % 4)
295 // {
296 // case 0:
297 // // Determine if the block is empty
298 // if(Parts[Block] == 0)
299 // {
300 // EmptyProduct = 3;
301 //
302 // continue;
303 // }
304 //
305 // // Determine if this product is already loaded
306 // for(Location = 0; Location < (signed)Product.size(); Location++)
307 // {
308 // if(Parts[Block] == Product.at(Location) &&
309 // Parts[Block + 1] == MetaState.at(Location))
310 // {
311 // break;
312 // }
313 // }
314 //
315 // // The product hasn't been created yet
316 // // Add it and initialize the other vectors
317 // if(Location == (signed)Product.size())
318 // {
319 // Product.push_back(Parts[Block]);
320 // MetaState.push_back((G4FFGEnumerations::MetaState)Parts[Block +
321 // 1]); Yield.at(CurrentEnergyGroup).push_back(0.0);
322 // Error.at(CurrentEnergyGroup).push_back(0.0);
323 // }
324 // break;
325 //
326 // case 2:
327 // Yield.at(CurrentEnergyGroup).at(Location) = Parts[Block];
328 // break;
329 //
330 // case 3:
331 // Error.at(CurrentEnergyGroup).at(Location) = Parts[Block];
332 // break;
333 // }
334 //
335 // ItemCounter++;
336 // }
337 // }
338 //
339 // if (LN == LastLineInEnergyGroup)
340 // {
341 // FoundEnergyGroup = false;
342 // }
343 // }
344 // }
345 //
346 // G4ENDFYieldDataContainer* NewDataContainer;
347 // EnergyGroups_ = EnergyPoints.size();
348 // EnergyGroupValues_ = new G4double[EnergyGroups_];
349 // G4int NewProduct;
350 // G4FFGEnumerations::MetaState NewMetaState;
351 // G4double* NewYield = new G4double[EnergyGroups_];
352 // G4double* NewError = new G4double[EnergyGroups_];
353 //
354 // for(G4int i = 0; i < EnergyGroups_; i++)
355 // {
356 // // Load the energy values
357 // EnergyGroupValues_[i] = EnergyPoints.at(i);
358 //
359 // // Make all the vectors the same size
360 // Yield[i].resize(maxSize, 0.0);
361 // Error[i].resize(maxSize, 0.0);
362 // }
363 //
364 // // Load the data into the yield table
365 // for(ItemCounter = 0; ItemCounter < (signed)Product.size(); ItemCounter++)
366 // {
367 // NewProduct = Product.at(ItemCounter);
368 // NewMetaState = MetaState.at(ItemCounter);
369 //
370 // for(CurrentEnergyGroup = 0; CurrentEnergyGroup < EnergyGroups_; CurrentEnergyGroup++)
371 // {
372 // NewYield[CurrentEnergyGroup] = Yield.at(CurrentEnergyGroup).at(ItemCounter);
373 // NewYield[CurrentEnergyGroup] = Error.at(CurrentEnergyGroup).at(ItemCounter);
374 // }
375 //
376 // NewDataContainer = YieldContainerTable_->G4GetNewContainer(EnergyGroups_ + 1);
377 // NewDataContainer->SetProduct(NewProduct);
378 // NewDataContainer->SetMetaState(NewMetaState);
379 // NewDataContainer->SetYieldProbability(NewYield);
380 // NewDataContainer->SetYieldError(NewError);
381 // }
382 //
383 // delete[] NewYield;
384 // delete[] NewError;
385
386 G4int MT;
387 G4bool correctMT;
388 G4int MF;
389 G4double dummy;
390 G4int blockCount;
391 G4int currentEnergy = 0;
392 G4double incidentEnergy;
393 G4int itemCount;
394 // TODO correctly implement the interpolation in the fission product yield
395 G4int interpolation;
396 G4int isotope;
397 G4int metastate;
398 G4int identifier;
399 G4double yield;
400 // "error" is included here in the event that errors are included in the future
401 G4double error = 0.0;
402 G4int maxSize = 0;
403
404 std::vector<G4double> projectileEnergies;
405 std::map<const G4int, std::pair<std::vector<G4double>, std::vector<G4double>>> intermediateData;
406 std::map<const G4int, std::pair<std::vector<G4double>, std::vector<G4double>>>::iterator
407 dataIterator;
408
409 while (dataStream.good()) // Loop checking, 11.05.2015, T. Koi
410 {
411 dataStream >> MT >> MF >> dummy >> blockCount;
412
413 correctMT = MT == YieldType_;
414
415 for (G4int b = 0; b < blockCount; ++b) {
416 dataStream >> incidentEnergy >> itemCount >> interpolation;
417 maxSize = maxSize >= itemCount ? maxSize : itemCount;
418
419 if (correctMT) {
420 // Load in the energy of the projectile
421 projectileEnergies.push_back(incidentEnergy);
422 currentEnergy = G4int(projectileEnergies.size() - 1);
423 }
424 else {
425 // !!! Do not break since we need to parse through the !!!
426 // !!! entire data file for all possible energies !!!
427 }
428
429 for (G4int i = 0; i < itemCount; ++i) {
430 dataStream >> isotope >> metastate >> yield;
431
432 if (correctMT) {
433 identifier = isotope * 10 + metastate;
434
435 dataIterator =
436 intermediateData
437 .insert(std::make_pair(
438 identifier, std::make_pair(std::vector<G4double>(projectileEnergies.size(), 0.0),
439 std::vector<G4double>(projectileEnergies.size(), 0.0))))
440 .first;
441
442 if (dataIterator->second.first.size() < projectileEnergies.size()) {
443 dataIterator->second.first.resize(projectileEnergies.size());
444 dataIterator->second.second.resize(projectileEnergies.size());
445 }
446
447 dataIterator->second.first[currentEnergy] = yield;
448 dataIterator->second.second[currentEnergy] = error;
449 }
450 else {
451 // !!! Do not break since we need to parse through the !!!
452 // !!! entire data file for all possible energies !!!
453 }
454 }
455 }
456 }
457
458 G4ENDFYieldDataContainer* NewDataContainer;
459 EnergyGroups_ = (G4int)projectileEnergies.size();
460 EnergyGroupValues_ = new G4double[EnergyGroups_];
461 G4int NewProduct;
462 G4FFGEnumerations::MetaState NewMetaState;
463 auto NewYield = new G4double[EnergyGroups_];
464 auto NewError = new G4double[EnergyGroups_];
465
466 for (G4int energyGroup = 0; energyGroup < EnergyGroups_; energyGroup++) {
467 // Load the energy values
468 EnergyGroupValues_[energyGroup] = projectileEnergies[energyGroup];
469 }
470
471 // Load the data into the yield table
472 for (dataIterator = intermediateData.begin(); dataIterator != intermediateData.end();
473 ++dataIterator)
474 {
475 identifier = dataIterator->first;
476 metastate = identifier % 10;
477 switch (metastate) {
478 case 1:
479 NewMetaState = G4FFGEnumerations::META_1;
480 break;
481
482 case 2:
483 NewMetaState = G4FFGEnumerations::META_2;
484 break;
485
486 default:
487 G4Exception("G4ENDFTapeRead::ReadInData()", "Unsupported state", JustWarning,
488 "Unsupported metastable state supplied in fission yield data. Defaulting to "
489 "the ground state");
490 // Fall through
491 case 0:
492 NewMetaState = G4FFGEnumerations::GROUND_STATE;
493 break;
494 }
495 NewProduct = (identifier - metastate) / 10;
496
497 for (G4int energyGroup = 0; energyGroup < EnergyGroups_; energyGroup++) {
498 if (energyGroup < (signed)dataIterator->second.first.size()) {
499 yield = dataIterator->second.first[energyGroup];
500 error = dataIterator->second.second[energyGroup];
501 }
502 else {
503 yield = 0.0;
504 error = 0.0;
505 }
506
507 NewYield[energyGroup] = yield;
508 NewError[energyGroup] = error;
509 }
510
511 NewDataContainer = YieldContainerTable_->G4GetNewContainer(EnergyGroups_);
512 NewDataContainer->SetProduct(NewProduct);
513 NewDataContainer->SetMetaState(NewMetaState);
514 NewDataContainer->SetYieldProbability(NewYield);
515 NewDataContainer->SetYieldError(NewError);
516 }
517
518 delete[] NewYield;
519 delete[] NewError;
520
522}
523
525{
527
528 delete[] EnergyGroupValues_;
529 delete YieldContainerTable_;
530
532}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4FFG_DATA_FUNCTIONENTER__
#define G4FFG_DATA_FUNCTIONLEAVE__
#define G4FFG_FUNCTIONLEAVE__
#define G4FFG_FUNCTIONENTER__
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4double * G4GetEnergyGroupValues()
void Initialize(G4String dataFile)
G4int G4GetNumberOfEnergyGroups()
void G4SetVerbosity(G4int WhatVerbosity)
G4ENDFYieldDataContainer * G4GetYield(G4int WhichYield)
G4ENDFTapeRead(G4String FileLocation, G4String FileName, G4FFGEnumerations::YieldType WhichYield, G4FFGEnumerations::FissionCause WhichCause)
G4int G4GetNumberOfFissionProducts()
void SetMetaState(G4FFGEnumerations::MetaState MetaState)
void SetYieldError(G4double *YieldError)
void SetYieldProbability(G4double *YieldProbability)
void GetDataStream(const G4String &, std::istringstream &iss)
static G4ParticleHPManager * GetInstance()
G4long G4GetNumberOfElements()
T * G4GetContainer(unsigned int WhichContainer)