Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4DNASamplingTable.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#include "G4DNASamplingTable.hh"
29#include "G4EmParameters.hh"
30#include "Randomize.hh"
31#include "G4Log.hh"
32#include "G4Exp.hh"
33
34#include <vector>
35#include <fstream>
36#include <sstream>
37
38
40{
41 fPrimaryEnergy.reserve(npoints);
42 fSecEnergy.reserve(npoints);
43 for (G4int i=0; i<5; ++i) { (fPDF[i]).reserve(npoints); }
44}
45
47{
48 for (auto & p : fSecEnergy) { delete p; }
49 for (G4int i=0; i<5; ++i) {
50 for (auto & p : fPDF[i]) { delete p; }
51 }
52}
53
55 G4double fact, G4bool verbose)
56{
57 std::ostringstream ost;
58 ost << G4EmParameters::Instance()->GetDirLEDATA() << "/" << fname;
59 std::ifstream fin(ost.str().c_str());
60 if (!fin.is_open()) {
62 ed << "File <" << ost.str().c_str() << "> is not opened!";
63 G4Exception("G4DNASamplingTable::LoadDifferential ", "em0003",
64 FatalException, ed, "");
65 return;
66 }
67
68 G4double t, e, sig;
69 G4double e0{0.0};
70 G4int ntmax{0};
71 G4int nt{0};
72 std::vector<G4double>* v = nullptr;
73 std::vector<G4double>* vPDF[5];
74 for (;;) {
75 fin >> e;
76 if (fin.eof()) { break; }
77 if (e != e0 || nullptr == v) {
78 fPrimaryEnergy.push_back(e*factE);
79 e0 = e;
80 ++fNpoints;
81 v = new std::vector<G4double>;
82 fSecEnergy.push_back(v);
83 for (G4int i=0; i<5; ++i) {
84 vPDF[i] = new std::vector<G4double>;
85 (fPDF[i]).push_back(vPDF[i]);
86 }
87 ntmax = std::max(ntmax, nt);
88 nt = 0;
89 }
90 fin >> t;
91 v->push_back(t*factE);
92 ++nt;
93 for (G4int i=0; i<5; ++i) {
94 fin >> sig;
95 sig *= fact;
96 (vPDF[i])->push_back(sig);
97 }
98 if (fin.eof()) { break; }
99 }
100 if (verbose) {
101 G4cout << "G4DNASamplingTable::LoadData from file:" << G4endl;
102 G4cout << fname << G4endl;
103 G4cout << " Nenergy= " << fNpoints << " NmaxT= " << ntmax << G4endl;
104 }
105 if (fNpoints > 0) { --fNpoints; }
106}
107
109 G4double ekinSec, G4int shell) const
110{
111 std::vector<G4double>* e1{nullptr};
112 std::vector<G4double>* e2{nullptr};
113 std::vector<G4double>* s1{nullptr};
114 std::vector<G4double>* s2{nullptr};
115 G4int idx = GetIndex(fPrimaryEnergy, ekinPrimary);
116 if (idx == -1) {
117 e1 = fSecEnergy[0];
118 s1 = (fPDF[shell])[0];
119 } else if (idx > fNpoints) {
120 e1 = fSecEnergy[fNpoints];
121 s1 = (fPDF[shell])[fNpoints];
122 } else {
123 e1 = fSecEnergy[idx];
124 s1 = (fPDF[shell])[idx];
125 e2 = fSecEnergy[idx + 1];
126 s2 = (fPDF[shell])[idx + 1];
127 }
128 // edge cases
129 G4double res1 = VecInterpolation(e1, s1, ekinSec);
130 if (nullptr == e2) { return res1; }
131
132 // ordinary case
133 G4double res2 = VecInterpolation(e2, s2, ekinSec);
134 G4double res = Interpolate(fPrimaryEnergy[idx], fPrimaryEnergy[idx + 1],
135 ekinPrimary, res1, res2);
136 return res;
137}
138
139G4int G4DNASamplingTable::GetIndex(const std::vector<G4double>& v, G4double x) const
140{
141 G4int idx;
142 if (x <= v[0]) { idx = -1; }
143 else if (x >= v.back()) { idx = (G4int)v.size(); }
144 else {
145 std::size_t i = std::upper_bound(v.cbegin(), v.cend(), x) - v.cbegin() - 1;
146 idx = (G4int)i;
147 }
148 return idx;
149}
150
151G4double G4DNASamplingTable::VecInterpolation(const std::vector<G4double>* ener,
152 const std::vector<G4double>* val,
153 G4double e) const
154{
155 G4int idx = GetIndex(*ener, e);
156 G4double res;
157 if (idx == -1) { res = (*val)[0]; }
158 else if (e >= ener->back()) { res = val->back(); }
159 else {
160 res = Interpolate((*ener)[idx], (*ener)[idx + 1], e, (*val)[idx], (*val)[idx + 1]);
161 }
162 return res;
163}
164
165G4double G4DNASamplingTable::Interpolate(G4double e1, G4double e2, G4double e,
166 G4double xs1, G4double xs2) const
167{
168 G4double res;
169 // special case
170 if (e1 == e2) {
171 res = 0.5 * (xs1 + xs2);
172
173 // Log-log interpolation by default
174 } else if (e1 > 0.0 && e2 > 0.0 && xs1 > 0.0 && xs2 > 0.0) {
175 G4double y = G4Log(xs1) + G4Log(e/e1) * G4Log(xs2/xs1)/G4Log(e2/e1);
176 res = G4Exp(y);
177
178 // Lin-Log interpolation
179 } else if (xs1 > 0.0 && xs2 > 0.0) {
180 G4double y = G4Log(xs1) + (e - e1) * G4Log(xs2/xs1)/(e2 - e1);
181 res = G4Exp(y);
182
183 // Lin-Lin interpolation
184 } else {
185 res = xs1 + (e - e1) * (xs2 - xs1)/(e2 - e1);
186 }
187 return res;
188}
189
192{
193 std::vector<G4double>* e1{nullptr};
194 std::vector<G4double>* e2{nullptr};
195 std::vector<G4double>* s1{nullptr};
196 std::vector<G4double>* s2{nullptr};
197 G4int idx = GetIndex(fPrimaryEnergy, ekinPrimary);
198 if (idx == -1) {
199 e1 = fSecEnergy[0];
200 s1 = (fPDF[shell])[0];
201 } else if (idx > fNpoints) {
202 e1 = fSecEnergy[fNpoints];
203 s1 = (fPDF[shell])[fNpoints];
204 } else {
205 e1 = fSecEnergy[idx];
206 s1 = (fPDF[shell])[idx];
207 e2 = fSecEnergy[idx + 1];
208 s2 = (fPDF[shell])[idx + 1];
209 }
211
212 // edge cases
213 G4double res1 = VecInterpolation(s1, e1, q);
214 if (nullptr == e2) { return res1; }
215
216 // ordinary case
217 G4double res2 = VecInterpolation(s2, e2, q);
218 G4double res = Interpolate(fPrimaryEnergy[idx], fPrimaryEnergy[idx + 1],
219 ekinPrimary, res1, res2);
220 return res;
221}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition G4Exp.hh:132
G4double G4Log(G4double x)
Definition G4Log.hh:169
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
G4DNASamplingTable(std::size_t npoint)
G4double SampleCumulative(G4double ekinPrimary, G4int shell) const
G4double GetValue(G4double ekinPrimary, G4double ekinSecondary, G4int shell) const
void LoadData(const G4String &filename, G4double factorE, G4double scaleFactor, G4bool verbose)
static G4EmParameters * Instance()
const G4String & GetDirLEDATA() const