source: trunk/source/processes/electromagnetic/lowenergy/src/G4ShellData.cc @ 1315

Last change on this file since 1315 was 1315, checked in by garnier, 14 years ago

update geant4-09-04-beta-cand-01 interfaces-V09-03-09 vis-V09-03-08

File size: 10.1 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: G4ShellData.cc,v 1.11 2009/06/10 13:32:36 mantero Exp $
28// GEANT4 tag $Name: geant4-09-04-beta-cand-01 $
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 "G4ShellData.hh"
39#include "G4DataVector.hh"
40#include "G4SystemOfUnits.hh"
41#include <fstream>
42#include <sstream>
43#include <numeric>
44#include <algorithm>
45#include <valarray>
46#include <functional>
47#include "Randomize.hh"
48
49// The following deprecated header is included because <functional> seems not to be found on MGP's laptop
50//#include "function.h"
51
52// Constructor
53
54G4ShellData::G4ShellData(G4int minZ, G4int maxZ, G4bool isOccupancy)
55  : zMin(minZ), zMax(maxZ), occupancyData(isOccupancy)
56{  }
57
58// Destructor
59G4ShellData::~G4ShellData()
60{
61  std::map<G4int,std::vector<G4double>*,std::less<G4int> >::iterator pos;
62  for (pos = idMap.begin(); pos != idMap.end(); ++pos)
63    {
64      std::vector<G4double>* dataSet = (*pos).second;
65      delete dataSet;
66    }
67
68  std::map<G4int,G4DataVector*,std::less<G4int> >::iterator pos2;
69  for (pos2 = bindingMap.begin(); pos2 != bindingMap.end(); ++pos2)
70    {
71      G4DataVector* dataSet = (*pos2).second;
72      delete dataSet;
73    }
74
75  if (occupancyData)
76    {
77      std::map<G4int,std::vector<G4double>*,std::less<G4int> >::iterator pos3;
78      for (pos3 = occupancyPdfMap.begin(); pos3 != occupancyPdfMap.end(); ++pos3)
79        {
80          std::vector<G4double>* dataSet = (*pos3).second;
81          delete dataSet;
82        }
83    }
84}
85
86
87size_t G4ShellData::NumberOfShells(G4int Z) const
88{
89  G4int z = Z - 1;
90  G4int n = 0;
91
92  if (Z>= zMin && Z <= zMax)
93    {
94      n = nShells[z];
95    }
96  return n;
97}
98
99
100const std::vector<G4double>& G4ShellData::ShellIdVector(G4int Z) const
101{
102  std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
103  if (Z < zMin || Z > zMax) G4Exception("G4ShellData::ShellIdVector - Z outside boundaries");
104  pos = idMap.find(Z);
105  std::vector<G4double>* dataSet = (*pos).second;
106  return *dataSet;
107}
108
109
110const std::vector<G4double>& G4ShellData::ShellVector(G4int Z) const
111{
112  std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
113  if (Z < zMin || Z > zMax) G4Exception("G4ShellData::ShellVector - Z outside boundaries");
114  pos = occupancyPdfMap.find(Z);
115  std::vector<G4double>* dataSet = (*pos).second;
116  return *dataSet;
117}
118
119
120G4int G4ShellData::ShellId(G4int Z, G4int shellIndex) const
121{
122  G4int n = -1;
123
124  if (Z >= zMin && Z <= zMax)
125    {
126      std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
127      pos = idMap.find(Z);
128      if (pos!= idMap.end())
129        {
130          std::vector<G4double> dataSet = *((*pos).second);
131          G4int nData = dataSet.size();
132          if (shellIndex >= 0 && shellIndex < nData)
133            {
134              n = (G4int) dataSet[shellIndex];
135            }
136        }
137    }
138  return n;
139}
140
141
142G4double G4ShellData::ShellOccupancyProbability(G4int Z, G4int shellIndex) const
143{
144  G4double prob = -1.;
145
146  if (Z >= zMin && Z <= zMax)
147    {
148      std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator pos;
149      pos = idMap.find(Z);
150      if (pos!= idMap.end())
151        {
152          std::vector<G4double> dataSet = *((*pos).second);
153          G4int nData = dataSet.size();
154          if (shellIndex >= 0 && shellIndex < nData)
155            {
156              prob = dataSet[shellIndex];
157            }
158        }
159    }
160  return prob;
161}
162
163
164
165G4double G4ShellData::BindingEnergy(G4int Z, G4int shellIndex)  const
166{
167  G4double value = 0.;
168
169  if (Z >= zMin && Z <= zMax)
170    {
171      std::map<G4int,G4DataVector*,std::less<G4int> >::const_iterator pos;
172      pos = bindingMap.find(Z);
173      if (pos!= bindingMap.end())
174        {
175          G4DataVector dataSet = *((*pos).second);
176          G4int nData = dataSet.size();
177          if (shellIndex >= 0 && shellIndex < nData)
178            {
179              value = dataSet[shellIndex];
180            }
181        }
182    }
183  return value;
184}
185
186void G4ShellData::PrintData() const
187{
188  for (G4int Z = zMin; Z <= zMax; Z++)
189    {
190      G4cout << "---- Shell data for Z = "
191             << Z
192             << " ---- "
193             << G4endl;
194      G4int nSh = nShells[Z-1];
195      std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator posId;
196      posId = idMap.find(Z);
197      std::vector<G4double>* ids = (*posId).second;
198      std::map<G4int,G4DataVector*,std::less<G4int> >::const_iterator posE;
199      posE = bindingMap.find(Z);
200      G4DataVector* energies = (*posE).second;
201      for (G4int i=0; i<nSh; i++)
202        {
203          G4int id = (G4int) (*ids)[i];
204          G4double e = (*energies)[i] / keV;
205          G4cout << i << ") ";
206
207          if (occupancyData) 
208            {
209              G4cout << " Occupancy: ";
210            }
211          else 
212            {
213              G4cout << " Shell id: ";
214            }
215          G4cout << id << " - Binding energy = "
216                 << e << " keV ";
217            if (occupancyData)
218              {
219                std::map<G4int,std::vector<G4double>*,std::less<G4int> >::const_iterator posOcc;
220                posOcc = occupancyPdfMap.find(Z);
221                std::vector<G4double> probs = *((*posOcc).second);
222                G4double prob = probs[i];
223                G4cout << "- Probability = " << prob;
224              }
225            G4cout << G4endl;
226        }
227      G4cout << "-------------------------------------------------" 
228             << G4endl;
229    }
230}
231
232
233void G4ShellData::LoadData(const G4String& fileName)
234{ 
235  // Build the complete string identifying the file with the data set
236 
237  std::ostringstream ost;
238 
239  ost << fileName << ".dat";
240 
241  G4String name(ost.str());
242 
243  char* path = getenv("G4LEDATA");
244  if (!path)
245    { 
246      G4String excep("G4EMDataSet - G4LEDATA environment variable not set");
247      G4Exception(excep);
248    }
249 
250  G4String pathString(path);
251  G4String dirFile = pathString + name;
252  std::ifstream file(dirFile);
253  std::filebuf* lsdp = file.rdbuf();
254
255  if (! (lsdp->is_open()) )
256    {
257      G4String s1("G4ShellData - data file: ");
258      G4String s2(" not found");
259      G4String excep = s1 + dirFile + s2;
260      G4Exception(excep);
261    }
262
263  G4double a = 0;
264  G4int k = 1;
265  G4int s = 0;
266 
267  G4int Z = 1;
268  G4DataVector* energies = new G4DataVector;
269  std::vector<G4double>* ids = new std::vector<G4double>;
270
271  do {
272    file >> a;
273    G4int nColumns = 2;
274    if (a == -1)
275      {
276        if (s == 0)
277          {
278            // End of a shell data set
279            idMap[Z] = ids;
280            bindingMap[Z] = energies;
281            G4int n = ids->size();
282            nShells.push_back(n);
283            // Start of new shell data set
284            ids = new std::vector<G4double>;
285            energies = new G4DataVector;
286            Z++;           
287          }     
288        s++;
289        if (s == nColumns)
290        {
291          s = 0;
292        }
293      }
294    else if (a == -2)
295      {
296        // End of file; delete the empty vectors created when encountering the last -1 -1 row
297        delete energies;
298        delete ids;
299        //nComponents = components.size();
300      }
301    else
302      {
303        // 1st column is shell id
304        if(k%nColumns != 0)
305          {         
306            ids->push_back(a);
307            k++;
308          }
309        else if (k%nColumns == 0)
310          {
311            // 2nd column is binding energy
312            G4double e = a * MeV;
313            energies->push_back(e);
314            k = 1;
315          }
316      }
317  } while (a != -2); // end of file
318  file.close();   
319
320  // For Doppler broadening: the data set contains shell occupancy and binding energy for each shell
321  // Build additional map with probability for each shell based on its occupancy
322
323  if (occupancyData)
324    {
325      // Build cumulative from raw shell occupancy
326
327      for (G4int Z=zMin; Z <= zMax; Z++)
328        {
329          std::vector<G4double> occupancy = ShellIdVector(Z);
330
331          std::vector<G4double>* prob = new std::vector<G4double>;
332          G4double scale = 1. / G4double(Z);
333
334          prob->push_back(occupancy[0] * scale);
335          for (size_t i=1; i<occupancy.size(); i++)
336            {
337              prob->push_back(occupancy[i]*scale + (*prob)[i-1]);
338            }
339          occupancyPdfMap[Z] = prob;
340
341          /*
342            G4double scale = 1. / G4double(Z);
343            //      transform((*prob).begin(),(*prob).end(),(*prob).begin(),bind2nd(multiplies<G4double>(),scale));
344
345            for (size_t i=0; i<occupancy.size(); i++)
346            {
347            (*prob)[i] *= scale;
348            }
349          */
350        }
351    }
352}
353
354
355G4int G4ShellData::SelectRandomShell(G4int Z) const
356{
357  if (Z < zMin || Z > zMax) G4Exception("G4ShellData::RandomSelect - Z outside boundaries");
358
359  G4int shellIndex = 0;   
360  std::vector<G4double> prob = ShellVector(Z);
361  G4double random = G4UniformRand();
362
363  // std::vector<G4double>::const_iterator pos;
364  // pos = lower_bound(prob.begin(),prob.end(),random);
365
366  // Binary search the shell with probability less or equal random
367
368  G4int nShells = NumberOfShells(Z);
369  G4int upperBound = nShells;
370
371  while (shellIndex <= upperBound) 
372    {
373      G4int midShell = (shellIndex + upperBound) / 2;
374      if ( random < prob[midShell] ) 
375        upperBound = midShell - 1;
376      else 
377        shellIndex = midShell + 1;
378    } 
379  if (shellIndex >= nShells) shellIndex = nShells - 1;
380
381  return shellIndex;
382}
Note: See TracBrowser for help on using the repository browser.