Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4SPSEneDistribution.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26///////////////////////////////////////////////////////////////////////////////
27//
28// MODULE: G4SPSEneDistribution.cc
29//
30// Version: 1.0
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
49
50#include "G4SystemOfUnits.hh"
51#include "Randomize.hh"
52
54 : particle_definition(0), eneRndm(0), Splinetemp(0)
55{
56 //
57 // Initialise all variables
58 particle_energy = 1.0 * MeV;
59
60 EnergyDisType = "Mono";
61 weight = 1.;
62 MonoEnergy = 1 * MeV;
63 Emin = 0.;
64 Emax = 1.e30;
65 alpha = 0.;
66 biasalpha = 0.;
67 prob_norm = 1.0;
68 Ezero = 0.;
69 SE = 0.;
70 Temp = 0.;
71 grad = 0.;
72 cept = 0.;
73 Biased = false; // not biased
74 EnergySpec = true; // true - energy spectra, false - momentum spectra
75 DiffSpec = true; // true - differential spec, false integral spec
76 IntType = "NULL"; // Interpolation type
77 IPDFEnergyExist = false;
78 IPDFArbExist = false;
79
80 ArbEmin = 0.;
81 ArbEmax = 1.e30;
82
83 verbosityLevel = 0;
84
85}
86
88}
89
91 EnergyDisType = DisType;
92 if (EnergyDisType == "User") {
93 UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
94 IPDFEnergyExist = false;
95 } else if (EnergyDisType == "Arb") {
96 ArbEnergyH = IPDFArbEnergyH = ZeroPhysVector;
97 IPDFArbExist = false;
98 } else if (EnergyDisType == "Epn") {
99 UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
100 IPDFEnergyExist = false;
101 EpnEnergyH = ZeroPhysVector;
102 }
103}
104
106 Emin = emi;
107}
108
110 Emax = ema;
111}
112
114 MonoEnergy = menergy;
115}
116
118 SE = e;
119}
121 alpha = alp;
122}
123
125 biasalpha = alp;
126 Biased = true;
127}
128
130 Temp = tem;
131}
132
134 Ezero = eze;
135}
136
138 grad = gr;
139}
140
142 cept = c;
143}
144
146 G4double ehi, val;
147 ehi = input.x();
148 val = input.y();
149 if (verbosityLevel > 1) {
150 G4cout << "In UserEnergyHisto" << G4endl;
151 G4cout << " " << ehi << " " << val << G4endl;
152 }
153 UDefEnergyH.InsertValues(ehi, val);
154 Emax = ehi;
155}
156
158 G4double ehi, val;
159 ehi = input.x();
160 val = input.y();
161 if (verbosityLevel > 1) {
162 G4cout << "In ArbEnergyHisto" << G4endl;
163 G4cout << " " << ehi << " " << val << G4endl;
164 }
165 ArbEnergyH.InsertValues(ehi, val);
166}
167
169 std::ifstream infile(filename, std::ios::in);
170 if (!infile)
171 G4Exception("G4SPSEneDistribution::ArbEnergyHistoFile",
172 "Event0301",FatalException,
173 "Unable to open the histo ASCII file");
174 G4double ehi, val;
175 while (infile >> ehi >> val) {
176 ArbEnergyH.InsertValues(ehi, val);
177 }
178}
179
181 G4double ehi, val;
182 ehi = input.x();
183 val = input.y();
184 if (verbosityLevel > 1) {
185 G4cout << "In EpnEnergyHisto" << G4endl;
186 G4cout << " " << ehi << " " << val << G4endl;
187 }
188 EpnEnergyH.InsertValues(ehi, val);
189 Emax = ehi;
190 Epnflag = true;
191}
192
194 if (EnergyDisType == "Cdg")
195 CalculateCdgSpectrum();
196 else if (EnergyDisType == "Bbody")
197 CalculateBbodySpectrum();
198}
199
200void G4SPSEneDistribution::CalculateCdgSpectrum() {
201 // This uses the spectrum from The INTEGRAL Mass Model (TIMM)
202 // to generate a Cosmic Diffuse X/gamma ray spectrum.
203 G4double pfact[2] = { 8.5, 112 };
204 G4double spind[2] = { 1.4, 2.3 };
205 G4double ene_line[3] = { 1. * keV, 18. * keV, 1E6 * keV };
206 G4int n_par;
207
208 ene_line[0] = Emin;
209 if (Emin < 18 * keV) {
210 n_par = 2;
211 ene_line[2] = Emax;
212 if (Emax < 18 * keV) {
213 n_par = 1;
214 ene_line[1] = Emax;
215 }
216 } else {
217 n_par = 1;
218 pfact[0] = 112.;
219 spind[0] = 2.3;
220 ene_line[1] = Emax;
221 }
222
223 // Create a cumulative histogram.
224 CDGhist[0] = 0.;
225 G4double omalpha;
226 G4int i = 0;
227
228 while (i < n_par) {
229 omalpha = 1. - spind[i];
230 CDGhist[i + 1] = CDGhist[i] + (pfact[i] / omalpha) * (std::pow(
231 ene_line[i + 1] / keV, omalpha) - std::pow(ene_line[i] / keV,
232 omalpha));
233 i++;
234 }
235
236 // Normalise histo and divide by 1000 to make MeV.
237 i = 0;
238 while (i < n_par) {
239 CDGhist[i + 1] = CDGhist[i + 1] / CDGhist[n_par];
240 // G4cout << CDGhist[i] << CDGhist[n_par] << G4endl;
241 i++;
242 }
243}
244
245void G4SPSEneDistribution::CalculateBbodySpectrum() {
246 // create bbody spectrum
247 // Proved very hard to integrate indefinitely, so different
248 // method. User inputs emin, emax and T. These are used to
249 // create a 10,000 bin histogram.
250 // Use photon density spectrum = 2 nu**2/c**2 * (std::exp(h nu/kT)-1)
251 // = 2 E**2/h**2c**2 times the exponential
252 G4double erange = Emax - Emin;
253 G4double steps = erange / 10000.;
254 G4double Bbody_y[10000];
255 G4double k = 8.6181e-11; //Boltzmann const in MeV/K
256 G4double h = 4.1362e-21; // Plancks const in MeV s
257 G4double c = 3e8; // Speed of light
258 G4double h2 = h * h;
259 G4double c2 = c * c;
260 G4int count = 0;
261 G4double sum = 0.;
262 BBHist[0] = 0.;
263 while (count < 10000) {
264 Bbody_x[count] = Emin + G4double(count * steps);
265 Bbody_y[count] = (2. * std::pow(Bbody_x[count], 2.)) / (h2 * c2
266 * (std::exp(Bbody_x[count] / (k * Temp)) - 1.));
267 sum = sum + Bbody_y[count];
268 BBHist[count + 1] = BBHist[count] + Bbody_y[count];
269 count++;
270 }
271
272 Bbody_x[10000] = Emax;
273 // Normalise cumulative histo.
274 count = 0;
275 while (count < 10001) {
276 BBHist[count] = BBHist[count] / sum;
277 count++;
278 }
279}
280
282 // Allows user to specifiy spectrum is momentum
283 EnergySpec = value; // false if momentum
284 if (verbosityLevel > 1)
285 G4cout << "EnergySpec has value " << EnergySpec << G4endl;
286}
287
289 // Allows user to specify integral or differential spectra
290 DiffSpec = value; // true = differential, false = integral
291 if (verbosityLevel > 1)
292 G4cout << "Diffspec has value " << DiffSpec << G4endl;
293}
294
296 if (EnergyDisType != "Arb")
297 G4cout << "Error: this is for arbitrary distributions" << G4endl;
298 IntType = IType;
299 ArbEmax = ArbEnergyH.GetMaxLowEdgeEnergy();
300 ArbEmin = ArbEnergyH.GetMinLowEdgeEnergy();
301
302 // Now interpolate points
303 if (IntType == "Lin")
304 LinearInterpolation();
305 if (IntType == "Log")
306 LogInterpolation();
307 if (IntType == "Exp")
308 ExpInterpolation();
309 if (IntType == "Spline")
310 SplineInterpolation();
311}
312
313void G4SPSEneDistribution::LinearInterpolation() {
314 // Method to do linear interpolation on the Arb points
315 // Calculate equation of each line segment, max 1024.
316 // Calculate Area under each segment
317 // Create a cumulative array which is then normalised Arb_Cum_Area
318
319 G4double Area_seg[1024]; // Stores area under each segment
320 G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
321 G4int i, count;
322 G4int maxi = ArbEnergyH.GetVectorLength();
323 for (i = 0; i < maxi; i++) {
324 Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
325 Arb_y[i] = ArbEnergyH(size_t(i));
326 }
327 // Points are now in x,y arrays. If the spectrum is integral it has to be
328 // made differential and if momentum it has to be made energy.
329 if (DiffSpec == false) {
330 // Converts integral point-wise spectra to Differential
331 for (count = 0; count < maxi - 1; count++) {
332 Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
333 / (Arb_x[count + 1] - Arb_x[count]);
334 }
335 maxi--;
336 }
337 //
338 if (EnergySpec == false) {
339 // change currently stored values (emin etc) which are actually momenta
340 // to energies.
341 if (particle_definition == NULL)
342 G4cout << "Error: particle not defined" << G4endl;
343 else {
344 // Apply Energy**2 = p**2c**2 + m0**2c**4
345 // p should be entered as E/c i.e. without the division by c
346 // being done - energy equivalent.
347 G4double mass = particle_definition->GetPDGMass();
348 // convert point to energy unit and its value to per energy unit
349 G4double total_energy;
350 for (count = 0; count < maxi; count++) {
351 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
352 * mass)); // total energy
353
354 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
355 Arb_x[count] = total_energy - mass; // kinetic energy
356 }
357 }
358 }
359 //
360 i = 1;
361 Arb_grad[0] = 0.;
362 Arb_cept[0] = 0.;
363 Area_seg[0] = 0.;
364 Arb_Cum_Area[0] = 0.;
365 while (i < maxi) {
366 // calc gradient and intercept for each segment
367 Arb_grad[i] = (Arb_y[i] - Arb_y[i - 1]) / (Arb_x[i] - Arb_x[i - 1]);
368 if (verbosityLevel == 2)
369 G4cout << Arb_grad[i] << G4endl;
370 if (Arb_grad[i] > 0.) {
371 if (verbosityLevel == 2)
372 G4cout << "Arb_grad is positive" << G4endl;
373 Arb_cept[i] = Arb_y[i] - (Arb_grad[i] * Arb_x[i]);
374 } else if (Arb_grad[i] < 0.) {
375 if (verbosityLevel == 2)
376 G4cout << "Arb_grad is negative" << G4endl;
377 Arb_cept[i] = Arb_y[i] + (-Arb_grad[i] * Arb_x[i]);
378 } else {
379 if (verbosityLevel == 2)
380 G4cout << "Arb_grad is 0." << G4endl;
381 Arb_cept[i] = Arb_y[i];
382 }
383
384 Area_seg[i] = ((Arb_grad[i] / 2) * (Arb_x[i] * Arb_x[i] - Arb_x[i - 1]
385 * Arb_x[i - 1]) + Arb_cept[i] * (Arb_x[i] - Arb_x[i - 1]));
386 Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
387 sum = sum + Area_seg[i];
388 if (verbosityLevel == 2)
389 G4cout << Arb_x[i] << Arb_y[i] << Area_seg[i] << sum << Arb_grad[i]
390 << G4endl;
391 i++;
392 }
393
394 i = 0;
395 while (i < maxi) {
396 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum; // normalisation
397 IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
398 i++;
399 }
400
401 // now scale the ArbEnergyH, needed by Probability()
402 ArbEnergyH.ScaleVector(1., 1./sum);
403
404 if (verbosityLevel >= 1) {
405 G4cout << "Leaving LinearInterpolation" << G4endl;
406 ArbEnergyH.DumpValues();
407 IPDFArbEnergyH.DumpValues();
408 }
409}
410
411void G4SPSEneDistribution::LogInterpolation() {
412 // Interpolation based on Logarithmic equations
413 // Generate equations of line segments
414 // y = Ax**alpha => log y = alpha*logx + logA
415 // Find area under line segments
416 // create normalised, cumulative array Arb_Cum_Area
417 G4double Area_seg[1024]; // Stores area under each segment
418 G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
419 G4int i, count;
420 G4int maxi = ArbEnergyH.GetVectorLength();
421 for (i = 0; i < maxi; i++) {
422 Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
423 Arb_y[i] = ArbEnergyH(size_t(i));
424 }
425 // Points are now in x,y arrays. If the spectrum is integral it has to be
426 // made differential and if momentum it has to be made energy.
427 if (DiffSpec == false) {
428 // Converts integral point-wise spectra to Differential
429 for (count = 0; count < maxi - 1; count++) {
430 Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
431 / (Arb_x[count + 1] - Arb_x[count]);
432 }
433 maxi--;
434 }
435 //
436 if (EnergySpec == false) {
437 // change currently stored values (emin etc) which are actually momenta
438 // to energies.
439 if (particle_definition == NULL)
440 G4cout << "Error: particle not defined" << G4endl;
441 else {
442 // Apply Energy**2 = p**2c**2 + m0**2c**4
443 // p should be entered as E/c i.e. without the division by c
444 // being done - energy equivalent.
445 G4double mass = particle_definition->GetPDGMass();
446 // convert point to energy unit and its value to per energy unit
447 G4double total_energy;
448 for (count = 0; count < maxi; count++) {
449 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
450 * mass)); // total energy
451
452 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
453 Arb_x[count] = total_energy - mass; // kinetic energy
454 }
455 }
456 }
457 //
458 i = 1;
459 Arb_alpha[0] = 0.;
460 Arb_Const[0] = 0.;
461 Area_seg[0] = 0.;
462 Arb_Cum_Area[0] = 0.;
463 if (Arb_x[0] <= 0. || Arb_y[0] <= 0.) {
464 G4cout << "You should not use log interpolation with points <= 0."
465 << G4endl;
466 G4cout << "These will be changed to 1e-20, which may cause problems"
467 << G4endl;
468 if (Arb_x[0] <= 0.)
469 Arb_x[0] = 1e-20;
470 if (Arb_y[0] <= 0.)
471 Arb_y[0] = 1e-20;
472 }
473
474 G4double alp;
475 while (i < maxi) {
476 // Incase points are negative or zero
477 if (Arb_x[i] <= 0. || Arb_y[i] <= 0.) {
478 G4cout << "You should not use log interpolation with points <= 0."
479 << G4endl;
480 G4cout
481 << "These will be changed to 1e-20, which may cause problems"
482 << G4endl;
483 if (Arb_x[i] <= 0.)
484 Arb_x[i] = 1e-20;
485 if (Arb_y[i] <= 0.)
486 Arb_y[i] = 1e-20;
487 }
488
489 Arb_alpha[i] = (std::log10(Arb_y[i]) - std::log10(Arb_y[i - 1]))
490 / (std::log10(Arb_x[i]) - std::log10(Arb_x[i - 1]));
491 Arb_Const[i] = Arb_y[i] / (std::pow(Arb_x[i], Arb_alpha[i]));
492 alp = Arb_alpha[i] + 1;
493 if (alp == 0.) {
494 Area_seg[i] = Arb_Const[i] * (std::log(Arb_x[i]) - std::log(Arb_x[i - 1]));
495 } else {
496 Area_seg[i] = (Arb_Const[i] / alp) * (std::pow(Arb_x[i], alp)
497 - std::pow(Arb_x[i - 1], alp));
498 }
499 sum = sum + Area_seg[i];
500 Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
501 if (verbosityLevel == 2)
502 G4cout << Arb_alpha[i] << Arb_Const[i] << Area_seg[i] << G4endl;
503 i++;
504 }
505
506 i = 0;
507 while (i < maxi) {
508 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
509 IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
510 i++;
511 }
512
513 // now scale the ArbEnergyH, needed by Probability()
514 ArbEnergyH.ScaleVector(1., 1./sum);
515
516 if (verbosityLevel >= 1)
517 G4cout << "Leaving LogInterpolation " << G4endl;
518}
519
520void G4SPSEneDistribution::ExpInterpolation() {
521 // Interpolation based on Exponential equations
522 // Generate equations of line segments
523 // y = Ae**-(x/e0) => ln y = -x/e0 + lnA
524 // Find area under line segments
525 // create normalised, cumulative array Arb_Cum_Area
526 G4double Area_seg[1024]; // Stores area under each segment
527 G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
528 G4int i, count;
529 G4int maxi = ArbEnergyH.GetVectorLength();
530 for (i = 0; i < maxi; i++) {
531 Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
532 Arb_y[i] = ArbEnergyH(size_t(i));
533 }
534 // Points are now in x,y arrays. If the spectrum is integral it has to be
535 // made differential and if momentum it has to be made energy.
536 if (DiffSpec == false) {
537 // Converts integral point-wise spectra to Differential
538 for (count = 0; count < maxi - 1; count++) {
539 Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
540 / (Arb_x[count + 1] - Arb_x[count]);
541 }
542 maxi--;
543 }
544 //
545 if (EnergySpec == false) {
546 // change currently stored values (emin etc) which are actually momenta
547 // to energies.
548 if (particle_definition == NULL)
549 G4cout << "Error: particle not defined" << G4endl;
550 else {
551 // Apply Energy**2 = p**2c**2 + m0**2c**4
552 // p should be entered as E/c i.e. without the division by c
553 // being done - energy equivalent.
554 G4double mass = particle_definition->GetPDGMass();
555 // convert point to energy unit and its value to per energy unit
556 G4double total_energy;
557 for (count = 0; count < maxi; count++) {
558 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
559 * mass)); // total energy
560
561 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
562 Arb_x[count] = total_energy - mass; // kinetic energy
563 }
564 }
565 }
566 //
567 i = 1;
568 Arb_ezero[0] = 0.;
569 Arb_Const[0] = 0.;
570 Area_seg[0] = 0.;
571 Arb_Cum_Area[0] = 0.;
572 while (i < maxi) {
573 G4double test = std::log(Arb_y[i]) - std::log(Arb_y[i - 1]);
574 if (test > 0. || test < 0.) {
575 Arb_ezero[i] = -(Arb_x[i] - Arb_x[i - 1]) / (std::log(Arb_y[i])
576 - std::log(Arb_y[i - 1]));
577 Arb_Const[i] = Arb_y[i] / (std::exp(-Arb_x[i] / Arb_ezero[i]));
578 Area_seg[i] = -(Arb_Const[i] * Arb_ezero[i]) * (std::exp(-Arb_x[i]
579 / Arb_ezero[i]) - std::exp(-Arb_x[i - 1] / Arb_ezero[i]));
580 } else {
581 G4cout << "Flat line segment: problem" << G4endl;
582 Arb_ezero[i] = 0.;
583 Arb_Const[i] = 0.;
584 Area_seg[i] = 0.;
585 }
586 sum = sum + Area_seg[i];
587 Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + Area_seg[i];
588 if (verbosityLevel == 2)
589 G4cout << Arb_ezero[i] << Arb_Const[i] << Area_seg[i] << G4endl;
590 i++;
591 }
592
593 i = 0;
594 while (i < maxi) {
595 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
596 IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
597 i++;
598 }
599
600 // now scale the ArbEnergyH, needed by Probability()
601 ArbEnergyH.ScaleVector(1., 1./sum);
602
603 if (verbosityLevel >= 1)
604 G4cout << "Leaving ExpInterpolation " << G4endl;
605}
606
607void G4SPSEneDistribution::SplineInterpolation() {
608 // Interpolation using Splines.
609 // Create Normalised arrays, make x 0->1 and y hold
610 // the function (Energy)
611 //
612 // Current method based on the above will not work in all cases.
613 // new method is implemented below.
614
615 G4double sum, Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
616 G4int i, count;
617
618 G4int maxi = ArbEnergyH.GetVectorLength();
619 for (i = 0; i < maxi; i++) {
620 Arb_x[i] = ArbEnergyH.GetLowEdgeEnergy(size_t(i));
621 Arb_y[i] = ArbEnergyH(size_t(i));
622 }
623 // Points are now in x,y arrays. If the spectrum is integral it has to be
624 // made differential and if momentum it has to be made energy.
625 if (DiffSpec == false) {
626 // Converts integral point-wise spectra to Differential
627 for (count = 0; count < maxi - 1; count++) {
628 Arb_y[count] = (Arb_y[count] - Arb_y[count + 1])
629 / (Arb_x[count + 1] - Arb_x[count]);
630 }
631 maxi--;
632 }
633 //
634 if (EnergySpec == false) {
635 // change currently stored values (emin etc) which are actually momenta
636 // to energies.
637 if (particle_definition == NULL)
638 G4Exception("G4SPSEneDistribution::SplineInterpolation",
639 "Event0302",FatalException,
640 "Error: particle not defined");
641 else {
642 // Apply Energy**2 = p**2c**2 + m0**2c**4
643 // p should be entered as E/c i.e. without the division by c
644 // being done - energy equivalent.
645 G4double mass = particle_definition->GetPDGMass();
646 // convert point to energy unit and its value to per energy unit
647 G4double total_energy;
648 for (count = 0; count < maxi; count++) {
649 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
650 * mass)); // total energy
651
652 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
653 Arb_x[count] = total_energy - mass; // kinetic energy
654 }
655 }
656 }
657
658 //
659 i = 1;
660 Arb_Cum_Area[0] = 0.;
661 sum = 0.;
662 Splinetemp = new G4DataInterpolation(Arb_x, Arb_y, maxi, 0., 0.);
663 G4double ei[101],prob[101];
664 while (i < maxi) {
665 // 100 step per segment for the integration of area
666 G4double de = (Arb_x[i] - Arb_x[i - 1])/100.;
667 G4double area = 0.;
668
669 for (count = 0; count < 101; count++) {
670 ei[count] = Arb_x[i - 1] + de*count ;
671 prob[count] = Splinetemp->CubicSplineInterpolation(ei[count]);
672 if (prob[count] < 0.) {
674 ED << "Warning: G4DataInterpolation returns value < 0 " << prob[count] <<" "<<ei[count]<< G4endl;
675 G4Exception("G4SPSEneDistribution::SplineInterpolation","Event0303",
676 FatalException,ED);
677 }
678 area += prob[count]*de;
679 }
680 Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + area;
681 sum += area;
682
683 prob[0] = prob[0]/(area/de);
684 for (count = 1; count < 100; count++)
685 prob[count] = prob[count-1] + prob[count]/(area/de);
686
687 SplineInt[i] = new G4DataInterpolation(prob, ei, 101, 0., 0.);
688 // note i start from 1!
689 i++;
690 }
691 i = 0;
692 while (i < maxi) {
693 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum; // normalisation
694 IPDFArbEnergyH.InsertValues(Arb_x[i], Arb_Cum_Area[i]);
695 i++;
696 }
697 // now scale the ArbEnergyH, needed by Probability()
698 ArbEnergyH.ScaleVector(1., 1./sum);
699
700 if (verbosityLevel > 0)
701 G4cout << "Leaving SplineInterpolation " << G4endl;
702}
703
704void G4SPSEneDistribution::GenerateMonoEnergetic() {
705 // Method to generate MonoEnergetic particles.
706 particle_energy = MonoEnergy;
707}
708
709void G4SPSEneDistribution::GenerateGaussEnergies() {
710 // Method to generate Gaussian particles.
711 particle_energy = G4RandGauss::shoot(MonoEnergy,SE);
712 if (particle_energy < 0) particle_energy = 0.;
713}
714
715void G4SPSEneDistribution::GenerateLinearEnergies(G4bool bArb = false) {
716 G4double rndm;
717 G4double emaxsq = std::pow(Emax, 2.); //Emax squared
718 G4double eminsq = std::pow(Emin, 2.); //Emin squared
719 G4double intersq = std::pow(cept, 2.); //cept squared
720
721 if (bArb)
722 rndm = G4UniformRand();
723 else
724 rndm = eneRndm->GenRandEnergy();
725
726 G4double bracket = ((grad / 2.) * (emaxsq - eminsq) + cept * (Emax - Emin));
727 bracket = bracket * rndm;
728 bracket = bracket + (grad / 2.) * eminsq + cept * Emin;
729 // Now have a quad of form m/2 E**2 + cE - bracket = 0
730 bracket = -bracket;
731 // G4cout << "BRACKET" << bracket << G4endl;
732 if (grad != 0.) {
733 G4double sqbrack = (intersq - 4 * (grad / 2.) * (bracket));
734 // G4cout << "SQBRACK" << sqbrack << G4endl;
735 sqbrack = std::sqrt(sqbrack);
736 G4double root1 = -cept + sqbrack;
737 root1 = root1 / (2. * (grad / 2.));
738
739 G4double root2 = -cept - sqbrack;
740 root2 = root2 / (2. * (grad / 2.));
741
742 // G4cout << root1 << " roots " << root2 << G4endl;
743
744 if (root1 > Emin && root1 < Emax)
745 particle_energy = root1;
746 if (root2 > Emin && root2 < Emax)
747 particle_energy = root2;
748 } else if (grad == 0.)
749 // have equation of form cE - bracket =0
750 particle_energy = bracket / cept;
751
752 if (particle_energy < 0.)
753 particle_energy = -particle_energy;
754
755 if (verbosityLevel >= 1)
756 G4cout << "Energy is " << particle_energy << G4endl;
757}
758
759void G4SPSEneDistribution::GeneratePowEnergies(G4bool bArb = false) {
760 // Method to generate particle energies distributed as
761 // a power-law
762
763 G4double rndm;
764 G4double emina, emaxa;
765
766 emina = std::pow(Emin, alpha + 1);
767 emaxa = std::pow(Emax, alpha + 1);
768
769 if (bArb)
770 rndm = G4UniformRand();
771 else
772 rndm = eneRndm->GenRandEnergy();
773
774 if (alpha != -1.) {
775 particle_energy = ((rndm * (emaxa - emina)) + emina);
776 particle_energy = std::pow(particle_energy, (1. / (alpha + 1.)));
777 } else {
778 particle_energy = (std::log(Emin) + rndm * (std::log(Emax) - std::log(
779 Emin)));
780 particle_energy = std::exp(particle_energy);
781 }
782 if (verbosityLevel >= 1)
783 G4cout << "Energy is " << particle_energy << G4endl;
784}
785
786void G4SPSEneDistribution::GenerateBiasPowEnergies() {
787 // Method to generate particle energies distributed as
788 // in biased power-law and calculate its weight
789
790 G4double rndm;
791 G4double emina, emaxa, emin, emax;
792
793 G4double normal = 1. ;
794
795 emin = Emin;
796 emax = Emax;
797 // if (EnergyDisType == "Arb") {
798 // emin = ArbEmin;
799 // emax = ArbEmax;
800 //}
801
802 rndm = eneRndm->GenRandEnergy();
803
804 if (biasalpha != -1.) {
805 emina = std::pow(emin, biasalpha + 1);
806 emaxa = std::pow(emax, biasalpha + 1);
807 particle_energy = ((rndm * (emaxa - emina)) + emina);
808 particle_energy = std::pow(particle_energy, (1. / (biasalpha + 1.)));
809 normal = 1./(1+biasalpha) * (emaxa - emina);
810 } else {
811 particle_energy = (std::log(emin) + rndm * (std::log(emax) - std::log(
812 emin)));
813 particle_energy = std::exp(particle_energy);
814 normal = std::log(emax) - std::log(emin) ;
815 }
816 weight = GetProbability(particle_energy) / (std::pow(particle_energy,biasalpha)/normal);
817
818 if (verbosityLevel >= 1)
819 G4cout << "Energy is " << particle_energy << G4endl;
820}
821
822void G4SPSEneDistribution::GenerateExpEnergies(G4bool bArb = false) {
823 // Method to generate particle energies distributed according
824 // to an exponential curve.
825 G4double rndm;
826
827 if (bArb)
828 rndm = G4UniformRand();
829 else
830 rndm = eneRndm->GenRandEnergy();
831
832 particle_energy = -Ezero * (std::log(rndm * (std::exp(-Emax / Ezero)
833 - std::exp(-Emin / Ezero)) + std::exp(-Emin / Ezero)));
834 if (verbosityLevel >= 1)
835 G4cout << "Energy is " << particle_energy << G4endl;
836}
837
838void G4SPSEneDistribution::GenerateBremEnergies() {
839 // Method to generate particle energies distributed according
840 // to a Bremstrahlung equation of
841 // form I = const*((kT)**1/2)*E*(e**(-E/kT))
842
843 G4double rndm;
844 rndm = eneRndm->GenRandEnergy();
845 G4double expmax, expmin, k;
846
847 k = 8.6181e-11; // Boltzmann's const in MeV/K
848 G4double ksq = std::pow(k, 2.); // k squared
849 G4double Tsq = std::pow(Temp, 2.); // Temp squared
850
851 expmax = std::exp(-Emax / (k * Temp));
852 expmin = std::exp(-Emin / (k * Temp));
853
854 // If either expmax or expmin are zero then this will cause problems
855 // Most probably this will be because T is too low or E is too high
856
857 if (expmax == 0.)
858 G4cout << "*****EXPMAX=0. Choose different E's or Temp" << G4endl;
859 if (expmin == 0.)
860 G4cout << "*****EXPMIN=0. Choose different E's or Temp" << G4endl;
861
862 G4double tempvar = rndm * ((-k) * Temp * (Emax * expmax - Emin * expmin)
863 - (ksq * Tsq * (expmax - expmin)));
864
865 G4double bigc = (tempvar - k * Temp * Emin * expmin - ksq * Tsq * expmin)
866 / (-k * Temp);
867
868 // This gives an equation of form: Ee(-E/kT) + kTe(-E/kT) - C =0
869 // Solve this iteratively, step from Emin to Emax in 1000 steps
870 // and take the best solution.
871
872 G4double erange = Emax - Emin;
873 G4double steps = erange / 1000.;
874 G4int i;
875 G4double etest, diff, err;
876
877 err = 100000.;
878
879 for (i = 1; i < 1000; i++) {
880 etest = Emin + (i - 1) * steps;
881
882 diff = etest * (std::exp(-etest / (k * Temp))) + k * Temp * (std::exp(
883 -etest / (k * Temp))) - bigc;
884
885 if (diff < 0.)
886 diff = -diff;
887
888 if (diff < err) {
889 err = diff;
890 particle_energy = etest;
891 }
892 }
893 if (verbosityLevel >= 1)
894 G4cout << "Energy is " << particle_energy << G4endl;
895}
896
897void G4SPSEneDistribution::GenerateBbodyEnergies() {
898 // BBody_x holds Energies, and BBHist holds the cumulative histo.
899 // binary search to find correct bin then lin interpolation.
900 // Use the earlier defined histogram + RandGeneral method to generate
901 // random numbers following the histos distribution.
902 G4double rndm;
903 G4int nabove, nbelow = 0, middle;
904 nabove = 10001;
905 rndm = eneRndm->GenRandEnergy();
906
907 // Binary search to find bin that rndm is in
908 while (nabove - nbelow > 1) {
909 middle = (nabove + nbelow) / 2;
910 if (rndm == BBHist[middle])
911 break;
912 if (rndm < BBHist[middle])
913 nabove = middle;
914 else
915 nbelow = middle;
916 }
917
918 // Now interpolate in that bin to find the correct output value.
919 G4double x1, x2, y1, y2, t, q;
920 x1 = Bbody_x[nbelow];
921 x2 = Bbody_x[nbelow + 1];
922 y1 = BBHist[nbelow];
923 y2 = BBHist[nbelow + 1];
924 t = (y2 - y1) / (x2 - x1);
925 q = y1 - t * x1;
926
927 particle_energy = (rndm - q) / t;
928
929 if (verbosityLevel >= 1) {
930 G4cout << "Energy is " << particle_energy << G4endl;
931 }
932}
933
934void G4SPSEneDistribution::GenerateCdgEnergies() {
935 // Gen random numbers, compare with values in cumhist
936 // to find appropriate part of spectrum and then
937 // generate energy in the usual inversion way.
938 // G4double pfact[2] = {8.5, 112};
939 // G4double spind[2] = {1.4, 2.3};
940 // G4double ene_line[3] = {1., 18., 1E6};
941 G4double rndm, rndm2;
942 G4double ene_line[3];
943 G4double omalpha[2];
944 if (Emin < 18 * keV && Emax < 18 * keV) {
945 omalpha[0] = 1. - 1.4;
946 ene_line[0] = Emin;
947 ene_line[1] = Emax;
948 }
949 if (Emin < 18 * keV && Emax > 18 * keV) {
950 omalpha[0] = 1. - 1.4;
951 omalpha[1] = 1. - 2.3;
952 ene_line[0] = Emin;
953 ene_line[1] = 18. * keV;
954 ene_line[2] = Emax;
955 }
956 if (Emin > 18 * keV) {
957 omalpha[0] = 1. - 2.3;
958 ene_line[0] = Emin;
959 ene_line[1] = Emax;
960 }
961 rndm = eneRndm->GenRandEnergy();
962 rndm2 = eneRndm->GenRandEnergy();
963
964 G4int i = 0;
965 while (rndm >= CDGhist[i]) {
966 i++;
967 }
968 // Generate final energy.
969 particle_energy = (std::pow(ene_line[i - 1], omalpha[i - 1]) + (std::pow(
970 ene_line[i], omalpha[i - 1]) - std::pow(ene_line[i - 1], omalpha[i
971 - 1])) * rndm2);
972 particle_energy = std::pow(particle_energy, (1. / omalpha[i - 1]));
973
974 if (verbosityLevel >= 1)
975 G4cout << "Energy is " << particle_energy << G4endl;
976}
977
978void G4SPSEneDistribution::GenUserHistEnergies() {
979 // Histograms are DIFFERENTIAL.
980 // G4cout << "In GenUserHistEnergies " << G4endl;
981 if (IPDFEnergyExist == false) {
982 G4int ii;
983 G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
984 G4double bins[1024], vals[1024], sum;
985 sum = 0.;
986
987 if ((EnergySpec == false) && (particle_definition == NULL))
988 G4cout << "Error: particle definition is NULL" << G4endl;
989
990 if (maxbin > 1024) {
991 G4cout << "Maxbin > 1024" << G4endl;
992 G4cout << "Setting maxbin to 1024, other bins are lost" << G4endl;
993 }
994
995 if (DiffSpec == false)
996 G4cout << "Histograms are Differential!!! " << G4endl;
997 else {
998 bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
999 vals[0] = UDefEnergyH(size_t(0));
1000 sum = vals[0];
1001 for (ii = 1; ii < maxbin; ii++) {
1002 bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
1003 vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii - 1];
1004 sum = sum + UDefEnergyH(size_t(ii));
1005 }
1006 }
1007
1008 if (EnergySpec == false) {
1009 G4double mass = particle_definition->GetPDGMass();
1010 // multiply the function (vals) up by the bin width
1011 // to make the function counts/s (i.e. get rid of momentum
1012 // dependence).
1013 for (ii = 1; ii < maxbin; ii++) {
1014 vals[ii] = vals[ii] * (bins[ii] - bins[ii - 1]);
1015 }
1016 // Put energy bins into new histo, plus divide by energy bin width
1017 // to make evals counts/s/energy
1018 for (ii = 0; ii < maxbin; ii++) {
1019 bins[ii] = std::sqrt((bins[ii] * bins[ii]) + (mass * mass))
1020 - mass; //kinetic energy
1021 }
1022 for (ii = 1; ii < maxbin; ii++) {
1023 vals[ii] = vals[ii] / (bins[ii] - bins[ii - 1]);
1024 }
1025 sum = vals[maxbin - 1];
1026 vals[0] = 0.;
1027 }
1028 for (ii = 0; ii < maxbin; ii++) {
1029 vals[ii] = vals[ii] / sum;
1030 IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
1031 }
1032
1033 // Make IPDFEnergyExist = true
1034 IPDFEnergyExist = true;
1035 if (verbosityLevel > 1)
1036 IPDFEnergyH.DumpValues();
1037 }
1038
1039 // IPDF has been create so carry on
1040 G4double rndm = eneRndm->GenRandEnergy();
1041 particle_energy = IPDFEnergyH.GetEnergy(rndm);
1042
1043 if (verbosityLevel >= 1)
1044 G4cout << "Energy is " << particle_energy << G4endl;
1045}
1046
1047void G4SPSEneDistribution::GenArbPointEnergies() {
1048 if (verbosityLevel > 0)
1049 G4cout << "In GenArbPointEnergies" << G4endl;
1050 G4double rndm;
1051 rndm = eneRndm->GenRandEnergy();
1052 // IPDFArbEnergyH.DumpValues();
1053 // Find the Bin
1054 // have x, y, no of points, and cumulative area distribution
1055 G4int nabove, nbelow = 0, middle;
1056 nabove = IPDFArbEnergyH.GetVectorLength();
1057 // G4cout << nabove << G4endl;
1058 // Binary search to find bin that rndm is in
1059 while (nabove - nbelow > 1) {
1060 middle = (nabove + nbelow) / 2;
1061 if (rndm == IPDFArbEnergyH(size_t(middle)))
1062 break;
1063 if (rndm < IPDFArbEnergyH(size_t(middle)))
1064 nabove = middle;
1065 else
1066 nbelow = middle;
1067 }
1068 if (IntType == "Lin") {
1069 Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
1070 Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
1071 grad = Arb_grad[nbelow + 1];
1072 cept = Arb_cept[nbelow + 1];
1073 // G4cout << rndm << " " << Emax << " " << Emin << " " << grad << " " << cept << G4endl;
1074 GenerateLinearEnergies(true);
1075 } else if (IntType == "Log") {
1076 Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
1077 Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
1078 alpha = Arb_alpha[nbelow + 1];
1079 // G4cout << rndm << " " << Emax << " " << Emin << " " << alpha << G4endl;
1080 GeneratePowEnergies(true);
1081 } else if (IntType == "Exp") {
1082 Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
1083 Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
1084 Ezero = Arb_ezero[nbelow + 1];
1085 // G4cout << rndm << " " << Emax << " " << Emin << " " << Ezero << G4endl;
1086 GenerateExpEnergies(true);
1087 } else if (IntType == "Spline") {
1088 Emax = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow + 1));
1089 Emin = IPDFArbEnergyH.GetLowEdgeEnergy(size_t(nbelow));
1090 particle_energy = -1e100;
1091 rndm = eneRndm->GenRandEnergy();
1092 while (particle_energy < Emin || particle_energy > Emax) {
1093 particle_energy = SplineInt[nbelow+1]->CubicSplineInterpolation(rndm);
1094 rndm = eneRndm->GenRandEnergy();
1095 }
1096 if (verbosityLevel >= 1)
1097 G4cout << "Energy is " << particle_energy << G4endl;
1098 } else
1099 G4cout << "Error: IntType unknown type" << G4endl;
1100}
1101
1102void G4SPSEneDistribution::GenEpnHistEnergies() {
1103 // G4cout << "In GenEpnHistEnergies " << Epnflag << G4endl;
1104
1105 // Firstly convert to energy if not already done.
1106 if (Epnflag == true)
1107 // epnflag = true means spectrum is epn, false means e.
1108 {
1109 // convert to energy by multiplying by A number
1110 ConvertEPNToEnergy();
1111 // EpnEnergyH will be replace by UDefEnergyH.
1112 // UDefEnergyH.DumpValues();
1113 }
1114
1115 // G4cout << "Creating IPDFEnergy if not already done so" << G4endl;
1116 if (IPDFEnergyExist == false) {
1117 // IPDF has not been created, so create it
1118 G4double bins[1024], vals[1024], sum;
1119 G4int ii;
1120 G4int maxbin = G4int(UDefEnergyH.GetVectorLength());
1121 bins[0] = UDefEnergyH.GetLowEdgeEnergy(size_t(0));
1122 vals[0] = UDefEnergyH(size_t(0));
1123 sum = vals[0];
1124 for (ii = 1; ii < maxbin; ii++) {
1125 bins[ii] = UDefEnergyH.GetLowEdgeEnergy(size_t(ii));
1126 vals[ii] = UDefEnergyH(size_t(ii)) + vals[ii - 1];
1127 sum = sum + UDefEnergyH(size_t(ii));
1128 }
1129
1130 for (ii = 0; ii < maxbin; ii++) {
1131 vals[ii] = vals[ii] / sum;
1132 IPDFEnergyH.InsertValues(bins[ii], vals[ii]);
1133 }
1134 // Make IPDFEpnExist = true
1135 IPDFEnergyExist = true;
1136 }
1137 // IPDFEnergyH.DumpValues();
1138 // IPDF has been create so carry on
1139 G4double rndm = eneRndm->GenRandEnergy();
1140 particle_energy = IPDFEnergyH.GetEnergy(rndm);
1141
1142 if (verbosityLevel >= 1)
1143 G4cout << "Energy is " << particle_energy << G4endl;
1144}
1145
1146void G4SPSEneDistribution::ConvertEPNToEnergy() {
1147 // Use this before particle generation to convert the
1148 // currently stored histogram from energy/nucleon
1149 // to energy.
1150 // G4cout << "In ConvertEpntoEnergy " << G4endl;
1151 if (particle_definition == NULL)
1152 G4cout << "Error: particle not defined" << G4endl;
1153 else {
1154 // Need to multiply histogram by the number of nucleons.
1155 // Baryon Number looks to hold the no. of nucleons.
1156 G4int Bary = particle_definition->GetBaryonNumber();
1157 // G4cout << "Baryon No. " << Bary << G4endl;
1158 // Change values in histogram, Read it out, delete it, re-create it
1159 G4int count, maxcount;
1160 maxcount = G4int(EpnEnergyH.GetVectorLength());
1161 // G4cout << maxcount << G4endl;
1162 G4double ebins[1024], evals[1024];
1163 if (maxcount > 1024) {
1164 G4cout << "Histogram contains more than 1024 bins!" << G4endl;
1165 G4cout << "Those above 1024 will be ignored" << G4endl;
1166 maxcount = 1024;
1167 }
1168 if (maxcount < 1) {
1169 G4cout << "Histogram contains less than 1 bin!" << G4endl;
1170 G4cout << "Redefine the histogram" << G4endl;
1171 return;
1172 }
1173 for (count = 0; count < maxcount; count++) {
1174 // Read out
1175 ebins[count] = EpnEnergyH.GetLowEdgeEnergy(size_t(count));
1176 evals[count] = EpnEnergyH(size_t(count));
1177 }
1178
1179 // Multiply the channels by the nucleon number to give energies
1180 for (count = 0; count < maxcount; count++) {
1181 ebins[count] = ebins[count] * Bary;
1182 }
1183
1184 // Set Emin and Emax
1185 Emin = ebins[0];
1186 if (maxcount > 1)
1187 Emax = ebins[maxcount - 1];
1188 else
1189 Emax = ebins[0];
1190 // Put energy bins into new histogram - UDefEnergyH.
1191 for (count = 0; count < maxcount; count++) {
1192 UDefEnergyH.InsertValues(ebins[count], evals[count]);
1193 }
1194 Epnflag = false; //so that you dont repeat this method.
1195 }
1196}
1197
1198//
1200 if (atype == "energy") {
1201 UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
1202 IPDFEnergyExist = false;
1203 Emin = 0.;
1204 Emax = 1e30;
1205 } else if (atype == "arb") {
1206 ArbEnergyH = IPDFArbEnergyH = ZeroPhysVector;
1207 IPDFArbExist = false;
1208 } else if (atype == "epn") {
1209 UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
1210 IPDFEnergyExist = false;
1211 EpnEnergyH = ZeroPhysVector;
1212 } else {
1213 G4cout << "Error, histtype not accepted " << G4endl;
1214 }
1215}
1216
1218 particle_definition = a;
1219 particle_energy = -1.;
1220
1221 while ((EnergyDisType == "Arb") ? (particle_energy < ArbEmin
1222 || particle_energy > ArbEmax) : (particle_energy < Emin
1223 || particle_energy > Emax)) {
1224 if (Biased) {
1225 GenerateBiasPowEnergies();
1226 } else {
1227 if (EnergyDisType == "Mono")
1228 GenerateMonoEnergetic();
1229 else if (EnergyDisType == "Lin")
1230 GenerateLinearEnergies();
1231 else if (EnergyDisType == "Pow")
1232 GeneratePowEnergies();
1233 else if (EnergyDisType == "Exp")
1234 GenerateExpEnergies();
1235 else if (EnergyDisType == "Gauss")
1236 GenerateGaussEnergies();
1237 else if (EnergyDisType == "Brem")
1238 GenerateBremEnergies();
1239 else if (EnergyDisType == "Bbody")
1240 GenerateBbodyEnergies();
1241 else if (EnergyDisType == "Cdg")
1242 GenerateCdgEnergies();
1243 else if (EnergyDisType == "User")
1244 GenUserHistEnergies();
1245 else if (EnergyDisType == "Arb")
1246 GenArbPointEnergies();
1247 else if (EnergyDisType == "Epn")
1248 GenEpnHistEnergies();
1249 else
1250 G4cout << "Error: EnergyDisType has unusual value" << G4endl;
1251 }
1252 }
1253 return particle_energy;
1254}
1255
1257 G4double prob = 1.;
1258
1259 if (EnergyDisType == "Lin") {
1260 if (prob_norm == 1.) {
1261 prob_norm = 0.5*grad*Emax*Emax + cept*Emax - 0.5*grad*Emin*Emin - cept*Emin;
1262 }
1263 prob = cept + grad * ene;
1264 prob /= prob_norm;
1265 }
1266 else if (EnergyDisType == "Pow") {
1267 if (prob_norm == 1.) {
1268 if (alpha != -1.) {
1269 G4double emina = std::pow(Emin, alpha + 1);
1270 G4double emaxa = std::pow(Emax, alpha + 1);
1271 prob_norm = 1./(1.+alpha) * (emaxa - emina);
1272 } else {
1273 prob_norm = std::log(Emax) - std::log(Emin) ;
1274 }
1275 }
1276 prob = std::pow(ene, alpha)/prob_norm;
1277 }
1278 else if (EnergyDisType == "Exp"){
1279 if (prob_norm == 1.) {
1280 prob_norm = -Ezero*(std::exp(-Emax/Ezero) - std::exp(Emin/Ezero));
1281 }
1282 prob = std::exp(-ene / Ezero);
1283 prob /= prob_norm;
1284 }
1285 else if (EnergyDisType == "Arb") {
1286 prob = ArbEnergyH.Value(ene);
1287 // prob = ArbEInt->CubicSplineInterpolation(ene);
1288 //G4double deltaY;
1289 //prob = ArbEInt->PolynomInterpolation(ene, deltaY);
1290 if (prob <= 0.) {
1291 //G4cout << " Warning:G4SPSEneDistribution::GetProbability: prob<= 0. "<<prob <<" "<<ene << " " <<deltaY<< G4endl;
1292 G4cout << " Warning:G4SPSEneDistribution::GetProbability: prob<= 0. "<<prob <<" "<<ene << G4endl;
1293 prob = 1e-30;
1294 }
1295 // already normalised
1296 }
1297 else
1298 G4cout << "Error: EnergyDisType not supported" << G4endl;
1299
1300 return prob;
1301}
@ FatalException
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
double x() const
double y() const
G4double CubicSplineInterpolation(G4double pX) const
void InsertValues(G4double energy, G4double value)
G4double GetLowEdgeEnergy(size_t binNumber) const
G4double GetEnergy(G4double aValue)
G4double Value(G4double theEnergy)
size_t GetVectorLength() const
virtual void ScaleVector(G4double factorE, G4double factorV)
G4double GetProbability(G4double)
void UserEnergyHisto(G4ThreeVector)
void ArbEnergyHisto(G4ThreeVector)
G4double GenerateOne(G4ParticleDefinition *)
void InputDifferentialSpectra(G4bool)
void EpnEnergyHisto(G4ThreeVector)
void SetEnergyDisType(G4String)
void ArbEnergyHistoFile(G4String)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76