Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/event/src/G4SPSEneDistribution.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /event/src/G4SPSEneDistribution.cc (Version 11.3.0) and /event/src/G4SPSEneDistribution.cc (Version 10.5)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4SPSEneDistribution class implementation   <<  26 ///////////////////////////////////////////////////////////////////////////////
 27 //                                                 27 //
 28 // Author: Fan Lei, QinetiQ ltd - 05/02/2004   <<  28 // MODULE:        G4SPSEneDistribution.cc
 29 // Customer: ESA/ESTEC                         <<  29 //
 30 // Revisions: Andrew Green, Andrea Dotti       <<  30 // Version:      1.0
 31 // ------------------------------------------- <<  31 // Date:         5/02/04
                                                   >>  32 // Author:       Fan Lei 
                                                   >>  33 // Organisation: QinetiQ ltd.
                                                   >>  34 // Customer:     ESA/ESTEC
                                                   >>  35 //
                                                   >>  36 ///////////////////////////////////////////////////////////////////////////////
                                                   >>  37 //
                                                   >>  38 // CHANGE HISTORY
                                                   >>  39 // --------------
                                                   >>  40 //
                                                   >>  41 //
                                                   >>  42 // Version 1.0, 05/02/2004, Fan Lei, Created.
                                                   >>  43 //    Based on the G4GeneralParticleSource class in Geant4 v6.0
                                                   >>  44 //
                                                   >>  45 ///////////////////////////////////////////////////////////////////////////////
                                                   >>  46 //
                                                   >>  47 //  26/03/2014, Andrew Green.
                                                   >>  48 //      Modification to used STL vectors instead of C-style arrays. This should save some space,
                                                   >>  49 //      particularly when the blackbody function is not used. Also moved to dynamically allocated
                                                   >>  50 //      memory in the LinearInterpolation, ExpInterpolation and LogInterpolation functions. Again,
                                                   >>  51 //      this will save space if these functions are unused.
                                                   >>  52 //
                                                   >>  53 //
                                                   >>  54 // 24/11/2017  Fan Lei
                                                   >>  55 //    Added cutoff power-law distribution option. Implementation is similar to that of the BlackBody one.
                                                   >>  56 ///////////////////////////////////////////////////////////////////////////////
 32 #include "G4SPSEneDistribution.hh"                 57 #include "G4SPSEneDistribution.hh"
 33                                                    58 
 34 #include "G4Exp.hh"                                59 #include "G4Exp.hh"
 35 #include "G4SystemOfUnits.hh"                      60 #include "G4SystemOfUnits.hh"
 36 #include "G4UnitsTable.hh"                     << 
 37 #include "Randomize.hh"                            61 #include "Randomize.hh"
 38 #include "G4AutoLock.hh"                           62 #include "G4AutoLock.hh"
 39 #include "G4Threading.hh"                          63 #include "G4Threading.hh"
 40                                                    64 
 41 G4SPSEneDistribution::G4SPSEneDistribution()   <<  65 G4SPSEneDistribution::G4SPSEneDistribution(): Epnflag(false),eneRndm(0),Splinetemp(0)
 42 {                                                  66 {
 43   G4MUTEXINIT(mutex);                          <<  67     G4MUTEXINIT(mutex);
                                                   >>  68   //
                                                   >>  69   // Initialise all variables
                                                   >>  70   particle_energy = 1.0 * MeV;
                                                   >>  71   EnergyDisType = "Mono";
                                                   >>  72   weight=1.;
                                                   >>  73   MonoEnergy = 1 * MeV;
                                                   >>  74   Emin = 0.;
                                                   >>  75   Emax = 1.e30;
                                                   >>  76   alpha = 0.;
                                                   >>  77   biasalpha = 0.;
                                                   >>  78     prob_norm = 1.0;
                                                   >>  79   Ezero = 0.;
                                                   >>  80   SE = 0.;
                                                   >>  81   Temp = 0.;
                                                   >>  82   grad = 0.;
                                                   >>  83   cept = 0.;
                                                   >>  84   Biased = false; // not biased
                                                   >>  85   EnergySpec = true; // true - energy spectra, false - momentum spectra
                                                   >>  86   DiffSpec = true; // true - differential spec, false integral spec
                                                   >>  87   IntType = "NULL"; // Interpolation type
                                                   >>  88   IPDFEnergyExist = false;
                                                   >>  89   IPDFArbExist = false;
 44                                                    90 
 45   // Initialise all variables                  <<  91   ArbEmin = 0.;
                                                   >>  92   ArbEmax = 1.e30;
 46                                                    93 
 47   particle_energy = 1.0 * MeV;                 <<  94   verbosityLevel = 0;
 48   EnergyDisType = "Mono";                      <<  95     
 49   weight=1.;                                   <<  96     //AG: Set these pointers to NULL so we know if they were used...
 50   MonoEnergy = 1 * MeV;                        <<  97     Arb_grad = NULL;
 51   Emin = 0.;                                   <<  98     Arb_cept = NULL;
 52   Emax = 1.e30;                                <<  99     Arb_alpha = NULL;
 53   alpha = 0.;                                  << 100     Arb_Const = NULL;
 54   biasalpha = 0.;                              << 101     Arb_ezero = NULL;
 55   prob_norm = 1.0;                             << 102     Arb_grad_cept_flag = false;
 56   Ezero = 0.;                                  << 103     Arb_alpha_Const_flag = false;
 57   SE = 0.;                                     << 104     Arb_ezero_flag = false;
 58   Temp = 0.;                                   << 105     BBhistInit = false;
 59   grad = 0.;                                   << 106     BBhistCalcd = false;
 60   cept = 0.;                                   << 107     CPhistInit = false;
 61   IntType = "NULL"; // Interpolation type      << 108     CPhistCalcd = false;
 62                                                << 109     
 63   ArbEmin = 0.;                                << 110     BBHist = NULL;
 64   ArbEmax = 1.e30;                             << 111     Bbody_x = NULL;
 65                                                << 112     CPHist = NULL;
 66   verbosityLevel = 0;                          << 113     CP_x = NULL;
 67                                                << 114 
 68   threadLocal_t& data = threadLocalData.Get(); << 115     threadLocal_t& data = threadLocalData.Get();
 69   data.Emax = Emax;                            << 116     data.Emax = Emax;
 70   data.Emin = Emin;                            << 117     data.Emin = Emin;
 71   data.alpha =alpha;                           << 118     data.alpha =alpha;
 72   data.cept = cept;                            << 119     data.cept = cept;
 73   data.Ezero = Ezero;                          << 120     data.Ezero = Ezero;
 74   data.grad = grad;                            << 121     data.grad = grad;
 75   data.particle_energy = 0.;                   << 122     data.particle_energy = 0;
 76   data.particle_definition = nullptr;          << 123     data.particle_definition = NULL;
 77   data.weight = weight;                        << 124     data.weight = weight;
 78 }                                                 125 }
 79                                                   126 
 80 G4SPSEneDistribution::~G4SPSEneDistribution()     127 G4SPSEneDistribution::~G4SPSEneDistribution()
 81 {                                                 128 {
 82   G4MUTEXDESTROY(mutex);                       << 129     G4MUTEXDESTROY(mutex);
 83   if(Arb_grad_cept_flag)                       << 130     if(Arb_grad_cept_flag)
 84   {                                            << 131     {
 85     delete [] Arb_grad;                        << 132         delete[] Arb_grad;
 86     delete [] Arb_cept;                        << 133         delete[] Arb_cept;
 87   }                                            << 134     }
 88                                                << 135     
 89   if(Arb_alpha_Const_flag)                     << 136     if(Arb_alpha_Const_flag)
 90   {                                            << 137     {
 91     delete [] Arb_alpha;                       << 138         delete[] Arb_alpha;
 92     delete [] Arb_Const;                       << 139         delete[] Arb_Const;
 93   }                                            << 140     }
 94                                                << 141     
 95   if(Arb_ezero_flag)                           << 142     if(Arb_ezero_flag)
 96   {                                            << 143     {
 97     delete [] Arb_ezero;                       << 144         delete[] Arb_ezero;
 98   }                                            << 145     }
 99   delete Bbody_x;                              << 146     delete Bbody_x;
100   delete BBHist;                               << 147     delete BBHist;
101   delete CP_x;                                 << 148     delete CP_x;
102   delete CPHist;                               << 149     delete CPHist;
103   for (auto & it : SplineInt)                  << 150     for ( std::vector<G4DataInterpolation*>::iterator it = SplineInt.begin() ; it!=SplineInt.end() ; ++it)
104   {                                            << 151     {
105     delete it;                                 << 152         delete *it;
106     it = nullptr;                              << 153         *it = 0;
107   }                                            << 154     }
108   SplineInt.clear();                           << 155     SplineInt.clear();
109 }                                              << 156 }
110                                                << 157 
111 void G4SPSEneDistribution::SetEnergyDisType(co << 158 void G4SPSEneDistribution::SetEnergyDisType(G4String DisType) {
112 {                                              << 159     G4AutoLock l(&mutex);
113   G4AutoLock l(&mutex);                        << 160   EnergyDisType = DisType;
114   EnergyDisType = DisType;                     << 161   if (EnergyDisType == "User")
115   if (EnergyDisType == "User")                 << 162     {
116   {                                            << 163     UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
117     UDefEnergyH = IPDFEnergyH = ZeroPhysVector << 164     IPDFEnergyExist = false;
118     IPDFEnergyExist = false;                   << 165   }
119   }                                            << 166     else if (EnergyDisType == "Arb")
120   else if (EnergyDisType == "Arb")             << 167     {
121   {                                            << 168     ArbEnergyH = IPDFArbEnergyH = ZeroPhysVector;
122     ArbEnergyH = IPDFArbEnergyH = ZeroPhysVect << 169     IPDFArbExist = false;
123     IPDFArbExist = false;                      << 170   }
124   }                                            << 171     else if (EnergyDisType == "Epn")
125   else if (EnergyDisType == "Epn")             << 172     {
126   {                                            << 173     UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
127     UDefEnergyH = IPDFEnergyH = ZeroPhysVector << 174     IPDFEnergyExist = false;
128     IPDFEnergyExist = false;                   << 175     EpnEnergyH = ZeroPhysVector;
129     EpnEnergyH = ZeroPhysVector;               << 176   }
130   }                                            << 177 }
131 }                                              << 178 
132                                                << 179 G4String G4SPSEneDistribution::GetEnergyDisType()
133 const G4String& G4SPSEneDistribution::GetEnerg << 180 {
134 {                                              << 181     G4AutoLock l(&mutex);
135   G4AutoLock l(&mutex);                        << 182     return EnergyDisType;
136   return EnergyDisType;                        << 183 }
137 }                                              << 184 
138                                                << 185 void G4SPSEneDistribution::SetEmin(G4double emi) {
139 void G4SPSEneDistribution::SetEmin(G4double em << 186     G4AutoLock l(&mutex);
140 {                                              << 187   Emin = emi;
141   G4AutoLock l(&mutex);                        << 188     threadLocalData.Get().Emin = Emin;
142   Emin = emi;                                  << 
143   threadLocalData.Get().Emin = Emin;           << 
144 }                                                 189 }
145                                                   190 
146 G4double G4SPSEneDistribution::GetEmin() const << 191 G4double G4SPSEneDistribution::GetEmin()
147 {                                                 192 {
148   return threadLocalData.Get().Emin;           << 193     return threadLocalData.Get().Emin;
149 }                                                 194 }
150                                                   195 
151 G4double G4SPSEneDistribution::GetArbEmin()       196 G4double G4SPSEneDistribution::GetArbEmin()
152 {                                                 197 {
153   G4AutoLock l(&mutex);                        << 198     G4AutoLock l(&mutex);
154   return ArbEmin;                              << 199     return ArbEmin;
155 }                                                 200 }
156                                                   201 
157 G4double G4SPSEneDistribution::GetArbEmax()       202 G4double G4SPSEneDistribution::GetArbEmax()
158 {                                                 203 {
159   G4AutoLock l(&mutex);                        << 204     G4AutoLock l(&mutex);
160   return ArbEmax;                              << 205     return ArbEmax;
161 }                                                 206 }
162                                                   207 
163 void G4SPSEneDistribution::SetEmax(G4double em << 208 void G4SPSEneDistribution::SetEmax(G4double ema) {
164 {                                              << 209     G4AutoLock l(&mutex);
165   G4AutoLock l(&mutex);                        << 210   Emax = ema;
166   Emax = ema;                                  << 211     threadLocalData.Get().Emax = Emax;
167   threadLocalData.Get().Emax = Emax;           << 
168 }                                                 212 }
169                                                   213 
170 G4double G4SPSEneDistribution::GetEmax() const << 214 G4double G4SPSEneDistribution::GetEmax()
171 {                                                 215 {
172   return threadLocalData.Get().Emax;           << 216     return threadLocalData.Get().Emax;
173 }                                                 217 }
174                                                   218 
175 void G4SPSEneDistribution::SetMonoEnergy(G4dou << 219 
176 {                                              << 220 void G4SPSEneDistribution::SetMonoEnergy(G4double menergy) {
177   G4AutoLock l(&mutex);                        << 221     G4AutoLock l(&mutex);
178   MonoEnergy = menergy;                        << 222   MonoEnergy = menergy;
179 }                                                 223 }
180                                                   224 
181 void G4SPSEneDistribution::SetBeamSigmaInE(G4d << 225 void G4SPSEneDistribution::SetBeamSigmaInE(G4double e) {
182 {                                              << 226     G4AutoLock l(&mutex);
183   G4AutoLock l(&mutex);                        << 227   SE = e;
184   SE = e;                                      << 
185 }                                                 228 }
186 void G4SPSEneDistribution::SetAlpha(G4double a << 229 void G4SPSEneDistribution::SetAlpha(G4double alp) {
187 {                                              << 230     G4AutoLock l(&mutex);
188   G4AutoLock l(&mutex);                        << 231   alpha = alp;
189   alpha = alp;                                 << 232     threadLocalData.Get().alpha = alpha;
190   threadLocalData.Get().alpha = alpha;         << 
191 }                                                 233 }
192                                                   234 
193 void G4SPSEneDistribution::SetBiasAlpha(G4doub << 235 void G4SPSEneDistribution::SetBiasAlpha(G4double alp) {
194 {                                              << 236     G4AutoLock l(&mutex);
195   G4AutoLock l(&mutex);                        << 237   biasalpha = alp;
196   biasalpha = alp;                             << 238   Biased = true;
197   Biased = true;                               << 
198 }                                                 239 }
199                                                   240 
200 void G4SPSEneDistribution::SetTemp(G4double te << 241 void G4SPSEneDistribution::SetTemp(G4double tem) {
201 {                                              << 242   G4AutoLock l(&mutex);
202   G4AutoLock l(&mutex);                        << 243     Temp = tem;
203   Temp = tem;                                  << 
204 }                                                 244 }
205                                                   245 
206 void G4SPSEneDistribution::SetEzero(G4double e << 246 void G4SPSEneDistribution::SetEzero(G4double eze) {
207 {                                              << 247   G4AutoLock l(&mutex);
208   G4AutoLock l(&mutex);                        << 248     Ezero = eze;
209   Ezero = eze;                                 << 249     threadLocalData.Get().Ezero = Ezero;
210   threadLocalData.Get().Ezero = Ezero;         << 
211 }                                                 250 }
212                                                   251 
213 void G4SPSEneDistribution::SetGradient(G4doubl << 252 void G4SPSEneDistribution::SetGradient(G4double gr) {
214 {                                              << 253   G4AutoLock l(&mutex);
215   G4AutoLock l(&mutex);                        << 254     grad = gr;
216   grad = gr;                                   << 255     threadLocalData.Get().grad = grad;
217   threadLocalData.Get().grad = grad;           << 
218 }                                                 256 }
219                                                   257 
220 void G4SPSEneDistribution::SetInterCept(G4doub << 258 void G4SPSEneDistribution::SetInterCept(G4double c) {
221 {                                              << 259   G4AutoLock l(&mutex);
222   G4AutoLock l(&mutex);                        << 260     cept = c;
223   cept = c;                                    << 261     threadLocalData.Get().cept = cept;
224   threadLocalData.Get().cept = cept;           << 
225 }                                                 262 }
226                                                   263 
227 const G4String& G4SPSEneDistribution::GetIntTy << 264 G4String G4SPSEneDistribution::GetIntType()
228 {                                                 265 {
229   G4AutoLock l(&mutex);                        << 266   G4AutoLock l(&mutex);
230   return IntType;                              << 267     return IntType;
231 }                                                 268 }
232                                                   269 
233 void G4SPSEneDistribution::SetBiasRndm(G4SPSRa    270 void G4SPSEneDistribution::SetBiasRndm(G4SPSRandomGenerator* a)
234 {                                                 271 {
235   G4AutoLock l(&mutex);                        << 272     G4AutoLock l(&mutex);
236   eneRndm = a;                                 << 273     eneRndm = a;
237 }                                                 274 }
238                                                   275 
239 void G4SPSEneDistribution::SetVerbosity(G4int     276 void G4SPSEneDistribution::SetVerbosity(G4int a)
240 {                                                 277 {
241   G4AutoLock l(&mutex);                        << 278     G4AutoLock l(&mutex);
242   verbosityLevel = a;                          << 279     verbosityLevel = a;
243 }                                                 280 }
244                                                   281 
245 G4double G4SPSEneDistribution::GetWeight() con << 282 G4double G4SPSEneDistribution::GetWeight()
246 {                                                 283 {
247   return threadLocalData.Get().weight;         << 284     return threadLocalData.Get().weight;
248 }                                                 285 }
249                                                   286 
250 G4double G4SPSEneDistribution::GetMonoEnergy()    287 G4double G4SPSEneDistribution::GetMonoEnergy()
251 {                                                 288 {
252   G4AutoLock l(&mutex);                        << 289     G4AutoLock l(&mutex);
253   return MonoEnergy;                           << 290     return MonoEnergy;
254 }                                                 291 }
255                                                   292 
256 G4double G4SPSEneDistribution::GetSE()            293 G4double G4SPSEneDistribution::GetSE()
257 {                                                 294 {
258   G4AutoLock l(&mutex);                        << 295     G4AutoLock l(&mutex);
259   return SE;                                   << 296     return SE;
260 }                                                 297 }
261                                                   298 
262 G4double G4SPSEneDistribution::Getalpha() cons << 299 G4double G4SPSEneDistribution::Getalpha()
263 {                                                 300 {
264   return threadLocalData.Get().alpha;          << 301     return threadLocalData.Get().alpha;
265 }                                                 302 }
266                                                   303 
267 G4double G4SPSEneDistribution::GetEzero() cons << 304 G4double G4SPSEneDistribution::GetEzero()
268 {                                                 305 {
269   return threadLocalData.Get().Ezero;          << 306     return threadLocalData.Get().Ezero;
270 }                                                 307 }
271                                                   308 
272 G4double G4SPSEneDistribution::GetTemp()          309 G4double G4SPSEneDistribution::GetTemp()
273 {                                                 310 {
274   G4AutoLock l(&mutex);                        << 311     G4AutoLock l(&mutex);
275   return Temp;                                 << 312     return Temp;
276 }                                                 313 }
277                                                   314 
278 G4double G4SPSEneDistribution::Getgrad() const << 315 G4double G4SPSEneDistribution::Getgrad()
279 {                                                 316 {
280   return threadLocalData.Get().grad;           << 317     return threadLocalData.Get().grad;
281 }                                                 318 }
282                                                   319 
283 G4double G4SPSEneDistribution::Getcept() const << 320 G4double G4SPSEneDistribution::Getcept()
284 {                                                 321 {
285   return threadLocalData.Get().cept;           << 322     return threadLocalData.Get().cept;
286 }                                                 323 }
287                                                   324 
288 G4PhysicsFreeVector G4SPSEneDistribution::GetU << 325 G4PhysicsOrderedFreeVector G4SPSEneDistribution::GetUserDefinedEnergyHisto()
289 {                                                 326 {
290   G4AutoLock l(&mutex);                        << 327     G4AutoLock l(&mutex);
291   return UDefEnergyH;                          << 328     return UDefEnergyH;
292 }                                                 329 }
293                                                   330 
294 G4PhysicsFreeVector G4SPSEneDistribution::GetA << 331 G4PhysicsOrderedFreeVector G4SPSEneDistribution::GetArbEnergyHisto()
295 {                                                 332 {
296   G4AutoLock l(&mutex);                        << 333     G4AutoLock l(&mutex);
297   return ArbEnergyH;                           << 334     return ArbEnergyH;
298 }                                                 335 }
299                                                   336 
300 void G4SPSEneDistribution::UserEnergyHisto(con << 337 void G4SPSEneDistribution::UserEnergyHisto(G4ThreeVector input) {
301 {                                              << 338   G4AutoLock l(&mutex);
302   G4AutoLock l(&mutex);                        << 339     G4double ehi, val;
303   G4double ehi = input.x(),                    << 340   ehi = input.x();
304            val = input.y();                    << 341   val = input.y();
305   if (verbosityLevel > 1)                      << 342   if (verbosityLevel > 1) {
306   {                                            << 343     G4cout << "In UserEnergyHisto" << G4endl;
307     G4cout << "In UserEnergyHisto" << G4endl;  << 344     G4cout << " " << ehi << " " << val << G4endl;
308     G4cout << " " << ehi << " " << val << G4en << 345   }
309   }                                            << 346   UDefEnergyH.InsertValues(ehi, val);
310   UDefEnergyH.InsertValues(ehi, val);          << 347   Emax = ehi;
311   Emax = ehi;                                  << 348     threadLocalData.Get().Emax = Emax;
312   threadLocalData.Get().Emax = Emax;           << 
313 }                                                 349 }
314                                                   350 
315 void G4SPSEneDistribution::ArbEnergyHisto(cons << 351 void G4SPSEneDistribution::ArbEnergyHisto(G4ThreeVector input)
316 {                                                 352 {
317   G4AutoLock l(&mutex);                        << 353     G4AutoLock l(&mutex);
318   G4double ehi = input.x(),                    << 354   G4double ehi, val;
319            val = input.y();                    << 355   ehi = input.x();
320   if (verbosityLevel > 1)                      << 356   val = input.y();
321   {                                            << 357   if (verbosityLevel > 1)
322     G4cout << "In ArbEnergyHisto" << G4endl;   << 358     {
323     G4cout << " " << ehi << " " << val << G4en << 359     G4cout << "In ArbEnergyHisto" << G4endl;
324   }                                            << 360     G4cout << " " << ehi << " " << val << G4endl;
325   ArbEnergyH.InsertValues(ehi, val);           << 361   }
                                                   >> 362   ArbEnergyH.InsertValues(ehi, val);
326 }                                                 363 }
327                                                   364 
328 void G4SPSEneDistribution::ArbEnergyHistoFile( << 365 void G4SPSEneDistribution::ArbEnergyHistoFile(G4String filename)
329 {                                                 366 {
330   G4AutoLock l(&mutex);                        << 367     G4AutoLock l(&mutex);
331   std::ifstream infile(filename, std::ios::in) << 368   std::ifstream infile(filename, std::ios::in);
332   if (!infile)                                 << 369   if (!infile)
333   {                                            << 370     {
334     G4Exception("G4SPSEneDistribution::ArbEner << 371     G4Exception("G4SPSEneDistribution::ArbEnergyHistoFile","Event0301",FatalException,"Unable to open the histo ASCII file");
335                 FatalException, "Unable to ope << 372     }
336   }                                            << 373   G4double ehi, val;
337   G4double ehi, val;                           << 374   while (infile >> ehi >> val)
338   while (infile >> ehi >> val)                 << 375     {
339   {                                            << 376     ArbEnergyH.InsertValues(ehi, val);
340     ArbEnergyH.InsertValues(ehi, val);         << 377   }
341   }                                            << 
342 }                                                 378 }
343                                                   379 
344 void G4SPSEneDistribution::EpnEnergyHisto(cons << 380 void G4SPSEneDistribution::EpnEnergyHisto(G4ThreeVector input)
345 {                                                 381 {
346   G4AutoLock l(&mutex);                        << 382     G4AutoLock l(&mutex);
347   G4double ehi = input.x(),                    << 383   G4double ehi, val;
348            val = input.y();                    << 384   ehi = input.x();
349   if (verbosityLevel > 1)                      << 385   val = input.y();
350   {                                            << 386   if (verbosityLevel > 1)
351     G4cout << "In EpnEnergyHisto" << G4endl;   << 387     {
352     G4cout << " " << ehi << " " << val << G4en << 388     G4cout << "In EpnEnergyHisto" << G4endl;
353   }                                            << 389     G4cout << " " << ehi << " " << val << G4endl;
354   EpnEnergyH.InsertValues(ehi, val);           << 390   }
355   Emax = ehi;                                  << 391   EpnEnergyH.InsertValues(ehi, val);
356   threadLocalData.Get().Emax = Emax;           << 392   Emax = ehi;
357   Epnflag = true;                              << 393     threadLocalData.Get().Emax = Emax;
                                                   >> 394   Epnflag = true;
358 }                                                 395 }
359                                                   396 
360 void G4SPSEneDistribution::Calculate()            397 void G4SPSEneDistribution::Calculate()
361 {                                                 398 {
362   G4AutoLock l(&mutex);                        << 399     G4AutoLock l(&mutex);
363   if (EnergyDisType == "Cdg")                  << 400   if (EnergyDisType == "Cdg")
364   {                                            << 
365     CalculateCdgSpectrum();                    << 
366   }                                            << 
367   else if (EnergyDisType == "Bbody")           << 
368   {                                            << 
369     if(!BBhistInit)                            << 
370     {                                          << 
371       BBInitHists();                           << 
372     }                                          << 
373     CalculateBbodySpectrum();                  << 
374   }                                            << 
375   else if (EnergyDisType == "CPow")            << 
376   {                                            << 
377     if(!CPhistInit)                            << 
378     {                                          << 
379       CPInitHists();                           << 
380     }                                          << 
381     CalculateCPowSpectrum();                   << 
382   }                                            << 
383 }                                              << 
384                                                << 
385 void G4SPSEneDistribution::BBInitHists()  // M << 
386 {                                              << 
387   BBHist = new std::vector<G4double>(10001, 0. << 
388   Bbody_x = new std::vector<G4double>(10001, 0 << 
389   BBhistInit = true;                           << 
390 }                                              << 
391                                                << 
392 void G4SPSEneDistribution::CPInitHists()  // M << 
393 {                                              << 
394   CPHist = new std::vector<G4double>(10001, 0. << 
395   CP_x = new std::vector<G4double>(10001, 0.0) << 
396   CPhistInit = true;                           << 
397 }                                              << 
398                                                << 
399 void G4SPSEneDistribution::CalculateCdgSpectru << 
400 {                                              << 
401   // This uses the spectrum from the INTEGRAL  << 
402   // to generate a Cosmic Diffuse X/gamma ray  << 
403                                                << 
404   G4double pfact[2] = { 8.5, 112 };            << 
405   G4double spind[2] = { 1.4, 2.3 };            << 
406   G4double ene_line[3] = { 1. * keV, 18. * keV << 
407   G4int n_par;                                 << 
408                                                << 
409   ene_line[0] = threadLocalData.Get().Emin;    << 
410   if (threadLocalData.Get().Emin < 18 * keV)   << 
411   {                                            << 
412     n_par = 2;                                 << 
413     ene_line[2] = threadLocalData.Get().Emax;  << 
414     if (threadLocalData.Get().Emax < 18 * keV) << 
415     {                                          << 
416       n_par = 1;                               << 
417       ene_line[1] = threadLocalData.Get().Emax << 
418     }                                          << 
419   }                                            << 
420   else                                         << 
421   {                                            << 
422     n_par = 1;                                 << 
423     pfact[0] = 112.;                           << 
424     spind[0] = 2.3;                            << 
425     ene_line[1] = threadLocalData.Get().Emax;  << 
426   }                                            << 
427                                                << 
428   // Create a cumulative histogram             << 
429   //                                           << 
430   CDGhist[0] = 0.;                             << 
431   G4double omalpha;                            << 
432   G4int i = 0;                                 << 
433   while (i < n_par)                            << 
434   {                                            << 
435     omalpha = 1. - spind[i];                   << 
436     CDGhist[i + 1] = CDGhist[i] + (pfact[i] /  << 
437                                 * (std::pow(en << 
438                                 - std::pow(ene << 
439     ++i;                                       << 
440   }                                            << 
441                                                << 
442   // Normalise histo and divide by 1000 to mak << 
443   //                                           << 
444   i = 0;                                       << 
445   while (i < n_par)                            << 
446   {                                            << 
447     CDGhist[i + 1] = CDGhist[i + 1] / CDGhist[ << 
448     ++i;                                       << 
449   }                                            << 
450 }                                              << 
451                                                << 
452 void G4SPSEneDistribution::CalculateBbodySpect << 
453 {                                              << 
454   // Create bbody spectrum                     << 
455   // Proved very hard to integrate indefinitel << 
456   // User inputs emin, emax and T. These are u << 
457   // bin histogram.                            << 
458   // Use photon density spectrum = 2 nu**2/c** << 
459   // = 2 E**2/h**2c**2 times the exponential   << 
460                                                << 
461   G4double erange = threadLocalData.Get().Emax << 
462   G4double steps = erange / 10000.;            << 
463                                                << 
464   const G4double k = 8.6181e-11; //Boltzmann c << 
465   const G4double h = 4.1362e-21; // Plancks co << 
466   const G4double c = 3e8; // Speed of light    << 
467   const G4double h2 = h * h;                   << 
468   const G4double c2 = c * c;                   << 
469   G4int count = 0;                             << 
470   G4double sum = 0.;                           << 
471   BBHist->at(0) = 0.;                          << 
472                                                << 
473   while (count < 10000)                        << 
474   {                                            << 
475     Bbody_x->at(count) = threadLocalData.Get() << 
476     G4double Bbody_y = (2. * std::pow(Bbody_x- << 
477                      / (h2*c2*(std::exp(Bbody_ << 
478     sum = sum + Bbody_y;                       << 
479     BBHist->at(count + 1) = BBHist->at(count)  << 
480     ++count;                                   << 
481   }                                            << 
482                                                << 
483   Bbody_x->at(10000) = threadLocalData.Get().E << 
484                                                << 
485   // Normalise cumulative histo                << 
486   //                                           << 
487   count = 0;                                   << 
488   while (count < 10001)                        << 
489   {                                            << 
490     BBHist->at(count) = BBHist->at(count) / su << 
491     ++count;                                   << 
492   }                                            << 
493 }                                              << 
494                                                << 
495 void G4SPSEneDistribution::CalculateCPowSpectr << 
496 {                                              << 
497   // Create cutoff power-law spectrum, x^a exp << 
498   // The integral of this function is an incom << 
499   // is only available in the Boost library.   << 
500   //                                           << 
501   // User inputs are emin, emax and alpha and  << 
502   // create a 10,000 bin histogram.            << 
503                                                << 
504   G4double erange = threadLocalData.Get().Emax << 
505   G4double steps = erange / 10000.;            << 
506   alpha = threadLocalData.Get().alpha ;        << 
507   Ezero = threadLocalData.Get().Ezero ;        << 
508                                                << 
509   G4int count = 0;                             << 
510   G4double sum = 0.;                           << 
511   CPHist->at(0) = 0.;                          << 
512                                                << 
513   while (count < 10000)                        << 
514   {                                            << 
515     CP_x->at(count) = threadLocalData.Get().Em << 
516     G4double CP_y = std::pow(CP_x->at(count),  << 
517                   * std::exp(-CP_x->at(count)  << 
518     sum = sum + CP_y;                          << 
519     CPHist->at(count + 1) = CPHist->at(count)  << 
520     ++count;                                   << 
521   }                                            << 
522                                                << 
523   CP_x->at(10000) = threadLocalData.Get().Emax << 
524                                                << 
525   // Normalise cumulative histo                << 
526   //                                           << 
527   count = 0;                                   << 
528   while (count < 10001)                        << 
529   {                                            << 
530     CPHist->at(count) = CPHist->at(count) / su << 
531     ++count;                                   << 
532   }                                            << 
533 }                                              << 
534                                                << 
535 void G4SPSEneDistribution::InputEnergySpectra( << 
536 {                                              << 
537   G4AutoLock l(&mutex);                        << 
538                                                << 
539   // Allows user to specify spectrum is moment << 
540   //                                           << 
541   EnergySpec = value; // false if momentum     << 
542   if (verbosityLevel > 1)                      << 
543   {                                            << 
544     G4cout << "EnergySpec has value " << Energ << 
545   }                                            << 
546 }                                              << 
547                                                << 
548 void G4SPSEneDistribution::InputDifferentialSp << 
549 {                                              << 
550   G4AutoLock l(&mutex);                        << 
551                                                << 
552   // Allows user to specify integral or differ << 
553   //                                           << 
554   DiffSpec = value; // true = differential, fa << 
555   if (verbosityLevel > 1)                      << 
556   {                                            << 
557     G4cout << "Diffspec has value " << DiffSpe << 
558   }                                            << 
559 }                                              << 
560                                                << 
561 void G4SPSEneDistribution::ArbInterpolate(cons << 
562 {                                              << 
563   G4AutoLock l(&mutex);                        << 
564                                                << 
565   IntType = IType;                             << 
566   ArbEmax = ArbEnergyH.GetMaxEnergy();         << 
567   ArbEmin = ArbEnergyH.Energy(0);              << 
568                                                << 
569   // Now interpolate points                    << 
570                                                << 
571   if (IntType == "Lin") LinearInterpolation(); << 
572   if (IntType == "Log") LogInterpolation();    << 
573   if (IntType == "Exp") ExpInterpolation();    << 
574   if (IntType == "Spline") SplineInterpolation << 
575 }                                              << 
576                                                << 
577 void G4SPSEneDistribution::LinearInterpolation << 
578 {                                              << 
579   // Method to do linear interpolation on the  << 
580   // Calculate equation of each line segment,  << 
581   // Calculate Area under each segment         << 
582   // Create a cumulative array which is then n << 
583                                                << 
584   G4double Area_seg[1024]; // Stores area unde << 
585   G4double sum = 0., Arb_x[1024]={0.}, Arb_y[1 << 
586   std::size_t i, count;                        << 
587   std::size_t maxi = ArbEnergyH.GetVectorLengt << 
588   for (i = 0; i < maxi; ++i)                   << 
589   {                                            << 
590     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(i); << 
591     Arb_y[i] = ArbEnergyH(i);                  << 
592   }                                            << 
593                                                << 
594   // Points are now in x,y arrays. If the spec << 
595   // made differential and if momentum it has  << 
596                                                << 
597   if (!DiffSpec)                               << 
598   {                                            << 
599     // Converts integral point-wise spectra to << 
600     //                                         << 
601     for (count = 0; count < maxi-1; ++count)   << 
602     {                                          << 
603       Arb_y[count] = (Arb_y[count] - Arb_y[cou << 
604                    / (Arb_x[count + 1] - Arb_x << 
605     }                                          << 
606     --maxi;                                    << 
607   }                                            << 
608                                                << 
609   if (!EnergySpec)                             << 
610   {                                            << 
611     // change currently stored values (emin et << 
612     // to energies                             << 
613     //                                         << 
614     G4ParticleDefinition* pdef = threadLocalDa << 
615     if (pdef == nullptr)                       << 
616     {                                          << 
617       G4Exception("G4SPSEneDistribution::Linea << 
618                   "Event0302", FatalException, << 
619                   "Error: particle not defined << 
620     }                                          << 
621     else                                       << 
622     {                                             401     {
623       // Apply Energy**2 = p**2c**2 + m0**2c** << 402     CalculateCdgSpectrum();
624       // p should be entered as E/c i.e. witho << 
625       // being done - energy equivalent        << 
626                                                << 
627       G4double mass = pdef->GetPDGMass();      << 
628                                                << 
629       // Convert point to energy unit and its  << 
630       //                                       << 
631       G4double total_energy;                   << 
632       for (count = 0; count < maxi; ++count)   << 
633       {                                        << 
634         total_energy = std::sqrt((Arb_x[count] << 
635                      + (mass * mass)); // tota << 
636         Arb_y[count] = Arb_y[count] * Arb_x[co << 
637         Arb_x[count] = total_energy - mass; // << 
638       }                                        << 
639     }                                          << 
640   }                                            << 
641                                                << 
642   i = 1;                                       << 
643                                                << 
644   Arb_grad = new G4double [1024];              << 
645   Arb_cept = new G4double [1024];              << 
646   Arb_grad_cept_flag = true;                   << 
647                                                << 
648   Arb_grad[0] = 0.;                            << 
649   Arb_cept[0] = 0.;                            << 
650   Area_seg[0] = 0.;                            << 
651   Arb_Cum_Area[0] = 0.;                        << 
652   while (i < maxi)                             << 
653   {                                            << 
654     // calculate gradient and intercept for ea << 
655     //                                         << 
656     Arb_grad[i] = (Arb_y[i] - Arb_y[i - 1]) /  << 
657     if (verbosityLevel == 2)                   << 
658     {                                          << 
659       G4cout << Arb_grad[i] << G4endl;         << 
660     }                                          << 
661     if (Arb_grad[i] > 0.)                      << 
662     {                                          << 
663       if (verbosityLevel == 2)                 << 
664       {                                        << 
665          G4cout << "Arb_grad is positive" << G << 
666       }                                        << 
667       Arb_cept[i] = Arb_y[i] - (Arb_grad[i] *  << 
668     }                                          << 
669     else if (Arb_grad[i] < 0.)                 << 
670     {                                          << 
671       if (verbosityLevel == 2)                 << 
672       {                                        << 
673         G4cout << "Arb_grad is negative" << G4 << 
674       }                                        << 
675       Arb_cept[i] = Arb_y[i] + (-Arb_grad[i] * << 
676     }                                             403     }
677     else                                       << 404   else if (EnergyDisType == "Bbody")
678     {                                             405     {
679       if (verbosityLevel == 2)                 << 406         if(!BBhistInit)
680       {                                        << 407         {
681         G4cout << "Arb_grad is 0." << G4endl;  << 408             BBInitHists();
682       }                                        << 409         }
683       Arb_cept[i] = Arb_y[i];                  << 410     CalculateBbodySpectrum();
684     }                                          << 
685                                                << 
686     Area_seg[i] = ((Arb_grad[i] / 2)           << 
687                 * (Arb_x[i] * Arb_x[i] - Arb_x << 
688                 + Arb_cept[i] * (Arb_x[i] - Ar << 
689     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Ar << 
690     sum = sum + Area_seg[i];                   << 
691     if (verbosityLevel == 2)                   << 
692     {                                          << 
693       G4cout << Arb_x[i] << Arb_y[i] << Area_s << 
694              << Arb_grad[i] << G4endl;         << 
695     }                                          << 
696     ++i;                                       << 
697   }                                            << 
698                                                << 
699   i = 0;                                       << 
700   while (i < maxi)                             << 
701   {                                            << 
702     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum; / << 
703     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_ << 
704     ++i;                                       << 
705   }                                            << 
706                                                << 
707   // now scale the ArbEnergyH, needed by Proba << 
708   //                                           << 
709   ArbEnergyH.ScaleVector(1., 1./sum);          << 
710                                                << 
711   if (verbosityLevel >= 1)                     << 
712   {                                            << 
713     G4cout << "Leaving LinearInterpolation" << << 
714     ArbEnergyH.DumpValues();                   << 
715     IPDFArbEnergyH.DumpValues();               << 
716   }                                            << 
717 }                                              << 
718                                                << 
719 void G4SPSEneDistribution::LogInterpolation()  << 
720 {                                              << 
721   // Interpolation based on Logarithmic equati << 
722   // Generate equations of line segments       << 
723   // y = Ax**alpha => log y = alpha*logx + log << 
724   // Find area under line segments             << 
725   // Create normalised, cumulative array Arb_C << 
726                                                << 
727   G4double Area_seg[1024]; // Stores area unde << 
728   G4double sum = 0., Arb_x[1024]={0.}, Arb_y[1 << 
729   std::size_t i, count;                        << 
730   std::size_t maxi = ArbEnergyH.GetVectorLengt << 
731   for (i = 0; i < maxi; ++i)                   << 
732   {                                            << 
733     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(i); << 
734     Arb_y[i] = ArbEnergyH(i);                  << 
735   }                                            << 
736                                                << 
737   // Points are now in x,y arrays. If the spec << 
738   // made differential and if momentum it has  << 
739                                                << 
740   if (!DiffSpec)                               << 
741   {                                            << 
742     // Converts integral point-wise spectra to << 
743     //                                         << 
744     for (count = 0; count < maxi-1; ++count)   << 
745     {                                          << 
746       Arb_y[count] = (Arb_y[count] - Arb_y[cou << 
747                    / (Arb_x[count + 1] - Arb_x << 
748     }                                          << 
749     --maxi;                                    << 
750   }                                            << 
751                                                << 
752   if (!EnergySpec)                             << 
753   {                                            << 
754     // Change currently stored values (emin et << 
755     // to energies                             << 
756                                                << 
757     G4ParticleDefinition* pdef = threadLocalDa << 
758     if (pdef == nullptr)                       << 
759     {                                          << 
760       G4Exception("G4SPSEneDistribution::LogIn << 
761                   "Event0302", FatalException, << 
762                   "Error: particle not defined << 
763     }                                             411     }
764     else                                       << 412   else if (EnergyDisType == "CPow")
765     {                                             413     {
766       // Apply Energy**2 = p**2c**2 + m0**2c** << 414         if(!CPhistInit)
767       // p should be entered as E/c i.e. witho << 415         {
768       // being done - energy equivalent        << 416             CPInitHists();
769                                                << 417         }
770       G4double mass = pdef->GetPDGMass();      << 418     CalculateCPowSpectrum();
771                                                << 
772       // Convert point to energy unit and its  << 
773       //                                       << 
774       G4double total_energy;                   << 
775       for (count = 0; count < maxi; ++count)   << 
776       {                                        << 
777         total_energy = std::sqrt((Arb_x[count] << 
778         Arb_y[count] = Arb_y[count] * Arb_x[co << 
779         Arb_x[count] = total_energy - mass; // << 
780       }                                        << 
781     }                                          << 
782   }                                            << 
783                                                << 
784   i = 1;                                       << 
785                                                << 
786   if ( Arb_ezero != nullptr ) { delete [] Arb_ << 
787   if ( Arb_Const != nullptr ) { delete [] Arb_ << 
788   Arb_alpha = new G4double [1024];             << 
789   Arb_Const = new G4double [1024];             << 
790   Arb_alpha_Const_flag = true;                 << 
791                                                << 
792   Arb_alpha[0] = 0.;                           << 
793   Arb_Const[0] = 0.;                           << 
794   Area_seg[0] = 0.;                            << 
795   Arb_Cum_Area[0] = 0.;                        << 
796   if (Arb_x[0] <= 0. || Arb_y[0] <= 0.)        << 
797   {                                            << 
798     G4cout << "You should not use log interpol << 
799            << G4endl;                          << 
800     G4cout << "These will be changed to 1e-20, << 
801            << G4endl;                          << 
802     if (Arb_x[0] <= 0.)                        << 
803     {                                          << 
804       Arb_x[0] = 1e-20;                        << 
805     }                                          << 
806     if (Arb_y[0] <= 0.)                        << 
807     {                                          << 
808       Arb_y[0] = 1e-20;                        << 
809     }                                          << 
810   }                                            << 
811                                                << 
812   G4double alp;                                << 
813   while (i < maxi)                             << 
814   {                                            << 
815     // In case points are negative or zero     << 
816     //                                         << 
817     if (Arb_x[i] <= 0. || Arb_y[i] <= 0.)      << 
818     {                                          << 
819       G4cout << "You should not use log interp << 
820              << G4endl;                        << 
821       G4cout << "These will be changed to 1e-2 << 
822              << G4endl;                        << 
823       if (Arb_x[i] <= 0.)                      << 
824       {                                        << 
825         Arb_x[i] = 1e-20;                      << 
826       }                                        << 
827       if (Arb_y[i] <= 0.)                      << 
828       {                                        << 
829         Arb_y[i] = 1e-20;                      << 
830       }                                        << 
831     }                                          << 
832                                                << 
833     Arb_alpha[i] = (std::log10(Arb_y[i]) - std << 
834                  / (std::log10(Arb_x[i]) - std << 
835     Arb_Const[i] = Arb_y[i] / (std::pow(Arb_x[ << 
836     alp = Arb_alpha[i] + 1;                    << 
837     if (alp == 0.)                             << 
838     {                                          << 
839       Area_seg[i] = Arb_Const[i]               << 
840                   * (std::log(Arb_x[i]) - std: << 
841     }                                             419     }
                                                   >> 420 }
                                                   >> 421 
                                                   >> 422 //MT: Lock in caller
                                                   >> 423 void G4SPSEneDistribution::BBInitHists()
                                                   >> 424 {
                                                   >> 425     BBHist = new std::vector<G4double>(10001, 0.0);
                                                   >> 426     Bbody_x = new std::vector<G4double>(10001, 0.0);
                                                   >> 427     BBhistInit = true;
                                                   >> 428 }
                                                   >> 429 
                                                   >> 430 //MT: Lock in caller
                                                   >> 431 void G4SPSEneDistribution::CPInitHists()
                                                   >> 432 {
                                                   >> 433     CPHist = new std::vector<G4double>(10001, 0.0);
                                                   >> 434     CP_x = new std::vector<G4double>(10001, 0.0);
                                                   >> 435     CPhistInit = true;
                                                   >> 436 }
                                                   >> 437 
                                                   >> 438 
                                                   >> 439 //MT: Lock in caller
                                                   >> 440 void G4SPSEneDistribution::CalculateCdgSpectrum()
                                                   >> 441 {
                                                   >> 442   // This uses the spectrum from The INTEGRAL Mass Model (TIMM)
                                                   >> 443   // to generate a Cosmic Diffuse X/gamma ray spectrum.
                                                   >> 444   G4double pfact[2] = { 8.5, 112 };
                                                   >> 445   G4double spind[2] = { 1.4, 2.3 };
                                                   >> 446   G4double ene_line[3] = { 1. * keV, 18. * keV, 1E6 * keV };
                                                   >> 447   G4int n_par;
                                                   >> 448 
                                                   >> 449   ene_line[0] = threadLocalData.Get().Emin;
                                                   >> 450   if (threadLocalData.Get().Emin < 18 * keV)
                                                   >> 451     {
                                                   >> 452     n_par = 2;
                                                   >> 453     ene_line[2] = threadLocalData.Get().Emax;
                                                   >> 454     if (threadLocalData.Get().Emax < 18 * keV)
                                                   >> 455         {
                                                   >> 456       n_par = 1;
                                                   >> 457       ene_line[1] = threadLocalData.Get().Emax;
                                                   >> 458     }
                                                   >> 459   }
842     else                                          460     else
843     {                                             461     {
844       Area_seg[i] = (Arb_Const[i] / alp)       << 462     n_par = 1;
845                   * (std::pow(Arb_x[i], alp) - << 463     pfact[0] = 112.;
                                                   >> 464     spind[0] = 2.3;
                                                   >> 465     ene_line[1] = threadLocalData.Get().Emax;
                                                   >> 466   }
                                                   >> 467 
                                                   >> 468   // Create a cumulative histogram.
                                                   >> 469   CDGhist[0] = 0.;
                                                   >> 470   G4double omalpha;
                                                   >> 471   G4int i = 0;
                                                   >> 472 
                                                   >> 473   while (i < n_par)
                                                   >> 474     {
                                                   >> 475     omalpha = 1. - spind[i];
                                                   >> 476     CDGhist[i + 1] = CDGhist[i] + (pfact[i] / omalpha) * (std::pow(ene_line[i + 1] / keV, omalpha) - std::pow(ene_line[i] / keV,omalpha));
                                                   >> 477     i++;
                                                   >> 478   }
                                                   >> 479 
                                                   >> 480   // Normalise histo and divide by 1000 to make MeV.
                                                   >> 481   i = 0;
                                                   >> 482   while (i < n_par)
                                                   >> 483     {
                                                   >> 484     CDGhist[i + 1] = CDGhist[i + 1] / CDGhist[n_par];
                                                   >> 485     //      G4cout << CDGhist[i] << CDGhist[n_par] << G4endl;
                                                   >> 486     i++;
                                                   >> 487   }
                                                   >> 488 }
                                                   >> 489 
                                                   >> 490 //MT: Lock in caller
                                                   >> 491 void G4SPSEneDistribution::CalculateBbodySpectrum()
                                                   >> 492 {
                                                   >> 493   // create bbody spectrum
                                                   >> 494   // Proved very hard to integrate indefinitely, so different
                                                   >> 495   // method. User inputs emin, emax and T. These are used to
                                                   >> 496   // create a 10,000 bin histogram.
                                                   >> 497   // Use photon density spectrum = 2 nu**2/c**2 * (std::exp(h nu/kT)-1)
                                                   >> 498   // = 2 E**2/h**2c**2 times the exponential
                                                   >> 499     
                                                   >> 500   G4double erange = threadLocalData.Get().Emax - threadLocalData.Get().Emin;
                                                   >> 501   G4double steps = erange / 10000.;
                                                   >> 502     
                                                   >> 503   const G4double k = 8.6181e-11; //Boltzmann const in MeV/K
                                                   >> 504   const G4double h = 4.1362e-21; // Plancks const in MeV s
                                                   >> 505   const G4double c = 3e8; // Speed of light
                                                   >> 506   const G4double h2 = h * h;
                                                   >> 507   const G4double c2 = c * c;
                                                   >> 508   G4int count = 0;
                                                   >> 509   G4double sum = 0.;
                                                   >> 510   BBHist->at(0) = 0.;
                                                   >> 511     
                                                   >> 512   while (count < 10000) {
                                                   >> 513     Bbody_x->at(count) = threadLocalData.Get().Emin + G4double(count * steps);
                                                   >> 514         G4double Bbody_y = (2. * std::pow(Bbody_x->at(count), 2.)) / (h2 * c2 * (std::exp(Bbody_x->at(count) / (k * Temp)) - 1.));
                                                   >> 515     sum = sum + Bbody_y;
                                                   >> 516     BBHist->at(count + 1) = BBHist->at(count) + Bbody_y;
                                                   >> 517         count++;
                                                   >> 518   }
                                                   >> 519 
                                                   >> 520   Bbody_x->at(10000) = threadLocalData.Get().Emax;
                                                   >> 521   // Normalise cumulative histo.
                                                   >> 522   count = 0;
                                                   >> 523   while (count < 10001) {
                                                   >> 524     BBHist->at(count) = BBHist->at(count) / sum;
                                                   >> 525     count++;
                                                   >> 526   }
                                                   >> 527 }
                                                   >> 528 
                                                   >> 529 //MT: Lock in caller
                                                   >> 530 void G4SPSEneDistribution::CalculateCPowSpectrum()
                                                   >> 531 {
                                                   >> 532   // create cutoff power-law spectrum
                                                   >> 533   // x^a exp(-x/b)
                                                   >> 534   // the integral of this function is an incomplete gamma function, which is only available in the Boost library.
                                                   >> 535     // 
                                                   >> 536   // User inputs are emin, emax and alpha and Ezero. These are used to
                                                   >> 537   // create a 10,000 bin histogram.
                                                   >> 538     
                                                   >> 539   G4double erange = threadLocalData.Get().Emax - threadLocalData.Get().Emin;
                                                   >> 540   G4double steps = erange / 10000.;
                                                   >> 541   alpha = threadLocalData.Get().alpha ;
                                                   >> 542   Ezero = threadLocalData.Get().Ezero ;
                                                   >> 543     
                                                   >> 544   G4int count = 0;
                                                   >> 545   G4double sum = 0.;
                                                   >> 546   CPHist->at(0) = 0.;
                                                   >> 547     
                                                   >> 548   while (count < 10000) {
                                                   >> 549     CP_x->at(count) = threadLocalData.Get().Emin + G4double(count * steps);
                                                   >> 550         G4double CP_y = std::pow(CP_x->at(count), alpha) * std::exp(-CP_x->at(count) / Ezero);
                                                   >> 551     sum = sum + CP_y;
                                                   >> 552     CPHist->at(count + 1) = CPHist->at(count) + CP_y;
                                                   >> 553         count++;
                                                   >> 554   }
                                                   >> 555 
                                                   >> 556   CP_x->at(10000) = threadLocalData.Get().Emax;
                                                   >> 557   // Normalise cumulative histo.
                                                   >> 558   count = 0;
                                                   >> 559   while (count < 10001) {
                                                   >> 560     CPHist->at(count) = CPHist->at(count) / sum;
                                                   >> 561     count++;
                                                   >> 562   }
                                                   >> 563 }
                                                   >> 564 
                                                   >> 565 void G4SPSEneDistribution::InputEnergySpectra(G4bool value) {
                                                   >> 566     G4AutoLock l(&mutex);
                                                   >> 567   // Allows user to specifiy spectrum is momentum
                                                   >> 568   EnergySpec = value; // false if momentum
                                                   >> 569   if (verbosityLevel > 1)
                                                   >> 570     G4cout << "EnergySpec has value " << EnergySpec << G4endl;
                                                   >> 571 }
                                                   >> 572 
                                                   >> 573 void G4SPSEneDistribution::InputDifferentialSpectra(G4bool value) {
                                                   >> 574     G4AutoLock l(&mutex);
                                                   >> 575   // Allows user to specify integral or differential spectra
                                                   >> 576   DiffSpec = value; // true = differential, false = integral
                                                   >> 577   if (verbosityLevel > 1)
                                                   >> 578     G4cout << "Diffspec has value " << DiffSpec << G4endl;
                                                   >> 579 }
                                                   >> 580 
                                                   >> 581 void G4SPSEneDistribution::ArbInterpolate(G4String IType) {
                                                   >> 582     G4AutoLock l(&mutex);
                                                   >> 583   if (EnergyDisType != "Arb")
                                                   >> 584         G4Exception("G4SPSEneDistribution::ArbInterpolate",
                                                   >> 585                     "Event0302",FatalException,
                                                   >> 586               "Error: this is for arbitrary distributions");
                                                   >> 587   IntType = IType;
                                                   >> 588   ArbEmax = ArbEnergyH.GetMaxLowEdgeEnergy();
                                                   >> 589   ArbEmin = ArbEnergyH.GetMinLowEdgeEnergy();
                                                   >> 590 
                                                   >> 591   // Now interpolate points
                                                   >> 592   if (IntType == "Lin")
                                                   >> 593     LinearInterpolation();
                                                   >> 594   if (IntType == "Log")
                                                   >> 595     LogInterpolation();
                                                   >> 596   if (IntType == "Exp")
                                                   >> 597     ExpInterpolation();
                                                   >> 598   if (IntType == "Spline")
                                                   >> 599     SplineInterpolation();
                                                   >> 600 }
                                                   >> 601 
                                                   >> 602 //MT: Lock in caller
                                                   >> 603 void G4SPSEneDistribution::LinearInterpolation() {
                                                   >> 604   // Method to do linear interpolation on the Arb points
                                                   >> 605   // Calculate equation of each line segment, max 1024.
                                                   >> 606   // Calculate Area under each segment
                                                   >> 607   // Create a cumulative array which is then normalised Arb_Cum_Area
                                                   >> 608 
                                                   >> 609   G4double Area_seg[1024]; // Stores area under each segment
                                                   >> 610   G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
                                                   >> 611   G4int i, count;
                                                   >> 612   G4int maxi = ArbEnergyH.GetVectorLength();
                                                   >> 613   for (i = 0; i < maxi; i++)
                                                   >> 614     {
                                                   >> 615     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
                                                   >> 616     Arb_y[i] = ArbEnergyH(size_t(i));
                                                   >> 617   }
                                                   >> 618   // Points are now in x,y arrays. If the spectrum is integral it has to be
                                                   >> 619   // made differential and if momentum it has to be made energy.
                                                   >> 620   if (DiffSpec == false)
                                                   >> 621     {
                                                   >> 622     // Converts integral point-wise spectra to Differential
                                                   >> 623     for (count = 0; count < maxi - 1; count++)
                                                   >> 624         {
                                                   >> 625       Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
                                                   >> 626           / (Arb_x[count + 1] - Arb_x[count]);
                                                   >> 627     }
                                                   >> 628     maxi--;
                                                   >> 629   }
                                                   >> 630   //
                                                   >> 631   if (EnergySpec == false)
                                                   >> 632     {
                                                   >> 633     // change currently stored values (emin etc) which are actually momenta
                                                   >> 634     // to energies.
                                                   >> 635         G4ParticleDefinition* pdef =threadLocalData.Get().particle_definition;
                                                   >> 636     if (pdef == NULL)
                                                   >> 637         {
                                                   >> 638             G4Exception("G4SPSEneDistribution::LinearInterpolation",
                                                   >> 639                         "Event0302",FatalException,
                                                   >> 640                         "Error: particle not defined");
                                                   >> 641         }
                                                   >> 642     else
                                                   >> 643         {
                                                   >> 644       // Apply Energy**2 = p**2c**2 + m0**2c**4
                                                   >> 645       // p should be entered as E/c i.e. without the division by c
                                                   >> 646       // being done - energy equivalent.
                                                   >> 647       G4double mass = pdef->GetPDGMass();
                                                   >> 648       // convert point to energy unit and its value to per energy unit
                                                   >> 649       G4double total_energy;
                                                   >> 650       for (count = 0; count < maxi; count++)
                                                   >> 651             {
                                                   >> 652         total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
                                                   >> 653             * mass)); // total energy
                                                   >> 654 
                                                   >> 655         Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
                                                   >> 656         Arb_x[count] = total_energy - mass; // kinetic energy
                                                   >> 657       }
                                                   >> 658     }
                                                   >> 659   }
                                                   >> 660   //
                                                   >> 661   i = 1;
                                                   >> 662     // AG:
                                                   >> 663     // This *should* be the first use of Arb_grad and friends, so we *should* be able to
                                                   >> 664     // dynamically allocate here
                                                   >> 665     Arb_grad = new G4double [1024];
                                                   >> 666     Arb_cept = new G4double [1024];
                                                   >> 667     Arb_grad_cept_flag = true;
                                                   >> 668     
                                                   >> 669   Arb_grad[0] = 0.;
                                                   >> 670   Arb_cept[0] = 0.;
                                                   >> 671   Area_seg[0] = 0.;
                                                   >> 672   Arb_Cum_Area[0] = 0.;
                                                   >> 673   while (i < maxi)
                                                   >> 674     {
                                                   >> 675     // calc gradient and intercept for each segment
                                                   >> 676     Arb_grad[i] = (Arb_y[i] - Arb_y[i - 1]) / (Arb_x[i] - Arb_x[i - 1]);
                                                   >> 677     if (verbosityLevel == 2)
                                                   >> 678         {
                                                   >> 679       G4cout << Arb_grad[i] << G4endl;
                                                   >> 680         }
                                                   >> 681     if (Arb_grad[i] > 0.)
                                                   >> 682         {
                                                   >> 683       if (verbosityLevel == 2)
                                                   >> 684             {
                                                   >> 685         G4cout << "Arb_grad is positive" << G4endl;
                                                   >> 686             }
                                                   >> 687       Arb_cept[i] = Arb_y[i] - (Arb_grad[i] * Arb_x[i]);
                                                   >> 688     }
                                                   >> 689         else if (Arb_grad[i] < 0.)
                                                   >> 690         {
                                                   >> 691       if (verbosityLevel == 2)
                                                   >> 692             {
                                                   >> 693         G4cout << "Arb_grad is negative" << G4endl;
                                                   >> 694             }
                                                   >> 695       Arb_cept[i] = Arb_y[i] + (-Arb_grad[i] * Arb_x[i]);
                                                   >> 696     }
                                                   >> 697         else
                                                   >> 698         {
                                                   >> 699       if (verbosityLevel == 2)
                                                   >> 700             {
                                                   >> 701         G4cout << "Arb_grad is 0." << G4endl;
                                                   >> 702             }
                                                   >> 703       Arb_cept[i] = Arb_y[i];
                                                   >> 704     }
                                                   >> 705 
                                                   >> 706     Area_seg[i] = ((Arb_grad[i] / 2) * (Arb_x[i] * Arb_x[i] - Arb_x[i - 1] * Arb_x[i - 1]) + Arb_cept[i] * (Arb_x[i] - Arb_x[i - 1]));
                                                   >> 707     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
                                                   >> 708     sum = sum + Area_seg[i];
                                                   >> 709     if (verbosityLevel == 2)
                                                   >> 710         {
                                                   >> 711       G4cout << Arb_x[i] << Arb_y[i] << Area_seg[i] << sum << Arb_grad[i] << G4endl;
                                                   >> 712         }
                                                   >> 713     i++;
                                                   >> 714   }
                                                   >> 715 
                                                   >> 716   i = 0;
                                                   >> 717   while (i < maxi)
                                                   >> 718     {
                                                   >> 719     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum; // normalisation
                                                   >> 720     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
                                                   >> 721     i++;
                                                   >> 722   }
                                                   >> 723 
                                                   >> 724   // now scale the ArbEnergyH, needed by Probability()
                                                   >> 725   ArbEnergyH.ScaleVector(1., 1./sum);
                                                   >> 726 
                                                   >> 727   if (verbosityLevel >= 1)
                                                   >> 728     {
                                                   >> 729     G4cout << "Leaving LinearInterpolation" << G4endl;
                                                   >> 730     ArbEnergyH.DumpValues();
                                                   >> 731     IPDFArbEnergyH.DumpValues();
                                                   >> 732   }
                                                   >> 733 }
                                                   >> 734 
                                                   >> 735 //MT: Lock in caller
                                                   >> 736 void G4SPSEneDistribution::LogInterpolation()
                                                   >> 737 {
                                                   >> 738   // Interpolation based on Logarithmic equations
                                                   >> 739   // Generate equations of line segments
                                                   >> 740   // y = Ax**alpha => log y = alpha*logx + logA
                                                   >> 741   // Find area under line segments
                                                   >> 742   // create normalised, cumulative array Arb_Cum_Area
                                                   >> 743   G4double Area_seg[1024]; // Stores area under each segment
                                                   >> 744   G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
                                                   >> 745   G4int i, count;
                                                   >> 746   G4int maxi = ArbEnergyH.GetVectorLength();
                                                   >> 747   for (i = 0; i < maxi; i++)
                                                   >> 748     {
                                                   >> 749     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
                                                   >> 750     Arb_y[i] = ArbEnergyH(size_t(i));
                                                   >> 751   }
                                                   >> 752   // Points are now in x,y arrays. If the spectrum is integral it has to be
                                                   >> 753   // made differential and if momentum it has to be made energy.
                                                   >> 754   if (DiffSpec == false)
                                                   >> 755     {
                                                   >> 756     // Converts integral point-wise spectra to Differential
                                                   >> 757     for (count = 0; count < maxi - 1; count++)
                                                   >> 758         {
                                                   >> 759       Arb_y[count] = (Arb_y[count] - Arb_y[count + 1]) / (Arb_x[count + 1] - Arb_x[count]);
                                                   >> 760     }
                                                   >> 761     maxi--;
                                                   >> 762   }
                                                   >> 763   //
                                                   >> 764   if (EnergySpec == false)
                                                   >> 765     {
                                                   >> 766     // change currently stored values (emin etc) which are actually momenta
                                                   >> 767     // to energies.
                                                   >> 768         G4ParticleDefinition* pdef = threadLocalData.Get().particle_definition;
                                                   >> 769     if (pdef == NULL)
                                                   >> 770         {
                                                   >> 771             G4Exception("G4SPSEneDistribution::LogInterpolation",
                                                   >> 772                         "Event0302",FatalException,
                                                   >> 773                         "Error: particle not defined");
                                                   >> 774         }
                                                   >> 775     else
                                                   >> 776         {
                                                   >> 777       // Apply Energy**2 = p**2c**2 + m0**2c**4
                                                   >> 778       // p should be entered as E/c i.e. without the division by c
                                                   >> 779       // being done - energy equivalent.
                                                   >> 780       G4double mass = pdef->GetPDGMass();
                                                   >> 781       // convert point to energy unit and its value to per energy unit
                                                   >> 782       G4double total_energy;
                                                   >> 783       for (count = 0; count < maxi; count++)
                                                   >> 784             {
                                                   >> 785         total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
                                                   >> 786             * mass)); // total energy
                                                   >> 787 
                                                   >> 788         Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
                                                   >> 789         Arb_x[count] = total_energy - mass; // kinetic energy
                                                   >> 790       }
                                                   >> 791     }
                                                   >> 792   }
                                                   >> 793   //
                                                   >> 794   i = 1;
                                                   >> 795     
                                                   >> 796     //AG:  *Should* be the first use of these two arrays
                                                   >> 797     if ( Arb_ezero ) { delete[] Arb_ezero; Arb_ezero = 0; }
                                                   >> 798     if ( Arb_Const ) { delete[] Arb_Const; Arb_Const = 0; }
                                                   >> 799     Arb_alpha = new G4double [1024];
                                                   >> 800     Arb_Const = new G4double [1024];
                                                   >> 801     Arb_alpha_Const_flag = true;
                                                   >> 802     
                                                   >> 803     
                                                   >> 804   Arb_alpha[0] = 0.;
                                                   >> 805   Arb_Const[0] = 0.;
                                                   >> 806   Area_seg[0] = 0.;
                                                   >> 807   Arb_Cum_Area[0] = 0.;
                                                   >> 808   if (Arb_x[0] <= 0. || Arb_y[0] <= 0.)
                                                   >> 809     {
                                                   >> 810     G4cout << "You should not use log interpolation with points <= 0." << G4endl;
                                                   >> 811     G4cout << "These will be changed to 1e-20, which may cause problems" << G4endl;
                                                   >> 812     if (Arb_x[0] <= 0.)
                                                   >> 813         {
                                                   >> 814       Arb_x[0] = 1e-20;
                                                   >> 815         }
                                                   >> 816     if (Arb_y[0] <= 0.)
                                                   >> 817         {
                                                   >> 818       Arb_y[0] = 1e-20;
                                                   >> 819         }
                                                   >> 820   }
                                                   >> 821 
                                                   >> 822   G4double alp;
                                                   >> 823   while (i < maxi)
                                                   >> 824     {
                                                   >> 825     // Incase points are negative or zero
                                                   >> 826     if (Arb_x[i] <= 0. || Arb_y[i] <= 0.)
                                                   >> 827         {
                                                   >> 828       G4cout << "You should not use log interpolation with points <= 0." << G4endl;
                                                   >> 829       G4cout << "These will be changed to 1e-20, which may cause problems" << G4endl;
                                                   >> 830       if (Arb_x[i] <= 0.)
                                                   >> 831             {
                                                   >> 832         Arb_x[i] = 1e-20;
                                                   >> 833             }
                                                   >> 834       if (Arb_y[i] <= 0.)
                                                   >> 835             {
                                                   >> 836         Arb_y[i] = 1e-20;
                                                   >> 837             }
                                                   >> 838     }
                                                   >> 839 
                                                   >> 840     Arb_alpha[i] = (std::log10(Arb_y[i]) - std::log10(Arb_y[i - 1])) / (std::log10(Arb_x[i]) - std::log10(Arb_x[i - 1]));
                                                   >> 841     Arb_Const[i] = Arb_y[i] / (std::pow(Arb_x[i], Arb_alpha[i]));
                                                   >> 842     alp = Arb_alpha[i] + 1;
                                                   >> 843     if (alp == 0.)
                                                   >> 844         {
                                                   >> 845       Area_seg[i] = Arb_Const[i] * (std::log(Arb_x[i]) - std::log(Arb_x[i - 1])); 
                                                   >> 846     }
                                                   >> 847         else
                                                   >> 848         {
                                                   >> 849       Area_seg[i] = (Arb_Const[i] / alp) * (std::pow(Arb_x[i], alp) - std::pow(Arb_x[i - 1], alp));
                                                   >> 850     }
                                                   >> 851     sum = sum + Area_seg[i];
                                                   >> 852     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
                                                   >> 853     if (verbosityLevel == 2)
                                                   >> 854         {
                                                   >> 855       G4cout << Arb_alpha[i] << Arb_Const[i] << Area_seg[i] << G4endl;
                                                   >> 856         }
                                                   >> 857     i++;
                                                   >> 858   }
                                                   >> 859 
                                                   >> 860   i = 0;
                                                   >> 861   while (i < maxi)
                                                   >> 862     {
                                                   >> 863     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
                                                   >> 864     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
                                                   >> 865     i++;
                                                   >> 866   }
                                                   >> 867 
                                                   >> 868   // now scale the ArbEnergyH, needed by Probability()
                                                   >> 869   ArbEnergyH.ScaleVector(1., 1./sum);
                                                   >> 870 
                                                   >> 871   if (verbosityLevel >= 1)
                                                   >> 872     {
                                                   >> 873     G4cout << "Leaving LogInterpolation " << G4endl;
                                                   >> 874     }
                                                   >> 875 }
                                                   >> 876 
                                                   >> 877 //MT: Lock in caller
                                                   >> 878 void G4SPSEneDistribution::ExpInterpolation()
                                                   >> 879 {
                                                   >> 880   // Interpolation based on Exponential equations
                                                   >> 881   // Generate equations of line segments
                                                   >> 882   // y = Ae**-(x/e0) => ln y = -x/e0 + lnA
                                                   >> 883   // Find area under line segments
                                                   >> 884   // create normalised, cumulative array Arb_Cum_Area
                                                   >> 885   G4double Area_seg[1024]; // Stores area under each segment
                                                   >> 886   G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
                                                   >> 887   G4int i, count;
                                                   >> 888   G4int maxi = ArbEnergyH.GetVectorLength();
                                                   >> 889   for (i = 0; i < maxi; i++)
                                                   >> 890     {
                                                   >> 891     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
                                                   >> 892     Arb_y[i] = ArbEnergyH(size_t(i));
                                                   >> 893   }
                                                   >> 894   // Points are now in x,y arrays. If the spectrum is integral it has to be
                                                   >> 895   // made differential and if momentum it has to be made energy.
                                                   >> 896   if (DiffSpec == false)
                                                   >> 897     {
                                                   >> 898     // Converts integral point-wise spectra to Differential
                                                   >> 899     for (count = 0; count < maxi - 1; count++)
                                                   >> 900         {
                                                   >> 901       Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
                                                   >> 902           / (Arb_x[count + 1] - Arb_x[count]);
                                                   >> 903     }
                                                   >> 904     maxi--;
                                                   >> 905   }
                                                   >> 906   //
                                                   >> 907   if (EnergySpec == false)
                                                   >> 908     {
                                                   >> 909     // change currently stored values (emin etc) which are actually momenta
                                                   >> 910     // to energies.
                                                   >> 911         G4ParticleDefinition* pdef = threadLocalData.Get().particle_definition;
                                                   >> 912     if (pdef == NULL)
                                                   >> 913         {
                                                   >> 914             G4Exception("G4SPSEneDistribution::ExpInterpolation",
                                                   >> 915                         "Event0302",FatalException,
                                                   >> 916                         "Error: particle not defined");
                                                   >> 917         }
                                                   >> 918     else
                                                   >> 919         {
                                                   >> 920       // Apply Energy**2 = p**2c**2 + m0**2c**4
                                                   >> 921       // p should be entered as E/c i.e. without the division by c
                                                   >> 922       // being done - energy equivalent.
                                                   >> 923       G4double mass = pdef->GetPDGMass();
                                                   >> 924       // convert point to energy unit and its value to per energy unit
                                                   >> 925       G4double total_energy;
                                                   >> 926       for (count = 0; count < maxi; count++)
                                                   >> 927             {
                                                   >> 928         total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass * mass)); // total energy
                                                   >> 929         Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
                                                   >> 930         Arb_x[count] = total_energy - mass; // kinetic energy
                                                   >> 931       }
                                                   >> 932     }
                                                   >> 933   }
                                                   >> 934   //
                                                   >> 935   i = 1;
                                                   >> 936     
                                                   >> 937     //AG: Should be first use...
                                                   >> 938     if ( Arb_ezero ) { delete[] Arb_ezero; Arb_ezero = 0; }
                                                   >> 939     if ( Arb_Const ) { delete[] Arb_Const; Arb_Const = 0; }
                                                   >> 940     Arb_ezero = new G4double [1024];
                                                   >> 941     Arb_Const = new G4double [1024];
                                                   >> 942     Arb_ezero_flag = true;
                                                   >> 943     
                                                   >> 944   Arb_ezero[0] = 0.;
                                                   >> 945   Arb_Const[0] = 0.;
                                                   >> 946   Area_seg[0] = 0.;
                                                   >> 947   Arb_Cum_Area[0] = 0.;
                                                   >> 948   while (i < maxi)
                                                   >> 949     {
                                                   >> 950     G4double test = std::log(Arb_y[i]) - std::log(Arb_y[i - 1]);
                                                   >> 951     if (test > 0. || test < 0.)
                                                   >> 952         {
                                                   >> 953       Arb_ezero[i] = -(Arb_x[i] - Arb_x[i - 1]) / (std::log(Arb_y[i]) - std::log(Arb_y[i - 1]));
                                                   >> 954       Arb_Const[i] = Arb_y[i] / (std::exp(-Arb_x[i] / Arb_ezero[i]));
                                                   >> 955       Area_seg[i] = -(Arb_Const[i] * Arb_ezero[i]) * (std::exp(-Arb_x[i] / Arb_ezero[i]) - std::exp(-Arb_x[i - 1] / Arb_ezero[i]));
                                                   >> 956     }
                                                   >> 957         else
                                                   >> 958         {
                                                   >> 959             G4Exception("G4SPSEneDistribution::ExpInterpolation",
                                                   >> 960                         "Event0302",JustWarning,
                                                   >> 961                         "Flat line segment: problem, setting to zero parameters.");
                                                   >> 962       G4cout << "Flat line segment: problem" << G4endl;
                                                   >> 963       Arb_ezero[i] = 0.;
                                                   >> 964       Arb_Const[i] = 0.;
                                                   >> 965       Area_seg[i] = 0.;
                                                   >> 966     }
                                                   >> 967     sum = sum + Area_seg[i];
                                                   >> 968     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
                                                   >> 969     if (verbosityLevel == 2)
                                                   >> 970         {
                                                   >> 971       G4cout << Arb_ezero[i] << Arb_Const[i] << Area_seg[i] << G4endl;
                                                   >> 972         }
                                                   >> 973     i++;
                                                   >> 974   }
                                                   >> 975 
                                                   >> 976   i = 0;
                                                   >> 977   while (i < maxi)
                                                   >> 978     {
                                                   >> 979     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
                                                   >> 980     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
                                                   >> 981     i++;
                                                   >> 982   }
                                                   >> 983 
                                                   >> 984   // now scale the ArbEnergyH, needed by Probability()
                                                   >> 985   ArbEnergyH.ScaleVector(1., 1./sum);
                                                   >> 986 
                                                   >> 987   if (verbosityLevel >= 1)
                                                   >> 988     {
                                                   >> 989     G4cout << "Leaving ExpInterpolation " << G4endl;
846     }                                             990     }
847     sum = sum + Area_seg[i];                   << 991 }
848     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Ar << 992 
849     if (verbosityLevel == 2)                   << 993 //MT: Lock in caller
850     {                                          << 994 void G4SPSEneDistribution::SplineInterpolation()
851       G4cout << Arb_alpha[i] << Arb_Const[i] < << 995 {
852     }                                          << 996   // Interpolation using Splines.
853     ++i;                                       << 997   // Create Normalised arrays, make x 0->1 and y hold
854   }                                            << 998   // the function (Energy)
855                                                << 999         // 
856   i = 0;                                       << 1000         // Current method based on the above will not work in all cases. 
857   while (i < maxi)                             << 1001         // new method is implemented below.
858   {                                            << 1002   
859     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;   << 1003   G4double sum, Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
860     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_ << 1004   G4int i, count;
861     ++i;                                       << 1005 
862   }                                            << 1006   G4int maxi = ArbEnergyH.GetVectorLength();
863                                                << 1007   for (i = 0; i < maxi; i++) {
864   // Now scale the ArbEnergyH, needed by Proba << 1008     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
865   //                                           << 1009     Arb_y[i] = ArbEnergyH(size_t(i));
866   ArbEnergyH.ScaleVector(1., 1./sum);          << 1010   }
867                                                << 1011   // Points are now in x,y arrays. If the spectrum is integral it has to be
868   if (verbosityLevel >= 1)                     << 1012   // made differential and if momentum it has to be made energy.
869   {                                            << 1013   if (DiffSpec == false) {
870     G4cout << "Leaving LogInterpolation " << G << 1014     // Converts integral point-wise spectra to Differential
871   }                                            << 1015     for (count = 0; count < maxi - 1; count++)
872 }                                              << 1016         {
873                                                << 1017       Arb_y[count] = (Arb_y[count] - Arb_y[count + 1]) / (Arb_x[count + 1] - Arb_x[count]);
874 void G4SPSEneDistribution::ExpInterpolation()  << 1018     }
875 {                                              << 1019     maxi--;
876   // Interpolation based on Exponential equati << 1020   }
877   // Generate equations of line segments       << 1021   //
878   // y = Ae**-(x/e0) => ln y = -x/e0 + lnA     << 1022   if (EnergySpec == false) {
879   // Find area under line segments             << 1023     // change currently stored values (emin etc) which are actually momenta
880   // Create normalised, cumulative array Arb_C << 1024     // to energies.
881                                                << 1025         G4ParticleDefinition* pdef = threadLocalData.Get().particle_definition;
882   G4double Area_seg[1024]; // Stores area unde << 1026     if (pdef == NULL)
883   G4double sum = 0., Arb_x[1024]={0.}, Arb_y[1 << 1027                     G4Exception("G4SPSEneDistribution::SplineInterpolation",
884   std::size_t i, count;                        << 1028                                 "Event0302",FatalException,
885   std::size_t maxi = ArbEnergyH.GetVectorLengt << 1029               "Error: particle not defined");
886   for (i = 0; i < maxi; ++i)                   << 1030     else {
887   {                                            << 1031       // Apply Energy**2 = p**2c**2 + m0**2c**4
888     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(i); << 1032       // p should be entered as E/c i.e. without the division by c
889     Arb_y[i] = ArbEnergyH(i);                  << 1033       // being done - energy equivalent.
890   }                                            << 1034       G4double mass = pdef->GetPDGMass();
891                                                << 1035       // convert point to energy unit and its value to per energy unit
892   // Points are now in x,y arrays. If the spec << 1036       G4double total_energy;
893   // made differential and if momentum it has  << 1037       for (count = 0; count < maxi; count++) {
894                                                << 1038         total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
895   if (!DiffSpec)                               << 1039             * mass)); // total energy
896   {                                            << 1040 
897     // Converts integral point-wise spectra to << 1041         Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
898     //                                         << 1042         Arb_x[count] = total_energy - mass; // kinetic energy
899     for (count = 0; count < maxi - 1; ++count) << 1043       }
900     {                                          << 1044     }
901       Arb_y[count] = (Arb_y[count] - Arb_y[cou << 1045   }
902                    / (Arb_x[count + 1] - Arb_x << 1046 
903     }                                          << 1047   //
904     --maxi;                                    << 1048   i = 1;
905   }                                            << 1049   Arb_Cum_Area[0] = 0.;
906                                                << 1050   sum = 0.;
907   if (!EnergySpec)                             << 1051   Splinetemp = new G4DataInterpolation(Arb_x, Arb_y, maxi, 0., 0.);
908   {                                            << 1052   G4double ei[101],prob[101];
909     // Change currently stored values (emin et << 1053     for ( std::vector<G4DataInterpolation*>::iterator it = SplineInt.begin() ; it!=SplineInt.end() ; ++it)
910     // to energies                             << 1054     {
911     //                                         << 1055         delete *it;
912     G4ParticleDefinition* pdef = threadLocalDa << 1056         *it = 0;
913     if (pdef == nullptr)                       << 1057     }
914     {                                          << 1058     SplineInt.clear();
915       G4Exception("G4SPSEneDistribution::ExpIn << 1059     SplineInt.resize(1024,NULL);
916                   "Event0302", FatalException, << 1060   while (i < maxi) {
917                   "Error: particle not defined << 1061     // 100 step per segment for the integration of area
                                                   >> 1062     G4double de = (Arb_x[i] - Arb_x[i - 1])/100.;
                                                   >> 1063     G4double area = 0.;
                                                   >> 1064 
                                                   >> 1065     for (count = 0; count < 101; count++) {
                                                   >> 1066       ei[count] = Arb_x[i - 1] + de*count ;
                                                   >> 1067       prob[count] =  Splinetemp->CubicSplineInterpolation(ei[count]);
                                                   >> 1068       if (prob[count] < 0.) { 
                                                   >> 1069               G4ExceptionDescription ED;
                                                   >> 1070         ED << "Warning: G4DataInterpolation returns value < 0  " << prob[count] <<" "<<ei[count]<< G4endl;
                                                   >> 1071               G4Exception("G4SPSEneDistribution::SplineInterpolation","Event0303",
                                                   >> 1072               FatalException,ED);
                                                   >> 1073       }
                                                   >> 1074       area += prob[count]*de;
                                                   >> 1075     }
                                                   >> 1076     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + area;
                                                   >> 1077     sum += area; 
                                                   >> 1078 
                                                   >> 1079     prob[0] = prob[0]/(area/de);
                                                   >> 1080     for (count = 1; count < 100; count++)
                                                   >> 1081       prob[count] = prob[count-1] + prob[count]/(area/de);
                                                   >> 1082 
                                                   >> 1083     SplineInt[i]=new G4DataInterpolation(prob, ei, 101, 0., 0.);
                                                   >> 1084     // note i start from 1!
                                                   >> 1085     i++;
                                                   >> 1086   }
                                                   >> 1087   i = 0;
                                                   >> 1088   while (i < maxi) {
                                                   >> 1089     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum; // normalisation
                                                   >> 1090     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
                                                   >> 1091     i++;
                                                   >> 1092   }
                                                   >> 1093   // now scale the ArbEnergyH, needed by Probability()
                                                   >> 1094   ArbEnergyH.ScaleVector(1., 1./sum);
                                                   >> 1095 
                                                   >> 1096   if (verbosityLevel > 0)
                                                   >> 1097     G4cout << "Leaving SplineInterpolation " << G4endl;
                                                   >> 1098 }
                                                   >> 1099 
                                                   >> 1100 void G4SPSEneDistribution::GenerateMonoEnergetic() {
                                                   >> 1101   // Method to generate MonoEnergetic particles.
                                                   >> 1102     threadLocalData.Get().particle_energy = MonoEnergy;
                                                   >> 1103 }
                                                   >> 1104 
                                                   >> 1105 void G4SPSEneDistribution::GenerateGaussEnergies() {
                                                   >> 1106   // Method to generate Gaussian particles.
                                                   >> 1107   G4double ene = G4RandGauss::shoot(MonoEnergy,SE);
                                                   >> 1108   if (ene < 0) ene = 0.;
                                                   >> 1109     threadLocalData.Get().particle_energy = ene;
                                                   >> 1110 }
                                                   >> 1111 
                                                   >> 1112 void G4SPSEneDistribution::GenerateLinearEnergies(G4bool bArb = false) {
                                                   >> 1113   G4double rndm;
                                                   >> 1114     threadLocal_t& params = threadLocalData.Get();
                                                   >> 1115   G4double emaxsq = std::pow(params.Emax, 2.); //Emax squared
                                                   >> 1116   G4double eminsq = std::pow(params.Emin, 2.); //Emin squared
                                                   >> 1117   G4double intersq = std::pow(params.cept, 2.); //cept squared
                                                   >> 1118 
                                                   >> 1119   if (bArb)
                                                   >> 1120     rndm = G4UniformRand();
                                                   >> 1121   else
                                                   >> 1122     rndm = eneRndm->GenRandEnergy();
                                                   >> 1123 
                                                   >> 1124   G4double bracket = ((params.grad / 2.) * (emaxsq - eminsq) + params.cept * (params.Emax - params.Emin));
                                                   >> 1125   bracket = bracket * rndm;
                                                   >> 1126   bracket = bracket + (params.grad / 2.) * eminsq + params.cept * params.Emin;
                                                   >> 1127   // Now have a quad of form m/2 E**2 + cE - bracket = 0
                                                   >> 1128   bracket = -bracket;
                                                   >> 1129   //  G4cout << "BRACKET" << bracket << G4endl;
                                                   >> 1130   if (params.grad != 0.)
                                                   >> 1131     {
                                                   >> 1132     G4double sqbrack = (intersq - 4 * (params.grad / 2.) * (bracket));
                                                   >> 1133     //      G4cout << "SQBRACK" << sqbrack << G4endl;
                                                   >> 1134     sqbrack = std::sqrt(sqbrack);
                                                   >> 1135     G4double root1 = -params.cept + sqbrack;
                                                   >> 1136     root1 = root1 / (2. * (params.grad / 2.));
                                                   >> 1137 
                                                   >> 1138     G4double root2 = -params.cept - sqbrack;
                                                   >> 1139     root2 = root2 / (2. * (params.grad / 2.));
                                                   >> 1140 
                                                   >> 1141     //      G4cout << root1 << " roots " << root2 << G4endl;
                                                   >> 1142 
                                                   >> 1143     if (root1 > params.Emin && root1 < params.Emax)
                                                   >> 1144         {
                                                   >> 1145       params.particle_energy = root1;
                                                   >> 1146         }
                                                   >> 1147     if (root2 > params.Emin && root2 < params.Emax)
                                                   >> 1148         {
                                                   >> 1149       params.particle_energy = root2;
                                                   >> 1150         }
                                                   >> 1151   }
                                                   >> 1152     else if (params.grad == 0.)
                                                   >> 1153     {
                                                   >> 1154     // have equation of form cE - bracket =0
                                                   >> 1155     params.particle_energy = bracket / params.cept;
918     }                                             1156     }
919     else                                       << 1157 
                                                   >> 1158   if (params.particle_energy < 0.)
920     {                                             1159     {
921       // Apply Energy**2 = p**2c**2 + m0**2c** << 1160     params.particle_energy = -params.particle_energy;
922       // p should be entered as E/c i.e. witho << 
923       // being done - energy equivalent        << 
924                                                << 
925       G4double mass = pdef->GetPDGMass();      << 
926                                                << 
927       // Convert point to energy unit and its  << 
928       //                                       << 
929       G4double total_energy;                   << 
930       for (count = 0; count < maxi; ++count)   << 
931       {                                        << 
932         total_energy = std::sqrt((Arb_x[count] << 
933         Arb_y[count] = Arb_y[count] * Arb_x[co << 
934         Arb_x[count] = total_energy - mass; // << 
935       }                                        << 
936     }                                          << 
937   }                                            << 
938                                                << 
939   i = 1;                                       << 
940                                                << 
941   if ( Arb_ezero != nullptr ) { delete[] Arb_e << 
942   if ( Arb_Const != nullptr ) { delete[] Arb_C << 
943   Arb_ezero = new G4double [1024];             << 
944   Arb_Const = new G4double [1024];             << 
945   Arb_ezero_flag = true;                       << 
946                                                << 
947   Arb_ezero[0] = 0.;                           << 
948   Arb_Const[0] = 0.;                           << 
949   Area_seg[0] = 0.;                            << 
950   Arb_Cum_Area[0] = 0.;                        << 
951   while (i < maxi)                             << 
952   {                                            << 
953     G4double test = std::log(Arb_y[i]) - std:: << 
954     if (test > 0. || test < 0.)                << 
955     {                                          << 
956       Arb_ezero[i] = -(Arb_x[i] - Arb_x[i - 1] << 
957                    / (std::log(Arb_y[i]) - std << 
958       Arb_Const[i] = Arb_y[i] / (std::exp(-Arb << 
959       Area_seg[i] = -(Arb_Const[i] * Arb_ezero << 
960                   * (std::exp(-Arb_x[i] / Arb_ << 
961                    - std::exp(-Arb_x[i - 1] /  << 
962     }                                             1161     }
963     else                                       << 1162 
                                                   >> 1163   if (verbosityLevel >= 1)
964     {                                             1164     {
965       G4Exception("G4SPSEneDistribution::ExpIn << 1165     G4cout << "Energy is " << params.particle_energy << G4endl;
966                   "Event0302", JustWarning,    << 
967                   "Flat line segment: problem, << 
968       G4cout << "Flat line segment: problem" < << 
969       Arb_ezero[i] = 0.;                       << 
970       Arb_Const[i] = 0.;                       << 
971       Area_seg[i] = 0.;                        << 
972     }                                          << 
973     sum = sum + Area_seg[i];                   << 
974     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Ar << 
975     if (verbosityLevel == 2)                   << 
976     {                                          << 
977       G4cout << Arb_ezero[i] << Arb_Const[i] < << 
978     }                                          << 
979     ++i;                                       << 
980   }                                            << 
981                                                << 
982   i = 0;                                       << 
983   while (i < maxi)                             << 
984   {                                            << 
985     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;   << 
986     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_ << 
987     ++i;                                       << 
988   }                                            << 
989                                                << 
990   // Now scale the ArbEnergyH, needed by Proba << 
991   //                                           << 
992   ArbEnergyH.ScaleVector(1., 1./sum);          << 
993                                                << 
994   if (verbosityLevel >= 1)                     << 
995   {                                            << 
996     G4cout << "Leaving ExpInterpolation " << G << 
997   }                                            << 
998 }                                              << 
999                                                << 
1000 void G4SPSEneDistribution::SplineInterpolatio << 
1001 {                                             << 
1002   // Interpolation using Splines.             << 
1003   // Create Normalised arrays, make x 0->1 an << 
1004   //                                          << 
1005   // Current method based on the above will n << 
1006   // New method is implemented below.         << 
1007                                               << 
1008   G4double sum, Arb_x[1024]={0.}, Arb_y[1024] << 
1009   std::size_t i, count;                       << 
1010   std::size_t maxi = ArbEnergyH.GetVectorLeng << 
1011                                               << 
1012   for (i = 0; i < maxi; ++i)                  << 
1013   {                                           << 
1014     Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(i) << 
1015     Arb_y[i] = ArbEnergyH(i);                 << 
1016   }                                           << 
1017                                               << 
1018   // Points are now in x,y arrays. If the spe << 
1019   // made differential and if momentum it has << 
1020                                               << 
1021   if (!DiffSpec)                              << 
1022   {                                           << 
1023     // Converts integral point-wise spectra t << 
1024     //                                        << 
1025     for (count = 0; count < maxi - 1; ++count << 
1026     {                                         << 
1027       Arb_y[count] = (Arb_y[count] - Arb_y[co << 
1028                    / (Arb_x[count + 1] - Arb_ << 
1029     }                                         << 
1030     --maxi;                                   << 
1031   }                                           << 
1032                                               << 
1033   if (!EnergySpec)                            << 
1034   {                                           << 
1035     // Change currently stored values (emin e << 
1036     // to energies                            << 
1037     //                                        << 
1038     G4ParticleDefinition* pdef = threadLocalD << 
1039     if (pdef == nullptr)                      << 
1040     {                                         << 
1041       G4Exception("G4SPSEneDistribution::Spli << 
1042                   "Event0302", FatalException << 
1043                   "Error: particle not define << 
1044     }                                            1166     }
1045     else                                      << 
1046     {                                         << 
1047       // Apply Energy**2 = p**2c**2 + m0**2c* << 
1048       // p should be entered as E/c i.e. with << 
1049       // being done - energy equivalent       << 
1050                                               << 
1051       G4double mass = pdef->GetPDGMass();     << 
1052                                               << 
1053       // Convert point to energy unit and its << 
1054       //                                      << 
1055       G4double total_energy;                  << 
1056       for (count = 0; count < maxi; ++count)  << 
1057       {                                       << 
1058         total_energy = std::sqrt((Arb_x[count << 
1059         Arb_y[count] = Arb_y[count] * Arb_x[c << 
1060         Arb_x[count] = total_energy - mass; / << 
1061       }                                       << 
1062     }                                         << 
1063   }                                           << 
1064                                               << 
1065   i = 1;                                      << 
1066   Arb_Cum_Area[0] = 0.;                       << 
1067   sum = 0.;                                   << 
1068   Splinetemp = new G4DataInterpolation(Arb_x, << 
1069   G4double ei[101], prob[101];                << 
1070   for (auto & it : SplineInt)                 << 
1071   {                                           << 
1072     delete it;                                << 
1073     it = nullptr;                             << 
1074   }                                           << 
1075   SplineInt.clear();                          << 
1076   SplineInt.resize(1024,nullptr);             << 
1077   while (i < maxi)                            << 
1078   {                                           << 
1079     // 100 step per segment for the integrati << 
1080                                               << 
1081     G4double de = (Arb_x[i] - Arb_x[i - 1])/1 << 
1082     G4double area = 0.;                       << 
1083                                               << 
1084     for (count = 0; count < 101; ++count)     << 
1085     {                                         << 
1086       ei[count] = Arb_x[i - 1] + de*count ;   << 
1087       prob[count] =  Splinetemp->CubicSplineI << 
1088       if (prob[count] < 0.)                   << 
1089       {                                       << 
1090         G4ExceptionDescription ED;            << 
1091         ED << "Warning: G4DataInterpolation r << 
1092            << " " << ei[count] << G4endl;     << 
1093         G4Exception("G4SPSEneDistribution::Sp << 
1094                     FatalException, ED);      << 
1095       }                                       << 
1096       area += prob[count]*de;                 << 
1097     }                                         << 
1098     Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + a << 
1099     sum += area;                              << 
1100                                               << 
1101     prob[0] = prob[0]/(area/de);              << 
1102     for (count = 1; count < 100; ++count)     << 
1103     {                                         << 
1104       prob[count] = prob[count-1] + prob[coun << 
1105     }                                         << 
1106                                               << 
1107     SplineInt[i] = new G4DataInterpolation(pr << 
1108                                               << 
1109     // NOTE: i starts from 1!                 << 
1110     //                                        << 
1111     ++i;                                      << 
1112   }                                           << 
1113                                               << 
1114   i = 0;                                      << 
1115   while (i < maxi)                            << 
1116   {                                           << 
1117     Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;  << 
1118     IPDFArbEnergyH.InsertValues(Arb_x[i], Arb << 
1119     ++i;                                      << 
1120   }                                           << 
1121                                               << 
1122   // Now scale the ArbEnergyH, needed by Prob << 
1123   //                                          << 
1124   ArbEnergyH.ScaleVector(1., 1./sum);         << 
1125                                               << 
1126   if (verbosityLevel > 0)                     << 
1127   {                                           << 
1128     G4cout << "Leaving SplineInterpolation "  << 
1129   }                                           << 
1130 }                                             << 
1131                                               << 
1132 void G4SPSEneDistribution::GenerateMonoEnerge << 
1133 {                                             << 
1134   // Method to generate MonoEnergetic particl << 
1135                                               << 
1136   threadLocalData.Get().particle_energy = Mon << 
1137 }                                             << 
1138                                               << 
1139 void G4SPSEneDistribution::GenerateGaussEnerg << 
1140 {                                             << 
1141   // Method to generate Gaussian particles    << 
1142                                               << 
1143   G4double ene = G4RandGauss::shoot(MonoEnerg << 
1144   if (ene < 0) ene = 0.;                      << 
1145   threadLocalData.Get().particle_energy = ene << 
1146 }                                             << 
1147                                               << 
1148 void G4SPSEneDistribution::GenerateLinearEner << 
1149 {                                             << 
1150   G4double rndm;                              << 
1151   threadLocal_t& params = threadLocalData.Get << 
1152   G4double emaxsq = std::pow(params.Emax, 2.) << 
1153   G4double eminsq = std::pow(params.Emin, 2.) << 
1154   G4double intersq = std::pow(params.cept, 2. << 
1155                                               << 
1156   if (bArb) rndm = G4UniformRand();           << 
1157   else      rndm = eneRndm->GenRandEnergy();  << 
1158                                               << 
1159   G4double bracket = ((params.grad / 2.)      << 
1160                    * (emaxsq - eminsq)        << 
1161                    + params.cept * (params.Em << 
1162   bracket = bracket * rndm;                   << 
1163   bracket = bracket + (params.grad / 2.) * em << 
1164                                               << 
1165   // Now have a quad of form m/2 E**2 + cE -  << 
1166   //                                          << 
1167   bracket = -bracket;                         << 
1168                                               << 
1169   if (params.grad != 0.)                      << 
1170   {                                           << 
1171     G4double sqbrack = (intersq - 4 * (params << 
1172     sqbrack = std::sqrt(sqbrack);             << 
1173     G4double root1 = -params.cept + sqbrack;  << 
1174     root1 = root1 / (2. * (params.grad / 2.)) << 
1175                                               << 
1176     G4double root2 = -params.cept - sqbrack;  << 
1177     root2 = root2 / (2. * (params.grad / 2.)) << 
1178                                               << 
1179     if (root1 > params.Emin && root1 < params << 
1180     {                                         << 
1181       params.particle_energy = root1;         << 
1182     }                                         << 
1183     if (root2 > params.Emin && root2 < params << 
1184     {                                         << 
1185       params.particle_energy = root2;         << 
1186     }                                         << 
1187   }                                           << 
1188   else if (params.grad == 0.)                 << 
1189   {                                           << 
1190     // have equation of form cE - bracket =0  << 
1191     //                                        << 
1192     params.particle_energy = bracket / params << 
1193   }                                           << 
1194                                               << 
1195   if (params.particle_energy < 0.)            << 
1196   {                                           << 
1197     params.particle_energy = -params.particle << 
1198   }                                           << 
1199                                               << 
1200   if (verbosityLevel >= 1)                    << 
1201   {                                           << 
1202     G4cout << "Energy is " << params.particle << 
1203   }                                           << 
1204 }                                                1167 }
1205                                                  1168 
1206 void G4SPSEneDistribution::GeneratePowEnergie    1169 void G4SPSEneDistribution::GeneratePowEnergies(G4bool bArb = false)
1207 {                                                1170 {
1208   // Method to generate particle energies dis << 1171   // Method to generate particle energies distributed as
                                                   >> 1172   // a power-law
1209                                                  1173 
1210   G4double rndm;                              << 1174   G4double rndm;
1211   G4double emina, emaxa;                      << 1175   G4double emina, emaxa;
1212                                                  1176     
1213   threadLocal_t& params = threadLocalData.Get << 1177     threadLocal_t& params = threadLocalData.Get();
1214                                                  1178     
1215   emina = std::pow(params.Emin, params.alpha  << 1179   emina = std::pow(params.Emin, params.alpha + 1);
1216   emaxa = std::pow(params.Emax, params.alpha  << 1180   emaxa = std::pow(params.Emax, params.alpha + 1);
1217                                               << 1181 
1218   if (bArb) rndm = G4UniformRand();           << 1182   if (bArb)
1219   else      rndm = eneRndm->GenRandEnergy();  << 1183     {
1220                                               << 1184     rndm = G4UniformRand();
1221   if (params.alpha != -1.)                    << 1185     }
1222   {                                           << 1186   else
1223     G4double ene = ((rndm * (emaxa - emina))  << 1187     {
1224     ene = std::pow(ene, (1. / (params.alpha + << 1188     rndm = eneRndm->GenRandEnergy();
1225     params.particle_energy = ene;             << 1189     }
1226   }                                           << 1190 
1227   else                                        << 1191   if (params.alpha != -1.)
1228   {                                           << 1192     {
1229     G4double ene = (std::log(params.Emin)     << 1193     G4double ene = ((rndm * (emaxa - emina)) + emina);
1230                  + rndm * (std::log(params.Em << 1194     ene = std::pow(ene, (1. / (params.alpha + 1.)));
1231     params.particle_energy = std::exp(ene);   << 1195         params.particle_energy = ene;
1232   }                                           << 1196   }
1233   if (verbosityLevel >= 1)                    << 1197     else
1234   {                                           << 1198     {
1235     G4cout << "Energy is " << params.particle << 1199     G4double ene = (std::log(params.Emin) + rndm * (std::log(params.Emax) - std::log(params.Emin)));
1236   }                                           << 1200     params.particle_energy = std::exp(ene);
                                                   >> 1201   }
                                                   >> 1202   if (verbosityLevel >= 1)
                                                   >> 1203     {
                                                   >> 1204     G4cout << "Energy is " << params.particle_energy << G4endl;
                                                   >> 1205     }
1237 }                                                1206 }
1238                                                  1207 
1239 void G4SPSEneDistribution::GenerateCPowEnergi    1208 void G4SPSEneDistribution::GenerateCPowEnergies()
1240 {                                                1209 {
1241   // Method to generate particle energies dis << 1210   // Method to generate particle energies distributed in
1242   // cutoff power-law distribution            << 1211   // cutoff power-law distribution
1243   //                                          << 
1244   // CP_x holds Energies, and CPHist holds th << 
1245   // binary search to find correct bin then l << 
1246   // Use the earlier defined histogram + Rand << 
1247   // random numbers following the histos dist << 
1248                                               << 
1249   G4double rndm = eneRndm->GenRandEnergy();   << 
1250   G4int nabove = 10001, nbelow = 0, middle;   << 
1251                                               << 
1252   G4AutoLock l(&mutex);                       << 
1253   G4bool done = CPhistCalcd;                  << 
1254   l.unlock();                                 << 
1255                                               << 
1256   if(!done)                                   << 
1257   {                                           << 
1258     Calculate(); //This is has a lock inside, << 
1259     l.lock();                                 << 
1260     CPhistCalcd = true;                       << 
1261     l.unlock();                               << 
1262   }                                           << 
1263                                                  1212 
1264   // Binary search to find bin that rndm is i << 1213   // CP_x holds Energies, and CPHist holds the cumulative histo.
1265   //                                          << 1214   // binary search to find correct bin then lin interpolation.
1266   while (nabove - nbelow > 1)                 << 1215   // Use the earlier defined histogram + RandGeneral method to generate
1267   {                                           << 1216   // random numbers following the histos distribution.
1268     middle = (nabove + nbelow) / 2;           << 1217   G4double rndm;
1269     if (rndm == CPHist->at(middle))           << 1218   G4int nabove, nbelow = 0, middle;
                                                   >> 1219   nabove = 10001;
                                                   >> 1220   rndm = eneRndm->GenRandEnergy();
                                                   >> 1221     G4AutoLock l(&mutex);
                                                   >> 1222     G4bool done = CPhistCalcd;
                                                   >> 1223     l.unlock();
                                                   >> 1224     if(!done)
                                                   >> 1225     {
                                                   >> 1226         Calculate(); //This is has a lock inside, risk is to do it twice
                                                   >> 1227         l.lock();
                                                   >> 1228         CPhistCalcd = true;
                                                   >> 1229         l.unlock();
                                                   >> 1230     }
                                                   >> 1231 
                                                   >> 1232   // Binary search to find bin that rndm is in
                                                   >> 1233   while (nabove - nbelow > 1)
                                                   >> 1234     {
                                                   >> 1235     middle = (nabove + nbelow) / 2;
                                                   >> 1236     if (rndm == CPHist->at(middle))
                                                   >> 1237         {
                                                   >> 1238       break;
                                                   >> 1239         }
                                                   >> 1240     if (rndm < CPHist->at(middle))
                                                   >> 1241         {
                                                   >> 1242       nabove = middle;
                                                   >> 1243         }
                                                   >> 1244     else
                                                   >> 1245         {
                                                   >> 1246       nbelow = middle;
                                                   >> 1247         }
                                                   >> 1248   }
                                                   >> 1249 
                                                   >> 1250   // Now interpolate in that bin to find the correct output value.
                                                   >> 1251   G4double x1, x2, y1, y2, t, q;
                                                   >> 1252   x1 = CP_x->at(nbelow);
                                                   >> 1253     if(nbelow+1 == static_cast<G4int>(CP_x->size()))
                                                   >> 1254     {
                                                   >> 1255         x2 = CP_x->back();
                                                   >> 1256     }
                                                   >> 1257     else
1270     {                                            1258     {
1271       break;                                  << 1259         x2 = CP_x->at(nbelow + 1);
1272     }                                            1260     }
1273     if (rndm < CPHist->at(middle))            << 1261   y1 = CPHist->at(nbelow);
                                                   >> 1262     if(nbelow+1 == static_cast<G4int>(CPHist->size()))
1274     {                                            1263     {
1275       nabove = middle;                        << 1264         G4cout << CPHist->back() << G4endl;
                                                   >> 1265         y2 = CPHist->back();
1276     }                                            1266     }
1277     else                                         1267     else
1278     {                                            1268     {
1279       nbelow = middle;                        << 1269         y2 = CPHist->at(nbelow + 1);
1280     }                                            1270     }
1281   }                                           << 1271   t = (y2 - y1) / (x2 - x1);
                                                   >> 1272   q = y1 - t * x1;
                                                   >> 1273 
                                                   >> 1274   threadLocalData.Get().particle_energy = (rndm - q) / t;
1282                                                  1275 
1283   // Now interpolate in that bin to find the  << 1276   if (verbosityLevel >= 1) {
1284   //                                          << 1277     G4cout << "Energy is " << threadLocalData.Get().particle_energy << G4endl;
1285   G4double x1, x2, y1, y2, t, q;              << 1278   }
1286   x1 = CP_x->at(nbelow);                      << 
1287   if(nbelow+1 == static_cast<G4int>(CP_x->siz << 
1288   {                                           << 
1289     x2 = CP_x->back();                        << 
1290   }                                           << 
1291   else                                        << 
1292   {                                           << 
1293     x2 = CP_x->at(nbelow + 1);                << 
1294   }                                           << 
1295   y1 = CPHist->at(nbelow);                    << 
1296   if(nbelow+1 == static_cast<G4int>(CPHist->s << 
1297   {                                           << 
1298     G4cout << CPHist->back() << G4endl;       << 
1299     y2 = CPHist->back();                      << 
1300   }                                           << 
1301   else                                        << 
1302   {                                           << 
1303     y2 = CPHist->at(nbelow + 1);              << 
1304   }                                           << 
1305   t = (y2 - y1) / (x2 - x1);                  << 
1306   q = y1 - t * x1;                            << 
1307                                               << 
1308   threadLocalData.Get().particle_energy = (rn << 
1309                                               << 
1310   if (verbosityLevel >= 1)                    << 
1311   {                                           << 
1312     G4cout << "Energy is " << threadLocalData << 
1313   }                                           << 
1314 }                                                1279 }
1315                                                  1280 
1316 void G4SPSEneDistribution::GenerateBiasPowEne << 1281 void G4SPSEneDistribution::GenerateBiasPowEnergies()//G4double& ene,G4double& wweight)
1317 {                                                1282 {
1318   // Method to generate particle energies dis    1283   // Method to generate particle energies distributed as
1319   // in biased power-law and calculate its we    1284   // in biased power-law and calculate its weight
1320                                                  1285     
1321   threadLocal_t& params = threadLocalData.Get << 1286     threadLocal_t& params = threadLocalData.Get();
1322                                                  1287     
1323   G4double rndm;                              << 1288     G4double rndm;
1324   G4double emina, emaxa, emin, emax;          << 1289     G4double emina, emaxa, emin, emax;
1325                                               << 
1326   G4double normal = 1.;                       << 
1327                                               << 
1328   emin = params.Emin;                         << 
1329   emax = params.Emax;                         << 
1330                                               << 
1331   rndm = eneRndm->GenRandEnergy();            << 
1332                                               << 
1333   if (biasalpha != -1.)                       << 
1334   {                                           << 
1335     emina = std::pow(emin, biasalpha + 1);    << 
1336     emaxa = std::pow(emax, biasalpha + 1);    << 
1337     G4double ee = ((rndm * (emaxa - emina)) + << 
1338     params.particle_energy = std::pow(ee, (1. << 
1339     normal = 1./(1+biasalpha) * (emaxa - emin << 
1340   }                                           << 
1341   else                                        << 
1342   {                                           << 
1343     G4double ee = (std::log(emin) + rndm * (s << 
1344     params.particle_energy = std::exp(ee);    << 
1345     normal = std::log(emax) - std::log(emin); << 
1346   }                                           << 
1347   params.weight = GetProbability(params.parti << 
1348                 / (std::pow(params.particle_e << 
1349                                               << 
1350   if (verbosityLevel >= 1)                    << 
1351   {                                           << 
1352     G4cout << "Energy is " << params.particle << 
1353   }                                           << 
1354 }                                             << 
1355                                                  1290 
1356 void G4SPSEneDistribution::GenerateExpEnergie << 1291     G4double normal = 1.;
1357 {                                             << 
1358   // Method to generate particle energies dis << 
1359   // to an exponential curve                  << 
1360                                                  1292 
1361   G4double rndm;                              << 1293     emin = params.Emin;
                                                   >> 1294     emax = params.Emax;
                                                   >> 1295     //  if (EnergyDisType == "Arb") {
                                                   >> 1296     //  emin = ArbEmin;
                                                   >> 1297     //  emax = ArbEmax;
                                                   >> 1298     //}
1362                                                  1299 
1363   if (bArb) rndm = G4UniformRand();           << 1300     rndm = eneRndm->GenRandEnergy();
1364   else      rndm = eneRndm->GenRandEnergy();  << 
1365                                                  1301 
1366   threadLocal_t& params = threadLocalData.Get << 1302     if (biasalpha != -1.)
1367   params.particle_energy = -params.Ezero      << 1303     {
1368                          * (std::log(rndm * ( << 1304         emina = std::pow(emin, biasalpha + 1);
1369                                               << 1305         emaxa = std::pow(emax, biasalpha + 1);
1370                                            -  << 1306         G4double ee = ((rndm * (emaxa - emina)) + emina);
1371                                               << 1307         params.particle_energy = std::pow(ee, (1. / (biasalpha + 1.)));
1372                                    + std::exp << 1308         normal = 1./(1+biasalpha) * (emaxa - emina);
1373   if (verbosityLevel >= 1)                    << 1309     }
1374   {                                           << 1310     else
1375     G4cout << "Energy is " << params.particle << 1311     {
1376   }                                           << 1312         G4double ee = (std::log(emin) + rndm * (std::log(emax) - std::log(emin)));
1377 }                                             << 1313         params.particle_energy = std::exp(ee);
                                                   >> 1314         normal = std::log(emax) - std::log(emin) ;
                                                   >> 1315     }
                                                   >> 1316     params.weight = GetProbability(params.particle_energy)
                                                   >> 1317                       / (std::pow(params.particle_energy,biasalpha)/normal);
1378                                                  1318 
1379 void G4SPSEneDistribution::GenerateBremEnergi << 1319     if (verbosityLevel >= 1)
1380 {                                             << 1320     {
1381   // Method to generate particle energies dis << 1321         G4cout << "Energy is " << params.particle_energy << G4endl;
1382   // to a Bremstrahlung equation of the form  << 1322     }
1383   // I = const*((kT)**1/2)*E*(e**(-E/kT))     << 
1384                                               << 
1385   G4double rndm = eneRndm->GenRandEnergy();   << 
1386   G4double expmax, expmin, k;                 << 
1387                                               << 
1388   k = 8.6181e-11; // Boltzmann's const in MeV << 
1389   G4double ksq = std::pow(k, 2.); // k square << 
1390   G4double Tsq = std::pow(Temp, 2.); // Temp  << 
1391                                               << 
1392   threadLocal_t& params = threadLocalData.Get << 
1393                                               << 
1394   expmax = std::exp(-params.Emax / (k * Temp) << 
1395   expmin = std::exp(-params.Emin / (k * Temp) << 
1396                                               << 
1397   // If either expmax or expmin are zero then << 
1398   // Most probably this will be because T is  << 
1399                                               << 
1400   if (expmax == 0.)                           << 
1401   {                                           << 
1402     G4Exception("G4SPSEneDistribution::Genera << 
1403                 "Event0302", FatalException,  << 
1404                 "*****EXPMAX=0. Choose differ << 
1405   }                                           << 
1406   if (expmin == 0.)                           << 
1407   {                                           << 
1408     G4Exception("G4SPSEneDistribution::Genera << 
1409                 "Event0302", FatalException,  << 
1410                 "*****EXPMIN=0. Choose differ << 
1411   }                                           << 
1412                                               << 
1413   G4double tempvar = rndm * ((-k) * Temp * (p << 
1414                                           - p << 
1415                           - (ksq * Tsq * (exp << 
1416                                               << 
1417   G4double bigc = (tempvar - k * Temp * param << 
1418                  - ksq * Tsq * expmin) / (-k  << 
1419                                               << 
1420   // This gives an equation of form: Ee(-E/kT << 
1421   // Solve this iteratively, step from Emin t << 
1422   // and take the best solution.              << 
1423                                               << 
1424   G4double erange = params.Emax - params.Emin << 
1425   G4double steps = erange / 1000.;            << 
1426   G4int i;                                    << 
1427   G4double etest, diff, err = 100000.;        << 
1428                                               << 
1429   for (i = 1; i < 1000; ++i)                  << 
1430   {                                           << 
1431     etest = params.Emin + (i - 1) * steps;    << 
1432     diff = etest * (std::exp(-etest / (k * Te << 
1433          + k * Temp * (std::exp(-etest / (k * << 
1434                                               << 
1435     if (diff < 0.)                            << 
1436     {                                         << 
1437       diff = -diff;                           << 
1438     }                                         << 
1439                                               << 
1440     if (diff < err)                           << 
1441     {                                         << 
1442       err = diff;                             << 
1443       params.particle_energy = etest;         << 
1444     }                                         << 
1445   }                                           << 
1446   if (verbosityLevel >= 1)                    << 
1447   {                                           << 
1448     G4cout << "Energy is " << params.particle << 
1449   }                                           << 
1450 }                                                1323 }
1451                                                  1324 
1452 void G4SPSEneDistribution::GenerateBbodyEnerg << 1325 void G4SPSEneDistribution::GenerateExpEnergies(G4bool bArb = false)
1453 {                                                1326 {
1454   // BBody_x holds Energies, and BBHist holds << 1327   // Method to generate particle energies distributed according
1455   // Binary search to find correct bin then l << 1328   // to an exponential curve.
1456   // Use the earlier defined histogram + Rand << 1329   G4double rndm;
1457   // random numbers following the histos dist << 
1458                                               << 
1459   G4double rndm = eneRndm->GenRandEnergy();   << 
1460   G4int nabove = 10001, nbelow = 0, middle;   << 
1461                                               << 
1462   G4AutoLock l(&mutex);                       << 
1463   G4bool done = BBhistCalcd;                  << 
1464   l.unlock();                                 << 
1465                                               << 
1466   if(!done)                                   << 
1467   {                                           << 
1468     Calculate(); //This is has a lock inside, << 
1469     l.lock();                                 << 
1470     BBhistCalcd = true;                       << 
1471     l.unlock();                               << 
1472   }                                           << 
1473                                                  1330 
1474   // Binary search to find bin that rndm is i << 1331   if (bArb)
1475   //                                          << 
1476   while (nabove - nbelow > 1)                 << 
1477   {                                           << 
1478     middle = (nabove + nbelow) / 2;           << 
1479     if (rndm == BBHist->at(middle))           << 
1480     {                                            1332     {
1481       break;                                  << 1333     rndm = G4UniformRand();
1482     }                                            1334     }
1483     if (rndm < BBHist->at(middle))            << 1335   else
1484     {                                            1336     {
1485       nabove = middle;                        << 1337     rndm = eneRndm->GenRandEnergy();
1486     }                                            1338     }
1487     else                                      << 1339 
                                                   >> 1340     threadLocal_t& params = threadLocalData.Get();
                                                   >> 1341   params.particle_energy = -params.Ezero * (std::log(rndm * (std::exp(-params.Emax / params.Ezero) - std::exp(-params.Emin / params.Ezero)) + std::exp(-params.Emin / params.Ezero)));
                                                   >> 1342   if (verbosityLevel >= 1)
1488     {                                            1343     {
1489       nbelow = middle;                        << 1344     G4cout << "Energy is " << params.particle_energy  << G4endl;
1490     }                                            1345     }
1491   }                                           << 
1492                                               << 
1493   // Now interpolate in that bin to find the  << 
1494   //                                          << 
1495   G4double x1, x2, y1, y2, t, q;              << 
1496   x1 = Bbody_x->at(nbelow);                   << 
1497                                               << 
1498   if(nbelow+1 == static_cast<G4int>(Bbody_x-> << 
1499   {                                           << 
1500     x2 = Bbody_x->back();                     << 
1501   }                                           << 
1502   else                                        << 
1503   {                                           << 
1504     x2 = Bbody_x->at(nbelow + 1);             << 
1505   }                                           << 
1506   y1 = BBHist->at(nbelow);                    << 
1507   if(nbelow+1 == static_cast<G4int>(BBHist->s << 
1508   {                                           << 
1509     G4cout << BBHist->back() << G4endl;       << 
1510     y2 = BBHist->back();                      << 
1511   }                                           << 
1512   else                                        << 
1513   {                                           << 
1514     y2 = BBHist->at(nbelow + 1);              << 
1515   }                                           << 
1516   t = (y2 - y1) / (x2 - x1);                  << 
1517   q = y1 - t * x1;                            << 
1518                                               << 
1519   threadLocalData.Get().particle_energy = (rn << 
1520                                               << 
1521   if (verbosityLevel >= 1)                    << 
1522   {                                           << 
1523     G4cout << "Energy is " << threadLocalData << 
1524   }                                           << 
1525 }                                             << 
1526                                               << 
1527 void G4SPSEneDistribution::GenerateCdgEnergie << 
1528 {                                             << 
1529   // Generate random numbers, compare with va << 
1530   // to find appropriate part of spectrum and << 
1531   // generate energy in the usual inversion w << 
1532                                               << 
1533   G4double rndm, rndm2;                       << 
1534   G4double ene_line[3]={0,0,0};               << 
1535   G4double omalpha[2]={0,0};                  << 
1536   threadLocal_t& params = threadLocalData.Get << 
1537   if (params.Emin < 18 * keV && params.Emax < << 
1538   {                                           << 
1539     omalpha[0] = 1. - 1.4;                    << 
1540     ene_line[0] = params.Emin;                << 
1541     ene_line[1] = params.Emax;                << 
1542   }                                           << 
1543   if (params.Emin < 18 * keV && params.Emax > << 
1544   {                                           << 
1545     omalpha[0] = 1. - 1.4;                    << 
1546     omalpha[1] = 1. - 2.3;                    << 
1547     ene_line[0] = params.Emin;                << 
1548     ene_line[1] = 18. * keV;                  << 
1549     ene_line[2] = params.Emax;                << 
1550   }                                           << 
1551   if (params.Emin > 18 * keV)                 << 
1552   {                                           << 
1553     omalpha[0] = 1. - 2.3;                    << 
1554     ene_line[0] = params.Emin;                << 
1555     ene_line[1] = params.Emax;                << 
1556   }                                           << 
1557   rndm = eneRndm->GenRandEnergy();            << 
1558   rndm2 = eneRndm->GenRandEnergy();           << 
1559                                               << 
1560   G4int i = 0;                                << 
1561   while (rndm >= CDGhist[i])                  << 
1562   {                                           << 
1563     ++i;                                      << 
1564   }                                           << 
1565                                               << 
1566   // Generate final energy                    << 
1567   //                                          << 
1568   G4double ene = (std::pow(ene_line[i - 1], o << 
1569                + (std::pow(ene_line[i], omalp << 
1570                 - std::pow(ene_line[i - 1], o << 
1571   params.particle_energy = std::pow(ene, (1.  << 
1572                                               << 
1573   if (verbosityLevel >= 1)                    << 
1574   {                                           << 
1575     G4cout << "Energy is " << params.particle << 
1576   }                                           << 
1577 }                                                1346 }
1578                                                  1347 
1579 void G4SPSEneDistribution::GenUserHistEnergie << 1348 void G4SPSEneDistribution::GenerateBremEnergies()
1580 {                                                1349 {
1581   // Histograms are DIFFERENTIAL              << 1350   // Method to generate particle energies distributed according
                                                   >> 1351   // to a Bremstrahlung equation of
                                                   >> 1352   // form I = const*((kT)**1/2)*E*(e**(-E/kT))
                                                   >> 1353 
                                                   >> 1354   G4double rndm;
                                                   >> 1355   rndm = eneRndm->GenRandEnergy();
                                                   >> 1356   G4double expmax, expmin, k;
                                                   >> 1357     
                                                   >> 1358   k = 8.6181e-11; // Boltzmann's const in MeV/K
                                                   >> 1359   G4double ksq = std::pow(k, 2.); // k squared
                                                   >> 1360   G4double Tsq = std::pow(Temp, 2.); // Temp squared
1582                                                  1361 
1583   G4AutoLock l(&mutex);                       << 1362     threadLocal_t& params = threadLocalData.Get();
1584                                                  1363 
1585   if (!IPDFEnergyExist)                       << 1364   expmax = std::exp(-params.Emax / (k * Temp));
1586   {                                           << 1365   expmin = std::exp(-params.Emin / (k * Temp));
1587     std::size_t ii;                           << 
1588     std::size_t maxbin = UDefEnergyH.GetVecto << 
1589     G4double bins[1024], vals[1024], sum;     << 
1590     for ( ii = 0 ; ii<1024 ; ++ii ) { bins[ii << 
1591     sum = 0.;                                 << 
1592                                                  1366 
1593     if ( (!EnergySpec)                        << 1367   // If either expmax or expmin are zero then this will cause problems
1594       && (threadLocalData.Get().particle_defi << 1368   // Most probably this will be because T is too low or E is too high
1595     {                                         << 
1596       G4Exception("G4SPSEneDistribution::GenU << 
1597                   "Event0302", FatalException << 
1598                   "Error: particle definition << 
1599     }                                         << 
1600                                                  1369 
1601     if (maxbin > 1024)                        << 1370   if (expmax == 0.)
1602     {                                            1371     {
1603       G4Exception("G4SPSEneDistribution::GenU << 1372         G4Exception("G4SPSEneDistribution::GenerateBremEnergies",
1604                   "Event0302", JustWarning,   << 1373                     "Event0302",FatalException,
1605                  "Maxbin>1024\n Setting maxbi << 1374               "*****EXPMAX=0. Choose different E's or Temp");
1606       maxbin = 1024;                          << 
1607     }                                            1375     }
1608                                               << 1376   if (expmin == 0.)
1609     if (!DiffSpec)                            << 
1610     {                                            1377     {
1611       G4cout << "Histograms are Differential! << 1378         G4Exception("G4SPSEneDistribution::GenerateBremEnergies",
                                                   >> 1379                     "Event0302",FatalException,
                                                   >> 1380               "*****EXPMIN=0. Choose different E's or Temp");
1612     }                                            1381     }
1613     else                                      << 
1614     {                                         << 
1615       bins[0] = UDefEnergyH.GetLowEdgeEnergy( << 
1616       vals[0] = UDefEnergyH(0);               << 
1617       sum = vals[0];                          << 
1618       for (ii = 1; ii < maxbin; ++ii)         << 
1619       {                                       << 
1620         bins[ii] = UDefEnergyH.GetLowEdgeEner << 
1621         vals[ii] = UDefEnergyH(ii) + vals[ii  << 
1622         sum = sum + UDefEnergyH(ii);          << 
1623       }                                       << 
1624     }                                         << 
1625                                               << 
1626     if (!EnergySpec)                          << 
1627     {                                         << 
1628       G4double mass = threadLocalData.Get().p << 
1629                                               << 
1630       // Multiply the function (vals) up by t << 
1631       // to make the function counts/s (i.e.  << 
1632                                               << 
1633       for (ii = 1; ii < maxbin; ++ii)         << 
1634       {                                       << 
1635         vals[ii] = vals[ii] * (bins[ii] - bin << 
1636       }                                       << 
1637                                               << 
1638       // Put energy bins into new histo, plus << 
1639       // to make evals counts/s/energy        << 
1640       //                                      << 
1641       for (ii = 0; ii < maxbin; ++ii)         << 
1642       {                                       << 
1643         // kinetic energy                     << 
1644         //                                    << 
1645         bins[ii] = std::sqrt((bins[ii]*bins[i << 
1646       }                                       << 
1647       for (ii = 1; ii < maxbin; ++ii)         << 
1648       {                                       << 
1649         vals[ii] = vals[ii] / (bins[ii] - bin << 
1650       }                                       << 
1651       sum = vals[maxbin - 1];                 << 
1652       vals[0] = 0.;                           << 
1653     }                                         << 
1654     for (ii = 0; ii < maxbin; ++ii)           << 
1655     {                                         << 
1656       vals[ii] = vals[ii] / sum;              << 
1657       IPDFEnergyH.InsertValues(bins[ii], vals << 
1658     }                                         << 
1659                                               << 
1660     IPDFEnergyExist = true;                   << 
1661     if (verbosityLevel > 1)                   << 
1662     {                                         << 
1663       IPDFEnergyH.DumpValues();               << 
1664     }                                         << 
1665   }                                           << 
1666   l.unlock();                                 << 
1667                                               << 
1668   // IPDF has been create so carry on         << 
1669   //                                          << 
1670   G4double rndm = eneRndm->GenRandEnergy();   << 
1671   threadLocalData.Get().particle_energy= IPDF << 
1672                                               << 
1673   if (verbosityLevel >= 1)                    << 
1674   {                                           << 
1675     G4cout << "Energy is " << particle_energy << 
1676   }                                           << 
1677 }                                             << 
1678                                               << 
1679 G4double G4SPSEneDistribution::GetArbEneWeigh << 
1680 {                                             << 
1681   auto nbelow = IPDFArbEnergyH.FindBin(ene,(I << 
1682   G4double wei = 0.;                          << 
1683   if(IntType=="Lin")                          << 
1684   {                                           << 
1685     // note: grad[i] and cept[i] are calculat << 
1686     auto gr = Arb_grad[nbelow + 1];           << 
1687     auto ce = Arb_cept[nbelow + 1];           << 
1688     wei = ene*gr + ce;                        << 
1689   }                                           << 
1690   else if(IntType=="Log")                     << 
1691   {                                           << 
1692     auto alp = Arb_alpha[nbelow + 1];         << 
1693     auto cns = Arb_Const[nbelow + 1];         << 
1694     wei = cns * std::pow(ene,alp);            << 
1695   }                                           << 
1696   else if(IntType=="Exp")                     << 
1697   {                                           << 
1698     auto e0 = Arb_ezero[nbelow + 1];          << 
1699     auto cns = Arb_Const[nbelow + 1];         << 
1700     wei = cns * std::exp(-ene/e0);            << 
1701   }                                           << 
1702   else if(IntType=="Spline")                  << 
1703   {                                           << 
1704     wei = SplineInt[nbelow+1]->CubicSplineInt << 
1705   }                                           << 
1706   return wei;                                 << 
1707 }                                             << 
1708                                                  1382 
1709 void G4SPSEneDistribution::GenArbPointEnergie << 1383   G4double tempvar = rndm * ((-k) * Temp * (params.Emax * expmax - params.Emin * expmin) - (ksq * Tsq * (expmax - expmin)));
1710 {                                             << 1384 
1711   if (verbosityLevel > 0)                     << 1385   G4double bigc = (tempvar - k * Temp * params.Emin * expmin - ksq * Tsq * expmin) / (-k * Temp);
1712   {                                           << 1386 
1713     G4cout << "In GenArbPointEnergies" << G4e << 1387   // This gives an equation of form: Ee(-E/kT) + kTe(-E/kT) - C =0
1714   }                                           << 1388   // Solve this iteratively, step from Emin to Emax in 1000 steps
                                                   >> 1389   // and take the best solution.
                                                   >> 1390 
                                                   >> 1391   G4double erange = params.Emax - params.Emin;
                                                   >> 1392   G4double steps = erange / 1000.;
                                                   >> 1393   G4int i;
                                                   >> 1394   G4double etest, diff, err;
                                                   >> 1395 
                                                   >> 1396   err = 100000.;
                                                   >> 1397 
                                                   >> 1398   for (i = 1; i < 1000; i++)
                                                   >> 1399     {
                                                   >> 1400     etest = params.Emin + (i - 1) * steps;
1715                                                  1401 
1716   G4double rndm = eneRndm->GenRandEnergy();   << 1402     diff = etest * (std::exp(-etest / (k * Temp))) + k * Temp * (std::exp(-etest / (k * Temp))) - bigc;
1717                                                  1403 
1718   // Find the Bin, have x, y, no of points, a << 1404     if (diff < 0.)
1719   //                                          << 1405         {
1720   std::size_t nabove = IPDFArbEnergyH.GetVect << 1406       diff = -diff;
                                                   >> 1407         }
1721                                                  1408 
1722   // Binary search to find bin that rndm is i << 1409     if (diff < err)
1723   //                                          << 1410         {
1724   while (nabove - nbelow > 1)                 << 1411       err = diff;
1725   {                                           << 1412       params.particle_energy = etest;
1726     middle = (nabove + nbelow) / 2;           << 1413     }
1727     if (rndm == IPDFArbEnergyH(middle))       << 1414   }
                                                   >> 1415   if (verbosityLevel >= 1)
1728     {                                            1416     {
1729       break;                                  << 1417     G4cout << "Energy is " << params.particle_energy << G4endl;
1730     }                                            1418     }
1731     if (rndm < IPDFArbEnergyH(middle))        << 1419 }
                                                   >> 1420 
                                                   >> 1421 void G4SPSEneDistribution::GenerateBbodyEnergies()
                                                   >> 1422 {
                                                   >> 1423   // BBody_x holds Energies, and BBHist holds the cumulative histo.
                                                   >> 1424   // binary search to find correct bin then lin interpolation.
                                                   >> 1425   // Use the earlier defined histogram + RandGeneral method to generate
                                                   >> 1426   // random numbers following the histos distribution.
                                                   >> 1427   G4double rndm;
                                                   >> 1428   G4int nabove, nbelow = 0, middle;
                                                   >> 1429   nabove = 10001;
                                                   >> 1430   rndm = eneRndm->GenRandEnergy();
                                                   >> 1431     G4AutoLock l(&mutex);
                                                   >> 1432     G4bool done = BBhistCalcd;
                                                   >> 1433     l.unlock();
                                                   >> 1434     if(!done)
1732     {                                            1435     {
1733       nabove = middle;                        << 1436         Calculate(); //This is has a lock inside, risk is to do it twice
                                                   >> 1437         l.lock();
                                                   >> 1438         BBhistCalcd = true;
                                                   >> 1439         l.unlock();
                                                   >> 1440     }
                                                   >> 1441 
                                                   >> 1442   // Binary search to find bin that rndm is in
                                                   >> 1443   while (nabove - nbelow > 1)
                                                   >> 1444     {
                                                   >> 1445     middle = (nabove + nbelow) / 2;
                                                   >> 1446     if (rndm == BBHist->at(middle))
                                                   >> 1447         {
                                                   >> 1448       break;
                                                   >> 1449         }
                                                   >> 1450     if (rndm < BBHist->at(middle))
                                                   >> 1451         {
                                                   >> 1452       nabove = middle;
                                                   >> 1453         }
                                                   >> 1454     else
                                                   >> 1455         {
                                                   >> 1456       nbelow = middle;
                                                   >> 1457         }
                                                   >> 1458   }
                                                   >> 1459 
                                                   >> 1460   // Now interpolate in that bin to find the correct output value.
                                                   >> 1461   G4double x1, x2, y1, y2, t, q;
                                                   >> 1462   x1 = Bbody_x->at(nbelow);
                                                   >> 1463     if(nbelow+1 == static_cast<G4int>(Bbody_x->size()))
                                                   >> 1464     {
                                                   >> 1465         x2 = Bbody_x->back();
1734     }                                            1466     }
1735     else                                         1467     else
1736     {                                            1468     {
1737       nbelow = middle;                        << 1469         x2 = Bbody_x->at(nbelow + 1);
1738     }                                            1470     }
1739   }                                           << 1471   y1 = BBHist->at(nbelow);
1740   threadLocal_t& params = threadLocalData.Get << 1472     if(nbelow+1 == static_cast<G4int>(BBHist->size()))
1741   if (IntType == "Lin")                       << 
1742   {                                           << 
1743     // Update thread-local copy of parameters << 
1744     //                                        << 
1745     params.Emax = IPDFArbEnergyH.GetLowEdgeEn << 
1746     params.Emin = IPDFArbEnergyH.GetLowEdgeEn << 
1747     params.grad = Arb_grad[nbelow + 1];       << 
1748     params.cept = Arb_cept[nbelow + 1];       << 
1749     GenerateLinearEnergies(true);             << 
1750   }                                           << 
1751   else if (IntType == "Log")                  << 
1752   {                                           << 
1753     params.Emax = IPDFArbEnergyH.GetLowEdgeEn << 
1754     params.Emin = IPDFArbEnergyH.GetLowEdgeEn << 
1755     params.alpha = Arb_alpha[nbelow + 1];     << 
1756     GeneratePowEnergies(true);                << 
1757   }                                           << 
1758   else if (IntType == "Exp")                  << 
1759   {                                           << 
1760     params.Emax = IPDFArbEnergyH.GetLowEdgeEn << 
1761     params.Emin = IPDFArbEnergyH.GetLowEdgeEn << 
1762     params.Ezero = Arb_ezero[nbelow + 1];     << 
1763     GenerateExpEnergies(true);                << 
1764   }                                           << 
1765   else if (IntType == "Spline")               << 
1766   {                                           << 
1767     params.Emax = IPDFArbEnergyH.GetLowEdgeEn << 
1768     params.Emin = IPDFArbEnergyH.GetLowEdgeEn << 
1769     params.particle_energy = -1e100;          << 
1770     rndm = eneRndm->GenRandEnergy();          << 
1771     while (params.particle_energy < params.Em << 
1772         || params.particle_energy > params.Em << 
1773     {                                            1473     {
1774       params.particle_energy =                << 1474         G4cout << BBHist->back() << G4endl;
1775         SplineInt[nbelow+1]->CubicSplineInter << 1475         y2 = BBHist->back();
1776       rndm = eneRndm->GenRandEnergy();        << 
1777     }                                            1476     }
1778     if (verbosityLevel >= 1)                  << 1477     else
1779     {                                            1478     {
1780       G4cout << "Energy is " << params.partic << 1479         y2 = BBHist->at(nbelow + 1);
1781     }                                         << 
1782   }                                           << 
1783   else                                        << 
1784   {                                           << 
1785     G4Exception("G4SPSEneDistribution::GenArb << 
1786                 FatalException, "Error: IntTy << 
1787   }                                           << 
1788 }                                             << 
1789                                               << 
1790 void G4SPSEneDistribution::GenEpnHistEnergies << 
1791 {                                             << 
1792   // Firstly convert to energy if not already << 
1793                                               << 
1794   G4AutoLock l(&mutex);                       << 
1795                                               << 
1796   if (Epnflag)  // true means spectrum is epn << 
1797   {                                           << 
1798     // Convert to energy by multiplying by A  << 
1799     //                                        << 
1800     ConvertEPNToEnergy();                     << 
1801   }                                           << 
1802   if (!IPDFEnergyExist)                       << 
1803   {                                           << 
1804     // IPDF has not been created, so create i << 
1805     //                                        << 
1806     G4double bins[1024], vals[1024], sum;     << 
1807     std::size_t ii;                           << 
1808     std::size_t maxbin = UDefEnergyH.GetVecto << 
1809     bins[0] = UDefEnergyH.GetLowEdgeEnergy(0) << 
1810     vals[0] = UDefEnergyH(0);                 << 
1811     sum = vals[0];                            << 
1812     for (ii = 1; ii < maxbin; ++ii)           << 
1813     {                                         << 
1814       bins[ii] = UDefEnergyH.GetLowEdgeEnergy << 
1815       vals[ii] = UDefEnergyH(ii) + vals[ii -  << 
1816       sum = sum + UDefEnergyH(ii);            << 
1817     }                                            1480     }
                                                   >> 1481   t = (y2 - y1) / (x2 - x1);
                                                   >> 1482   q = y1 - t * x1;
1818                                                  1483 
1819     l.lock();                                 << 1484   threadLocalData.Get().particle_energy = (rndm - q) / t;
1820     for (ii = 0; ii < maxbin; ++ii)           << 
1821     {                                         << 
1822       vals[ii] = vals[ii] / sum;              << 
1823       IPDFEnergyH.InsertValues(bins[ii], vals << 
1824     }                                         << 
1825     IPDFEnergyExist = true;                   << 
1826                                               << 
1827   }                                           << 
1828   l.unlock();                                 << 
1829                                                  1485 
1830   // IPDF has been create so carry on         << 1486   if (verbosityLevel >= 1) {
1831   //                                          << 1487     G4cout << "Energy is " << threadLocalData.Get().particle_energy << G4endl;
1832   G4double rndm = eneRndm->GenRandEnergy();   << 1488   }
1833   threadLocalData.Get().particle_energy = IPD << 1489 }
                                                   >> 1490 
                                                   >> 1491 void G4SPSEneDistribution::GenerateCdgEnergies() {
                                                   >> 1492   // Gen random numbers, compare with values in cumhist
                                                   >> 1493   // to find appropriate part of spectrum and then
                                                   >> 1494   // generate energy in the usual inversion way.
                                                   >> 1495   //  G4double pfact[2] = {8.5, 112};
                                                   >> 1496   // G4double spind[2] = {1.4, 2.3};
                                                   >> 1497   // G4double ene_line[3] = {1., 18., 1E6};
                                                   >> 1498   G4double rndm, rndm2;
                                                   >> 1499   G4double ene_line[3]={0,0,0};
                                                   >> 1500   G4double omalpha[2]={0,0};
                                                   >> 1501     threadLocal_t& params = threadLocalData.Get();
                                                   >> 1502   if (params.Emin < 18 * keV && params.Emax < 18 * keV)
                                                   >> 1503     {
                                                   >> 1504     omalpha[0] = 1. - 1.4;
                                                   >> 1505     ene_line[0] = params.Emin;
                                                   >> 1506     ene_line[1] = params.Emax;
                                                   >> 1507   }
                                                   >> 1508   if (params.Emin < 18 * keV && params.Emax > 18 * keV)
                                                   >> 1509     {
                                                   >> 1510     omalpha[0] = 1. - 1.4;
                                                   >> 1511     omalpha[1] = 1. - 2.3;
                                                   >> 1512     ene_line[0] = params.Emin;
                                                   >> 1513     ene_line[1] = 18. * keV;
                                                   >> 1514     ene_line[2] = params.Emax;
                                                   >> 1515   }
                                                   >> 1516   if (params.Emin > 18 * keV)
                                                   >> 1517     {
                                                   >> 1518     omalpha[0] = 1. - 2.3;
                                                   >> 1519     ene_line[0] = params.Emin;
                                                   >> 1520     ene_line[1] = params.Emax;
                                                   >> 1521   }
                                                   >> 1522   rndm = eneRndm->GenRandEnergy();
                                                   >> 1523   rndm2 = eneRndm->GenRandEnergy();
                                                   >> 1524 
                                                   >> 1525   G4int i = 0;
                                                   >> 1526   while (rndm >= CDGhist[i])
                                                   >> 1527     {
                                                   >> 1528     i++;
                                                   >> 1529   }
                                                   >> 1530   // Generate final energy.
                                                   >> 1531   G4double ene = (std::pow(ene_line[i - 1], omalpha[i - 1]) + (std::pow(ene_line[i], omalpha[i - 1]) - std::pow(ene_line[i - 1], omalpha[i- 1])) * rndm2);
                                                   >> 1532   params.particle_energy = std::pow(ene, (1. / omalpha[i - 1]));
1834                                                  1533 
1835   if (verbosityLevel >= 1)                    << 1534   if (verbosityLevel >= 1)
1836   {                                           << 1535     {
1837     G4cout << "Energy is " << threadLocalData << 1536     G4cout << "Energy is " << params.particle_energy << G4endl;
1838   }                                           << 1537     }
1839 }                                                1538 }
1840                                                  1539 
1841 void G4SPSEneDistribution::ConvertEPNToEnergy << 1540 void G4SPSEneDistribution::GenUserHistEnergies()
1842 {                                                1541 {
1843   // Use this before particle generation to c << 1542   // Histograms are DIFFERENTIAL.
1844   // currently stored histogram from energy/n << 1543   //  G4cout << "In GenUserHistEnergies " << G4endl;
1845                                               << 1544     G4AutoLock l(&mutex);
1846   threadLocal_t& params = threadLocalData.Get << 1545   if (IPDFEnergyExist == false)
1847   if (params.particle_definition == nullptr)  << 1546     {
1848   {                                           << 1547     G4int ii;
1849     G4cout << "Error: particle not defined" < << 1548     G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
1850   }                                           << 1549     G4double bins[1024], vals[1024], sum;
1851   else                                        << 1550     for ( ii = 0 ; ii<1024 ; ++ii ) { bins[ii]=0; vals[ii]=0; }
1852   {                                           << 1551     sum = 0.;
1853     // Need to multiply histogram by the numb << 1552 
1854     // Baryon Number looks to hold the no. of << 1553     if ((EnergySpec == false) && (threadLocalData.Get().particle_definition == NULL))
1855     //                                        << 1554         {
1856     G4int Bary = params.particle_definition-> << 1555             G4Exception("G4SPSEneDistribution::GenUserHistEnergies",
                                                   >> 1556                         "Event0302",FatalException,
                                                   >> 1557                         "Error: particle definition is NULL");
                                                   >> 1558         }
                                                   >> 1559 
                                                   >> 1560     if (maxbin > 1024)
                                                   >> 1561         {
                                                   >> 1562             G4Exception("G4SPSEneDistribution::GenUserHistEnergies",
                                                   >> 1563                         "Event0302",JustWarning,"Maxbin>1024\n Setting maxbin to 1024, other bins are lost");
                                                   >> 1564             maxbin = 1024;
                                                   >> 1565     }
                                                   >> 1566 
                                                   >> 1567     if (DiffSpec == false)
                                                   >> 1568         {
                                                   >> 1569       G4cout << "Histograms are Differential!!! " << G4endl;
                                                   >> 1570         }
                                                   >> 1571     else
                                                   >> 1572         {
                                                   >> 1573       bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
                                                   >> 1574       vals[0] = UDefEnergyH(size_t(0));
                                                   >> 1575       sum = vals[0];
                                                   >> 1576       for (ii = 1; ii < maxbin; ii++)
                                                   >> 1577             {
                                                   >> 1578         bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
                                                   >> 1579         vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii - 1];
                                                   >> 1580         sum = sum + UDefEnergyH(size_t(ii));
                                                   >> 1581       }
                                                   >> 1582     }
                                                   >> 1583 
                                                   >> 1584     if (EnergySpec == false)
                                                   >> 1585         {
                                                   >> 1586       G4double mass = threadLocalData.Get().particle_definition->GetPDGMass();
                                                   >> 1587       // multiply the function (vals) up by the bin width
                                                   >> 1588       // to make the function counts/s (i.e. get rid of momentum
                                                   >> 1589       // dependence).
                                                   >> 1590       for (ii = 1; ii < maxbin; ii++)
                                                   >> 1591             {
                                                   >> 1592         vals[ii] = vals[ii] * (bins[ii] - bins[ii - 1]);
                                                   >> 1593       }
                                                   >> 1594       // Put energy bins into new histo, plus divide by energy bin width
                                                   >> 1595       // to make evals counts/s/energy
                                                   >> 1596       for (ii = 0; ii < maxbin; ii++)
                                                   >> 1597             {
                                                   >> 1598         bins[ii] = std::sqrt((bins[ii] * bins[ii]) + (mass * mass))- mass; //kinetic energy
                                                   >> 1599       }
                                                   >> 1600       for (ii = 1; ii < maxbin; ii++)
                                                   >> 1601             {
                                                   >> 1602         vals[ii] = vals[ii] / (bins[ii] - bins[ii - 1]);
                                                   >> 1603       }
                                                   >> 1604       sum = vals[maxbin - 1];
                                                   >> 1605       vals[0] = 0.;
                                                   >> 1606     }
                                                   >> 1607     for (ii = 0; ii < maxbin; ii++)
                                                   >> 1608         {
                                                   >> 1609       vals[ii] = vals[ii] / sum;
                                                   >> 1610       IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
                                                   >> 1611     }
                                                   >> 1612 
                                                   >> 1613     // Make IPDFEnergyExist = true
                                                   >> 1614     IPDFEnergyExist = true;
                                                   >> 1615     if (verbosityLevel > 1)
                                                   >> 1616         {
                                                   >> 1617       IPDFEnergyH.DumpValues();
                                                   >> 1618         }
                                                   >> 1619   }
                                                   >> 1620     l.unlock();
                                                   >> 1621     
                                                   >> 1622   // IPDF has been create so carry on
                                                   >> 1623   G4double rndm = eneRndm->GenRandEnergy();
                                                   >> 1624   threadLocalData.Get().particle_energy= IPDFEnergyH.GetEnergy(rndm);
1857                                                  1625 
1858     // Change values in histogram, Read it ou << 1626   if (verbosityLevel >= 1)
1859     //                                        << 
1860     std::size_t count, maxcount;              << 
1861     maxcount = EpnEnergyH.GetVectorLength();  << 
1862     G4double ebins[1024], evals[1024];        << 
1863     if (maxcount > 1024)                      << 
1864     {                                            1627     {
1865       G4Exception("G4SPSEneDistribution::Conv << 1628     G4cout << "Energy is " << particle_energy << G4endl;
1866                   "gps001", JustWarning,      << 
1867                   "Histogram contains more th << 
1868                    Those above 1024 will be i << 
1869       maxcount = 1024;                        << 
1870     }                                            1629     }
1871     if (maxcount < 1)                         << 1630 }
                                                   >> 1631 
                                                   >> 1632 void G4SPSEneDistribution::GenArbPointEnergies()
                                                   >> 1633 {
                                                   >> 1634   if (verbosityLevel > 0)
1872     {                                            1635     {
1873       G4Exception("G4SPSEneDistribution::Conv << 1636     G4cout << "In GenArbPointEnergies" << G4endl;
1874                  "gps001", FatalException,    << 
1875                  "Histogram contains less tha << 
1876       return;                                 << 
1877     }                                            1637     }
1878     for (count = 0; count < maxcount; ++count << 1638   G4double rndm;
                                                   >> 1639   rndm = eneRndm->GenRandEnergy();
                                                   >> 1640   //      IPDFArbEnergyH.DumpValues();
                                                   >> 1641   // Find the Bin
                                                   >> 1642   // have x, y, no of points, and cumulative area distribution
                                                   >> 1643   G4int nabove, nbelow = 0, middle;
                                                   >> 1644   nabove = IPDFArbEnergyH.GetVectorLength();
                                                   >> 1645   //      G4cout << nabove << G4endl;
                                                   >> 1646   // Binary search to find bin that rndm is in
                                                   >> 1647   while (nabove - nbelow > 1)
                                                   >> 1648     {
                                                   >> 1649         middle = (nabove + nbelow) / 2;
                                                   >> 1650         if (rndm == IPDFArbEnergyH(size_t(middle)))
                                                   >> 1651         {
                                                   >> 1652             break;
                                                   >> 1653         }
                                                   >> 1654         if (rndm < IPDFArbEnergyH(size_t(middle)))
                                                   >> 1655         {
                                                   >> 1656             nabove = middle;
                                                   >> 1657         }
                                                   >> 1658         else
                                                   >> 1659         {
                                                   >> 1660             nbelow = middle;
                                                   >> 1661         }
                                                   >> 1662   }
                                                   >> 1663     threadLocal_t& params = threadLocalData.Get();
                                                   >> 1664   if (IntType == "Lin")
                                                   >> 1665     {
                                                   >> 1666         //Update thread-local copy of parameters
                                                   >> 1667         params.Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
                                                   >> 1668         params.Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
                                                   >> 1669         params.grad = Arb_grad[nbelow + 1];
                                                   >> 1670         params.cept = Arb_cept[nbelow + 1];
                                                   >> 1671         //    G4cout << rndm << " " << Emax << " " << Emin << " " << grad << " " << cept << G4endl;
                                                   >> 1672         GenerateLinearEnergies(true);
                                                   >> 1673   }
                                                   >> 1674     else if (IntType == "Log")
                                                   >> 1675     {
                                                   >> 1676         params.Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
                                                   >> 1677         params.Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
                                                   >> 1678         params.alpha = Arb_alpha[nbelow + 1];
                                                   >> 1679         //    G4cout << rndm << " " << Emax << " " << Emin << " " << alpha << G4endl;
                                                   >> 1680         GeneratePowEnergies(true);
                                                   >> 1681   }
                                                   >> 1682     else if (IntType == "Exp")
                                                   >> 1683     {
                                                   >> 1684         params.Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
                                                   >> 1685         params.Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
                                                   >> 1686         params.Ezero = Arb_ezero[nbelow + 1];
                                                   >> 1687         //    G4cout << rndm << " " << Emax << " " << Emin << " " << Ezero << G4endl;
                                                   >> 1688         GenerateExpEnergies(true);
                                                   >> 1689   }
                                                   >> 1690     else if (IntType == "Spline")
                                                   >> 1691     {
                                                   >> 1692         params.Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
                                                   >> 1693         params.Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
                                                   >> 1694         params.particle_energy = -1e100;
                                                   >> 1695         rndm = eneRndm->GenRandEnergy();
                                                   >> 1696         while (params.particle_energy < params.Emin || params.particle_energy > params.Emax)
                                                   >> 1697         {
                                                   >> 1698             params.particle_energy = SplineInt[nbelow+1]->CubicSplineInterpolation(rndm);
                                                   >> 1699             rndm = eneRndm->GenRandEnergy();
                                                   >> 1700         }
                                                   >> 1701         if (verbosityLevel >= 1)
                                                   >> 1702         {
                                                   >> 1703             G4cout << "Energy is " << params.particle_energy << G4endl;
                                                   >> 1704         }
                                                   >> 1705   }
                                                   >> 1706     else
1879     {                                            1707     {
1880       // Read out                             << 1708         G4Exception("G4SPSEneDistribution::GenArbPointEnergies","Event0302",
1881       ebins[count] = EpnEnergyH.GetLowEdgeEne << 1709                     FatalException,"Error: IntType unknown type");
1882       evals[count] = EpnEnergyH(count);       << 
1883     }                                            1710     }
                                                   >> 1711 }
1884                                                  1712 
1885     // Multiply the channels by the nucleon n << 1713 void G4SPSEneDistribution::GenEpnHistEnergies() {
1886     //                                        << 1714   //  G4cout << "In GenEpnHistEnergies " << Epnflag << G4endl;
1887     for (count = 0; count < maxcount; ++count << 1715 
1888     {                                         << 1716   // Firstly convert to energy if not already done.
1889       ebins[count] = ebins[count] * Bary;     << 1717     G4AutoLock l(&mutex);
1890     }                                         << 1718   if (Epnflag == true)
                                                   >> 1719   // epnflag = true means spectrum is epn, false means e.
                                                   >> 1720   {
                                                   >> 1721     // convert to energy by multiplying by A number
                                                   >> 1722     ConvertEPNToEnergy();
                                                   >> 1723     // EpnEnergyH will be replace by UDefEnergyH.
                                                   >> 1724     //      UDefEnergyH.DumpValues();
                                                   >> 1725   }
                                                   >> 1726   if (IPDFEnergyExist == false)
                                                   >> 1727     {
                                                   >> 1728     // IPDF has not been created, so create it
                                                   >> 1729     G4double bins[1024], vals[1024], sum;
                                                   >> 1730     G4int ii;
                                                   >> 1731     G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
                                                   >> 1732     bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
                                                   >> 1733     vals[0] = UDefEnergyH(size_t(0));
                                                   >> 1734     sum = vals[0];
                                                   >> 1735     for (ii = 1; ii < maxbin; ii++)
                                                   >> 1736         {
                                                   >> 1737       bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
                                                   >> 1738       vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii - 1];
                                                   >> 1739       sum = sum + UDefEnergyH(size_t(ii));
                                                   >> 1740     }
                                                   >> 1741 
                                                   >> 1742         l.lock();
                                                   >> 1743     for (ii = 0; ii < maxbin; ii++)
                                                   >> 1744         {
                                                   >> 1745       vals[ii] = vals[ii] / sum;
                                                   >> 1746       IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
                                                   >> 1747     }
                                                   >> 1748     // Make IPDFEpnExist = true
                                                   >> 1749     IPDFEnergyExist = true;
                                                   >> 1750        
                                                   >> 1751   }
                                                   >> 1752     l.unlock();
                                                   >> 1753   //  IPDFEnergyH.DumpValues();
                                                   >> 1754   // IPDF has been create so carry on
                                                   >> 1755   G4double rndm = eneRndm->GenRandEnergy();
                                                   >> 1756   threadLocalData.Get().particle_energy = IPDFEnergyH.GetEnergy(rndm);
                                                   >> 1757 
                                                   >> 1758   if (verbosityLevel >= 1)
                                                   >> 1759     {
                                                   >> 1760     G4cout << "Energy is " << threadLocalData.Get().particle_energy << G4endl;
                                                   >> 1761     }
                                                   >> 1762 }
                                                   >> 1763 
                                                   >> 1764 //MT: lock in caller
                                                   >> 1765 void G4SPSEneDistribution::ConvertEPNToEnergy()
                                                   >> 1766 {
                                                   >> 1767   // Use this before particle generation to convert  the
                                                   >> 1768   // currently stored histogram from energy/nucleon
                                                   >> 1769   // to energy.
                                                   >> 1770   //  G4cout << "In ConvertEpntoEnergy " << G4endl;
                                                   >> 1771     threadLocal_t& params = threadLocalData.Get();
                                                   >> 1772   if (params.particle_definition == NULL)
                                                   >> 1773     {
                                                   >> 1774     G4cout << "Error: particle not defined" << G4endl;
                                                   >> 1775     }
                                                   >> 1776   else
                                                   >> 1777     {
                                                   >> 1778     // Need to multiply histogram by the number of nucleons.
                                                   >> 1779     // Baryon Number looks to hold the no. of nucleons.
                                                   >> 1780     G4int Bary = params.particle_definition->GetBaryonNumber();
                                                   >> 1781     //      G4cout << "Baryon No. " << Bary << G4endl;
                                                   >> 1782     // Change values in histogram, Read it out, delete it, re-create it
                                                   >> 1783     G4int count, maxcount;
                                                   >> 1784     maxcount = G4int(EpnEnergyH.GetVectorLength());
                                                   >> 1785     //      G4cout << maxcount << G4endl;
                                                   >> 1786     G4double ebins[1024], evals[1024];
                                                   >> 1787     if (maxcount > 1024)
                                                   >> 1788         {
                                                   >> 1789             G4Exception("G4SPSEneDistribution::ConvertEPNToEnergy()","gps001", JustWarning,
                                                   >> 1790                         "Histogram contains more than 1024 bins!\nThose above 1024 will be ignored");
                                                   >> 1791       maxcount = 1024;
                                                   >> 1792     }
                                                   >> 1793     if (maxcount < 1)
                                                   >> 1794         {
                                                   >> 1795             G4Exception("G4SPSEneDistribution::ConvertEPNToEnergy()","gps001", FatalException,"Histogram contains less than 1 bin!\nRedefine the histogram");
                                                   >> 1796       return;
                                                   >> 1797     }
                                                   >> 1798     for (count = 0; count < maxcount; count++)
                                                   >> 1799         {
                                                   >> 1800       // Read out
                                                   >> 1801       ebins[count] = EpnEnergyH.GetLowEdgeEnergy(size_t(count));
                                                   >> 1802       evals[count] = EpnEnergyH(size_t(count));
                                                   >> 1803     }
                                                   >> 1804 
                                                   >> 1805     // Multiply the channels by the nucleon number to give energies
                                                   >> 1806     for (count = 0; count < maxcount; count++)
                                                   >> 1807         {
                                                   >> 1808       ebins[count] = ebins[count] * Bary;
                                                   >> 1809     }
                                                   >> 1810 
                                                   >> 1811     // Set Emin and Emax
                                                   >> 1812     params.Emin = ebins[0];
                                                   >> 1813     if (maxcount > 1)
                                                   >> 1814         {
                                                   >> 1815       params.Emax = ebins[maxcount - 1];
                                                   >> 1816         }
                                                   >> 1817     else
                                                   >> 1818         {
                                                   >> 1819       params.Emax = ebins[0];
                                                   >> 1820         }
                                                   >> 1821     // Put energy bins into new histogram - UDefEnergyH.
                                                   >> 1822     for (count = 0; count < maxcount; count++)
                                                   >> 1823         {
                                                   >> 1824       UDefEnergyH.InsertValues(ebins[count], evals[count]);
                                                   >> 1825     }
                                                   >> 1826     Epnflag = false; //so that you dont repeat this method.
                                                   >> 1827   }
                                                   >> 1828 }
1891                                                  1829 
1892     // Set Emin and Emax                      << 1830 //
1893     //                                        << 1831 void G4SPSEneDistribution::ReSetHist(G4String atype)
1894     params.Emin = ebins[0];                   << 1832 {
1895     if (maxcount > 1)                         << 1833     G4AutoLock l(&mutex);
                                                   >> 1834   if (atype == "energy")
1896     {                                            1835     {
1897       params.Emax = ebins[maxcount - 1];      << 1836     UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
1898     }                                         << 1837     IPDFEnergyExist = false;
                                                   >> 1838     Emin = 0.;
                                                   >> 1839     Emax = 1e30;
                                                   >> 1840   }
                                                   >> 1841     else if (atype == "arb")
                                                   >> 1842     {
                                                   >> 1843     ArbEnergyH = IPDFArbEnergyH = ZeroPhysVector;
                                                   >> 1844     IPDFArbExist = false;
                                                   >> 1845   }
                                                   >> 1846     else if (atype == "epn")
                                                   >> 1847     {
                                                   >> 1848     UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
                                                   >> 1849     IPDFEnergyExist = false;
                                                   >> 1850     EpnEnergyH = ZeroPhysVector;
                                                   >> 1851   }
1899     else                                         1852     else
1900     {                                            1853     {
1901       params.Emax = ebins[0];                 << 1854     G4cout << "Error, histtype not accepted " << G4endl;
1902     }                                         << 1855   }
1903                                               << 
1904     // Put energy bins into new histogram - U << 
1905     //                                        << 
1906     for (count = 0; count < maxcount; ++count << 
1907     {                                         << 
1908       UDefEnergyH.InsertValues(ebins[count],  << 
1909     }                                         << 
1910     Epnflag = false; // so that you dont repe << 
1911   }                                           << 
1912 }                                             << 
1913                                               << 
1914 void G4SPSEneDistribution::ReSetHist(const G4 << 
1915 {                                             << 
1916   G4AutoLock l(&mutex);                       << 
1917   if (atype == "energy")                      << 
1918   {                                           << 
1919     UDefEnergyH = IPDFEnergyH = ZeroPhysVecto << 
1920     IPDFEnergyExist = false;                  << 
1921     Emin = 0.;                                << 
1922     Emax = 1e30;                              << 
1923   }                                           << 
1924   else if (atype == "arb")                    << 
1925   {                                           << 
1926     ArbEnergyH = IPDFArbEnergyH = ZeroPhysVec << 
1927     IPDFArbExist = false;                     << 
1928   }                                           << 
1929   else if (atype == "epn")                    << 
1930   {                                           << 
1931     UDefEnergyH = IPDFEnergyH = ZeroPhysVecto << 
1932     IPDFEnergyExist = false;                  << 
1933     EpnEnergyH = ZeroPhysVector;              << 
1934   }                                           << 
1935   else                                        << 
1936   {                                           << 
1937     G4cout << "Error, histtype not accepted " << 
1938   }                                           << 
1939 }                                                1856 }
1940                                                  1857 
1941 G4double G4SPSEneDistribution::GenerateOne(G4    1858 G4double G4SPSEneDistribution::GenerateOne(G4ParticleDefinition* a)
1942 {                                                1859 {
1943   // Copy global shared status to thread-loca << 1860     //Copy global shared status to thread-local one
1944   //                                          << 1861     threadLocal_t& params = threadLocalData.Get();
1945   threadLocal_t& params = threadLocalData.Get << 1862     params.particle_definition=a;
1946   params.particle_definition=a;               << 1863     params.particle_energy=-1;
1947   params.particle_energy=-1;                  << 
1948   if(applyEvergyWeight)                       << 
1949   {                                           << 
1950     params.Emax = ArbEmax;                    << 
1951     params.Emin = ArbEmin;                    << 
1952   }                                           << 
1953   else                                        << 
1954   {                                           << 
1955     params.Emax = Emax;                          1864     params.Emax = Emax;
1956     params.Emin = Emin;                          1865     params.Emin = Emin;
1957   }                                           << 1866     params.alpha = alpha;
1958   params.alpha = alpha;                       << 1867     params.Ezero = Ezero;
1959   params.Ezero = Ezero;                       << 1868     params.grad = grad;
1960   params.grad = grad;                         << 1869     params.cept = cept;
1961   params.cept = cept;                         << 1870     params.weight = weight;
1962   params.weight = weight;                     << 1871     //particle_energy = -1.;
1963   // particle_energy = -1.;                   << 1872     while ((EnergyDisType == "Arb") ? (params.particle_energy < ArbEmin || params.particle_energy > ArbEmax) : (params.particle_energy < params.Emin|| params.particle_energy > params.Emax))
1964                                               << 1873     {
1965   if((EnergyDisType == "Mono") && ((MonoEnerg << 1874         if (Biased)
1966   {                                           << 1875         {
1967     G4ExceptionDescription ed;                << 1876             GenerateBiasPowEnergies();
1968     ed << "MonoEnergy " << G4BestUnit(MonoEne << 1877         }
1969        << " is outside of [Emin,Emax] = ["    << 1878         else
1970        << G4BestUnit(Emin,"Energy") << ", "   << 1879         {
1971        << G4BestUnit(Emax,"Energy") << ". Mon << 1880       if (EnergyDisType == "Mono")
1972     G4Exception("G4SPSEneDistribution::Genera << 1881             {
1973                 "GPS0001", JustWarning, ed);  << 1882         GenerateMonoEnergetic();
1974     params.particle_energy=MonoEnergy;        << 1883             }
1975     return params.particle_energy;            << 1884       else if (EnergyDisType == "Lin")
1976   }                                           << 1885             {
1977   while ( (EnergyDisType == "Arb")            << 1886         GenerateLinearEnergies(false);
1978         ?   (params.particle_energy < ArbEmin << 1887             }
1979           || params.particle_energy > ArbEmax << 1888       else if (EnergyDisType == "Pow")
1980         :   (params.particle_energy < params. << 1889             {
1981           || params.particle_energy > params. << 1890         GeneratePowEnergies(false);
1982   {                                           << 1891             }
1983     if (Biased)                               << 1892       else if (EnergyDisType == "CPow")
1984     {                                         << 1893             {
1985       GenerateBiasPowEnergies();              << 1894         GenerateCPowEnergies();
1986     }                                         << 1895             }
1987     else                                      << 1896       else if (EnergyDisType == "Exp")
1988     {                                         << 1897             {
1989       if (EnergyDisType == "Mono")            << 1898         GenerateExpEnergies(false);
1990       {                                       << 1899             }
1991         GenerateMonoEnergetic();              << 1900       else if (EnergyDisType == "Gauss")
1992       }                                       << 1901             {
1993       else if (EnergyDisType == "Lin")        << 1902         GenerateGaussEnergies();
1994       {                                       << 1903             }
1995         GenerateLinearEnergies(false);        << 1904       else if (EnergyDisType == "Brem")
1996       }                                       << 1905             {
1997       else if (EnergyDisType == "Pow")        << 1906         GenerateBremEnergies();
1998       {                                       << 1907             }
1999         GeneratePowEnergies(false);           << 1908       else if (EnergyDisType == "Bbody")
2000       }                                       << 1909             {
2001       else if (EnergyDisType == "CPow")       << 1910         GenerateBbodyEnergies();
2002       {                                       << 1911             }
2003         GenerateCPowEnergies();               << 1912       else if (EnergyDisType == "Cdg")
2004       }                                       << 1913             {
2005       else if (EnergyDisType == "Exp")        << 1914         GenerateCdgEnergies();
2006       {                                       << 1915             }
2007         GenerateExpEnergies(false);           << 1916       else if (EnergyDisType == "User")
2008       }                                       << 1917             {
2009       else if (EnergyDisType == "Gauss")      << 1918         GenUserHistEnergies();
2010       {                                       << 1919             }
2011         GenerateGaussEnergies();              << 1920       else if (EnergyDisType == "Arb")
2012       }                                       << 1921             {
2013       else if (EnergyDisType == "Brem")       << 1922         GenArbPointEnergies();
2014       {                                       << 1923             }
2015         GenerateBremEnergies();               << 1924       else if (EnergyDisType == "Epn")
2016       }                                       << 1925             {
2017       else if (EnergyDisType == "Bbody")      << 1926         GenEpnHistEnergies();
2018       {                                       << 1927             }
2019         GenerateBbodyEnergies();              << 1928       else
2020       }                                       << 1929             {
2021       else if (EnergyDisType == "Cdg")        << 1930         G4cout << "Error: EnergyDisType has unusual value" << G4endl;
2022       {                                       << 1931             }
2023         GenerateCdgEnergies();                << 1932     }
2024       }                                       << 1933   }
2025       else if (EnergyDisType == "User")       << 1934   return params.particle_energy;
2026       {                                       << 
2027         GenUserHistEnergies();                << 
2028       }                                       << 
2029       else if (EnergyDisType == "Arb")        << 
2030       {                                       << 
2031         GenArbPointEnergies();                << 
2032       }                                       << 
2033       else if (EnergyDisType == "Epn")        << 
2034       {                                       << 
2035         GenEpnHistEnergies();                 << 
2036       }                                       << 
2037       else                                    << 
2038       {                                       << 
2039         G4cout << "Error: EnergyDisType has u << 
2040       }                                       << 
2041     }                                         << 
2042   }                                           << 
2043    return params.particle_energy;             << 
2044 }                                                1935 }
2045                                                  1936 
2046 G4double G4SPSEneDistribution::GetProbability    1937 G4double G4SPSEneDistribution::GetProbability(G4double ene)
2047 {                                                1938 {
2048   G4double prob = 1.;                         << 1939     G4double prob = 1.;
2049                                                  1940 
2050   threadLocal_t& params = threadLocalData.Get << 1941     threadLocal_t& params = threadLocalData.Get();
2051   if (EnergyDisType == "Lin")                 << 1942     if (EnergyDisType == "Lin")
2052   {                                           << 1943     {
2053     if (prob_norm == 1.)                      << 1944         if (prob_norm == 1.)
2054     {                                         << 1945         {
2055       prob_norm = 0.5*params.grad*params.Emax << 1946             prob_norm = 0.5*params.grad*params.Emax*params.Emax + params.cept*params.Emax - 0.5*params.grad*params.Emin*params.Emin - params.cept*params.Emin;
2056                 + params.cept*params.Emax     << 1947         }
2057                 - 0.5*params.grad*params.Emin << 1948         prob = params.cept + params.grad * ene;
2058                 - params.cept*params.Emin;    << 1949         prob /= prob_norm;
2059     }                                         << 1950     }
2060     prob = params.cept + params.grad * ene;   << 1951     else if (EnergyDisType == "Pow")
2061     prob /= prob_norm;                        << 1952     {
2062   }                                           << 1953         if (prob_norm == 1.)
2063   else if (EnergyDisType == "Pow")            << 1954         {
2064   {                                           << 1955             if (alpha != -1.)
2065     if (prob_norm == 1.)                      << 1956             {
2066     {                                         << 1957                 G4double emina = std::pow(params.Emin, params.alpha + 1);
2067       if (alpha != -1.)                       << 1958                 G4double emaxa = std::pow(params.Emax, params.alpha + 1);
2068       {                                       << 1959                 prob_norm = 1./(1.+alpha) * (emaxa - emina);
2069         G4double emina = std::pow(params.Emin << 1960             }
2070         G4double emaxa = std::pow(params.Emax << 1961             else
2071         prob_norm = 1./(1.+alpha) * (emaxa -  << 1962             {
2072       }                                       << 1963                 prob_norm = std::log(params.Emax) - std::log(params.Emin) ;
2073       else                                    << 1964             }
2074       {                                       << 1965         }
2075         prob_norm = std::log(params.Emax) - s << 1966         prob = std::pow(ene, params.alpha)/prob_norm;
2076       }                                       << 1967     }
2077     }                                         << 1968     else if (EnergyDisType == "Exp")
2078     prob = std::pow(ene, params.alpha)/prob_n << 1969     {
2079   }                                           << 1970         if (prob_norm == 1.)
2080   else if (EnergyDisType == "Exp")            << 1971         {
2081   {                                           << 1972             prob_norm = -params.Ezero*(std::exp(-params.Emax/params.Ezero) - std::exp(params.Emin/params.Ezero));
2082     if (prob_norm == 1.)                      << 1973         }  
2083     {                                         << 1974         prob = std::exp(-ene / params.Ezero);
2084       prob_norm = -params.Ezero*(std::exp(-pa << 1975         prob /= prob_norm;
2085                                - std::exp(par << 1976     }
2086     }                                         << 1977     else if (EnergyDisType == "Arb")
2087     prob = std::exp(-ene / params.Ezero);     << 1978     {
2088     prob /= prob_norm;                        << 1979         prob = ArbEnergyH.Value(ene);
2089   }                                           << 1980         //  prob = ArbEInt->CubicSplineInterpolation(ene);
2090   else if (EnergyDisType == "Arb")            << 1981         //G4double deltaY;
2091   {                                           << 1982         //prob = ArbEInt->PolynomInterpolation(ene, deltaY);
2092     prob = ArbEnergyH.Value(ene);             << 1983         if (prob <= 0.)
2093                                               << 1984         {
2094     if (prob <= 0.)                           << 1985             //G4cout << " Warning:G4SPSEneDistribution::GetProbability: prob<= 0. "<<prob <<" "<<ene << " " <<deltaY<< G4endl;
2095     {                                         << 1986             G4cout << " Warning:G4SPSEneDistribution::GetProbability: prob<= 0. "<<prob <<" "<<ene << G4endl;
2096       G4cout << " Warning:G4SPSEneDistributio << 1987             prob = 1e-30;
2097              << prob << " " << ene << G4endl; << 1988         }
2098       prob = 1e-30;                           << 1989         // already normalised
2099     }                                         << 1990     }
2100   }                                           << 1991   else
2101   else                                        << 1992     {
2102   {                                           << 1993     G4cout << "Error: EnergyDisType not supported" << G4endl;
2103     G4cout << "Error: EnergyDisType not suppo << 1994     }
2104   }                                           << 1995        
2105                                               << 1996   return prob;
2106   return prob;                                << 
2107 }                                                1997 }
2108                                                  1998