icemc
 All Classes Namespaces Files Functions Variables Friends Macros Pages
ray.hh
Go to the documentation of this file.
1 #ifndef RAY_H_
2 #define RAY_H_
3 
5 //class Ray:
7 class Vector;
8 class IceModel;
9 class Settings;
10 class Anita;
11 class TRandom3;
12 class Position;
13 class Signal;
14 
15 #include <iostream>
16 #include <cmath>
17 
18 
19 using std::cout;
21 class Ray {
22 
23 private:
24  TRandom3 Rand3;
25 
26 protected:
27 
28 
29 
30 public:
31  Ray();
32  void Initialize();
33 
34  int MAKEVERTICAL; // option in the input file to force the signal to hit the payload with completely vertical polarisation. For making signal efficiency curves.
35  Vector n_exit2bn[5]; // normal vector in direction of exit point to balloon - 5 iterations, 3 directions for each
36  Vector nsurf_rfexit; // normal of the surface at the place where the rf leaves
38  Vector nrf_iceside[5]; // direction of rf [tries][3d]
39 
43 
45  Position rfexit[5]; // position where the rf exits the ice- 5 iterations, 3 dimensions each
46 
47 
48  double sum_slopeyness; // for summing the average slopeyness
49  //double sum_slopeyness=0; // for summing the average slopeyness
51 
53 
54  int GetRayIceSide(const Vector &n_exit2bn,
55  const Vector &nsurf_rfexit,
56  double nexit,
57  double nenter,
58  int inu,
59 
60  Vector &nrf2_iceside);
61 
62  int TraceRay(Settings *settings1,Anita *anita1,int whichiteration,double n_depth,int inu);
63 
64 
65  int GetSurfaceNormal(Settings *settings1,IceModel *antarctica,Vector posnu,double &slopeyangle,int whichtry);
66 
67  int RandomizeSurface(Settings *settings1,Position rfexit_temp,Vector posnu,IceModel *antarctica,double &slopeyangle,int whichtry);
68 
69 
70  void GetRFExit(Settings *settings1,Anita *anita1,int whichray,Position posnu,Position posnu_down,Position r_bn,Position r_boresights[Anita::NLAYERS_MAX][Anita::NPHI_MAX],int whichtry,IceModel *antarctica);
71 
72  // void WhereDoesItLeave(const Position &posnu,
73  // const Vector &nnu,Position &r_out);
74 
75  // static void WhereDoesItLeave(const Position &posnu,
76  // const Vector &nnu,Position &r_out);
77 
78  static int WhereDoesItLeave(int inu,const Position &posnu,
79  const Vector &ntemp,IceModel *antarctica,
80  Position &r_out) {
81 
82  double distance=0;
83  double posnu_length=posnu.Mag(); // distance from center of earth to interaction
84 
85  double lon,lat,lon_old,lat_old; //latitude, longitude indices for 1st and 2nd iteration
86  lon = posnu.Lon(); // what latitude, longitude does interaction occur at
87  lat = posnu.Lat();
88  lon_old=lon; // save this longitude and latitude so we can refer to it later
89  lat_old=lat;
90 
91  // use law of cosines to get distance from interaction to exit point for the ray
92  // need to solve for that distance using the quadratic formula
93 
94  // angle between posnu and ntemp vector for law of cosines.
95  double costheta=-1*(posnu*ntemp)/posnu_length;
96 
97  // a,b,c for quadratic formula, needed to solve for
98  double a=1;
99  double b=-1*2*posnu_length*costheta;
100  double c=posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2);
101 
102 
103  if (b*b-4*a*c<0.) {
104 
105  return 0;
106  }
107  // else
108  // cout << "positive. c is " << c << "\n";
109 
110 
111  // use the "+" solution because the other one is where the ray is headed downward toward the rock
112  distance=(-1*b+sqrt(b*b-4*a*c))/2;
113 
114 
115  // now here is the exit point for the ray
116  r_out = posnu + distance*ntemp;
117 
118  lon = r_out.Lon(); // latitude and longitude of exit point
119  lat = r_out.Lat();
120 
121 
122  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
123  // sometimes though the new surface is lower than the one over posnu which causes a problem.
124  if (b*b-4*a*c<0.) {
125  //cout << "inu is " << inu << "\n";
126  // try halving the distance
127  distance=distance/2.;
128  //cout << "bad. distance 1/2 is " << distance << "\n";
129  r_out = posnu + distance*ntemp;
130  lon = r_out.Lon(); // latitude and longitude of exit point
131  lat = r_out.Lat();
132  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
133  if (b*b-4*a*c<0.) { // if we still have the problem back up more
134  distance=distance/2.; // now we are at 1/4 the distance
135  //cout << "bad. distance 1/4 is " << distance << "\n";
136  r_out = posnu + distance*ntemp;
137  lon = r_out.Lon(); // latitude and longitude of exit point
138  lat = r_out.Lat();
139  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
140  if (b*b-4*a*c<0.) { // the problem is less then 1/4 of the way in
141 
142  distance=distance/2.; // now we are at 1/8 the distance
143  //cout << "bad. distance 1/8 is " << distance << "\n";
144  r_out = posnu + distance*ntemp;
145  lon = r_out.Lon(); // latitude and longitude of exit point
146  lat = r_out.Lat();
147  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
148 
149  if (b*b-4*a*c<0.) {
150  // still have the problem so just make the distance 0
151  distance=0.; // now we are at 1/8 the distance
152  //cout << "bad. distance is " << distance << "\n";
153  lon = posnu.Lon(); // latitude and longitude of exit point
154  lat = posnu.Lat();
155  r_out=antarctica->Surface(lon,lat)/posnu.Mag()*posnu;
156  }
157  // else
158  // cout << "good.\n";
159 
160 
161 
162 
163 
164  } // now we are at 1/8 the distance
165  else {// if this surface is ok problem is between 1/4 and 1/2
166  distance=distance*1.5; // now we are at 3/8 the distance
167  // cout << "good. distance 3/8 is " << distance << "\n";
168  r_out = posnu + distance*ntemp;
169  lon = r_out.Lon(); // latitude and longitude of exit point
170  lat = r_out.Lat();
171  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
172 
173  if (b*b-4.*a*c<0.) {
174  distance=distance*2./3.; // go back to 1/4
175  r_out = posnu + distance*ntemp;
176  lon = r_out.Lon(); // latitude and longitude of exit point
177  lat = r_out.Lat();
178  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
179  //cout << "good at distance 1/4 is " << distance << "\n";
180  }
181  // else
182  // cout << "good.\n";
183 
184  } // now we are at 3/8 the distance
185 
186 
187  } // now we are at 1/4 the distance
188  else { // if this surface at 1/2 distance is ok see if we can go a little further
189  distance=distance*1.5; // now we are at 3/4 the distance
190  //cout << "good. distance 3/4 is " << distance << "\n";
191  r_out = posnu + distance*ntemp;
192  lon = r_out.Lon(); // latitude and longitude of exit point
193  lat = r_out.Lat();
194  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
195  if (b*b-4*a*c<0.) { // the problem is between 1/2 and 3/4 of the way in
196 
197  distance=distance*5./6.; // now we are at 5/8 the distance
198  //cout << "bad. distance 5/8 is " << distance << "\n";
199  r_out = posnu + distance*ntemp;
200  lon = r_out.Lon(); // latitude and longitude of exit point
201  lat = r_out.Lat();
202  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
203 
204  if (b*b-4*a*c<0.) {
205  distance=distance*4./5.;
206  r_out = posnu + distance*ntemp;
207  lon = r_out.Lon(); // latitude and longitude of exit point
208  lat = r_out.Lat();
209  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
210  //cout << "good at distance 3/4 is " << distance << "\n";
211  }
212  // else
213  // cout << "good at distance 5/8.\n";
214 
215 
216 
217  } // now we are at 1/8 the distance
218  else {// if this surface is ok problem is between 1/4 and 1/2
219  distance=distance*7./6.; // now we are at 7/8 the distance
220  //cout << "good. distance 7/8 is " << distance << "\n";
221  r_out = posnu + distance*ntemp;
222  lon = r_out.Lon(); // latitude and longitude of exit point
223  lat = r_out.Lat();
224  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
225 
226  if (b*b-4*a*c<0) {
227  // now found the problem so go back to 3/4 distance
228  distance=distance*6./7.;
229  //cout << "good at distance 3/4 is " << distance << "\n";
230  r_out = posnu + distance*ntemp;
231  lon = r_out.Lon(); // latitude and longitude of exit point
232  lat = r_out.Lat();
233  c = posnu_length*posnu_length - pow(antarctica->Surface(lon,lat),2); // redo the law of cosines
234 
235 
236  }
237  // else
238  // cout << "good.\n";
239 
240  } // now we are at 3/8 the distance
241 
242  } // now we are at 3/4 distance
243 
244  } // if exit point we initially found was not ok
245  else {
246  distance=(-1*b+sqrt(b*b-4*a*c))/2; // and quadratic formula
247  r_out = posnu + distance*ntemp;
248  }
249  return 1;
250  }
251 
252 
253 
257 }; //class Ray
258 
259 
260 #endif