00001
00011 #include <math.h>
00012
00013
00014
00015
00016
00017 #include <CLHEP/Random/RandomEngine.h>
00018 #include <CLHEP/Random/RandGeneral.h>
00019 #include <CLHEP/Random/JamesRandom.h>
00020
00021 #include "CrProtonSplash.h"
00022
00023
00024 typedef double G4double;
00025
00026
00027
00028 namespace {
00029 const G4double pi = 3.14159265358979323846264339;
00030
00031 const G4double restE = 0.938;
00032
00033 const G4double lowE_splash = 0.1;
00034 const G4double highE_splash = 10.0;
00035
00036
00037
00038
00039
00040
00041 const G4double INTEGRAL_splash = 26.449;
00042
00043
00044
00045 inline G4double beta(G4double E ){
00046 return sqrt(1 - pow(E/restE+1, -2));
00047 }
00048
00049
00050 inline G4double rigidity(G4double E ){
00051 return sqrt(pow(E + restE, 2) - pow(restE, 2));
00052 }
00053
00054
00055 inline G4double energy(G4double rigidity ){
00056 return sqrt(pow(rigidity, 2) + pow(restE, 2)) - restE;
00057 }
00058
00059
00060
00072
00073 const G4double A_splash = 3.0e-3;
00074
00075 const G4double a_splash = 2.5;
00076
00077 G4double LOW_CUTOFF = 0.16;
00078
00079
00080
00081 inline G4double splashCRspec(G4double E , G4double cor , G4double phi ){
00082 return A_splash * pow(E, -a_splash) * exp(-pow(E/LOW_CUTOFF,-1));
00083 }
00084
00085
00086 inline G4double splashCRenvelope(G4double E , G4double cor , G4double phi ){
00087 return 2.04e-3*pow(LOW_CUTOFF,-0.3)*pow(E,-2.2)
00088 *exp(-pow(E/(LOW_CUTOFF*0.65),-1.2));
00089 }
00090
00091
00092 inline G4double splashCRenvelope_integral
00093 (G4double E , G4double cor , G4double phi ){
00094 return exp(-pow(E/(LOW_CUTOFF*0.65), -1.2));
00095 }
00096
00097
00098 inline G4double splashCRenvelope_integral_inv
00099 (G4double value, G4double cor , G4double phi ){
00100 return LOW_CUTOFF * 0.65 * pow(-log(value), 1./-1.2);
00101 }
00102
00103
00104 G4double splashCRenergy(HepRandomEngine* engine, G4double cor, G4double solarPotential){
00105 G4double rand_min =
00106 splashCRenvelope_integral(lowE_splash, cor, solarPotential);
00107 G4double rand_max =
00108 splashCRenvelope_integral(highE_splash, cor, solarPotential);
00109
00110 double r, E;
00111
00112 while(1){
00113 r = engine->flat() * (rand_max - rand_min) + rand_min;
00114 E = splashCRenvelope_integral_inv(r, cor, solarPotential);
00115 if (engine->flat() * splashCRenvelope(E, cor, solarPotential)
00116 < splashCRspec(E, cor, solarPotential)){
00117 break;
00118 }
00119 }
00120 return E ;
00121 }
00122
00123 }
00124
00125
00126
00127
00128
00129
00130 CrProtonSplash::CrProtonSplash()
00131 {
00132 ;
00133 }
00134
00135
00136 CrProtonSplash::~CrProtonSplash()
00137 {
00138 ;
00139 }
00140
00141
00142 std::pair<double,double> CrProtonSplash::dir(double energy, HepRandomEngine* engine) const
00143
00144
00145
00146 {
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 double zenith_angle;
00157 while (1){
00158 zenith_angle = acos(engine->flat());
00159 if (engine->flat()*1.6<1+0.6*sin(zenith_angle)){break;}
00160 }
00161
00162 zenith_angle = M_PI - zenith_angle;
00163
00164 double azimuth = engine->flat() * 2 * pi;
00165
00166 return std::pair<double,double>(cos(zenith_angle), azimuth);
00167 }
00168
00169
00170 double CrProtonSplash::energySrc(HepRandomEngine* engine) const
00171 {
00172 return splashCRenergy(engine, m_cutOffRigidity, m_solarWindPotential);
00173 }
00174
00175
00176 double CrProtonSplash::flux() const
00177 {
00178
00179
00180
00181
00182
00183
00184
00185 return 0.5 * (1 + 0.15*pi) * INTEGRAL_splash;
00186 }
00187
00188
00189 double CrProtonSplash::solidAngle() const
00190 {
00191 return 2 * pi;
00192 }
00193
00194
00195 const char* CrProtonSplash::particleName() const
00196 {
00197 return "proton";
00198 }
00199
00200
00201 float CrProtonSplash::operator()(float r)
00202 {
00203 HepJamesRandom engine;
00204 engine.setSeed(r * 900000000);
00205
00206
00207 return (float)energySrc(&engine);
00208 }
00209
00210
00211 double CrProtonSplash::calculate_rate(double old_rate)
00212 {
00213 return old_rate;
00214 }
00215
00216
00217 float CrProtonSplash::flux(float latitude, float longitude) const
00218 {
00219 return flux();
00220 }
00221
00222
00223 float CrProtonSplash::flux(std::pair<double,double> coords) const
00224 {
00225 return flux();
00226 }
00227
00228
00229 std::string CrProtonSplash::title() const
00230 {
00231 return "CrProtonSplash";
00232 }
00233
00234
00235 float CrProtonSplash::fraction(float energy)
00236
00237 {
00238 return 0;
00239 }
00240
00241
00242 std::pair<float,float> CrProtonSplash::dir(float energy) const
00243 {
00244 HepJamesRandom engine;
00245
00246 std::pair<double,double> d = dir(energy, &engine);
00247
00248 return std::pair<float,float>(d.first, d.second);
00249 }
00250