source: trunk/source/processes/electromagnetic/lowenergy/src/G4EMDataSet.cc@ 1057

Last change on this file since 1057 was 1007, checked in by garnier, 17 years ago

update to geant4.9.2

File size: 10.3 KB
Line 
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: G4EMDataSet.cc,v 1.18 2008/03/17 13:40:53 pia Exp $
28// GEANT4 tag $Name: geant4-09-02 $
29//
30// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
31//
32// History:
33// -----------
34// 31 Jul 2001 MGP Created
35//
36// -------------------------------------------------------------------
37
38#include "G4EMDataSet.hh"
39#include "G4VDataSetAlgorithm.hh"
40#include <fstream>
41#include <sstream>
42#include "G4Integrator.hh"
43#include "Randomize.hh"
44#include "G4LinInterpolation.hh"
45
46
47G4EMDataSet::G4EMDataSet(G4int Z,
48 G4VDataSetAlgorithm* 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("G4EMDataSet::G4EMDataSet - interpolation == 0");
62 if (randomSet) BuildPdf();
63}
64
65G4EMDataSet::G4EMDataSet(G4int argZ,
66 G4DataVector* dataX,
67 G4DataVector* dataY,
68 G4VDataSetAlgorithm* algo,
69 G4double xUnit,
70 G4double yUnit,
71 G4bool random):
72 z(argZ),
73 energies(dataX),
74 data(dataY),
75 algorithm(algo),
76 unitEnergies(xUnit),
77 unitData(yUnit),
78 pdf(0),
79 randomSet(random)
80{
81 if (algorithm == 0) G4Exception("G4EMDataSet::G4EMDataSet - interpolation == 0");
82
83 if ((energies == 0) ^ (data == 0))
84 G4Exception("G4EMDataSet::G4EMDataSet - different size for energies and data (zero case)");
85
86 if (energies == 0) return;
87
88 if (energies->size() != data->size())
89 G4Exception("G4EMDataSet::G4EMDataSet - different size for energies and data");
90
91 if (randomSet) BuildPdf();
92}
93
94G4EMDataSet::~G4EMDataSet()
95{
96 delete algorithm;
97 if (energies) delete energies;
98 if (data) delete data;
99 if (pdf) delete pdf;
100}
101
102G4double G4EMDataSet::FindValue(G4double energy, G4int /* componentId */) const
103{
104 if (!energies) G4Exception("G4EMDataSet::FindValue - energies == 0");
105 if (energies->empty()) return 0;
106 if (energy <= (*energies)[0]) return (*data)[0];
107
108 size_t i = energies->size()-1;
109 if (energy >= (*energies)[i]) return (*data)[i];
110
111 return algorithm->Calculate(energy, FindLowerBound(energy), *energies, *data);
112}
113
114
115void G4EMDataSet::PrintData(void) const
116{
117 if (!energies)
118 {
119 G4cout << "Data not available." << G4endl;
120 }
121 else
122 {
123 size_t size = energies->size();
124 for (size_t i(0); i<size; i++)
125 {
126 G4cout << "Point: " << ((*energies)[i]/unitEnergies)
127 << " - Data value: " << ((*data)[i]/unitData);
128 if (pdf != 0) G4cout << " - PDF : " << (*pdf)[i];
129 G4cout << G4endl;
130 }
131 }
132}
133
134
135void G4EMDataSet::SetEnergiesData(G4DataVector* dataX,
136 G4DataVector* dataY,
137 G4int /* componentId */)
138{
139 if (energies) delete energies;
140 energies = dataX;
141
142 if (data) delete data;
143 data = dataY;
144
145 if ((energies == 0) ^ (data==0))
146 G4Exception("G4EMDataSet::SetEnergiesData - different size for energies and data (zero case)");
147
148 if (energies == 0) return;
149
150 if (energies->size() != data->size())
151 G4Exception("G4EMDataSet::SetEnergiesData - different size for energies and data");
152}
153
154G4bool G4EMDataSet::LoadData(const G4String& fileName)
155{
156 // The file is organized into two columns:
157 // 1st column is the energy
158 // 2nd column is the corresponding value
159 // The file terminates with the pattern: -1 -1
160 // -2 -2
161
162 G4String fullFileName(FullFileName(fileName));
163 std::ifstream in(fullFileName);
164
165 if (!in.is_open())
166 {
167 G4String message("G4EMDataSet::LoadData - data file \"");
168 message += fullFileName;
169 message += "\" not found";
170 G4Exception(message);
171 }
172
173 G4DataVector* argEnergies=new G4DataVector;
174 G4DataVector* argData=new G4DataVector;
175
176 G4double a;
177 bool energyColumn(true);
178
179 do
180 {
181 in >> a;
182
183 if (a!=-1 && a!=-2)
184 {
185 if (energyColumn)
186 argEnergies->push_back(a*unitEnergies);
187 else
188 argData->push_back(a*unitData);
189 energyColumn=(!energyColumn);
190 }
191 }
192 while (a != -2);
193
194 SetEnergiesData(argEnergies, argData, 0);
195 if (randomSet) BuildPdf();
196
197 return true;
198}
199
200G4bool G4EMDataSet::SaveData(const G4String& name) const
201{
202 // The file is organized into two columns:
203 // 1st column is the energy
204 // 2nd column is the corresponding value
205 // The file terminates with the pattern: -1 -1
206 // -2 -2
207
208 G4String fullFileName(FullFileName(name));
209 std::ofstream out(fullFileName);
210
211 if (!out.is_open())
212 {
213 G4String message("G4EMDataSet::SaveData - cannot open \"");
214 message+=fullFileName;
215 message+="\"";
216 G4Exception(message);
217 }
218
219 out.precision(10);
220 out.width(15);
221 out.setf(std::ofstream::left);
222
223 if (energies!=0 && data!=0)
224 {
225 G4DataVector::const_iterator i(energies->begin());
226 G4DataVector::const_iterator endI(energies->end());
227 G4DataVector::const_iterator j(data->begin());
228
229 while (i!=endI)
230 {
231 out.precision(10);
232 out.width(15);
233 out.setf(std::ofstream::left);
234 out << ((*i)/unitEnergies) << ' ';
235
236 out.precision(10);
237 out.width(15);
238 out.setf(std::ofstream::left);
239 out << ((*j)/unitData) << std::endl;
240
241 i++;
242 j++;
243 }
244 }
245
246 out.precision(10);
247 out.width(15);
248 out.setf(std::ofstream::left);
249 out << -1.f << ' ';
250
251 out.precision(10);
252 out.width(15);
253 out.setf(std::ofstream::left);
254 out << -1.f << std::endl;
255
256 out.precision(10);
257 out.width(15);
258 out.setf(std::ofstream::left);
259 out << -2.f << ' ';
260
261 out.precision(10);
262 out.width(15);
263 out.setf(std::ofstream::left);
264 out << -2.f << std::endl;
265
266 return true;
267}
268
269size_t G4EMDataSet::FindLowerBound(G4double x) const
270{
271 size_t lowerBound = 0;
272 size_t upperBound(energies->size() - 1);
273
274 while (lowerBound <= upperBound)
275 {
276 size_t midBin((lowerBound + upperBound) / 2);
277
278 if (x < (*energies)[midBin]) upperBound = midBin - 1;
279 else lowerBound = midBin + 1;
280 }
281
282 return upperBound;
283}
284
285
286size_t G4EMDataSet::FindLowerBound(G4double x, G4DataVector* values) const
287{
288 size_t lowerBound = 0;;
289 size_t upperBound(values->size() - 1);
290
291 while (lowerBound <= upperBound)
292 {
293 size_t midBin((lowerBound + upperBound) / 2);
294
295 if (x < (*values)[midBin]) upperBound = midBin - 1;
296 else lowerBound = midBin + 1;
297 }
298
299 return upperBound;
300}
301
302
303G4String G4EMDataSet::FullFileName(const G4String& name) const
304{
305 char* path = getenv("G4LEDATA");
306 if (!path)
307 G4Exception("G4EMDataSet::FullFileName - G4LEDATA environment variable not set");
308
309 std::ostringstream fullFileName;
310 fullFileName << path << '/' << name << z << ".dat";
311
312 return G4String(fullFileName.str().c_str());
313}
314
315
316void G4EMDataSet::BuildPdf()
317{
318 pdf = new G4DataVector;
319 G4Integrator <G4EMDataSet, G4double(G4EMDataSet::*)(G4double)> integrator;
320
321 G4int nData = data->size();
322 pdf->push_back(0.);
323
324 // Integrate the data distribution
325 G4int i;
326 G4double totalSum = 0.;
327 for (i=1; i<nData; i++)
328 {
329 G4double xLow = (*energies)[i-1];
330 G4double xHigh = (*energies)[i];
331 G4double sum = integrator.Legendre96(this, &G4EMDataSet::IntegrationFunction, xLow, xHigh);
332 totalSum = totalSum + sum;
333 pdf->push_back(totalSum);
334 }
335
336 // Normalize to the last bin
337 G4double tot = 0.;
338 if (totalSum > 0.) tot = 1. / totalSum;
339 for (i=1; i<nData; i++)
340 {
341 (*pdf)[i] = (*pdf)[i] * tot;
342 }
343}
344
345
346G4double G4EMDataSet::RandomSelect(G4int /* componentId */) const
347{
348 // Random select a X value according to the cumulative probability distribution
349 // derived from the data
350
351 if (!pdf) G4Exception("G4EMDataSet::RandomSelect - PDF has not been created for this data set");
352
353 G4double value = 0.;
354 G4double x = G4UniformRand();
355
356 // Locate the random value in the X vector based on the PDF
357 size_t bin = FindLowerBound(x,pdf);
358
359 // Interpolate the PDF to calculate the X value:
360 // linear interpolation in the first bin (to avoid problem with 0),
361 // interpolation with associated data set algorithm in other bins
362
363 G4LinInterpolation linearAlgo;
364 if (bin == 0) value = linearAlgo.Calculate(x, bin, *pdf, *energies);
365 else value = algorithm->Calculate(x, bin, *pdf, *energies);
366
367 // G4cout << x << " random bin "<< bin << " - " << value << G4endl;
368 return value;
369}
370
371G4double G4EMDataSet::IntegrationFunction(G4double x)
372{
373 // This function is needed by G4Integrator to calculate the integral of the data distribution
374
375 G4double y = 0;
376
377 // Locate the random value in the X vector based on the PDF
378 size_t bin = FindLowerBound(x);
379
380 // Interpolate to calculate the X value:
381 // linear interpolation in the first bin (to avoid problem with 0),
382 // interpolation with associated algorithm in other bins
383
384 G4LinInterpolation linearAlgo;
385
386 if (bin == 0) y = linearAlgo.Calculate(x, bin, *energies, *data);
387 else y = algorithm->Calculate(x, bin, *energies, *data);
388
389 return y;
390}
391
Note: See TracBrowser for help on using the repository browser.