balloon.cc
1 #include "TChain.h"
2 #include "TFile.h"
3 #include "Constants.h"
4 #include "Settings.h"
5 #include "earthmodel.hh"
6 #include "icemodel.hh"
7 #include "vector.hh"
8 #include "TF1.h"
9 #include "TH1F.h"
10 #include "TGraph.h"
11 #include "TMath.h"
12 
13 #include "position.hh"
14 #include "anita.hh"
15 #include "ray.hh"
16 
17 #include "balloon.hh"
18 #include "Settings.h"
19 #include "Primaries.h"
20 #include "EnvironmentVariable.h"
21 #include "icemc_random.h"
22 
23 
24 #if defined(ANITA_UTIL_EXISTS) and defined(VECTORIZE)
25 #include "vectormath_trig.h"
26 
27 #endif
28 using std::ifstream;
29 
30 const string ICEMC_SRC_DIR=EnvironmentVariable::ICEMC_SRC_DIR();
31 const string ICEMC_DATA_DIR=ICEMC_SRC_DIR+"/data/";
32 const string anitaliteflight=ICEMC_DATA_DIR+"/BalloonGPS.txt"; // the gps path of the anita-lite flight
33 const string anitaflight=ICEMC_DATA_DIR+"/anitagps.txt";// gps path of anita flight
34 
35 
36 Balloon::Balloon() {
37  MAXHORIZON=800000.; // pick the interaction within this distance from the balloon so that it is within the horizon
38  ibnposition=0;
39  igps=0;
40  horizcoord_bn=0; // x component of balloon position
41  vertcoord_bn=0; // y component of balloon position
42  BN_LONGITUDE=999; //balloon longitude for fixed balloon location
43  BN_LATITUDE=999; //balloon latitude for fixed balloon location
44 }
45 
46 void Balloon::setObservationLocation(Interaction *interaction1,int inu,IceModel *antarctica,Settings *settings1) {
47  interaction1->banana_volts = 0; //Zero the variable
49 
50  // First pick theta of the obs vector from nu vector
51  interaction1->banana_theta_obs = -0.5*PI/settings1->vertical_banana_points * ((int)(inu/settings1->horizontal_banana_points));
52  interaction1->banana_phi_obs = 2*PI/settings1->horizontal_banana_points * (inu%settings1->horizontal_banana_points);
53  interaction1->banana_weight = (double)fabs(sin(interaction1->banana_theta_obs)); //Set "weight" - purely a phase factor
54  interaction1->banana_obs = interaction1->banana_obs.RotateY(interaction1->banana_theta_obs);
55 
56  // Now the phi of the obs vector relative to the nu vector
57  interaction1->banana_obs = interaction1->banana_obs.RotateZ(interaction1->banana_phi_obs);
58 
59  // Finally rotate the obs vector to the nu vector's orientation (change coordinate systems, in effect)
60  interaction1->banana_obs = interaction1->banana_obs.RotateY(PI-Interaction::theta_nu_banana);
61  interaction1->banana_obs = interaction1->banana_obs.RotateZ(Interaction::phi_nu_banana);
62 
63  //Finally, set the balloon position to the location which we would like to observe
64  r_bn = interaction1->nu_banana_surface + interaction1->banana_obs;
65 
66  theta_bn = r_bn.Theta();
67  phi_bn = r_bn.Phi();
68  surface_under_balloon = antarctica->Surface(r_bn);
69  // position of balloon at earth's surface (the shadow it would cast with the sun overhead)
71  altitude_bn = r_bn.Mag() - surface_under_balloon;
72 
73  //Finished setting observation location
74 }
75 void Balloon::SetDefaultBalloonPosition(IceModel *antarctica1) { // position of surface of earth under balloon
76 
77  // set the default balloon position
78  // if you are an Anita path, these get overwritten for each event
79  //cout << "BN_LATITUDE is " << BN_LATITUDE << "\n";
80  //cout << "BN_LONGITUDE is " << BN_LONGITUDE << "\n";
81 
82  int BN_LATITUDE_SETTING = BN_LATITUDE;
83  int BN_LONGITUDE_SETTING = BN_LONGITUDE;
84 
85  if(BN_LATITUDE_SETTING==999)
86  theta_bn=10*RADDEG; // wrt south pole
87  else
88  theta_bn=(90-BN_LATITUDE_SETTING)*RADDEG;
89 
90  if(BN_LONGITUDE_SETTING==999)
91  phi_bn=PI/4; //wrt 90E longitude
92  else
93  phi_bn=EarthModel::LongtoPhi_0isPrimeMeridian(BN_LONGITUDE_SETTING); //remember input of LongtoPhi is between -180 and 180
94 
95 
96  r_bn = Position(theta_bn,phi_bn); // direction of balloon- right now this is a unit vector
97 
98  if (BN_ALTITUDE==0) // if the altitude isn't set in the input file
99  altitude_bn=37000.; // 37000 m.
100  else
101  altitude_bn=BN_ALTITUDE; // altitude in meters
102 
103  surface_under_balloon = antarctica1->Surface(r_bn); // distance between center of earth and surface under balloon
104 
105  r_bn_shadow = surface_under_balloon * r_bn.Unit(); // position of surface under balloon
106 
107  r_bn = (antarctica1->Geoid(r_bn)+altitude_bn) * r_bn; // position of balloon
108 
109 } // set default balloon position
110 
111 
113 
114 
115 
116 
117  ifstream flightfile(anitaliteflight.c_str()); //set file to the right one
118  if (!flightfile) {
119  cout << "Flight file not found.\n";
120  exit(1);
121  }
122 
123 
124 
125  string slatitude; // latitude in string format
126  string slongitude; //longitude in string format
127  string saltitude; // altitude in string format
128  string sheading; // heading in string format
129  string srealtime; // real life unix time in string format
130  string junk; // string not used for anything
131 
132  string line; // for reading a whole line
133  double latitude; // same quantities as above but in double format
134  double longitude;
135  double altitude;
136  double heading;
137  double realtime;
138 
139  getline(flightfile,junk); // first few lines are junk
140  getline(flightfile,junk);
141  getline(flightfile,junk);
142  getline(flightfile,junk);
143 
144  NPOINTS=0; // number of points we have for the flight path
145 
146 
147 
148  while (!flightfile.eof()) {
149 
150 
151  flightfile >> srealtime >> junk >> slatitude >> slongitude >> saltitude >> sheading >> junk >> junk >> junk;
152 
153 
154  //cout << "they are " << NPOINTS << " " << srealtime << " " << junk << " " << slatitude << " " << slongitude << " " << saltitude << " " << sheading << "\n";
155  //cout << "slatitude is " << slatitude << "\n";
156  latitude=(double)atof(slatitude.c_str());
157  longitude=(double)atof(slongitude.c_str());
158  altitude=(double)atof(saltitude.c_str());
159  heading=(double)atof(sheading.c_str());
160  realtime=(double)atof(srealtime.c_str());
161 
162 
163  // latitude and longitude of each balloon position
164  latitude_bn_anitalite[NPOINTS]=latitude;
165  longitude_bn_anitalite[NPOINTS]=longitude;
166  altitude_bn_anitalite[NPOINTS]=altitude;
167  heading_bn_anitalite[NPOINTS]=heading;
168  realtime_bn_anitalite[NPOINTS]=realtime;
169 
170 
171  NPOINTS++;
172 
173 
174  // cout << "NPOINTS, altitude are " << NPOINTS << " " << altitude << "\n";
175 
176  getline(flightfile,junk);
177 
178  }//while
179 
180 
181 
182  NPOINTS_MAX=NPOINTS-140; // exclude the fall
183  NPOINTS_MIN=0;
184 
185 
186 
187 }//ReadAnitaliteFlight
189 
190 
191  // GPS positions of Anita or Anita-lite balloon flight
192  if (WHICHPATH==2)
194 
195 
196  MINALTITUDE=30000; // balloon has to be 30 km altitude at least for us to read the event from the flight data file
197 
198  // initialisation of igps_previous
199  if (WHICHPATH==6 || WHICHPATH==7 || WHICHPATH==8 || WHICHPATH==9)
200  igps_previous=0; // which entry from the flight data file the previous event was
201  if (WHICHPATH==2)
202  igps_previous=NPOINTS_MIN; // initialise here to avoid times during launch
203 
204  flightdatachain = 0;
205 
206  // This for Anita 1 flight
207  if (WHICHPATH==6) {
208 
209  flightdatachain = new TChain("foricemc");
210  flightdatachain->Add((ICEMC_DATA_DIR+"/anita1flightdata.root").c_str());
211 
212  flightdatachain->SetBranchAddress("surfTrigBandMask",surfTrigBandMask);
213  flightdatachain->SetBranchAddress("powerthresh",powerthresh);
214  flightdatachain->SetBranchAddress("meanp",meanp);
215  flightdatachain->SetBranchAddress("longitude",&flongitude);
216  flightdatachain->SetBranchAddress("latitude",&flatitude);
217  flightdatachain->SetBranchAddress("altitude",&faltitude);
218  flightdatachain->SetBranchAddress("realTime_surfhk",&realTime_flightdata);
219  flightdatachain->SetBranchAddress("heading",&fheading);
220  }
221 
222  // This for Anita 2 flight
223  if (WHICHPATH==7) {
224 
225  flightdatachain = new TChain("adu5PatTree");
226  flightdatachain->SetMakeClass(1);
227  flightdatachain->Add((ICEMC_DATA_DIR+"/anita2gps_pitchandroll.root").c_str());//created to include pitch and roll.
228  flightdatachain->SetBranchAddress("longitude",&flongitude);
229  flightdatachain->SetBranchAddress("latitude",&flatitude);
230  flightdatachain->SetBranchAddress("altitude",&faltitude);
231  flightdatachain->SetBranchAddress("heading",&fheading);
232  flightdatachain->SetBranchAddress("realTime",&realTime_flightdata_temp);
233  flightdatachain->SetBranchAddress("pitch",&fpitch);
234  flightdatachain->SetBranchAddress("roll",&froll);
235  //cout << "Loading file. n events is " << flightdatachain->GetEntries() << "\n";
236 
237  } else if (WHICHPATH==8 || WHICHPATH==9) { // for anita-3 and 4 flights
238 
239  string balloonFile="";
240  if (WHICHPATH==8) balloonFile+=ICEMC_DATA_DIR+"/anita3gps_pitchroll.root";
241  else balloonFile+=ICEMC_DATA_DIR+"/anita4gps_pitchroll.root";
242 
243  flightdatachain = new TChain("adu5PatTree");
244  flightdatachain->SetMakeClass(1);
245  flightdatachain->Add(balloonFile.c_str());//created to include pitch and roll.
246  flightdatachain->SetBranchAddress("longitude",&flongitude);
247  flightdatachain->SetBranchAddress("latitude",&flatitude);
248  flightdatachain->SetBranchAddress("altitude",&faltitude);
249  flightdatachain->SetBranchAddress("heading",&fheading);
250  flightdatachain->SetBranchAddress("realTime",&realTime_flightdata_temp);
251  flightdatachain->SetBranchAddress("pitch",&fpitch);
252  flightdatachain->SetBranchAddress("roll",&froll);
253 
254  }
255 
256 
257  min_time = flightdatachain ? flightdatachain->GetMinimum(WHICHPATH == 6 ? "realTime_surfhk": "realTime") : 0;
258  max_time = flightdatachain ? flightdatachain->GetMaximum(WHICHPATH == 6 ? "realTime_surfhk": "realTime") : 0;
259 
260  for (int i=0;i<10000;i++) {
264  }
265  NPOINTS=0;
267 
268 
269 
270  if (WHICHPATH!=6) {
271  // if it's not the anita path, you won't be able to read in thresholds and masks
272  for (int i=0;i<9;i++) {
273  for (int j=0;j<2;j++) {
274  surfTrigBandMask[i][j]=0;
275  }
276  for (int j=0;j<32;j++) {
277  powerthresh[i][j]=3.E-12;
278  meanp[i][j]=1.E-12;
279  }
280 
281  }
282 
283 
284  }
285 }
286 
287 double Balloon::GetBalloonSpin(double heading) { // get the azimuth of the balloon
288 
289  double phi_spin;
290  if (WHICHPATH==2 || WHICHPATH==6 || WHICHPATH==7 || WHICHPATH==8 || WHICHPATH==9)
291  phi_spin=heading*RADDEG;
292  else {
294  phi_spin=getRNG(RNG_BALLOON_POSITION)->Rndm()*2*PI;
295  else
296  phi_spin=0.;
297  }
298 
299  return phi_spin;
300 }
301 
302 
304  int ibnposition_tmp;
305  if (WHICHPATH==1)
306  ibnposition_tmp = (int)(r_bn.Lon() / 2);
307  else if (WHICHPATH==2 || WHICHPATH==6 || WHICHPATH==7 || WHICHPATH==8 || WHICHPATH==9){
308  ibnposition_tmp=(int)((double)igps/(double)REDUCEBALLOONPOSITIONS);
309  // std::cout << __FUNCTION__ << " " << igps << " " << REDUCEBALLOONPOSITIONS << " " << ibnposition_tmp << std::endl;
310  } else
311  ibnposition_tmp=0;
312 
313  return ibnposition_tmp;
314 
315 }
316 
317 void Balloon::PickBalloonPosition(Vector straightup,IceModel *antarctica1,Settings *settings1,Anita *anita1) {
318  // takes a 3d vector pointing along the z axis
319  Vector thetazero(0.,0.,1.);
320  Vector phizero(1.,0.,0.);
321  igps=0;
322  theta_bn=acos(straightup.Dot(thetazero)); // 1deg
323 
324  if (straightup.GetX()==0 && straightup.GetY()==0)
325  phi_bn=0.;
326  else
327  phi_bn=acos((straightup.Cross(thetazero)).Dot(phizero)); // 1deg
328  // cout << "theta_bn, phi_bn are " << theta_bn << " " << phi_bn << "\n";
329  r_bn=Position(theta_bn,phi_bn); // sets r_bn
330  //cout << "r_bn is ";
331  //r_bn.Print();
332  if (BN_ALTITUDE!=0)
333  altitude_bn=BN_ALTITUDE; // set the altitude of the balloon to be what you pick. This isn't in time for CreateHorizons though!
334  //cout << "altitude_bn is " << altitude_bn << "\n";
335  surface_under_balloon = antarctica1->Surface(r_bn);
336  //cout << "surface_under_balloon is " << surface_under_balloon << "\n";
337  r_bn_shadow = surface_under_balloon * r_bn.Unit();
338  //cout << "r_bn_shadow is " << r_bn_shadow << "\n";
339  // r_bn = (antarctica->Geoid(r_bn)+altitude_bn) * r_bn.Unit();
340 
341  r_bn = (antarctica1->Surface(r_bn)+altitude_bn) * r_bn.Unit();
342  //cout << "r_bn is ";
343  // r_bn.Print();
344 
345 
346  ibnposition=Getibnposition();
347 
348  dtryingposition=1.;
349 
350  phi_spin=0.; // get the azimuth of the balloon.
351 
352  // normalized balloon position
353  n_bn = r_bn.Unit();
354 
355  // finding which direction is east under the balloon
356  n_east = Vector(sin(phi_bn), -1*cos(phi_bn), 0.);
357 
358 
359  // find position of each antenna boresight
360 
361  // now finding north
362  n_north = n_bn.Cross(n_east);
363 
364  // these coordinates are for filling ntuples.
365  horizcoord_bn=r_bn[0]/1000.; //m to km
366  vertcoord_bn=r_bn[1]/1000.;
367 
368 
369  calculate_antenna_positions(settings1,anita1);
370  // cout << "calculated antenna positions.\n";
371  if (settings1->BORESIGHTS)
372  GetBoresights(settings1,anita1);
373 
374 }
375 
376 // for tuffs for anita-4
377 int getTuffIndex(int Curr_time) {
378  if((TUFFconfig_B_end_3 < Curr_time) && (Curr_time <= TUFFconfig_A_end_1)) {// config A trigconfigA.imp
379  return 0;
380  }
381  else if(((0 < Curr_time) && (Curr_time <= TUFFconfig_B_end_1)) || ((TUFFconfig_P_end_3 < Curr_time) && (Curr_time <= TUFFconfig_B_end_2)) || ((TUFFconfig_P_end_4 < Curr_time) && (Curr_time <= TUFFconfig_B_end_3)) || ((TUFFconfig_A_end_1 < Curr_time) && (Curr_time <= TUFFconfig_B_end_4)) || ((TUFFconfig_P_end_5 < Curr_time) && (Curr_time <= TUFFconfig_B_end_5)) || ((TUFFconfig_P_end_6 < Curr_time) && (Curr_time <= TUFFconfig_B_end_6)) || (TUFFconfig_P_end_7 < Curr_time) ) { // config B trigconfigB.imp
382  return 1;
383  }
384  else if((TUFFconfig_P_end_1 < Curr_time) && (Curr_time <= TUFFconfig_C_end_1)) { // config C trigconfigC.imp
385  return 2;
386  }
387  else if( ((TUFFconfig_P_end_2 < Curr_time) && (Curr_time <= TUFFconfig_G_end_1)) || ((TUFFconfig_O_end_1 < Curr_time) && (Curr_time <= TUFFconfig_G_end_2)) ) { // config G trigconfigG.imp
388  return 3;
389  }
390  else if( ((TUFFconfig_G_end_1 < Curr_time) && (Curr_time <= TUFFconfig_O_end_1)) || ((TUFFconfig_G_end_2 < Curr_time) && (Curr_time <= TUFFconfig_O_end_2)) ) { // config O trigconfigO.imp
391  return 4;
392  }
393  else if( ((TUFFconfig_B_end_1 < Curr_time) && (Curr_time <= TUFFconfig_P_end_1)) || ((TUFFconfig_C_end_1 < Curr_time) && (Curr_time <= TUFFconfig_P_end_2)) || ((TUFFconfig_O_end_2 < Curr_time) && (Curr_time <= TUFFconfig_P_end_3)) || ((TUFFconfig_B_end_2 < Curr_time) && (Curr_time <= TUFFconfig_P_end_4)) || ((TUFFconfig_B_end_4 < Curr_time) && (Curr_time <= TUFFconfig_P_end_5)) || ((TUFFconfig_B_end_5 < Curr_time) && (Curr_time <= TUFFconfig_P_end_6)) || ((TUFFconfig_B_end_6 < Curr_time) && (Curr_time <= TUFFconfig_P_end_7)) ) { // config P trigconfigP.imp
394  return 5;
395  }
396 
397  return -1;
398 }
399 // this is called for each neutrino
400 void Balloon::PickBalloonPosition(IceModel *antarctica1,Settings *settings1,int inu,Anita *anita1, double randomNumber) { // r_bn_shadow=position of spot under the balloon on earth's surface
401  //cout << "calling pickballoonposition.\n";
402  pitch=0.;
403  roll=0.;
404  phi_spin=0.;
405 
406 
407 
408  //flightdatatree->SetBranchAddress("surfTrigBandMask",&surfTrigBandMask);
409  //unsigned short test[9][2];
410 
411  //double latitude,longitude,altitude;
412 
413  // cout << "I'm in pickballoonposition. whichpath is " << WHICHPATH << "\n";
414  //Pick balloon position
415  if (WHICHPATH==2 || WHICHPATH==6 || WHICHPATH==7 || WHICHPATH==8 || WHICHPATH==9) { // anita-lite or anita-I or -II path
416 
417  if (WHICHPATH==2) {
418  igps=NPOINTS_MIN+(igps_previous+1-NPOINTS_MIN)%(NPOINTS_MAX-NPOINTS_MIN); //Note: ignore last 140 points, where balloon is falling - Stephen
419  flatitude=(float)latitude_bn_anitalite[igps];
420  flongitude=(float)longitude_bn_anitalite[igps];
421  faltitude=(float)altitude_bn_anitalite[igps];
422  fheading=(float)heading_bn_anitalite[igps];
423 
424 
425  }
426  else if (WHICHPATH==6 || WHICHPATH==7 || WHICHPATH==8 || WHICHPATH==9) { // For Anita 1 and Anita 2 and Anita 3:
427  //igps=(igps_previous+1)%flightdatachain->GetEntries(); // pick which event in the tree we want
428 
429 
430  static int start_igps = 0;
431  static int ngps = flightdatachain->GetEntries();
432  static int init_best = 0;
433 
434 
435  if (settings1->PAYLOAD_USE_SPECIFIC_TIME && !init_best)
436  {
437  int N = flightdatachain->Draw("realTime","","goff");
438  double * times = flightdatachain->GetV1();
439 
440  int best_igps = TMath::BinarySearch(N, times, (double) settings1->PAYLOAD_USE_SPECIFIC_TIME);
441  start_igps = best_igps;
442  int end_igps = best_igps;
443 
444  while (times[start_igps] > settings1->PAYLOAD_USE_SPECIFIC_TIME - settings1->PAYLOAD_USE_SPECIFIC_TIME_DELTA)
445  {
446  start_igps--;
447  }
448 
449  while (times[end_igps] < settings1->PAYLOAD_USE_SPECIFIC_TIME + settings1->PAYLOAD_USE_SPECIFIC_TIME_DELTA)
450  {
451  end_igps++;
452  }
453 
454  ngps = end_igps - start_igps + 1;
455  init_best = 1;
456  }
457 
458  igps = start_igps + int(randomNumber*ngps); // use random position
459  bool adjustedTime = false;
461  if (WHICHPATH==9 && ((igps>870 && igps<880) || (igps>7730 && igps<7740) || (igps>23810 && igps<23820) || (igps>31630 && igps<31660) || (igps==17862) ) )
462  {
463  igps+=30;
464  igps=igps%flightdatachain->GetEntries(); // make sure it's not beyond the maximum entry number
465  }
466 
467  flightdatachain->GetEvent(igps); // this grabs the balloon position data for this event
471  if(WHICHPATH==9)
472  {
473  //std::cout << "realTime_flightdata = " << realTime_flightdata << std::endl;
474  // Small portion of flight, so shouldn't cause slowdown
475  while( (realTime_flightdata >= 1480725528 && realTime_flightdata <= 1480730678) || (realTime_flightdata >= 1480796516 && realTime_flightdata <= 1480804184) )
476  {
477  adjustedTime = true;
478  //std::cout << "BAD TIME DETECTED: " << realTime_flightdata << std::endl;
479  igps+=30; // pick another time, out range
480  igps=igps%flightdatachain->GetEntries(); // make sure it's not beyond the maximum entry number
481  flightdatachain->GetEvent(igps); // get new event
482  realTime_flightdata = realTime_flightdata_temp; // recalculate fight time with new igps
483  }
484  //if(adjustedTime==true){std::cout << "GOOD TIME DETECTED = " << realTime_flightdata << std::endl;}
485  }
486 
487  if(settings1->TUFFSTATUS==1){
488  anita1->tuffIndex = getTuffIndex(realTime_flightdata);
489  if(settings1->TRIGGEREFFSCAN){
490  anita1->tuffIndex = 6;
491  }
492  } else if (WHICHPATH==9 && settings1->TUFFSTATUS==2) anita1->tuffIndex = 6;
493 
494  while (faltitude<MINALTITUDE || fheading<0) { // if the altitude is too low, pick another event.
495 
496  (void) adjustedTime;
497  igps++; // increment by 1
498  igps=igps%flightdatachain->GetEntries(); // make sure it's not beyond the maximum entry number
499 
500  flightdatachain->GetEvent(igps); // get new event
501  }
502  // set phi Masking for Anita 2 or Anita 3
503  // the deadtime is read from the same tree
504  if ((WHICHPATH==7 || WHICHPATH==8 || WHICHPATH==9) && (settings1->PHIMASKING==1 || settings1->USEDEADTIME))
505  anita1->setphiTrigMask(realTime_flightdata);
506  if ((WHICHPATH==8 || WHICHPATH==9) && settings1->USETIMEDEPENDENTTHRESHOLDS==1) // set time-dependent thresholds
507  anita1->setTimeDependentThresholds(realTime_flightdata);
508 
509  }
511  latitude=(double)flatitude;
512  longitude=(double)flongitude;
513  altitude=(double)faltitude;
514  heading=(double)fheading;
515  roll=(double)froll;
516  pitch=(double)fpitch;
517 
518  setr_bn(latitude,longitude); // sets theta_bn, phi_bn and r_bn. r_bn is a unit vector pointing in the right direction
519 
520 
521 
522  if (WHICHPATH==2)
523  altitude_bn=altitude*12.*CMINCH/100.; // ANITA-lite flight input is in feet
524  else if (WHICHPATH==6 || WHICHPATH==7 || WHICHPATH==8 || WHICHPATH==9)
525  altitude_bn=altitude; // get the altitude of the balloon in the right units
526 
527  surface_under_balloon = antarctica1->Surface(r_bn); // get altitude of the surface under the balloon
528 
529  r_bn_shadow = surface_under_balloon * r_bn.Unit(); // this is a vector pointing to spot just under the balloon on the surface (its shadow at high noon)
530  r_bn = (antarctica1->Geoid(r_bn)+altitude_bn) * r_bn.Unit();
531  //r_bn = (antarctica->Surface(r_bn)+altitude_bn) * r_bn.Unit(); //this points to balloon position (not a unit vector)
532  } //if (ANITA-lite path) or anita 1 or anita 2
533 
534 
535 
536  else if (WHICHPATH==1){ // pick random phi at 80 deg S
537  phi_bn=getRNG(RNG_BALLOON_POSITION)->Rndm()*TWOPI;
538 
539  r_bn = Position(theta_bn,phi_bn);
540  surface_under_balloon = antarctica1->Surface(r_bn);
541 
543  // r_bn = (antarctica->Geoid(r_bn)+altitude_bn) * r_bn.Unit();
544  r_bn = (antarctica1->Surface(r_bn)+altitude_bn) * r_bn.Unit();
545  igps=0;
546  } //else if(random position at 80 deg S)
547  else if (WHICHPATH==0){
548 
549  igps=0; // set gps position to be zero - we're at a fixed balloon position
550 
551  }
552  else if (WHICHPATH==5) { // for slac?
553  igps=0;
554  theta_bn=1.*RADDEG; // 1deg
555  phi_bn=1.*RADDEG; // 1deg
556  r_bn=Position(theta_bn,phi_bn); // sets r_bn
557  if (BN_ALTITUDE!=0)
558  altitude_bn=BN_ALTITUDE; // set the altitude of the balloon to be what you pick. This isn't in time for CreateHorizons though!
559  surface_under_balloon = antarctica1->Surface(r_bn);
561  // r_bn = (antarctica->Geoid(r_bn)+altitude_bn) * r_bn.Unit();
562 
563  r_bn = (antarctica1->Surface(r_bn)+altitude_bn) * r_bn.Unit();
564  } // you pick it
565  else if (WHICHPATH==4){ // for making comparison with Peter's event
566  //phi_bn=0.767945;
567  // phi_bn=0.95993;
568  //166.73 longitude
569  // phi_bn=-1.339;// this is McM phi
570  // 156.73
571  phi_bn=-1.1646;// this is McM phi
572  //phi_bn=-0.523;
573  // theta_bn has been set to 10 degrees in setdefaultballoonposition
574  // we want theta_bn to be on a path along same longitude as
575  // McM but up to 10 deg further south in latitude
576  // 12.12 deg. is McM
577  double theta_max=0.2115; // this is McM theta
578  double theta_min=0.2115-0.110; // this approximately one horizon north of McM
579  //This is 701.59 km along the surface of the earth
580  int npositions=1000; // number of possible positions between those two bounds
581  theta_bn=theta_min+(theta_max-theta_min)*(double)(inu%npositions)/(double)npositions;
582 
583  r_bn = Position(theta_bn,phi_bn);
584  surface_under_balloon = antarctica1->Surface(r_bn);
585 
587  // r_bn = (antarctica->Geoid(r_bn)+altitude_bn) * r_bn.Unit();
588 
589  r_bn = (antarctica1->Surface(r_bn)+altitude_bn) * r_bn.Unit();
590  igps=0;
591  } // comparing with Peter's event
592 
593 
594 
595  ibnposition=Getibnposition();
596 
597  if (!settings1->UNBIASED_SELECTION && dtryingposition!=-999)
598  dtryingposition=antarctica1->GetBalloonPositionWeight(ibnposition);
599  else if (settings1->UNBIASED_SELECTION == 2)
600  dtryingposition=1.;
601 
602  phi_spin=GetBalloonSpin(heading); // get the azimuth of the balloon.
603 
604  // normalized balloon position
605  n_bn = r_bn.Unit();
606 
607  // finding which direction is east under the balloon
608  n_east = Vector(sin(phi_bn), -1*cos(phi_bn), 0.);
609 
610  if (settings1->SLAC)
611  AdjustSlacBalloonPosition(inu); // move payload around like we did at slac
612  // find position of each antenna boresight
613 
614  // now finding north
615  n_north = n_bn.Cross(n_east);
616 
617  // these coordinates are for filling ntuples.
618  horizcoord_bn=r_bn[0]/1000.; //m to km
619  vertcoord_bn=r_bn[1]/1000.;
620 
621  calculate_antenna_positions(settings1,anita1);
622  if (settings1->BORESIGHTS)
623  GetBoresights(settings1,anita1);
624 
625 
626 } // end PickBalloonPosition
627 void Balloon::AdjustSlacBalloonPosition(int inu) { // move payload around like we did at slac
628 
629  if (inu<=MAX_POSITIONS) // use the event number for the position if we c an
630  islacposition=inu;
631  else
632  islacposition=0; // otherwise just use the first positions
633  // adjust the payload position
634  r_bn+=slacpositions[islacposition].GetX()*n_east
635  +slacpositions[islacposition].GetY()*n_bn;
636 
637 }
638 
639 void Balloon::CenterPayload(double& hitangle_e) {
640 
641  // allow an option to rotate the payload so the signal is
642  // always on the boresight of one phi sector
643 
644  phi_spin-=hitangle_e;
645 
646 }
647 
648 
649 void Balloon::GetAntennaOrientation(Settings *settings1, Anita *anita1, int ilayer, int ifold, Vector& n_eplane, Vector& n_hplane, Vector& n_normal){
650 
651  // rotate for antenna's orientation on payload
652  // face of antenna starts out relative to +x because phi is relative to +x
653  // n_normal points northwards for antenna 0 (0-31)
654  // const vectors const_z (n_eplane), const_y (-n_hplane), const_x (n_normal) defined under Constants.h -- oindree
655 
656 
657  if(settings1->WHICH==6 || settings1->WHICH==8 || settings1->WHICH==9 || settings1->WHICH==10) {
658  n_eplane = const_z.RotateY(anita1->ANTENNA_DOWN[ilayer][ifold]);
659  n_hplane = (-const_y).RotateY(anita1->ANTENNA_DOWN[ilayer][ifold]);
660  n_normal = const_x.RotateY(anita1->ANTENNA_DOWN[ilayer][ifold]);
661  }
662  else {
663  n_eplane = const_z.RotateY(anita1->THETA_ZENITH[ilayer] - PI/2);
664  n_hplane = (-const_y).RotateY(anita1->THETA_ZENITH[ilayer] - PI/2);
665  n_normal = const_x.RotateY(anita1->THETA_ZENITH[ilayer] - PI/2);
666  }
667 
668 
669  double phi;
670  // rotate about z axis for phi
671  if (settings1->CYLINDRICALSYMMETRY==1) {
672  phi=(double)ifold/(double)anita1->NRX_PHI[ilayer]*2*PI + anita1->PHI_OFFSET[ilayer] + phi_spin;
673  }
674  else{
675  //phi=anita1->PHI_EACHLAYER[ilayer][ifold] + anita1->PHI_OFFSET[ilayer] +phi_spin;
676  phi=anita1->PHI_EACHLAYER[ilayer][ifold];
677  }
678 
679  n_eplane = n_eplane.RotateZ(phi);
680  n_hplane = n_hplane.RotateZ(phi);
681  n_normal = n_normal.RotateZ(phi);
682 
683  n_eplane = RotatePayload(n_eplane);
684  n_hplane = RotatePayload(n_hplane);
685  n_normal = RotatePayload(n_normal);
686 
687 } //end void GetAntennaOrientation
688 
689 
690 void Balloon::GetEcompHcompkvector(Vector n_eplane, Vector n_hplane, Vector n_normal, const Vector n_exit2bn, double& e_component_kvector, double& h_component_kvector, double& n_component_kvector){
691 
692 
693  // find component along e-plane for the purpose of finding hit angles, that is, in direction of k vector, direction of radio wave)
694  e_component_kvector = -(n_exit2bn * n_eplane);
695  // find component along h-plane for the purpose of finding hit angles, that is, in direction of k vector, direction of radio wave)
696  h_component_kvector = -(n_exit2bn * n_hplane);
697  // find the component normal
698  n_component_kvector = -(n_exit2bn * n_normal);
699 
700 } // end GetEcompHcompkvector
701 
702 
703 
704 void Balloon::GetEcompHcompEvector(Settings *settings1, Vector n_eplane, Vector n_hplane, const Vector n_pol, double& e_component, double& h_component, double& n_component){
705 
706  // find component along e-plane in direction of polarization, that is in direction of the E field
707  e_component = n_pol*n_eplane;
708  // std::cout << "n_component : " << n_exit2bn << " " << n_normal << " " << n_component << std::endl;
709 
710  // find component along h-plane in direction of polarization, that is in direction of the E field
711  h_component = n_pol*n_hplane;
712 
713 
714  if (settings1->REMOVEPOLARIZATION) {
715  //Trying to remove effects of polarization at antenna. Stephen
716  e_component = n_pol * n_pol;
717  h_component = 0.001;
718  n_component = 0.001;
719  } //if
720 
721 
722 } // end GetEcompHcompEvector
723 
724 
725 
726 void Balloon::GetHitAngles(double e_component_kvector, double h_component_kvector, double n_component_kvector, double& hitangle_e, double& hitangle_h) {
727 #if defined(ANITA_UTIL_EXISTS) and defined(VECTORIZE)
728  Vec2d y(e_component_kvector, h_component_kvector);
729  Vec2d x(n_component_kvector, n_component_kvector);
730  Vec2d answer = atan2(y,x);
731  hitangle_h = answer[0];
732  hitangle_e = answer[1];
733 
734 #else
735  hitangle_e=atan2(h_component_kvector,n_component_kvector);
736  hitangle_h=atan2(e_component_kvector,n_component_kvector);
737 #endif
738 
739 } //end void GetHitAngles
740 
741 
742 void Balloon::setr_bn(double latitude,double longitude) {
743 
744  // latitude is between -90 and 0.
745  // theta_bn measured from the SP and is between 0 and PI/2.
746  theta_bn=(90+latitude)*RADDEG;
747 
748  // this is the payload's longitude, not the azimuth of the balloon like it sounds.
749  // longitude is between -180 to 180 with 0 at prime meridian
750  // phi is from 0 to 360 with 0 at +90 longitude
751  phi_bn=(-1*longitude+90.);
752 
753  if (phi_bn<0)
754  phi_bn+=360.;
755 
756  phi_bn*=RADDEG;
757 
758  r_bn = Position(theta_bn,phi_bn); //r_bn is a unit vector pointing in the right direction
759 }
760 
761 
762 void Balloon::PickDownwardInteractionPoint(Interaction *interaction1, Anita *anita1, Settings *settings1, IceModel *antarctica1, Ray *ray1, int &beyondhorizon, double len_int_kgm2, Vector * force_dir) {
763 
764  // double distance=1.E7;
765  double phi=0,theta=0;
766  double lon=0;
767  double latfromSP=0;
768 
769 
770  if (settings1->UNBIASED_SELECTION>=1) {
771 
772 
773  if ( (settings1->UNBIASED_SELECTION == 1 && antarctica1->PickUnbiased(interaction1,len_int_kgm2,dtryingposition,settings1->UNBIASED_CHORD_STEP_M, force_dir)) ||
774  (settings1->UNBIASED_SELECTION == 2 && antarctica1->PickUnbiasedPointSourceNearBalloon(interaction1,&r_bn,
775  settings1->UNBIASED_PS_MAX_DISTANCE_KM,
776  settings1->UNBIASED_CHORD_STEP_M,
777  len_int_kgm2,force_dir)) )
778  { // pick neutrino direction and interaction point
779  interaction1->dtryingdirection=1.;
780  interaction1->iceinteraction=1;
781  }
782  else
783  {
784  interaction1->iceinteraction=0;
785  interaction1->d_effective_area = 0;
786  }
787 
788 
789  } else {
790  interaction1->d_effective_area = 0;
791  interaction1->iceinteraction=1;
792  if (WHICHPATH==3) { //Force interaction point if we want to make a banana plot
793  interaction1->posnu = interaction1->nu_banana;
794  } //if (making banana plot)
795  else if (WHICHPATH==4) {// Force interaction point for comparison with Peter.
796 
797  // want interaction location at Taylor Dome
798  // According to lab book it's 77 deg, 52.818' S=77.8803
799  // 158 deg, 27.555' east=158.45925
800  latfromSP=12.1197; // this is degrees latitude from the south pole
801  //lon=180.+166.73;
802  lon=180.+158.45925;
803  //lon=180.+120.
804  phi=EarthModel::LongtoPhi_0is180thMeridian(lon);
805 
806  theta = latfromSP*RADDEG;
807 
808  double elevation=antarctica1->SurfaceAboveGeoid(lon,latfromSP)-500.;
809 
810  interaction1->posnu = Vector((elevation+antarctica1->Geoid(latfromSP))*sin(theta)*cos(phi),(elevation+antarctica1->Geoid(latfromSP))*sin(theta)*sin(phi),(elevation+antarctica1->Geoid(latfromSP))*cos(theta));
811 
812 
813 
814  } //if (WHICHPATH==4)
815 
816  else if (settings1->SLAC) {
817 
818  Vector zaxis(0.,0.,1.); // start with vector pointing in the +z direction
819 
820  interaction1->posnu=zaxis.RotateY(r_bn.Theta()-settings1->SLAC_HORIZDIST/EarthModel::R_EARTH); // rotate to theta of balloon, less the distance from the interaction to the balloon
821 
822  interaction1->posnu=interaction1->posnu.RotateZ(r_bn.Phi()); // rotate to phi of the balloon
823 
824  interaction1->posnu=(antarctica1->Surface(interaction1->posnu)-settings1->SLAC_DEPTH)*interaction1->posnu; // put the interaction position at depth settings1->SLAC_DEPTH in the ice
825 
826  }
827  else{
828 
829  // If we require neutrinos from a particular position
830  // we generate that cartesian position here
831 
832  static Position specific_position(settings1->SPECIFIC_NU_POSITION_LONGITUDE, 90 + settings1->SPECIFIC_NU_POSITION_LATITUDE, settings1->SPECIFIC_NU_POSITION_ALTITUDE + antarctica1->Geoid(settings1->SPECIFIC_NU_POSITION_LATITUDE));
833 
834  int nattempts = 0;
835  do
836  {
837  interaction1->posnu = antarctica1->PickInteractionLocation(ibnposition, settings1, r_bn, interaction1);
838  // std::cout << nattempts <<":" << specific_position << " / " << interaction1->posnu << " | " << interaction1->posnu.Distance(specific_position) << std::endl;
839  nattempts++;
840  } while(settings1->SPECIFIC_NU_POSITION && interaction1->posnu.Distance(specific_position) > settings1->SPECIFIC_NU_POSITION_DISTANCE && nattempts<100000000);
841  // printf("====Took %d attempts to find a position====\n", nattempts);
842 
843  }
844  }
845 
846  //cout<<interaction1->posnu<<" "<<r_bn<<" :: "<<r_bn.Distance(interaction1->posnu)<<"\n";
847  // if (interaction1->iceinteraction) {
848  // //cout << "posnu is ";interaction1->posnu.Print();
849  // }
850  // first guess at the rf exit point is just the point on the surface directly above the interaction
851  ray1->rfexit[0] = antarctica1->Surface(interaction1->posnu) * interaction1->posnu.Unit();
852 
853  // unit vector pointing to antenna from exit point.
854  ray1->n_exit2bn[0] = (r_bn - ray1->rfexit[0]).Unit();
855 
856  if (settings1->BORESIGHTS) {
857  for(int ilayer=0;ilayer<settings1->NLAYERS;ilayer++) {
858  for(int ifold=0;ifold<anita1->NRX_PHI[ilayer];ifold++) {
859  ray1->rfexit_eachboresight[0][ilayer][ifold]=antarctica1->Surface(interaction1->posnu) * interaction1->posnu.Unit();// this first guess rfexit is the same for all antennas too
860  ray1->n_exit2bn_eachboresight[0][ilayer][ifold]=(r_boresights[ilayer][ifold]- ray1->rfexit_eachboresight[0][ilayer][ifold]).Unit();
861  // cout << "ilayer, ifold, n_exit2bn are " << ilayer << "\t" << ifold << " ";
862  }
863  }
864  }
865 
866  // first pass at direction of vector from interaction to exit point
867  // just make the ray go radially outward away from center of earth.
868  // still for first guess
869  // should incorporate this into PickInteractionPoint
870  ray1->nrf_iceside[0] = interaction1->posnu.Unit();
871 
872  if (settings1->BORESIGHTS) {
873  // this is the same for all of the antennas too
874  for(int ilayer=0;ilayer<settings1->NLAYERS;ilayer++) { // loop over layers on the payload
875  for(int ifold=0;ifold<anita1->NRX_PHI[ilayer];ifold++) {
876 
877  ray1->nrf_iceside_eachboresight[0][ilayer][ifold]=interaction1->posnu.Unit();
878  } // end loop over fold
879  } // end loop over payload layers
880  } // end if boresights
881 
882 
883 
884 
885  double r_down = 2*(antarctica1->Surface(interaction1->posnu)-antarctica1->IceThickness(interaction1->posnu))-interaction1->posnu.Mag();
886  interaction1->posnu_down = r_down * interaction1->posnu.Unit();
887  //position of the mirror point of interaction
888 
889  //interaction1->posnu is downward interaction1->posnu.
890  // distance=interaction1->posnu.Distance(r_bn);
891 
892 
893  // depth of interaction
894  // gets distance between interaction and exit point, this time it's same as depth
895  // because our first guess at exit point is radially outward from interaction.
896  // negative means below surface
897  interaction1->altitude_int=-1*ray1->rfexit[0].Distance(interaction1->posnu);
898  interaction1->altitude_int_mirror=-1*ray1->rfexit[0].Distance(interaction1->posnu_down);//get depth of mirror point
899 
900 
901  interaction1->r_fromballoon[0]=r_bn.Distance(interaction1->posnu);
902 
903  //distance from the mirror point to the balloon because it is equal to the path that signals pass
904  interaction1->r_fromballoon[1]=r_bn.Distance(interaction1->posnu_down);
905 
906 
907  // std::cout << (interaction1->posnu) << std::endl;
908  if (ray1->n_exit2bn[0].Angle(interaction1->posnu) > PI/2 && !(WHICHPATH==3 || WHICHPATH==4))
909  beyondhorizon = 1;
910 
911 
912  return;
913 }//PickDownwardInteractionPoint
914 
915 
916 
918 
919  sslacpositions[0]="phi 4-5";
920  slacpositions[0]=Vector(0.3,179.7,223.8);
921 
922  sslacpositions[1]="phi 1, start location";
923  slacpositions[1]=Vector(3.1,158.8,222.3);
924 
925  sslacpositions[2]="phi 13, start location";
926  slacpositions[2]=Vector(3.5,158.4,226.2);
927 
928  sslacpositions[3]="phi 9, start location";
929  slacpositions[3]=Vector(8.9,158.2,225.6);
930 
931  sslacpositions[4]="phi 5, start location";
932  slacpositions[4]=Vector(6.0,157.2,219.6);
933 
934  sslacpositions[5]="phi 1, X=0, Y=2m";
935  slacpositions[5]=Vector(1.3,233.8,221.0);
936 
937  sslacpositions[6]="phi 13 X=0, Y=0";
938  slacpositions[6]=Vector(5.4,154.4,226.2);
939 
940  sslacpositions[7]="phi 13, X=3m, Y=0";
941  slacpositions[7]=Vector(107.3,150.5,226.7);
942 
943  sslacpositions[8]="phi 5, X=3m, Y=0";
944  slacpositions[8]=Vector(110.4,144.6,220.1);
945 
946  sslacpositions[9]="phi 1, left ant. at X=0";
947  slacpositions[9]=Vector(104.7,147.8,223.2);
948 
949  sslacpositions[10]="phi 1, Y=2m, left ant at X=0";
950  slacpositions[10]=Vector(104.8,232.4,220.8);
951 
952  sslacpositions[11]="phi 13, Y=2m, left ant at X=0";
953  slacpositions[11]=Vector(104.1,233.1,225.5);
954 
955  sslacpositions[12]="phi 1, Y=0, right ant at X=0";
956  slacpositions[12]=Vector(-102.5,155.8,222.5);
957 
958  sslacpositions[13]="phi 13, right ant at X=0";
959  slacpositions[13]=Vector(-101.6,157.0,230.4);
960 
961  sslacpositions[14]="phi 13, X=0, Y=-2m";
962  slacpositions[14]=Vector(1.7,81.3,230.6);
963 
964  sslacpositions[15]="phi 13, X=3m, Y=-2m";
965  slacpositions[15]=Vector(103.1,82.4,231.2);
966 
967  sslacpositions[16]="phi 3, X=0, Y=0";
968  slacpositions[16]=Vector(-0.5,156.1,225.8);
969 
970  sslacpositions[17]="phi 7, X=0, Y=0";
971  slacpositions[17]=Vector(3.3,157.3,226.7);
972 
973  sslacpositions[18]="phi 11, X=0, Y=0";
974  slacpositions[18]=Vector(2.2,159.2,230.0);
975 
976  sslacpositions[19]="phi 15, X=0, Y=0";
977  slacpositions[19]=Vector(-1.8,158.8,228.5);
978 
979  sslacpositions[20]="phi 13, X=0, Y=2m";
980  slacpositions[20]=Vector(-2.5,237.0,229.7);
981 
982  sslacpositions[21]="phi 13, X=-3m, Y=2m";
983  slacpositions[21]=Vector(-109.8,237.4,229.2);
984 
985  sslacpositions[22]="phi 13, X=-3m, Y=-2m";
986  slacpositions[22]=Vector(-101.8,88.7,231.4);
987 
988  sslacpositions[22]="phi 14, X=0m, Y=0m";
989  slacpositions[22]=Vector(-0.8,160.4,228.2);
990 
991  sslacpositions[23]="phi 2, X=0m, Y=0m";
992  slacpositions[23]=Vector(2.4,158.9,225.7);
993 
994  sslacpositions[24]="phi 6, X=0m, Y=0m";
995  slacpositions[24]=Vector(5.5,158.2,223.6);
996 
997  sslacpositions[25]="phi 10, X=0m, Y=0m";
998  slacpositions[25]=Vector(5.9,160.3,228.2);
999 
1000  sslacpositions[26]="phi 12, X=0m, Y=0m";
1001  slacpositions[26]=Vector(3.1,160.5,230.4);
1002 
1003  sslacpositions[27]="phi 8, X=0m, Y=0m";
1004  slacpositions[27]=Vector(6.7,159.7,226.7);
1005 
1006  sslacpositions[28]="phi 4, X=0m, Y=0m";
1007  slacpositions[28]=Vector(4.5,157.8,224.1);
1008 
1009  sslacpositions[29]="phi 16, X=0m, Y=0m";
1010  slacpositions[29]=Vector(1.4,159.4,227.3);
1011 
1012  sslacpositions[30]="phi 13, X=0m, Y=-6m";
1013  slacpositions[30]=Vector(3.5,21.1,231.1);
1014 
1015  // if you add any positions, be sure the change the number in the next line!!
1016  for (int i=0;i<=30;i++) {
1017 
1018  slacpositions[i]=Vector(slacpositions[i].GetX()*CMINCH/100.,
1019  slacpositions[i].GetY()*CMINCH/100.,
1020  slacpositions[i].GetZ()*CMINCH/100.);// inches to meters
1021  slacpositions[i].SetY(slacpositions[i].GetY()-BN_ALTITUDE-0.5584-anita1->LAYER_VPOSITION[2]+0.4); // subtract balloon altitude, add depth of beam relative to surface. Use 0.4 m for the height of an antenna.
1022 
1023  }
1024 
1025 }
1026 
1028 
1029  // this fills r_boresights with the position of the antenna boresights.
1030  for(int ilayer=0;ilayer<settings1->NLAYERS;ilayer++) {
1031  for(int ifold=0;ifold<anita1->NRX_PHI[ilayer];ifold++) {
1032 
1033  Vector n_boresight(1,0,0); // this will be a unit vector that points from the center axis of the payload to the boresight on each level of the payload (it will stay in the x-y plane)
1034 
1035  double phi;
1036  // rotate about z axis for phi
1037  if (settings1->CYLINDRICALSYMMETRY==1) {
1038  phi=(double)ifold/(double)anita1->NRX_PHI[ilayer]*2*PI + anita1->PHI_OFFSET[ilayer]+phi_spin;
1039  }
1040  else{
1041  phi=anita1->PHI_EACHLAYER[ilayer][ifold] + anita1->PHI_OFFSET[ilayer] +phi_spin;
1042  }
1043 
1044 
1045  n_boresight = n_boresight.RotateZ(phi);
1046 
1047  // start with a vector that points in the +z direction but with the same length as r_bn
1048  r_boresights[ilayer][ifold].SetX(0.); // this will be a unit vector that points from the center axis of the payload to the boresight on each level of the payload (it will stay in the x-y plane)
1049  r_boresights[ilayer][ifold].SetY(0.);
1050  r_boresights[ilayer][ifold].SetZ(r_bn.Mag());
1051 
1052  Vector zaxis(0.,0.,1.);
1053  Vector xaxis(1.,0.,0.);
1054  Vector yaxis(0.,1.,0.);
1055 
1056  // Add the positions of the antennas relative to the center of the payload
1057  r_boresights[ilayer][ifold]+=anita1->RRX[ilayer]*n_boresight
1058  + anita1->LAYER_VPOSITION[ilayer]*zaxis
1059  + anita1->LAYER_HPOSITION[ilayer]*cos(anita1->LAYER_PHIPOSITION[ilayer])*xaxis
1060  + anita1->LAYER_HPOSITION[ilayer]*sin(anita1->LAYER_PHIPOSITION[ilayer])*yaxis;
1061 
1062 
1063  // now rotate to balloon's position on the continent
1064  r_boresights[ilayer][ifold] = r_boresights[ilayer][ifold].ChangeCoord(n_north,-1.*n_east);
1065 
1066 
1067  }
1068  }
1069 }
1070 
1071 
1072 /*
1073  void Balloon::GetBoresights(Settings *settings1,Anita *anita1) {
1074 
1075  // this fills r_boresights with the position of the antenna boresights.
1076  for(int ilayer=0;ilayer<settings1->NLAYERS;ilayer++) {
1077  for(int ifold=0;ifold<anita1->NRX_PHI[ilayer];ifold++) {
1078 
1079  Vector n_boresight(1,0,0); // this will be a unit vector that points from the center axis of the payload to the boresight on each level of the payload (it will stay in the x-y plane)
1080 
1081  double phi;
1082  // rotate about z axis for phi
1083  if (settings1->CYLINDRICALSYMMETRY==1) {
1084  phi=(double)ifold/(double)anita1->NRX_PHI[ilayer]*2*PI + anita1->PHI_OFFSET[ilayer]+phi_spin;
1085  }
1086  else
1087  phi=anita1->PHI_EACHLAYER[ilayer][ifold] + anita1->PHI_OFFSET[ilayer]+phi_spin;
1088 
1089 
1090  n_boresight = n_boresight.RotateZ(phi);
1091 
1092  // start with a vector that points in the +z direction but with the same length as r_bn
1093  r_boresights[ilayer][ifold].SetX(0.); // this will be a unit vector that points from the center axis of the payload to the boresight on each level of the payload (it will stay in the x-y plane)
1094  r_boresights[ilayer][ifold].SetY(0.);
1095  r_boresights[ilayer][ifold].SetZ(r_bn.Mag());
1096 
1097  Vector zaxis(0.,0.,1.);
1098  Vector xaxis(1.,0.,0.);
1099  Vector yaxis(0.,1.,0.);
1100 
1101  // Add the positions of the antennas relative to the center of the payload
1102  r_boresights[ilayer][ifold]+=anita1->RRX[ilayer]*n_boresight
1103  + anita1->LAYER_VPOSITION[ilayer]*zaxis
1104  + anita1->LAYER_HPOSITION[ilayer]*cos(anita1->LAYER_PHIPOSITION[ilayer])*xaxis
1105  + anita1->LAYER_HPOSITION[ilayer]*sin(anita1->LAYER_PHIPOSITION[ilayer])*yaxis;
1106 
1107 
1108  // now rotate to balloon's position on the continent
1109  r_boresights[ilayer][ifold] = r_boresights[ilayer][ifold].ChangeCoord(n_north,-1.*n_east);
1110 
1111 
1112  }
1113  }
1114  }
1115 */
1116 void Balloon::GetBoresights(Settings *settings1,Anita *anita1) {
1117  Vector ant_pos;
1118  for(int ilayer=0;ilayer<settings1->NLAYERS;ilayer++) {
1119  for(int ifold=0;ifold<anita1->NRX_PHI[ilayer];ifold++) {
1120  ant_pos=anita1->ANTENNA_POSITION_START[0][ilayer][ifold];
1121  ant_pos=RotatePayload(ant_pos);
1122  r_boresights[ilayer][ifold] = ant_pos+r_bn;
1123  }
1124  }
1125 }
1126 
1128  int number_all_antennas = 0;
1129  Vector antenna_position;
1130 
1131 
1132  for (int ipol=0; ipol<2; ipol++){
1133  number_all_antennas=0;
1134  for (int ilayer = 0; ilayer < settings1->NLAYERS; ilayer++){
1135  for (int ifold = 0; ifold < anita1->NRX_PHI[ilayer]; ifold++){
1136  double phi = 0;
1137  if (settings1->WHICH==6 || settings1->WHICH==8 || settings1->WHICH == 9 || settings1->WHICH == 10){ //If payload is either
1138  antenna_position = anita1->ANTENNA_POSITION_START[ipol][ilayer][ifold];
1139  }
1140  else {
1141  if (settings1->CYLINDRICALSYMMETRY==1){ // for timing code
1142  // phi is 0 for antenna 0 (0-31) and antenna 16 (0-31)
1143  // antenna 1 (1-32) and antenna 18 (1-32)
1144  phi = (double) ifold / (double) anita1->NRX_PHI[ilayer] * 2 * PI + anita1->PHI_OFFSET[ilayer];
1145  }else{
1146  phi = anita1->PHI_EACHLAYER[ilayer][ifold] + anita1->PHI_OFFSET[ilayer];
1147  }
1148  antenna_position = Vector(anita1->RRX[ilayer]*cos(phi) + anita1->LAYER_HPOSITION[ilayer]*cos(anita1->LAYER_PHIPOSITION[ilayer]), anita1->RRX[ilayer]*sin(phi)+anita1->LAYER_HPOSITION[ilayer]*sin(anita1->LAYER_PHIPOSITION[ilayer]), anita1->LAYER_VPOSITION[ilayer]);
1149 
1150  }//else
1151 
1152  //cout<<"antenna_position start for "<<number_all_antennas<<" is "<<antenna_position<<"\n";
1153  antenna_position=RotatePayload(antenna_position);
1154 
1155  anita1->antenna_positions[ipol][number_all_antennas] = antenna_position;
1156  //cout<<"antenna_position for "<<number_all_antennas<<" is "<<antenna_position<<"\n";
1157  number_all_antennas++;
1158  }
1159  }
1160  }
1161  return;
1162 }
1163 
1165  if(WHICHPATH==7){
1166  // ANITA-2 analysis fitted fixed pitch and roll
1167  pitch=-0.29;
1168  roll=0.89;
1169  } else if(WHICHPATH==8){
1170  // ANITA-3 analysis forced pitch and roll to be 0
1171  pitch=roll=0;
1172  }
1173 
1174  Vector BalloonPos;
1175 
1176  BalloonPos=r_bn;
1177  double BalloonTheta = BalloonPos.Theta();
1178  double BalloonPhi = BalloonPos.Phi();
1179 
1180  if(BalloonPhi > PI){
1181  BalloonPhi =BalloonPhi-TWOPI;
1182  }
1183 
1184  Vector ant_pos = ant_pos_pre;
1185 
1186  Vector zaxis(0.,0.,-1.);
1187  Vector xaxis(1.,0.,0.);//roll axis
1188  Vector yaxis(0.,-1.,0.);//pitch axis for positive rotation to the clockwise of roll
1189 
1190  Vector northaxis(1,0,0);
1191  Vector eastaxis(0,-1,0);
1192  //rotate to correct heading, roll and pitch
1193 
1194  ant_pos=ant_pos.Rotate(heading*RADDEG,zaxis);
1195  xaxis=xaxis.Rotate(heading*RADDEG,zaxis);
1196  yaxis=yaxis.Rotate(heading*RADDEG,zaxis);
1197 
1198  ant_pos=ant_pos.Rotate(pitch*RADDEG,yaxis);
1199  xaxis=xaxis.Rotate(pitch*RADDEG,yaxis);
1200 
1201  ant_pos=ant_pos.Rotate(roll*RADDEG,xaxis);//roll and pitch
1202 
1204  // BalloonPhi =latitude*RADDEG;
1205  ant_pos=ant_pos.RotateY(BalloonTheta);
1206  northaxis=northaxis.RotateY(BalloonTheta);
1207  eastaxis=eastaxis.RotateY(BalloonTheta);
1208 
1209 
1210  ant_pos=ant_pos.RotateZ(BalloonPhi);
1211  northaxis = northaxis.RotateZ(BalloonPhi);
1212  eastaxis = eastaxis.RotateZ(BalloonPhi);
1213 
1214  // cout<<"northaxis is "<<northaxis<<" n_north is "<<n_north<<"\n";
1215  // cout<<"eastaxis is "<<eastaxis<<" n_east is "<<n_east<<"\n";
1216  this->x_axis_rot = xaxis;
1217  this->y_axis_rot = yaxis;
1218  this->z_axis_rot = zaxis;
1219  return ant_pos;
1220 }
1221 Vector Balloon::unRotatePayload(Vector ant_pos_pre) {//rotate back to Payload Centric coordinates
1222  if(WHICHPATH==7){
1223  pitch=-0.29; //ANITA-2 settings in ANALYSIS
1224  roll=0.89; //ANITA-2 settings in ANALYSIS
1225  } else if(WHICHPATH==8){
1226  // ANITA-3 analysis forced pitch and roll to be 0
1227  pitch=roll=0;
1228  }
1229 
1230 
1231  Vector BalloonPos;
1232 
1233  BalloonPos=r_bn;
1234  double BalloonTheta = BalloonPos.Theta();
1235  double BalloonPhi = BalloonPos.Phi();
1236 
1237  //cout<<"BalloonTheta is "<<BalloonTheta<<" phi is "<<BalloonPhi<<"\n";
1238  if(BalloonPhi > PI){
1239  BalloonPhi =BalloonPhi-TWOPI;
1240  }
1241 
1242 
1243  Vector ant_pos = ant_pos_pre;
1244 
1245 
1246  //rotate to correct heading, roll and pitch
1247 
1248 
1249  ant_pos=ant_pos.RotateZ(-1*BalloonPhi);
1250 
1251  ant_pos=ant_pos.RotateY(-1*BalloonTheta);
1252 
1253  ant_pos=ant_pos.Rotate(-1*roll*RADDEG,x_axis_rot);//roll and pitch
1254 
1255  ant_pos=ant_pos.Rotate(-1*pitch*RADDEG,y_axis_rot);
1256 
1257  ant_pos=ant_pos.Rotate(-1*heading*RADDEG,z_axis_rot);
1258  return ant_pos;
1259 }
1260 
1261 
unsigned int realTime_flightdata_temp
realtime from the flight data file
Definition: balloon.hh:50
double realtime_bn_anitalite[100000]
same for real life time
Definition: balloon.hh:87
int WHICHPATH
0=fixed balloon position,1=randomized,2=ANITA-lite GPS data,3=banana plot
Definition: balloon.hh:57
unsigned short surfTrigBandMask[9][2]
Ryan&#39;s 16 bit masks for 9 surfs. 2x16 bit masks gives 32 channels per surf.
Definition: balloon.hh:60
int igps
which balloon position do we use out of the 25000 anitalite GPS positions.
Definition: balloon.hh:41
void ReadAnitaliteFlight()
This function reads in the ANITA LITE flight.
Definition: balloon.cc:112
Position r_bn
position of balloon
Definition: balloon.hh:66
static const int MAX_POSITIONS
for the slac beam test
Definition: balloon.hh:44
double r_fromballoon[2]
distance from interaction to balloon for each ray
Definition: Primaries.h:251
double phi_bn
theta,phi of balloon wrt south pole
Definition: balloon.hh:65
Vector RotatePayload(Vector ant_pos)
This function rotates the payload.
Definition: balloon.cc:1164
static constexpr double phi_nu_banana
Location in phi.
Definition: Primaries.h:163
double Distance(const Position &second) const
Returns chord distance (direct distance between two vectors)
Definition: position.cc:37
Position nu_banana_surface
The location of the surface above the forced neutrino interaction point.
Definition: Primaries.h:240
double heading_bn_anitalite[100000]
same for heading of the balloon
Definition: balloon.hh:86
double LAYER_VPOSITION[Anita::NLAYERS_MAX]
position of layers in z relative to vertical center of the payload
Definition: anita.hh:81
double MAXHORIZON
pick the interaction within this distance from the balloon so that it is within the horizon ...
Definition: balloon.hh:78
double THETA_ZENITH[NLAYERS_MAX]
how the antenna is tilted in theta (in radians with 0=up)
Definition: anita.hh:75
int Getibnposition()
This function gets ith balloon position.
Definition: balloon.cc:303
void PickBalloonPosition(Vector straightup, IceModel *antarctica, Settings *settings1, Anita *anita1)
This function picks the balloon position.
Definition: balloon.cc:317
void AdjustSlacBalloonPosition(int inu)
This function adjusts the slac balloon position.
Definition: balloon.cc:627
void CenterPayload(double &hitangle_e)
This function centers the payload.
Definition: balloon.cc:639
double horizcoord_bn
x component of balloon position
Definition: balloon.hh:67
int REDUCEBALLOONPOSITIONS
only take every 100th entry in the flight data file
Definition: balloon.hh:56
const char * ICEMC_SRC_DIR()
double altitude_bn_anitalite[100000]
same for altitude
Definition: balloon.hh:85
double dtryingdirection
weighting factor: how many equivalent tries each neutrino counts for after having reduced angular pha...
Definition: Primaries.h:243
int NPOINTS_MIN
min and max index for gps positions we want to include in the simulation (to exclude launch and fall)...
Definition: balloon.hh:81
double BN_LATITUDE
balloon latitude for fixed balloon location
Definition: balloon.hh:89
void PickDownwardInteractionPoint(Interaction *interaction1, Anita *anita1, Settings *settings1, IceModel *antarctica1, Ray *ray1, int &beyondhorizon, double len_int_km2, Vector *force_dir=0)
This function picks downward interaction point.
Definition: balloon.cc:762
Position r_bn_shadow
position of the balloon projected on earth surface - point just below balloon at surface of the earth...
Definition: balloon.hh:77
double MINALTITUDE
minimum altitude balloon needs to be before we consider it a good event to read from the flight data ...
Definition: balloon.hh:54
Reads in and stores input settings for the run.
Definition: Settings.h:37
static constexpr double banana_observation_distance
How far from the surface above the interaction are we when we measure the voltages? (meters) Note: Should be at least 100000 for best results.
Definition: Primaries.h:165
void setr_bn(double latitude, double longitude)
This function sets r of the balloon.
Definition: balloon.cc:742
int NPOINTS
number of GPS positions we&#39;re picking from.
Definition: balloon.hh:80
double BN_ALTITUDE
pick balloon altitude
Definition: balloon.hh:59
double BN_LONGITUDE
balloon longitude for fixed balloon location
Definition: balloon.hh:88
double PHI_EACHLAYER[NLAYERS_MAX][NPHI_MAX]
phi of the center of each antenna on each layer
Definition: anita.hh:70
Vector n_bn
normalized r_bn
Definition: balloon.hh:73
double PHI_OFFSET[NLAYERS_MAX]
antenna offset in phi for each layer (radians)
Definition: anita.hh:74
float powerthresh[9][32]
power threshold in Watts
Definition: balloon.hh:61
void InitializeBalloon()
This function initializes the balloon or the specific flight.
Definition: balloon.cc:188
This class is a 3-vector that represents a position on the Earth&#39;s surface.
Definition: position.hh:26
int RANDOMIZE_BN_ORIENTATION
0=fixed balloon orientation,1=randomized
Definition: balloon.hh:58
Vector ANTENNA_POSITION_START[2][NLAYERS_MAX][NPHI_MAX]
antenna positions from Kurt&#39;s measurements
Definition: anita.hh:62
Stores everything about a particular neutrino interaction. Interaction.
Definition: Primaries.h:135
void GetAntennaOrientation(Settings *settings1, Anita *anita1, int ilayer, int ifold, Vector &n_eplane, Vector &n_hplane, Vector &n_normal)
This function gets the antenna orientation.
Definition: balloon.cc:649
double RRX[Anita::NLAYERS_MAX]
radius that the antenna sits from the axis of the payload (feedpoint)
Definition: anita.hh:87
Vector n_north
north, as seen from the balloon position
Definition: balloon.hh:75
double longitude_bn_anitalite[100000]
same for longitude
Definition: balloon.hh:84
double GetBalloonSpin(double heading)
This function gets the spin of the balloon whatever that means.
Definition: balloon.cc:287
double altitude_int_mirror
depth of the mirror point of interaction.
Definition: Primaries.h:249
double phi_spin
orientation of the balloon
Definition: balloon.hh:79
void SetDefaultBalloonPosition(IceModel *antarctica1)
This function sets the default balloon position.
Definition: balloon.cc:75
Contains everything about positions within payload and signals it sees for each event, in both the trigger and signal paths.
Definition: anita.hh:32
void calculate_antenna_positions(Settings *settings1, Anita *anita1)
This function calculates antenna positions.
Definition: balloon.cc:1127
Vector unRotatePayload(Vector ant_pos)
This function UN-rotates the payload.
Definition: balloon.cc:1221
double surface_under_balloon
distance between center of the earth and the surface of earth under balloon
Definition: balloon.hh:76
static const int NLAYERS_MAX
max number of layers (in smex design, it&#39;s 4)
Definition: anita.hh:59
double altitude_int
depth of interaction
Definition: Primaries.h:248
Vector antenna_positions[2][NLAYERS_MAX *NPHI_MAX]
these are the antenna positions in space in a coordinate system where x=north and y=west and the orig...
Definition: anita.hh:67
double vertcoord_bn
y component of balloon position
Definition: balloon.hh:68
double banana_volts
Total voltage measured at a spot on the sky.
Definition: Primaries.h:216
double latitude_bn_anitalite[100000]
latitude at times along flightpath, equally distributed among gps data. This is filled with anita or ...
Definition: balloon.hh:83
int iceinteraction
whether or not there is an interaction in the ice
Definition: Primaries.h:256
void setObservationLocation(Interaction *interaction1, int inu, IceModel *antarctic, Settings *settings1)
This function sets the observation location.
Definition: balloon.cc:46
void GetEcompHcompEvector(Settings *settings1, Vector n_eplane, Vector n_hplane, const Vector n_pol, double &e_component, double &h_component, double &n_component)
This function gets the e-component, h-component and e-vector.
Definition: balloon.cc:704
Vector n_east
east, as seen from the balloon position
Definition: balloon.hh:74
static constexpr double theta_nu_banana
Location of banana neutrino in theta.
Definition: Primaries.h:166
This class represents a three-vector. Operators are overloaded to provide for the familiar operations...
Definition: vector.hh:27
Position nu_banana
The forced interaction point of the neutrino for the banana plots.
Definition: Primaries.h:239
double ANTENNA_DOWN[NLAYERS_MAX][NPHI_MAX]
down angles of antennas from Kurt&#39;s measurements
Definition: anita.hh:63
static const int NPHI_MAX
max number of antennas around in phi (in smex, 16)
Definition: anita.hh:61
void GetHitAngles(double e_component_kvector, double h_component_kvector, double n_component_kvector, double &hitangle_e, double &hitangle_h)
This function gets the hit angles.
Definition: balloon.cc:726
int igps_previous
which entry from the flight data file the previous event was so we can just take the next one...
Definition: balloon.hh:55
Vector banana_obs
Vector from the neutrino interaction to the observation point.
Definition: Primaries.h:173
float meanp[9][32]
mean power in Watts
Definition: balloon.hh:62
double dtryingposition
weighting factor: how many equivalent tries each neutrino counts for after having reduced possible in...
Definition: balloon.hh:43
double LAYER_PHIPOSITION[Anita::NLAYERS_MAX]
phi corresponding to the position of each "layer" on the "payload"
Definition: anita.hh:86
Ray tracing.
Definition: ray.hh:20
double Lon() const
Returns longitude.
Definition: position.cc:51
void GetEcompHcompkvector(Vector n_eplane, Vector n_hplane, Vector n_normal, const Vector n_exit2bn, double &e_component_kvector, double &h_component_kvector, double &n_component_kvector)
This function gets the e-component, h-component and k-vector.
Definition: balloon.cc:690
int NRX_PHI[NLAYERS_MAX]
number of antennas around in each layer. (radians)
Definition: anita.hh:69
void GetBoresights(Settings *settings1, Anita *anita1, Position r_boresights[Anita::NLAYERS_MAX][Anita::NPHI_MAX])
This function gets the boresights.
double banana_weight
Weight measurement locations to account for phase space.
Definition: Primaries.h:214
Position r_boresights[Anita::NLAYERS_MAX][Anita::NPHI_MAX]
position of antenna boresights
Definition: balloon.hh:69
Ice thicknesses and water depth.
Definition: icemodel.hh:103
double d_effective_area
In unbaised mode, projection of surface onto nnu.
Definition: Primaries.h:246
unsigned int realTime_flightdata
realtime from the flight data file
Definition: balloon.hh:51
void GetSlacPositions(Anita *anita1)
This function gets the slac balloon positions.
Definition: balloon.cc:917
double LAYER_HPOSITION[Anita::NLAYERS_MAX]
distance in horizontal plane between center axis of the "payload" and each "layer".
Definition: anita.hh:85