source: JEM-EUSO/esaf_cc_at_lal/packages/simulation/detector/optics/src/Ktrace_optF1v1.cc @ 114

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

actual version of ESAF at CCin2p3

File size: 27.6 KB
Line 
1/* -------------------------------------------------------------------------
2 *   trace_optF1v1.c
3 *
4 *   --- main program of raytracing
5 *
6 * $Id: Ktrace_optF1v1.cc 2924 2011-06-12 20:22:13Z mabl $
7 * -------------------------------------------------------------------------
8 */
9#include <stdio.h>
10#include <stdlib.h>
11#include "TMath.h"
12#include "EsafRandom.hh"
13#include "Kspline.hh"
14#include "KEUSO_optF1v1.hh"
15#include "Kutils.hh"
16#include "Ktrace_optF1v1.hh"
17
18#define RT_SEARCH_ITER_MAX        100
19#define RT_INTERACTION_MAX         20
20
21#define X      0
22#define Y      1
23#define Z      2
24#define PX     3
25#define PY     4
26#define PZ     5
27#define L      6
28#define T      7
29
30/* lens surface data */
31static Int_t n_s1=0,n_s2=0,n_s5=0,n_s6=0;
32static Double_t sr1[S_DATA],sz1[S_DATA];
33static Double_t sr2[S_DATA],sz2[S_DATA];
34static Double_t sr5[S_DATA],sz5[S_DATA];
35static Double_t sr6[S_DATA],sz6[S_DATA];
36
37/* lens material data */
38static Int_t n_acryl=0, n_bg3=0;
39static Double_t ac_la[Acryl_N],ac_n[Acryl_N],ac_k[Acryl_N];
40static Double_t bg3_la[Bg3_N],bg3_n[Bg3_N],bg3_k[Bg3_N];
41
42/* diffractive structure data */
43static Int_t n_sd1=0, n_sd6=0;
44#define N_DIFFR_DATA   13000
45static Double_t SD1_R[N_DIFFR_DATA];
46static Double_t SD1_D[N_DIFFR_DATA];
47static Double_t SD6_R[N_DIFFR_DATA];
48static Double_t SD6_D[N_DIFFR_DATA];
49
50static Double_t Kref(Double_t n1, Double_t n2, Double_t ci, Double_t ct);
51static Int_t Kcheck_intersect_cylinder(Double_t r1, Double_t z1, Double_t r2, Double_t z2,
52                    Double_t phot[8], Double_t *dis);
53static Int_t Kcheck_intersect_cone    (Double_t r1, Double_t z1, Double_t r2, Double_t z2,
54                    Double_t phot[8], Double_t *dis);
55static Int_t KCheckIris(Double_t phot[6]);
56
57/*
58 * ========================================================================
59 * functions for diffractive optics start
60 * ========================================================================
61 */
62/*
63 * ------------------------------------------------------------------------
64 *  Calculate normal vector to the sphere approximating the lens surface
65 *  Input:
66 *    aX, aY, aZ: photon position on the lens surface
67 *    aCZ       : center of the approximated sphere
68 *
69 *  Output:
70 *    nnnDIFF[3]: normal unit vector
71 * ------------------------------------------------------------------------
72 */
73Int_t KCalSpheVec(Double_t aX, Double_t aY, Double_t aZ, Double_t aCZ, Double_t nnnDIFF[3])
74{
75       
76  Double_t N_;
77       
78  nnnDIFF[0] = aX;
79  nnnDIFF[1] = aY;
80  nnnDIFF[2] = aZ - aCZ;
81       
82  N_ = TMath::Sqrt(Kvdot(nnnDIFF,nnnDIFF));
83       
84  nnnDIFF[0] = nnnDIFF[0]/N_;
85  nnnDIFF[1] = nnnDIFF[1]/N_;
86  nnnDIFF[2] = nnnDIFF[2]/N_;
87
88  return 0;
89}
90
91
92/*
93 * ------------------------------------------------------------------------
94 *  read parameters of diffractive optics
95 *    Input:
96 *        dirname    the name of the directory name
97 *                        where data files are stored
98 *    Output:
99 *        (return value) status
100 * ------------------------------------------------------------------------
101 */
102Int_t KReadSD(const char *dirname)
103{
104  FILE *fr;
105  char Infname[128];
106       
107#ifdef DEBUG
108  fprintf(stderr,"Reading Diffractive Surface Data....  ");
109#endif
110
111  /* read diffractive optics data for S1 */
112  sprintf(Infname,"%.100s/SD1_F1v1.dat",dirname);
113       
114  if(( fr = fopen(Infname,"r" )) == NULL)
115    {
116      fprintf(stderr,"%s not OPEN\n",Infname );
117      return (-1);
118    }
119  n_sd1=0;
120  while(n_sd1<N_DIFFR_DATA
121    && fscanf(fr,"%lf %lf",&SD1_R[n_sd1],&SD1_D[n_sd1])==2)
122    n_sd1++;
123  fclose(fr);
124  if(n_sd1==N_DIFFR_DATA)
125    return (-2);
126
127  /* read diffractive optics data for S6 */
128  sprintf(Infname,"%.100s/SD6_F1v1.dat",dirname);
129       
130  if(( fr = fopen(Infname,"r" )) == NULL)
131    {
132      fprintf(stderr,"%s not OPEN\n",Infname);
133      return (-1);
134    }
135
136  n_sd6=0;
137  while(n_sd6<N_DIFFR_DATA && 
138    fscanf(fr,"%lf %lf",&SD6_R[n_sd6],&SD6_D[n_sd6])==2)
139    n_sd6++;
140  fclose(fr);
141
142  if(n_sd6==N_DIFFR_DATA)
143    return (-2);
144       
145#ifdef DEBUG
146  fprintf(stderr,"Done.\n");
147#endif
148  return (0);
149}
150
151/*
152 * ------------------------------------------------------------------------
153 *  calculate the diffractive structure
154 *   Input:
155 *      r   the distance in mm to the optical axis at the intersection point
156 *      s   surface ID (i.e. S1,S2,...)
157 *   Output:
158 *     (return value)
159 * ------------------------------------------------------------------------
160 */
161Double_t KCal_D(Double_t r, Int_t s) 
162{
163  Int_t i;
164
165  if(s==1)
166    {
167      i=Krt_bsearch(SD1_R,r,0,n_sd1-1);
168      return (SD1_D[i]);
169    }
170
171  if(s==6)
172    {
173      i=Krt_bsearch(SD6_R,r,0,n_sd6-1);
174      return (SD6_D[i]);
175    }
176
177  return 0.0;
178}
179
180/*
181 * ------------------------------------------------------------------------
182 *  calculate the diffracted ray
183 *  Input:
184 *        in_ph[3]      array x,y,z of photon
185 *        nnn[3]        normal vector to the diffractive surface
186 *                         at the intersection
187 *        n1            refractive index of xxx
188 *        n2            refractive index of xxx
189 *        d
190 *        wl            wavelength in mm
191 *        m             index
192 *  Output:
193 *        in_ph[3]
194 * ------------------------------------------------------------------------
195 */
196Int_t Kdiffract(Int_t ID, Double_t in_phdir[3], 
197         Double_t x3, Double_t y3, Double_t z3, Double_t Zc,
198         Double_t n1, Double_t n2, Double_t wl, Int_t m)
199{
200  Int_t    i;
201  Double_t CosIN, CosD, dir, nnnR[3], r3, ppp[3], nnn[3], d, norm;
202
203  r3=TMath::Sqrt(x3*x3+y3*y3);
204  nnnR[0]= x3/r3;
205  nnnR[1]= y3/r3;
206  nnnR[2]=0.0;
207
208  KCalSpheVec(x3, y3, z3, Zc, nnn);
209  d=KCal_D(r3,ID);
210
211  if(in_phdir[Z]>0.)
212    dir=1.0;
213  else
214    dir=-1.0;
215
216  CosIN=Kvdot(in_phdir,nnn);
217  CosD=Kvdot(nnn,nnnR);
218
219  for(i=0;i<3;i++)
220    ppp[i]=(n1*(in_phdir[i]-CosIN*nnn[i])
221      +(Double_t)m*wl/357.0e-6*d*(nnnR[i]-CosD*nnn[i])*dir)/n2;
222
223  norm=Kvdot(ppp,ppp);
224  if(norm>1.0)
225    return -1;
226
227  norm=TMath::Sqrt(1.0-norm);
228
229#ifdef DEBUG
230  fprintf(stderr,"Diffractive: (%.3f , %.3f , %.3f)=>",
231      in_phdir[0],in_phdir[1],in_phdir[2]);
232#endif
233
234  for(i=0;i<3;i++)
235    in_phdir[i]=ppp[i]+norm*nnn[i]*(CosIN>0.0?(1.0):(-1.0));
236
237#ifdef DEBUG
238  fprintf(stderr,"(%.3f , %.3f , %.3f)\n",in_phdir[0],in_phdir[1],in_phdir[2]);
239#endif
240
241  return (0);
242}
243       
244/*
245 * ========================================================================
246 * functions for diffractive optics END
247 * ========================================================================
248 */
249
250/*
251 * ------------------------------------------------------------------------
252 * calculate reflection probability assuming no polariation
253 *   n1,n2: refractive index of the media of this side and the other side
254 *   ci,ct: cosine of the incident light and reflected light to the surface
255 *          normal vector
256 * ------------------------------------------------------------------------
257 */
258static Double_t Kref(Double_t n1, Double_t n2, Double_t ci, Double_t ct)
259{
260  Double_t rp,rs;
261
262  rp=(n2*ci-n1*ct)/(n2*ci+n1*ct);
263  rs=(n1*ci-n2*ct)/(n1*ci+n2*ct);
264
265  return((rp*rp+rs*rs)/2.0);
266}
267
268/*
269 * ------------------------------------------------------------------------
270 *  read parameters of lens surface shapes, and optical indices
271 * ------------------------------------------------------------------------
272 */
273Int_t Kread_para(const char *dir)
274{
275  FILE *fp;
276  char filename[128];
277
278#ifdef DEBUG
279  fprintf(stderr,"Reading Surface Data....  ");
280#endif
281
282  /* Read S1 surface */
283  sprintf(filename,"%.100s/S1_F1v1.dat",dir);
284  if((fp=fopen(filename,"r"))==NULL)
285    return -1;
286  n_s1=0;
287  while(n_s1<S_DATA && 
288        fscanf(fp,"%lf %*f %*f %lf",&sr1[n_s1], &sz1[n_s1])!=EOF)
289    {
290      sz1[n_s1]=Sz1-sz1[n_s1];
291      n_s1++;
292    }
293  fclose(fp);
294
295  /* Read S2 surface */
296  sprintf(filename,"%.100s/S2_F1v1.dat",dir);
297  if((fp=fopen(filename,"r"))==NULL)
298    return -2;
299  n_s2=0;
300  while(n_s2<S_DATA && 
301        fscanf(fp,"%lf %*f %*f %lf",&sr2[n_s2], &sz2[n_s2])!=EOF)
302    {
303      sz2[n_s2]=Sz2-sz2[n_s2];
304      n_s2++;
305    }
306  fclose(fp);
307
308  /* Read S5 surface */
309  sprintf(filename,"%.100s/S5_F1v1.dat",dir);
310  if((fp=fopen(filename,"r"))==NULL)
311    return -5;
312  n_s5=0;
313  while(n_s5<S_DATA && 
314        fscanf(fp,"%lf %*f %*f %lf",&sr5[n_s5], &sz5[n_s5])!=EOF)
315    {
316      sz5[n_s5]=Sz5-sz5[n_s5];
317      n_s5++;
318    }
319  fclose(fp);
320
321  /* Read S6 surface */
322  sprintf(filename,"%.100s/S6_F1v1.dat",dir);
323  if((fp=fopen(filename,"r"))==NULL)
324    return -6;
325  n_s6=0;
326  while(n_s6<S_DATA &&
327        fscanf(fp,"%lf %*f %*f %lf",&sr6[n_s6], &sz6[n_s6])!=EOF)
328    {
329      sz6[n_s6]=Sz6-sz6[n_s6];
330      n_s6++;
331    }
332  fclose(fp);
333#ifdef DEBUG
334  fprintf(stderr,"Done.\n");
335
336  fprintf(stderr,"Reading Optical Data....   ");
337#endif
338
339  /* Read Acryl data */
340  sprintf(filename,"%.100s/Mitsubishi_000.dat",dir);
341  if((fp=fopen(filename,"r"))==NULL)
342    return -10;
343  n_acryl=0;
344  while(n_acryl<Acryl_N &&
345    fscanf(fp,"%lf %lf %lf",&ac_la[n_acryl],
346           &ac_n[n_acryl], &ac_k[n_acryl])!=EOF)
347    {
348      n_acryl++;
349    }
350  fclose(fp);
351
352  /* Read BG3 data */
353  sprintf(filename,"%.100s/bg3.dat",dir);
354  if((fp=fopen(filename,"r"))==NULL)
355    return -11;
356  n_bg3=0;
357  while(n_bg3<Bg3_N &&
358    fscanf(fp,"%lf %lf %lf",&bg3_la[n_bg3],
359           &bg3_n[n_bg3], &bg3_k[n_bg3])!=EOF)
360    {
361      n_bg3++;
362    }
363  fclose(fp);
364
365#ifdef DEBUG
366  fprintf(stderr,"Done.\n");
367#endif
368  return 0;
369}
370
371/*
372 * ------------------------------------------------------------------------
373 *  get refractive index of the acryl at wavelength lambda
374 *    using cubic spline interpolation
375 * ------------------------------------------------------------------------
376 */
377Double_t KGet_n_Acryl(Double_t lambda)
378{
379  static Int_t init=0;
380  static Double_t *z;
381
382  if(!init)
383    {
384      init=1;
385      if((z=(Double_t *)malloc(sizeof(Double_t)*n_acryl))==NULL)
386    return -1000.0;
387      Kcsp_maketable(ac_la, ac_n, z, n_acryl);
388    }
389
390  return Kcspline(lambda, ac_la, ac_n, z, n_acryl);
391}
392
393/*
394 * ------------------------------------------------------------------------
395 *  get extinction coefficient of the acryl at wavelength lambda
396 *    using cubic spline interpolation
397 * ------------------------------------------------------------------------
398 */
399Double_t KGet_k_Acryl(Double_t lambda)
400{
401  static Int_t init=0;
402  static Double_t *z;
403
404  if(!init)
405    {
406      init=1;
407      if((z=(Double_t *)malloc(sizeof(Double_t)*n_acryl))==NULL)
408    return -1000.0;
409      Kcsp_maketable(ac_la, ac_k, z, n_acryl);
410    }
411
412  return Kcspline(lambda, ac_la, ac_k, z, n_acryl);
413}
414
415/*
416 * ------------------------------------------------------------------------
417 *  get the refracted ray
418 *    if reflected it is thrown away.
419 *
420 *   in_ph[3]: incident photon vector (normalized)
421 *   nnn[3]  : surface normal vector (direct to this side)
422 *   n1,n2   : refractive indices of the media of this side and the other side
423 * ------------------------------------------------------------------------
424 */
425Int_t Krefract(Double_t in_phdir[3],Double_t nnn[3],Double_t n1,Double_t n2)
426{
427  Int_t i, TotalReflection=0;
428  Double_t CosIN, CosOUT=1.0, ppp[3], norm, out_phdir[3];
429
430  CosIN=Kvdot(in_phdir,nnn);
431  for(i=0;i<3;i++)
432    ppp[i]=(in_phdir[i]-CosIN*nnn[i])*n1/n2;
433
434  norm=Kvdot(ppp,ppp);
435#ifdef NO_REFLECTION
436  if(norm>1.0)
437    return(RT_NO_REFRACTED_LIGHT);  /* total reflection */
438#else
439  if(norm>1.0)
440    TotalReflection=1;
441  else
442    {
443#endif
444
445      norm=TMath::Sqrt(1.0-norm);
446      for(i=0;i<3;i++)
447    out_phdir[i]=ppp[i]+norm*nnn[i]*(CosIN>0.0?(1.0):(-1.0));
448
449#ifndef NO_REFLECTION
450      /* check reflection */
451      CosOUT=Kvdot(out_phdir,nnn);
452    }
453  TRandom *rndm = EsafRandom::Get();
454  if(TotalReflection==1 || rndm->Rndm() < Kref(n1,n2,CosIN,CosOUT))
455    { 
456      for(i=0;i<3;i++)
457    in_phdir[i]-=2.0*CosIN*nnn[i];
458      return(RT_REFLECTED);
459    }
460#endif
461
462  /* in_phdir[]: direction of incident ray -> refracted ray */
463  for(i=0;i<3;i++)
464    in_phdir[i]=out_phdir[i];
465
466  return(RT_REFRACTED);
467}
468
469/*
470 *
471 * check if there are any intersections with a cylinder
472 *
473 */
474static Int_t Kcheck_intersect_cylinder(Double_t r1, Double_t z1, Double_t r2, Double_t z2,
475                    Double_t phot[8], Double_t *dis)
476{
477  Double_t aa[3], xx[2], tmp, z;
478  Int_t    nroot, i;
479
480  aa[0] = phot[PX]*phot[PX] + phot[PY]*phot[PY];
481  aa[1] = 2.0*(phot[X]*phot[PX] + phot[Y]*phot[PY]);
482  aa[2] = (phot[X]*phot[X] + phot[Y]*phot[Y]) - r1*r1;
483
484  nroot=KSolveQuadratic(aa,xx);
485  if(nroot<2)
486    return(RT_NO_INTERSECTION1);
487
488  /* solution is the smaller positive value */
489  /* swap */
490  if(xx[0]>xx[1])
491    {
492      tmp=xx[0];
493      xx[0]=xx[1];
494      xx[1]=tmp;
495    }
496  if(xx[1]<0)
497    return(RT_NO_INTERSECTION1);
498
499  for(i=0;i<2;i++)
500    {
501      if(xx[i]>0.0)
502    {
503      z=phot[Z]+phot[PZ]*xx[i];
504      /* check if the solution is in the specified range */
505      if((z-z1)*(z-z2)<0)
506        {
507          *dis=xx[i];
508          return 0;
509        }
510    }
511    }
512
513  *dis=(xx[0]>0 ? xx[0]:xx[1]);
514  return(RT_NO_INTERSECTION2);
515}
516
517/*
518 *
519 * check if there are any intersections with a cone
520 *
521 */
522static Int_t Kcheck_intersect_cone(Double_t r1, Double_t z1, Double_t r2, Double_t z2,
523                Double_t phot[8], Double_t *dis)
524{
525  Double_t a00, a0, aa[3], xx[2], z0, dbuf1, tmp, x, y, r, zz[2];
526  Int_t    nroot, i;
527
528  a00 = (z2-z1)/(r2-r1);
529  z0  = z1-a00*r1;
530  a0  = a00*a00;
531
532  dbuf1 = phot[Z]-z0;
533  aa[0] = a0*phot[PX]*phot[PX] + a0*phot[PY]*phot[PY] - phot[PZ]*phot[PZ];
534  aa[1] = 2.0*(a0*phot[PX]*phot[X] + a0*phot[PY]*phot[Y] - phot[PZ]*dbuf1);
535  aa[2] = a0*phot[X]*phot[X] + a0*phot[Y]*phot[Y] - dbuf1*dbuf1;
536
537  nroot=KSolveQuadratic(aa,xx);
538  if(nroot<2)
539    return(RT_NO_INTERSECTION1);
540
541  /* solution is the smaller positive value */
542  /* swap */
543  if(xx[0]>xx[1])
544    {
545      tmp=xx[0];
546      xx[0]=xx[1];
547      xx[1]=tmp;
548    }
549  if(xx[1]<=0.0)
550    return(RT_NO_INTERSECTION1);
551
552  /* We usually have a solution on a virtual cone with -a00 */
553  /* check this condition */
554  for(i=0;i<2;i++)
555    if(xx[i]>0.0)
556      {
557    x=phot[PX]*xx[i]+phot[X];
558    y=phot[PY]*xx[i]+phot[Y];
559    zz[i]=phot[PZ]*xx[i]+phot[Z];
560    r=TMath::Sqrt(x*x+y*y);
561    if((r-r1)*(r-r2)<0.0)
562      {
563        *dis=xx[i];
564        return 0;
565      }
566      }
567
568  if(xx[0]<=0.0)
569    *dis=xx[1];
570  else
571    {
572      /* the nearer one to the surface will be what we want... */
573      if(fabs(zz[0]-z1)<fabs(zz[1]-z1))
574    *dis=xx[0];
575      else
576    *dis=xx[1];
577    }
578
579  return(RT_NO_INTERSECTION2);
580}
581
582/*
583 * ------------------------------------------------------------------------
584 *
585 *  ID:            Lens Surface ID
586 *  phot[8]: input and output photon data
587 *    phot[0,1,2]: x,y,z position in mm
588 *    phot[3,4,5]: l,m,n direction
589 *    phot[6]    : wavelength in nm
590 *    phot[7]    : time in ns
591 *  offset_z     : the offset z-position of sphare center approximating
592 *                 lens surface
593 *  radius       : the radius of sphare approximated lens surface
594 *  lens_r[],lens_z[]: lens surface data sets of the radius and the height
595 *  n_lens_elem  : number of data elements of lens_r[]
596 *  medium1_n, medium2_n: refractive indices of the media in this side
597 *                         and the other side
598 * ------------------------------------------------------------------------
599 */
600Int_t Klens_interaction(Int_t ID, Double_t phot[8],
601             Double_t Zc, Double_t radius,
602             Double_t *lens_r, Double_t *lens_z, Int_t n_lens_elem,
603             Double_t medium1_n, Double_t medium2_n, Double_t *dis)
604{
605  Int_t r_idx,iter,flag,Found,nroot,dir,status,idx_dir;
606  Double_t dbuf1, aa[3], xx[2], x3,y3,z3,r3, r1,r2, z1,z2;
607  Double_t nnn[3];
608  Double_t a00;
609  Double_t tmp, tmp_dis, v[3], tmp_x[3];
610
611  /* as an initial guess, intersection with an approximated sphere
612     is calculated */
613
614  dbuf1 = phot[Z]-Zc;
615  aa[0] = phot[PX]*phot[PX] + phot[PY]*phot[PY] + phot[PZ]*phot[PZ];
616  aa[1] = 2.0*(phot[PX]*phot[X] + phot[PY]*phot[Y] + phot[PZ]*dbuf1);
617  aa[2] = phot[X]*phot[X] + phot[Y]*phot[Y] + dbuf1*dbuf1-radius*radius;
618
619  nroot=KSolveQuadratic(aa,xx);
620  if(nroot<2)
621    return(RT_NO_INTERSECTION1);
622
623  /* swap */
624  if(xx[0]>xx[1])
625    {
626      tmp=xx[0];
627      xx[0]=xx[1];
628      xx[1]=tmp;
629    }
630
631  /* We need a positive, smaller solution. */
632  if(xx[0]>0.0)
633    dbuf1=xx[0];
634  else
635    {
636      if(xx[1]>0.0)
637    dbuf1=xx[1];
638      else
639    return(RT_NO_INTERSECTION1);
640    }
641
642  x3=phot[PX]*dbuf1+phot[X];
643  y3=phot[PY]*dbuf1+phot[Y];
644  z3=phot[PZ]*dbuf1+phot[Z];
645   /* distance to the optical axis at the initially guessed intersection */
646  r3=TMath::Sqrt(x3*x3+y3*y3);
647
648  if(r3>R_LENS)
649    {
650      /* The other solution may be acceptable just for an initial guess. */
651      dbuf1=xx[0];
652      x3=phot[PX]*dbuf1+phot[X];
653      y3=phot[PY]*dbuf1+phot[Y];
654      z3=phot[PZ]*dbuf1+phot[Z];
655
656      r3=TMath::Sqrt(x3*x3+y3*y3);
657      if(r3>R_LENS)
658    return(RT_HIT_SIDE_WALL);
659    }
660
661  /* search the index near r3 */
662  r_idx=Krt_bsearch(lens_r,r3,0,n_lens_elem-1);
663
664  if(r_idx>n_lens_elem-2)
665    r_idx=n_lens_elem-2;
666
667  /* search intersection point with real fresnel lens */
668  iter=0; /* number of iterations */
669  do{
670    Found=0;
671
672    r1=lens_r[r_idx];
673    z1=lens_z[r_idx];
674    r2=lens_r[r_idx+1];
675    z2=lens_z[r_idx+1];
676
677    if(r1==r2)
678      {
679        /* intersection with a part of the cylinder */
680    status=Kcheck_intersect_cylinder(r1, z1, r2, z2, phot, dis);
681
682    x3=phot[PX]*(*dis)+phot[X];
683    y3=phot[PY]*(*dis)+phot[Y];
684    z3=phot[PZ]*(*dis)+phot[Z];
685
686    if(!status)     /* intersection found */
687      {
688        Found=1;
689        /* normal vector */
690        if(z2>z1)
691          dir=1;
692        else
693          dir=-1;
694        nnn[X]=dir*x3/r1;
695        nnn[Y]=dir*y3/r1;
696        nnn[Z]=0.0;
697      }
698    else /* intersection with cylinder not found */
699      {
700        if(status==RT_NO_INTERSECTION2 && fabs(z3-z1)<100.0)
701          {
702        v[X]=x3;
703        v[Y]=y3;
704        v[Z]=0.0;
705
706        if((z3-z1)*Kvdot(v,&phot[PX])*phot[PZ]>0)
707          r_idx--;
708        else
709          r_idx++;
710          }
711        else
712          {
713        *dis=(z1-phot[Z])/phot[PZ];
714        z3=z1;
715        x3=phot[PX]*(*dis)+phot[X];
716        y3=phot[PY]*(*dis)+phot[Y];
717        r3=TMath::Sqrt(x3*x3+y3*y3);
718        r_idx=Krt_bsearch(lens_r,r3,0,n_lens_elem-1);
719          }
720      }
721#ifdef DEBUG
722    fprintf(stderr,"ridx0(%d): %d (%.1f: %.3f %.3f %.3f (%.1f %.1f %.1f)(%.3f %.3f %.3f))\n",
723    status,r_idx,z1,r1,r2,r3,phot[X],phot[Y],phot[Z],phot[PX],phot[PY],phot[PZ]);
724#endif
725      }
726    else  /* r1 != r2 */
727      {
728    /* intersection with a part of the cone */
729    status=Kcheck_intersect_cone(r1, z1, r2, z2, phot, dis);
730
731    x3=phot[PX]*(*dis)+phot[X];
732    y3=phot[PY]*(*dis)+phot[Y];
733    z3=phot[PZ]*(*dis)+phot[Z];
734
735    r3=TMath::Sqrt(x3*x3+y3*y3);
736
737    if(!status)   /* intersection found */
738      {
739        Found=1;
740        /* normal vector */
741        a00=(z2-z1)/(r2-r1);
742        nnn[X]=a00*x3;
743        nnn[Y]=a00*y3;
744        nnn[Z]=-r3;
745        dbuf1=TMath::Sqrt(Kvdot(nnn,nnn));
746        nnn[X]/=dbuf1;
747        nnn[Y]/=dbuf1;
748        nnn[Z]/=dbuf1;
749      }
750    else /* not found */
751      {
752        if(status==RT_NO_INTERSECTION2 &&
753           fabs(z3-z1)<10. && fabs(r3-r1)<5.)
754          {
755        if(r3<r1)
756          r_idx--;
757        if(r3>r2)
758          r_idx++;
759          }
760        else
761          {
762        *dis=(z1-phot[Z])/phot[PZ];
763        z3=z1;
764        x3=phot[PX]*(*dis)+phot[X];
765        y3=phot[PY]*(*dis)+phot[Y];
766        r3=TMath::Sqrt(x3*x3+y3*y3);
767        r_idx=Krt_bsearch(lens_r,r3,0,n_lens_elem-1);
768          }
769      }
770#ifdef DEBUG
771fprintf(stderr,"ridx1(%d): %d (%.1f: %.3f %.3f %.3f (%.1f %.1f %.1f)(%.3f %.3f %.3f))\n",
772    status,r_idx,z1,r1,r2,r3,phot[X],phot[Y],phot[Z],phot[PX],phot[PY],phot[PZ]);
773#endif
774      }
775
776    if(r_idx>=S_DATA)
777      return(RT_OUT_OF_SURFACE2);
778    if(r_idx<0 && r3>R_LENS && fabs(z3-z1)<10.0)
779      return(RT_OUT_OF_SURFACE2);
780    if(r_idx<0)
781      {
782    r_idx=1;
783    /* return(RT_OUT_OF_SURFACE1); */
784      }
785
786    /* iteration doesn't converge */
787    if(iter>RT_SEARCH_ITER_MAX)
788      return(-iter);
789
790    iter++;
791
792  } while(!Found);
793
794  /*
795   * check no intersections at a nearer point
796   */
797  v[X]=x3;
798  v[Y]=y3;
799  v[Z]=0.0;
800  if(Kvdot(v,&phot[PX])<0)
801    idx_dir=1;
802  else
803    idx_dir=-1;
804
805  do {
806    r_idx+=idx_dir;
807
808    r1=lens_r[r_idx];
809    z1=lens_z[r_idx];
810    r2=lens_r[r_idx+1];
811    z2=lens_z[r_idx+1];
812
813    if(r1==r2)
814      status=Kcheck_intersect_cylinder(r1, z1, r2, z2, phot, &tmp_dis);
815    else
816      status=Kcheck_intersect_cone(r1, z1, r2, z2, phot, &tmp_dis);
817
818    if(!status)  /* intersection found */
819      {
820    tmp_x[X]=phot[PX]*tmp_dis+phot[X];
821    tmp_x[Y]=phot[PY]*tmp_dis+phot[Y];
822    tmp_x[Z]=phot[PZ]*tmp_dis+phot[Z];
823    r3=TMath::Sqrt(tmp_x[X]*tmp_x[X]+tmp_x[Y]*tmp_x[Y]);
824
825    if(r1==r2)
826      {
827        if(z2>z1)
828          dir=1;
829        else
830          dir=-1;
831        nnn[X]=dir*tmp_x[X]/r3;
832        nnn[Y]=dir*tmp_x[Y]/r3;
833        nnn[Z]=0.0;
834      }
835    else
836      {
837        a00=(z2-z1)/(r2-r1);
838        /* normal vector */
839        nnn[X]=a00*tmp_x[X];
840        nnn[Y]=a00*tmp_x[Y];
841        nnn[Z]=-r3;
842        dbuf1=TMath::Sqrt(Kvdot(nnn,nnn));
843        nnn[X]/=dbuf1;
844        nnn[Y]/=dbuf1;
845        nnn[Z]/=dbuf1;
846      }
847
848    if(Kvdot(nnn,&phot[PX])>=0) /* wrong intersection; back side */
849      status=1;
850    else                      /* update intersection point */
851      {
852        x3=tmp_x[X];
853        y3=tmp_x[Y];
854        z3=tmp_x[Z];
855        *dis=tmp_dis;
856      }
857      }
858  }while(!status);
859
860#ifndef NO_DIFFRACTIVE
861  if(ID==1 && phot[PZ]>0.0 && nnn[Z]!=0.0)
862    {
863      Kdiffract(ID, &phot[PX], x3, y3, z3, Zc, 1.0003, 1.0003, 
864           phot[L]*1e-6, 1);
865    }
866  if(ID==6 && phot[PZ]<0.0 && nnn[Z]!=0.0)
867    {
868      Kdiffract(ID, &phot[PX], x3, y3, z3, Zc, 1.0003, 1.0003, 
869           phot[L]*1e-6, 1);
870    }
871#endif
872
873  /* refraction */
874  if(phot[PZ]<0.0)
875    {
876      tmp=medium2_n;
877      medium2_n=medium1_n;
878      medium1_n=tmp;
879    }
880  flag=Krefract(&phot[PX], nnn, medium1_n, medium2_n);
881#if 0
882  if(flag==RT_REFLECTED)
883    return(RT_REFLECTION_DISCARDED); /* reflected photons are thrown away */
884#endif
885
886#ifndef NO_DIFFRACTIVE
887  if(ID==1 && phot[PZ]<0.0 && nnn[Z]!=0.0)
888    {
889      Kdiffract(ID, &phot[PX], x3, y3, z3, Zc, 1.0003, 1.0003, 
890           phot[L]*1e-6, 1);
891    }
892  if(ID==6 && phot[PZ]>0.0 && nnn[Z]!=0.0)
893    {
894      Kdiffract(ID, &phot[PX], x3, y3, z3, Zc, 1.0003, 1.0003, 
895           phot[L]*1e-6, 1);
896    }
897#endif
898
899  /* distance between injection point and the Surface */
900  phot[T]+=(*dis)* medium1_n/C0;
901
902  phot[X]=x3;
903  phot[Y]=y3;
904  phot[Z]=z3;
905
906  return 0;
907}
908
909static Int_t KCheckIris(Double_t in_ph[6])
910{
911  Double_t x3, y3, dist, radius;
912
913  dist=(Zc3-in_ph[Z])/in_ph[PZ];
914  if(dist>=0.0)
915    {
916      x3=in_ph[PX]*dist+in_ph[X];
917      y3=in_ph[PY]*dist+in_ph[Y];
918
919      radius=TMath::Sqrt(x3*x3+y3*y3);
920      if(radius>Rc3)
921        return (RT_OUT_OF_IRIS);
922    }
923
924    return 0;
925}
926
927/*******************************************/
928/*         main routine                    */
929/*******************************************/
930
931Int_t Ktrace(Double_t ph_in[], Double_t ph_out[])
932     /* ph_in[0] : x0 mm */
933     /* ph_in[1] : y0 mm */
934     /* ph_in[2] : z0 mm */
935     /* ph_in[3] : l     */
936     /* ph_in[4] : m     */
937     /* ph_in[5] : n     */
938     /* ph_in[6] : lambda nm */
939     /* ph_in[7] : time ns */
940{
941  Int_t    status=0, n_int, WithinOptics;
942  Int_t    PrevPoint, CurPoint, NextPoint;
943  Double_t nn,kk;
944  Double_t AbsorbCoeff, TransProb;
945  Double_t dis;
946
947  ph_out[L]=ph_in[L];
948
949
950  /* Opt. index  for this lambda */ 
951  nn=KGet_n_Acryl(ph_in[L]);
952  kk=KGet_k_Acryl(ph_in[L]);
953
954  if(ph_in[Z]>=Sz6 && ph_in[PZ]<0.0)
955    {
956      PrevPoint=SURFACE7;
957      CurPoint=SURFACE7;
958      NextPoint=SURFACE6;
959    }
960  else
961    {
962      PrevPoint=SURFACE0;
963      CurPoint=SURFACE0;
964      NextPoint=SURFACE1;
965    }
966  n_int=0;
967  WithinOptics=1;
968
969  while(n_int++ < RT_INTERACTION_MAX && WithinOptics)
970    {
971      PrevPoint=CurPoint;
972      CurPoint=NextPoint;
973
974      switch(NextPoint)
975    {
976    case SURFACE0:
977    case SURFACE7:
978      WithinOptics=0;
979      break;
980
981    case SURFACE1:
982      status=Klens_interaction(1, ph_in, Zc1, Rc1, sr1, sz1, n_s1,
983                  REFRACTIVE_IDX_MEDIA,nn,&dis);
984#ifdef DEBUG
985      printf("1 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]);
986#endif
987      if(ph_in[PZ]>0.0)
988        NextPoint=SURFACE2;
989      else
990        NextPoint=SURFACE0;
991      break;
992
993    case SURFACE2:
994      status=Klens_interaction(2, ph_in, Zc2, Rc2, sr2, sz2, n_s2,
995                  nn,REFRACTIVE_IDX_MEDIA, &dis);
996#ifdef DEBUG
997      printf("2 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]);
998#endif
999      if(ph_in[PZ]>0.0)
1000        NextPoint=SURFACE5;
1001      else
1002        NextPoint=SURFACE1;
1003      break;
1004
1005    case SURFACE5:
1006      status=Klens_interaction(5, ph_in, Zc5, Rc5, sr5, sz5, n_s5,
1007                  REFRACTIVE_IDX_MEDIA, nn, &dis);
1008#ifdef DEBUG
1009      printf("5 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]);
1010#endif
1011      if(ph_in[PZ]>0.0)
1012        NextPoint=SURFACE6;
1013      else
1014        NextPoint=SURFACE2;
1015      break;
1016
1017    case SURFACE6:
1018      status=Klens_interaction(6, ph_in, Zc6, Rc6, sr6, sz6, n_s6,
1019                  nn, REFRACTIVE_IDX_MEDIA, &dis);
1020#ifdef DEBUG
1021      printf("6 %f %f %f\n",ph_in[X],ph_in[Y],ph_in[Z]);
1022#endif
1023      if(ph_in[PZ]>0.0)
1024        NextPoint=SURFACE7;
1025      else
1026        NextPoint=SURFACE5;
1027      break;
1028    }
1029#ifdef DEBUG
1030      fprintf(stderr,"%d %.1f %.1f %.1f  %.3f %.3f %.3f\n",
1031          -CurPoint/1000,
1032          ph_in[X],ph_in[Y],ph_in[Z],ph_in[PX],ph_in[PY],ph_in[PZ]);
1033#endif
1034    // thea debug
1035    // even if it dies, I want to know where it does
1036    ph_out[X]  = ph_in[X];
1037    ph_out[Y]  = ph_in[Y];
1038    ph_out[Z]  = ph_in[Z];
1039    ph_out[PX] = ph_in[PX];
1040    ph_out[PY] = ph_in[PY];
1041    ph_out[PZ] = ph_in[PZ];
1042    ph_out[T]  = ph_in[T];
1043
1044    if (status == RT_NO_INTERSECTION1 || status == RT_HIT_SIDE_WALL) {
1045        // track the photons up to the borders
1046        if ( TMath::Sqrt(ph_in[X]*ph_in[X]+ph_in[Y]*ph_in[Y]) > R_WALL){
1047            //ph is outside, invert it's dir for tracing
1048            ph_in[PX] = -ph_in[PX];
1049            ph_in[PY] = -ph_in[PY];
1050            ph_in[PZ] = -ph_in[PZ];
1051        }
1052        Double_t tmp_dis;
1053        if (!Kcheck_intersect_cylinder(R_WALL, Sz1, R_WALL, Sz6, ph_in, &tmp_dis)){
1054            // the photon crosses the boundaries of the optics
1055            ph_out[X]=ph_in[X]+ph_in[PX]*tmp_dis;
1056            ph_out[Y]=ph_in[Y]+ph_in[PY]*tmp_dis;
1057            ph_out[Z]=ph_in[Z]+ph_in[PZ]*tmp_dis;
1058        }
1059        return 0;
1060    }
1061
1062    if(status)
1063        return (status+CurPoint);
1064
1065#ifndef NO_ABSORPTION
1066      /* absorption between S1 and S2 or between S5 and S6 */
1067      if((PrevPoint==SURFACE1 && CurPoint==SURFACE2) ||
1068     (PrevPoint==SURFACE2 && CurPoint==SURFACE1) ||
1069     (PrevPoint==SURFACE5 && CurPoint==SURFACE6) ||
1070     (PrevPoint==SURFACE6 && CurPoint==SURFACE5))
1071   {
1072      AbsorbCoeff=kk*TMath::Pi()*4.0/(ph_in[L]*1.e-6);
1073      TransProb=exp(-AbsorbCoeff*dis);
1074          TRandom *rndm = EsafRandom::Get();
1075      if(rndm->Rndm()>TransProb)
1076        return(RT_ABSORBED+CurPoint);
1077    }
1078#endif
1079    if((CurPoint==SURFACE2 && NextPoint==SURFACE5) ||
1080     (CurPoint==SURFACE5 && NextPoint==SURFACE2))
1081        if(KCheckIris(ph_in)<0){
1082            Double_t tmp_dis, radius, x3, y3;
1083           
1084            ph_out[PX] = ph_in[PX];
1085            ph_out[PY] = ph_in[PY];
1086            ph_out[PZ] = ph_in[PZ];
1087            ph_out[T]  = ph_in[T];
1088
1089            tmp_dis=(Zc3-ph_in[Z])/ph_in[PZ];
1090            x3=ph_in[PX]*tmp_dis+ph_in[X];
1091            y3=ph_in[PY]*tmp_dis+ph_in[Y];
1092            radius = TMath::Sqrt(x3*x3+y3*y3);
1093            if ( radius < R_WALL) {
1094                // intersection with the pupil
1095                ph_out[X]=x3;
1096                ph_out[Y]=y3;
1097                ph_out[Z]=Zc3;
1098                return RT_OUT_OF_IRIS;
1099            } else {
1100                // the photon hit the wall, not the iris
1101                Kcheck_intersect_cylinder(R_WALL, ph_in[Z], R_WALL, Zc3, ph_in, &tmp_dis);
1102                ph_out[X]=ph_in[X]+ph_in[PX]*tmp_dis;
1103                ph_out[Y]=ph_in[Y]+ph_in[PY]*tmp_dis;
1104                ph_out[Z]=ph_in[Z]+ph_in[PZ]*tmp_dis;
1105                return RT_HIT_SIDE_WALL;
1106            }
1107
1108        }
1109    }
1110
1111  if(n_int>=RT_INTERACTION_MAX)
1112    return (RT_STRAY_LIGHT);
1113
1114  return 0;
1115}
Note: See TracBrowser for help on using the repository browser.