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

Last change on this file since 1063 was 1007, checked in by garnier, 15 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.