00001
00002
00003
00004
00005
00006
00007 namespace {
00008
00009
00010
00011 float fromMeV ( float e ) { return e / 1000.; }
00012 }
00013
00014 #include "flux/ProtonSpectrum.h"
00015
00016 #include <algorithm>
00017
00018 float ProtonSpectrum::operator()(float r)const
00019 { return fromMeV( protonenergy( std::max(1e-6, 1.0-r)) );
00020 }
00021
00022
00023 #include <cmath>
00024 #include <algorithm>
00025 #include <functional>
00026
00027 #include "CLHEP/Random/Random.h"
00028 #include "flux/GPS.h"
00029
00030
00031 #include "SpectrumFactory.h"
00032
00033 static SpectrumFactory<ProtonSpectrum> factory;
00034 const ISpectrumFactory& ProtonSpectrumFactory = factory;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 struct tbl {float flux; float energy;};
00054
00055 int ProtonSpectrum::prolocate(struct tbl *data, int n, double x)
00056
00057
00058
00059 {
00060 int ju, jm, jl;
00061 int ascnd;
00062
00063 jl=0; ju=n+1;
00064 ascnd = (data[n-1].flux > data[0].flux);
00065 while (ju-jl > 1) {
00066 jm=(ju+jl) >>1;
00067 if ((x > data[jm-1].flux) == ascnd)
00068 jl = jm;
00069 else
00070 ju = jm;
00071 }
00072 return jl-1;
00073 }
00074
00075 #ifdef _MSC_VER
00076 # pragma warning(disable:4305) //warning C4305: 'initializing' : truncation from 'const double' to 'float'
00077 #endif //_MSC_VER
00078
00079 double ProtonSpectrum::protonenergy(float r)
00080 {
00081 static struct tbl
00082 datain[] = {
00083
00084 { 0.78953E+01 , 0.87096E+05 },
00085 { 0.87333E+01 , 0.81283E+05 },
00086 { 0.96432E+01 , 0.75857E+05 },
00087 { 0.10631E+02 , 0.70794E+05 },
00088 { 0.11704E+02 , 0.66069E+05 },
00089 { 0.12869E+02 , 0.61659E+05 },
00090 { 0.14133E+02 , 0.57544E+05 },
00091 { 0.15505E+02 , 0.53703E+05 },
00092 { 0.16993E+02 , 0.50118E+05 },
00093 { 0.18609E+02 , 0.46773E+05 },
00094 { 0.20361E+02 , 0.43651E+05 },
00095 { 0.22262E+02 , 0.40738E+05 },
00096 { 0.24323E+02 , 0.38019E+05 },
00097 { 0.26557E+02 , 0.35481E+05 },
00098 { 0.28980E+02 , 0.33113E+05 },
00099 { 0.31604E+02 , 0.30903E+05 },
00100 { 0.34447E+02 , 0.28840E+05 },
00101 { 0.37526E+02 , 0.26915E+05 },
00102 { 0.40858E+02 , 0.25119E+05 },
00103 { 0.44465E+02 , 0.23442E+05 },
00104 { 0.48365E+02 , 0.21878E+05 },
00105 { 0.52583E+02 , 0.20417E+05 },
00106 { 0.57140E+02 , 0.19055E+05 },
00107 { 0.62062E+02 , 0.17783E+05 },
00108 { 0.67375E+02 , 0.16596E+05 },
00109 { 0.73107E+02 , 0.15488E+05 },
00110 { 0.79286E+02 , 0.14454E+05 },
00111 { 0.85763E+02 , 0.13490E+05 },
00112 { 0.92247E+02 , 0.12589E+05 },
00113 { 0.98383E+02 , 0.11749E+05 },
00114 { 0.10390E+03 , 0.10965E+05 },
00115 { 0.10863E+03 , 0.10233E+05 },
00116 { 0.11257E+03 , 0.95499E+04 },
00117 { 0.11599E+03 , 0.89125E+04 },
00118 { 0.11906E+03 , 0.83176E+04 },
00119 { 0.12183E+03 , 0.77624E+04 },
00120 { 0.12435E+03 , 0.72443E+04 },
00121 { 0.12666E+03 , 0.67608E+04 },
00122 { 0.12878E+03 , 0.63096E+04 },
00123 { 0.13073E+03 , 0.58884E+04 },
00124 { 0.13247E+03 , 0.54954E+04 },
00125 { 0.13394E+03 , 0.51286E+04 },
00126 { 0.13507E+03 , 0.47863E+04 },
00127 { 0.13585E+03 , 0.44668E+04 },
00128 { 0.13635E+03 , 0.41687E+04 },
00129 { 0.13668E+03 , 0.38904E+04 },
00130 { 0.13691E+03 , 0.36308E+04 },
00131 { 0.13704E+03 , 0.33884E+04 },
00132 { 0.13710E+03 , 0.31623E+04 },
00133 { 0.13712E+03 , 0.29512E+04 },
00134 };
00135
00136 static int npts = sizeof(datain)/sizeof(datain[0]);
00137 double f = r*datain[npts-1].flux;
00138 if (f < datain[0].flux )
00139 return datain[0].energy *
00140 pow(f/ datain[0].flux, -0.61);
00141 else {
00142 int n = prolocate(datain, npts, f);
00143 return datain[n].energy + (datain[n+1].energy-datain[n].energy) *
00144 (f-datain[n].flux) / (datain[n+1].flux-datain[n].flux);
00145 }
00146 }
00147
00148
00149 double ProtonSpectrum::calculate_rate(double old_rate)
00150 {
00151 return old_rate;
00152 }
00153
00154 const char* ProtonSpectrum::particleName()const {
00155 return "p";
00156 }
00157
00158 std::string ProtonSpectrum::title()const {
00159 return "ProtonSpectrum";
00160 }
00161
00162