1 | #include <vector>
|
---|
2 | #include <iostream>
|
---|
3 |
|
---|
4 | #include <TH1.h>
|
---|
5 | #include <TMarker.h>
|
---|
6 | #include <TArrow.h>
|
---|
7 | #include <TCanvas.h>
|
---|
8 | #include <TRandom.h>
|
---|
9 |
|
---|
10 | #include "MFresnelLens.h"
|
---|
11 |
|
---|
12 | /*****************************************************************
|
---|
13 |
|
---|
14 | fresnellens_traceray.C - 2D Example of ray-tracing the fresnel lens
|
---|
15 |
|
---|
16 | The macro has to be compilesd to work
|
---|
17 |
|
---|
18 | To run the macro from the command line (assuming you are in a directory
|
---|
19 | Mars/build where you have built your Mars environment) you have to do
|
---|
20 |
|
---|
21 | root ../hawc/fresnellens_traceray.C++
|
---|
22 |
|
---|
23 | or from within root
|
---|
24 |
|
---|
25 | [0] .x ../hawc/fresnellens_traceray.C++
|
---|
26 |
|
---|
27 | ******************************************************************/
|
---|
28 | void fresnellens_traceray()
|
---|
29 | {
|
---|
30 | // ------------------- setup lens -----------------------
|
---|
31 |
|
---|
32 | const double D = 54.92; // [cm] Diameter of the refractive surface
|
---|
33 | const double F = 50.21; // [cm] Nominal focal length of the lens
|
---|
34 |
|
---|
35 | const double H = 0.25; // [cm] Width of a single groove
|
---|
36 | const double w = 0.01; // [cm] Width of a single groove
|
---|
37 | //const double w = 1; // [cm] Width of a single groove
|
---|
38 | //const double H = 2.5; // [cm] Thickness of lens
|
---|
39 |
|
---|
40 | const double Z = F+H; // [cm] camera position w.r.t. lens exit (see also MGeomCamFAMOUS!)
|
---|
41 | const double R = D/2; // [cm] radius of lens
|
---|
42 |
|
---|
43 | const double lambda0 = 546; // [nm] Wavelength for lens surface definition
|
---|
44 | const double lambda = 546; // [nm] Wavelength for the simulated photons
|
---|
45 |
|
---|
46 | const bool point_source = false; // Enable simulation of a point source
|
---|
47 |
|
---|
48 | const double angle = 6; // [deg] Angle of incidence of the simulated rays
|
---|
49 |
|
---|
50 | const double Z0 = point_source ? F : 3; // [cm] Starting Z-position of rays
|
---|
51 | const double X0 = Z0*atan(angle*TMath::DegToRad()); // [cm] (If<0: parallel rays (see angle), If>=0: point source at X0/Z0)
|
---|
52 |
|
---|
53 | MFresnelLens lens;
|
---|
54 | lens.DefineLens(F, D, w, H, lambda0);
|
---|
55 | //lens.SetPSF(psf);
|
---|
56 | //lens.EnableSlopeAbsorption();
|
---|
57 | //lens.EnableDraftAbsorption();
|
---|
58 | //lens.DisableBottomReflection();
|
---|
59 | //lens.DisableMultiEntry();
|
---|
60 | //lens.DisableFresnelReflection();
|
---|
61 | lens.ReadTransmission("resmc/hawcseye/transmission-pmma-3mm.txt", 0.3, true);
|
---|
62 |
|
---|
63 | // ------------------ Setup display ---------------------
|
---|
64 |
|
---|
65 | TH1C h("", "", 10000, -R*1.1, R*1.1);
|
---|
66 | h.SetStats(kFALSE);
|
---|
67 | h.SetMaximum( 3);
|
---|
68 | h.SetMinimum(-1.1*F);
|
---|
69 | h.DrawCopy();
|
---|
70 |
|
---|
71 | TLine line;
|
---|
72 | line.SetLineWidth(2);
|
---|
73 |
|
---|
74 | for (unsigned int i=0; i<lens.GetNumGrooves(); i++)
|
---|
75 | {
|
---|
76 | const MFresnelLens::Groove &g = lens[i];
|
---|
77 |
|
---|
78 | line.SetLineColor(kBlack);
|
---|
79 | line.DrawLine( w*i, 0, g.r, g.slope.h);
|
---|
80 | line.DrawLine(-w*i, 0, -g.r, g.slope.h);;
|
---|
81 |
|
---|
82 | line.SetLineColor(kRed);
|
---|
83 | line.DrawLine( g.r, g.slope.h, w*i+w, 0);
|
---|
84 | line.DrawLine(-g.r, g.slope.h, -w*i-w, 0);
|
---|
85 | }
|
---|
86 |
|
---|
87 | line.SetLineColor(kBlack);
|
---|
88 | line.SetLineWidth(1);
|
---|
89 | line.DrawLine(-30, -H, 30, -H);
|
---|
90 | line.DrawLine(-30, -Z, 30, -Z);
|
---|
91 | line.DrawLine( R, -Z, R, 0);
|
---|
92 | line.DrawLine(-R, -Z, -R, 0);
|
---|
93 | line.SetLineWidth(3);
|
---|
94 | line.DrawLine(-4.5*1.5, -Z, 4.5*1.5, -Z);
|
---|
95 | line.SetLineWidth(1);
|
---|
96 |
|
---|
97 | // ------------------------------------------------------
|
---|
98 |
|
---|
99 | if (point_source)
|
---|
100 | cout << "\nPoint source at x=" << X0 << " z=" << Z0 << "\n" << endl;
|
---|
101 |
|
---|
102 | // ------------------------------------------------------
|
---|
103 |
|
---|
104 | TArrow arrow;
|
---|
105 | TMarker marker;
|
---|
106 |
|
---|
107 | marker.SetMarkerColor(kBlue);
|
---|
108 | marker.SetMarkerStyle(kFullDotMedium);
|
---|
109 |
|
---|
110 | arrow.SetArrowSize(0.01);
|
---|
111 | arrow.SetLineColor(kBlue);
|
---|
112 |
|
---|
113 | double vc = 1./(TMath::C()*100/1e9); // cm/ns
|
---|
114 |
|
---|
115 | for (int i=0; i<100; i++)
|
---|
116 | {
|
---|
117 | double X = gRandom->Uniform(-R, R);
|
---|
118 |
|
---|
119 | TVector3 pos(X, 0, 0);
|
---|
120 | TVector3 dir(0, 0, -1);
|
---|
121 |
|
---|
122 | double theta = point_source ?
|
---|
123 | TMath::Pi()-atan((X+X0)/Z0) :
|
---|
124 | (180-angle)*TMath::DegToRad();
|
---|
125 |
|
---|
126 | dir.SetMagThetaPhi(1, theta, 0);
|
---|
127 |
|
---|
128 | MQuaternion p(pos, 0);
|
---|
129 | MQuaternion u(dir, vc);
|
---|
130 |
|
---|
131 | // Propagate to starting plane in front of the lens
|
---|
132 | p.PropagateZ(u, Z0);
|
---|
133 |
|
---|
134 | vector<MQuaternion> vec;
|
---|
135 | vec.push_back(p);
|
---|
136 |
|
---|
137 | const int cnt = lens.TraceRay(vec, p, u, lambda, true);
|
---|
138 |
|
---|
139 | // Particle successfully reached the focal plane
|
---|
140 | if (cnt>=0)
|
---|
141 | {
|
---|
142 | p.PropagateZ(u, -Z);
|
---|
143 | vec.push_back(p);
|
---|
144 |
|
---|
145 | p.PropagateZ(u, u.Z()<0 ? -2.5*F : Z0);
|
---|
146 | vec.push_back(p);
|
---|
147 | }
|
---|
148 |
|
---|
149 | // Particle is upgoing and has hit no surface
|
---|
150 | if (cnt==-1291 || cnt==-1391)
|
---|
151 | {
|
---|
152 | p.PropagateZ(u, 3);
|
---|
153 | vec.push_back(p);
|
---|
154 | }
|
---|
155 |
|
---|
156 | arrow.SetLineColor(kBlue);
|
---|
157 | for (unsigned int j=0; j<vec.size()-1; j++)
|
---|
158 | {
|
---|
159 | arrow.DrawArrow(vec[j].X(), vec[j].Z(), vec[j+1].X(), vec[j+1].Z());
|
---|
160 | marker.DrawMarker(vec[j+1].X(), vec[j+1].Z());
|
---|
161 | }
|
---|
162 | }
|
---|
163 | }
|
---|