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

AlbedoPSpectrum.cxx

Go to the documentation of this file.
00001 // $Id: AlbedoPSpectrum.cxx,v 1.6 2002/06/24 22:37:15 srobinsn Exp $
00002 
00003 
00004 #include "AlbedoPSpectrum.h"
00005 
00006 #include <cmath>
00007 #include <algorithm>
00008 #include <functional>
00009 #include "CLHEP/Random/Random.h"
00010 #include "GPS.h"
00011 #include "Geomag.h"
00012 #include "SpectrumFactory.h"
00013 
00014 static SpectrumFactory<AlbedoPSpectrum> factory;
00015 const ISpectrumFactory& AlbedoPSpectrumFactory = factory;
00016 
00017 
00019 void AlbedoPSpectrum::init(const std::vector<float>& params) {
00020     
00021     float lat =  params.size()>0? params[0]: 0.0f;
00022     float lon =  params.size()>1? params[1]: 0.0f;
00023     setPosition(lat, lon);
00024     
00025     m_particle_name = "p";
00026     
00027     // set callback to be notified when the position changes
00028     m_observer.setAdapter( new ActionAdapter<AlbedoPSpectrum>
00029         (this, &AlbedoPSpectrum::askGPS) );
00030     
00031     GPS::instance()->notification().attach( &m_observer );
00032     
00033 }
00034 
00035 
00036 //-------------------------- constructors---------------------
00037 
00039 AlbedoPSpectrum::AlbedoPSpectrum(const std::string& paramstring) {
00040     std::vector<float> params;
00041     
00042     parseParamList(paramstring,params);
00043     
00044     init(params);
00045 }
00046 
00047 
00048 //------------------------ title()
00049 
00051 std::string AlbedoPSpectrum::title() const {
00052     return "AlbedoPSpectrum";
00053 }
00054 
00055 //------------------------- particleName
00056 
00058 const char * AlbedoPSpectrum::particleName() const {
00059     return m_particle_name.c_str();
00060 }
00061 
00062 //-------------------------- setParticleName
00063 
00065 void AlbedoPSpectrum::setParticleName(std::string name)
00066 {
00067     m_particle_name = name;
00068 }
00069 
00070 //-------------------------- flux() (current position)
00071 
00073 double AlbedoPSpectrum::flux(double) const {
00074     return m_flux;
00075 }
00076 
00077 //--------------------------
00078 
00080 double AlbedoPSpectrum::solidAngle() const
00081 {
00082     return 4.*M_PI;
00083 }
00084 
00085 //-------------------------- flux() (specified position)
00086 
00090 float AlbedoPSpectrum::flux(float lat, float lon) const {
00091     double v1,v2, alf1, alf2, emin, emax, Ejoin;
00092     fitParams(lat, lon, alf1, alf2, emin, emax, v1, v2, Ejoin);
00093     // The factor 1.47 is induced by the assumed angular dependence.
00094     return 1.47 * (v1+v2);
00095 }
00096 
00097 //-------------------------- flux() (position given in a pair)
00098 
00100 float AlbedoPSpectrum::flux( std::pair<double,double> coords) const {
00101     return flux(coords.first, coords.second);
00102 }
00103 
00104 //-------------------------- operator()  sample an energy value
00105 
00109 float AlbedoPSpectrum::operator() (float x) const{
00110     double v1,v2, alf1, alf2, emin, emax, Ejoin;
00111     fitParams(m_lat, m_lon, alf1, alf2, emin, emax, v1, v2, Ejoin);
00112     double split = v1/(v1+v2);
00113     if (x > split) {
00114         return pow((pow(Ejoin,1.-alf2)+((1.-x)/(1.-split))*(pow(emax,1.-alf2)
00115             -pow(Ejoin,1.-alf2))), 1./(1.-alf2));
00116     } else {
00117         return pow((pow(emin,1.-alf1)+(x/split)*(pow(Ejoin,1.-alf1)
00118             -pow(emin,1.-alf1))), 1./(1.-alf1));
00119     }
00120 }
00121 
00122 //-------------------------- askGPS()
00123 
00125 int AlbedoPSpectrum::askGPS()
00126 {
00127     setPosition(GPS::instance()->lat(), GPS::instance()->lon());
00128     return 0; // can't be void in observer pattern
00129 }
00130 
00131 //-------------------------- setPosition(separate coordinates)
00133 void AlbedoPSpectrum::setPosition(float lat, float lon) {
00134     m_lat = lat;
00135     m_lon = lon;
00136     m_flux = flux(lat, lon);
00137 }
00138 
00139 //-------------------------- setPosition (coordinates packaged in a pair)
00141 void AlbedoPSpectrum::setPosition( std::pair<double,double> coords) {
00142     AlbedoPSpectrum::setPosition(coords.first, coords.second);
00143 }
00144 
00145 //------------------------- calculate_rate()
00147 double AlbedoPSpectrum::calculate_rate(double old_rate)
00148 {
00149     return flux(GPS::instance()->lat(), GPS::instance()->lon());
00150 }
00151 
00152 //-------------------------- dir()
00155 std::pair<float,float> AlbedoPSpectrum::dir(float energy)const
00156 {
00157     // Random particle direction
00158     
00159     float coszenith, earthazi,dens,v;
00160     const int try_max = 1000;
00161     static int max_tried = 0;
00162     int trial = 0;
00163     earthazi = 2. * M_PI * HepRandom::getTheGenerator()->flat();
00164     do {
00165         coszenith = 2. * HepRandom::getTheGenerator()->flat() - 1.;
00166         dens = 1. + 0.6 * sqrt(1.-coszenith*coszenith);
00167         v = 1.6 * HepRandom::getTheGenerator()->flat();
00168     } while (v > dens && trial++ < try_max);
00169     
00170     max_tried = std::max(trial, max_tried);
00171     
00172     return std::make_pair<float,float>(coszenith, earthazi);
00173 }
00174 
00175 //------------------------- fitParams()
00188 void AlbedoPSpectrum::fitParams(const double lat, const double lon, 
00189                                 double& alf1, double& alf2, double& emin, double& emax, 
00190                                 double& v1, double &v2, double& Ejoin) const
00191 {
00192     double theta = abs(Geomag::geolat(lat,lon)) * M_PI / 180.;
00193     double e1 = .2;  // pivot point of lower power law
00194     double e2 = 1.;  // pivot point of higher power law
00195     emin = .01;      
00196     emax = 10.;
00197     // normalization values of the two power laws
00198     double a1 = 0.142 + theta * (-.4809 + theta * .5517);
00199     double a2 = .0499 + theta * (-.3239 + theta * (.8077 + theta * (-.8800 + 
00200         theta * .3607)));
00201     alf1 = .4913 + theta * (2.017 + theta * (-.6941 - 1.49 * theta));
00202     alf2 = 2.85 - .875 * theta;
00203     Ejoin = pow(a1*pow(e1,alf1) / (a2*pow(e2,alf2)), 1./(alf1-alf2));
00204     v1 = 1000.*a1*pow(e1,alf1)*(pow(Ejoin,1.-alf1)-pow(emin,1.-alf1))
00205         /(1.-alf1);  // integral of lower power law
00206     v2 = 1000.*a2*pow(e2,alf2)*(pow(emax,1.-alf2)-pow(Ejoin,1.-alf2)) 
00207         /(1.-alf2);  // integral of upper power law
00208 }

Generated on Wed Oct 16 14:01:28 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001