Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4SBBremTable.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 Class file
30//
31//
32// File name: G4SBBremTable
33//
34// Author: Mihaly Novak
35//
36// Creation date: 15.07.2018
37//
38// Modifications:
39//
40// -------------------------------------------------------------------
41//
42#include "G4SBBremTable.hh"
43
44#include "G4SystemOfUnits.hh"
45
46#include "G4Material.hh"
49#include "Randomize.hh"
50
51#include "G4String.hh"
52
53#include "G4Log.hh"
54#include "G4Exp.hh"
55
56#include "zlib.h"
57
58#include <iostream>
59#include <fstream>
60#include <sstream>
61#include <algorithm>
62
64 : fMaxZet(-1), fNumElEnergy(-1), fNumKappa(-1), fUsedLowEenergy(-1.),
65 fUsedHighEenergy(-1.), fLogMinElEnergy(-1.), fILDeltaElEnergy(-1.)
66{}
67
69{
71}
72
73void G4SBBremTable::Initialize(const G4double lowe, const G4double highe)
74{
75 fUsedLowEenergy = lowe;
76 fUsedHighEenergy = highe;
77 BuildSamplingTables();
78 InitSamplingTables();
79// Dump();
80}
81
82// run-time method that samples energy transferred to the emitted gamma photon
84 const G4double leekin,
85 const G4double gcut,
86 const G4double dielSupConst,
87 const G4int iZet,
88 const G4int matCutIndx,
89 const G4bool isElectron)
90{
91 static const G4double kAlpha2Pi = CLHEP::twopi*CLHEP::fine_structure_const;
92 const G4double zet = (G4double)iZet;
93 const G4int izet = std::max(std::min(fMaxZet, iZet),1);
94 G4double eGamma = 0.;
95 // this should be checked in the caller
96 // if (eekin<=gcut) return kappa;
97 const G4double lElEnergy = leekin;
98 const SamplingTablePerZ* stZ = fSBSamplingTables[izet];
99 // get the gamma cut of this Z that corresponds to the current mat-cuts
100 const std::size_t gamCutIndx = stZ->fMatCutIndxToGamCutIndx[matCutIndx];
101 // gcut was not found: should never happen (only in verbose mode)
102 if (gamCutIndx >= stZ->fNumGammaCuts || stZ->fGammaECuts[gamCutIndx]!=gcut) {
103 G4String msg = " Gamma cut="+std::to_string(gcut) + " [MeV] was not found ";
104 msg += "in case of Z = " + std::to_string(iZet) + ". ";
105 G4Exception("G4SBBremTable::SampleEnergyTransfer()","em0X",FatalException,
106 msg.c_str());
107 }
108 const G4double lGCut = stZ->fLogGammaECuts[gamCutIndx];
109 // get the random engine
110 CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
111 // find lower e- energy bin
112 G4bool isCorner = false; // indicate that the lower edge e- energy < gam-gut
113 G4bool isSimply = false; // simply sampling: isCorner+lower egde is selected
114 G4int elEnergyIndx = stZ->fMaxElEnergyIndx;
115 // only if e- ekin is below the maximum value(use table at maximum otherwise)
116 if (eekin < fElEnergyVect[elEnergyIndx]) {
117 const G4double val = (lElEnergy-fLogMinElEnergy)*fILDeltaElEnergy;
118 elEnergyIndx = (G4int)val;
119 G4double pIndxH = val-elEnergyIndx;
120 // check if we are at limiting case: lower edge e- energy < gam-gut
121 if (fElEnergyVect[elEnergyIndx]<=gcut) {
122 // recompute the probability of taking the higher e- energy bin()
123 pIndxH = (lElEnergy-lGCut)/(fLElEnergyVect[elEnergyIndx+1]-lGCut);
124 isCorner = true;
125 }
126 //
127 if (rndmEngine->flat()<pIndxH) {
128 ++elEnergyIndx; // take the table at the higher e- energy bin
129 } else if (isCorner) { // take the table at the lower e- energy bin
130 // special sampling need to be done if lower edge e- energy < gam-gut:
131 // actually, we "sample" from a table "built" at the gamm-cut i.e. delta
132 isSimply = true;
133 }
134 }
135 // should never happen under normal conditions but add protection
136 if (!stZ->fTablesPerEnergy[elEnergyIndx]) {
137 return 0.;
138 }
139 // Do the photon energy sampling:
140 const STable *st = stZ->fTablesPerEnergy[elEnergyIndx];
141 const std::vector<G4double>& cVect = st->fCumCutValues;
142 const std::vector<STPoint>& pVect = st->fSTable;
143 const G4double minVal = cVect[gamCutIndx];
144
145 // should never happen under normal conditions but add protection
146 if (minVal >= 1.) {
147 return 0.;
148 }
149 // some transfomrmtion variables used in the looop
150 const G4double lCurKappaC = lGCut - leekin;
151 const G4double lUsedKappaC = lGCut - fLElEnergyVect[elEnergyIndx];
152 // dielectric (always) and e+ correction suppressions (if the primary is e+)
153 G4double suppression = 1.;
154 G4double rndm[2];
155 // rejection loop starts here
156 do {
157 rndmEngine->flatArray(2, rndm);
158 G4double kappa = 1.0;
159 if (!isSimply) {
160 const G4double cumRV = rndm[0]*(1.-minVal)+minVal;
161 // find lower index of the values in the Cumulative Function: use linear
162 // instead of binary search because it's faster in our case
163 const G4int cumLIndx = LinSearch(pVect, fNumKappa, cumRV)-1;
164// const G4int cumLIndx = std::lower_bound( pVect.begin(), pVect.end(), cumRV,
165// [](const STPoint& p, const double& cumV) {
166// return p.fCum<cumV; } ) - pVect.begin() -1;
167 const STPoint& stPL = pVect[cumLIndx];
168 const G4double pA = stPL.fParA;
169 const G4double pB = stPL.fParB;
170 const G4double cumL = stPL.fCum;
171 const G4double cumH = pVect[cumLIndx+1].fCum;
172 const G4double lKL = fLKappaVect[cumLIndx];
173 const G4double lKH = fLKappaVect[cumLIndx+1];
174 const G4double dm1 = (cumRV-cumL)/(cumH-cumL);
175 const G4double dm2 = (1.+pA+pB)*dm1;
176 const G4double dm3 = 1.+dm1*(pA+pB*dm1);
177 // kappa sampled at E_i e- energy
178 const G4double lKappa = lKL+dm2/dm3*(lKH-lKL);
179 // transform lKappa to [log(gcut/eekin),0] form [log(gcut/E_i),0]
180 kappa = G4Exp(lKappa*lCurKappaC/lUsedKappaC);
181 } else {
182// const G4double upLimit = std::min(1.*CLHEP::eV,eekin-gcut);
183// kappa = (gcut+rndm[0]*upLimit)/eekin;
184 kappa = 1.-rndm[0]*(1.-gcut/eekin);
185 }
186 // compute the emitted photon energy: k
187 eGamma = kappa*eekin;
188 const G4double invEGamma = 1./eGamma;
189 // compute dielectric suppression: 1/(1+[gk_p/k]^2)
190 suppression = 1./(1.+dielSupConst*invEGamma*invEGamma);
191 // add positron correction if particle is e+
192 if (!isElectron) {
193 const G4double e1 = eekin - gcut;
194 const G4double iBeta1 = (e1 + CLHEP::electron_mass_c2)
195 / std::sqrt(e1*(e1 + 2.*CLHEP::electron_mass_c2));
196 const G4double e2 = eekin - eGamma;
197 const G4double iBeta2 = (e2 + CLHEP::electron_mass_c2)
198 / std::sqrt(e2*(e2 + 2.*CLHEP::electron_mass_c2));
199 const G4double dum = kAlpha2Pi*zet*(iBeta1 - iBeta2);
200 suppression = (dum > -12.) ? suppression*G4Exp(dum) : 0.;
201 }
202 } while (rndm[1] > suppression);
203 // end of rejection loop
204 // return the sampled photon energy value k
205 return eGamma;
206}
207
208
209void G4SBBremTable::BuildSamplingTables() {
210 // claer
212 LoadSTGrid();
213 // First elements and gamma cuts data structures need to be built:
214 // loop over all material-cuts and add gamma cut to the list of elements
217 // a temporary vector to store one element
218 std::vector<std::size_t> vtmp(1,0);
219 std::size_t numMatCuts = thePCTable->GetTableSize();
220 for (G4int imc=0; imc<(G4int)numMatCuts; ++imc) {
221 const G4MaterialCutsCouple *matCut = thePCTable->GetMaterialCutsCouple(imc);
222 if (!matCut->IsUsed()) {
223 continue;
224 }
225 const G4Material* mat = matCut->GetMaterial();
226 const G4ElementVector* elemVect = mat->GetElementVector();
227 const G4int indxMC = matCut->GetIndex();
228 const G4double gamCut = (*(thePCTable->GetEnergyCutsVector(0)))[indxMC];
229 const std::size_t numElems = elemVect->size();
230 for (std::size_t ielem=0; ielem<numElems; ++ielem) {
231 const G4Element *elem = (*elemVect)[ielem];
232 const G4int izet = std::max(std::min(fMaxZet, elem->GetZasInt()),1);
233 if (!fSBSamplingTables[izet]) {
234 // create data structure but do not load sampling tables yet: will be
235 // loaded after we know what are the min/max e- energies where sampling
236 // will be needed during the simulation for this Z
237 // LoadSamplingTables(izet);
238 fSBSamplingTables[izet] = new SamplingTablePerZ();
239 }
240 // add current gamma cut to the list of this element data (only if this
241 // cut value is still not tehre)
242 const std::vector<double> &cVect = fSBSamplingTables[izet]->fGammaECuts;
243 std::size_t indx = std::find(cVect.cbegin(), cVect.cend(), gamCut)-cVect.cbegin();
244 if (indx==cVect.size()) {
245 vtmp[0] = imc;
246 fSBSamplingTables[izet]->fGamCutIndxToMatCutIndx.push_back(vtmp);
247 fSBSamplingTables[izet]->fGammaECuts.push_back(gamCut);
248 fSBSamplingTables[izet]->fLogGammaECuts.push_back(G4Log(gamCut));
249 ++fSBSamplingTables[izet]->fNumGammaCuts;
250 } else {
251 fSBSamplingTables[izet]->fGamCutIndxToMatCutIndx[indx].push_back(imc);
252 }
253 }
254 }
255}
256
257void G4SBBremTable::InitSamplingTables() {
258 const std::size_t numMatCuts = G4ProductionCutsTable::GetProductionCutsTable()
259 ->GetTableSize();
260 for (G4int iz=1; iz<fMaxZet+1; ++iz) {
261 SamplingTablePerZ* stZ = fSBSamplingTables[iz];
262 if (!stZ) continue;
263 // Load-in sampling table data:
264 LoadSamplingTables(iz);
265 // init data
266 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
267 if (!stZ->fTablesPerEnergy[iee])
268 continue;
269 const G4double elEnergy = fElEnergyVect[iee];
270 // 1 indicates that gamma production is not possible at this e- energy
271 stZ->fTablesPerEnergy[iee]->fCumCutValues.resize(stZ->fNumGammaCuts,1.);
272 // sort gamma cuts and other members accordingly
273 for (std::size_t i=0; i<stZ->fNumGammaCuts-1; ++i) {
274 for (std::size_t j=i+1; j<stZ->fNumGammaCuts; ++j) {
275 if (stZ->fGammaECuts[j]<stZ->fGammaECuts[i]) {
276 G4double dum0 = stZ->fGammaECuts[i];
277 G4double dum1 = stZ->fLogGammaECuts[i];
278 std::vector<std::size_t> dumv = stZ->fGamCutIndxToMatCutIndx[i];
279 stZ->fGammaECuts[i] = stZ->fGammaECuts[j];
280 stZ->fLogGammaECuts[i] = stZ->fLogGammaECuts[j];
281 stZ->fGamCutIndxToMatCutIndx[i] = stZ->fGamCutIndxToMatCutIndx[j];
282 stZ->fGammaECuts[j] = dum0;
283 stZ->fLogGammaECuts[j] = dum1;
284 stZ->fGamCutIndxToMatCutIndx[j] = dumv;
285 }
286 }
287 }
288 // set couple indices to store the corresponding gamma cut index
289 stZ->fMatCutIndxToGamCutIndx.resize(numMatCuts,-1);
290 for (std::size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
291 for (std::size_t j=0; j<stZ->fGamCutIndxToMatCutIndx[i].size(); ++j) {
292 stZ->fMatCutIndxToGamCutIndx[stZ->fGamCutIndxToMatCutIndx[i][j]] = i;
293 }
294 }
295 // clear temporary vector
296 for (std::size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
297 stZ->fGamCutIndxToMatCutIndx[i].clear();
298 }
299 stZ->fGamCutIndxToMatCutIndx.clear();
300 // init for each gamma cut that are below the e- energy
301 for (std::size_t ic=0; ic<stZ->fNumGammaCuts; ++ic) {
302 const G4double gamCut = stZ->fGammaECuts[ic];
303 if (elEnergy>gamCut) {
304 // find lower kappa index; compute the 'xi' i.e. cummulative value for
305 // gamCut/elEnergy
306 const G4double cutKappa = std::max(1.e-12, gamCut/elEnergy);
307 const std::size_t iKLow = (cutKappa>1.e-12)
308 ? std::lower_bound(fKappaVect.cbegin(), fKappaVect.cend(), cutKappa)
309 - fKappaVect.cbegin() -1
310 : 0;
311 const STPoint* stpL = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow]);
312 const STPoint* stpH = &(stZ->fTablesPerEnergy[iee]->fSTable[iKLow+1]);
313 const G4double pA = stpL->fParA;
314 const G4double pB = stpL->fParB;
315 const G4double etaL = stpL->fCum;
316 const G4double etaH = stpH->fCum;
317 const G4double alph = G4Log(cutKappa/fKappaVect[iKLow])
318 /G4Log(fKappaVect[iKLow+1]/fKappaVect[iKLow]);
319 const G4double dum = pA*(alph-1.)-1.-pB;
320 G4double val = etaL;
321 if (alph==0.) {
322 stZ->fTablesPerEnergy[iee]->fCumCutValues[ic] = val;
323 } else {
324 val = -(dum+std::sqrt(dum*dum-4.*pB*alph*alph))/(2.*pB*alph);
325 val = val*(etaH-etaL)+etaL;
326 stZ->fTablesPerEnergy[iee]->fCumCutValues[ic] = val;
327 }
328 }
329 }
330 }
331 }
332}
333
334// should be called only from LoadSamplingTables(G4int) and once
335void G4SBBremTable::LoadSTGrid() {
336 const char* path = G4FindDataDir("G4LEDATA");
337 if (!path) {
338 G4Exception("G4SBBremTable::LoadSTGrid()","em0006",
339 FatalException, "Environment variable G4LEDATA not defined");
340 return;
341 }
342 const G4String fname = G4String(path) + "/brem_SB/SBTables/grid";
343 std::ifstream infile(fname,std::ios::in);
344 if (!infile.is_open()) {
345 G4String msgc = "Cannot open file: " + fname;
346 G4Exception("G4SBBremTable::LoadSTGrid()","em0006",
347 FatalException, msgc.c_str());
348 return;
349 }
350 // get max Z, # electron energies and # kappa values
351 infile >> fMaxZet;
352 infile >> fNumElEnergy;
353 infile >> fNumKappa;
354 // allocate space for the data and get them in:
355 // (1.) first eletron energy grid
356 fElEnergyVect.resize(fNumElEnergy);
357 fLElEnergyVect.resize(fNumElEnergy);
358 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
359 G4double dum;
360 infile >> dum;
361 fElEnergyVect[iee] = dum*CLHEP::MeV;
362 fLElEnergyVect[iee] = G4Log(fElEnergyVect[iee]);
363 }
364 // (2.) then the kappa grid
365 fKappaVect.resize(fNumKappa);
366 fLKappaVect.resize(fNumKappa);
367 for (G4int ik=0; ik<fNumKappa; ++ik) {
368 infile >> fKappaVect[ik];
369 fLKappaVect[ik] = G4Log(fKappaVect[ik]);
370 }
371 // (3.) set size of the main container for sampling tables
372 fSBSamplingTables.resize(fMaxZet+1,nullptr);
373 // init electron energy grid related variables: use accurate values !!!
374// fLogMinElEnergy = G4Log(fElEnergyVect[0]);
375// fILDeltaElEnergy = 1./G4Log(fElEnergyVect[1]/fElEnergyVect[0]);
376 const G4double elEmin = 100.0*CLHEP::eV; //fElEnergyVect[0];
377 const G4double elEmax = 10.0*CLHEP::GeV;//fElEnergyVect[fNumElEnergy-1];
378 fLogMinElEnergy = G4Log(elEmin);
379 fILDeltaElEnergy = 1./(G4Log(elEmax/elEmin)/(fNumElEnergy-1.0));
380 // reset min/max energies if needed
381 fUsedLowEenergy = std::max(fUsedLowEenergy ,elEmin);
382 fUsedHighEenergy = std::min(fUsedHighEenergy,elEmax);
383 //
384 infile.close();
385}
386
387void G4SBBremTable::LoadSamplingTables(G4int iz) {
388 // check if grid needs to be loaded first
389 if (fMaxZet<0) {
390 LoadSTGrid();
391 }
392 // load data for a given Z only once
393 iz = std::max(std::min(fMaxZet, iz),1);
394 const char* path = G4FindDataDir("G4LEDATA");
395 if (!path) {
396 G4Exception("G4SBBremTable::LoadSamplingTables()","em0006",
397 FatalException, "Environment variable G4LEDATA not defined");
398 return;
399 }
400 const G4String fname = G4String(path) + "/brem_SB/SBTables/sTableSB_"
401 + std::to_string(iz);
402 std::istringstream infile(std::ios::in);
403 // read the compressed data file into the stream
404 ReadCompressedFile(fname, infile);
405 // the SamplingTablePerZ object was already created, set size of containers
406 // then load sampling table data for each electron energies
407 SamplingTablePerZ* zTable = fSBSamplingTables[iz];
408 //
409 // Determine min/max elektron kinetic energies and indices
410 const G4double minGammaCut = zTable->fGammaECuts[ std::min_element(
411 std::cbegin(zTable->fGammaECuts),std::cend(zTable->fGammaECuts))
412 -std::cbegin(zTable->fGammaECuts)];
413 const G4double elEmin = std::max(fUsedLowEenergy, minGammaCut);
414 const G4double elEmax = fUsedHighEenergy;
415 // find low/high elecrton energy indices where tables will be needed
416 // low:
417 zTable->fMinElEnergyIndx = 0;
418 if (elEmin>=fElEnergyVect[fNumElEnergy-1]) {
419 zTable->fMinElEnergyIndx = fNumElEnergy-1;
420 } else {
421 zTable->fMinElEnergyIndx = G4int(std::lower_bound(fElEnergyVect.cbegin(),
422 fElEnergyVect.cend(), elEmin)
423 - fElEnergyVect.cbegin() -1);
424 }
425 // high:
426 zTable->fMaxElEnergyIndx = 0;
427 if (elEmax>=fElEnergyVect[fNumElEnergy-1]) {
428 zTable->fMaxElEnergyIndx = fNumElEnergy-1;
429 } else {
430 // lower + 1
431 zTable->fMaxElEnergyIndx = G4int(std::lower_bound(fElEnergyVect.cbegin(),
432 fElEnergyVect.cend(), elEmax)
433 - fElEnergyVect.cbegin());
434 }
435 // protect
436 if (zTable->fMaxElEnergyIndx<=zTable->fMinElEnergyIndx) {
437 return;
438 }
439 // load sampling tables that are needed: file is already in the stream
440 zTable->fTablesPerEnergy.resize(fNumElEnergy, nullptr);
441 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
442 // go over data that are not needed
443 if (iee<zTable->fMinElEnergyIndx || iee>zTable->fMaxElEnergyIndx) {
444 for (G4int ik=0; ik<fNumKappa; ++ik) {
445 G4double dum;
446 infile >> dum; infile >> dum; infile >> dum;
447 }
448 } else { // load data that are needed
449 zTable->fTablesPerEnergy[iee] = new STable();
450 zTable->fTablesPerEnergy[iee]->fSTable.resize(fNumKappa);
451 for (G4int ik=0; ik<fNumKappa; ++ik) {
452 STPoint &stP = zTable->fTablesPerEnergy[iee]->fSTable[ik];
453 infile >> stP.fCum;
454 infile >> stP.fParA;
455 infile >> stP.fParB;
456 }
457 }
458 }
459}
460
461// clean away all sampling tables and make ready to re-install
463 for (G4int iz=0; iz<fMaxZet+1; ++iz) {
464 if (fSBSamplingTables[iz]) {
465 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
466 if (fSBSamplingTables[iz]->fTablesPerEnergy[iee]) {
467 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fSTable.clear();
468 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fCumCutValues.clear();
469 }
470 }
471 fSBSamplingTables[iz]->fTablesPerEnergy.clear();
472 fSBSamplingTables[iz]->fGammaECuts.clear();
473 fSBSamplingTables[iz]->fLogGammaECuts.clear();
474 fSBSamplingTables[iz]->fMatCutIndxToGamCutIndx.clear();
475 //
476 delete fSBSamplingTables[iz];
477 fSBSamplingTables[iz] = nullptr;
478 }
479 }
480 fSBSamplingTables.clear();
481 fElEnergyVect.clear();
482 fLElEnergyVect.clear();
483 fKappaVect.clear();
484 fLKappaVect.clear();
485 fMaxZet = -1;
486}
487
488//void G4SBBremTable::Dump() {
489// G4cerr<< "\n ===== Dumping ===== \n" << G4endl;
490// for (G4int iz=0; iz<fMaxZet+1; ++iz) {
491// if (fSBSamplingTables[iz]) {
492// G4cerr<< " ----> There are " << fSBSamplingTables[iz]->fNumGammaCuts
493// << " g-cut for Z = " << iz << G4endl;
494// for (std::size_t ic=0; ic<fSBSamplingTables[iz]->fGammaECuts.size(); ++ic)
495// G4cerr<< " i = " << ic << " "
496// << fSBSamplingTables[iz]->fGammaECuts[ic] << G4endl;
497// }
498// }
499//}
500
501// find lower bin index of value: used in acse of CDF values i.e. val in [0,1)
502// while vector elements in [0,1]
503G4int G4SBBremTable::LinSearch(const std::vector<STPoint>& vect,
504 const G4int size,
505 const G4double val) {
506 G4int i= 0;
507 while (i + 3 < size) {
508 if (vect [i + 0].fCum > val) return i + 0;
509 if (vect [i + 1].fCum > val) return i + 1;
510 if (vect [i + 2].fCum > val) return i + 2;
511 if (vect [i + 3].fCum > val) return i + 3;
512 i += 4;
513 }
514 while (i < size) {
515 if (vect [i].fCum > val)
516 break;
517 ++i;
518 }
519 return i;
520}
521
522// uncompress one data file into the input string stream
523void G4SBBremTable::ReadCompressedFile(const G4String &fname,
524 std::istringstream &iss) {
525 std::string *dataString = nullptr;
526 std::string compfilename(fname+".z");
527 // create input stream with binary mode operation and positioning at the end
528 // of the file
529 std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
530 if (in.good()) {
531 // get current position in the stream (was set to the end)
532 std::streamoff fileSize = in.tellg();
533 // set current position being the beginning of the stream
534 in.seekg(0,std::ios::beg);
535 // create (zlib) byte buffer for the data
536 Bytef *compdata = new Bytef[fileSize];
537 while(in) {
538 in.read((char*)compdata, fileSize);
539 }
540 // create (zlib) byte buffer for the uncompressed data
541 uLongf complen = (uLongf)(fileSize*4);
542 Bytef *uncompdata = new Bytef[complen];
543 while (Z_OK!=uncompress(uncompdata, &complen, compdata, fileSize)) {
544 // increase uncompressed byte buffer
545 delete[] uncompdata;
546 complen *= 2;
547 uncompdata = new Bytef[complen];
548 }
549 // delete the compressed data buffer
550 delete [] compdata;
551 // create a string from the uncompressed data (will be deleted by the caller)
552 dataString = new std::string((char*)uncompdata, (long)complen);
553 // delete the uncompressed data buffer
554 delete [] uncompdata;
555 } else {
556 std::string msg = " Problem while trying to read "
557 + compfilename + " data file.\n";
558 G4Exception("G4SBBremTable::ReadCompressedFile","em0006",
559 FatalException,msg.c_str());
560 return;
561 }
562 // create the input string stream from the data string
563 if (dataString) {
564 iss.str(*dataString);
565 in.close();
566 delete dataString;
567 }
568}
std::vector< const G4Element * > G4ElementVector
const char * G4FindDataDir(const char *)
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
G4double G4Log(G4double x)
Definition: G4Log.hh:227
#define elem(i, j)
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
virtual double flat()=0
virtual void flatArray(const int size, double *vect)=0
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:185
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
double SampleEnergyTransfer(const G4double eekin, const G4double leekin, const G4double gcut, const G4double dielSupConst, const G4int izet, const G4int matCutIndx, const bool iselectron)
void Initialize(const G4double lowe, const G4double highe)
void ClearSamplingTables()
int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: uncompr.c:85
#define Z_OK
Definition: zlib.h:177