Geant4 10.7.0
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 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<size_t> vtmp(1,0);
219 size_t numMatCuts = thePCTable->GetTableSize();
220 for (size_t imc=0; imc<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 size_t numElems = elemVect->size();
230 for (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 size_t indx = std::find(cVect.begin(), cVect.end(), gamCut)-cVect.begin();
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 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 (size_t i=0; i<stZ->fNumGammaCuts-1; ++i) {
274 for (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<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 (size_t i=0; i<stZ->fGamCutIndxToMatCutIndx.size(); ++i) {
291 for (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 (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 (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 G4int iKLow = (cutKappa>1.e-12)
308 ? std::lower_bound(fKappaVect.begin(), fKappaVect.end(), cutKappa)
309 - fKappaVect.begin() -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 char* path = std::getenv("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 char* path = std::getenv("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::begin(zTable->fGammaECuts),std::end(zTable->fGammaECuts))
412 -std::begin(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 = std::lower_bound(fElEnergyVect.begin(),
422 fElEnergyVect.end(), elEmin) - fElEnergyVect.begin() -1;
423 }
424 // high:
425 zTable->fMaxElEnergyIndx = 0;
426 if (elEmax>=fElEnergyVect[fNumElEnergy-1]) {
427 zTable->fMaxElEnergyIndx = fNumElEnergy-1;
428 } else {
429 // lower + 1
430 zTable->fMaxElEnergyIndx = std::lower_bound(fElEnergyVect.begin(),
431 fElEnergyVect.end(), elEmax) - fElEnergyVect.begin();
432 }
433 // protect
434 if (zTable->fMaxElEnergyIndx<=zTable->fMinElEnergyIndx) {
435 return;
436 }
437 // load sampling tables that are needed: file is already in the stream
438 zTable->fTablesPerEnergy.resize(fNumElEnergy, nullptr);
439 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
440 // go over data that are not needed
441 if (iee<zTable->fMinElEnergyIndx || iee>zTable->fMaxElEnergyIndx) {
442 for (G4int ik=0; ik<fNumKappa; ++ik) {
443 G4double dum;
444 infile >> dum; infile >> dum; infile >> dum;
445 }
446 } else { // load data that are needed
447 zTable->fTablesPerEnergy[iee] = new STable();
448 zTable->fTablesPerEnergy[iee]->fSTable.resize(fNumKappa);
449 for (G4int ik=0; ik<fNumKappa; ++ik) {
450 STPoint &stP = zTable->fTablesPerEnergy[iee]->fSTable[ik];
451 infile >> stP.fCum;
452 infile >> stP.fParA;
453 infile >> stP.fParB;
454 }
455 }
456 }
457}
458
459// clean away all sampling tables and make ready to re-install
461 for (G4int iz=0; iz<fMaxZet+1; ++iz) {
462 if (fSBSamplingTables[iz]) {
463 for (G4int iee=0; iee<fNumElEnergy; ++iee) {
464 if (fSBSamplingTables[iz]->fTablesPerEnergy[iee]) {
465 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fSTable.clear();
466 fSBSamplingTables[iz]->fTablesPerEnergy[iee]->fCumCutValues.clear();
467 }
468 }
469 fSBSamplingTables[iz]->fTablesPerEnergy.clear();
470 fSBSamplingTables[iz]->fGammaECuts.clear();
471 fSBSamplingTables[iz]->fLogGammaECuts.clear();
472 fSBSamplingTables[iz]->fMatCutIndxToGamCutIndx.clear();
473 //
474 delete fSBSamplingTables[iz];
475 fSBSamplingTables[iz] = nullptr;
476 }
477 }
478 fSBSamplingTables.clear();
479 fElEnergyVect.clear();
480 fLElEnergyVect.clear();
481 fKappaVect.clear();
482 fLKappaVect.clear();
483 fMaxZet = -1;
484}
485
486//void G4SBBremTable::Dump() {
487// G4cerr<< "\n ===== Dumping ===== \n" << G4endl;
488// for (G4int iz=0; iz<fMaxZet+1; ++iz) {
489// if (fSBSamplingTables[iz]) {
490// G4cerr<< " ----> There are " << fSBSamplingTables[iz]->fNumGammaCuts
491// << " g-cut for Z = " << iz << G4endl;
492// for (size_t ic=0; ic<fSBSamplingTables[iz]->fGammaECuts.size(); ++ic)
493// G4cerr<< " i = " << ic << " "
494// << fSBSamplingTables[iz]->fGammaECuts[ic] << G4endl;
495// }
496// }
497//}
498
499// find lower bin index of value: used in acse of CDF values i.e. val in [0,1)
500// while vector elements in [0,1]
501G4int G4SBBremTable::LinSearch(const std::vector<STPoint>& vect,
502 const G4int size,
503 const G4double val) {
504 G4int i= 0;
505 while (i + 3 < size) {
506 if (vect [i + 0].fCum > val) return i + 0;
507 if (vect [i + 1].fCum > val) return i + 1;
508 if (vect [i + 2].fCum > val) return i + 2;
509 if (vect [i + 3].fCum > val) return i + 3;
510 i += 4;
511 }
512 while (i < size) {
513 if (vect [i].fCum > val)
514 break;
515 ++i;
516 }
517 return i;
518}
519
520// uncompress one data file into the input string stream
521void G4SBBremTable::ReadCompressedFile(const G4String &fname,
522 std::istringstream &iss) {
523 std::string *dataString = nullptr;
524 std::string compfilename(fname+".z");
525 // create input stream with binary mode operation and positioning at the end
526 // of the file
527 std::ifstream in(compfilename, std::ios::binary | std::ios::ate);
528 if (in.good()) {
529 // get current position in the stream (was set to the end)
530 int fileSize = in.tellg();
531 // set current position being the beginning of the stream
532 in.seekg(0,std::ios::beg);
533 // create (zlib) byte buffer for the data
534 Bytef *compdata = new Bytef[fileSize];
535 while(in) {
536 in.read((char*)compdata, fileSize);
537 }
538 // create (zlib) byte buffer for the uncompressed data
539 uLongf complen = (uLongf)(fileSize*4);
540 Bytef *uncompdata = new Bytef[complen];
541 while (Z_OK!=uncompress(uncompdata, &complen, compdata, fileSize)) {
542 // increase uncompressed byte buffer
543 delete[] uncompdata;
544 complen *= 2;
545 uncompdata = new Bytef[complen];
546 }
547 // delete the compressed data buffer
548 delete [] compdata;
549 // create a string from the uncompressed data (will be deleted by the caller)
550 dataString = new std::string((char*)uncompdata, (long)complen);
551 // delete the uncompressed data buffer
552 delete [] uncompdata;
553 } else {
554 std::string msg = " Problem while trying to read "
555 + compfilename + " data file.\n";
556 G4Exception("G4SBBremTable::ReadCompressedFile","em0006",
557 FatalException,msg.c_str());
558 return;
559 }
560 // create the input string stream from the data string
561 if (dataString) {
562 iss.str(*dataString);
563 in.close();
564 delete dataString;
565 }
566}
std::vector< G4Element * > G4ElementVector
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:179
G4double G4Log(G4double x)
Definition: G4Log.hh:226
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
G4int GetZasInt() const
Definition: G4Element.hh:131
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:188
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