/Lens.cc
Go to the documentation of this file.
1 
9 #include "Lens.h"
10 #include "RTFunctions.h"
11 
12 #include <TPolyLine3D.h>
13 #include <TObjArray.h>
14 
15 #include <utl/Math.h>
16 #include <utl/MathConstants.h>
17 #include <utl/AugerUnits.h>
18 
19 #include <utl/Photon.h>
20 #include <utl/Point.h>
21 #include <utl/Vector.h>
22 #include <utl/CoordinateSystemPtr.h>
23 
24 #include <utl/RandomEngine.h>
25 #include <CLHEP/Random/Randomize.h>
26 
27 #include <fdet/Telescope.h>
28 #include <fdet/Corrector.h>
29 
30 #include <det/Detector.h>
31 
32 #include <atm/Atmosphere.h>
33 #include <atm/ProfileResult.h>
34 
35 #include <iostream>
36 #include <sstream>
37 #include <utility>
38 
39 using namespace TelescopeSimulatorKG2;
40 using namespace utl;
41 using namespace std;
42 
43 using CLHEP::RandFlat;
44 
45 
47  const fdet::Telescope& detTel,
48  const bool simulateHaloEffects,
49  const double lensIncreaseRefl,
50  const double lensPosition,
51  const double minLensThickness,
52  const double torusRadius,
53  const double tubeRadius,
54  const double torusZ0) :
55  fRandom(rndm),
56  fSimulateHaloEffects(simulateHaloEffects),
57  fIncreaseReflection(lensIncreaseRefl),
58  fPosZ(lensPosition),
59  fMinLensThickness(minLensThickness),
60  fTorusRadius(torusRadius),
61  fTubeRadius(tubeRadius),
62  fTorusZ0(torusZ0),
63  fTelCS(detTel.GetTelescopeCoordinateSystem()),
64  fOrigin(0, 0, fPosZ, fTelCS),
65  fTorusOrigin(0, 0, fTorusZ0, fTelCS),
66  fPosPlane(0, 0, fPosZ, fTelCS),
67  fR1(detTel.GetCorrector().GetInnerRadius()),
68  fR2(detTel.GetCorrector().GetOuterRadius()),
69  fRefractiveIndex(detTel.GetCorrector().GetRefractiveIndex()),
70  fTransmittance(detTel.GetCorrector().GetTransmittance()),
71  fSigRho(detTel.GetCorrector().GetSigmaNormal()),
72  fNbug(0)
73 {
74  // lens defines the entrance of the telescope
75  // center of curvature of camera and mirror are here
76  // 0 is at the edge of the lens elements at 850mm (the one closer to the filter)
77 
78  /*fPosZ = -0.*cm;
79  fMinLensThickness = 6.628*mm; // Julias first calculation
80  fTorusRadius = 795.*mm; // FD paper
81  fTubeRadius = 8380.*mm; // FD paper
82  fTorusZ0 = fPosZ + ftubeRadius - 0.18*mm; // Julias first calculation
83 
84  fLXTorusRadius = 795.27*mm; // value used in LX module (spherical)
85  fLXTubeRadius = 8383.*mm; // value used in LX module (spherical)
86  fLXz0 = 8380.9*mm;
87 
88  fMinLensThickness = 6.13822*mm;//6.5*mm;
89  fTorusRadius = 795.27*mm;//795.*mm;//795.*mm;//849.*mm;//795.*mm;//795.*mm;//850.*mm;//804.10*mm;
90  fTubeRadius = 8383*mm;//9002.67*mm;//8832.98*mm;//10169.7*mm;//21436.5*mm;//14524.6*mm;//6130.*mm;//ftubeRadius;
91  const double tmp_torusZ0 = ftubeRadius + 5.95956*mm;//9002.5*mm;//8826.25*mm;//10162.8*mm;//21429.7*mm;//14517.8*mm ;//ftubeRadius + 6.9*mm;//8386.775*mm;
92  ftorusZ0 = fPosZ + tmp_torusZ0;*/
93 
94  //fTorusOrigin = Point(0, 0, fPosZ + ftubeRadius - 0.18*mm, fTelCS);
95  //fPosPlane = Point(0, 0, fPosZ - fminLensThickness, fTelCS);
96  //fPosPlane = Point(0, 0, -fminLensThickness, fTelCS);
97  // const double Tm = corrector.GetMeanLensThickness(); // average lens thickness
98 
99  // air refractive index
100 /*#warning this is inconsistent throughout the raytracing! CHECK.
101 #warning Here refractive index of air is taken from the time-dependent Atmosphere
102  const atm::ProfileResult& refractiveIndexVsHeight =
103  det::Detector::GetInstance().GetAtmosphere().EvaluateRefractionIndexVsHeight();
104  fIndexAir = refractiveIndexVsHeight.Y(refractiveIndexVsHeight.MinX());*/
105 }
106 
107 
109 #if 0
110 RTNext
111 Lens::Trace(const utl::Photon& photonIn, utl::Photon& photonOut)
112 {
113  cout << "tracing without torus!" << endl;
114 
115  // some helper variables
116  const Vector nPlane(0, 0, 1, fTelCS);
117  const double lambda = photonIn.GetWavelength();
118  const double r_index = fRefractiveIndex.Y(lambda) / fIndexAir;
119  double weight = photonIn.GetWeight(); // input weight, this will get reduced via absorption
120 
121  // propagate photon to lens "plane" -> photonLens
122  // at this stage the lens is just a plane at fPosZ distance from aperture
123  // fOrigin is Point(0, 0, fPosZ, fTelCS)
124  utl::Photon photonLens;
125  RTFunctions::Plane(fPosPlane, nPlane, photonIn, photonLens);
126 
127  bool inLens = false; // photon not yet in lens material
128 
129  /* the corrector lens gaps are implemented, but there are no vertical optical boundaries implemented.
130  Only the front and back side of the lens plus the inner/outer radius + gaps.
131  Effectively: photons that travel beyond R2 are absorbed, photons that travel beyond R1 or hit one of the gaps,
132  pass out of the lens back into the telescope. */
133 
134  //double travelPath = 0; // sum up the distance traveled by the photon in the glass
135 
136  int nDist = 0;
137  int count = 0;
138 
139  do { // internal reflections in the glass
140 
141  ++count;
142  const Vector& nDir = photonLens.GetDirection();
143  const bool backwards = nDir.GetZ(fTelCS) > 0; // towards the aperture !!
144 
145  if (!fSimulateHaloEffects && backwards) {
146  // the light is going out of the telescope
147  photonOut = photonLens;
148  return eLost;
149  }
150 
151  const Point& pLens = photonLens.GetPosition();
152  const double x = pLens.GetX(fTelCS);
153  const double y = pLens.GetY(fTelCS);
154  const double r2 = x*x + y*y;
155  const double r = sqrt(r2);
156 
157  /*if (r > fR1 && r < fR2) {
158  photonOut = photonLens;
159  return eLost; // mask the lens
160  }*/
161  if (r > fR2) {
162  photonOut = photonLens;
163  return eLost; // the light doesn't pass through the aperture window
164  }
165 
166  if (r < fR1) {
167  photonOut = photonLens;
168  if (inLens) {
169  //cout << "first inLens, now in aperture - bug! for now -> return eLost" << endl;
170  ++fNbug;
171  return eLost;
172  }
173  // the light went through the aperture window,
174  return backwards ? eFilter : eCameraShadow;
175  // to mask the center of the aperture use instead:
176  //return eLost;
177  }
178 
179  // corrector ring gaps
180  const double phiAngle = atan(abs(y/x));
181  if (fSimulateHaloEffects && phiAngle - floor(phiAngle / (kPi/12)) * (kPi/12) < 0.265*deg /*gap*/) {
182  photonOut = photonLens;
183  // avoid photons going from lens glass directly into the gap (would result in wrong direction)
184  if (inLens) {
185  //cout << "first inLens, now in gap - bug! for now -> return eLost" << endl;
186  ++fNbug;
187  return eLost;
188  }
189  return backwards ? eFilter : eCameraShadow;
190  }
191 
192  const Vector normal = backwards ?
193  (inLens ? CurvaturePrototype(x,y) : nPlane) :
194  (inLens ? nPlane : CurvaturePrototype(x, y));
195  cout << " we are doing this: curvaturePrototype can be used!" << endl;
196 
197  // calculate refraction at optical boundary
198  RTFunctions::PhotonList photonsRefracted;
199  RTFunctions::Refraction(inLens ? r_index : 1/r_index, photonLens, normal, photonsRefracted);
200 
201  if (photonsRefracted.size() == 1) { // total internal reflection
202 
203  if (!fSimulateHaloEffects) {
204  photonOut = photonsRefracted[0];
205  return eLost;
206  }
207 
208  if (!inLens) {
209  cout << "total internal reflection but !inLens ---------- this can not happen!" << endl;
210  photonOut = photonsRefracted[0];
211  return backwards ? eCameraShadow : eFilter;
212  }
213 
214  // photon is total internal reflected in lens
215 
216  photonLens = photonsRefracted[0];
217 
218  // -> propagate to next optical surface
219 
220  } else { // partial transmission/reflection
221 
222  // modify reflectivity (ad-hoc) ONLY when coming from the outside! Internal reflections are not affected.
223  if (!inLens && fIncreaseReflection != 1) {
224  const double weightRefl = photonsRefracted[1].GetWeight();
225  const double inWeight = weight;
226  const double newRefl = min(inWeight, weightRefl * fIncreaseReflection);
227  const double newRefr = inWeight - newRefl;
228  photonsRefracted[1].SetWeight(newRefl);
229  photonsRefracted[0].SetWeight(newRefr);
230  }
231  // end modify reflectivity --
232 
233  if (fSimulateHaloEffects) { // in the halo case we do MC raytracing of one photon
234 
235  const double tmpRandNr = RandFlat::shoot(&fRandom.GetEngine(), 0, 1);
236 
237  if (tmpRandNr > photonsRefracted[0].GetWeight() / weight) {
238 
239  // -> reflection
240  if (!inLens) { // photon does not enter the lens
241  photonOut = photonsRefracted[1];
242  photonOut.SetWeight(weight);
243  //cout << "photon does not enter the lens, count = " << count << endl;
244  return backwards ? eCameraShadow : eFilter;
245  }
246 
247  photonLens = photonsRefracted[1];
248  photonLens.SetWeight(weight);
249 
250  // -> we are internal in lens glass
251 
252  // -> propagate to next optical interface ...
253 
254  } else { // end reflection, start transmission
255 
256  if (!inLens) {
257 
258  inLens = true; // now we are in the lens !
259 
260  photonLens = photonsRefracted[0];
261  photonLens.SetWeight(weight);
262  //cout << "now in lens, count: " << count << endl;
263 
264  // -> propagate to next optical interface
265 
266  } else { // now we are leaving the lens !
267 
268  photonOut = photonsRefracted[0];
269  photonOut.SetWeight(weight);
270  //cout << "now leaving lens, count: " << count << endl;
271  // debug
272  //cout << "x: " << x << ", y: " << y << endl;
273  return backwards ? eFilter : eCameraShadow;
274 
275  }
276 
277  }
278 
279  } else { // end do Halo, start non-halo
280 
281  // in the non-halo mode we are only considering the weight-loss of the photon moving in forward direction!
282 
283  // only (forward) transmission
284 
285  if (inLens) { // photon is leaving the lens
286  photonOut = photonsRefracted[0];
287  return eCameraShadow;
288  }
289 
290  inLens = true;
291  photonLens = photonsRefracted[0];
292  weight = photonLens.GetWeight(); // update weight
293 
294  // -> propagate to next optical interface ...
295 
296  }
297 
298  }
299 
300  // propagate photon to next optical interface
301 
302  const Vector& nDirLens = photonLens.GetDirection();
303  const bool backwardsLens = nDirLens.GetZ(fTelCS) > 0; // towards the aperture !!
304  const double cosThetaPhoton = (backwardsLens ? +1 : -1) * nDirLens.GetCosTheta(fTelCS);
305  const double z = ProfilePrototype(r); // glass thickness
306  const double distance = z / cosThetaPhoton; // thickness of the glass along nDirLens
307 
308  // RU: save track point for drawing
309  if (fPhotonTrack)
310  fPhotonTrack->AddPoint(pLens);
311 
312  // calculate the position of light at the second surface of the lens.
313  Point pNext = pLens + distance * nDirLens;
314  if (!backwardsLens) // in this case we are now at the plane inner surface of the lens at fPosZ from the filter
315  pNext = Point(pNext.GetX(fTelCS), pNext.GetY(fTelCS), fPosZ, fTelCS);
316 
317  photonLens.SetPosition(pNext);
318 
319  weight *= exp(distance / (1*cm) * log(fTransmittance.Y(lambda)));
320  photonLens.SetWeight(weight);
321 
322  ++nDist;
323  //cout << " -> distance=" << distance/mm << " mm nDist=" << nDist << endl;
324 
325  // mark photons and plot them later
326  if (nDist == 3 /*nDist >= 23*/) {
327  const int everyOnehundred = RandFlat::shoot(&fRandom.GetEngine(), 0, 100);
328  if (everyOnehundred == 4)
329  photonLens.SetSource(3333); // secret number
330  }
331 
332  } while (weight > 1e-20);
333 
334  // too many multiple reflections -> absorbed
335  photonOut = photonLens;
336  return eLost;
337 }
338 #endif
339 
340 RTNext
341 Lens::TraceWithTorus(const utl::Photon& photonIn, utl::Photon& photonOut)
342 {
343  const bool printLens = false;
344  // some helper variables
345  const double lambda = photonIn.GetWavelength();
346  const double r_index = fRefractiveIndex.Y(lambda) / fIndexAir;
347  //const double r_index = 1.2;
348  //cout << "refractive index r_index = " << r_index << endl;
349  double weight = photonIn.GetWeight(); // input weight, this will get reduced via absorption
350 
351  const Vector inwards(0, 0, -1, fTelCS);
352  const bool outwards = photonIn.GetDirection().GetZ(fTelCS) > 0;
353  const Vector nPlane(0, 0, 1, fTelCS);
354 
355  // propagate photon to lens surface -> photonLens
356  // fOrigin is Point(0, 0, fPosZ, fTelCS)
357 
358  utl::Photon photonLens;
359  if (outwards)
360  RTFunctions::Plane(fPosPlane, nPlane, photonIn, photonLens);
361  else {
362  RTFunctions::IntersectionList intersections;
363  RTFunctions::Torus(fTorusOrigin, inwards, fTorusRadius, fTubeRadius, photonIn, intersections);
364  if (intersections.empty()) {
365  ERROR("no intersection with torus???");
366  return eLost;
367  }
368 
369  unsigned int indexOfSmallestZ = 4; // maximum number of intersections is 4 (0 to 3)
370  // curved lens surface has the smallest z values on the torus
371  ChoosePhysicalIntersection(indexOfSmallestZ, intersections);
372 
373  if (indexOfSmallestZ == 4) {
374  ERROR("smallestZ was not found -> indexOfSmallestZ is not correct!");
375  return eLost;
376  }
377 
378  photonLens = photonIn;
379  photonLens.SetPosition(intersections[indexOfSmallestZ].first.GetPosition());
380  }
381 
382  bool inLens = false; // photon not yet in lens material
383 
384  /* the corrector lens gaps are implemented, but there are no vertical optical boundaries implemented.
385  Only the front and back side of the lens plus the inner/outer radius + gaps.
386  Effectively: photons that travel beyond R2 are absorbed, photons that travel beyond R1 or hit one of the gaps,
387  pass out of the lens back into the telescope. */
388 
389  //double travelPath = 0; // sum up the distance traveled by the photon in the glass
390 
391  int nDist = 0;
392  int count = 0;
393 
394  do { // internal reflections in the glass
395 
396  ++count;
397 // const Vector& nDir = photonLens.GetDirection();
398 // const bool backwards = nDir.GetZ(fTelCS) > 0; // towards the aperture !!
399  const bool outwards = photonLens.GetDirection().GetZ(fTelCS) > 0;// towards the aperture !!
400 
401  if (!fSimulateHaloEffects && outwards) {
402  // the light is going out of the telescope
403  photonOut = photonLens;
404  return eLost;
405  }
406 
407  const Point& pLens = photonLens.GetPosition();
408  const double pos_x = pLens.GetX(fTelCS);
409  const double pos_y = pLens.GetY(fTelCS);
410  //const double pos_z = pLens.GetZ(fTelCS);
411  const double pos_r2 = Sqr(pos_x) + Sqr(pos_y);
412  const double pos_r = sqrt(pos_r2);
413 
414  /*if (pos_r > fR1 && pos_r < fR2) {
415  photonOut = photonLens;
416  return eLost; //mask the lens
417  }*/
418 
419  if (pos_r > fR2) {
420  photonOut = photonLens;
421  return eLost; // the light doesn't pass through the aperture window
422  }
423 
424  if (pos_r < fR1) {
425  photonOut = photonLens;
426  if (inLens) {
427  //cout << "first inLens, now in aperture - bug! for now -> return eLost" << endl;
428  ++fNbug;
429  return eLost;
430  }
431  if (!outwards && printLens)
432  cout << 0 << ',';
433  // the light went through the aperture window,
434  return outwards ? eFilter : eCameraShadow;
435 
436  // to mask the center of the aperture use instead:
437  // return eLost;
438  }
439 
440  const bool debug = false;
441 
442  // corrector ring gaps, see FD NIM paper for numbers (Fig. 11)
443  const double ringElementAngle = kPi / 12; // = 15 deg
444  const double phiAngle = atan2(abs(pos_y), abs(pos_x)) + (ringElementAngle / 2);
445  const double gapWidth = ((2 * kPi * 850*mm) - (24 * 218*mm)) / 24; // = 4.5mm, fig.11 FD NIM
446  //const double gapWidth = 19 * mm; // width of the tape on the lens gaps, see FD Task Log 2011-11-28
447  const double gapAngularWidth = sin(gapWidth / (975*mm)); // 975mm = middle of corrector ring
448  //if (fSimulateHaloEffects && abs(phiAngle - round(phiAngle / ringElementAngle) * ringElementAngle) < (gapAngularWidth / 2)) {
449  if (abs(phiAngle - round(phiAngle / ringElementAngle) * ringElementAngle) < (gapAngularWidth / 2)) {
450  if (debug) {
451  cout << pLens.GetX(fTelCS) / mm << ','
452  << pLens.GetY(fTelCS) / mm << ','
453  << pLens.GetZ(fTelCS) / mm << '\n';
454  }
455  photonOut = photonLens;
456  //return eLost; // make gaps in the Lens absorbing
457  // avoid photons going from lens glass directly into the gap (would result in wrong direction)
458  if (inLens) {
459  //cout << "first inLens, now in gap - bug! for now -> return eLost" << endl;
460  ++fNbug;
461  return eLost;
462  }
463  //ERROR("hit the corrector gap");
464  if (!outwards && printLens)
465  cout << 2 << ',';
466  return outwards ? eFilter : eCameraShadow;
467  }
468 
469  const Vector nTorus = RTFunctions::TorusNormal(fTorusOrigin, inwards, pLens, fTorusRadius, fTubeRadius);
470  // for test purposes use "old" function instead
471  //const Vector nTorus = CurvaturePrototype(pos_x, pos_y);
472 
473  // depending on the incoming direction take normal on the plane or curved side of the lens
474  const Vector normal = outwards ? (inLens ? nTorus : nPlane) : (inLens ? nPlane : nTorus);
475 
476  // debug
477  /*cout << "backwards = " << backwards << ", inLens = " << inLens << ", normal = (" << normal.GetX(fTelCS) << ","
478  << normal.GetY(fTelCS) << ","
479  << normal.GetZ(fTelCS) << ") in point (" << pos_x/mm << "," << pos_y/mm << "," << pos_z/mm << ") "
480  "at r = " << pos_r/mm << ", old z value = " << ProfilePrototype(pos_r)/mm << endl;
481  cout << "for root " << backwards << "\t" << inLens << "\t" << normal.GetX(fTelCS) << "\t"
482  << normal.GetY(fTelCS) << "\t"
483  << normal.GetZ(fTelCS) << "\t" << pos_x/mm << "\t" << pos_y/mm << "\t" << pos_z/mm << "\t"
484  << pos_r/mm << "\t" << ProfilePrototype(pos_r)/mm << endl;*/
485 
486  // calculate refraction at optical boundary
487  RTFunctions::PhotonList photonsRefracted;
488  RTFunctions::Refraction(inLens ? r_index : 1 / r_index, photonLens, normal, photonsRefracted);
489 
490  if (photonsRefracted.size() == 1) { // total internal reflection
491 
492  if (!fSimulateHaloEffects) {
493  photonOut = photonsRefracted[0];
494  return eLost;
495  }
496 
497  if (!inLens) {
498  ERROR("total internal reflection but !inLens ---------- this can not happen!");
499  photonOut = photonsRefracted[0];
500  //return outwards ? eCameraShadow : eFilter;
501  return eLost;
502  }
503 
504  // photon is total internal reflected in lens
505 
506  photonLens = photonsRefracted[0];
507 
508  // -> propagate to next optical surface
509 
510  } else { // partial transmission/reflection
511 
512  // modify reflectivity (ad-hoc) ONLY when coming from the outside! Internal reflections are not affected.
513  if (!inLens && fIncreaseReflection != 1) {
514  const double weightRefl = photonsRefracted[1].GetWeight();
515  const double inWeight = weight;
516  const double newRefl = min(inWeight, weightRefl * fIncreaseReflection);
517  const double newRefr = inWeight - newRefl;
518  photonsRefracted[1].SetWeight(newRefl);
519  photonsRefracted[0].SetWeight(newRefr);
520  }
521  // end modify reflectivity --
522 
523  if (fSimulateHaloEffects) { // in the halo case we do MC raytracing of one photon
524  const double tmpRandNr = RandFlat::shoot(&fRandom.GetEngine(), 0, 1);
525  if (tmpRandNr > photonsRefracted[0].GetWeight() / weight) {
526  // -> reflection
527  if (!inLens) { // photon does not enter the lens
528  photonOut = photonsRefracted[1];
529  photonOut.SetWeight(weight);
530  //cout << "photon does not enter the lens, count = " << count << endl;
531  /*// mask lens
532  if (backwards)
533  return eLost;
534  else*/
535 
536  // diffusive component
537  const double amountOfStrayLight = 0; // 0% of the light will go in "lambertian directions"
538  if (amountOfStrayLight > 0) {
539  double maxTheta = 25*deg;
540  const Vector lambertdiffusion =
541  RTFunctions::LambertDiffusion(fRandom , photonOut.GetDirection(), normal, amountOfStrayLight, maxTheta);
542  photonOut.SetDirection(lambertdiffusion);
543  }
544  if (!outwards && printLens)
545  cout << 1 << ',';
546  return outwards ? eCameraShadow : eFilter;
547  }
548 
549  photonLens = photonsRefracted[1];
550  photonLens.SetWeight(weight);
551 
552  // -> we are internal in lens glass
553  // -> propagate to next optical interface ...
554 
555  } else { // end reflection, start transmission
556 
557  if (!inLens) {
558 
559  inLens = true; // now we are in the lens !
560 
561  photonLens = photonsRefracted[0];
562  photonLens.SetWeight(weight);
563  //cout << "now in lens, count: " << count << endl;
564 
565  // -> propagate to next optical interface
566 
567  } else { // now we are leaving the lens !
568 
569  photonOut = photonsRefracted[0];
570  photonOut.SetWeight(weight);
571  //cout << "now leaving lens, count: " << count << endl;
572  /*// mask lens
573  if (!backwards)
574  return eLost;
575  else*/
576 
577  // diffusive component
578  //const double amountOfStrayLight = 0.05; // 5% of the light will go in "lambertian directions"
579  const double amountOfStrayLight = 0; // 0% of the light will go in "lambertian directions"
580  double maxTheta = 25*deg;
581  const Vector lambertdiffusion =
582  RTFunctions::LambertDiffusion(fRandom, photonOut.GetDirection(), normal, amountOfStrayLight, maxTheta);
583  photonOut.SetDirection(lambertdiffusion);
584 
585  if (!outwards && printLens)
586  cout << 1 << ',';
587  return outwards ? eFilter : eCameraShadow;
588  }
589  }
590  } else { // end do Halo, start non-halo
591 
592  // in the non-halo mode we are only considering the weight-loss of the photon moving in forward direction!
593  // only (forward) transmission
594 
595  if (inLens) { // photon is leaving the lens
596  photonOut = photonsRefracted[0];
597  return eCameraShadow;
598  }
599 
600  inLens = true;
601  photonLens = photonsRefracted[0];
602  weight = photonLens.GetWeight(); // update weight
603 
604  // -> propagate to next optical interface ...
605  }
606  }
607 
608  Point pNext = pLens;
609  const bool outwardsLens = photonLens.GetDirection().GetZ(fTelCS) > 0; // towards the aperture !!
610  if (inLens) {
611  if (outwardsLens) { // intersection with torus
612  RTFunctions::IntersectionList intersections;
613  RTFunctions::Torus(fTorusOrigin, inwards, fTorusRadius, fTubeRadius, photonLens, intersections);
614 
615  if (intersections.empty()) {
616  ERROR("inside the lens and flying outwards - but no intersection with torus???");
617  return eLost;
618  }
619 
620  unsigned int indexOfSmallestZ = 4; // maximum number of intersections is 4 (0 to 3)
621  ChoosePhysicalIntersection(indexOfSmallestZ, intersections);
622 
623  if (indexOfSmallestZ == 4) {
624  ERROR("smallestZ was not found -> indexOfSmallestZ is not correct!");
625  return eLost;
626  }
627  // curved lens surface has the smallest z values on the torus
628  pNext = intersections[indexOfSmallestZ].first.GetPosition();
629 
630  } else { // intersection with plane
631  Photon tmpPhoton = photonLens;
632  RTFunctions::Plane(fPosPlane, nPlane, photonLens, tmpPhoton);
633  pNext = tmpPhoton.GetPosition();
634 
635  }
636  photonLens.SetPosition(pNext);
637  } else {
638  ERROR("propagate to next optical interface (inside lens) but photon is not inLens!!!!!");
639  return eLost;
640  }
641 
642  const Vector& pathInLens = pNext - pLens;
643  const double distance = pathInLens.GetMag();
644  weight *= exp(distance / (1*cm) * log(fTransmittance.Y(lambda)));
645 
646  ++nDist;
647  if (nDist > 100) {
648  ERROR("so many reflections? CHECK?!?!");
649  return eLost;
650  }
651 
652  // mark photons and plot them later
653  if (nDist == 3 /*nDist >= 23*/) {
654  const int everyOnehundred = RandFlat::shoot(&fRandom.GetEngine(), 0, 100);
655  if (everyOnehundred == 4)
656  photonLens.SetSource(3333); // secret number
657  }
658 
659  } while (weight > 1e-20);
660 
661  ERROR("Lost photon due to too many multiple reflections in the lens");
662  // too many multiple reflections -> absorbed
663 
664  photonOut = photonLens;
665  return eLost;
666 }
667 
668 
669 TObjArray*
671 {
672  TObjArray* const objs = new TObjArray();
673 
674  const int color = 1;
675  const int width = 2;
676 
677  const int nSeg = 15;
678  for (int i = 0; i < nSeg; ++i) {
679 
680  const double theta_1 = 360*deg / nSeg * i;
681  const double theta_2 = 360*deg / nSeg * (i + 1);
682 
683  TPolyLine3D* const l_in = new TPolyLine3D(2);
684  l_in->SetPoint(0, cos(theta_1)*fR1, sin(theta_1)*fR1, fPosZ);
685  l_in->SetPoint(1, cos(theta_2)*fR1, sin(theta_2)*fR1, fPosZ);
686  l_in->SetLineColor(color);
687  l_in->SetLineWidth(width);
688  l_in->Draw();
689  objs->AddLast(l_in);
690 
691  TPolyLine3D* const l_out = new TPolyLine3D(2);
692  l_out->SetPoint(0, cos(theta_1)*fR2, sin(theta_1)*fR2, fPosZ);
693  l_out->SetPoint(1, cos(theta_2)*fR2, sin(theta_2)*fR2, fPosZ);
694  l_out->SetLineColor(color);
695  l_out->SetLineWidth(width);
696  l_out->Draw();
697  objs->AddLast(l_out);
698 
699  TPolyLine3D* const l_seg = new TPolyLine3D(2);
700  l_seg->SetPoint(0, cos(theta_1)*fR1, sin(theta_1)*fR1, fPosZ);
701  l_seg->SetPoint(1, cos(theta_1)*fR2, sin(theta_1)*fR2, fPosZ);
702  l_seg->SetLineColor(color);
703  l_seg->SetLineWidth(width);
704  l_seg->Draw();
705  objs->AddLast(l_seg);
706  }
707  return objs;
708 }
709 
710 
711 /*
712  new KG default from GAP 1999-12,1999-13, 1999-14 (older prototypes)
713  GAP 2000-003 describes also the final lens design !!!!!!!!!!!!!!!!!
714 
715  the function CurvaturePrototype and ProfilePrototype
716  are derived from Tilo Waldenmaier, not sure how this relates to reality...
717 
718  The real lenses are torus shapes as explained in gap 2000-003 and in the FD-Paper NIM 2012
719 */
720 
721 
722 // thikness profile as a function of radial distance
723 Vector
724 Lens::CurvaturePrototype(const double x, const double y)
725  const
726 {
727  const double r = sqrt(x*x + y*y);
728 
729  static const double f = 3.4*m - 1.743*m;
730  static const double Rd = 0.85*m;
731  static const double A = 3/2. * Rd * Rd;
732  static const double n = 1.5;
733 
734  static const double denominator = 32 * (n - 1) * f * f * f;
735  static const double a1 = 1 / denominator; // r^4
736  static const double a2 = A / denominator; // r^2
737 
738  const double dTdr = 4 * a1 * r * r * r - 2 * a2 * r;
739  //dTdr *= 0.9; // this would be a bit better
740 
741  // Tilos KA prototyp
742  //const double dTdr = 6 * 4e-18*mm * pow(r, 5) * pow(1*mm, -6);
743 
744  // new KG default from GAP ...
745 
746  double nr = dTdr;
747  double nz = 1;
748  const double norm = sqrt(nr*nr + nz*nz);
749 
750  nr /= norm;
751  nz /= norm;
752 
753  const double phi = atan2(y, x);
754 
755  return Vector(-nr * cos(phi), -nr * sin(phi), nz, fTelCS);
756 
757  // old FDSim code:
758  /*const double r2 = r*r;
759  const double aux = 2*(-1.2461221e-02 + 2 * 8.6476346e-03 * r2 + 3*2.0361284e-03 * r2*r2);
760 
761  const Vector norm = Normalized(Vector(-x*aux, -y*aux, 1.0, fTelCS));
762 
763  return norm;*/
764 }
765 
766 
767 void
769  const RTFunctions::IntersectionList& intersections)
770  const
771 {
772  double smallestZ = 10 * fTubeRadius; // definitely outside the torus and outside the telescope
773  for (unsigned int i = 0, n = intersections.size(); i < n; ++i) {
774  const double tmp_z = intersections[i].first.GetPosition().GetZ(fTelCS);
775  if (tmp_z < smallestZ) {
776  smallestZ = tmp_z;
777  index = i;
778  }
779  }
780 }
781 
782 #if 0
783 // thikness profile as a function of radial distance
784 double
785 Lens::ProfilePrototype(const double r)
786  const
787 {
788  const double r2 = r * r;
789 
790  // Tilos KA prototyp
791  /*r2 /= (mm*mm);
792  const double z = 4e-18*mm * pow(r2, 3) + 0.91*mm;*/
793 
794  static const double f = 3.4*m - 1.743*m;
795  static const double Rd = 0.85*m;
796  static const double A = 3/2. * Rd * Rd;
797  static const double n = 1.5;
798 
799  static const double denominator = 32 * (n - 1) * f * f * f;
800  static const double a1 = 1 / denominator; // r^4
801  static const double a2 = A / denominator; // r^2
802 
803  static const double z0 = 10*mm;
804 
805  const double z = z0 + a1 * r2 * r2 - a2 * r2;
806 
807  // old FDSim code:
808  /*const double aux = 2*(-1.2461221e-02 + 2*8.6476346e-03*r2 + 3*2.0361284e-03*r2*r2);
809 
810  const Vector norm = Normalized(Vector(-x*aux, -y*aux, 1.0, fTelCS));
811 
812  const double z = sqrt(pow(norm.GetX(fTelCS), 2) + pow(norm.GetY(fTelCS), 2));*/
813 
814  return z;
815 }
816 #endif
817 
818 
820 {
821 #if 0
822  if (fNbug) {
823  //INFO("#######################################################");
824  ostringstream bugMsg;
825  bugMsg << fNbug << " photons lost because of \'first inLens, now in aperture\'-bug";
826  INFO(bugMsg.str());
827  //INFO("#######################################################");
828  }
829 #endif
830 }
std::vector< PhotonNormalPair > IntersectionList
Definition: /RTFunctions.h:47
RayTracer::Track * fPhotonTrack
Definition: /Lens.h:98
utl::CoordinateSystemPtr fTelCS
Definition: /Lens.h:83
TObjArray * Draw()
Definition: /Lens.cc:670
constexpr double mm
Definition: AugerUnits.h:113
constexpr T Sqr(const T &x)
Point object.
Definition: Point.h:32
const double fR2
Definition: /Lens.h:90
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
const double fPosZ
Definition: /Lens.h:74
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
Definition: BasicVector.h:251
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
double GetWeight() const
weight assigned to the photon
Definition: Photon.h:21
int debug
Definition: dump1090.h:276
Lens(utl::RandomEngine &rndm, const fdet::Telescope &tel, const bool simulateHaloEffects, const double lensIncreaseRefl, const double lensPosition, const double minLensThickness, const double torusRadius, const double tubeRadius, const double torusZ0)
Definition: /Lens.cc:46
double GetMag() const
Definition: Vector.h:58
void SetPosition(const utl::Point &p)
Definition: Photon.h:33
int Refraction(const double n12, const utl::Photon &photonIn, const Vector &normal, PhotonList &photonsOut)
const double fR1
Definition: /Lens.h:89
constexpr double deg
Definition: AugerUnits.h:140
unsigned int fNbug
Definition: /Lens.h:95
Vector TorusNormal(const utl::Point &origin, const utl::Vector &inwards, const utl::Point &point, const double torusRadius, const double tubeRadius)
void AddPoint(const utl::Point &p)
Definition: /RayTracer.cc:34
const utl::TabulatedFunction & fTransmittance
Definition: /Lens.h:93
const utl::Point fPosPlane
Definition: /Lens.h:86
double GetX(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:206
utl::Vector CurvaturePrototype(const double x, const double y) const
Definition: /Lens.cc:724
Wraps the random number engine used to generate distributions.
Definition: RandomEngine.h:27
constexpr double kPi
Definition: MathConstants.h:24
const double fIndexAir
Definition: /Lens.h:91
double abs(const SVector< n, T > &v)
void SetSource(const int source)
Definition: Photon.h:32
void ChoosePhysicalIntersection(unsigned int &index, const RTFunctions::IntersectionList &intersections) const
Definition: /Lens.cc:768
const double fTorusRadius
Definition: /Lens.h:76
RTNext TraceWithTorus(const utl::Photon &photonIn, utl::Photon &photonOut)
Simulate the lens.
Definition: /Lens.cc:341
void SetWeight(const double w)
source of the photons. Should use Eye::LightSource enum types
Definition: Photon.h:31
const bool fSimulateHaloEffects
Definition: /Lens.h:68
const utl::Vector & GetDirection() const
Definition: Photon.h:26
double GetY(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:209
const double fIncreaseReflection
Definition: /Lens.h:71
double Plane(const utl::Point &point, const utl::Vector &normal, const utl::Photon &photonIn, utl::Photon &photonOut)
Definition: /RTFunctions.cc:81
Detector description interface for Telescope-related data.
double norm(utl::Vector x)
double ProfilePrototype(const double r) const
Vector LambertDiffusion(utl::RandomEngine &rndm, const Vector &rayIn, const Vector &normal, const double amountOfStrayLight, const double MaxTheta)
constexpr double cm
Definition: AugerUnits.h:117
Vector object.
Definition: Vector.h:30
RTNext Trace(const utl::Photon &photonIn, utl::Photon &photonOut)
const utl::Point fTorusOrigin
Definition: /Lens.h:85
std::vector< utl::Photon > PhotonList
Definition: /RTFunctions.h:35
const utl::TabulatedFunction & fRefractiveIndex
Definition: /Lens.h:92
double GetWavelength() const
Definition: Photon.h:27
double GetZ(const CoordinateSystemPtr &coordinateSystem) const
Definition: BasicVector.h:212
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
utl::RandomEngine & fRandom
Definition: /Lens.h:67
void Torus(const utl::Point &origin, const utl::Vector &inwards, const double torusRadius, const double tubeRadius, const utl::Photon &photonIn, IntersectionList &intersections)
void SetDirection(const utl::Vector &v)
Definition: Photon.h:34
const double fTubeRadius
Definition: /Lens.h:77
const utl::Point & GetPosition() const
Definition: Photon.h:25

, generated on Tue Sep 26 2023.