00001
00015 #include <math.h>
00016
00017
00018
00019
00020
00021 #include <CLHEP/Random/RandomEngine.h>
00022 #include <CLHEP/Random/RandGeneral.h>
00023 #include <CLHEP/Random/JamesRandom.h>
00024
00025 #include "CrElectronReentrant.h"
00026
00027
00028 typedef double G4double;
00029
00030
00031
00032 namespace {
00033 const G4double pi = 3.14159265358979323846264339;
00034 const G4double restE = 5.11e-4;
00035
00036 const G4double lowE_reent = 0.1;
00037 const G4double highE_reent = 10.0;
00038
00039
00040
00041
00042
00043 const G4double INTEGRAL_reent = 17.812;
00044
00045
00046
00047 inline G4double beta(G4double E )
00048 {
00049 #if 0 // if E ~ restE
00050 return sqrt(1 - pow(E/restE+1, -2));
00051 #else // if E >> restE
00052 return 1.0;
00053 #endif
00054 }
00055
00056
00057
00058 inline G4double rigidity(G4double E )
00059 {
00060 #if 0 // if E ~ restE
00061 return sqrt(pow(E + restE, 2) - pow(restE, 2));
00062 #else // if E >> restE
00063 return E;
00064 #endif
00065 }
00066
00067
00068
00069 inline G4double energy(G4double rigidity )
00070 {
00071 #if 0 // if energy ~ restE
00072 return sqrt(pow(rigidity, 2) + pow(restE, 2)) - restE;
00073 #else // if energy >> restE
00074 return rigidity;
00075 #endif
00076 }
00077
00078
00079
00080
00094 const G4double A_reent = 1.33e-4;
00095 const G4double a_reent = 3.53;
00096
00097 const G4double Cut_E = 0.06;
00098 const G4double A_Envelope = 1.5e-04;
00099
00100
00101
00102 inline G4double reentrantCRspec(G4double E )
00103 {
00104 return A_reent * pow(E, -a_reent);
00105 }
00106
00107
00108
00109 inline G4double reentrantCRenvelope(G4double E )
00110 {
00111 return A_Envelope * pow(E, -a_reent) * exp(-pow(E/Cut_E, -a_reent+1));
00112 }
00113
00114
00115
00116 inline G4double reentrantCRenvelope_integral(G4double E )
00117 {
00118 return exp(-pow(E/Cut_E, -a_reent+1));
00119 }
00120
00121
00122
00123 inline G4double reentrantCRenvelope_integral_inv(G4double value)
00124 {
00125 return Cut_E * pow(-log(value), -1./(a_reent-1));
00126 }
00127
00128
00129
00130 G4double reentrantCRenergy(HepRandomEngine* engine)
00131 {
00132 G4double rand_min = reentrantCRenvelope_integral(lowE_reent);
00133 G4double rand_max = reentrantCRenvelope_integral(highE_reent);
00134
00135 double r, E;
00136
00137 while (1){
00138 r = engine->flat() * (rand_max - rand_min) + rand_min;
00139 E = reentrantCRenvelope_integral_inv(r);
00140
00141
00142 if (engine->flat() <= reentrantCRspec(E) / reentrantCRenvelope(E)){
00143 break;
00144 }
00145 }
00146 return E ;
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155 CrElectronReentrant::CrElectronReentrant()
00156 {
00157 ;
00158 }
00159
00160
00161 CrElectronReentrant::~CrElectronReentrant()
00162 {
00163 ;
00164 }
00165
00166
00167 std::pair<double,double> CrElectronReentrant::dir(double energy, HepRandomEngine* engine) const
00168
00169
00170
00171 {
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 double zenith_angle;
00182 while (1){
00183 zenith_angle = acos(engine->flat());
00184 if (engine->flat()*1.6<1+0.6*sin(zenith_angle)){break;}
00185 }
00186
00187 double azimuth = engine->flat() * 2 * pi;
00188
00189 return std::pair<double,double>(cos(zenith_angle), azimuth );
00190 }
00191
00192
00193 double CrElectronReentrant::energySrc(HepRandomEngine* engine) const
00194 {
00195 return reentrantCRenergy(engine);
00196 }
00197
00198
00199 double CrElectronReentrant::flux() const
00200 {
00201
00202
00203
00204
00205
00206
00207
00208 return 0.5 * (1 + 0.15*pi) * INTEGRAL_reent;
00209 }
00210
00211
00212 double CrElectronReentrant::solidAngle() const
00213 {
00214 return 2 * pi;
00215 }
00216
00217
00218 const char* CrElectronReentrant::particleName() const
00219 {
00220 return "e-";
00221 }
00222
00223
00224 float CrElectronReentrant::operator()(float r)
00225 {
00226 HepJamesRandom engine;
00227 engine.setSeed(r * 900000000);
00228
00229
00230 return (float)energySrc(&engine);
00231 }
00232
00233
00234 double CrElectronReentrant::calculate_rate(double old_rate)
00235 {
00236 return old_rate;
00237 }
00238
00239
00240 float CrElectronReentrant::flux(float latitude, float longitude) const
00241 {
00242 return flux();
00243 }
00244
00245
00246 float CrElectronReentrant::flux(std::pair<double,double> coords) const
00247 {
00248 return flux();
00249 }
00250
00251
00252 std::string CrElectronReentrant::title() const
00253 {
00254 return "CrElectronReentrant";
00255 }
00256
00257
00258 float CrElectronReentrant::fraction(float energy)
00259
00260 {
00261 return 0;
00262 }
00263
00264
00265 std::pair<float,float> CrElectronReentrant::dir(float energy) const
00266 {
00267 HepJamesRandom engine;
00268
00269 std::pair<double,double> d = dir(energy, &engine);
00270
00271 return std::pair<float,float>(d.first, d.second);
00272 }