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