Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4DataSet.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// $Id$
28//
29// Author: Maria Grazia Pia ([email protected])
30//
31// History:
32// -----------
33// 31 Jul 2001 MGP Created
34// 31 Jul 2008 MGP Revised and renamed to G4DataSet
35//
36// -------------------------------------------------------------------
37
38#include "G4DataSet.hh"
39#include "G4IInterpolator.hh"
40#include <fstream>
41#include <sstream>
42#include "G4Integrator.hh"
43#include "Randomize.hh"
44#include "G4LinInterpolation.hh"
45
46
48 G4IInterpolator* algo,
49 G4double xUnit,
50 G4double yUnit,
51 G4bool random):
52 z(Z),
53 energies(0),
54 data(0),
55 algorithm(algo),
56 unitEnergies(xUnit),
57 unitData(yUnit),
58 pdf(0),
59 randomSet(random)
60{
61 if (algorithm == 0) G4Exception("G4DataSet::G4DataSet",
62 "pii00000101",
64 "Interpolation == 0");
65 if (randomSet) BuildPdf();
66}
67
69 G4DataVector* dataX,
70 G4DataVector* dataY,
71 G4IInterpolator* algo,
72 G4double xUnit,
73 G4double yUnit,
74 G4bool random):
75 z(argZ),
76 energies(dataX),
77 data(dataY),
78 algorithm(algo),
79 unitEnergies(xUnit),
80 unitData(yUnit),
81 pdf(0),
82 randomSet(random)
83{
84 if (algorithm == 0) G4Exception("G4DataSet::G4DataSet",
85 "pii00000110",
87 "Interpolation == 0");
88
89 if ((energies == 0) ^ (data == 0))
90 G4Exception("G4DataSet::G4DataSet",
91 "pii00000111-",
93 "different size for energies and data (zero case)");
94
95 if (energies == 0) return;
96
97 if (energies->size() != data->size())
98 G4Exception("G4DataSet::G4DataSet",
99 "pii00000112",
101 "different size for energies and data");
102
103 if (randomSet) BuildPdf();
104}
105
107{
108 delete algorithm;
109 if (energies) delete energies;
110 if (data) delete data;
111 if (pdf) delete pdf;
112}
113
114G4double G4DataSet::FindValue(G4double energy, G4int /* componentId */) const
115{
116 if (!energies) G4Exception("G4DataSet::FindValue",
117 "pii00000120",
119 "energies == 0");
120 if (energies->empty()) return 0;
121 if (energy <= (*energies)[0]) return (*data)[0];
122
123 size_t i = energies->size()-1;
124 if (energy >= (*energies)[i]) return (*data)[i];
125
126 G4double interpolated = algorithm->Calculate(energy,FindLowerBound(energy),*energies,*data);
127 return interpolated;
128}
129
130
131void G4DataSet::PrintData(void) const
132{
133 if (!energies)
134 {
135 G4cout << "Data not available." << G4endl;
136 }
137 else
138 {
139 size_t size = energies->size();
140 for (size_t i(0); i<size; i++)
141 {
142 G4cout << "Point: " << ((*energies)[i]/unitEnergies)
143 << " - Data value: " << ((*data)[i]/unitData);
144 if (pdf != 0) G4cout << " - PDF : " << (*pdf)[i];
145 G4cout << G4endl;
146 }
147 }
148}
149
150
152 G4DataVector* dataY,
153 G4int /* componentId */)
154{
155 if (energies) delete energies;
156 energies = dataX;
157
158 if (data) delete data;
159 data = dataY;
160
161 if ((energies == 0) ^ (data==0))
162 G4Exception("G4DataSet::SetEnergiesData",
163 "pii00000130",
165 "different size for energies and data (zero case)");
166
167 if (energies == 0) return;
168
169 if (energies->size() != data->size())
170 G4Exception("G4DataSet::SetEnergiesData",
171 "pii00000131",
173 "different size for energies and data");
174}
175
177{
178 // The file is organized into two columns:
179 // 1st column is the energy
180 // 2nd column is the corresponding value
181 // The file terminates with the pattern: -1 -1
182 // -2 -2
183
184 G4String fullFileName(FullFileName(fileName));
185 std::ifstream in(fullFileName);
186
187 if (!in.is_open())
188 {
189
190 std::ostringstream message;
191 message << "G4DataSet::LoadData - data file " << fullFileName << " not found";
192
193 G4Exception("G4CompositeDataSet::LoadData",
194 "pii00000140",
196 message.str().c_str());
197 }
198
199 G4DataVector* argEnergies=new G4DataVector;
200 G4DataVector* argData=new G4DataVector;
201
202 G4double a;
203 bool energyColumn(true);
204
205 do
206 {
207 in >> a;
208
209 if (a!=-1 && a!=-2)
210 {
211 if (energyColumn)
212 {
213 // std::cout << fullFileName << ", a = " << a <<std::endl;
214 argEnergies->push_back(a*unitEnergies);
215 }
216 else
217 argData->push_back(a*unitData);
218 energyColumn=(!energyColumn);
219 }
220 }
221 while (a != -2);
222
223 SetEnergiesData(argEnergies, argData, 0);
224 if (randomSet) BuildPdf();
225
226 return true;
227}
228
230{
231 // The file is organized into two columns:
232 // 1st column is the energy
233 // 2nd column is the corresponding value
234 // The file terminates with the pattern: -1 -1
235 // -2 -2
236
237 G4String fullFileName(FullFileName(name));
238 std::ofstream out(fullFileName);
239
240 if (!out.is_open())
241 {
242
243 std::ostringstream message;
244 message << "G4DataSet:: SaveData - cannot open " << fullFileName;
245
246 G4Exception("G4CompositeDataSet::SaveData",
247 "pii00000150",
249 message.str().c_str());
250
251 }
252
253 out.precision(10);
254 out.width(15);
255 out.setf(std::ofstream::left);
256
257 if (energies!=0 && data!=0)
258 {
259 G4DataVector::const_iterator i(energies->begin());
260 G4DataVector::const_iterator endI(energies->end());
261 G4DataVector::const_iterator j(data->begin());
262
263 while (i!=endI)
264 {
265 out.precision(10);
266 out.width(15);
267 out.setf(std::ofstream::left);
268 out << ((*i)/unitEnergies) << ' ';
269
270 out.precision(10);
271 out.width(15);
272 out.setf(std::ofstream::left);
273 out << ((*j)/unitData) << std::endl;
274
275 i++;
276 j++;
277 }
278 }
279
280 out.precision(10);
281 out.width(15);
282 out.setf(std::ofstream::left);
283 out << -1.f << ' ';
284
285 out.precision(10);
286 out.width(15);
287 out.setf(std::ofstream::left);
288 out << -1.f << std::endl;
289
290 out.precision(10);
291 out.width(15);
292 out.setf(std::ofstream::left);
293 out << -2.f << ' ';
294
295 out.precision(10);
296 out.width(15);
297 out.setf(std::ofstream::left);
298 out << -2.f << std::endl;
299
300 return true;
301}
302
303size_t G4DataSet::FindLowerBound(G4double x) const
304{
305 size_t lowerBound = 0;
306 size_t upperBound(energies->size() - 1);
307
308 while (lowerBound <= upperBound)
309 {
310 size_t midBin((lowerBound + upperBound) / 2);
311
312 if (x < (*energies)[midBin]) upperBound = midBin - 1;
313 else lowerBound = midBin + 1;
314 }
315
316 return upperBound;
317}
318
319
320size_t G4DataSet::FindLowerBound(G4double x, G4DataVector* values) const
321{
322 size_t lowerBound = 0;;
323 size_t upperBound(values->size() - 1);
324
325 while (lowerBound <= upperBound)
326 {
327 size_t midBin((lowerBound + upperBound) / 2);
328
329 if (x < (*values)[midBin]) upperBound = midBin - 1;
330 else lowerBound = midBin + 1;
331 }
332
333 return upperBound;
334}
335
336
337G4String G4DataSet::FullFileName(const G4String& name) const
338{
339 char* path = getenv("G4PIIDATA");
340 if (!path)
341 G4Exception("G4DataSet::FullFileName",
342 "pii00000160",
344 "G4PIIDATA environment variable not set");
345
346 std::ostringstream fullFileName;
347 fullFileName << path << '/' << name << z << ".dat";
348
349 return G4String(fullFileName.str().c_str());
350}
351
352
353void G4DataSet::BuildPdf()
354{
355 pdf = new G4DataVector;
357
358 G4int nData = data->size();
359 pdf->push_back(0.);
360
361 // Integrate the data distribution
362 G4int i;
363 G4double totalSum = 0.;
364 for (i=1; i<nData; i++)
365 {
366 G4double xLow = (*energies)[i-1];
367 G4double xHigh = (*energies)[i];
368 G4double sum = integrator.Legendre96(this, &G4DataSet::IntegrationFunction, xLow, xHigh);
369 totalSum = totalSum + sum;
370 pdf->push_back(totalSum);
371 }
372
373 // Normalize to the last bin
374 G4double tot = 0.;
375 if (totalSum > 0.) tot = 1. / totalSum;
376 for (i=1; i<nData; i++)
377 {
378 (*pdf)[i] = (*pdf)[i] * tot;
379 }
380}
381
382
383G4double G4DataSet::RandomSelect(G4int /* componentId */) const
384{
385 // Random select a X value according to the cumulative probability distribution
386 // derived from the data
387
388 if (!pdf) G4Exception("G4DataSet::RandomSelect",
389 "pii00000170",
391 "PDF has not been created for this data set");
392
393 G4double value = 0.;
395
396 // Locate the random value in the X vector based on the PDF
397 size_t bin = FindLowerBound(x,pdf);
398
399 // Interpolate the PDF to calculate the X value:
400 // linear interpolation in the first bin (to avoid problem with 0),
401 // interpolation with associated data set algorithm in other bins
402
403 G4LinInterpolation linearAlgo;
404 if (bin == 0) value = linearAlgo.Calculate(x, bin, *pdf, *energies);
405 else value = algorithm->Calculate(x, bin, *pdf, *energies);
406
407 // G4cout << x << " random bin "<< bin << " - " << value << G4endl;
408 return value;
409}
410
411G4double G4DataSet::IntegrationFunction(G4double x)
412{
413 // This function is needed by G4Integrator to calculate the integral of the data distribution
414
415 G4double y = 0;
416
417 // Locate the random value in the X vector based on the PDF
418 size_t bin = FindLowerBound(x);
419
420 // Interpolate to calculate the X value:
421 // linear interpolation in the first bin (to avoid problem with 0),
422 // interpolation with associated algorithm in other bins
423
424 G4LinInterpolation linearAlgo;
425
426 if (bin == 0) y = linearAlgo.Calculate(x, bin, *energies, *data);
427 else y = algorithm->Calculate(x, bin, *energies, *data);
428
429 return y;
430}
431
@ FatalException
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
virtual void PrintData(void) const
Definition: G4DataSet.cc:131
virtual void SetEnergiesData(G4DataVector *xData, G4DataVector *data, G4int componentId)
Definition: G4DataSet.cc:151
G4DataSet(G4int argZ, G4IInterpolator *algo, G4double xUnit=CLHEP::MeV, G4double yUnit=CLHEP::barn, G4bool random=false)
Definition: G4DataSet.cc:47
virtual ~G4DataSet()
Definition: G4DataSet.cc:106
virtual G4double RandomSelect(G4int componentId=0) const
Definition: G4DataSet.cc:383
virtual G4bool SaveData(const G4String &fileName) const
Definition: G4DataSet.cc:229
virtual G4double FindValue(G4double x, G4int componentId=0) const
Definition: G4DataSet.cc:114
virtual G4bool LoadData(const G4String &fileName)
Definition: G4DataSet.cc:176
virtual G4double Calculate(G4double point, G4int bin, const G4DataVector &energies, const G4DataVector &data) const =0
G4double Calculate(G4double point, G4int bin, const G4DataVector &energies, const G4DataVector &data) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41