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