1 | // ESAF : Euso Simulation and Analysis Framework |
---|
2 | // $Id: RadiativeProcessesCalculator.cc 2527 2006-03-02 13:40:43Z moreggia $ |
---|
3 | // Sylvain Moreggia created Jan, 9 2004 |
---|
4 | |
---|
5 | #include "RadiativeProcessesCalculator.hh" |
---|
6 | #include "EarthVector.hh" |
---|
7 | #include "Atmosphere.hh" |
---|
8 | #include <math.h> |
---|
9 | #include "BunchOfPhotons.hh" |
---|
10 | #include "SinglePhoton.hh" |
---|
11 | #include "EsafMsgSource.hh" |
---|
12 | #include "EsafRandom.hh" |
---|
13 | #include <TF1.h> |
---|
14 | |
---|
15 | ClassImp(RadiativeProcessesCalculator) |
---|
16 | |
---|
17 | using namespace TMath; |
---|
18 | |
---|
19 | |
---|
20 | //_____________________________________________________________________________ |
---|
21 | RadiativeProcessesCalculator::RadiativeProcessesCalculator() : EsafMsgSource() { |
---|
22 | // |
---|
23 | // ctor |
---|
24 | // |
---|
25 | } |
---|
26 | |
---|
27 | //_____________________________________________________________________________ |
---|
28 | RadiativeProcessesCalculator::~RadiativeProcessesCalculator() { |
---|
29 | // |
---|
30 | // dtor |
---|
31 | // |
---|
32 | } |
---|
33 | |
---|
34 | //_____________________________________________________________________________ |
---|
35 | void RadiativeProcessesCalculator::RandomDir(string type,EarthVector& dir, Double_t g) const { |
---|
36 | // |
---|
37 | // 'dir' is the incoming direction -> this method set dir to the scattering outgoing direction |
---|
38 | // get a random direction, sampling relevant scattering phase functions |
---|
39 | // |
---|
40 | |
---|
41 | Double_t theta(0); |
---|
42 | Double_t u1, u2; |
---|
43 | TRandom* rndm = EsafRandom::Get(); |
---|
44 | |
---|
45 | // get random theta, assuming isotropic distribution in phi |
---|
46 | // theta is the angle between incoming and outgoing directions |
---|
47 | if(type == "rayleigh") { |
---|
48 | // von neumann sampling -> much faster than using TF1 |
---|
49 | do { |
---|
50 | u1 = -1. + rndm->Rndm()*2.; |
---|
51 | u2 = rndm->Rndm() * 3./4.; |
---|
52 | } while(u2 >= (3./8. * (1. + u1*u1))); |
---|
53 | theta = acos(u1); |
---|
54 | } |
---|
55 | else if(type == "HG_mie") { |
---|
56 | Msg(EsafMsg::Panic) << "<RandomTheta> Mie scattering not implemented yet"<<MsgDispatch; |
---|
57 | if(g == -10) Msg(EsafMsg::Panic) << "<RandomTheta> Asymmetry parameter should be defined" <<MsgDispatch; |
---|
58 | } |
---|
59 | else Msg(EsafMsg::Panic) << "<RandomTheta> Wrong type of distribution : "<<type<<MsgDispatch; |
---|
60 | |
---|
61 | // then get a random direction |
---|
62 | EarthVector v = dir.Orthogonal(); |
---|
63 | v.Rotate(rndm->Rndm()*2.*Pi(),dir); |
---|
64 | EarthVector axis = v.Cross(dir); |
---|
65 | dir.Rotate(theta,axis); |
---|
66 | } |
---|
67 | |
---|
68 | //_____________________________________________________________________________ |
---|
69 | Double_t RadiativeProcessesCalculator::RayleighPhaseFunction(const EarthVector& bunchdir,const EarthVector& dir) const { |
---|
70 | // |
---|
71 | // rayleigh scattering phase function - Normalized when integrated over full solid angle |
---|
72 | // |
---|
73 | Double_t rtn; |
---|
74 | Double_t theta = dir.Angle(bunchdir); |
---|
75 | rtn = 3 * (1. + cos(theta)*cos(theta)) / (16.*Pi()); |
---|
76 | |
---|
77 | return rtn; |
---|
78 | } |
---|
79 | |
---|
80 | //_____________________________________________________________________________ |
---|
81 | Double_t RadiativeProcessesCalculator::Mie_HG_PhaseFunction(const EarthVector& bunchdir,const EarthVector& dir,Double_t g) const { |
---|
82 | // |
---|
83 | // Mie scattering phase function - Henyey-Greenstein parametrization |
---|
84 | // Normalized when integrated over full solid angle |
---|
85 | // |
---|
86 | Double_t rtn; |
---|
87 | Double_t theta = dir.Angle(bunchdir); |
---|
88 | rtn = 1./(4*Pi()) * (1 - g*g) / pow(1 - 2*g*cos(theta) + g*g,1.5); |
---|
89 | |
---|
90 | return rtn; |
---|
91 | } |
---|
92 | //_____________________________________________________________________________ |
---|
93 | Double_t RadiativeProcessesCalculator::GetMaxPhaseFunction(string type) const { |
---|
94 | // |
---|
95 | // returns maximum value of specified phase function (phase function is normalized when integrated over full solid angle) |
---|
96 | // |
---|
97 | Double_t rtn; |
---|
98 | if(type == "rayleigh") rtn = 3./(8.*Pi()); |
---|
99 | else Msg(EsafMsg::Panic) << "<GetMaxPhaseFunction> Wrong type of phase function : "<<type<<MsgDispatch; |
---|
100 | |
---|
101 | return rtn; |
---|
102 | } |
---|
103 | |
---|