Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CrElectronSplash.cxx

Go to the documentation of this file.
00001 
00013 #include <math.h>
00014 
00015 // Geant4
00016 //#include "Randomize.hh"               // in source/global/HEPRandom/include/
00017 //#include "SystemOfUnits.h"    // in source/global/management/include/
00018 // CLHEP
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 // private function definitions.
00030 namespace {
00031   const G4double pi    = 3.14159265358979323846264339;
00032   const G4double restE = 5.11e-4; // rest energy of electron in [GeV]
00033   // lower and higher energy limit of primary electron in units of GeV
00034   const G4double lowE_splash  = 0.1;
00035   const G4double highE_splash = 10.0;
00036 
00037   // The following value were computed from the model in advance.
00038   // This should be changed when the model is changed.
00039   // The integral should be done from lowE_* to highE_*.
00040   // FIX ME!!
00041   const G4double INTEGRAL_splash  = 17.812; // [m**-2 s**-1 Sr**-1]
00042 
00043 
00044 
00045   // gives v/c as a function of kinetic Energy
00046   inline G4double beta(G4double E /* GeV */)
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   // gives rigidity (GV) as a function of kinetic Energy
00057   inline G4double rigidity(G4double E /* GeV */)
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   // gives kinetic energy (GeV) as a function of rigidity
00068   inline G4double energy(G4double rigidity /* GV */)
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; // cutoff energy (GeV) used in envelope func.
00097   const G4double A_Envelope = 1.5e-04;
00098 
00099 
00100   // spectral model of splash cosmic-ray electrons
00101   inline G4double splashCRspec(G4double E /* GeV */)
00102   {
00103     return A_splash * pow(E, -a_splash);
00104   }
00105 
00106 
00107   // envelope function of splash cosmic-ray electrons
00108   inline G4double splashCRenvelope(G4double E /* GeV */)
00109   {
00110     return A_Envelope * pow(E, -a_splash) * exp(-pow(E/Cut_E, -a_splash+1));
00111   }
00112 
00113 
00114   // simplified integral of envelope function
00115   inline G4double splashCRenvelope_integral(G4double E /* GeV */)
00116   {
00117     return exp(-pow(E/Cut_E, -a_splash+1));
00118   }
00119 
00120 
00121   // inverse function of simplified integral of envelope function
00122   inline G4double splashCRenvelope_integral_inv(G4double value)
00123   {
00124     return Cut_E * pow(-log(value), -1./(a_splash-1));
00125   }
00126 
00127 
00128   // returns energy obeying splash cosmic-ray electron spectrum
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       // G4cerr << "E: " << E << ", splashCRspec(E): " << splashCRspec(E) << ", "
00140       // Gecerr << "splashCRenvelope(E)" << splashCRenvelope(E) << G4endl;
00141       if (engine->flat() <= splashCRspec(E) / splashCRenvelope(E)){
00142         break;
00143       }
00144     }
00145     return E;//THB * GeV;
00146   }
00147 } // End of noname-namespace: private function definitions.
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   // return: cos(zenith_angle) and azimuth [rad]
00168   // The downward has plus sign in cos(zenith_angle),
00169   // and azimuth = 0 from the east, +pi/2 from the north.
00170 {
00171   /***
00172    * Here we assume that
00173    *  zenith angle(theta): the flux (per steradian) is proportional to 1 + 0.6*sin(theta)
00174    *  azimuth angle(phi) : isotropic
00175    *
00176    * Reference:
00177    *   Tylka, A. J. 2000-05-12, GLAST team internal report "A Review of Cosmic-Ray Albedo Studies: 1949-1970" (1 + 0.6 sin(theta))
00178    */
00179 
00180   double zenith_angle=0.;
00181   while (1){
00182     zenith_angle = acos(engine->flat());//THB *rad;
00183     if (engine->flat()*1.6<1+0.6*sin(zenith_angle)){break;}
00184   }
00185   // upward
00186   zenith_angle = M_PI /*THB 180*deg*/  - zenith_angle;
00187 
00188   double azimuth = engine->flat() * 2 * pi;
00189 
00190   return  std::pair<double,double>(cos(zenith_angle), azimuth); //THB / rad);
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   // Integrated over the upper (sky-side) hemisphere.
00204   // Integral of sin(theta)*(1+0.6sin(theta)) in [0,pi/2].
00205   return  2*pi * (1 + 0.15*pi) * INTEGRAL_splash;  // [m**-2 s**-1]
00206   *****/
00207   // Integrated over the upper (sky-side) hemisphere.
00208   // Integral of sin(theta)*(1+0.6sin(theta)) in [0,pi/2].
00209   return  0.5 * (1 + 0.15*pi) * INTEGRAL_splash;  // [m**-2 s**-1 Sr**-1]
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   // 900000000 comes from HepJamesRandom::setSeed function's comment...
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 /*latitude*/, float /*longitude*/) const
00242 {
00243   return  flux();
00244 }
00245 
00246 
00247 float CrElectronSplash::flux(std::pair<double,double> /*coords*/) 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 /*energy*/)
00260 // This function doesn't work in this class... :-(
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 }

Generated at Wed Nov 21 12:20:33 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000