1 | // ESAF : Euso Simulation and Analysis Framework |
---|
2 | // class TestOpticalAdaptor |
---|
3 | // $Id: OpticalSystem.cc 2835 2009-07-16 03:22:42Z biktem $ |
---|
4 | // |
---|
5 | #include <TMath.h> |
---|
6 | #include "TRotation.h" |
---|
7 | |
---|
8 | #include "OpticalSystem.hh" |
---|
9 | #include "EsafRandom.hh" |
---|
10 | #include "EEvent.hh" |
---|
11 | #include "EConst.hh" |
---|
12 | |
---|
13 | using namespace sou; |
---|
14 | using namespace TMath; |
---|
15 | using namespace EConst; |
---|
16 | |
---|
17 | #define DEBUG |
---|
18 | |
---|
19 | ClassImp(OpticalSystem) |
---|
20 | ClassImp(TestOpticalSystem) |
---|
21 | |
---|
22 | //______________________________________________________________________________ |
---|
23 | TestOpticalSystem::TestOpticalSystem() : OpticalSystem() { |
---|
24 | fPos=EVector(0,0,Conf()->GetNum("TestOpticalSystem.pos.Z"))*mm; |
---|
25 | fDZup=Conf()->GetNum("TestOpticalSystem.DZup")*mm; |
---|
26 | fDZdown=Conf()->GetNum("TestOpticalSystem.DZdown")*mm; |
---|
27 | fFocalDistance=Conf()->GetNum("TestOpticalSystem.FocalDistance")*mm; |
---|
28 | fR=Conf()->GetNum("TestOpticalSystem.Radius")*mm; |
---|
29 | |
---|
30 | psf=new Interpolate("config/Optics/"+Conf()->GetStr("TestOpticalSystem.psf.filename")); |
---|
31 | tr=new Interpolate("config/Optics/"+Conf()->GetStr("TestOpticalSystem.tr.filename")); |
---|
32 | |
---|
33 | } |
---|
34 | |
---|
35 | //______________________________________________________________________________ |
---|
36 | Photon *TestOpticalSystem::Transport(Photon *p) const { |
---|
37 | |
---|
38 | // theta is the angle between the photon direction and the lens axis |
---|
39 | double theta=p->dir.Angle(EVector(0.,0.,1.)); |
---|
40 | if(theta > TMath::PiOver2()) theta=TMath::Pi() - theta; |
---|
41 | #ifdef DEBUG |
---|
42 | cout<<"position = "<<p->pos<<endl; |
---|
43 | cout<<"direction = "<<p->dir<<endl; |
---|
44 | cout<<"theta: "<<theta/TMath::Pi()*180.<<endl; |
---|
45 | #endif /* DEBUG */ |
---|
46 | |
---|
47 | // check if photon is in FOV (FOV=30 deg) |
---|
48 | if( theta > 30*deg) { |
---|
49 | // photon outside FOV |
---|
50 | // destroy it |
---|
51 | #ifdef DEBUG |
---|
52 | cout<<"photon outside FOV: destroyed"<<endl; |
---|
53 | #endif /* DEBUG */ |
---|
54 | p=0; |
---|
55 | return p; |
---|
56 | } |
---|
57 | // photon inside FOV |
---|
58 | |
---|
59 | // check if it is absorbed or refracted |
---|
60 | TRandom* rndm = EsafRandom::Get(); |
---|
61 | if(rndm->Rndm() > tr->GetValue(theta/deg)) { |
---|
62 | #ifdef DEBUG |
---|
63 | cout<<"photon absorbed by opticalSystem: destroyed"<<endl; |
---|
64 | #endif /* DEBUG */ |
---|
65 | p=0; |
---|
66 | return p; |
---|
67 | } |
---|
68 | |
---|
69 | EVector dir=p->dir.Unit(); |
---|
70 | |
---|
71 | // propagate photon to the center of the lens |
---|
72 | double DZ=(dir[Z]>0 ? fDZdown : -fDZup); |
---|
73 | EVector dummy=dir*(DZ/dir[Z]); |
---|
74 | p->time+=dummy.Mag()/Clight(); |
---|
75 | p->pos+=dummy; |
---|
76 | |
---|
77 | if(p->pos.Perp() > fR) { |
---|
78 | // hit wall |
---|
79 | #ifdef DEBUG |
---|
80 | cout<<"Hit Wall: "<<p->pos<<endl; |
---|
81 | #endif /* DEBUG */ |
---|
82 | p=0; |
---|
83 | return p; |
---|
84 | } |
---|
85 | |
---|
86 | // calculate new direction |
---|
87 | // This is for a plane focalplane |
---|
88 | // EVector newDir=dir*(fFocalDistance/fabs(dir[Z])) - (p->pos - fPos); |
---|
89 | |
---|
90 | // This is for a spherical focalplane with radius fFocalDistance |
---|
91 | // newDir is the point on the focal surface |
---|
92 | double thetain=p->dir.Theta(); // save original theta |
---|
93 | // used later for PSF |
---|
94 | EVector newDir=dir*fFocalDistance - (p->pos - fPos); |
---|
95 | p->dir=newDir.Unit(); |
---|
96 | |
---|
97 | // Point Spread Function |
---|
98 | EVector PSF=getPSF(p, thetain); |
---|
99 | newDir+=PSF; |
---|
100 | p->dir=newDir.Unit(); |
---|
101 | |
---|
102 | // propagate photon to the end of the lens |
---|
103 | dir=p->dir; |
---|
104 | DZ=(dir[Z]>0 ? fDZup : -fDZdown); |
---|
105 | dummy=dir*(DZ/dir[Z]); |
---|
106 | p->time+=dummy.Mag()/Clight(); |
---|
107 | p->pos+=dummy; |
---|
108 | |
---|
109 | p->pos[Z]=(dir[Z]>0 ? Top() : Bottom()); |
---|
110 | |
---|
111 | if(p->pos.Perp() > fR) { |
---|
112 | // hit wall |
---|
113 | #ifdef DEBUG |
---|
114 | cout<<"Hit Wall: "<<p->pos<<endl; |
---|
115 | #endif /* DEBUG */ |
---|
116 | p=0; |
---|
117 | return p; |
---|
118 | } |
---|
119 | |
---|
120 | #ifdef DEBUG |
---|
121 | cout<<"new position = "<<p->pos<<endl; |
---|
122 | cout<<"new direction = "<<p->dir<<endl; |
---|
123 | #endif /* DEBUG */ |
---|
124 | |
---|
125 | return p; |
---|
126 | } |
---|
127 | |
---|
128 | //______________________________________________________________________________ |
---|
129 | EVector TestOpticalSystem::getPSF(Photon *p, double thetain) const { |
---|
130 | // theta is the angle between the photon direction and the lens axis |
---|
131 | double theta=p->dir.Angle(EVector(0.,0.,1.)); |
---|
132 | if(theta > TMath::PiOver2()) theta=TMath::Pi() - theta; |
---|
133 | |
---|
134 | double psf_t=psf->GetValue(thetain/deg); |
---|
135 | #ifdef DEBUG |
---|
136 | cout<<"psf("<<thetain/deg<<"): "<<psf_t<<endl; |
---|
137 | #endif /* DEBUG */ |
---|
138 | |
---|
139 | TRandom* rndm=EsafRandom::Get(); |
---|
140 | double r=rndm->Gaus(0., psf_t); |
---|
141 | double phi=rndm->Rndm()*360.*deg; |
---|
142 | EVector psf_v(1,0,0); |
---|
143 | psf_v.SetPhi(phi); |
---|
144 | psf_v.SetMag(r); |
---|
145 | #ifdef DEBUG |
---|
146 | cout<<"psf_v: "<<psf_v<<endl; |
---|
147 | cout<<"p->dir: "<<p->dir<<endl; |
---|
148 | #endif /* DEBUG */ |
---|
149 | |
---|
150 | TRotation rot; |
---|
151 | EVector axis=p->dir.Cross(EVector(0.,0.,1.)); |
---|
152 | rot=rot.Rotate(-asin(axis.Mag()), axis.Unit()); |
---|
153 | psf_v.Transform(rot); |
---|
154 | |
---|
155 | #ifdef DEBUG |
---|
156 | cout<<"psf_v = "<<psf_v<<endl; |
---|
157 | cout<<"dot = "<<psf_v.Dot(p->dir)<<endl; |
---|
158 | #endif /* DEBUG */ |
---|
159 | |
---|
160 | return psf_v; |
---|
161 | } |
---|
162 | |
---|
163 | //______________________________________________________________________________ |
---|
164 | Bool_t OpticalSystem::HitSide(Photon *p) const{ |
---|
165 | // checks if p is going to hit the dead border of the optics when it's goint toward |
---|
166 | // the optics i.e. if it's going to hit the walls between lenses from outside |
---|
167 | |
---|
168 | |
---|
169 | Double_t dt = CylinderIntersection( p ); |
---|
170 | if (dt < 0 || (p->pos+p->dir*dt)[Z]-fDZup < kTolerance |
---|
171 | || (p->pos+p->dir*dt)[Z]-fDZdown < kTolerance ) |
---|
172 | return kFALSE; |
---|
173 | return kTRUE; |
---|
174 | } |
---|