source: JEM-EUSO/esaf_lal/tags/v1_r0/esaf/packages/simulation/detector/optics/src/ParamOpticalSystem.cc @ 117

Last change on this file since 117 was 117, checked in by moretto, 11 years ago

ESAF version compilable on mac OS

File size: 12.2 KB
Line 
1// $Id: ParamOpticalSystem.cc 2922 2011-06-12 14:21:23Z mabl $
2// Author: A.Thea   2004/07/19
3
4/*****************************************************************************
5 * ESAF: Euso Simulation and Analysis Framework                              *
6 *                                                                           *
7 *  Id: ParamOpticalSystem                                                   *
8 *  Package: Optics                                                          *
9 *  Coordinator: Alessandro.Thea                                             *
10 *                                                                           *
11 *****************************************************************************/
12
13//_____________________________________________________________________________
14// 
15//   Parameterized Optical System
16//   ============================
17//
18//   Parameterized optical system. This Optical System is done to reproduce the
19//   behaviour of an optics design through a set of parameters.
20//   The main purpose is to simulate and OS with a given Triggering efficacy
21//   without the need of the full MC simulation.
22//
23//   ParamOpticalSystem behaves as an ideal optical system with a given focal
24//   surface.
25//
26//   The position an incoming photon hits the focal surface is calculated
27//   accordingly the relation
28//
29//   d = (Dmax/ThetaMax)*theta
30//
31//   where:
32//   d is the distance of the impact point on the FS from the center of the FS
33//   calculated along the FS.
34//
35//   Dmax is the maximum distance.
36//
37//   theta is the angle between the incoming photon direction and the optical
38//   axis.
39//
40//   ThetaMax is the maximum value of theta accepted by the optics.
41//
42// 
43//   Config file parameters
44//   ======================
45//
46//   fPos.Z [mm]: Z coordinate of the bottom base of the OpticalSystem in
47//   the Detector Reference System.
48//
49//   fRadius [mm]: Radius of the Optical Sytem.
50//
51//   fRmax [mm]: Maximum radius of the Focal Surface.
52//
53//   fDZ [mm]: Heigth of the Optical System.
54//
55//   fThetaMax [deg]: Maximum valid incident angle of an incoming photon.
56//
57//   fFocalSurfaceZ [mm]: Z coordinate of the center (tip) of the focal
58//   surface.
59//
60//   fDataDirectory: path where data files are stored. If it begins with '/'
61//   path is assumed to be absolute, otherwise relative to this cfg file current
62//   position
63//   
64//   fTotalEfficacy.fFilename [string]: two column file containing the
65//   total efficacy as a function of the incident angle.
66//   
67//   fAnglesOfIncidence.fFilename [string]: two column file containing the chief
68//   ray incident angle on the focal surface as a function of the incident
69//   angle on the pupil.
70//
71//   fPsfType [string]: type of PSF to use.
72//   * options
73//      - point: No spread.
74//      - gauss: Gaussian psf. RMS and angles of incidence listed in
75//               fGaussSpread.filename
76//
77//   fGaussSpread.fFilename [string]: three column file containing RMS of the
78//   gaussian psf and focal surface incident photons cone aperture.
79//
80//BEGIN_HTML <!--
81/* -->
82<!--*/
83// -->END_HTML
84//
85
86#include "ParamOpticalSystem.hh"
87#include "Config.hh"
88#include "Etypes.hh"
89#include "EConst.hh"
90#include "EsafRandom.hh"
91#include "IdealFocalSurface.hh"
92#include "KIdealFocalSurface.hh"
93#include "JIdealFocalSurface.hh"
94
95using namespace sou;
96using namespace TMath;
97using namespace EConst;
98
99const Double_t kThetaTolerance = 0.1*deg;
100
101ClassImp(ParamOpticalSystem)
102
103//_____________________________________________________________________________
104ParamOpticalSystem::ParamOpticalSystem() : fTotalEfficacy(0), fGaussSpread(0),
105    fIntegral(0) {
106    //
107    // Constructor
108    //
109
110    ConfigFileParser *pC = Conf();
111
112    string config = Conf()->GetStr("ParamOpticalSystem.fUseConfig");
113
114    // path of the config dir
115    string path;
116    path = path+ClassType()+'/'+ClassName()+'/'+ config;
117
118    ConfigFileParser *myParser = Config::Get()->GetCF(ClassType(),config,path+".cfg");
119
120    pC = myParser;
121
122    fPos           = EVector(0,0,pC->GetNum("ParamOpticalSystem.fPos.Z")*mm);
123    fR             = pC->GetNum("ParamOpticalSystem.fR")*mm;
124
125    fDZup          = pC->GetNum("ParamOpticalSystem.fDZup")*mm;
126
127    fRmax          = pC->GetNum("ParamOpticalSystem.fRmax")*mm;
128    fThetaMax      = pC->GetNum("ParamOpticalSystem.fThetaMax")*deg;
129    fOutLensBorder = pC->GetNum("ParamOpticalSystem.fOutLensBorder")*mm;
130
131    fDmax          = 0*mm;
132
133    fNbins         = 1000;
134
135    string dummy;
136
137    // set the descriptor of the focal surface descriptor
138    dummy = pC->GetStr("ParamOpticalSystem.fFSDescriptor") ;
139    if ( dummy == "Ideal" ) {
140        // in case of ideal focal surface descriptor build it
141        fFSDescriptor = kIdeal;
142        dummy = pC->GetStr("ParamOpticalSystem.fIdealFS.fType") ;
143        if ( dummy == "KIdeal" )
144            fIdealFocalSurface = new KIdealFocalSurface();
145        else if ( dummy == "JIdeal" )
146            fIdealFocalSurface = new JIdealFocalSurface();
147        else
148            FatalError("Ideal focal surface type "+dummy+" unknown");
149    } else
150        FatalError("fFSDescriptor: "+dummy+"\" is not a valid option.");
151
152    string datadir   = pC->GetCfgDir()+'/'+path+'/'; 
153
154    // define point spread function
155    string type     = pC->GetStr("ParamOpticalSystem.fPsfType");
156    if ( type == "gauss" ) { 
157        fPsfType    = kGauss;
158        fGaussAmpl  = pC->GetNum("ParamOpticalSystem.fGaussAmpl");
159        fGaussSigma = pC->GetNum("ParamOpticalSystem.fGaussSigma");
160    } else if ( type == "gaussVsTheta" ) {
161        fPsfType = kGaussVsTheta;
162        // load gaussian shapes from datafile
163        string gaussfile = datadir+pC->GetStr("ParamOpticalSystem.fGaussSpread.fFilename");
164        fGaussSpread     = new Interpolate( gaussfile ,2);
165    } else if ( type == "point" ) {
166        fPsfType = kPoint;
167    }
168    else
169        FatalError("fPsfType: "+type+" is not a valid option.");
170   
171    string toteffile = datadir+pC->GetStr("ParamOpticalSystem.fTotalEfficacy.fFilename");
172    fTotalEfficacy   = new Interpolate( toteffile );
173
174    fEPD             = pC->GetNum("ParamOpticalSystem.fEPD");
175
176    fSpreadFun       = new TF2("spreadgauss", "xygaus", -10, 10, -10, 10);
177
178    fSpreadFun->SetNpx(200);
179    fSpreadFun->SetNpy(200);
180
181    fSpreadFun->SetParameter(0,1.); // normalization
182    fSpreadFun->SetParameter(1,0.); // psf center - X
183    fSpreadFun->SetParameter(3,0.); // psf center - Y
184    fSpreadFun->SetParameter(2,1.); // psf rms - X
185    fSpreadFun->SetParameter(4,1.); // psf rms - Y
186
187    InitIntegral();
188}
189
190//_____________________________________________________________________________
191ParamOpticalSystem::~ParamOpticalSystem() {
192    //
193    // Destructor
194    //
195
196    if ( fIdealFocalSurface ) delete fIdealFocalSurface;
197    if ( fIntegral )          delete [] fIntegral;
198    if ( fGaussSpread)        delete fGaussSpread;
199    if ( fSpreadFun )         delete fSpreadFun;
200
201}
202
203//______________________________________________________________________________
204Bool_t ParamOpticalSystem::InitIntegral() {
205    //
206    // Initialize integral tables
207    //
208
209    if ( fIntegral ) delete [] fIntegral;
210
211    fIntegral = new Double_t[fNbins+1];
212
213    fIntegral[0] = 0;
214    Double_t dz, step, r;
215    Double_t dr = (fRmax/fNbins);
216
217    for( Int_t i(1); i < fNbins+1; i++ ) {
218        r = dr*i;
219        dz = FocalSurfProfile(r)-FocalSurfProfile(r-dr); 
220        step = Sqrt( dr*dr+dz*dz );
221        fIntegral[i] = fIntegral[i-1]+step;
222    }
223
224    // fDmax is the length from center to the border of the focal surface
225
226    fDmax = fIntegral[fNbins];
227   
228    return kTRUE;
229}
230   
231
232//______________________________________________________________________________
233Photon *ParamOpticalSystem::Transport(Photon *ph) const {
234    //
235    // Transport photon through the optics
236    //
237
238    Double_t th  = ph->dir.Theta();
239    Double_t phi = ph->dir.Phi();
240    Double_t wl  = ph->wl;
241
242    // check geometry
243    if ( ph->pos.Perp() > fEPD/2. ) {
244        ph->fate = kOutOfPupil;
245        return 0;
246    }
247
248    // check incident angle
249    if ( (fThetaMax-th) < kThetaTolerance ) {
250        ph->fate = kOutOfFoV;
251        return 0;
252    }
253
254    // check system absorption
255    if ( IsAbsorbed( th, wl ) ) {
256        ph->fate = kAbsorbed;
257        return 0;
258    }
259
260    // distance from focal surface center
261    Double_t d = (fDmax/fThetaMax)*th;
262
263    // find the position in cyl coordinates
264    Double_t r = DistanceToRadius( d );
265
266    Double_t z = FocalSurfProfile( r );
267
268    // r,z and phi are the coordinates on the focal surface
269    TVector3 center(r, 0, z);
270
271    Double_t step, tg;
272    step = (fRmax/fNbins)*0.1;
273
274    tg = (FocalSurfProfile(r+step)-FocalSurfProfile(r))/(step);
275    TVector3 xAxis(1, 0, tg);
276    TVector3 yAxis(0, 1, 0);
277    TVector3 zAxis(-tg, 0, 1);
278    TVector3 chiefDir;
279
280    xAxis.SetMag(1);
281    zAxis.SetMag(1);
282
283    TVector3 pos;
284    TVector3 fspos;
285    TVector3 dir;
286
287    // add spread
288    Double_t dx, dy, a, b;
289    if ( Spread( th, wl, dx, dy, a, b) ) {
290        // the ph is inside the psf
291        fspos = center+dx*xAxis+dy*yAxis; 
292        /*
293           dir.Rotate(a, yAxis);
294           dir.Rotate(b, chiefDir);
295         */
296        dir.RotateZ( phi );
297        fspos.RotateZ( phi );
298    } else {
299        // the photon is somewhere on the focal surface
300        ph->pos[Z] = SecondLensTop();
301        ph->fate = kOutOfPsf;
302        return 0;
303    }
304
305    TRandom *rndm = EsafRandom::Get();
306    Double_t rho = (fR-fOutLensBorder)*Sqrt(rndm->Rndm());
307    Double_t alpha = rndm->Rndm()*TMath::TwoPi();
308
309    pos.SetXYZ(rho*Cos(alpha),rho*Sin(alpha),SecondLensTop());
310    dir = (fspos-pos).Unit();
311
312    ph->time += (ph->pos-pos).Mag()/Clight();
313    ph->pos = pos;
314    ph->dir = dir;
315
316    return ph;
317
318}
319
320//______________________________________________________________________________
321Double_t ParamOpticalSystem::FocalSurfProfile( Double_t r ) const {
322    //
323    // Profile of the focal surface Z(r)
324    //
325
326    if ( r < 0 || r > fRmax ) return 0;
327
328    Double_t z;
329   
330    switch ( fFSDescriptor ) {
331        case kIdeal:
332        default:
333            if (!fIdealFocalSurface) FatalError("No ideal focal surface defined");
334            z = fIdealFocalSurface->Profile(r);       
335    }
336    return z;
337}
338   
339
340//______________________________________________________________________________
341Double_t ParamOpticalSystem::DistanceToRadius( Double_t d ) const {
342    //
343    // Distance from the fs vertex to r using linear interpolation
344    //
345
346    if ( (d < 0) || (d > fDmax) ) return -kHuge;
347
348    Int_t jl = 0;
349    Int_t ju = fNbins;
350
351    while ( ju-jl > 1 ) {
352        Int_t jm = (jl+ju)/2;
353        if ( d >= fIntegral[jm] )
354            jl = jm;
355        else
356            ju = jm;
357    }
358
359    Double_t rl = (fRmax/fNbins)*jl;
360    Double_t ru = (fRmax/fNbins)*ju;
361
362    Double_t r = rl+(d-fIntegral[jl])/(fIntegral[ju]-fIntegral[jl])*(ru-rl);
363   
364    return r;
365}
366
367//______________________________________________________________________________
368Bool_t ParamOpticalSystem::IsAbsorbed( Double_t th, Double_t wl) const {
369    //
370    // True if photon is absorbed
371    //
372
373    TRandom *r = EsafRandom::Get();
374   
375    Double_t area = Pi()*fEPD*fEPD/4.;
376    return (r->Rndm() > fTotalEfficacy->GetValue(th*RadToDeg())/(area*Cos(th)));
377   
378}
379
380//______________________________________________________________________________
381Bool_t ParamOpticalSystem::Spread( Double_t th, Double_t wl, Double_t &x,
382    Double_t &y, Double_t &a, Double_t &b ) const {
383    //
384    // Returns a random point (x,y) and angles (a,b) according psf(th,wl)
385    //
386
387    TRandom *r = EsafRandom::Get();
388           
389    switch ( fPsfType ) {
390        case kPoint:
391            x = 0;
392            y = 0; 
393            a = 0;
394            b = 0;
395            break;
396        case kGauss:
397            {
398                // check if the ray ends up in the psf
399                if ( r->Rndm() > fGaussAmpl ) return kFALSE;
400
401                fSpreadFun->GetRandom2(x,y);
402                x *= fGaussSigma;
403                y *= fGaussSigma;
404
405                break;
406            }
407        case kGaussVsTheta:
408            {
409                Double_t theta  = th*RadToDeg();
410
411                // check if the ray ends up in the psf
412                if ( r->Rndm() > fGaussSpread->GetValue(theta,kAmpl) ) return kFALSE;
413
414                Double_t sig = fGaussSpread->GetValue(theta, kSigma)*mm;
415
416                fSpreadFun->GetRandom2(x,y);
417                x *= sig;
418                y *= sig;
419
420                break;
421            }
422    }
423
424    return kTRUE;
425
426}
Note: See TracBrowser for help on using the repository browser.