54 : particle_definition(0), eneRndm(0), Splinetemp(0)
58 particle_energy = 1.0 *
MeV;
60 EnergyDisType =
"Mono";
77 IPDFEnergyExist =
false;
91 EnergyDisType = DisType;
92 if (EnergyDisType ==
"User") {
93 UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
94 IPDFEnergyExist =
false;
95 }
else if (EnergyDisType ==
"Arb") {
96 ArbEnergyH = IPDFArbEnergyH = ZeroPhysVector;
98 }
else if (EnergyDisType ==
"Epn") {
99 UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
100 IPDFEnergyExist =
false;
101 EpnEnergyH = ZeroPhysVector;
114 MonoEnergy = menergy;
149 if (verbosityLevel > 1) {
161 if (verbosityLevel > 1) {
171 G4Exception(
"G4SPSEneDistribution::ArbEnergyHistoFile",
173 "Unable to open the histo ASCII file");
175 while (infile >> ehi >> val) {
184 if (verbosityLevel > 1) {
194 if (EnergyDisType ==
"Cdg")
195 CalculateCdgSpectrum();
196 else if (EnergyDisType ==
"Bbody")
197 CalculateBbodySpectrum();
200 void G4SPSEneDistribution::CalculateCdgSpectrum() {
209 if (Emin < 18 *
keV) {
212 if (Emax < 18 *
keV) {
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,
239 CDGhist[i + 1] = CDGhist[i + 1] / CDGhist[n_par];
245 void G4SPSEneDistribution::CalculateBbodySpectrum() {
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];
272 Bbody_x[10000] = Emax;
275 while (count < 10001) {
276 BBHist[count] = BBHist[count] / sum;
284 if (verbosityLevel > 1)
285 G4cout <<
"EnergySpec has value " << EnergySpec <<
G4endl;
291 if (verbosityLevel > 1)
296 if (EnergyDisType !=
"Arb")
297 G4cout <<
"Error: this is for arbitrary distributions" <<
G4endl;
303 if (IntType ==
"Lin")
304 LinearInterpolation();
305 if (IntType ==
"Log")
307 if (IntType ==
"Exp")
309 if (IntType ==
"Spline")
310 SplineInterpolation();
313 void G4SPSEneDistribution::LinearInterpolation() {
320 G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
323 for (i = 0; i < maxi; i++) {
325 Arb_y[i] = ArbEnergyH(
size_t(i));
329 if (DiffSpec ==
false) {
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]);
338 if (EnergySpec ==
false) {
341 if (particle_definition == NULL)
350 for (count = 0; count < maxi; count++) {
351 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
354 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
355 Arb_x[count] = total_energy - mass;
364 Arb_Cum_Area[0] = 0.;
367 Arb_grad[i] = (Arb_y[i] - Arb_y[i - 1]) / (Arb_x[i] - Arb_x[i - 1]);
368 if (verbosityLevel == 2)
370 if (Arb_grad[i] > 0.) {
371 if (verbosityLevel == 2)
373 Arb_cept[i] = Arb_y[i] - (Arb_grad[i] * Arb_x[i]);
374 }
else if (Arb_grad[i] < 0.) {
375 if (verbosityLevel == 2)
377 Arb_cept[i] = Arb_y[i] + (-Arb_grad[i] * Arb_x[i]);
379 if (verbosityLevel == 2)
381 Arb_cept[i] = Arb_y[i];
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]
396 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
404 if (verbosityLevel >= 1) {
411 void G4SPSEneDistribution::LogInterpolation() {
418 G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
421 for (i = 0; i < maxi; i++) {
423 Arb_y[i] = ArbEnergyH(
size_t(i));
427 if (DiffSpec ==
false) {
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]);
436 if (EnergySpec ==
false) {
439 if (particle_definition == NULL)
448 for (count = 0; count < maxi; count++) {
449 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
452 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
453 Arb_x[count] = total_energy - mass;
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."
466 G4cout <<
"These will be changed to 1e-20, which may cause problems"
477 if (Arb_x[i] <= 0. || Arb_y[i] <= 0.) {
478 G4cout <<
"You should not use log interpolation with points <= 0."
481 <<
"These will be changed to 1e-20, which may cause problems"
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;
494 Area_seg[i] = Arb_Const[i] * (std::log(Arb_x[i]) - std::log(Arb_x[i - 1]));
496 Area_seg[i] = (Arb_Const[i] / alp) * (std::pow(Arb_x[i], alp)
497 - std::pow(Arb_x[i - 1], alp));
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;
508 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
516 if (verbosityLevel >= 1)
520 void G4SPSEneDistribution::ExpInterpolation() {
527 G4double sum = 0., Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
530 for (i = 0; i < maxi; i++) {
532 Arb_y[i] = ArbEnergyH(
size_t(i));
536 if (DiffSpec ==
false) {
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]);
545 if (EnergySpec ==
false) {
548 if (particle_definition == NULL)
557 for (count = 0; count < maxi; count++) {
558 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
561 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
562 Arb_x[count] = total_energy - mass;
571 Arb_Cum_Area[0] = 0.;
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]));
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;
595 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
603 if (verbosityLevel >= 1)
607 void G4SPSEneDistribution::SplineInterpolation() {
615 G4double sum, Arb_x[1024], Arb_y[1024], Arb_Cum_Area[1024];
619 for (i = 0; i < maxi; i++) {
621 Arb_y[i] = ArbEnergyH(
size_t(i));
625 if (DiffSpec ==
false) {
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]);
634 if (EnergySpec ==
false) {
637 if (particle_definition == NULL)
638 G4Exception(
"G4SPSEneDistribution::SplineInterpolation",
640 "Error: particle not defined");
648 for (count = 0; count < maxi; count++) {
649 total_energy = std::sqrt((Arb_x[count] * Arb_x[count]) + (mass
652 Arb_y[count] = Arb_y[count] * Arb_x[count] / total_energy;
653 Arb_x[count] = total_energy - mass;
660 Arb_Cum_Area[0] = 0.;
666 G4double de = (Arb_x[i] - Arb_x[i - 1])/100.;
669 for (count = 0; count < 101; count++) {
670 ei[count] = Arb_x[i - 1] + de*count ;
672 if (prob[count] < 0.) {
674 ED <<
"Warning: G4DataInterpolation returns value < 0 " << prob[count] <<
" "<<ei[count]<<
G4endl;
675 G4Exception(
"G4SPSEneDistribution::SplineInterpolation",
"Event0303",
678 area += prob[count]*de;
680 Arb_Cum_Area[i] = Arb_Cum_Area[i - 1] + area;
683 prob[0] = prob[0]/(area/de);
684 for (count = 1; count < 100; count++)
685 prob[count] = prob[count-1] + prob[count]/(area/de);
693 Arb_Cum_Area[i] = Arb_Cum_Area[i] / sum;
700 if (verbosityLevel > 0)
704 void G4SPSEneDistribution::GenerateMonoEnergetic() {
706 particle_energy = MonoEnergy;
709 void G4SPSEneDistribution::GenerateGaussEnergies() {
711 particle_energy = G4RandGauss::shoot(MonoEnergy,SE);
712 if (particle_energy < 0) particle_energy = 0.;
715 void G4SPSEneDistribution::GenerateLinearEnergies(
G4bool bArb =
false) {
717 G4double emaxsq = std::pow(Emax, 2.);
718 G4double eminsq = std::pow(Emin, 2.);
719 G4double intersq = std::pow(cept, 2.);
726 G4double bracket = ((grad / 2.) * (emaxsq - eminsq) + cept * (Emax - Emin));
727 bracket = bracket *
rndm;
728 bracket = bracket + (grad / 2.) * eminsq + cept * Emin;
733 G4double sqbrack = (intersq - 4 * (grad / 2.) * (bracket));
735 sqbrack = std::sqrt(sqbrack);
737 root1 = root1 / (2. * (grad / 2.));
740 root2 = root2 / (2. * (grad / 2.));
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.)
750 particle_energy = bracket / cept;
752 if (particle_energy < 0.)
753 particle_energy = -particle_energy;
755 if (verbosityLevel >= 1)
759 void G4SPSEneDistribution::GeneratePowEnergies(
G4bool bArb =
false) {
766 emina = std::pow(Emin, alpha + 1);
767 emaxa = std::pow(Emax, alpha + 1);
775 particle_energy = ((rndm * (emaxa - emina)) + emina);
776 particle_energy = std::pow(particle_energy, (1. / (alpha + 1.)));
778 particle_energy = (std::log(Emin) + rndm * (std::log(Emax) - std::log(
780 particle_energy = std::exp(particle_energy);
782 if (verbosityLevel >= 1)
786 void G4SPSEneDistribution::GenerateBiasPowEnergies() {
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);
811 particle_energy = (std::log(emin) + rndm * (std::log(emax) - std::log(
813 particle_energy = std::exp(particle_energy);
814 normal = std::log(emax) - std::log(emin) ;
816 weight =
GetProbability(particle_energy) / (std::pow(particle_energy,biasalpha)/normal);
818 if (verbosityLevel >= 1)
822 void G4SPSEneDistribution::GenerateExpEnergies(
G4bool bArb =
false) {
832 particle_energy = -Ezero * (std::log(rndm * (std::exp(-Emax / Ezero)
833 - std::exp(-Emin / Ezero)) + std::exp(-Emin / Ezero)));
834 if (verbosityLevel >= 1)
838 void G4SPSEneDistribution::GenerateBremEnergies() {
851 expmax = std::exp(-Emax / (k * Temp));
852 expmin = std::exp(-Emin / (k * Temp));
858 G4cout <<
"*****EXPMAX=0. Choose different E's or Temp" <<
G4endl;
860 G4cout <<
"*****EXPMIN=0. Choose different E's or Temp" <<
G4endl;
862 G4double tempvar = rndm * ((-k) * Temp * (Emax * expmax - Emin * expmin)
863 - (ksq * Tsq * (expmax - expmin)));
865 G4double bigc = (tempvar - k * Temp * Emin * expmin - ksq * Tsq * expmin)
879 for (i = 1; i < 1000; i++) {
880 etest = Emin + (i - 1) * steps;
882 diff = etest * (std::exp(-etest / (k * Temp))) + k * Temp * (std::exp(
883 -etest / (k * Temp))) - bigc;
890 particle_energy = etest;
893 if (verbosityLevel >= 1)
897 void G4SPSEneDistribution::GenerateBbodyEnergies() {
903 G4int nabove, nbelow = 0, middle;
908 while (nabove - nbelow > 1) {
909 middle = (nabove + nbelow) / 2;
910 if (rndm == BBHist[middle])
912 if (rndm < BBHist[middle])
920 x1 = Bbody_x[nbelow];
921 x2 = Bbody_x[nbelow + 1];
923 y2 = BBHist[nbelow + 1];
924 t = (y2 -
y1) / (x2 - x1);
927 particle_energy = (rndm - q) / t;
929 if (verbosityLevel >= 1) {
934 void G4SPSEneDistribution::GenerateCdgEnergies() {
944 if (Emin < 18 *
keV && Emax < 18 *
keV) {
945 omalpha[0] = 1. - 1.4;
949 if (Emin < 18 * keV && Emax > 18 *
keV) {
950 omalpha[0] = 1. - 1.4;
951 omalpha[1] = 1. - 2.3;
953 ene_line[1] = 18. *
keV;
956 if (Emin > 18 * keV) {
957 omalpha[0] = 1. - 2.3;
965 while (rndm >= CDGhist[i]) {
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
972 particle_energy = std::pow(particle_energy, (1. / omalpha[i - 1]));
974 if (verbosityLevel >= 1)
978 void G4SPSEneDistribution::GenUserHistEnergies() {
981 if (IPDFEnergyExist ==
false) {
984 G4double bins[1024], vals[1024], sum;
987 if ((EnergySpec ==
false) && (particle_definition == NULL))
988 G4cout <<
"Error: particle definition is NULL" <<
G4endl;
992 G4cout <<
"Setting maxbin to 1024, other bins are lost" <<
G4endl;
995 if (DiffSpec ==
false)
999 vals[0] = UDefEnergyH(
size_t(0));
1001 for (ii = 1; ii < maxbin; ii++) {
1003 vals[ii] = UDefEnergyH(
size_t(ii)) + vals[ii - 1];
1004 sum = sum + UDefEnergyH(
size_t(ii));
1008 if (EnergySpec ==
false) {
1013 for (ii = 1; ii < maxbin; ii++) {
1014 vals[ii] = vals[ii] * (bins[ii] - bins[ii - 1]);
1018 for (ii = 0; ii < maxbin; ii++) {
1019 bins[ii] = std::sqrt((bins[ii] * bins[ii]) + (mass * mass))
1022 for (ii = 1; ii < maxbin; ii++) {
1023 vals[ii] = vals[ii] / (bins[ii] - bins[ii - 1]);
1025 sum = vals[maxbin - 1];
1028 for (ii = 0; ii < maxbin; ii++) {
1029 vals[ii] = vals[ii] / sum;
1034 IPDFEnergyExist =
true;
1035 if (verbosityLevel > 1)
1041 particle_energy = IPDFEnergyH.
GetEnergy(rndm);
1043 if (verbosityLevel >= 1)
1047 void G4SPSEneDistribution::GenArbPointEnergies() {
1048 if (verbosityLevel > 0)
1055 G4int nabove, nbelow = 0, middle;
1059 while (nabove - nbelow > 1) {
1060 middle = (nabove + nbelow) / 2;
1061 if (rndm == IPDFArbEnergyH(
size_t(middle)))
1063 if (rndm < IPDFArbEnergyH(
size_t(middle)))
1068 if (IntType ==
"Lin") {
1071 grad = Arb_grad[nbelow + 1];
1072 cept = Arb_cept[nbelow + 1];
1074 GenerateLinearEnergies(
true);
1075 }
else if (IntType ==
"Log") {
1078 alpha = Arb_alpha[nbelow + 1];
1080 GeneratePowEnergies(
true);
1081 }
else if (IntType ==
"Exp") {
1084 Ezero = Arb_ezero[nbelow + 1];
1086 GenerateExpEnergies(
true);
1087 }
else if (IntType ==
"Spline") {
1090 particle_energy = -1e100;
1092 while (particle_energy < Emin || particle_energy > Emax) {
1096 if (verbosityLevel >= 1)
1102 void G4SPSEneDistribution::GenEpnHistEnergies() {
1106 if (Epnflag ==
true)
1110 ConvertEPNToEnergy();
1116 if (IPDFEnergyExist ==
false) {
1118 G4double bins[1024], vals[1024], sum;
1122 vals[0] = UDefEnergyH(
size_t(0));
1124 for (ii = 1; ii < maxbin; ii++) {
1126 vals[ii] = UDefEnergyH(
size_t(ii)) + vals[ii - 1];
1127 sum = sum + UDefEnergyH(
size_t(ii));
1130 for (ii = 0; ii < maxbin; ii++) {
1131 vals[ii] = vals[ii] / sum;
1135 IPDFEnergyExist =
true;
1140 particle_energy = IPDFEnergyH.
GetEnergy(rndm);
1142 if (verbosityLevel >= 1)
1146 void G4SPSEneDistribution::ConvertEPNToEnergy() {
1151 if (particle_definition == NULL)
1159 G4int count, maxcount;
1163 if (maxcount > 1024) {
1164 G4cout <<
"Histogram contains more than 1024 bins!" <<
G4endl;
1165 G4cout <<
"Those above 1024 will be ignored" <<
G4endl;
1169 G4cout <<
"Histogram contains less than 1 bin!" <<
G4endl;
1173 for (count = 0; count < maxcount; count++) {
1176 evals[count] = EpnEnergyH(
size_t(count));
1180 for (count = 0; count < maxcount; count++) {
1181 ebins[count] = ebins[count] * Bary;
1187 Emax = ebins[maxcount - 1];
1191 for (count = 0; count < maxcount; count++) {
1200 if (atype ==
"energy") {
1201 UDefEnergyH = IPDFEnergyH = ZeroPhysVector;
1202 IPDFEnergyExist =
false;
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;
1218 particle_definition =
a;
1219 particle_energy = -1.;
1221 while ((EnergyDisType ==
"Arb") ? (particle_energy < ArbEmin
1222 || particle_energy > ArbEmax) : (particle_energy < Emin
1223 || particle_energy > Emax)) {
1225 GenerateBiasPowEnergies();
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();
1250 G4cout <<
"Error: EnergyDisType has unusual value" <<
G4endl;
1253 return particle_energy;
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;
1263 prob = cept + grad * ene;
1266 else if (EnergyDisType ==
"Pow") {
1267 if (prob_norm == 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);
1273 prob_norm = std::log(Emax) - std::log(Emin) ;
1276 prob = std::pow(ene, alpha)/prob_norm;
1278 else if (EnergyDisType ==
"Exp"){
1279 if (prob_norm == 1.) {
1280 prob_norm = -Ezero*(std::exp(-Emax/Ezero) - std::exp(Emin/Ezero));
1282 prob = std::exp(-ene / Ezero);
1285 else if (EnergyDisType ==
"Arb") {
1286 prob = ArbEnergyH.
Value(ene);
1292 G4cout <<
" Warning:G4SPSEneDistribution::GetProbability: prob<= 0. "<<prob <<
" "<<ene <<
G4endl;
1298 G4cout <<
"Error: EnergyDisType not supported" <<
G4endl;