Geant4  10.01.p01
G4ParticleHPVector.hh
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 // 070606 fix with Valgrind by T. Koi
28 // 080409 Fix div0 error with G4FPE by T. Koi
29 // 080811 Comment out unused method SetBlocked and SetBuffered
30 // Add required cleaning up in CleanUp by T. Koi
31 //
32 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
33 //
34 #ifndef G4ParticleHPVector_h
35 #define G4ParticleHPVector_h 1
36 
37 #include "G4ParticleHPDataPoint.hh"
38 #include "G4PhysicsVector.hh"
40 #include "Randomize.hh"
41 #include "G4ios.hh"
42 #include <fstream>
45 #include "G4ParticleHPHash.hh"
46 #include <cmath>
47 #include <vector>
48 
49 #if defined WIN32-VC
50  #include <float.h>
51 #endif
52 
54 {
57 
58  public:
59 
61 
63 
65 
67 
68  inline void SetVerbose(G4int ff)
69  {
70  Verbose = ff;
71  }
72 
73  inline void Times(G4double factor)
74  {
75  G4int i;
76  for(i=0; i<nEntries; i++)
77  {
78  theData[i].SetY(theData[i].GetY()*factor);
79  }
80  if(theIntegral!=0)
81  {
82  theIntegral[i] *= factor;
83  }
84  }
85 
86  inline void SetPoint(G4int i, const G4ParticleHPDataPoint & it)
87  {
88  G4double x = it.GetX();
89  G4double y = it.GetY();
90  SetData(i, x, y);
91  }
92 
93  inline void SetData(G4int i, G4double x, G4double y)
94  {
95 // G4cout <<"G4ParticleHPVector::SetData called"<<nPoints<<" "<<nEntries<<G4endl;
96  Check(i);
97  if(y>maxValue) maxValue=y;
98  theData[i].SetData(x, y);
99  }
100  inline void SetX(G4int i, G4double e)
101  {
102  Check(i);
103  theData[i].SetX(e);
104  }
105  inline void SetEnergy(G4int i, G4double e)
106  {
107  Check(i);
108  theData[i].SetX(e);
109  }
110  inline void SetY(G4int i, G4double x)
111  {
112  Check(i);
113  if(x>maxValue) maxValue=x;
114  theData[i].SetY(x);
115  }
116  inline void SetXsec(G4int i, G4double x)
117  {
118  Check(i);
119  if(x>maxValue) maxValue=x;
120  theData[i].SetY(x);
121  }
122  inline G4double GetEnergy(G4int i) const { return theData[i].GetX(); }
123  inline G4double GetXsec(G4int i) { return theData[i].GetY(); }
124  inline G4double GetX(G4int i) const
125  {
126  if (i<0) i=0;
127  if(i>=GetVectorLength()) i=GetVectorLength()-1;
128  return theData[i].GetX();
129  }
130  inline const G4ParticleHPDataPoint & GetPoint(G4int i) const { return theData[i]; }
131 
132  void Hash()
133  {
134  G4int i;
135  G4double x, y;
136  for(i=0 ; i<nEntries; i++)
137  {
138  if(0 == (i+1)%10)
139  {
140  x = GetX(i);
141  y = GetY(i);
142  theHash.SetData(i, x, y);
143  }
144  }
145  }
146 
147  void ReHash()
148  {
149  theHash.Clear();
150  Hash();
151  }
152 
155  {
156  G4int i;
157  for(i=min ; i<nEntries; i++)
158  {
159  if(theData[i].GetX()>e) break;
160  }
161  G4int low = i-1;
162  G4int high = i;
163  if(i==0)
164  {
165  low = 0;
166  high = 1;
167  }
168  else if(i==nEntries)
169  {
170  low = nEntries-2;
171  high = nEntries-1;
172  }
173  G4double y;
174  if(e<theData[nEntries-1].GetX())
175  {
176  // Protect against doubled-up x values
177  if( (theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
178  {
179  y = theData[low].GetY();
180  }
181  else
182  {
183  y = theInt.Interpolate(theManager.GetScheme(high), e,
184  theData[low].GetX(), theData[high].GetX(),
185  theData[low].GetY(), theData[high].GetY());
186  }
187  }
188  else
189  {
190  y=theData[nEntries-1].GetY();
191  }
192  return y;
193  }
194 
195  inline G4double GetY(G4double x) {return GetXsec(x);}
196  inline G4int GetVectorLength() const {return nEntries;}
197 
198  inline G4double GetY(G4int i)
199  {
200  if (i<0) i=0;
201  if(i>=GetVectorLength()) i=GetVectorLength()-1;
202  return theData[i].GetY();
203  }
204 
205  inline G4double GetY(G4int i) const
206  {
207  if (i<0) i=0;
208  if(i>=GetVectorLength()) i=GetVectorLength()-1;
209  return theData[i].GetY();
210  }
211  void Dump();
212 
213  inline void InitInterpolation(std::istream & aDataFile)
214  {
215  theManager.Init(aDataFile);
216  }
217 
218  void Init(std::istream & aDataFile, G4int total, G4double ux=1., G4double uy=1.)
219  {
220  G4double x,y;
221  for (G4int i=0;i<total;i++)
222  {
223  aDataFile >> x >> y;
224  x*=ux;
225  y*=uy;
226  SetData(i,x,y);
227  if(0 == nEntries%10)
228  {
229  theHash.SetData(nEntries-1, x, y);
230  }
231  }
232  }
233 
234  void Init(std::istream & aDataFile,G4double ux=1., G4double uy=1.)
235  {
236  G4int total;
237  aDataFile >> total;
238  if(theData!=0) delete [] theData;
240  nPoints=total;
241  nEntries=0;
242  theManager.Init(aDataFile);
243  Init(aDataFile, total, ux, uy);
244  }
245 
246  void ThinOut(G4double precision);
247 
248  inline void SetLabel(G4double aLabel)
249  {
250  label = aLabel;
251  }
252 
254  {
255  return label;
256  }
257 
258  inline void CleanUp()
259  {
260  nEntries=0;
262  maxValue = -DBL_MAX;
263  theHash.Clear();
264 //080811 TK DB
265  delete[] theIntegral;
266  theIntegral = NULL;
267  }
268 
269  // merges the vectors active and passive into *this
271  {
272  CleanUp();
273  G4int s_tmp = 0, n=0, m_tmp=0;
274  G4ParticleHPVector * tmp;
275  G4int a = s_tmp, p = n, t;
276  while (a<active->GetVectorLength()&&p<passive->GetVectorLength())
277  {
278  if(active->GetEnergy(a) <= passive->GetEnergy(p))
279  {
280  G4double xa = active->GetEnergy(a);
281  G4double yy = active->GetXsec(a);
282  SetData(m_tmp, xa, yy);
283  theManager.AppendScheme(m_tmp, active->GetScheme(a));
284  m_tmp++;
285  a++;
286  G4double xp = passive->GetEnergy(p);
287 
288 //080409 TKDB
289  //if( std::abs(std::abs(xp-xa)/xa)<0.001 ) p++;
290  if ( !( xa == 0 ) && std::abs(std::abs(xp-xa)/xa)<0.001 ) p++;
291  } else {
292  tmp = active;
293  t=a;
294  active = passive;
295  a=p;
296  passive = tmp;
297  p=t;
298  }
299  }
300  while (a!=active->GetVectorLength())
301  {
302  SetData(m_tmp, active->GetEnergy(a), active->GetXsec(a));
303  theManager.AppendScheme(m_tmp++, active->GetScheme(a));
304  a++;
305  }
306  while (p!=passive->GetVectorLength())
307  {
308  if(std::abs(GetEnergy(m_tmp-1)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.001)
309  //if(std::abs(GetEnergy(m)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.001)
310  {
311  SetData(m_tmp, passive->GetEnergy(p), passive->GetXsec(p));
312  theManager.AppendScheme(m_tmp++, active->GetScheme(p));
313  }
314  p++;
315  }
316  }
317 
318  void Merge(G4InterpolationScheme aScheme, G4double aValue,
320 
321  G4double SampleLin() // Samples X according to distribution Y, linear int
322  {
323  G4double result;
325  if(GetVectorLength()==1)
326  {
327  result = theData[0].GetX();
328  }
329  else
330  {
331  G4int i;
332  G4double rand = G4UniformRand();
333 
334  // this was replaced
335 // for(i=1;i<GetVectorLength();i++)
336 // {
337 // if(rand<theIntegral[i]/theIntegral[GetVectorLength()-1]) break;
338 // }
339 
340 // by this (begin)
341  for(i=GetVectorLength()-1; i>=0 ;i--)
342  {
343  if(rand>theIntegral[i]/theIntegral[GetVectorLength()-1]) break;
344  }
345  if(i!=GetVectorLength()-1) i++;
346 // until this (end)
347 
348  G4double x1, x2, y1, y2;
349  y1 = theData[i-1].GetX();
350  x1 = theIntegral[i-1];
351  y2 = theData[i].GetX();
352  x2 = theIntegral[i];
353  if(std::abs((y2-y1)/y2)<0.0000001) // not really necessary, since the case is excluded by construction
354  {
355  y1 = theData[i-2].GetX();
356  x1 = theIntegral[i-2];
357  }
358  result = theLin.Lin(rand, x1, x2, y1, y2);
359  }
360  return result;
361  }
362 
363  G4double Sample(); // Samples X according to distribution Y
364 
366  {
367  return theIntegral;
368  }
369 
370  inline void IntegrateAndNormalise()
371  {
372  G4int i;
373  if(theIntegral!=0) return;
375  if(nEntries == 1)
376  {
377  theIntegral[0] = 1;
378  return;
379  }
380  theIntegral[0] = 0;
381  G4double sum = 0;
382  G4double x1 = 0;
383  G4double x0 = 0;
384  for(i=1;i<GetVectorLength();i++)
385  {
386  x1 = theData[i].GetX();
387  x0 = theData[i-1].GetX();
388  if (std::abs(x1-x0) > std::abs(x1*0.0000001) )
389  {
390  //********************************************************************
391  //EMendoza -> the interpolation scheme is not always lin-lin
392  /*
393  sum+= 0.5*(theData[i].GetY()+theData[i-1].GetY())*
394  (x1-x0);
395  */
396  //********************************************************************
398  G4double y0 = theData[i-1].GetY();
399  G4double y1 = theData[i].GetY();
400  G4double integ=theInt.GetBinIntegral(aScheme,x0,x1,y0,y1);
401 #if defined WIN32-VC
402  if(!_finite(integ)){integ=0;}
403 #elif defined __IBMCPP__
404  if(isinf(integ)||isnan(integ)){integ=0;}
405 #else
406  if(std::isinf(integ)||std::isnan(integ)){integ=0;}
407 #endif
408  sum+=integ;
409  //********************************************************************
410  }
411  theIntegral[i] = sum;
412  }
414  for(i=1;i<GetVectorLength();i++)
415  {
416  theIntegral[i]/=total;
417  }
418  }
419 
420  inline void Integrate()
421  {
422  G4int i;
423  if(nEntries == 1)
424  {
425  totalIntegral = 0;
426  return;
427  }
428  G4double sum = 0;
429  for(i=1;i<GetVectorLength();i++)
430  {
431  if(std::abs((theData[i].GetX()-theData[i-1].GetX())/theData[i].GetX())>0.0000001)
432  {
433  G4double x1 = theData[i-1].GetX();
434  G4double x2 = theData[i].GetX();
435  G4double y1 = theData[i-1].GetY();
436  G4double y2 = theData[i].GetY();
438  if(aScheme==LINLIN||aScheme==CLINLIN||aScheme==ULINLIN)
439  {
440  sum+= 0.5*(y2+y1)*(x2-x1);
441  }
442  else if(aScheme==LINLOG||aScheme==CLINLOG||aScheme==ULINLOG)
443  {
444  G4double a = y1;
445  G4double b = (y2-y1)/(std::log(x2)-std::log(x1));
446  sum+= (a-b)*(x2-x1) + b*(x2*std::log(x2)-x1*std::log(x1));
447  }
448  else if(aScheme==LOGLIN||aScheme==CLOGLIN||aScheme==ULOGLIN)
449  {
450  G4double a = std::log(y1);
451  G4double b = (std::log(y2)-std::log(y1))/(x2-x1);
452  sum += (std::exp(a)/b)*(std::exp(b*x2)-std::exp(b*x1));
453  }
454  else if(aScheme==HISTO||aScheme==CHISTO||aScheme==UHISTO)
455  {
456  sum+= y1*(x2-x1);
457  }
458  else if(aScheme==LOGLOG||aScheme==CLOGLOG||aScheme==ULOGLOG)
459  {
460  G4double a = std::log(y1);
461  G4double b = (std::log(y2)-std::log(y1))/(std::log(x2)-std::log(x1));
462  sum += (std::exp(a)/(b+1))*(std::pow(x2,b+1)-std::pow(x1,b+1));
463  }
464  else
465  {
466  throw G4HadronicException(__FILE__, __LINE__, "Unknown interpolation scheme in G4ParticleHPVector::Integrate");
467  }
468 
469  }
470  }
471  totalIntegral = sum;
472  }
473 
474  inline G4double GetIntegral() // linear interpolation; use with care
475  {
476  if(totalIntegral<-0.5) Integrate();
477  return totalIntegral;
478  }
479 
480  inline void SetInterpolationManager(const G4InterpolationManager & aManager)
481  {
482  theManager = aManager;
483  }
484 
486  {
487  return theManager;
488  }
489 
491  {
492  theManager = aMan;
493  }
494 
495  inline void SetScheme(G4int aPoint, const G4InterpolationScheme & aScheme)
496  {
497  theManager.AppendScheme(aPoint, aScheme);
498  }
499 
501  {
502  return theManager.GetScheme(anIndex);
503  }
504 
506  {
507  G4double result;
508  G4double running = 0;
509  G4double weighted = 0;
510  for(G4int i=1; i<nEntries; i++)
511  {
512  running += theInt.GetBinIntegral(theManager.GetScheme(i-1),
513  theData[i-1].GetX(), theData[i].GetX(),
514  theData[i-1].GetY(), theData[i].GetY());
516  theData[i-1].GetX(), theData[i].GetX(),
517  theData[i-1].GetY(), theData[i].GetY());
518  }
519  result = weighted / running;
520  return result;
521  }
522 
523 /*
524  void Block(G4double aX)
525  {
526  theBlocked.push_back(aX);
527  }
528 
529  void Buffer(G4double aX)
530  {
531  theBuffered.push_back(aX);
532  }
533 */
534 
535  std::vector<G4double> GetBlocked() {return theBlocked;}
536  std::vector<G4double> GetBuffered() {return theBuffered;}
537 
538 // void SetBlocked(const std::vector<G4double> &aBlocked) {theBlocked = aBlocked;}
539 // void SetBuffered(const std::vector<G4double> &aBuffer) {theBuffered = aBuffer;}
540 
543 
544  private:
545 
546  void Check(G4int i);
547 
549 
550  private:
551 
553 
554  private:
555 
557 
559  G4InterpolationManager theManager; // knows how to interpolate the data.
564 
567  // debug only
569 
572 
573  std::vector<G4double> theBlocked;
574  std::vector<G4double> theBuffered;
577 
578 };
579 
580 #endif
void SetData(G4double e, G4double x)
G4double GetEnergy(G4int i) const
G4int GetVectorLength() const
std::vector< G4double > GetBlocked()
G4double Lin(G4double x, G4double x1, G4double x2, G4double y1, G4double y2)
void SetEnergy(G4int i, G4double e)
G4double GetXsec(G4double e, G4int min)
void Init(G4int aScheme, G4int aRange)
void SetData(G4int i, G4double x, G4double y)
void InitInterpolation(std::istream &aDataFile)
G4ParticleHPInterpolator theInt
void SetInterpolationManager(const G4InterpolationManager &aManager)
G4double a
Definition: TRTMaterials.hh:39
G4ParticleHPVector & operator=(const G4ParticleHPVector &right)
int G4int
Definition: G4Types.hh:78
G4double GetXsec(G4int i)
void SetData(G4int index, G4double x, G4double y)
G4double GetY(G4int i)
G4ParticleHPHash theHash
G4InterpolationManager theManager
void SetY(G4int i, G4double x)
void AppendScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
void Init(std::istream &aDataFile, G4int total, G4double ux=1., G4double uy=1.)
#define G4UniformRand()
Definition: Randomize.hh:95
G4ParticleHPDataPoint * theData
bool G4bool
Definition: G4Types.hh:79
G4InterpolationScheme GetScheme(G4int index) const
void Times(G4double factor)
G4double GetY(G4int i) const
void Merge(G4ParticleHPVector *active, G4ParticleHPVector *passive)
friend G4ParticleHPVector & operator+(G4ParticleHPVector &left, G4ParticleHPVector &right)
G4double GetX(G4int i) const
void SetPoint(G4int i, const G4ParticleHPDataPoint &it)
G4double GetY(G4double x)
const G4int n
G4double GetWeightedBinIntegral(const G4InterpolationScheme &aScheme, const G4double x1, const G4double x2, const G4double y1, const G4double y2)
G4double Interpolate(G4InterpolationScheme aScheme, G4double x, G4double x1, G4double x2, G4double y1, G4double y2) const
G4bool IsBlocked(G4double aX)
void Init(std::istream &aDataFile, G4double ux=1., G4double uy=1.)
std::vector< G4double > GetBuffered()
static const G4double factor
G4InterpolationScheme
G4double total(Particle const *const p1, Particle const *const p2)
void SetVerbose(G4int ff)
std::vector< G4double > theBlocked
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
const G4InterpolationManager & GetInterpolationManager() const
void SetXsec(G4int i, G4double x)
G4ParticleHPInterpolator theLin
G4double GetBinIntegral(const G4InterpolationScheme &aScheme, const G4double x1, const G4double x2, const G4double y1, const G4double y2)
std::vector< G4double > theBuffered
double G4double
Definition: G4Types.hh:76
G4InterpolationScheme GetScheme(G4int anIndex)
const G4ParticleHPDataPoint & GetPoint(G4int i) const
void SetX(G4int i, G4double e)
#define DBL_MAX
Definition: templates.hh:83
void SetScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
void SetLabel(G4double aLabel)
void ThinOut(G4double precision)
void SetInterpolationManager(G4InterpolationManager &aMan)