anita.cc
1 #include <array>
2 #include "vector.hh"
3 #include "position.hh"
4 
5 #include "Constants.h"
6 #include "Settings.h"
7 #include "earthmodel.hh"
8 #include "icemodel.hh"
9 #include "TF1.h"
10 
11 #include "rx.hpp"
12 #include "anita.hh"
13 
14 #include "ChanTrigger.h"
15 #include "balloon.hh"
16 #include <iostream>
17 #include <cmath>
18 #include <vector>
19 
20 #include <string>
21 
22 #include "Tools.h"
23 
24 #include "TTree.h"
25 #include "TH1F.h"
26 #include "TH2F.h"
27 #include "TH1.h"
28 #include "TF1.h"
29 #include "TFile.h"
30 #include "TGraph.h"
31 #include "TCanvas.h"
32 #include "TStyle.h"
33 #include "TLegend.h"
34 
35 #include "TMath.h"
36 
37 #include <sys/stat.h>
38 
39 #include "EnvironmentVariable.h"
40 
41 #ifdef ANITA_UTIL_EXISTS
42 #include "FFTtools.h"
43 #include "AnitaEventCalibrator.h"
44 #include "AnitaGeomTool.h"
45 #include "AnitaConventions.h"
46 #endif
47 
48 #include "icemc_random.h"
49 const std::string ICEMC_SRC_DIR=EnvironmentVariable::ICEMC_SRC_DIR();
50 const std::string ICEMC_DATA_DIR=ICEMC_SRC_DIR+"/data/";
51 
52 
53 using std::cout;
54 using std::cin;
55 using std::endl;
56 using std::vector;
57 
58 Anita::Anita() {
59 
60  stemp = "";
61 
62  for (int irx=0;irx<Anita::NLAYERS_MAX*Anita::NPHI_MAX;irx++) {
63  arrival_times[0][irx]=arrival_times[1][irx]=0.;
64  }
65  NCH_PASS=4;
66  rx_minarrivaltime=0.;
67 
68  Tools::Zero(VNOISE_ANITALITE,16);
69  INCLINE_TOPTHREE = 10.; // cant angle of top three layers of antennas
70  INCLINE_NADIR = 10.; // cant angle of nadir (bottom) layer of antennas
71  SIGMA_THETA=0.5*RADDEG; // resolution on the polar angle of the signal
72 
73  FREQ_LOW=0.;//200.E6;
74  FREQ_HIGH=1300.E6; //1200.E6;
75 
76  antennatosurf[0]=2;
77  antennatosurf[1]=4;
78  antennatosurf[2]=6;
79  antennatosurf[3]=8;
80  antennatosurf[4]=2;
81  antennatosurf[5]=4;
82  antennatosurf[6]=6;
83  antennatosurf[7]=8;
84  // layer 1
85  antennatosurf[8]=1;
86  antennatosurf[9]=3;
87  antennatosurf[10]=5;
88  antennatosurf[11]=7;
89  antennatosurf[12]=1;
90  antennatosurf[13]=3;
91  antennatosurf[14]=5;
92  antennatosurf[15]=7;
93  // layer 2
94  antennatosurf[16]=1;
95  antennatosurf[17]=2;
96  antennatosurf[18]=3;
97  antennatosurf[19]=4;
98  antennatosurf[20]=5;
99  antennatosurf[21]=6;
100  antennatosurf[22]=7;
101  antennatosurf[23]=8;
102  antennatosurf[24]=1;
103  antennatosurf[25]=2;
104  antennatosurf[26]=3;
105  antennatosurf[27]=4;
106  antennatosurf[28]=5;
107  antennatosurf[29]=6;
108  antennatosurf[30]=7;
109  antennatosurf[31]=8; // layer 3
110 
111  maxthreshold=0.;
112  Tools::Zero(bwslice_thresholds,5); // thresholds for each band -- this is just an initialization- this is set in the input file
113  for (int i=0;i<5;i++) {
114  bwslice_allowed[i]=1; // these bands are allowed to contribute to the trigger sum -- this is set in the input file
115  }
116  bwslice_required[0]=0;
117  bwslice_required[1]=0;
118  bwslice_required[2]=0;
119  bwslice_required[3]=0;
120  bwslice_required[4]=1; // these bands are required to be among the channels that pass -- this is set in the input file
121  pol_allowed[0]=1;// which polarisations are allowed to have channels that fire (V,H)
122  pol_allowed[1]=1;// which polarisations are allowed to have channels that fire (V,H)
123  pol_required[0]=1;// which polarisations are required to have channels that fire (V,H)
124  pol_required[1]=0;// which polarisations are required to have channels that fire (V,H)
125 
126 
127  bwslice_center[0]=265.e6;
128  bwslice_center[1]=435.e6;
129  bwslice_center[2]=650.e6;
130  bwslice_center[3]=980.e6;
131  bwslice_center[4]=682.5E6; // center frequencies
132 
133  bwslice_width[0]=130.e6;
134  bwslice_width[1]=160.e6;
135  bwslice_width[2]=250.e6;
136  bwslice_width[3]=370.e6;
137  bwslice_width[4]=965.E6; // 3 dB bandwidths, without overlap
138 
139 
140 
141  for (int i=0;i<4;i++) {
142  bwslice_min[i]=bwslice_center[i]-bwslice_width[i]/2.;
143  bwslice_max[i]=bwslice_center[i]+bwslice_width[i]/2.;
144  }
145 
146  for (int i = 0; i < 5; i++)
147  {
148  iminbin[i] = 0;
149  imaxbin[i] = NFOUR/2;
150  }
151 
152  bwslice_min[4]= bwslice_center[0]-bwslice_width[0]/2.; //minimum of each bandwidth slice
153  bwslice_max[4]=bwslice_center[3]+bwslice_width[3]/2.; //minimum of each bandwidth slice
154 
155  bwmin=0.; // minimum width of any allowed bandwidth slice
156 
157 
158  // If outputs dir doesn't already exist, create it
159  const char* outputdir;
160  outputdir = "outputs";
161  struct stat sb;
162 
163  if (stat(outputdir, &sb) == 0 && S_ISDIR(sb.st_mode))
164  {
165  // dir already exists don't overwrite
166  }
167  else
168  {
169  mkdir(outputdir,S_IRWXU);
170  }
171 
172 
173 }
174 
175 Anita::~Anita(){
176  coherent_datafile->cd();
177 
178  coherent_waveform_sum_tree->Write();
179  coherent_datafile->Write();
180 
181  coherent_waveform_sum_tree->Delete();
182  coherent_datafile->Close();
183  coherent_datafile->Delete();
184 
185 
186  return;
187 }
188 
189 int Anita::Match(int ilayer,int ifold,int rx_minarrivaltime) {
190 
191  if (ilayer==GetLayer(rx_minarrivaltime) && ifold==GetIfold(rx_minarrivaltime))
192  return 1;
193  else
194  return 0;
195 
196 }
197 int Anita::GetRx(int ilayer, int ifold) { // get antenna number based on which layer and position it is
198 
199  int irx=0;
200  for (int i=0;i<ilayer;i++) {
201  irx+=NRX_PHI[i];
202  }
203  irx+=ifold;
204  return irx;
205 
206 }
207 
208 int Anita::GetRxTriggerNumbering(int ilayer, int ifold) { // get antenna number based on which layer and position it is
209  // make the top trigger layer count 1-16 left to right
210  if (ilayer==0)
211  //cout << "ilayer, ifold, getrx are " << ilayer << "\t" << ifold << "\t" << 2*ifold+ilayer << "\n";
212  return 2*ifold;
213  else if(ilayer==1) {
214  return 2*ifold+1;
215  }
216  else {
217  //cout << "ilayer, ifold, getrx are " << ilayer << "\t" << ifold << "\t" << GetRx(ilayer,ifold) << "\n";
218  return GetRx(ilayer,ifold);
219  }
220 }
221 
222 void Anita::SetNoise(Settings *settings1,Balloon *bn1,IceModel *antarctica) {
223 
224  // these should only be used for the frequency domain trigger.
225  if (settings1->WHICH==2 || settings1->WHICH==6) { //this is for anita 1
226  for (int il=0;il<NLAYERS_MAX;il++) {
227  bwslice_vnoise[il][0]=5.5125E-6;
228  bwslice_vnoise[il][1]=6.1157E-6;
229  bwslice_vnoise[il][2]=7.64446E-6;
230  bwslice_vnoise[il][3]=9.29989E-6;
231  bwslice_vnoise[il][4]=0.;
232  for (int i=0;i<4;i++) {
233  bwslice_vnoise[il][4]+=bwslice_vnoise[il][i]*bwslice_vnoise[il][i];
234  }
235  bwslice_vnoise[il][4]=sqrt(bwslice_vnoise[il][4]);
236  }
237  }
238  else { // if not anita 1
239  for (int il=0;il<NLAYERS_MAX;il++) {
240  for (int ibw=0;ibw<5;ibw++) {
241  bwslice_vnoise[il][ibw]=ChanTrigger::GetNoise(settings1,bn1->altitude_bn,antarctica->SurfaceAboveGeoid(bn1->phi_bn,bn1->theta_bn),THETA_ZENITH[il],bwslice_max[ibw]-bwslice_min[ibw],0.);
242  }
243  }
244  }
245 
246 
247 
248 }
249 void Anita::Initialize(Settings *settings1,ofstream &foutput,int thisInu, TString outputdir)
250 {
251 
252 
253  tuffIndex=0; // keith edits
254  count_getnoisewaveforms=0;
255  rms_lab[0]=rms_lab[1]=0.;
256  rms_rfcm[0]=rms_rfcm[1]=0.;
257 
258  NBANDS=4; // subbands (not counting full band)
259  inu=thisInu;
260 
261  PERCENTBW=10; // subbands (not counting full band)
262 
263  TIMESTEP=(1./2.6)*1.E-9; // time step between samples
264 
265  USEPHASES=0;
266  ntuffs=1;
267  if (settings1->WHICH==10) ntuffs=7;
268 
269  for (int i=0;i<HALFNFOUR;i++) fTimes[i] = i * TIMESTEP * 1.0E9;
270 
271  for (int i=0;i<NFREQ;i++) {
272  freq[i]=FREQ_LOW+(FREQ_HIGH-FREQ_LOW)*(double)i/(double)NFREQ; // freq. of each bin.
273  avgfreq_rfcm[i]=0.;
274  avgfreq_rfcm_lab[i]=0.;
275  } //for
276 
277  initializeFixedPowerThresholds(foutput);
278 
279  additionalDt=0;
280  if (settings1->WHICH==10){
281  // powerthreshold[4] /= TMath::Sqrt(2.);
282  powerthreshold[4] = -3.1;
283  additionalDt=30.e-9;
284  }
285  if (settings1->TRIGGERSCHEME==5)
286  l1window=3.75E-9;
287  else
288  l1window=11.19E-9; // l1 coincidence window
289 
290  minsignalstrength=0.1;
291 
292  impedence=50.;
293  phase=90.; // phase for positive frequencies
294  // assuming v(t) is real, then phase(neg)=-phase(pos)
295  INTEGRATIONTIME=3.5E-9; // integration time of trigger diode
296 
297  DEADTIME=10.E-9; // dead time after a trigger
298  energythreshold=3.; // power threshold
299 
300 
301  // for ANITA 3 trigger
302  TRIG_TIMESTEP=3.75E-9;
303  N_STEPS_PHI = 100;
304  N_STEPS_THETA = 100;
305  MIN_PHI_HYPOTHESIS=-22.5;
306  MAX_PHI_HYPOTHESIS=22.5;
307  MIN_THETA_HYPOTHESIS=-50.;
308  MAX_THETA_HYPOTHESIS=20.;
309  //MIN_THETA_HYPOTHESIS=-55.;
310  //MAX_THETA_HYPOTHESIS=20.;
311 
312  double freqstep=1./(double)(NFOUR/2)/TIMESTEP;
313  // double freqstep_long=1./(double)(NFOUR)/TIMESTEP; // freqstep_long is actually shorter so that time domain waveform is longer
314 
315  for (int i=0;i<HALFNFOUR;i++) {
316  freq_forfft[2*i]=(double)i*freqstep;
317  freq_forfft[2*i+1]=(double)i*freqstep;
318 
319  if (i<HALFNFOUR/2) freq_forplotting[i]=freq_forfft[2*i];
320 
321  }
322 
323 
324  readVariableThresholds(settings1);
325 
326  phiTrigMask=0;
327  phiTrigMaskH=0;
328  l1TrigMask=0;
329  l1TrigMaskH=0;
330 
331 
332  readAmplification();
333 
334  // get lab attenuation data
335  getLabAttn(NPOINTS_LAB,freqlab,labattn);
336 
337 
338  getDiodeDataAndAttenuation(settings1, outputdir);
339 
340  if (settings1->PULSER==1) {
341  getPulserData();
342  }
343 
344  // for antenna gains
345  reference_angle[0]=0.;
346  reference_angle[1]=5.;
347  reference_angle[2]=10.;
348  reference_angle[3]=20.;
349  reference_angle[4]=30.;
350  reference_angle[5]=45.;
351  reference_angle[6]=90.; // reference angles for finding gains of antennas
352 
353 
354  THERMALNOISE_FACTOR=settings1->THERMALNOISE_FACTOR;
355  for (int j=0;j<settings1->NLAYERS;j++) {
356  // noise depends on cant angle of antenna
357  // // VNOISE[j]=ChanTrigger::GetNoise(altitude_bn,surface_under_balloon,THETA_ZENITH[j],BW_SEAVEYS,0.);
358  VNOISE[j]=1.52889E-5; // this comes from V^2/R=kT*bw -> V=sqrt(kT*bw*R)
359  VNOISE[j]*=THERMALNOISE_FACTOR;
360  }//for
361 
362 #ifdef ANITA_UTIL_EXISTS
363  if (settings1->NOISEFROMFLIGHTDIGITIZER || settings1->NOISEFROMFLIGHTTRIGGER){
364  readNoiseFromFlight(settings1);
365  }
366  if (settings1->APPLYIMPULSERESPONSEDIGITIZER){
367  readImpulseResponseDigitizer(settings1);
368  if(settings1->TUFFSTATUS>0){
369  readTuffResponseDigitizer(settings1);
370  readTuffResponseTrigger(settings1);
371  }
372  }
373  if (settings1->APPLYIMPULSERESPONSETRIGGER){
374  readImpulseResponseTrigger(settings1);
375  }
376 
377  // ANITA-4 uses Rayleigh distributions from ANITA-3 to generate thermal noise
378  // Some channels weren't great for ANITA-3 but were ok in ANITA-4
379  if (settings1->WHICH==10){
380 
381  double denom, trig, dig;
382 
383  // ANITA-3 channel 4TV was broken and channel 5TH had the alfa filter
384  // For ANITA-4 the Rayleigh distributions of those channels are taken from channels nearby
385  RayleighFits[0][3] = (TGraph*)RayleighFits[0][2]->Clone();
386  RayleighFits[1][4] = (TGraph*)RayleighFits[1][3]->Clone();
387  // 11MH 14BH 11MV 12MV 0BV show weird high/low noise for ANITA-4
388  RayleighFits[1][27] = (TGraph*)RayleighFits[1][26]->Clone();
389  RayleighFits[1][46] = (TGraph*)RayleighFits[1][47]->Clone();
390  RayleighFits[0][27] = (TGraph*)RayleighFits[0][26]->Clone();
391  RayleighFits[0][28] = (TGraph*)RayleighFits[0][29]->Clone();
392  RayleighFits[0][32] = (TGraph*)RayleighFits[0][33]->Clone();
393 
394  RayleighFits[1][9] = (TGraph*)RayleighFits[1][5]->Clone();
395  RayleighFits[1][42] = (TGraph*)RayleighFits[1][6]->Clone();
396 
397  for (int ifreq=0; ifreq<numFreqs; ifreq++){
398  fSignalChainResponseA3DigitizerFreqDomain[0][0][3][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[0][0][2][ifreq];
399  fSignalChainResponseA3DigitizerFreqDomain[1][0][4][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[1][0][3][ifreq];
400 
401  fSignalChainResponseA3DigitizerFreqDomain[1][1][11][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[1][1][10][ifreq];
402  fSignalChainResponseA3DigitizerFreqDomain[1][2][14][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[1][2][15][ifreq];
403  fSignalChainResponseA3DigitizerFreqDomain[0][1][11][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[0][1][10][ifreq];
404  fSignalChainResponseA3DigitizerFreqDomain[0][1][12][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[0][1][13][ifreq];
405  fSignalChainResponseA3DigitizerFreqDomain[0][2][0][ifreq] =fSignalChainResponseA3DigitizerFreqDomain[0][2][1][ifreq];
406 
407  fSignalChainResponseA3DigitizerFreqDomain[1][0][9][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[1][0][5][ifreq];
408  fSignalChainResponseA3DigitizerFreqDomain[1][2][10][ifreq]=fSignalChainResponseA3DigitizerFreqDomain[1][0][6][ifreq];
409 
410  }
411 
412  }
413 
414  calculateImpulseResponsesRatios(settings1);
415 
416 
417  if (settings1->TRIGGEREFFSCAN){
418  readTriggerEfficiencyScanPulser(settings1);
419  }
420 
421 
422 
423 
424 #endif
425 
426  setDiodeRMS(settings1, outputdir);
427 
428 
429  // Setting up output files
430 
431  string stemp=string(outputdir.Data())+"/signals.root";
432  fsignals=new TFile(stemp.c_str(),"RECREATE");
433  tsignals=new TTree("tsignals","tsignals");
434 
435  stemp=string(outputdir.Data())+"/data.root";
436  fdata=new TFile(stemp.c_str(),"RECREATE");
437  tdata=new TTree("tdata","tdata");
438 
439 
440  tsignals->Branch("signal_vpol_inanita",&signal_vpol_inanita,"signal_vpol_inanita[5][512]/D");
441  tsignals->Branch("timedomainnoise_rfcm_banding",&timedomainnoise_rfcm_banding,"timedomainnoise_rfcm_banding[2][5][512]/D");
442  tsignals->Branch("total_vpol_inanita",&total_vpol_inanita,"total_vpol_inanita[5][512]/D");
443  tsignals->Branch("total_diodeinput_1_inanita",&total_diodeinput_1_inanita,"total_diodeinput_1_inanita[5][512]/D"); // this is the waveform that is input to the tunnel diode in the first (LCP or vertical) polarization
444  tsignals->Branch("total_diodeinput_2_inanita",&total_diodeinput_2_inanita,"total_diodeinput_2_inanita[5][512]/D"); // this is the waveform that is input to the tunnel diode in the first (RCP or horizontal) polarization
445  tsignals->Branch("timedomain_output_corrected_forplotting",&timedomain_output_corrected_forplotting,"timedomain_output_1_corrected_forplotting[2][6][512]/D");
446  tsignals->Branch("timedomain_output_inanita",&timedomain_output_inanita,"timedomain_output_inanita[2][5][512]/D");
447 
448 
449  tsignals->Branch("peak_rx_rfcm_lab",&peak_rx_rfcm_lab,"peak_rx_rfcm_lab[2]/D");
450  tsignals->Branch("inu",&inu,"inu/I");
451  tsignals->Branch("dangle",&dangle_inanita,"dangle/D");
452  tsignals->Branch("emfrac",&emfrac_inanita,"emfrac/D");
453  tsignals->Branch("hadfrac",&hadfrac_inanita,"hadfrac/D");
454  tsignals->Branch("ston",&ston,"ston[5]/D");
455 
456  tsignals->Branch("peak", &peak_v_banding_rfcm, "peak_v_banding_rfcm[2][5]/D" );
457  tsignals->Branch("peak_rx", &peak_rx_signalonly, "peak_rx[2]/D" );
458  tsignals->Branch("peak_rx_rfcm", &peak_rx_rfcm, "peak_rx_rfcm[2]/D" );
459  tsignals->Branch("peak_rx_rfcm_signalonly", &peak_rx_rfcm_signalonly, "peak_rx_rfcm_signalonly[2]/D" );
460  tsignals->Branch("peak_rx_rfcm_lab", &peak_rx_rfcm_lab, "peak_rx_rfcm_lab[2]/D" );
461  tsignals->Branch("bwslice_vrms",&bwslice_vrms,"bwslice_vrms[5]/D");
462  tsignals->Branch("iminbin",&iminbin,"iminbin[5]/I");
463  tsignals->Branch("imaxbin",&imaxbin,"imaxbin[5]/I");
464  tsignals->Branch("maxbin_fortotal",&maxbin_fortotal,"maxbin_fortotal[5]/I");
465  tsignals->Branch("channels_passing",&channels_passing,"channels_passing[2][5]/I");
466  tsignals->Branch("bwslice_rmsdiode",&bwslice_rmsdiode,"bwslice_rmsdiode[2][5]/D");
467  tsignals->Branch("l1_passing",&l1_passing,"l1_passing/I");
468  tsignals->Branch("integral_vmmhz",&integral_vmmhz_foranita,"integral_vmmhz/D");
469  //tsignals->Branch("dnutries",&dnutries,"dnutries/D");
470  //tsignals->Branch("weight_test",&weight_test,"weight_test/D");
471  tsignals->Branch("flag_e_inanita",&flag_e_inanita,"flag_e_inanita[5][512]/I");
472  tsignals->Branch("flag_h_inanita",&flag_h_inanita,"flag_h_inanita[5][512]/I");
473 
474 
475  tdata=new TTree("tdata","tdata");
476  tdata->Branch("total_diodeinput_1_allantennas",&total_diodeinput_1_allantennas,"total_diodeinput_1_allantennas[48][512]/D"); // this is the waveform that is input to the tunnel diode in the first (LCP or vertical) polarization
477  tdata->Branch("total_diodeinput_2_allantennas",&total_diodeinput_2_allantennas,"total_diodeinput_2_allantennas[48][512]/D"); // this is the waveform that is input to the tunnel diode in the first (LCP or vertical) polarization
478  tdata->Branch("timedomain_output_allantennas",&timedomain_output_allantennas,"timedomain_output_allantennas[2][48][512]/D"); // this is the waveform that is output to the tunnel diode in the first (LCP or vertical) polarization
479  tdata->Branch("arrival_times",&arrival_times,"arrival_times[2][48]/D");
480  tdata->Branch("inu",&inu,"inu/I");
481  tdata->Branch("powerthreshold",&powerthreshold,"powerthreshold[5]/D");
482  tdata->Branch("bwslice_rmsdiode",&bwslice_rmsdiode,"bwslice_rmsdiode[2][5]/D");
483 
484  //std::array< std::array< std::array< std::array<std::vector<int>,5>, 2>, 16>, 3> arrayofhits_inanita;
485 
486  tdata->Branch("arrayofhits_inanita",&arrayofhits_inanita,"arrayofhits_inanita[3][16][2][512]/I");
487 
488  tdata->Branch("l1trig_anita3and4_inanita",&l1trig_anita3and4_inanita,"l1trig_anita3and4_inanita[2][16][512]/I");
489 
490  tdata->Branch("l1trig_anita4lr_inanita",&l1trig_anita4lr_inanita,"l1trig_anita4lr_inanita[3][16][512]/I");
491 
492 
493  tdata->Branch("l2trig_anita4lr_inanita",&l2trig_anita4lr_inanita,"l2trig_anita4lr_inanita[16][3][512]/I");
494 
495  tdata->Branch("l3type0trig_anita4lr_inanita",&l3type0trig_anita4lr_inanita,"l3type0trig_anita4lr_inanita[16][512]/I");
496  tdata->Branch("l3trig_anita4lr_inanita",&l3trig_anita4lr_inanita,"l3trig_anita4lr_inanita[16][512]/I");
497 
498 
499  //tdata->Branch("arrayofhits_inanita",&arrayofhits_inanita,"std::array< std::array< std::array< std::array<std::vector<int>,5>, 2>, 16>, 3>");
500  tdata->Branch("passglobtrig",&passglobtrig,"passglobtrig[2]/I");
501 
502 
503  tgaryanderic=new TTree("tgaryanderic","tgaryanderic");
504  tgaryanderic->Branch("arrayofhits",&arrayofhits_forgaryanderic,"arrayofhits_forgaryanderic[3][16][2][512]/I");
505  tgaryanderic->Branch("l1trig",&l1trig_anita4lr_forgaryanderic,"l1trig_anita4lr_forgaryanderic[3][16][512]/I");
506 
507  tgaryanderic->Branch("l2trig",&l2trig_anita4lr_forgaryanderic,"l2trig_anita4lr_forgaryanderic[16][512]/I");
508  tgaryanderic->Branch("l3type0trig",&l3type0trig_anita4lr_forgaryanderic,"l3type0trig_anita4lr_forgaryanderic[16][512]/I");
509  tgaryanderic->Branch("l3type1trig",&l3type1trig_anita4lr_forgaryanderic,"l3type1trig_anita4lr_forgaryanderic[16][512]/I");
510  tgaryanderic->Branch("passglobtrig",&passglobtrig,"passglobtrig[2]/I");
511  tgaryanderic->Branch("weight",&weight_inanita,"weight_inanita/D");
512  tgaryanderic->Branch("time",&time_trig,"time_trig[512]/D");
513 
514 
515  tglob=new TTree("tglob","tglob");
516  tglob->Branch("inu",&inu,"inu/I");
517  tglob->Branch("passglobtrig",&passglobtrig,"passglobtrig[2]/I");
518  tglob->Branch("l1_passing_allantennas",&l1_passing_allantennas,"l1_passing_allantennas[48]/I");
519 
520 
521 
522  // Prepare the file and tree for the coherent sum trigger's data tree
523  coherent_datafile = new TFile(Form("%s/coherent_sum_data_file.root", outputdir.Data()),"RECREATE");
524  coherent_waveform_sum_tree = new TTree("coherent_waveform_sum_tree", "Coherent Waveform Sum");
525  coherent_waveform_sum_tree->Branch("event_number", &cwst_event_number);
526  coherent_waveform_sum_tree->Branch("center_phi_sector", &cwst_center_phi_sector);
527  coherent_waveform_sum_tree->Branch("rms_noise", &cwst_rms_noise);
528  coherent_waveform_sum_tree->Branch("actual_rms", &cwst_actual_rms);
529  coherent_waveform_sum_tree->Branch("threshold", &cwst_threshold);
530  coherent_waveform_sum_tree->Branch("window_start", &cwst_window_start);
531  coherent_waveform_sum_tree->Branch("window_end", &cwst_window_end);
532 
533  coherent_waveform_sum_tree->Branch("deg_theta", &cwst_deg_theta);
534  coherent_waveform_sum_tree->Branch("deg_phi", &cwst_deg_phi);
535 
536  coherent_waveform_sum_tree->Branch("actual_deg_theta", &cwst_actual_deg_theta);
537  coherent_waveform_sum_tree->Branch("actual_deg_phi", &cwst_actual_deg_phi);
538 
539  coherent_waveform_sum_tree->Branch("timesteps", cwst_timesteps);
540 
541  for (unsigned i = 0; i < 48; ++i) {
542  cwst_RXs[i].waveform = new vector <double>(HALFNFOUR, 0.);
543  cwst_RXs[i].digitized = new vector <double>(HALFNFOUR, 0.);
544  coherent_waveform_sum_tree->Branch(Form("rx%u", i), &(cwst_RXs[i]));
545  }
546 
547  for (unsigned int i = 0; i < 9; i++) {
548  cwst_aligned_wfms[i].digitized = new vector <double>(HALFNFOUR, 0.);
549  coherent_waveform_sum_tree->Branch(Form("aligned_wfms%u", i), &(cwst_aligned_wfms[i]));
550  /*
551  //coherent_waveform_sum_tree->Branch(Form("whole_wfms%u", i), &(cwst_whole_wfms[i]));
552  cwst_whole_wfms[i] = new vector <double>(HALFNFOUR, 0.);
553  cwst_wfms[i] = new vector <double>(HALFNFOUR, 0.);
554  cwst_aligned_wfms[i] = new vector <double>(HALFNFOUR, 0.);
555  coherent_waveform_sum_tree->Branch(Form("whole_wfms%u", i), &(cwst_whole_wfms[i]));
556  coherent_waveform_sum_tree->Branch(Form("wfms%u", i), &(cwst_wfms[i]));
557  coherent_waveform_sum_tree->Branch(Form("aligned_wfms%u", i), &(cwst_aligned_wfms[i]));
558  */
559  }
560 
561  coherent_waveform_sum_tree->Branch("summed_wfm", &cwst_summed_wfm);
562  coherent_waveform_sum_tree->Branch("power_of_summed_wfm", &cwst_power_of_summed_wfm);
563  coherent_waveform_sum_tree->Branch("power", &cwst_power);
564  // End of preparition for the coherent sum trigger's data tree
565 
566 
567 }
568 
569 void Anita::initializeFixedPowerThresholds(ofstream &foutput){
570 
571  if (BANDING==2) { //anita 2
572 
573  // I derive these thresholds from Ryan's plot
574  //of measured rates vs. threshold
575  // that appears on p. 9 of his talk at the Anita meeting 19th Feb 2008
576  // Using 14 MHz, 8 MHz, 8MHz and 1 MHz for L, M, H and full bands
577  powerthreshold[0]=-1.87; // low band
578  powerthreshold[1]=-2.53; // middle band
579  powerthreshold[2]=-2.15; // high band
580  powerthreshold[3]=-1.; // not used for Anita 2
581  powerthreshold[4]=-4.41; // full band - use this threshold when other bands are used
582  //powerthreshold[4]=-5.3; // full band - use this threshold for full band only trigger
583 
584 
585  powerthreshold_nadir[0]=-6.7; // low band
586  powerthreshold_nadir[1]=-6.5; // middle band
587  powerthreshold_nadir[2]=-5.1; // high band
588  powerthreshold_nadir[3]=-1.; // not used for Anita 2
589  powerthreshold_nadir[4]=-6.7; // full band - use this threshold when other bands are used
590 
591 
592  foutput << "Thresholds are (in p/<p>): " <<
593  powerthreshold[0] << " (L)\t" <<
594  powerthreshold[1] << " (M)\t" <<
595  powerthreshold[2] << " (H)\t" <<
596  powerthreshold[4] << " (F)\n";
597  }
598  else if (BANDING==0 || BANDING==1) { // anita 1 or set your own
599 
600  powerthreshold[0]=-3.27;
601  powerthreshold[1]=-3.24;
602  powerthreshold[2]=-2.48;
603  powerthreshold[3]=-2.56;
604  powerthreshold[4]=-3.;
605 
606  foutput << "Thresholds are (in p/<p>): " <<
607  powerthreshold[0] << " (L)\t" <<
608  powerthreshold[1] << " (M1)\t" <<
609  powerthreshold[2] << " (M2)\t" <<
610  powerthreshold[3] << " (H)\t" <<
611  powerthreshold[4] << " \n";
612 
613  } else if (BANDING==4 || BANDING==5){ // anita-3
614  powerthreshold[0]=-1; // not used
615  powerthreshold[1]=-1; // not used
616  powerthreshold[2]=-1; // not used
617  powerthreshold[3]=-1; // not used
618  powerthreshold[4]=-5.40247; // Average Anita-3 scaler is 450kHz, which corresponds to this threshold as seen in
619  // p. 9 of Ryan's talk at the Anita meeting 19th Feb 2008
620 
621  foutput << "Thresholds are (in p/<p>): " <<
622  powerthreshold[0] << " (L)\t" <<
623  powerthreshold[1] << " (M1)\t" <<
624  powerthreshold[2] << " (M2)\t" <<
625  powerthreshold[3] << " (H)\t" <<
626  powerthreshold[4] << " \n";
627 
628  }
629 }
630 
631 void Anita::readVariableThresholds(Settings *settings1){
632 
633  if (settings1->WHICH==8) { // ANITA-2
634  fturf=new TFile((ICEMC_DATA_DIR+"/turfrate_icemc.root").c_str());
635  turfratechain=(TTree*)fturf->Get("turfrate_icemc");
636  turfratechain->SetMakeClass(1);
637  turfratechain->SetBranchAddress("phiTrigMask",&phiTrigMask);
638  turfratechain->SetBranchAddress("realTime",&realTime_turfrate);
639  turfratechain->BuildIndex("realTime");
640  turfratechain->GetEvent(0);
641  realTime_tr_min=realTime_turfrate; // realTime of first event in the file
642  turfratechain->GetEvent(turfratechain->GetEntries()-1);
643  realTime_tr_max=realTime_turfrate; // realTime of last event in file
644 
645 
646  }else if (settings1->WHICH==9 || settings1->WHICH==10){ // ANITA-3 and 4
647 
648  string turfFile="";
649  string surfFile="";
650  if (settings1->WHICH==9){
651  turfFile+=ICEMC_DATA_DIR+"/SampleTurf_icemc_anita3.root";
652  surfFile+=ICEMC_DATA_DIR+"/SampleSurf_icemc_anita3.root";
653  }else{
654  turfFile+=ICEMC_DATA_DIR+"/SampleTurf_run42to367_anita4.root";
655  surfFile+=ICEMC_DATA_DIR+"/SampleSurf_run42to367_anita4.root";
656  }
657 
658  // Reading in masking every 60 seconds
659  fturf=new TFile(turfFile.c_str());
660  turfratechain=(TTree*)fturf->Get("turfrate_icemc");
661  turfratechain->SetMakeClass(1);
662  turfratechain->SetBranchAddress("phiTrigMask",&phiTrigMask);
663  turfratechain->SetBranchAddress("phiTrigMaskH",&phiTrigMaskH);
664  turfratechain->SetBranchAddress("l1TrigMask",&l1TrigMask);
665  turfratechain->SetBranchAddress("l1TrigMaskH",&l1TrigMaskH);
666 
667  turfratechain->SetBranchAddress("deadTime",&deadTime);
668  turfratechain->SetBranchAddress("realTime",&realTime_turfrate);
669  turfratechain->BuildIndex("realTime");
670  turfratechain->GetEvent(0);
671  realTime_tr_min=realTime_turfrate; // realTime of first event in the file
672  turfratechain->GetEvent(turfratechain->GetEntries()-1);
673  realTime_tr_max=realTime_turfrate; // realTime of last event in file
674 
675  // Reading in thresholds/scalers every 60 seconds
676  fsurf=new TFile(surfFile.c_str());
677  surfchain=(TTree*)fsurf->Get("surf_icemc");
678  surfchain->SetMakeClass(1);
679  surfchain->SetBranchAddress("thresholds", &thresholds );
680  surfchain->SetBranchAddress("scalers", &scalers );
681  surfchain->SetBranchAddress("fakeThreshold", &fakeThresholds );
682  surfchain->SetBranchAddress("fakeThreshold2", &fakeThresholds2 );
683  surfchain->SetBranchAddress("fakeScaler", &fakeScalers );
684  surfchain->SetBranchAddress("realTime", &realTime_surf );
685  surfchain->BuildIndex("realTime");
686  surfchain->GetEvent(0);
687  realTime_surf_min=realTime_surf; // realTime of first event in the file
688  surfchain->GetEvent(surfchain->GetEntries()-1);
689  realTime_surf_max=realTime_surf; // realTime of last event in file
690  }
691 }
692 
693 
694 void Anita::readAmplification(){
695 
696  // get rfcm amplification data
697  // read from tree with amplification data
698  // this tree contains a different event for each antenna and polarization
699  TFile *f2=new TFile((ICEMC_DATA_DIR+"/gains.root").c_str());
700  TTree *tgain=(TTree*)f2->Get("tree1");
701 
702  float freq_ampl_eachantenna[NPOINTS_AMPL];
703  float ampl_eachantenna[NPOINTS_AMPL];
704  float noisetemp_eachantenna[NPOINTS_AMPL];
705 
706  tgain->SetBranchAddress("freq",freq_ampl_eachantenna);
707  tgain->SetBranchAddress("ampl",ampl_eachantenna);
708  tgain->SetBranchAddress("noisetemp",noisetemp_eachantenna);
709 
710  for (int iant=0;iant<48;iant++) {
711  tgain->GetEvent(iant);
712  for (int j=0;j<NPOINTS_AMPL;j++) {
713 
714  freq_ampl[iant][j]=(double)freq_ampl_eachantenna[j];
715 
716  ampl[iant][j]=(double)ampl_eachantenna[j];
717 
718  ampl[iant][j]+=32.; // add 32 dB to correct for attenuation that was used during the test
719  ampl_notdb[iant][j]=pow(10.,ampl[iant][j]/10.); // convert to regular fraction
720 
721  noisetemp[iant][j]=(double)noisetemp_eachantenna[j]; // so far we don't use this for anything
722  }
723  }
724  f2->Close();
725 }
726 
727 
728 
729 
730 void Anita::getDiodeDataAndAttenuation(Settings *settings1, TString outputdir){
731 
732  // get vnoise data
733  string sdiode;
734  if (BANDING==0)
735  sdiode=ICEMC_DATA_DIR+"/diode_anita1.root";
736  else if (BANDING==1)
737  sdiode=ICEMC_DATA_DIR+"/diode_nobanding.root";
738  else if (BANDING==2)
739  sdiode=ICEMC_DATA_DIR+"/diode_anita2.root";
740  else if (BANDING==4 || BANDING==5) // Linda
741  sdiode=ICEMC_DATA_DIR+"/diode_anita3.root";
742 
743  fnoise=new TFile(sdiode.c_str());
744  tdiode=(TTree*)fnoise->Get("diodeoutputtree");
745 
746 
747 
748  string sbands;
749  if (BANDING==0)
750  sbands=ICEMC_DATA_DIR+"/bands_anita1.root";
751  else if (BANDING==1)
752  sbands=ICEMC_DATA_DIR+"/bands_nobanding.root";
753  else if (BANDING==2)
754  sbands=ICEMC_DATA_DIR+"/bands_anita2.root";
755  else if (BANDING==4 || BANDING==5) // Linda
756  sbands=ICEMC_DATA_DIR+"/bands_anita2.root";
757 
758  TFile *fbands=new TFile(sbands.c_str());
759  TTree *tbands=(TTree*)fbands->Get("bandstree");
760 
761 
762  for (int i=0;i<HALFNFOUR;i++) {
763  time[i]=(double)i*TIMESTEP;
764  time_long[i]=time[i];
765  //cout << "time is " << time[i] << "\n";
766  time_centered[i]=time[i]-(double)HALFNFOUR/2*TIMESTEP;
767  }
768  for (int i=HALFNFOUR;i<NFOUR;i++) {
769  time_long[i]=(double)i*TIMESTEP;
770  }
771 
772 
773  // get diode model
774  getDiodeModel();
775 
776  int m=(int)(maxt_diode/TIMESTEP);
777  for (int j=0;j<5;j++) {
778  for (int i=0;i<m;i++) {
779  fdiode_real[j][i]=diode_real[j][i];
780  }
781  for (int i=m;i<NFOUR;i++) {
782  fdiode_real[j][i]=0.; // now fdiode_real is NFOUR array which is double sized then the signal we have. This is for zero padding for later convolution.
783  }
784 
785  Tools::realft(fdiode_real[j],1,NFOUR); // now fdiode_real is in freq domain
786  }
787  // try applying an exponential to the frequency domain
788 
789 
790  TCanvas *cdiode=new TCanvas("cdiode","cdiode",880,800);
791  cdiode->Divide(1,2);
792  TGraph *gdiode=new TGraph(NFOUR/2,time,diode_real[4]);
793  cdiode->cd(1);
794  gdiode->Draw("al");
795  gdiode=new TGraph(NFOUR/2,freq_forfft,fdiode_real[4]);
796  cdiode->cd(2);
797  gdiode->Draw("al");
798 
799  stemp=string(outputdir.Data())+"/diode.eps";
800  cdiode->Print((TString)stemp);
801 
802  tdiode->SetBranchAddress("avgfreqdomain_lab",&(avgfreqdomain_lab[0]));
803  tdiode->SetBranchAddress("freqdomain_amp_icemc",&(freqdomain_rfcm[0]));
804  tdiode->SetBranchAddress("freqdomain_rfcm_banding",&(freqdomain_rfcm_banding[0][0]));
805 
806 
807 
808  tbands->SetBranchAddress("freq_bands",freq_bands);
809  tbands->SetBranchAddress("bandsattn",bandsattn);
810  //tbands->SetBranchAddress("correl",&(correl[0][0]));
811  tbands->SetBranchAddress("correl_banding",&(correl_banding[0][0]));
812  tbands->SetBranchAddress("correl_lab",&(correl_lab[0]));
813  tbands->GetEntry(0);
814 
815 
816 
817 
818 
819  // cout << "WARNING!! Altering bandsattn.\n";
820  for (int j=0;j<5;j++) {
821  //BoxAverage(bandsattn[j],NPOINTS_BANDS,10);
822  for (int i=0;i<NPOINTS_BANDS;i++) {
823 
824  // bandsattn[j][i]*=4.;
825  if (bandsattn[j][i]>1.)
826  bandsattn[j][i]=1.;
827 
828  // if (BANDING==0 && j==4) // make this the same as the full band in anita 2
829  //bandsattn[j][i]=1.;
830  }
831  }
832 
833 
834  TGraph *gbandsattn[5];
835  TGraph *gcorr[5];
836  TH2F *hbandsattn=new TH2F("hbandsattn","hbandsattn",100,0.,2.E9,100,0.,1.);
837  TH2F *hcorr=new TH2F("hcorr","hcorr",100,0.,2.E9,100,0.,2.);
838  for (int i=0;i<5;i++) {
839  gbandsattn[i]=new TGraph(NPOINTS_BANDS,freq_bands[i],bandsattn[i]);
840  gbandsattn[i]->SetLineColor(2+i);
841  gcorr[i]=new TGraph(NPOINTS_BANDS,freq_bands[i],correl_banding[i]);
842  gcorr[i]->SetLineColor(2+i);
843  }
844  TCanvas *cbands=new TCanvas("cbands","cbands",880,800);
845  cbands->Divide(1,2);
846  cbands->cd(1);
847  hbandsattn->Draw();
848  for (int i=0;i<5;i++) {
849  gbandsattn[i]->Draw("l");
850  }
851  cbands->cd(2);
852  hcorr->Draw();
853  for (int i=0;i<5;i++) {
854  gcorr[i]->Draw("l");
855  }
856  stemp=string(outputdir.Data())+"/bands.eps";
857  cbands->Print((TString)stemp);
858 
859 
860 
861  // if (BANDING==0)
862  // sbands=ICEMC_DATA_DIR+"/bands_anita2.root";
863 
864 
865  // TFile *fbands_temp=new TFile(sbands.c_str());
866  // TTree *tbands_temp=(TTree*)fbands_temp->Get("bandstree");
867  // double bandsattn_temp[5][NPOINTS_BANDS];
868  // tbands_temp->SetBranchAddress("bandsattn",bandsattn_temp);
869  // tbands_temp->GetEvent(0);
870  // for (int i=0;i<NPOINTS_BANDS;i++) {
871  // bandsattn[4][i]=bandsattn_temp[4][i];
872  // }
873 
874 }
875 
876 
877 
878 void Anita::setDiodeRMS(Settings *settings1, TString outputdir){
879 
880  double mindiodeconvl[5];
881  double onediodeconvl[5];
882 
883  double power_noise_eachband[5][NFOUR];
884  double timedomain_output[5][NFOUR];
885 
886  // average result of diode integrator during quiet time
887 
888  for (int i=0;i<5;i++) {
889  bwslice_enoise[i]=0.;
890  bwslice_rmsdiode[0][i]=bwslice_rmsdiode[1][i]=0.;
891  bwslice_vrms[i]=0.;
892  }
893 
894 
895  nnoiseevents=tdiode->GetEntries();
896  noiseeventcounter=0;
897 
898 
899  int nhnoisebins=100;
900  TH1F *hnoise[5];
901 
902  char histname[150];
903  for (int j=0;j<3;j++) {
904 
905  sprintf(histname,"hnoise_%d",j);
906  if (BANDING==2)
907  hnoise[j]=new TH1F(histname,histname,nhnoisebins,-40.,20.);
908  else
909  hnoise[j]=new TH1F(histname,histname,nhnoisebins,-80.,40.);
910  }
911  if (BANDING==2) {
912  sprintf(histname,"hnoise_3");
913  hnoise[3]=new TH1F(histname,histname,nhnoisebins,-60.0,40.0);
914  sprintf(histname,"hnoise_4");
915  hnoise[4]=new TH1F(histname,histname,nhnoisebins,-60.0,40.0);
916  }
917  else {
918  sprintf(histname,"hnoise_3");
919  hnoise[3]=new TH1F(histname,histname,nhnoisebins,-120.0,80.0);
920  sprintf(histname,"hnoise_4");
921  hnoise[4]=new TH1F(histname,histname,nhnoisebins,-120.0,80.0);
922 
923  }
924 
925  // just take the average noise arrays from the tdiode tree
926  tdiode->GetEvent(0);
927 
928  cout << "after getting event, freqdomain_rfcm_banding is " << freqdomain_rfcm_banding[0][NFOUR/8-1] << "\n";
929 
930  // TGraph *gfreqdomain_rfcm=new TGraph(NFOUR/4,freq_forplotting,freqdomain_rfcm);
931  // TGraph *gavgfreqdomain_lab=new TGraph(NFOUR/4,freq_forplotting,avgfreqdomain_lab);
932  // TGraph *gfreqdomain_rfcm_banding[5];
933 
934  // for (int i=0;i<5;i++) {
935  // gfreqdomain_rfcm_banding[i]=new TGraph(NFOUR/4,freq_forplotting,freqdomain_rfcm_banding[i]);
936  // }
937 
938 
939 
940  // TCanvas *cfreq=new TCanvas("cfreq","cfreq",880,800);
941  // cfreq->Divide(1,3);
942  // cfreq->cd(1);
943  // gfreqdomain_rfcm->Draw("al");
944  // cfreq->cd(2);
945  // gavgfreqdomain_lab->Draw("al");
946  // cfreq->cd(3);
947  // gfreqdomain_rfcm_banding[4]->Draw("al");
948  // for (int i=0;i<5;i++) {
949  // gfreqdomain_rfcm_banding[i]->Draw("l");
950  // }
951  // stemp=string(outputdir.Data())+"/freqdomainplots.eps";
952  // cfreq->Print((TString)stemp);
953 
954 
955  // do the box banding for BANDING==1
956  if (BANDING==1) {
957  for (int j=0;j<5;j++) {
958 
959  for (int k=0;k<NFOUR/4;k++) {
960 
961  if (bwslice_min[j]>freq_forplotting[k] || bwslice_max[j]<freq_forplotting[k]) {
962  freqdomain_rfcm_banding[j][k]=0.;
963  }
964  }
965  }// end loop over bands
966  }
967 
968 
969 
970  double power=0.;
971  for (int j=0;j<5;j++) {
972  for (int k=0;k<NFOUR/4;k++) {
973  power+=freqdomain_rfcm_banding[j][k]/((double)NFOUR/4); // in V^2
974  }
975  // cout << "power is " << power << "\n";
976  }
977 
978  int ngeneratedevents=1000;
979  int passes[5]={0,0,0,0,0};
980  double averageoutput[5]={0.,0.,0.,0.,0.};
981 
982  if (!settings1->NOISEFROMFLIGHTTRIGGER){
983  for (int i=0;i<ngeneratedevents;i++) {
984  cout << double(i)/double(ngeneratedevents) << endl;
985  // put phases to freqdomain_rfcm_banding_rfcm array
986  // assign phases (w/ correlations) to freqdomain_rfcm_banding_rfmc_banding array
987  GetNoiseWaveforms();
988  for (int j=0;j<5;j++) {
989  // // timedomainnoise_rfcm_banding_e[j] contain noise waveforms for
990  // // each band. They come from taking the waveforms measured in
991  // // the signal stream, removing the rfcm's and lab attn.,
992  // // then reinserting rfcm's and band attn.
993  // // so they should be narrow band
994  // // myconvlv performs a convolution on that time domain waveform
995  // // based on the function that you define in getDiodeModel
996 
997  // cout << "timedomainnoise_rfcm_banding_e is " << timedomainnoise_rfcm_banding_e[j][NFOUR/4-1] << "\n";
998  myconvlv(timedomainnoise_rfcm_banding[0][j],NFOUR,fdiode_real[j],mindiodeconvl[j],onediodeconvl[j],power_noise_eachband[j],timedomain_output[j]);
999 
1000  hnoise[j]->Fill(onediodeconvl[j]*1.E15);
1001 
1002  bwslice_enoise[j]+=onediodeconvl[j];
1003 
1004 
1005  for (int m=(int)(maxt_diode/TIMESTEP);m<NFOUR/2;m++) {
1006  bwslice_meandiode[j]+=timedomain_output[j][m]/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1007  bwslice_vrms[j]+=timedomainnoise_rfcm_banding[0][j][m]*timedomainnoise_rfcm_banding[0][j][m]/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP)); // this is the rms of the diode input voltage
1008  averageoutput[j]+=timedomain_output[j][m]*timedomain_output[j][m]/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1009  } // end loop over samples where diode function is fully contained
1010 
1011  } // end loop over bands
1012 
1013  } // end loop over generated events
1014 
1015  // TCanvas *ctest=new TCanvas("ctest","ctest",880,800);
1016  // ctest->Divide(1,5);
1017  // TGraph *gtest[5];
1018  // for (int i=0;i<5;i++) {
1019  // ctest->cd(i+1);
1020  // gtest[i]=new TGraph(NFOUR,time_long,timedomain_output[i]);
1021  // gtest[i]->Draw("al");
1022  // }
1023  // stemp = string(outputdir.Data())+"/test.eps";
1024  // ctest->Print((TString)stemp);
1025 
1026  for (int j=0;j<5;j++) {
1027 
1028  bwslice_vrms[j]=sqrt(bwslice_vrms[j]); // this is the rms input voltage
1029  }
1030 
1031 
1032  for (int j=0;j<5;j++) {
1033  bwslice_enoise[j]=hnoise[j]->GetMean()/1.E15; // mean diode output with no correlations
1034 
1035  bwslice_fwhmnoise[j]=Tools::GetFWHM(hnoise[j]);
1036 
1037  }
1038 
1039 
1040  for (int i=0;i<ngeneratedevents;i++) {// now we need to get the rms
1041  GetNoiseWaveforms();
1042  for (int j=0;j<5;j++) {
1043 
1044  myconvlv(timedomainnoise_rfcm_banding[0][j],NFOUR,fdiode_real[j],mindiodeconvl[j],onediodeconvl[j],power_noise_eachband[j],timedomain_output[j]);
1045 
1046  for (int m=(int)(maxt_diode/TIMESTEP);m<NFOUR/2;m++) {
1047  bwslice_rmsdiode[0][j]+=(timedomain_output[j][m]-bwslice_meandiode[j])*(timedomain_output[j][m]-bwslice_meandiode[j])/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1048  }
1049 
1050  }
1051  }
1052 
1053  for (int j=0;j<5;j++) {
1054  bwslice_rmsdiode[0][j]=bwslice_rmsdiode[1][j]=sqrt(bwslice_rmsdiode[0][j]);
1055  cout << "mean, rms are " << bwslice_meandiode[j] << " " << bwslice_rmsdiode[0][j] << "\n";
1056  }
1057 
1058  double thresh_begin=-1.;
1059  double thresh_end=-11.;
1060  double thresh_step=1.;
1061 
1062  double rate[5][100];
1063  for (double testthresh=thresh_begin;testthresh>=thresh_end;testthresh-=thresh_step) {
1064  for (int j=0;j<5;j++) {
1065  passes[j]=0;
1066  }
1067  for (int i=0;i<ngeneratedevents;i++) {
1068 
1069  GetNoiseWaveforms();
1070  for (int j=0;j<5;j++) {
1071 
1072  myconvlv(timedomainnoise_rfcm_banding[0][j],NFOUR,fdiode_real[j],mindiodeconvl[j],onediodeconvl[j],power_noise_eachband[j],timedomain_output[j]);
1073 
1074  for (int m=(int)(maxt_diode/TIMESTEP);m<NFOUR/2;m++) {
1075 
1076  if (timedomain_output[j][m+1]<bwslice_rmsdiode[0][j]*testthresh) {
1077  passes[j]++;
1078  m+=(int)(DEADTIME/TIMESTEP);
1079  }
1080 
1081  } // end loop over samples where diode function is fully contained
1082  }
1083  }
1084  // brian m.
1085  for (int j=0;j<5;j++) {
1086  int ibin=(int)fabs((testthresh-thresh_begin)/thresh_step);
1087  // relthresh[j][ibin]=fabs(testthresh);
1088  rate[j][ibin]=passes[j]/((double)ngeneratedevents*((double)NFOUR/2*(TIMESTEP)-maxt_diode));
1089  if (rate[j][ibin]!=0)
1090  rate[j][ibin]=log10(rate[j][ibin]);
1091  //cout << "Threshold " << testthresh << " For the " << j << "th band, rate is " << rate[j][ibin] << "\n";
1092  }
1093  }
1094 
1095  } else { // IF WE HAVE NOISE FROM FLIGHT
1096 
1097 #ifdef ANITA_UTIL_EXISTS
1098  double quickNoise[HALFNFOUR];
1099 
1100  memset(bwslice_diodemean_fullband_allchan, 0, sizeof(bwslice_diodemean_fullband_allchan) );
1101  memset(bwslice_dioderms_fullband_allchan, 0, sizeof(bwslice_dioderms_fullband_allchan) );
1102 
1103  static double tempdiodeoutput[1000][NFOUR];
1104 
1105  if (settings1->WHICH==9) { // ANITA-3
1106  for (int ipol=0; ipol<2; ipol++){
1107  for (int iant=0; iant<48; iant++){
1108  // This takes for ages, and may appear to hang... some basic flushing to show user the status, esp for A4
1109  std::cout << "Using noise from flight to get rms of channel " << (ipol == 0 ? iant : 48+iant) + 1 << " of 96\r" << std::flush;
1110  if((ipol == 0 ? iant : 48+iant) + 1 == 96){std::cout << std::endl;}
1111 
1112  for (int ituff=0; ituff<ntuffs; ituff++){
1113  memset(tempdiodeoutput, 0, sizeof(tempdiodeoutput) );
1114 
1115  for (int i=0;i<ngeneratedevents;i++) {
1116 
1117  getQuickTrigNoiseFromFlight(settings1, quickNoise, ipol, iant, ituff);
1118 
1119  myconvlv(quickNoise,NFOUR,fdiode_real[4],mindiodeconvl[4],onediodeconvl[4],power_noise_eachband[4],tempdiodeoutput[i]);
1120 
1121  // First calculate the mean
1122  for (int m=(int)(maxt_diode/TIMESTEP);m<NFOUR/2;m++) {
1123  bwslice_diodemean_fullband_allchan[ipol][iant][ituff]+=tempdiodeoutput[i][m]/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1124  // cout << m << " " << timedomain_output[j][m] << " " << ((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP)) << endl;
1125 
1126  }
1127  }
1128 
1129  // Then get the RMS
1130  for (int i=0;i<ngeneratedevents;i++) {
1131 
1132  for (int m=(int)(maxt_diode/TIMESTEP);m<NFOUR/2;m++) {
1133  bwslice_dioderms_fullband_allchan[ipol][iant][ituff]+=(tempdiodeoutput[i][m]-bwslice_diodemean_fullband_allchan[ipol][iant][ituff])*(tempdiodeoutput[i][m]-bwslice_diodemean_fullband_allchan[ipol][iant][ituff])/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1134  }
1135 
1136  }
1137 
1138  bwslice_dioderms_fullband_allchan[ipol][iant][ituff]=sqrt(bwslice_dioderms_fullband_allchan[ipol][iant][ituff]);
1139  // cout << "EACH CHAN MEAN, RMS " << ipol << " " << iant << " " << ituff << " " << bwslice_diodemean_fullband_allchan[ipol][iant][ituff] << " , " << bwslice_dioderms_fullband_allchan[ipol][iant][ituff] << endl;
1140 
1141  }
1142  }
1143 
1144  }
1145 
1146  } else if (settings1->WHICH==10){ // ANITA-4
1147 
1148  double quickNoise2[2][HALFNFOUR];
1149  double lcprcpNoise[2][HALFNFOUR];
1150 
1151  static double tempdiodeoutput2[1000][NFOUR];
1152 
1153  for (int iant=0; iant<48; iant++){
1154  // This takes for ages, and may appear to hang... some basic flushing to show user the status, esp for A4
1155  std::cout << "Using noise from flight to get rms of channel pair " << iant + 1 << " of 48\r" << std::flush;
1156  if( iant + 1 == 48 ){std::cout << std::endl;}
1157 
1158  for (int ituff=0; ituff<ntuffs; ituff++){
1159 
1160  memset(tempdiodeoutput, 0, sizeof(tempdiodeoutput) );
1161  memset(tempdiodeoutput2, 0, sizeof(tempdiodeoutput2) );
1162 
1163  for (int i=0;i<ngeneratedevents;i++) {
1164 
1165  for (int ipol=0; ipol<2; ipol++){
1166  getQuickTrigNoiseFromFlight(settings1, quickNoise2[ipol], ipol, iant, ituff);
1167  }
1168 
1169  Tools::ConvertHVtoLRTimedomain(NFOUR, quickNoise2[0], quickNoise2[1], lcprcpNoise[0], lcprcpNoise[1]);
1170  myconvlv(lcprcpNoise[0],NFOUR,fdiode_real[4],mindiodeconvl[4],onediodeconvl[4],power_noise_eachband[4],tempdiodeoutput[i]);
1171  myconvlv(lcprcpNoise[1],NFOUR,fdiode_real[4],mindiodeconvl[4],onediodeconvl[4],power_noise_eachband[4],tempdiodeoutput2[i]);
1172 
1173  // First calculate the mean
1174  for (int m=(int)(maxt_diode/TIMESTEP);m<NFOUR/2;m++) {
1175  bwslice_diodemean_fullband_allchan[0][iant][ituff]+=tempdiodeoutput[i][m]/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1176  bwslice_diodemean_fullband_allchan[1][iant][ituff]+=tempdiodeoutput2[i][m]/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1177  // cout << m << " " << timedomain_output[j][m] << " " << ((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP)) << endl;
1178 
1179  }
1180 
1181  }
1182 
1183  // Then get the RMS
1184  for (int i=0;i<ngeneratedevents;i++) {
1185 
1186  for (int m=(int)(maxt_diode/TIMESTEP);m<NFOUR/2;m++) {
1187  bwslice_dioderms_fullband_allchan[0][iant][ituff]+=(tempdiodeoutput[i][m]-bwslice_diodemean_fullband_allchan[0][iant][ituff])*(tempdiodeoutput[i][m]-bwslice_diodemean_fullband_allchan[0][iant][ituff])/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1188  bwslice_dioderms_fullband_allchan[1][iant][ituff]+=(tempdiodeoutput2[i][m]-bwslice_diodemean_fullband_allchan[1][iant][ituff])*(tempdiodeoutput2[i][m]-bwslice_diodemean_fullband_allchan[1][iant][ituff])/((double)ngeneratedevents*((double)NFOUR/2-maxt_diode/TIMESTEP));
1189  }
1190 
1191  }
1192 
1193  bwslice_dioderms_fullband_allchan[0][iant][ituff]=sqrt(bwslice_dioderms_fullband_allchan[0][iant][ituff]);
1194  bwslice_dioderms_fullband_allchan[1][iant][ituff]=sqrt(bwslice_dioderms_fullband_allchan[1][iant][ituff]);
1195  // cout << "EACH CHAN MEAN, RMS " << ipol << " " << iant << " " << ituff << " " << bwslice_diodemean_fullband_allchan[ipol][iant][ituff] << " , " << bwslice_dioderms_fullband_allchan[ipol][iant][ituff] << endl;
1196 
1197  }
1198  }
1199 
1200  }
1201 
1202 
1203 
1204 
1205 
1206 
1207 #endif
1208  }
1209 
1210  TF1 *frice[5];
1211 
1212  int jplot;
1213  TCanvas *c4=new TCanvas("c4","c4",880,800);
1214  c4->Divide(1,5);
1215  for (int j=0;j<5;j++) {
1216 
1217 
1218  // cout << "cd to " << j+1 << "\n";
1219  frice[j]=new TF1("frice","[2]*(-1.*x-[1])/[0]^2*exp(-1.*(-1.*x-[1])^2/2/[0]^2)",-50.,50.);
1220  frice[j]->SetParameter(0,4.);
1221  // frice[j]->SetParameter(1,-5.);
1222  frice[j]->SetParameter(1,5.);
1223  frice[j]->SetParameter(2,400.);
1224  //frice[j]->SetParameter(2,frice[j]->GetParameter(2)*hnoise[j]->GetEntries()/frice[j]->Integral(-500.,500.));
1225  jplot=j;
1226  // if (BANDING==2 && j==4)
1227  //jplot=j-1;
1228 
1229  if ((BANDING==2 && j!=3) ||
1230  // (BANDING!=2 && j!=4)) {
1231  (BANDING!=2 && BANDING!=4) ||
1232  ((BANDING==4||BANDING==5) && j==4) ){
1233  c4->cd(jplot+1);
1234 
1235  if (j==0 && BANDING==2)
1236  hnoise[j]->Fit(frice[j],"Q","",-20.,1.);
1237  if (j==1 && BANDING==2)
1238  hnoise[j]->Fit(frice[j],"Q","",-20.,2.);
1239  if (j==2 && BANDING==2)
1240  hnoise[j]->Fit(frice[j],"Q","",-20.,10.);
1241  if (j==4 && (BANDING==2 || BANDING==4 || BANDING==5))
1242  hnoise[j]->Fit(frice[j],"Q","",-15.,15.);
1243 
1244  if (j==0 && BANDING==0)
1245  hnoise[j]->Fit(frice[j],"Q","",-20.,5.);
1246  if (j==1 && BANDING==0)
1247  hnoise[j]->Fit(frice[j],"Q","",-20.,5.);
1248  if (j==2 && BANDING==0)
1249  hnoise[j]->Fit(frice[j],"Q","",-20.,15.);
1250  if (j==3 && BANDING==0)
1251  hnoise[j]->Fit(frice[j],"Q","",-20.,20.);
1252 
1253  frice[j]->GetHistogram()->SetLineWidth(3);
1254 
1255  hnoise[j]->SetLineWidth(3);
1256  hnoise[j]->SetXTitle("Diode Output (10^{-15} Joules)");
1257  hnoise[j]->SetYTitle("Number of Noise Waveforms");
1258  hnoise[j]->SetTitleSize(0.05,"X");
1259  hnoise[j]->SetTitleSize(0.05,"Y");
1260 
1261  hnoise[j]->Draw();
1262  frice[j]->Draw("same");
1263  // cout << "bwslice_enoise is " << bwslice_enoise[j] << "\n";
1264  }
1265 
1266  }
1267  stemp=string(outputdir.Data())+"/hnoise.eps";
1268  c4->Print((TString)stemp);
1269 
1270 
1271 
1272 }
1273 
1274 
1275 
1276 #ifdef ANITA_UTIL_EXISTS
1277 void Anita::getQuickTrigNoiseFromFlight(Settings *settings1, double justNoise[HALFNFOUR], int ipol, int iant, int ituff){
1278 
1279  FFTWComplex *phasorsTrig = new FFTWComplex[numFreqs];
1280  phasorsTrig[0].setMagPhase(0,0);
1281  Double_t sigma, realPart, imPart, norm;
1282  int iring=2;
1283  if (iant<16) iring=0;
1284  else if (iant<32) iring=1;
1285 
1286  int iphi = iant - (iring*16);
1287 
1288  TRandom * fRand = getRNG(RNG_NOISE);
1289  for(int i=1;i<numFreqs;i++) {
1290 
1291  if (freqs[i]*1e6>=settings1->FREQ_LOW_SEAVEYS && freqs[i]*1e6<=settings1->FREQ_HIGH_SEAVEYS){
1292  norm = fRatioTriggerToA3DigitizerFreqDomain[ipol][iring][iphi][ituff][i];
1293  sigma = RayleighFits[ipol][iant]->Eval(freqs[i])*4./TMath::Sqrt(numFreqs);
1294  sigma*=norm;
1295  realPart = fRand->Gaus(0,sigma);
1296  imPart = fRand->Gaus(0,sigma);
1297  }else {
1298  imPart=realPart=0;
1299  }
1300  // cout << " " << i << " " << trig << " " << dig << " " << trig/dig << " " << norm << endl;
1301  phasorsTrig[i] = FFTWComplex(realPart, imPart);
1302  }
1303 
1304  RFSignal *rfNoiseTrig = new RFSignal(numFreqs,freqs,phasorsTrig,1);
1305  Double_t *justNoiseTemp = rfNoiseTrig->GetY();
1306 
1307  for (int i=0; i<HALFNFOUR; i++){
1308  justNoise[i] = justNoiseTemp[i]*THERMALNOISE_FACTOR;
1309  }
1310  delete rfNoiseTrig;
1311  delete[] phasorsTrig;
1312 
1313 }
1314 #endif
1315 
1316 void Anita::getPulserData(){
1317 
1318  TFile *fpulser=new TFile((ICEMC_DATA_DIR+"/pulser.root").c_str());
1319 
1320  TGraph *gpulser=(TGraph*)fpulser->Get("pulser");
1321  TGraph *gphases=(TGraph*)fpulser->Get("phases");
1322  TGraph *gnoise=(TGraph*)fpulser->Get("noise");
1323 
1324  USEPHASES=1;
1325 
1326  double *temp1=gpulser->GetX();
1327  for (int i=0;i<NFOUR/4;i++) {
1328  f_pulser[i]=temp1[i];
1329  }
1330  double *temp2=gphases->GetX();
1331  for (int i=0;i<NFOUR/4;i++) {
1332  f_phases[i]=temp2[i];
1333  }
1334  double *temp3=gpulser->GetY();
1335  double *temp4=gnoise->GetY();
1336 
1337 
1338  for (int i=0;i<NFOUR/4;i++) {
1339  v_pulser[i]=sqrt(temp3[i]); // is this right
1340  v_noise[i]=sqrt(temp4[i]);
1341  if (f_phases[i]<75.E6)
1342  v_noise[i]=0.;
1343 
1344  }
1345 
1346  TGraph *gpulser_eachband;
1347  TGraph *gnoise_eachband;
1348  TCanvas *cpulser=new TCanvas("cpulser","cpulser",880,800);
1349  cpulser->Divide(1,5);
1350  int iplot;
1351  for (int i=0;i<5;i++) {
1352  iplot=i;
1353 
1354  if (i!=3) {
1355  cpulser->cd(iplot+1);
1356 
1357  gpulser_eachband=new TGraph(NFOUR/4,f_pulser,v_pulser);
1358 
1359  gpulser_eachband->Draw("al");
1360  }
1361  }
1362 
1363  cpulser->Print("pulser.eps");
1364 
1365  TCanvas *cnoise=new TCanvas("cnoise","cnoise",880,800);
1366  cnoise->Divide(1,5);
1367  for (int i=0;i<5;i++) {
1368  iplot=i;
1369 
1370  if (i!=3) {
1371  cnoise->cd(iplot+1);
1372  gnoise_eachband=new TGraph(NFOUR/4,f_pulser,v_noise);
1373 
1374  gnoise_eachband->Draw("al");
1375  }
1376  }
1377 
1378  cnoise->Print("noise.eps");
1379 
1380 
1381  // gpulser_eachband=new TGraph(NFOUR/4,f_pulser,v_pulser[iplot]);
1382  //gpulser_eachband->Draw("al");
1383 
1384 
1385 
1386  double sumpulserpower=0.;
1387  double sumnoisepower=0.;
1388 
1389  for (int i=0;i<NFOUR/4;i++) {
1390  sumpulserpower+=v_pulser[i]*v_pulser[i];
1391  sumnoisepower+=v_noise[i]*v_noise[i];
1392  }
1393 
1394  double *temp5=gphases->GetY();
1395  for (int i=0;i<NFOUR/4;i++) {
1396  v_phases[i]=temp5[i];
1397  }
1398 
1399  gpulser->Delete();
1400  gphases->Delete();
1401  gnoise->Delete();
1402 
1403  fpulser->Close();
1404 }
1405 
1406 
1407 
1408 
1409 
1410 
1411 
1412 
1413 void Anita::ReadGains(void) {
1414  // gains from university of hawaii measurements.
1415  double sfrequency;
1416  int iii;
1417  ifstream gainsfile;
1418  gainsfile.open((ICEMC_DATA_DIR+"/hh_0").c_str()); // gains for horizontal polarization
1419  if(gainsfile.fail()) {
1420  cout << "can't open `$ICEMC_DATA_DIR`/hh_0\n";
1421  exit(1);
1422  }
1423  for(iii = 0; iii < NPOINTS_GAIN; iii++)
1424  gainsfile >> frequency_forgain_measured[iii] >> gainh_measured[iii];
1425  gainsfile.close();
1426 
1427  gainsfile.open((ICEMC_DATA_DIR+"/vv_0").c_str()); // gains for vertical polarization
1428  if(gainsfile.fail()) {
1429  cout << "can't open `$ICEMC_DATA_DIR`/vv_0\n";
1430  exit(1);
1431  }
1432  for(iii = 0; iii < NPOINTS_GAIN; iii++) {
1433  gainsfile >> sfrequency >> gainv_measured[iii];
1434  if(sfrequency != frequency_forgain_measured[iii])
1435  cout << "warning: sfrequency = " << sfrequency << ", frequency_forgain_measured[iii] = " << frequency_forgain_measured[iii] << endl;
1436  }
1437  gainsfile.close();
1438 
1439  gainsfile.open((ICEMC_DATA_DIR+"/hv_0").c_str()); // gains for h-->v cross polarization
1440  if(gainsfile.fail()) {
1441  cout << "can't open `$ICEMC_DATA_DIR`/hv_0\n";
1442  exit(1);
1443  }
1444  for(iii = 0; iii < NPOINTS_GAIN; iii++) {
1445  gainsfile >> sfrequency >> gainhv_measured[iii];
1446  if(sfrequency != frequency_forgain_measured[iii])
1447  cout << "warning: sfrequency = " << sfrequency << ", frequency_forgain_measured[iii] = " << frequency_forgain_measured[iii] << endl;
1448  }
1449  gainsfile.close();
1450 
1451  gainsfile.open((ICEMC_DATA_DIR+"/vh_0").c_str()); // gains for v-->h cross polarization
1452  if(gainsfile.fail()) {
1453  cout << "can't open `$ICEMC_DATA_DIR`/vh_0\n";
1454  exit(1);
1455  }
1456  for(iii = 0; iii < NPOINTS_GAIN; iii++) {
1457  gainsfile >> sfrequency >> gainvh_measured[iii];
1458  if(sfrequency != frequency_forgain_measured[iii])
1459  cout << "warning: sfrequency = " << sfrequency << ", frequency_forgain_measured[iii] = " << frequency_forgain_measured[iii] << endl;
1460  }
1461  gainsfile.close();
1462 } //ReadGains
1463 
1464 
1465 
1466 
1467 void Anita::AntennaGain(Settings *settings1,double hitangle_e,double hitangle_h,double e_component,double h_component,int k,double &vsignalarray_e,double &vsignalarray_h) {
1468 
1469  if (freq[k]>=settings1->FREQ_LOW_SEAVEYS && freq[k]<=settings1->FREQ_HIGH_SEAVEYS) {
1470 
1471  double relativegains[4]; // fill this for each frequency bin for each antenna. It's the gain of the antenna given the angle that the signal hits the balloon, for vv, vh, hv, hh, relative to the gain at boresight
1472 
1473  for (int pols=0;pols<2;pols++) {// loop over vv, hv
1474  if (fabs(hitangle_e)<PI/2)
1475  relativegains[pols]=Get_gain_angle(pols,k,hitangle_e);//change here to be constant if need be (ABBY). Add a setting to the code for use constant gain or dish or something. Make this a member function.
1476  else
1477  relativegains[pols]=0.;
1478  //if (fabs(hitangle_e)<PI/12)
1479  //cout << "relative gains is " << relativegains[pols] << "\n";
1480  }
1481 
1482 
1483  // if (fabs(hitangle_e)<PI/12)
1484  //cout << "vsignalarray_e before is " << vsignalarray_e << "\n";
1485 
1486  vsignalarray_e = settings1->IGNORE_CROSSPOL ? 0.5*vsignalarray_e * vvGaintoHeight[k] * e_component * sqrt(relativegains[0])
1487  : vsignalarray_e * 0.5 * sqrt(vvGaintoHeight[k] * vvGaintoHeight[k] * e_component * e_component * relativegains[0] + hvGaintoHeight[k] * hvGaintoHeight[k] * h_component * h_component * relativegains[1]); // 0.5 is for voltage dividing
1488 
1489 
1490  //cout << "In AntennaGain, vsignalarray_e is " << vsignalarray_e << "\n";
1491 
1492  //if (fabs(hitangle_e)<PI/12)
1493  //cout << "vsignalarray_e after is " << vsignalarray_e << "\n";
1494 
1495  for (int pols=2;pols<4;pols++) { // loop over hh, vh
1496  if (fabs(hitangle_h)<PI/2)
1497  relativegains[pols]=Get_gain_angle(pols,k,hitangle_h);
1498  else
1499  relativegains[pols]=0.;
1500  }
1501 
1502  // V/MHz
1503 
1504  //if (fabs(hitangle_h)<PI/12)
1505  //cout << "vsignalarray_h before is " << vsignalarray_h << "\n";
1506 
1507  vsignalarray_h= settings1->IGNORE_CROSSPOL ? vsignalarray_h * 0.5 * hhGaintoHeight[k] * h_component * sqrt(relativegains[2])
1508  : vsignalarray_h*0.5* sqrt(hhGaintoHeight[k]*hhGaintoHeight[k]*h_component*h_component*relativegains[2] + vhGaintoHeight[k]*vhGaintoHeight[k]*e_component*e_component*relativegains[3]);
1509 
1510  // the assumption is that the sign is set by the dominant component... the crosspol might actually be destructive :(
1511  if (settings1->POL_SIGN_HACK && !settings1->IGNORE_CROSSPOL)
1512  {
1513  if (e_component < 0) vsignalarray_e *=-1;
1514  if (h_component < 0) vsignalarray_h *=-1;
1515  }
1516 
1517  // if (fabs(hitangle_h)<PI/12)
1518  //cout << "vsignalarray_h after is " << vsignalarray_h << "\n";
1519 
1520  }
1521 }
1522 
1523 
1524 // The deck affects signals reaching the upper ring. These equations are for Fresnel diffraction around a half plane. The edge of the half plane passes just over and in front of the lower ring antenna that's facing the radio pulse. This assumption should be okay for the three upper ring antenns in the phi sector facing the pulse and should underestimate the effect of diffraction for the other upper ring antennas.
1525 // This only corrects for signal strength, not for changes in polarization and signal direction.
1526 // page and figure references are from Principles of Optics, by Born & Wolf, 7th edition
1527 void Anita::SetDiffraction() {
1528  const double cc = 299792458.0;
1529  const double height[2] = {3.21571, 2.25625}; // height of the phase centers of antennas 1 and 9 above the deck
1530  const double radius[2] = {1.40185, 1.5677}; // radius of the deck minus how far the phase centers of antennas 1 and 9 are from the payload's axis.
1531  const int ntau = 200;
1532  double ww, xx, ss, theta, sintheta, squigglyC, squigglyS, tau, dtau;
1533  for(int jj = 0; jj < 2; jj++) // loop through antenna layers
1534  for(int kk = 0; kk < 89; kk++) { // loop through pulse directions
1535  sintheta = 0.37 + 0.005*double(kk);
1536  theta = asin(sintheta); // angle between the direction from the center of the Earth to the payload and the direction of the pulse. This should be delta in figure 8.38
1537  ss = height[jj]/cos(theta); // page 382 fig 8.5 . This should be the distance between the phase center and wherever the pulse passes the deck.
1538  xx = height[jj]*tan(theta)-radius[jj]; // page 429 fig 8.38
1539  for(int ll = 0; ll < NFREQ; ll++) { // loop through frequencies
1540  ww = sqrt(2./cc*freq[ll]/ss)*xx*sintheta; // page 433 eq 23
1541  dtau = ww/double(ntau);
1542  squigglyS = 0.0;
1543  squigglyC = 0.0;
1544  for(int ii = 0; ii < ntau; ii++) { // page 430 eq 12
1545  tau = dtau*(double(ii)+0.5);
1546  squigglyC += cos(M_PI*0.5*tau*tau);
1547  squigglyS += sin(M_PI*0.5*tau*tau);
1548  }
1549  squigglyC *= dtau;
1550  squigglyS *= dtau;
1551  diffraction[jj][kk][ll] = sqrt(0.5*((0.5+squigglyC)*(0.5+squigglyC)+(0.5+squigglyS)*(0.5+squigglyS))); // page 434 eq 28
1552  if(jj == 0 && kk > 66) diffraction[jj][kk][ll] = 1.0; // in the top layer, diffraction[][][] has values greater than 1 in the low frequencies for sintheta > 0.73
1553  }
1554  }
1555  return;
1556 } // void SetDiffraction()
1557 
1558 double Anita::GetDiffraction(int ilayer, double zenith_angle, int ifreq) {
1559  double reference1 = (sin(zenith_angle)-0.37)*200.0;
1560  int whichbin = int(reference1);
1561  double factor = reference1 - double(whichbin);
1562  return factor*diffraction[ilayer][whichbin+1][ifreq] + (1.-factor)*diffraction[ilayer][whichbin][ifreq];
1563 }
1564 
1565 int Anita::SurfChanneltoBand(int ichan) {
1566 
1567  // takes surf channel (0-31) and finds what band it is
1568  if (ichan<0 || ichan>31) {
1569  cout << "surf channel out of range!\n";
1570  exit(1);
1571  }
1572 
1573  int iband= (ichan%8-ichan%2)/2;
1574 
1575 
1576  return iband;
1577 
1578 }
1579 
1580 // int Anita::GetScalarNumber(int lr,int ibw, int ilayer,int ifold) {
1581 
1582 // int rx = GetAntennaNumber(ilayer,ifold);
1583 // int rx_on_surf = (rx-1)%4 + 1; // surf holds four antennas. This number is 1-4.
1584 // int scalar= (rx_on_surf-1)*8 + ibw*2 + lr;
1585 
1586 // // returns the scalar number
1587 // return scalar;
1588 // }
1589 int Anita::GetAntennaNumber(int ilayer,int ifold) {
1590 
1591  return 8*(ilayer)+ifold+1; // antenna number 1-32
1592 
1593 }
1594 int Anita::GetLayer(int rx) {
1595  if (rx>=0 && rx<8)
1596  return 0;
1597  else if (rx>=8 && rx<16)
1598  return 1;
1599  else if (rx>=16 && rx<32)
1600  return 2;
1601 
1602  return -1;
1603 }
1604 int Anita::GetIfold(int rx) {
1605  if (rx>=0 && rx<16)
1606  return rx%8;
1607  else if (rx<32)
1608  return rx%16;
1609 
1610  return -1;
1611 }
1612 int Anita::AntennaWaveformtoSurf(int ilayer,int ifold) {
1613 
1614  int antenna=GetAntennaNumber(ilayer,ifold); // antenna number 1-32
1615 
1616  return antennatosurf[antenna-1]; // returns the surf number
1617 
1618 }
1619 int Anita::AntennaNumbertoSurfNumber(int ilayer,int ifold) {
1620  int antenna=GetAntennaNumber(ilayer,ifold); // antenna number 1-32
1621 
1622  return (antenna-1-(antenna-1)%4)/4+1; // returns the surf number 1-9
1623 
1624 
1625 }
1626 int Anita::GetSurfChannel(int antenna,int ibw,int ipol) { // 1 to 32
1627 
1628  return ((antenna-1)%4)*8+WhichBand(ibw,ipol);//which scalar channel, numbered 1 to 32
1629 
1630 }
1631 int Anita::WhichBand(int ibw,int ipol) {
1632 
1633  return 2*ibw+ipol+1; // from 1 to 8, which scalar channel on an antenna this band corresponds to, in order as they are on the surfs
1634 }
1635 void Anita::Banding(int j,double *freq_noise,double *vmmhz,int NPOINTS_NOISE) {
1636 
1637  if (j<0 || j>4) {
1638  cout << "Band out of range.\n";
1639  exit(1);
1640  }
1641  if (BANDING!=1) {
1642  int iband; // which index of freq_bands
1643  for (int i=0;i<NPOINTS_NOISE;i++) {
1644 
1645  iband=Tools::findIndex(freq_bands[j],freq_noise[i],NPOINTS_BANDS,freq_bands[j][0],freq_bands[j][NPOINTS_BANDS-1]);
1646  // cout << "freq_bands, freq_noise, NPOINTS_BANDS, freq_bands are " << freq_noise[i] << " " << NPOINTS_BANDS << " " << freq_bands[j][0] << " " << iband << "\n";
1647  vmmhz[i]=vmmhz[i]*sqrt(bandsattn[j][iband]); // sqrt since it's voltage and not power
1648 
1649 
1650  }
1651  }
1652  else if (BANDING==1) {
1653 
1654  for (int i=0;i<NPOINTS_NOISE;i++) {
1655  if (freq_noise[i]<bwslice_min[j] || freq_noise[i]>bwslice_max[j])
1656  vmmhz[i]=0.;
1657  } // loop over frequency bins
1658 
1659  } // if it's choose-your-own banding
1660 }
1661 void Anita::RFCMs(int ilayer,int ifold,double *vmmhz) {
1662 
1663  int irx=Anita::GetAntennaNumber(ilayer,ifold)-1; // want this to be 0-31
1664 
1665  int iampl;
1666  for (int i=0;i<NFREQ;i++) {
1667  // first find the index of the amplification array
1668  iampl=Tools::findIndex(freq_ampl[irx],freq[i],NPOINTS_AMPL,freq_ampl[irx][0],freq_ampl[irx][NPOINTS_AMPL-1]);
1669 
1670  vmmhz[i]=vmmhz[i]*sqrt(ampl_notdb[irx][iampl]);
1671 
1672  }
1673 
1674 }
1675 
1676 
1677 // reads in the effect of a signal not hitting the antenna straight on
1678 // also reads in gainxx_measured and sets xxgaintoheight
1679 void Anita::Set_gain_angle(Settings *settings1,double nmedium_receiver) {
1680  string gain_null1, gain_null2;
1681  double sfrequency;
1682  int iii, jjj;
1683  ifstream anglefile;
1684  for(jjj = 0; jjj < 4; jjj++)
1685  for(iii = 0; iii < 131; iii++)
1686  gain_angle[jjj][iii][0] = 1.;
1687 
1688  anglefile.open((ICEMC_DATA_DIR+"/vv_az").c_str()); // v polarization, a angle
1689  if(anglefile.fail()) {
1690  cout << "can't open `$ICEMC_DATA_DIR`/vv_az\n";
1691  exit(1);
1692  }
1693  for(jjj = 1; jjj < 7; jjj++)
1694  for(iii = 0; iii < 131; iii++) {
1695  anglefile >> sfrequency >> gain_angle[0][iii][jjj];
1696  if(sfrequency != frequency_forgain_measured[iii]) cout << "check frequencies for vv_az\n";
1697  }
1698  anglefile.close();
1699 
1700 
1701 
1702  anglefile.open((ICEMC_DATA_DIR+"/hh_az").c_str()); // h polarization, a angle
1703  if(anglefile.fail()) {
1704  cout << "can't open `$ICEMC_DATA_DIR`/hh_az\n";
1705  exit(1);
1706  }
1707  for(jjj = 1; jjj < 7; jjj++)
1708  for(iii = 0; iii < 131; iii++) {
1709  anglefile >> sfrequency >> gain_angle[1][iii][jjj];
1710  if(sfrequency != frequency_forgain_measured[iii]) cout << "check frequencies for hh_az\n";
1711  }
1712  anglefile.close();
1713 
1714  anglefile.open((ICEMC_DATA_DIR+"/hh_el").c_str()); // h polarization, e angle
1715  if(anglefile.fail()) {
1716  cout << "can't open `$ICEMC_DATA_DIR`/hh_el\n";
1717  exit(1);
1718  }
1719  for(jjj = 1; jjj < 7; jjj++)
1720  for(iii = 0; iii < 131; iii++) {
1721  anglefile >> sfrequency >> gain_angle[2][iii][jjj];
1722  if(sfrequency != frequency_forgain_measured[iii]) cout << "check frequencies for hh_el\n";
1723  }
1724  anglefile.close();
1725 
1726  anglefile.open((ICEMC_DATA_DIR+"/vv_el").c_str()); // v polarization, e angle
1727  if(anglefile.fail()) {
1728  cout << "can't open `$ICEMC_DATA_DIR`/vv_el\n";
1729  exit(1);
1730  }
1731  for(jjj = 1; jjj < 7; jjj++)
1732  for(iii = 0; iii < 131; iii++) {
1733  anglefile >> sfrequency >> gain_angle[3][iii][jjj];
1734  if(sfrequency != frequency_forgain_measured[iii]) cout << "check frequencies for vv_el\n";
1735  }
1736  anglefile.close();
1737  for(jjj = 0; jjj < 6; jjj++) inv_angle_bin_size[jjj] = 1. /
1738  (reference_angle[jjj+1] - reference_angle[jjj]); // this is used for interpolating gains at angles between reference angles
1739 
1740  double gainhv, gainhh, gainvh, gainvv;
1741  double gain_step = frequency_forgain_measured[1]-frequency_forgain_measured[0]; // how wide are the steps in frequency;
1742 
1743  cout << "GAINS is " << GAINS << "\n";
1744  for (int k = 0; k < NFREQ; ++k) {
1745  whichbin[k] = int((freq[k] - frequency_forgain_measured[0]) / gain_step); // finds the gains that were measured for the frequencies closest to the frequency being considered here
1746  if((whichbin[k] >= NPOINTS_GAIN || whichbin[k] < 0) && !settings1->FORSECKEL) {
1747  cout << "Set_gain_angle out of range, freq = " << freq[k] << endl;
1748  exit(1);
1749  }
1750 
1751  //now a linear interpolation for the frequency
1752  scalef2[k] = (freq[k] - frequency_forgain_measured[whichbin[k]]) / gain_step;
1753  // how far from the lower frequency
1754  scalef1[k] = 1. - scalef2[k]; // how far from the higher frequency
1755 
1756  // convert the gain at 0 degrees to the effective antenna height at 0 degrees for every frequency
1757  if(whichbin[k] == NPOINTS_GAIN - 1) { // if the frequency is 1.5e9 or goes a little over due to rounding
1758  gainhv = gainhv_measured[whichbin[k]];
1759  gainhh = gainh_measured[whichbin[k]];
1760  gainvh = gainvh_measured[whichbin[k]];
1761  gainvv = gainv_measured[whichbin[k]];
1762  } else {
1763  // These gains should be dimensionless numbers, not in dBi
1764  gainhv = scalef1[k] * gainhv_measured[whichbin[k]] + scalef2[k] * gainhv_measured[whichbin[k] + 1];
1765  gainhh = scalef1[k] * gainh_measured[whichbin[k]] + scalef2[k] * gainh_measured[whichbin[k] + 1];
1766  gainvh = scalef1[k] * gainvh_measured[whichbin[k]] + scalef2[k] * gainvh_measured[whichbin[k] + 1];
1767  gainvv = scalef1[k] * gainv_measured[whichbin[k]] + scalef2[k] * gainv_measured[whichbin[k] + 1];
1768  }
1769  if (GAINS==0) {
1770 
1771  gainhv=0.;
1772  gainhh=gain[1][k];
1773  gainvh=0.;
1774  gainvv=gain[0][k];
1775 
1776  }
1777 
1778 
1779  hvGaintoHeight[k] = GaintoHeight(gainhv,freq[k],nmedium_receiver);
1780  hhGaintoHeight[k] = GaintoHeight(gainhh,freq[k],nmedium_receiver);
1781  vhGaintoHeight[k] = GaintoHeight(gainvh,freq[k],nmedium_receiver);
1782  vvGaintoHeight[k] = GaintoHeight(gainvv,freq[k],nmedium_receiver);
1783 
1784  } // loop through frequency bins
1785 
1786 
1787 
1788 
1789 
1790 
1791 
1792 
1793 
1794 } // void Set_gain_angle()
1795 
1796 // determines the effect of a signal not hitting the antenna straight on
1797 // for the gain type, 0 means V polarization and el angle, 1 means H polarization and el angle, 2 means H polarization and az angle, 3 means V polarization and az angle
1798 // gain_angle[gain_type][][] lists the decrease in gain for different frequencies and angles. This subroutine finds the two angles closest to hitangle and the two frequencies closest to freq. It then returns a linear interpolation in 2 dimensions.
1799 int Anita::GetBeamWidths(Settings *settings1) {
1800 
1801  // first component is frequency
1802  // second component is which plane and which polarization
1803  // it goes e-plane: vp/hp, h-plane: vp/hp
1804 
1805  // these number were read from antenna specs
1806 
1807  // these are beam widths
1808 
1809  double freq_specs[5];
1810  int NFREQ_FORGAINS; // Number of
1811 
1812  if (settings1->WHICH==7) { // EeVa
1813  NFREQ_FORGAINS=4;
1814  freq_specs[0]=265.E6; // lower edge of
1815  freq_specs[1]=435.E6;
1816  freq_specs[2]=650.E6;
1817  freq_specs[3]=992.5E6;
1818 
1819 
1820  }
1821  else if (settings1->WHICH==11) { // Satellite
1822  NFREQ_FORGAINS=4;
1823  freq_specs[0]=265.E6; // lower edge of
1824  freq_specs[1]=435.E6;
1825  freq_specs[2]=650.E6;
1826  freq_specs[3]=992.5E6;
1827 
1828  }
1829 
1830  else { // everything else
1831  NFREQ_FORGAINS=5;
1832  freq_specs[0]=300.E6;
1833  freq_specs[1]=600.E6;
1834  freq_specs[2]=900.E6;
1835  freq_specs[3]=1200.E6;
1836  freq_specs[4]=1500.E6;
1837 
1838  }
1839 
1840 
1841 
1842  double specs[5][4];
1843 
1844  if (settings1->WHICH==7) { // EeVA
1845 
1846 
1847  // these are all for 200 MHz
1848  specs[0][0]=2.5; // eplane, vp
1849  specs[0][1]=2.5;// eplane, hp
1850  specs[0][2]=1.5;// hplane, vp
1851  specs[0][3]=1.5;// hplane, hp
1852 
1853  // these are for 355 MHz
1854  specs[1][0]=2.2;
1855  specs[1][1]=2.2;
1856  specs[1][2]=1.2;
1857  specs[1][3]=1.2;
1858 
1859  // 515 MHz
1860  specs[2][0]=2.2;
1861  specs[2][1]=2.2;
1862  specs[2][2]=1.0;
1863  specs[2][3]=1.0;
1864 
1865  // 785 MHz
1866  specs[3][0]=2.2;
1867  specs[3][1]=2.2;
1868  specs[3][2]=0.9;
1869  specs[3][3]=0.9;
1870 
1871  }
1872  else { // everything but EeVA
1873  // for now use this for satellite even
1874  // these are beam widths in degrees
1875  // these are all for 300 MHz
1876  specs[0][0]=57.5; // eplane, vp
1877  specs[0][1]=58.5;// eplane, hp
1878  specs[0][2]=66;// hplane, vp
1879  specs[0][3]=57;// hplane, hp
1880 
1881  // these are for 600 MHz
1882  specs[1][0]=33.5;
1883  specs[1][1]=34.5;
1884  specs[1][2]=36.5;
1885  specs[1][3]=38;
1886 
1887  // 900 MHz
1888  specs[2][0]=50.5;
1889  specs[2][1]=53;
1890  specs[2][2]=33;
1891  specs[2][3]=32;
1892 
1893  // 1200 MHz
1894  specs[3][0]=43.5;
1895  specs[3][1]=43;
1896  specs[3][2]=39;
1897  specs[3][3]=41.5;
1898 
1899  //1500 MHz
1900  specs[4][0]=36.5;
1901  specs[4][1]=46.5;
1902  specs[4][2]=32;
1903  specs[4][3]=31;
1904  }
1905 
1906  // These are gains, which are not used because we use Ped's numbers instead
1907  double specs2[5][2];
1908 
1909  if (settings1->WHICH==7) {// EeVA
1910  // this is in dBi
1911  // 200 MHz
1912  specs2[0][0]=26.85; // vp
1913  specs2[0][1]=26.85; // hp
1914 
1915  // 355 MHz
1916  specs2[1][0]=35.8;
1917  specs2[1][1]=35.8;
1918 
1919  // 515 MHz
1920  specs2[2][0]=25.;
1921  specs2[2][1]=25.;
1922 
1923  // 785 MHz
1924  specs2[3][0]=10.5;
1925  specs2[3][1]=10.5;
1926 
1927 
1928  }
1929  else if (settings1->WHICH==11) { // satellite
1930 
1931  // this is in dBi
1932  // 40 MHz
1933  specs2[0][0]=7.5; // vp
1934  specs2[0][1]=7.5; // hp
1935  //specs2[0][0]=0.0; // vp
1936  //specs2[0][1]=0.0; // hp
1937 
1938  // MHz
1939  specs2[1][0]=6.5;
1940  specs2[1][1]=6.5;
1941  //specs2[1][0]=0.0;
1942  //specs2[1][1]=0.0;
1943 
1944  // MHz
1945  specs2[2][0]=6.5;
1946  specs2[2][1]=6.5;
1947  //specs2[2][0]=0.0;
1948  //specs2[2][1]=0.0;
1949 
1950  // MHz
1951  specs2[3][0]=5.5;
1952  specs2[3][1]=5.5;
1953  //specs2[3][0]=0.0;
1954  //specs2[3][1]=0.0;
1955 
1956 
1957 
1958 
1959  }
1960  else { // everything else
1961  // these are dimensionless gains
1962  // turn to dBi below
1963  // 300 MHz
1964  specs2[0][0]=8.5; // vp
1965  specs2[0][1]=8.8; // hp
1966 
1967  // 600 MHz
1968  specs2[1][0]=11.0;
1969  specs2[1][1]=9.2;
1970 
1971  // 900 MHz
1972  specs2[2][0]=9.3;
1973  specs2[2][1]=9.6;
1974 
1975  // 1200 MHz
1976  specs2[3][0]=10.1;
1977  specs2[3][1]=11.5;
1978 
1979  // 1500 MHz
1980  specs2[4][0]=8.9;
1981  specs2[4][1]=9.0;
1982 
1983  }
1984 
1985  // now convert to dimensionless units
1986  for (int i=0;i<4;i++) {
1987  for (int j=0;j<2;j++) {
1988  specs2[i][j]=pow(10.,specs2[i][j]/10.);
1989  }
1990  }
1991 
1992 
1993 
1994 
1995 
1996  double scale=0;
1997  // loop through frequency bins and fill the flare array
1998  for (int k=0;k<NFREQ;k++) {
1999  // if the frequency is below the lowest from the specs, just use the 300 MHz value
2000  if (freq[k]<freq_specs[0]) {
2001  for (int j=0;j<4;j++) {
2002  flare[j][k]=specs[0][j]*RADDEG;
2003  } //for
2004  } //if
2005  // if the frequency is higher than the highest frequency from the specs, just use the 1500 MHz value
2006  else if (freq[k]>=freq_specs[NFREQ_FORGAINS-1]) {
2007  for (int j=0;j<4;j++) {
2008  flare[j][k]=specs[NFREQ_FORGAINS-1][j]*RADDEG;
2009 
2010  } //for
2011  } //else if
2012  // if it is in between, interpolate
2013  else {
2014  for (int i=0;i<NFREQ_FORGAINS;i++) {
2015  if (freq[k]>=freq_specs[i] && freq[k]<freq_specs[i+1]) {
2016  scale = (freq[k]-freq_specs[i])/(freq_specs[i+1]-freq_specs[i]);
2017 
2018  for (int j=0;j<4;j++) {
2019  flare[j][k]=(specs[i][j]+scale*(specs[i+1][j]-specs[i][j]))*RADDEG;
2020 
2021  } //for
2022  i=NFREQ_FORGAINS;
2023  } //if
2024  } //for
2025  } //else
2026  } //for (frequencies)
2027 
2028  // loop through frequencies to fill the gain array
2029  for (int k=0;k<NFREQ;k++) {
2030  // if below 300 MHz, use the 300 MHz value
2031  if (freq[k]<freq_specs[0]) {
2032  for (int j=0;j<2;j++) {
2033  gain[j][k]=specs2[0][j];
2034  } //for
2035  } //if
2036  // if higher than 1500 MHz, use the 1500 MHz value
2037  else if (freq[k]>=freq_specs[NFREQ_FORGAINS-1]) {
2038  for (int j=0;j<2;j++) {
2039  gain[j][k]=specs2[NFREQ_FORGAINS-1][j];
2040  } //for
2041  } //else if
2042  // if in between, interpolate
2043  else {
2044  for (int i=0;i<NFREQ_FORGAINS;i++) {
2045  if (freq[k]>=freq_specs[i] && freq[k]<freq_specs[i+1]) {
2046  scale = (freq[k]-freq_specs[i])/(freq_specs[i+1]-freq_specs[i]);
2047 
2048  for (int j=0;j<2;j++) {
2049  gain[j][k]=specs2[i][j]+scale*(specs2[i+1][j]-specs2[i][j]);
2050 
2051  } //for
2052  i=NFREQ_FORGAINS;
2053  } //if
2054  } //for
2055  } //else
2056  } //for (frequencies)
2057 
2058  return 1;
2059 } //GetBeamWidths
2060 double Anita::Get_gain_angle(int gain_type, int k, double hitangle) {
2061  double scaleh1, scaleh2;
2062  if(gain_type < 0 || gain_type > 3) {
2063  cout << "gain_type out of range\n";
2064  exit(1);
2065  }
2066 
2067  hitangle = fabs(hitangle)*DEGRAD;
2068  flare[gain_type][k]=flare[gain_type][k]*DEGRAD;
2069  if(hitangle > 90.00001) {
2070  cout << "hitangle out of range\n";
2071  exit(1);
2072  }
2073  if(hitangle >= 90.) hitangle = 89.99999;
2074 
2075  // int pol;
2076  if (GAINS==0) {
2077  // for this simple model just treat the cross pols the same with regard to effect of being hit off-axis
2078  // the absolute gain will of course be different for these
2079  // pol=(int)((double)gain_type/2.);
2080 
2081  // cout << "gain_type, k, flare, gain are " << gain_type << " " << k << " " << flare[gain_type][k] << " " << gain[pol][k] << "\n";
2082  //cout << "hitangle, flare, factor are " << hitangle << " " << flare[gain_type][k] << " " << exp(-1.*(hitangle*hitangle)/(2*flare[gain_type][k]*flare[gain_type][k])) << "\n";
2083  return exp(-1.*(hitangle*hitangle)/(2*flare[gain_type][k]*flare[gain_type][k]));
2084  } else {
2085  for(int iii = 1; iii < 7; iii++) { // linear interpolation for the angle
2086  if(hitangle <= reference_angle[iii]) {
2087  scaleh2 = (hitangle - reference_angle[iii-1]) *
2088  inv_angle_bin_size[iii-1]; // how far from the smaller angle
2089  scaleh1 = 1. - scaleh2; // how far from the larger angle
2090 
2091  if(whichbin[k] == NPOINTS_GAIN - 1) // if the frequency is 1.5e9 or goes a little over due to rounding
2092  return scaleh1 * gain_angle[gain_type][whichbin[k]][iii-1] +
2093  scaleh2 * gain_angle[gain_type][whichbin[k]][iii];
2094 
2095  return scaleh1 * scalef1[k] * gain_angle[gain_type][whichbin[k]][iii-1] +
2096  scaleh1 * scalef2[k] * gain_angle[gain_type][whichbin[k]+1][iii-1] +
2097  scaleh2 * scalef1[k] * gain_angle[gain_type][whichbin[k]][iii] +
2098  scaleh2 * scalef2[k] * gain_angle[gain_type][whichbin[k]+1][iii];
2099 
2100  }
2101  }
2102  }
2103 
2104 
2105  cout << "Get_gain_angle should have returned a value\n";
2106  exit(1);
2107 } // double Get_gain_angle(int gain_type, double freq, double hitangle)
2108 
2109 
2110 void Anita::getDiodeModel( ) {
2111 
2112 
2113  // this is our homegrown diode response function which is a downgoing gaussian followed by an upward step function
2114  TF1 *fdown1=new TF1("fl_down1","[3]+[0]*exp(-1.*(x-[1])*(x-[1])/(2*[2]*[2]))",-300.E-9,300.E-9);
2115  fdown1->SetParameter(0,-0.8);
2116  // fdown1->SetParameter(1,15.E-9);
2117  fdown1->SetParameter(1,15.E-9);
2118  fdown1->SetParameter(2,2.3E-9);
2119  //fdown1->SetParameter(2,0.5E-9);
2120  fdown1->SetParameter(3,0.);
2121 
2122  TF1 *fdown2=new TF1("fl_down2","[3]+[0]*exp(-1.*(x-[1])*(x-[1])/(2*[2]*[2]))",-300.E-9,300.E-9);
2123  fdown2->SetParameter(0,-0.2);
2124  // fdown2->SetParameter(1,15.E-9);
2125  fdown2->SetParameter(1,15.E-9);
2126  fdown2->SetParameter(2,4.0E-9);
2127  //fdown2->SetParameter(2,0.5E-9);
2128  fdown2->SetParameter(3,0.);
2129 
2130 
2131  maxt_diode=70.E-9;
2132  idelaybeforepeak[0]=(int)(5.E-9/TIMESTEP);
2133  iwindow[0]=(int)(20.E-9/TIMESTEP);
2134  idelaybeforepeak[1]=(int)(5.E-9/TIMESTEP);
2135  iwindow[1]=(int)(20.E-9/TIMESTEP);
2136  idelaybeforepeak[2]=(int)(5.E-9/TIMESTEP);
2137  iwindow[2]=(int)(20.E-9/TIMESTEP);
2138  idelaybeforepeak[3]=(int)(5.E-9/TIMESTEP);
2139  iwindow[3]=(int)(20.E-9/TIMESTEP);
2140  idelaybeforepeak[4]=(int)(13.E-9/TIMESTEP);
2141  iwindow[4]=(int)(4.E-9/TIMESTEP);
2142 
2143 
2144  fdown1->Copy(fdiode);
2145 
2146  TF1 *f_up=new TF1("f_up","[0]*([3]*(x-[1]))^2*exp(-(x-[1])/[2])",-200.E-9,100.E-9);
2147 
2148  f_up->SetParameter(2,7.0E-9);
2149  f_up->SetParameter(0,1.);
2150  f_up->SetParameter(1,18.E-9);
2151  f_up->SetParameter(3,1.E9);
2152 
2153  f_up->SetParameter(0,-1.*sqrt(2.*PI)*(fdiode.GetParameter(0)*fdiode.GetParameter(2)+fdown2->GetParameter(0)*fdown2->GetParameter(2))/(2.*pow(f_up->GetParameter(2),3.)*1.E18));
2154 
2155  double sum=0.;
2156  for (int j=0;j<5;j++) {
2157 
2158  if (j==0)
2159  f_up->SetParameter(0,0.00275);
2160  else if (j==1)
2161  f_up->SetParameter(0,0.004544);
2162  else
2163  f_up->SetParameter(0,-1.*sqrt(2.*PI)*(fdiode.GetParameter(0)*fdiode.GetParameter(2)+fdown2->GetParameter(0)*fdown2->GetParameter(2))/(2.*pow(f_up->GetParameter(2),3.)*1.E18));
2164 
2165  for (int i=0;i<NFOUR/2;i++) {
2166 
2167  if (time[i]>0. && time[i]<maxt_diode) {
2168 
2169  diode_real[j][i]=fdiode.Eval(time[i])+fdown2->Eval(time[i]);
2170  if (time[i]>f_up->GetParameter(1))
2171  diode_real[j][i]+=f_up->Eval(time[i]);
2172 
2173  sum+=diode_real[j][i];
2174  }
2175  else {
2176  diode_real[j][i]=0.;
2177  //cout << "diode: " << time[i] << " " << diode_real[i] << "\n";
2178  }
2179  }
2180  }
2181 
2182 
2183  // diode_real is the time domain response of the diode
2184 }
2185 
2186 void Anita::myconvlv(double *data,const int NFOUR,double *fdiode,double &mindiodeconvl,double &onediodeconvl,double *power_noise,double *diodeconv) {
2187 
2188  // NFOUR is the size array of fdiode_real, while data is NFOUR/2 sized array.
2189  // so we are going to make data array to NFOUR sized array with zero padding (see Numerical Recipes 3rd ED, 643 page)
2190  // We are actually using NFOUR/2 array for zero padding which might be too long in terms of efficiency but it's a simple way.
2191  // Returned diodeconv array is NFOUR sized array but actually initial NFOUR/2 is the information what we need
2192  // Last half NFOUR/2 array of diodeconv is result from zero padding and some spoiled information.
2193 
2194  const int length=NFOUR;
2195  // double data_copy[length];
2196  //double fdiode_real[length];
2197  double power_noise_copy[length];
2198 
2199 
2200  for (int i=0;i<NFOUR/2;i++) {
2201  power_noise_copy[i]=(data[i]*data[i])/impedence*TIMESTEP;
2202  }
2203  for (int i=NFOUR/2;i<NFOUR;i++) {
2204  power_noise_copy[i]=0.;
2205  }
2206 
2207 
2208  // TCanvas *c = new TCanvas("c");
2209  // string name = "oldnoise";
2210  // TGraph *gV = new TGraph(HALFNFOUR, fTimes, power_noise_copy);
2211  // gV->Draw("Al");
2212  // c->Print(Form("%s_%d_diodePower.png", name.c_str(), inu));
2213  // delete gV;
2214  // delete c;
2215 
2216  Tools::realft(power_noise_copy,1,length);
2217  // realft(fdiode_real,1,length);
2218 
2219  double ans_copy[length];
2220 
2221 
2222 
2223  // the +, - sign in the equation might look different then Numerical Recipes 3rd ED 649 page.
2224  // our equation (below) is the situation when power_noise_copy's 0th bin starts to meet fdiode's 0th bin
2225  // while code in Numerical Recipes 649 page is the situation when power_noise_copy's final bin starts to meet fdiode's 0th bin
2226  // so, in our case, below equation is correct.
2227  for (int j=1;j<length/2;j++) {
2228  ans_copy[2*j]=(power_noise_copy[2*j]*fdiode[2*j]-power_noise_copy[2*j+1]*fdiode[2*j+1])/((double)length/2);
2229  ans_copy[2*j+1]=(power_noise_copy[2*j+1]*fdiode[2*j]+power_noise_copy[2*j]*fdiode[2*j+1])/((double)length/2);
2230  }
2231  ans_copy[0]=power_noise_copy[0]*fdiode[0]/((double)length/2);
2232  ans_copy[1]=power_noise_copy[1]*fdiode[1]/((double)length/2);
2233 
2234 
2235 
2236  Tools::realft(ans_copy,-1,length);
2237 
2238 
2239  // even if there are NFOUR array in diodeconv, only first NFOUR/2 is meaningful for us.
2240  for (int i=0;i<NFOUR;i++) {
2241  power_noise[i]=power_noise_copy[i];
2242  diodeconv[i]=ans_copy[i];
2243  }
2244 
2245 
2246 
2247  int iminsamp,imaxsamp; // find min and max samples such that
2248  // the diode response is fully overlapping with the noise waveform
2249  iminsamp=(int)(maxt_diode/TIMESTEP);
2250  // the noise waveform is NFOUR/2 long
2251  // then for a time maxt_diode/TIMESTEP at the end of that, the
2252  // diode response function is only partially overlappying with the
2253  // waveform in the convolution
2254  imaxsamp=NFOUR/2;
2255 
2256  // cout << "iminsamp, imaxsamp are " << iminsamp << " " << imaxsamp << "\n";
2257  if (imaxsamp<iminsamp) {
2258  cout << "Noise waveform is not long enough for this diode response.\n";
2259  exit(1);
2260  }
2261 
2262  int ibin=((iminsamp+imaxsamp)-(iminsamp+imaxsamp)%2)/2;
2263  //cout << "ibin is " << ibin << "\n";
2264 
2265  // return the 50th sample, right in the middle
2266  onediodeconvl=diodeconv[ibin];
2267 
2268 
2269  mindiodeconvl=0.;
2270 
2271  for (int i=iminsamp;i<imaxsamp;i++) {
2272 
2273  if (diodeconv[i]<mindiodeconvl)
2274  mindiodeconvl=diodeconv[i];
2275 
2276 
2277  }
2278 
2279 
2280 
2281 
2282 
2283 
2284 }
2285 
2286 
2287 
2288 
2289 
2290 
2291 
2292 // get the frequency bin for a given frequency, the lower and upper limits and the
2293 // number of bins
2294 
2295 void Anita::GetPhases() {
2296 
2297  int iband;
2298  double corr,uncorr;
2299  double phase_corr,phase_uncorr;
2300  double phasor_x,phasor_y;
2301  TRandom * rng = getRNG(RNG_PHASES);
2302 
2303  for (int k=0;k<NFOUR/4;k++) { // loop through samples
2304  iband=Tools::findIndex(freq_bands[0],freq_forfft[2*k],NPOINTS_BANDS,freq_bands[0][0],freq_bands[0][NPOINTS_BANDS-1]);
2305 
2306 
2307  phases_rfcm[0][k]=2*PI*rng->Rndm(); // set phases at output of rfcm randoml
2308  phases_rfcm[1][k]=2*PI*rng->Rndm(); // set phases at output of rfcm randomly
2309 
2310 
2311  // now set phases at the lab chip
2312 
2313  if(iband < 0) corr = 0;
2314  else corr=correl_lab[iband];
2315  uncorr=1-corr;
2316  phase_corr=phases_rfcm[0][k];
2317  phase_uncorr=2*PI*rng->Rndm();
2318  phasor_x=corr*cos(phase_corr)+uncorr*cos(phase_uncorr);
2319  phasor_y=corr*sin(phase_corr)+uncorr*sin(phase_uncorr);
2320  phases_lab[0][k]=TMath::ATan2(phasor_y,phasor_x);
2321 
2322 
2323 
2324  phase_corr=phases_rfcm[1][k];
2325  phase_uncorr=2*PI*rng->Rndm();
2326  phasor_x=corr*cos(phase_corr)+uncorr*cos(phase_uncorr);
2327  phasor_y=corr*sin(phase_corr)+uncorr*sin(phase_uncorr);
2328  phases_lab[1][k]=TMath::ATan2(phasor_y,phasor_x);
2329 
2330 
2331  // do the same thing for the bands
2332  for (int j=0;j<5;j++) {
2333 
2334  if(iband < 0) corr = 0;
2335  else corr=correl_banding[j][iband];
2336  uncorr=1-corr;
2337  phase_corr=phases_rfcm[0][k];
2338  phase_uncorr=2*PI*rng->Rndm();
2339  phasor_x=corr*cos(phase_corr)+uncorr*cos(phase_uncorr);
2340  phasor_y=corr*sin(phase_corr)+uncorr*sin(phase_uncorr);
2341  phases_rfcm_banding[0][j][k]=TMath::ATan2(phasor_y,phasor_x);
2342  phase_corr=phases_rfcm[1][k];
2343  phase_uncorr=2*PI*rng->Rndm();
2344  phasor_x=corr*cos(phase_corr)+uncorr*cos(phase_uncorr);
2345  phasor_y=corr*sin(phase_corr)+uncorr*sin(phase_uncorr);
2346  phases_rfcm_banding[1][j][k]=TMath::ATan2(phasor_y,phasor_x);
2347 
2348  }
2349  }
2350 
2351 
2352 
2353 
2354 }
2355 
2356 void Anita::normalize_for_nsamples(double *spectrum, double nsamples, double nsamp){
2357  for (int k = 0; k < NFOUR / 4; k++){
2358  spectrum[2 * k] *= sqrt((double) nsamples / (double) nsamp);
2359  spectrum[2 * k + 1] *= sqrt((double) nsamples / (double) nsamp);
2360  }
2361  return;
2362 }
2363 
2364 void Anita::convert_power_spectrum_to_voltage_spectrum_for_fft(int length,double *spectrum, double domain[], double phase[]){
2365  double current_amplitude, current_phase;
2366  // for (int k = 0; k < NFOUR / 4; k++){
2367  for (int k = 0; k < length/2 ; k++){
2368  current_amplitude = domain[k];
2369  current_phase = phase[k];
2370 
2371  // Uncomment the following line of code to allow the the noise generated to have a Rician/Rayleigh distribution, which should increase the number of weighted neutrinos that pass *slightly*.
2372  Tools::get_random_rician(0., 0., sqrt(2. / M_PI) * domain[k], current_amplitude, current_phase);
2373  // The above function uses 0. as the mean of the rician distribution, and uses sqrt(2. / M_PI) * domain[k] as the standard deviation for the distribution, as discussed in Goodman's "Statistical Optics", equation 2.9-13 on page 49
2374 
2375  spectrum[2 * k] = sqrt(current_amplitude) * cos(phase[k]) / (( (double) NFOUR / 2) / 2);
2376  spectrum[2 * k + 1] = sqrt(current_amplitude) * sin(phase[k]) / (( (double) NFOUR / 2) / 2);
2377  }
2378  return;
2379 }
2380 
2381 void Anita::GetNoiseWaveforms() {
2382  GetPhases();
2383  int nsamples = NFOUR / 2;
2384  // int nsamples_long = NFOUR;
2385  double sumfreqdomain = 0.;
2386  double sumtimedomain = 0.;
2387 
2388  count_getnoisewaveforms++;
2389 
2390 
2391  // This is done in a stupid way for the moment to provide the same order of gRandom calls
2392  // So that I have the exact same results as masters
2393  // This should be done in 1 loop once I merge the trigger branch with master
2394  // LC, 16/02/17
2395 
2396 
2397  for (int ipol=0;ipol<2;ipol++)
2398  convert_power_spectrum_to_voltage_spectrum_for_fft(nsamples, timedomainnoise_rfcm[ipol], freqdomain_rfcm, phases_rfcm[ipol] );
2399  for (int ipol=0;ipol<2;ipol++)
2400  convert_power_spectrum_to_voltage_spectrum_for_fft(nsamples, timedomainnoise_lab[ipol], avgfreqdomain_lab, phases_lab[ipol] );
2401 
2402  // convert_power_spectrum_to_voltage_spectrum_for_fft(nsamples_long, timedomainnoise_rfcm_long[ipol], freqdomain_rfcm_long, phases_rfcm_long[ipol] );
2403  // convert_power_spectrum_to_voltage_spectrum_for_fft(nsamples_long, timedomainnoise_lab_long[ipol], avgfreqdomain_lab_long, phases_lab_long[ipol] );
2404 
2405  // want to restrict it to NFOUR/2 samples -# samples that equal twice
2406  // maxt_diode
2407  // freqdomain_rfcm_banding was made by averaging many nsamp=100-sample noise waveforms in the
2408  // frequency domain
2409  // the noise waveform that we create from it has NFOUR/2 samples
2410  // I don't know how to restrict it to nsamp=100 samples.
2411  // So in order to restrict the power to nsamp=100 samples we zero
2412  // everything but the middle nsamp samples and scale the waveforms
2413  // by sqrt((NFOUR/2)/nsamp)
2414 
2415  for (int ipol=0;ipol<2;ipol++){
2416  normalize_for_nsamples(timedomainnoise_rfcm[ipol], (double) nsamples, (double) nsamp);
2417  normalize_for_nsamples(timedomainnoise_lab[ipol], (double) nsamples, (double) nsamp);
2418 
2419  // normalize_for_nsamples(timedomainnoise_rfcm_long[ipol], (double) nsamples_long, (double) nsamp);
2420  // normalize_for_nsamples(timedomainnoise_lab_long[ipol], (double) nsamples_long, (double) nsamp);
2421 
2422  for (int k = 0; k < NFOUR / 4; k++){
2423  sumfreqdomain += avgfreqdomain_lab[k];
2424  }
2425 
2426  Tools::realft(timedomainnoise_rfcm[ipol], -1, NFOUR / 2);
2427  Tools::realft(timedomainnoise_lab[ipol], -1, NFOUR / 2);
2428 
2429  // Tools::realft(timedomainnoise_rfcm_long[ipol], -1, NFOUR );
2430  // Tools::realft(timedomainnoise_lab_long[ipol],-1, NFOUR );
2431 
2432  for (int k = 0; k < NFOUR / 2; k++) {
2433  timedomainnoise_lab[ipol][k] *=THERMALNOISE_FACTOR;
2434  timedomainnoise_rfcm[ipol][k]*=THERMALNOISE_FACTOR;
2435 
2436  if (ipol==0){
2437  sumtimedomain += timedomainnoise_lab[ipol][k] * timedomainnoise_lab[ipol][k];
2438  rms_rfcm_e_single_event += timedomainnoise_rfcm[ipol][k] * timedomainnoise_rfcm[ipol][k];
2439  }
2440  rms_rfcm[ipol] += timedomainnoise_rfcm[ipol][k] * timedomainnoise_rfcm[ipol][k] / ((double) NFOUR / 2);
2441  rms_lab[ipol] += timedomainnoise_lab[ipol][k] * timedomainnoise_lab[ipol][k] / ((double) NFOUR / 2);
2442 
2443  }
2444 
2445  }
2446 
2447  for (int iband=0; iband<5; iband++) {
2448  for (int ipol=0;ipol<2;ipol++)
2449  convert_power_spectrum_to_voltage_spectrum_for_fft(NFOUR/2,timedomainnoise_rfcm_banding[ipol][iband], freqdomain_rfcm_banding[iband], phases_rfcm_banding[ipol][iband]);
2450  for (int ipol=0;ipol<2;ipol++)
2451  normalize_for_nsamples(timedomainnoise_rfcm_banding[ipol][iband], (double) nsamples, (double) nsamp);
2452  for (int ipol=0;ipol<2;ipol++)
2453  Tools::realft(timedomainnoise_rfcm_banding[ipol][iband], -1, NFOUR / 2);
2454 
2455  // convert_power_spectrum_to_voltage_spectrum_for_fft(NFOUR,timedomainnoise_rfcm_banding_long[ipol][iband], freqdomain_rfcm_banding_long[iband], phases_rfcm_banding_e_long[iband]);
2456  // normalize_for_nsamples(timedomainnoise_rfcm_banding_long[ipol][iband], (double) nsamples_long, (double) nsamp);
2457  // Tools::realft(timedomainnoise_rfcm_banding_long[ipol][iband], -1, NFOUR);
2458 
2459 
2460 
2461  }
2462 }
2463 
2464 void Anita::GetArrayFromFFT(double *tmp_fftvhz, double *vhz_rx){
2465 
2466  int firstNonZero = Tools::Getifreq(freq[0],freq_forfft[0],freq_forfft[NFOUR/2-1],NFOUR/4);
2467  int lastNonZero = Tools::Getifreq(freq[NFREQ-1],freq_forfft[0],freq_forfft[NFOUR/2-1],NFOUR/4);
2468  double norm=TMath::Sqrt(double(lastNonZero-firstNonZero)/double(NFREQ));
2469  // cout << firstNonZero << " " << lastNonZero << " " << lastNonZero-firstNonZero << " " << norm << endl;
2470 
2471  for (int ifreq=0;ifreq<NFOUR/4;ifreq++){
2472  tmp_fftvhz[ifreq]=TMath::Sqrt(tmp_fftvhz[2*ifreq]*tmp_fftvhz[2*ifreq] + tmp_fftvhz[2*ifreq+1]*tmp_fftvhz[2*ifreq+1]);
2473  }
2474 
2475  for (int ifreq=0; ifreq<NFREQ; ifreq++){
2476 
2477  int ifour=Tools::Getifreq(freq[ifreq],freq_forfft[0],freq_forfft[NFOUR/2-1],NFOUR/4);
2478  vhz_rx[ifreq]=tmp_fftvhz[ifour]*norm;
2479  //cout << ifour << " " << freq[ifreq] << " " << vhz_rx[ifreq] << " " << endl;
2480  }
2481 
2482 }
2483 
2484 
2485 void Anita::GetPhasesFromFFT(double *tmp_fftvhz, double *phases){
2486 
2487  for (int ifreq=0; ifreq<NFOUR/4; ifreq++){
2488  phases[ifreq]=TMath::ATan2(tmp_fftvhz[ifreq+1], tmp_fftvhz[ifreq])*180./PI;
2489  }
2490 
2491 }
2492 
2493 
2494 void Anita::FromTimeDomainToIcemcArray(double *vsignalarray, double vhz[NFREQ]){
2495 
2496  // find the frequency domain
2497  Tools::realft(vsignalarray,1,NFOUR/2);
2498 
2499  GetPhasesFromFFT(vsignalarray, v_phases);
2500 
2501  //convert the V pol time waveform into frequency amplitudes
2502  GetArrayFromFFT(vsignalarray, vhz);
2503 
2504 
2505 
2506 }
2507 
2508 void Anita::MakeArrayforFFT(double *vsignalarray_e,double *vsignal_e_forfft, double phasedelay, bool useconstantdelay) {
2509 
2510  Tools::Zero(vsignal_e_forfft,NFOUR/2);
2511 
2512  double previous_value_e_even=0.;
2513  double previous_value_e_odd=0.;
2514  int count_nonzero=0;
2515  int iprevious=0;
2516  int ifirstnonzero=-1;
2517  int ilastnonzero=2000;
2518  for (int i=0;i<NFREQ;i++) {
2519  // freq_forfft has NFOUR/2 elements because it is meant to cover real and imaginary values
2520  // but there are only NFOUR/4 different values
2521  // it's the index among the NFOUR/4 that we're interested in
2522  int ifour=Tools::Getifreq(freq[i],freq_forfft[0],freq_forfft[NFOUR/2-1],NFOUR/4);
2523 
2524  if (ifour!=-1 && 2*ifour+1<NFOUR/2) {
2525  count_nonzero++;
2526  if (ifirstnonzero==-1){
2527  ifirstnonzero=ifour;
2528  }
2529 
2530  vsignal_e_forfft[2*ifour]=vsignalarray_e[i]*2/((double)NFOUR/2); // phases is 90 deg.
2531 
2532  // cout << "ifour, vsignal is " << ifour << " " << vsignal_e_forfft[2*ifour] << "\n";
2533 
2534  vsignal_e_forfft[2*ifour+1]=vsignalarray_e[i]*2/((double)NFOUR/2); // phase is 90 deg.
2535  // the 2/(nfour/2) needs to be included since were using Tools::realft with the -1 setting
2536 
2537  // the 2/(nfour/2) needs to be included since were using Tools::realft with the -1 setting
2538  // how about we interpolate instead of doing a box average
2539 
2540  for (int j=iprevious+1;j<ifour;j++) {
2541  vsignal_e_forfft[2*j]=previous_value_e_even+(vsignal_e_forfft[2*ifour]-previous_value_e_even)*(double)(j-iprevious)/(double)(ifour-iprevious);
2542  // cout << "j, vsignal is " << j << " " << vsignal_e_forfft[2*j] << "\n";
2543 
2544  vsignal_e_forfft[2*j+1]=previous_value_e_odd+(vsignal_e_forfft[2*ifour+1]-previous_value_e_odd)*(double)(j-iprevious)/(double)(ifour-iprevious);
2545  }
2546 
2547  ilastnonzero=ifour;
2548  iprevious=ifour;
2549  previous_value_e_even=vsignal_e_forfft[2*ifour];
2550  previous_value_e_odd=vsignal_e_forfft[2*ifour+1];
2551  }
2552 
2553  } // end loop over nfreq
2554 
2555  // EH check
2556  // cout << "ifirstnonzero, ilastnonzero are " << ifirstnonzero << " " << ilastnonzero << "\n";
2557  // cout << "ratio is " << (double)count_nonzero/(double)(ilastnonzero-ifirstnonzero) << "\n";
2558  for (int j=0;j<NFOUR/4;j++) {
2559  vsignal_e_forfft[2*j]*=sqrt((double)count_nonzero/(double)(ilastnonzero-ifirstnonzero));
2560  vsignal_e_forfft[2*j+1]*=sqrt((double)count_nonzero/(double)(ilastnonzero-ifirstnonzero));
2561  }
2562 
2563  // Tools::InterpolateComplex(vsignal_e_forfft,NFOUR/4);
2564 
2565  if (useconstantdelay){
2566  double cosphase=cos(phasedelay*PI/180.);
2567  double sinphase=sin(phasedelay*PI/180.);
2568  for (int ifour=0;ifour<NFOUR/4;ifour++) {
2569  if (USEPHASES) {
2570  cosphase = cos(v_phases[ifour]*PI/180.);
2571  sinphase = sin(v_phases[ifour]*PI/180.);
2572  }
2573  vsignal_e_forfft[2*ifour]*=cosphase;
2574  vsignal_e_forfft[2*ifour+1]*=sinphase;
2575  }
2576  }
2577 }
2578 
2579 
2580 void Anita::BoxAverageComplex(double *array, const int n,int navg) {
2581  // to get rid of the zero bins
2582  double array_temp[2*n];
2583  for (int i=0;i<n;i++) {
2584 
2585  array_temp[2*i]=0.;
2586  array_temp[2*i+1]=0.;
2587 
2588 
2589  for (int k=i;k<i+navg;k++) {
2590  if (k<n) {
2591  array_temp[2*i]+=array[2*k];
2592  array_temp[2*i+1]+=array[2*k+1];
2593  }
2594  }
2595 
2596  array[2*i]=array_temp[2*i]/(double)navg;
2597  array[2*i+1]=array_temp[2*i+1]/(double)navg;
2598 
2599  array_temp[2*i]=array[2*i];
2600  array_temp[2*i+1]=array[2*i+1];
2601 
2602  }
2603 }
2604 void Anita::BoxAverage(double *array, const int n,int navg) {
2605  // to get rid of the zero bins
2606  double array_temp[n];
2607  for (int i=0;i<n;i++) {
2608 
2609  array_temp[i]=0.;
2610 
2611  for (int k=i;k<i+navg;k++) {
2612  if (k<n) {
2613  array_temp[i]+=array[k];
2614  }
2615  }
2616 
2617  array[i]=array_temp[i]/(double)navg;
2618 
2619 
2620  array_temp[i]=array[i];
2621 
2622  }
2623 }
2624 
2625 
2626 void Anita::labAttn(double *vhz) {
2627  for (int i=0;i<NFREQ;i++) {
2628  // next find the index of the lab attenuation array
2629  int ilab=Tools::findIndex(freqlab,freq[i],NPOINTS_LAB,freqlab[0],freqlab[NPOINTS_LAB-1]);
2630  if (ilab!=-1) {
2631  vhz[i]*=sqrt(labattn[ilab]);
2632  vhz[i]*=sqrt(labattn[ilab]);
2633  }
2634  else
2635  cout << "Lab attenuation outside of band.\n";
2636  }
2637 }
2638 
2639 int Anita::getLabAttn(int NPOINTS_LAB,double *freqlab,double *labattn) {
2640 
2641  ifstream flab((ICEMC_DATA_DIR+"/surfatten_run294_ch23v.dat").c_str());
2642  if (flab.fail()) {
2643  cout << "Cannot open lab data file.\n";
2644  exit(1);
2645  }
2646  int index=0;
2647 
2648  string line;
2649  getline(flab,line); // first two lines are junk
2650  getline(flab,line);
2651 
2652  float ffreqlab,flabattn;
2653 
2654  // read in the rest of the lab data from a file
2655  while (!flab.eof() && index<NPOINTS_LAB) {
2656 
2657  flab >> ffreqlab >> flabattn;
2658  labattn[index]=(double)pow(10.,flabattn/10.);
2659  //cout << "Mofifying labattn!\n";
2660  //labattn[index]*=2.;
2661 
2662  freqlab[index]=(double)ffreqlab;
2663 
2664  index++;
2665 
2666  }
2667 
2668 
2669  flab.close();
2670 
2671  return 1;
2672 
2673 }
2674 
2675 
2676 double Anita::GaintoHeight(double gain,double freq,double nmedium_receiver) {
2677 
2678  // from gain=4*pi*A_eff/lambda^2
2679  // and h_eff=2*sqrt(A_eff*Z_rx/Z_air)
2680  // gain is in dB
2681  return 2*sqrt(gain/4/PI*CLIGHT*CLIGHT/(freq*freq)*Zr/(Z0*nmedium_receiver));
2682 } //GaintoHeight
2683 
2684 
2685 void Anita::fill_coherent_waveform_sum_tree(unsigned event_number, unsigned center_phi_sector_index, Settings* settings1, double rms_noise, double actual_rms, unsigned window_start, unsigned window_end, double deg_theta, double deg_phi, double actual_deg_theta, double actual_deg_phi, vector <double>& summed_wfm, vector <double>& power_of_summed_wfm, double power){
2686 
2687  cwst_event_number = event_number;
2688  cwst_center_phi_sector = center_phi_sector_index;
2689  cwst_rms_noise = rms_noise;
2690  cwst_actual_rms = actual_rms;
2691  cwst_threshold = settings1->COHERENT_THRESHOLD;
2692  cwst_window_start = window_start;
2693  cwst_window_end = window_end;
2694 
2695  cwst_deg_theta = deg_theta;
2696  cwst_deg_phi = deg_phi;
2697 
2698  cwst_actual_deg_theta = actual_deg_theta;
2699  cwst_actual_deg_phi = actual_deg_phi;
2700 
2701  // Reassign the array associated with the timesteps branch
2702  for (int i = 0; i < HALFNFOUR; i++){
2703  cwst_timesteps[i] = i;
2704  }
2705 
2706  cwst_summed_wfm = summed_wfm;
2707  cwst_power_of_summed_wfm = power_of_summed_wfm;
2708  cwst_power = power;
2709 
2710  coherent_waveform_sum_tree->Fill();
2711 
2712  return;
2713 }
2714 
2715 void Anita::GetPayload(Settings* settings1, Balloon* bn1){
2716  // anita-lite payload
2717  // see comments next to variable definitions
2718  double temp_eachrx[Anita::NPHI_MAX]; // temperature of each antenna (for the anita-lite configuration)
2719 
2720  const double gps_offset = atan2(-0.7042,0.71), MINCH = 0.0254, phase_center = 0.17;
2721  // const double phase_center_anita2=0.17;
2722  const double phase_center_anita2_analysis=.2;
2723  //const double gps_offset_anita2=atan2(0.89,-0.29);
2724  const double gps_offset_anita2=atan2(-0.7085,0.7056); // from elog 473
2725  const double gps_offset_anita3= 45*RADDEG; // Linda: 45 degrees from EventReader
2726  const double phase_center_anita3=0.20; // Linda: phase-centers are around 20 cm inwards of antennas face-end
2727 
2728 
2729  if (settings1->WHICH==0) { // anita-lite
2730 
2731  settings1->NFOLD=3;
2732 
2733  settings1->CYLINDRICALSYMMETRY=0;
2734  PHI_EACHLAYER[0][0]=0.;
2735  PHI_EACHLAYER[0][1]=22.5*RADDEG;
2736  NRX_PHI[0]=2;
2737  PHI_OFFSET[0]=0;
2738  THETA_ZENITH[0]=PI/2+10.*RADDEG;
2739  LAYER_VPOSITION[0]=0.; // vertical separation between layers
2740  LAYER_HPOSITION[0]=0.; // position of layer relative to center axis in horizontal plane
2741  LAYER_PHIPOSITION[0]=0.; // phi of position of layer
2742 
2743  for (int i=0;i<5;i++) {
2744  RRX[i]=3.006;
2745  }
2746 
2747  for (int i=0;i<NRX_PHI[0];i++) {
2748  VNOISE_ANITALITE[i]=ChanTrigger::GetNoise(settings1,bn1->altitude_bn,bn1->surface_under_balloon,THETA_ZENITH[i],settings1->BW_SEAVEYS,temp_eachrx[i]);
2749  }
2750  } //if (ANITA-lite)
2751 
2752  //Ross Payload
2753  else if (settings1->WHICH==1) {
2754  //settings1->NFOLD=8;
2755  settings1->CYLINDRICALSYMMETRY=1;
2756 
2757  NRX_PHI[0]=5;
2758  NRX_PHI[1]=5;
2759  NRX_PHI[2]=5;
2760  NRX_PHI[3]=5;
2761  NRX_PHI[4]=4;
2762 
2763  PHI_OFFSET[0]=0;
2764  PHI_OFFSET[1]=2*PI/(double)NRX_PHI[1]/2;
2765  PHI_OFFSET[2]=0;
2766  PHI_OFFSET[3]=2*PI/(double)NRX_PHI[3]/2;
2767  PHI_OFFSET[4]=0;
2768 
2769  THETA_ZENITH[0]=PI/2+10.*RADDEG;
2770  THETA_ZENITH[1]=PI/2+10.*RADDEG;
2771  THETA_ZENITH[2]=PI/2+10.*RADDEG;
2772  THETA_ZENITH[3]=PI/2+10.*RADDEG;
2773  THETA_ZENITH[4]=3*PI/4;
2774 
2775  // anita proposal "says that the separation between upper and lower
2776  // 2 layers of antennas is just under 4m.
2777  LAYER_VPOSITION[0]=3.5;
2778  LAYER_VPOSITION[1]=2.0;
2779  LAYER_VPOSITION[2]=-0.5;
2780  LAYER_VPOSITION[3]=-2.0;
2781  LAYER_VPOSITION[4]=-3.5;
2782 
2783  LAYER_HPOSITION[0]=0.;
2784  LAYER_HPOSITION[1]=0.;
2785  LAYER_HPOSITION[2]=0.;
2786  LAYER_HPOSITION[3]=0.;
2787  LAYER_HPOSITION[4]=0.;
2788 
2789  LAYER_PHIPOSITION[0]=0.;
2790  LAYER_PHIPOSITION[1]=0.;
2791  LAYER_PHIPOSITION[2]=0.;
2792  LAYER_PHIPOSITION[3]=0.;
2793  LAYER_PHIPOSITION[4]=0.;
2794 
2795  // position of layers in z relative to vertical center of the payload
2796  // radius that antennas sit at on the payload
2797  for (int i=0;i<5;i++) {
2798  RRX[i]=0.5;
2799  }
2800 
2801  } //else if (Ross payload)
2802  // Smex payload (full ANITA flown 2006-2007)
2803  else if (settings1->WHICH==2) {
2804  settings1->CYLINDRICALSYMMETRY=1;
2805 
2806  //these are physical layers
2807  NRX_PHI[0]=8;
2808  NRX_PHI[1]=8;
2809  NRX_PHI[2]=16;
2810  NRX_PHI[3]=8;
2811 
2812  PHITRIG[0]=16; // number of positions in phi in each *trigger* layer
2813  PHITRIG[1]=16;
2814  PHITRIG[2]=8;
2815 
2816  //these are physical layers again
2817  PHI_OFFSET[0]=0.; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
2818  // it's rotated by 1/2 the azimuth that separates two antennas on the 0th layer
2819  PHI_OFFSET[1]=-2.*PI/(double)NRX_PHI[0]/2.;
2820  PHI_OFFSET[2]=-2.*PI/(double)NRX_PHI[0]/2.;
2821  PHI_OFFSET[3]=-2.*PI/(double)NRX_PHI[0]/4.;
2822 
2823  //double INCLINE_NADIR=55; // this is set in the input file now EWG: so why not remove it?
2824 
2825  // sets their declination
2826  THETA_ZENITH[0]=PI/2+INCLINE_TOPTHREE*RADDEG;
2827  THETA_ZENITH[1]=PI/2+INCLINE_TOPTHREE*RADDEG;
2828  THETA_ZENITH[2]=PI/2+INCLINE_TOPTHREE*RADDEG;
2829  THETA_ZENITH[3]=PI/2+INCLINE_NADIR*RADDEG;
2830 
2831  // radius from center axis of the payload
2832  RRX[0] = 0.9210802;
2833  RRX[1] = 0.7553198;
2834  RRX[2] = 2.0645374;
2835  RRX[3]=1.40; // this is wrong, but I put this version of icemc here just to show one possible strategy to use V polarization and nadirs so it doesn't matter
2836 
2837  // vertical separation between layers.
2838  LAYER_VPOSITION[0]=0;
2839  LAYER_VPOSITION[1] = -0.9670034;
2840  LAYER_VPOSITION[2] = -3.730752;
2841  LAYER_VPOSITION[3]=(-3.175-0.948-0.889); // this is wrong too, but nadirs are probably gone so doesn't matter.
2842 
2843  LAYER_HPOSITION[0]=0.;
2844  LAYER_HPOSITION[1] = 0.;
2845  LAYER_HPOSITION[2] = 0.;
2846  LAYER_HPOSITION[3]=0.; // this is wrong too, but nadirs are probably gone so doesn't matter.
2847 
2848 
2849  } //else if (SMEX payload - default)
2850  else if (settings1->WHICH==3) {
2851 
2852  cout << "Is this configuration cylindrically symmetric? Yes(1) or No(0)\n";
2853  cin >> settings1->CYLINDRICALSYMMETRY;
2854 
2855  cout << "How many layers?\n";
2856  cin >> settings1->NLAYERS;
2857 
2858  for (int i=0;i<settings1->NLAYERS;i++) {
2859 
2860  cout << "How many antennas in the " << i << "th layer?\n";
2861  cin >> NRX_PHI[i];
2862 
2863  cout << "What is the offset in phi for the " << i << "th layer?\n";
2864  cin >> PHI_OFFSET[i];
2865 
2866  cout << "What is the theta ascent for the " << i << "th layer (0 if pointed straight upwards, PI if pointed straight downwards)?\n";
2867  cin >> THETA_ZENITH[i];
2868 
2869  cout << "What is the vertical position of this layer relative to the vertical center of the payload?";
2870  cin >> LAYER_VPOSITION[i];
2871 
2872  cout << "What is the distance between of the vertical axis of the payload and the center of this layer?";
2873  cin >> LAYER_HPOSITION[i];
2874 
2875  cout << "What is the phi of this layer relative to the vertical center of the payload in the horizontal plane?";
2876  cin >> LAYER_PHIPOSITION[i];
2877 
2878 
2879 
2880  if (settings1->CYLINDRICALSYMMETRY==0) {
2881  for (int j=0;j<NRX_PHI[i];j++) {
2882  cout << "What is the phi of the " << j << "th antenna is this layer?\n";
2883  cin >> PHI_EACHLAYER[i][j];
2884  } //for (read antenna phi)
2885  }//if (not cylindrically symmetric)
2886  } //for (antenna layers)
2887 
2888  cout << "How many polarizations must pass a voltage threshold?\n";
2889  cin >> settings1->NFOLD;
2890 
2891  cout << "How many times the expected noise level should the voltage threshold be?\n";
2892  cin >> maxthreshold;
2893  } //else if (custom payload)
2894 
2895  else if (settings1->WHICH==4) {// anita hill
2896 
2897  //settings1->NFOLD=1; // how many channels must pass the trigger
2898  //maxthreshold=2.3;
2899 
2900  if (settings1->NLAYERS!=2)
2901  cout << "Warning!!! Did not enter the right number of layers in the input file. For Anita Hill, it's 2.";
2902 
2903  settings1->CYLINDRICALSYMMETRY=1;
2904 
2905  NRX_PHI[0]=1; // this is how many antennas we have in phi on each "layer"
2906  NRX_PHI[1]=1; // for anita hill, we are calling each station a different "layer"
2907 
2908 
2909  PHI_OFFSET[0]=(bn1->BN_LONGITUDE+0.)*RADDEG; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
2910  // it's rotated by 1/2 the azimuth that separates two antennas on the 0th layer
2911  PHI_OFFSET[1]=(bn1->BN_LONGITUDE+0.)*RADDEG;
2912 
2913  cout << "phi_offsets are " << PHI_OFFSET[0] << " " << PHI_OFFSET[1] << "\n";
2914 
2915  //double INCLINE_NADIR=55; SET IN INPUT NOW!!!!
2916 
2917  // sets their declination
2918  THETA_ZENITH[0]=PI/2+INCLINE_TOPTHREE*RADDEG;
2919  THETA_ZENITH[1]=PI/2+INCLINE_TOPTHREE*RADDEG;
2920 
2921  // radius from center axis of the payload
2922  RRX[0] = 1.;
2923  RRX[1] = 1.;
2924 
2925  // vertical separation between layers.
2926  LAYER_VPOSITION[0]=0.;
2927  LAYER_VPOSITION[1] = 0.;
2928 
2929  LAYER_HPOSITION[0]=0.;
2930  LAYER_HPOSITION[1] = 100.; // in meters
2931 
2932  LAYER_PHIPOSITION[0]=0.;
2933  LAYER_PHIPOSITION[1] = 30.*RADDEG;// in radians
2934  }
2935 
2936  else if(settings1->WHICH==6) { // Kurt's measurements for the first flight in elog 345
2937  //settings1->NFOLD=8;
2938  settings1->CYLINDRICALSYMMETRY=0;
2939 
2940  NRX_PHI[0]=8;
2941  NRX_PHI[1]=8;
2942  NRX_PHI[2]=16;
2943 
2944  PHITRIG[0]=16; // number of positions in phi in each trigger layer
2945  PHITRIG[1]=16;
2946  PHITRIG[2]=8;
2947 
2948 
2949  THETA_ZENITH[0]=PI/2+INCLINE_TOPTHREE*RADDEG;
2950  THETA_ZENITH[1]=PI/2+INCLINE_TOPTHREE*RADDEG;
2951  THETA_ZENITH[2]=PI/2+INCLINE_TOPTHREE*RADDEG;
2952 
2953  PHI_OFFSET[0]=0.;
2954  PHI_OFFSET[1]=0.;
2955  PHI_OFFSET[2]=0.;
2956 
2957  ANTENNA_POSITION_START[0][0][0] = MINCH * Vector(40.957,-39.29,125.38).RotateZ(-gps_offset);
2958  ANTENNA_POSITION_START[0][0][1] = MINCH * Vector(57.608,0.606,124.97).RotateZ(-gps_offset);
2959  ANTENNA_POSITION_START[0][0][2] = MINCH * Vector(41.049,40.605,124.896).RotateZ(-gps_offset);
2960  ANTENNA_POSITION_START[0][0][3] = MINCH * Vector(1.032,57.128,124.93).RotateZ(-gps_offset);
2961  ANTENNA_POSITION_START[0][0][4] = MINCH * Vector(-38.832,40.508,125.607).RotateZ(-gps_offset);
2962  ANTENNA_POSITION_START[0][0][5] = MINCH * Vector(-55.545,0.549,125.851).RotateZ(-gps_offset);
2963  ANTENNA_POSITION_START[0][0][6] = MINCH * Vector(-38.793,-39.423,126.105).RotateZ(-gps_offset);
2964  ANTENNA_POSITION_START[0][0][7] = MINCH * Vector(1.113,-55.918,125.731).RotateZ(-gps_offset);
2965  ANTENNA_POSITION_START[0][1][0] = MINCH * Vector(19.841,-45.739,87.738).RotateZ(-gps_offset);
2966  ANTENNA_POSITION_START[0][1][1] = MINCH * Vector(46.959,-18.601,87.364).RotateZ(-gps_offset);
2967  ANTENNA_POSITION_START[0][1][2] = MINCH * Vector(46.983,19.646,87.208).RotateZ(-gps_offset);
2968  ANTENNA_POSITION_START[0][1][3] = MINCH * Vector(19.823,46.633,87.194).RotateZ(-gps_offset);
2969  ANTENNA_POSITION_START[0][1][4] = MINCH * Vector(-18.429,46.496,87.486).RotateZ(-gps_offset);
2970  ANTENNA_POSITION_START[0][1][5] = MINCH * Vector(-45.439,19.34,88.0).RotateZ(-gps_offset);
2971  ANTENNA_POSITION_START[0][1][6] = MINCH * Vector(-45.446,-18.769,88.183).RotateZ(-gps_offset);
2972  ANTENNA_POSITION_START[0][1][7] = MINCH * Vector(-18.297,-45.857,88.066).RotateZ(-gps_offset);
2973  ANTENNA_POSITION_START[0][2][0] = MINCH * Vector(38.622,-94.184,-20.615).RotateZ(-gps_offset);
2974  ANTENNA_POSITION_START[0][2][1] = MINCH * Vector(71.662,-72.036,-20.966).RotateZ(-gps_offset);
2975  ANTENNA_POSITION_START[0][2][2] = MINCH * Vector(93.857,-39.130,-21.512).RotateZ(-gps_offset);
2976  ANTENNA_POSITION_START[0][2][3] = MINCH * Vector(101.664,-0.202,-21.942).RotateZ(-gps_offset);
2977  ANTENNA_POSITION_START[0][2][4] = MINCH * Vector(93.993,38.733,-22.351).RotateZ(-gps_offset);
2978  ANTENNA_POSITION_START[0][2][5] = MINCH * Vector(71.92,71.815,-22.386).RotateZ(-gps_offset);
2979  ANTENNA_POSITION_START[0][2][6] = MINCH * Vector(38.944,93.885,-22.274).RotateZ(-gps_offset);
2980  ANTENNA_POSITION_START[0][2][7] = MINCH * Vector(0.036,101.619,-21.813).RotateZ(-gps_offset);
2981  ANTENNA_POSITION_START[0][2][8] = MINCH * Vector(-38.991,93.809,-21.281).RotateZ(-gps_offset);
2982  ANTENNA_POSITION_START[0][2][9] = MINCH * Vector(-71.899,71.704,-20.777).RotateZ(-gps_offset);
2983  ANTENNA_POSITION_START[0][2][10] = MINCH * Vector(-94.121,38.754,-20.825).RotateZ(-gps_offset);
2984  ANTENNA_POSITION_START[0][2][11] = MINCH * Vector(-101.986,-0.133,-20.71).RotateZ(-gps_offset);
2985  ANTENNA_POSITION_START[0][2][12] = MINCH * Vector(-94.175,-39.024,-20.671).RotateZ(-gps_offset);
2986  ANTENNA_POSITION_START[0][2][13] = MINCH * Vector(-72.138,-72.132,-20.295).RotateZ(-gps_offset);
2987  ANTENNA_POSITION_START[0][2][14] = MINCH * Vector(-39.111,-94.25,-20.23).RotateZ(-gps_offset);
2988  ANTENNA_POSITION_START[0][2][15] = MINCH * Vector(-0.163,-101.975,-20.229).RotateZ(-gps_offset);
2989  PHI_EACHLAYER[0][0] = -45.103 * RADDEG - gps_offset;
2990  PHI_EACHLAYER[0][1] = -0.14 * RADDEG - gps_offset;
2991  PHI_EACHLAYER[0][2] = 44.559 * RADDEG - gps_offset;
2992  PHI_EACHLAYER[0][3] = 89.959 * RADDEG - gps_offset;
2993  PHI_EACHLAYER[0][4] = 135.555 * RADDEG - gps_offset;
2994  PHI_EACHLAYER[0][5] = 179.651 * RADDEG - gps_offset;
2995  PHI_EACHLAYER[0][6] = -135.14 * RADDEG - gps_offset;
2996  PHI_EACHLAYER[0][7] = -90.18 * RADDEG - gps_offset;
2997  PHI_EACHLAYER[1][0] = -67.283 * RADDEG - gps_offset;
2998  PHI_EACHLAYER[1][1] = -23.004 * RADDEG - gps_offset;
2999  PHI_EACHLAYER[1][2] = 22.72 * RADDEG - gps_offset;
3000  PHI_EACHLAYER[1][3] = 67.82 * RADDEG - gps_offset;
3001  PHI_EACHLAYER[1][4] = 112.698 * RADDEG - gps_offset;
3002  PHI_EACHLAYER[1][5] = 157.565 * RADDEG - gps_offset;
3003  PHI_EACHLAYER[1][6] = -157.376 * RADDEG - gps_offset;
3004  PHI_EACHLAYER[1][7] = -112.449 * RADDEG - gps_offset;
3005  PHI_EACHLAYER[2][0] = -67.26 * RADDEG - gps_offset;
3006  PHI_EACHLAYER[2][1] = -45.284 * RADDEG - gps_offset;
3007  PHI_EACHLAYER[2][2] = -22.457 * RADDEG - gps_offset;
3008  PHI_EACHLAYER[2][3] = 0.227 * RADDEG - gps_offset;
3009  PHI_EACHLAYER[2][4] = 22.318 * RADDEG - gps_offset;
3010  PHI_EACHLAYER[2][5] = 45.008 * RADDEG - gps_offset;
3011  PHI_EACHLAYER[2][6] = 67.751 * RADDEG - gps_offset;
3012  PHI_EACHLAYER[2][7] = 89.913 * RADDEG - gps_offset;
3013  PHI_EACHLAYER[2][8] = 113.016 * RADDEG - gps_offset;
3014  PHI_EACHLAYER[2][9] = 135.608 * RADDEG - gps_offset;
3015  PHI_EACHLAYER[2][10] = 157.487 * RADDEG - gps_offset;
3016  PHI_EACHLAYER[2][11] = 179.709 * RADDEG - gps_offset;
3017  PHI_EACHLAYER[2][12] = -157.569 * RADDEG - gps_offset;
3018  PHI_EACHLAYER[2][13] = -135.021 * RADDEG - gps_offset;
3019  PHI_EACHLAYER[2][14] = -112.773 * RADDEG - gps_offset;
3020  PHI_EACHLAYER[2][15] = -89.959 * RADDEG - gps_offset;
3021  ANTENNA_DOWN[0][0] = 10.422 * RADDEG;
3022  ANTENNA_DOWN[0][1] = 10.207 * RADDEG;
3023  ANTENNA_DOWN[0][2] = 10.714 * RADDEG;
3024  ANTENNA_DOWN[0][3] = 10.381 * RADDEG;
3025  ANTENNA_DOWN[0][4] = 10.026 * RADDEG;
3026  ANTENNA_DOWN[0][5] = 9.515 * RADDEG;
3027  ANTENNA_DOWN[0][6] = 9.677 * RADDEG;
3028  ANTENNA_DOWN[0][7] = 9.544 * RADDEG;
3029  ANTENNA_DOWN[1][0] = 10.183 * RADDEG;
3030  ANTENNA_DOWN[1][1] = 10.44 * RADDEG;
3031  ANTENNA_DOWN[1][2] = 10.562 * RADDEG;
3032  ANTENNA_DOWN[1][3] = 10.655 * RADDEG;
3033  ANTENNA_DOWN[1][4] = 10.265 * RADDEG;
3034  ANTENNA_DOWN[1][5] = 9.77 * RADDEG;
3035  ANTENNA_DOWN[1][6] = 9.422 * RADDEG;
3036  ANTENNA_DOWN[1][7] = 9.526 * RADDEG;
3037  ANTENNA_DOWN[2][0] = 9.364 * RADDEG;
3038  ANTENNA_DOWN[2][1] = 9.712 * RADDEG;
3039  ANTENNA_DOWN[2][2] = 9.892 * RADDEG;
3040  ANTENNA_DOWN[2][3] = 10.253 * RADDEG;
3041  ANTENNA_DOWN[2][4] = 10.574 * RADDEG;
3042  ANTENNA_DOWN[2][5] = 10.62 * RADDEG;
3043  ANTENNA_DOWN[2][6] = 10.416 * RADDEG;
3044  ANTENNA_DOWN[2][7] = 10.189 * RADDEG;
3045  ANTENNA_DOWN[2][8] = 9.776 * RADDEG;
3046  ANTENNA_DOWN[2][9] = 9.596 * RADDEG;
3047  ANTENNA_DOWN[2][10] = 9.561 * RADDEG;
3048  ANTENNA_DOWN[2][11] = 9.695 * RADDEG;
3049  ANTENNA_DOWN[2][12] = 9.445 * RADDEG;
3050  ANTENNA_DOWN[2][13] = 9.387 * RADDEG;
3051  ANTENNA_DOWN[2][14] = 9.398 * RADDEG;
3052  ANTENNA_DOWN[2][15] = 9.288 * RADDEG;
3053  for(int iii = 0; iii < 3; iii++) // move from the square centers to the phase centers
3054  for(int jjj = 0; jjj < NRX_PHI[iii]; jjj++)
3055  ANTENNA_POSITION_START[1][iii][jjj] = ANTENNA_POSITION_START[0][iii][jjj] = ANTENNA_POSITION_START[0][iii][jjj] - phase_center * Vector(cos(PHI_EACHLAYER[iii][jjj])*sin(90.*RADDEG+ANTENNA_DOWN[iii][jjj]), sin(PHI_EACHLAYER[iii][jjj])*sin(90.*RADDEG+ANTENNA_DOWN[iii][jjj]), cos(90.*RADDEG+ANTENNA_DOWN[iii][jjj]));
3056  }
3057  else if (settings1->WHICH==7) {
3058 
3059  // Just one layer of antennas around balloon
3060  // EeVEX
3061 
3062  // settings1->NFOLD=1; //
3063  //maxthreshold=2.3;
3064 
3065  settings1->CYLINDRICALSYMMETRY=1;
3066 
3067  NRX_PHI[0]=360;
3068  NRX_PHI[1]=360;
3069  NRX_PHI[2]=360;
3070  NRX_PHI[3]=360;
3071  NRX_PHI[4]=360;
3072 
3073  PHITRIG[0]=360;
3074  PHITRIG[1]=360;
3075  PHITRIG[2]=360;
3076  PHITRIG[3]=360;
3077  PHITRIG[4]=360;
3078 
3079 
3080  PHI_OFFSET[0]=0.; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
3081  PHI_OFFSET[1]=0.; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
3082  PHI_OFFSET[2]=0.; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
3083  PHI_OFFSET[3]=0.; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
3084  PHI_OFFSET[4]=0.; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
3085  // it's rotated by 1/2 the azimuth that separates two antennas on the 0th layer
3086 
3087  // sets their declination
3088  THETA_ZENITH[0]=PI/2+5.5*RADDEG;
3089  THETA_ZENITH[1]=PI/2+7.5*RADDEG;
3090  THETA_ZENITH[2]=PI/2+9.5*RADDEG;
3091  THETA_ZENITH[3]=PI/2+11.5*RADDEG;
3092  THETA_ZENITH[4]=PI/2+13.5*RADDEG;
3093 
3094 
3095  // radius from center axis of the payload
3096  RRX[0] = 0.9210802;
3097  RRX[1] = 0.9210802;
3098  RRX[2] = 0.9210802;
3099  RRX[3] = 0.9210802;
3100  RRX[4] = 0.9210802;
3101 
3102  // vertical separation between layers.
3103  LAYER_VPOSITION[0]=0;
3104  LAYER_VPOSITION[1]=10.;
3105  LAYER_VPOSITION[2]=20.;
3106  LAYER_VPOSITION[3]=30.;
3107  LAYER_VPOSITION[4]=40.;
3108 
3109  LAYER_HPOSITION[0]=0.;
3110  LAYER_HPOSITION[1]=0.;
3111  LAYER_HPOSITION[2]=0.;
3112  LAYER_HPOSITION[3]=0.;
3113  LAYER_HPOSITION[4]=0.;
3114 
3115  } //else if (EeVEX)
3116  //anitaII or satellite
3117  else if (settings1->WHICH==8) {
3118  cout<<"initializing and using anitaII payload geometry"<<endl;
3119 
3120  // layer 0 is antennas 1-8 on the payload
3121  // layer 1 is antennas 9-15
3122  // layer 2 is antennas 16-32
3123 
3124  //settings1->NFOLD=8;
3125  //maxthreshold=2.3;
3126 
3127  settings1->CYLINDRICALSYMMETRY=0;
3128 
3129  NRX_PHI[0]=8;
3130  NRX_PHI[1]=8;
3131  NRX_PHI[2]=16;
3132  NRX_PHI[3]=8;
3133 
3134  PHITRIG[0]=16; // number of positions in phi in each trigger layer
3135  PHITRIG[1]=16;
3136  PHITRIG[2]=8;
3137 
3138  PHI_OFFSET[0]=0.;
3139  PHI_OFFSET[1]=0;
3140  PHI_OFFSET[2]=0;
3141  PHI_OFFSET[3]=0;
3142 
3143  // sets their declination
3144  THETA_ZENITH[0]=PI/2+INCLINE_TOPTHREE*RADDEG;
3145  THETA_ZENITH[1]=PI/2+INCLINE_TOPTHREE*RADDEG;
3146  THETA_ZENITH[2]=PI/2+INCLINE_TOPTHREE*RADDEG;
3147  THETA_ZENITH[3]=PI/2+INCLINE_TOPTHREE*RADDEG;
3148 
3149  ANTENNA_POSITION_START[0][0][0] = MINCH * Vector(40.438,-36.958,147.227);
3150  ANTENNA_POSITION_START[0][0][1] = MINCH * Vector(57.134,3.109,146.476);
3151  ANTENNA_POSITION_START[0][0][2] = MINCH * Vector(40.549,43.106,145.871);
3152  ANTENNA_POSITION_START[0][0][3] = MINCH * Vector(0.624,59.688,145.361);
3153  ANTENNA_POSITION_START[0][0][4] = MINCH * Vector(-39.455,43.147,145.928);
3154  ANTENNA_POSITION_START[0][0][5] = MINCH * Vector(-56.096,3.177,146.894);
3155  ANTENNA_POSITION_START[0][0][6] = MINCH * Vector(-39.355,-36.753,147.757);
3156  ANTENNA_POSITION_START[0][0][7] = MINCH * Vector(0.645,-53.539,147.876);
3157  ANTENNA_POSITION_START[0][1][0] = MINCH * Vector(19.554,-43.890,109.531);
3158  ANTENNA_POSITION_START[0][1][1] = MINCH * Vector(46.600,-16.625,108.889);
3159  ANTENNA_POSITION_START[0][1][2] = MINCH * Vector(46.587,21.659,108.220);
3160  ANTENNA_POSITION_START[0][1][3] = MINCH * Vector(19.476,48.539,107.671);
3161  ANTENNA_POSITION_START[0][1][4] = MINCH * Vector(-18.798,48.502,107.852);
3162  ANTENNA_POSITION_START[0][1][5] = MINCH * Vector(-45.899,21.424,108.516);
3163  ANTENNA_POSITION_START[0][1][6] = MINCH * Vector(-45.895,-16.821,109.354);
3164  ANTENNA_POSITION_START[0][1][7] = MINCH * Vector(-18.691,-43.864,109.843);
3165  ANTENNA_POSITION_START[0][2][0] = MINCH * Vector(38.636,-93.988,2.636);
3166  ANTENNA_POSITION_START[0][2][1] = MINCH * Vector(71.690,-72.108,1.953);
3167  ANTENNA_POSITION_START[0][2][2] = MINCH * Vector(93.897,-39.211,0.498);
3168  ANTENNA_POSITION_START[0][2][3] = MINCH * Vector(101.790,-0.212,-0.661);
3169  ANTENNA_POSITION_START[0][2][4] = MINCH * Vector(94.047,38.773,-1.788);
3170  ANTENNA_POSITION_START[0][2][5] = MINCH * Vector(72.080,71.816,-2.223);
3171  ANTENNA_POSITION_START[0][2][6] = MINCH * Vector(39.065,93.999,-2.561);
3172  ANTENNA_POSITION_START[0][2][7] = MINCH * Vector(0.121,101.815,-2.314);
3173  ANTENNA_POSITION_START[0][2][8] = MINCH * Vector(-38.815,94.002,-2.034);
3174  ANTENNA_POSITION_START[0][2][9] = MINCH * Vector(-71.809,71.912,-1.102);
3175  ANTENNA_POSITION_START[0][2][10] = MINCH * Vector(-93.886,39.000,-0.673);
3176  ANTENNA_POSITION_START[0][2][11] = MINCH * Vector(-101.885,0.048,0.102);
3177  ANTENNA_POSITION_START[0][2][12] = MINCH * Vector(-94.017,-38.841,0.865);
3178  ANTENNA_POSITION_START[0][2][13] = MINCH * Vector(-72.079,-71.902,1.864);
3179  ANTENNA_POSITION_START[0][2][14] = MINCH * Vector(-39.152,-93.935,2.464);
3180  ANTENNA_POSITION_START[0][2][15] = MINCH * Vector(-0.290,-101.771,2.991);
3181  ANTENNA_POSITION_START[0][3][0] = MINCH * Vector(32.625,-82.045,-71.140);
3182  ANTENNA_POSITION_START[0][3][1] = MINCH * Vector(79.071,-35.639,-72.809);
3183  ANTENNA_POSITION_START[0][3][2] = MINCH * Vector(79.172,30.988,-74.893);
3184  ANTENNA_POSITION_START[0][3][3] = MINCH * Vector(32.608,77.414,-75.342);
3185  ANTENNA_POSITION_START[0][3][4] = MINCH * Vector(-33.398,78.088,-74.957);
3186  ANTENNA_POSITION_START[0][3][5] = MINCH * Vector(-79.367,31.568,-73.922);
3187  ANTENNA_POSITION_START[0][3][6] = MINCH * Vector(-78.900,-34.192,-72.645);
3188  ANTENNA_POSITION_START[0][3][7] = MINCH * Vector(-33.046,-81.696,-70.907);
3189  PHI_EACHLAYER[0][0] = -45.012 * RADDEG ;//ant 7
3190  PHI_EACHLAYER[0][1] = -0.588 * RADDEG ;//ant 0
3191  PHI_EACHLAYER[0][2] = 45.694 * RADDEG ;//ant 1
3192  PHI_EACHLAYER[0][3] = 90.310 * RADDEG ;//ant 2
3193  PHI_EACHLAYER[0][4] = 135.161 * RADDEG ;//ant3
3194  PHI_EACHLAYER[0][5] = 179.861 * RADDEG ;//ant4
3195  PHI_EACHLAYER[0][6] = -134.930 * RADDEG ;//ant5
3196  PHI_EACHLAYER[0][7] = -90.638 * RADDEG ;//ant 6
3197  PHI_EACHLAYER[1][0] = -67.412 * RADDEG ;//ant 15
3198  PHI_EACHLAYER[1][1] = -23.005 * RADDEG ;//ant 8
3199  PHI_EACHLAYER[1][2] = 22.503 * RADDEG ;//ant 9
3200  PHI_EACHLAYER[1][3] = 67.722 * RADDEG ;//ant 10
3201  PHI_EACHLAYER[1][4] = 112.614 * RADDEG ;//ant 11
3202  PHI_EACHLAYER[1][5] = 157.685 * RADDEG ;//ant 12
3203  PHI_EACHLAYER[1][6] = -156.639 * RADDEG ;//ant 13
3204  PHI_EACHLAYER[1][7] = -112.587 * RADDEG ;//ant 14
3205  PHI_EACHLAYER[2][0] = -67.365 * RADDEG ;//ant 29
3206  PHI_EACHLAYER[2][1] = -45.135 * RADDEG ;//ant 30
3207  PHI_EACHLAYER[2][2] = -23.002 * RADDEG ;//ant 31
3208  PHI_EACHLAYER[2][3] = -1.013 * RADDEG ;//ant 16
3209  PHI_EACHLAYER[2][4] = 21.934 * RADDEG ;//ant 17
3210  PHI_EACHLAYER[2][5] = 44.467 * RADDEG ;//ant 18
3211  PHI_EACHLAYER[2][6] = 67.288 * RADDEG ;//ant 19
3212  PHI_EACHLAYER[2][7] = 89.971 * RADDEG ;//ant 20
3213  PHI_EACHLAYER[2][8] = 112.390 * RADDEG ;//ant 21
3214  PHI_EACHLAYER[2][9] = 134.988 * RADDEG ;//ant 22
3215  PHI_EACHLAYER[2][10] = 157.387 * RADDEG ;//ant 23
3216  PHI_EACHLAYER[2][11] = 179.843 * RADDEG ;//ant 24
3217  PHI_EACHLAYER[2][12] = -157.444 * RADDEG ;//ant 25
3218  PHI_EACHLAYER[2][13] = -134.877 * RADDEG ;//ant 26
3219  PHI_EACHLAYER[2][14] = -112.406 * RADDEG ;//ant 27
3220  PHI_EACHLAYER[2][15] = -90.081 * RADDEG ;//ant 28
3221  PHI_EACHLAYER[3][0] = -67.997 * RADDEG ;//ant
3222  PHI_EACHLAYER[3][1] = -22.948 * RADDEG ;//ant
3223  PHI_EACHLAYER[3][2] = 22.382 * RADDEG ;//ant
3224  PHI_EACHLAYER[3][3] = 67.583 * RADDEG ;//ant
3225  PHI_EACHLAYER[3][4] = 112.844 * RADDEG ;//ant
3226  PHI_EACHLAYER[3][5] = 157.761 * RADDEG ;//ant
3227  PHI_EACHLAYER[3][6] = -157.896 * RADDEG ;//ant
3228  PHI_EACHLAYER[3][7] = -112.791 * RADDEG ;//ant
3229  ANTENNA_DOWN[0][0] = 9.637 * RADDEG;
3230  ANTENNA_DOWN[0][1] = 10.108 * RADDEG;
3231  ANTENNA_DOWN[0][2] = 11.245 * RADDEG;
3232  ANTENNA_DOWN[0][3] = 11.291 * RADDEG;
3233  ANTENNA_DOWN[0][4] = 10.988 * RADDEG;
3234  ANTENNA_DOWN[0][5] = 9.491 * RADDEG;
3235  ANTENNA_DOWN[0][6] = 9.027 * RADDEG;
3236  ANTENNA_DOWN[0][7] = 8.743 * RADDEG;
3237  ANTENNA_DOWN[1][0] = 9.445 * RADDEG;
3238  ANTENNA_DOWN[1][1] = 10.061 * RADDEG;
3239  ANTENNA_DOWN[1][2] = 10.772 * RADDEG;
3240  ANTENNA_DOWN[1][3] = 11.484 * RADDEG;
3241  ANTENNA_DOWN[1][4] = 11.122 * RADDEG;
3242  ANTENNA_DOWN[1][5] = 10.376 * RADDEG;
3243  ANTENNA_DOWN[1][6] = 9.410 * RADDEG;
3244  ANTENNA_DOWN[1][7] = 9.039 * RADDEG;
3245  ANTENNA_DOWN[2][0] = 8.233 * RADDEG;
3246  ANTENNA_DOWN[2][1] = 8.807 * RADDEG;
3247  ANTENNA_DOWN[2][2] = 9.120 * RADDEG;
3248  ANTENNA_DOWN[2][3] = 10.352 * RADDEG;
3249  ANTENNA_DOWN[2][4] = 10.889 * RADDEG;
3250  ANTENNA_DOWN[2][5] = 11.315 * RADDEG;
3251  ANTENNA_DOWN[2][6] = 11.402 * RADDEG;
3252  ANTENNA_DOWN[2][7] = 11.379 * RADDEG;
3253  ANTENNA_DOWN[2][8] = 10.842 * RADDEG;
3254  ANTENNA_DOWN[2][9] = 10.725 * RADDEG;
3255  ANTENNA_DOWN[2][10] = 10.143 * RADDEG;
3256  ANTENNA_DOWN[2][11] = 10.067 * RADDEG;
3257  ANTENNA_DOWN[2][12] = 9.503 * RADDEG;
3258  ANTENNA_DOWN[2][13] = 9.021 * RADDEG;
3259  ANTENNA_DOWN[2][14] = 8.453 * RADDEG;
3260  ANTENNA_DOWN[2][15] = 8.268 * RADDEG;
3261  ANTENNA_DOWN[3][0] = 8.007 * RADDEG;
3262  ANTENNA_DOWN[3][1] = 9.817 * RADDEG;
3263  ANTENNA_DOWN[3][2] = 10.259 * RADDEG;
3264  ANTENNA_DOWN[3][3] = 11.648 * RADDEG;
3265  ANTENNA_DOWN[3][4] = 10.271 * RADDEG;
3266  ANTENNA_DOWN[3][5] = 10.015 * RADDEG;
3267  ANTENNA_DOWN[3][6] = 10.889 * RADDEG;
3268  ANTENNA_DOWN[3][7] = 7.314 * RADDEG;
3269 
3270  SIMON_DELTA_R[0][0] = -0.0384839;
3271  SIMON_DELTA_R[0][1] = 0.00634697;
3272  SIMON_DELTA_R[0][2] = -0.0861167;
3273  SIMON_DELTA_R[0][3] = 0.0461873;
3274  SIMON_DELTA_R[0][4] = 0.0153388;
3275  SIMON_DELTA_R[0][5] = -0.00927728;
3276  SIMON_DELTA_R[0][6] = 0.0239867;
3277  SIMON_DELTA_R[0][7] = 0.0125282;
3278  SIMON_DELTA_R[1][0] = -0.0111636;
3279  SIMON_DELTA_R[1][1] = -0.0959452;
3280  SIMON_DELTA_R[1][2] = -0.0330808;
3281  SIMON_DELTA_R[1][3] = -0.0475617;
3282  SIMON_DELTA_R[1][4] = 0.0196292;
3283  SIMON_DELTA_R[1][5] = -0.0190837;
3284  SIMON_DELTA_R[1][6] = -0.00922367;
3285  SIMON_DELTA_R[1][7] = -0.0294811;
3286  SIMON_DELTA_R[2][0] = 0.0140245;
3287  SIMON_DELTA_R[2][1] = -0.0621836;
3288  SIMON_DELTA_R[2][2] = -0.0379325;
3289  SIMON_DELTA_R[2][3] = -0.0108062;
3290  SIMON_DELTA_R[2][4] = -0.0601935;
3291  SIMON_DELTA_R[2][5] = -0.0968276;
3292  SIMON_DELTA_R[2][6] = -0.0348523;
3293  SIMON_DELTA_R[2][7] = 0.0121726;
3294  SIMON_DELTA_R[2][8] = 0.0405193;
3295  SIMON_DELTA_R[2][9] = 0.0239992;
3296  SIMON_DELTA_R[2][10] = -0.0405203;
3297  SIMON_DELTA_R[2][11] = -0.00401756;
3298  SIMON_DELTA_R[2][12] = -0.0362955;
3299  SIMON_DELTA_R[2][13] = -0.00587152;
3300  SIMON_DELTA_R[2][14] = -0.00611182;
3301  SIMON_DELTA_R[2][15] = -0.00321244;
3302  SIMON_DELTA_R[3][0] = -0.0437687;
3303  SIMON_DELTA_R[3][1] = -0.0643475;
3304  SIMON_DELTA_R[3][2] = -0.0804245;
3305  SIMON_DELTA_R[3][3] = -0.0112675;
3306  SIMON_DELTA_R[3][4] = 0.0337428;
3307  SIMON_DELTA_R[3][5] = -0.0525977;
3308  SIMON_DELTA_R[3][6] = -0.101587;
3309  SIMON_DELTA_R[3][7] = -0.0401037;
3310 
3311  SIMON_DELTA_PHI[0][0] = -0.0100608;
3312  SIMON_DELTA_PHI[0][1] = -0.00313443;
3313  SIMON_DELTA_PHI[0][2] = -0.015312;
3314  SIMON_DELTA_PHI[0][3] = 0.00206827;
3315  SIMON_DELTA_PHI[0][4] = -0.0227948;
3316  SIMON_DELTA_PHI[0][5] = 0.00750385;
3317  SIMON_DELTA_PHI[0][6] = 0.00388065;
3318  SIMON_DELTA_PHI[0][7] = -0.00131021;
3319  SIMON_DELTA_PHI[1][0] = -0.0299233;
3320  SIMON_DELTA_PHI[1][1] = -0.00165365;
3321  SIMON_DELTA_PHI[1][2] = -0.0107407;
3322  SIMON_DELTA_PHI[1][3] = 0.0145914;
3323  SIMON_DELTA_PHI[1][4] = -0.0150373;
3324  SIMON_DELTA_PHI[1][5] = -0.0121967;
3325  SIMON_DELTA_PHI[1][6] = -0.0038106;
3326  SIMON_DELTA_PHI[1][7] = 0.0106842;
3327  SIMON_DELTA_PHI[2][0] = -0.0087849;
3328  SIMON_DELTA_PHI[2][1] = 0.000682206;
3329  SIMON_DELTA_PHI[2][2] = -0.00516052;
3330  SIMON_DELTA_PHI[2][3] = -0.00770935;
3331  SIMON_DELTA_PHI[2][4] = -0.00862535;
3332  SIMON_DELTA_PHI[2][5] = -0.00920648;
3333  SIMON_DELTA_PHI[2][6] = 0.00037431;
3334  SIMON_DELTA_PHI[2][7] = 0.00310935;
3335  SIMON_DELTA_PHI[2][8] = -0.00546085;
3336  SIMON_DELTA_PHI[2][9] = -0.00901249;
3337  SIMON_DELTA_PHI[2][10] = -0.0145529;
3338  SIMON_DELTA_PHI[2][11] = -0.00666063;
3339  SIMON_DELTA_PHI[2][12] = -0.00372999;
3340  SIMON_DELTA_PHI[2][13] = 0.00197442;
3341  SIMON_DELTA_PHI[2][14] = -0.000789595;
3342  SIMON_DELTA_PHI[2][15] = 0.000188257;
3343  SIMON_DELTA_PHI[3][0] = -0.00289577;
3344  SIMON_DELTA_PHI[3][1] = -0.0203117;
3345  SIMON_DELTA_PHI[3][2] = -0.00503387;
3346  SIMON_DELTA_PHI[3][3] = -0.000220575;
3347  SIMON_DELTA_PHI[3][4] = -0.00416114;
3348  SIMON_DELTA_PHI[3][5] = -0.0223176;
3349  SIMON_DELTA_PHI[3][6] = 0.0058874;
3350  SIMON_DELTA_PHI[3][7] = 0.00899651;
3351 
3352  for(int iii = 0; iii < 4; iii++){ // move from the square centers to the phase centers
3353  for(int jjj = 0; jjj < NRX_PHI[iii]; jjj++){
3354 
3355  //ANTENNA_DOWN is measured from horiztonal. Put negatives in correct places. Verified with analysis code
3356  ANTENNA_POSITION_START[0][iii][jjj] = ANTENNA_POSITION_START[0][iii][jjj] - phase_center_anita2_analysis * Vector(cos(PHI_EACHLAYER[iii][jjj])*cos(-1*ANTENNA_DOWN[iii][jjj]), sin(PHI_EACHLAYER[iii][jjj])*cos(-1*ANTENNA_DOWN[iii][jjj]), sin(-1*ANTENNA_DOWN[iii][jjj]));
3357  }//jjj
3358  }//iii
3359  double r;
3360  double phi;
3361 
3362  double x;
3363  double y;
3364  double z;
3365 
3366 
3367  for(int iii = 0; iii < 4; iii++){ // move from the square centers to the phase centers
3368  for(int jjj = 0; jjj < NRX_PHI[iii]; jjj++){
3369  x = ANTENNA_POSITION_START[0][iii][jjj][0];
3370  y = ANTENNA_POSITION_START[0][iii][jjj][1];
3371  z = ANTENNA_POSITION_START[0][iii][jjj][2];
3372 
3373  r = sqrt(pow(x,2)+pow(y,2));
3374  phi = atan2(y,x);
3375 
3376  ANTENNA_POSITION_START[0][iii][jjj]= Vector((r+SIMON_DELTA_R[iii][jjj])*cos(phi+SIMON_DELTA_PHI[iii][jjj]),(r+SIMON_DELTA_R[iii][jjj])*sin(phi+SIMON_DELTA_PHI[iii][jjj]),z);
3377 
3378  ANTENNA_POSITION_START[1][iii][jjj]=ANTENNA_POSITION_START[0][iii][jjj]=ANTENNA_POSITION_START[0][iii][jjj].RotateZ(-gps_offset_anita2);
3379  PHI_EACHLAYER[iii][jjj]=atan2(ANTENNA_POSITION_START[0][iii][jjj][1],ANTENNA_POSITION_START[0][iii][jjj][0]);//set phi of each antennas to correct starting position
3380 
3381  //cout<<"Antenna pos is "<<ANTENNA_POSITION_START[0][iii][jjj]<<" PHI is "<<PHI_EACHLAYER[iii][jjj]<<"\n";
3382  }
3383  }
3384 
3385 
3386  }
3387  else if (settings1->WHICH==9 || settings1->WHICH==10) { // ANITA-3 and ANITA-4
3388 
3389  // Read photogrammetry positions
3390  string whichANITAroman="";
3391  if (settings1->WHICH==9) whichANITAroman+="III";
3392  else whichANITAroman+="IV";
3393  cout<<"Initializing and using ANITA-" << whichANITAroman << " payload geometry"<<endl;
3394 
3395  // layer 0 is antennas 1-8 on the payload
3396  // layer 1 is antennas 9-15
3397  // layer 2 is antennas 16-32
3398  // layer 3 is antennas 32-48
3399 
3400 
3401  settings1->CYLINDRICALSYMMETRY=0;
3402 
3403  //these are physical layers
3404  NRX_PHI[0]=8;
3405  NRX_PHI[1]=8;
3406  NRX_PHI[2]=16;
3407  NRX_PHI[3]=16;
3408 
3409  PHITRIG[0]=16; // number of positions in phi in each *trigger* layer
3410  PHITRIG[1]=16;
3411  PHITRIG[2]=16;
3412 
3413  //these are physical layers again
3414  PHI_OFFSET[0]=0.;
3415  PHI_OFFSET[1]=0.; // 2.*PI/(double)NRX_PHI[0]/2.; // Linda: changed this offset to 0 as it shouldn't be needed
3416  PHI_OFFSET[2]=0.;
3417  PHI_OFFSET[3]=0.;
3418 
3419  //double INCLINE_NADIR=55; // this is set in the input file now So should be removed
3420 
3421  // sets their declination
3422  THETA_ZENITH[0]=PI/2+INCLINE_TOPTHREE*RADDEG;
3423  THETA_ZENITH[1]=PI/2+INCLINE_TOPTHREE*RADDEG;
3424  THETA_ZENITH[2]=PI/2+INCLINE_TOPTHREE*RADDEG;
3425  THETA_ZENITH[3]=PI/2+INCLINE_TOPTHREE*RADDEG;
3426 
3427  string photoFile;
3428 #ifdef ANITA_UTIL_EXISTS
3429  photoFile += ( (string)getenv("ANITA_UTIL_INSTALL_DIR") +"/share/anitaCalib/anita"+whichANITAroman+"Photogrammetry.csv");
3430 #else
3431  photoFile += (ICEMC_DATA_DIR+"/anita"+whichANITAroman+"Photogrammetry.csv");
3432 #endif
3433 
3434  std::ifstream Anita3PhotoFile(photoFile.c_str());
3435  if (!Anita3PhotoFile){
3436  std::cerr << "Couldn't open photogrammetry!" << std::endl;
3437  return;
3438  }
3439 
3440  //First up are the antenna positions
3441  TString line;
3442  for(int i=0;i<2;i++) {
3443  line.ReadLine(Anita3PhotoFile);
3444  //std::cout << line.Data() << "\n";
3445  }
3446 
3447  //Array with photogrammetry values
3448  Double_t xAntPhoto[48]; //inch
3449  Double_t yAntPhoto[48]; //inch
3450  Double_t zAntPhoto[48]; //inch
3451  Double_t rAntPhoto[48]; //inch
3452  Double_t azCentrePhoto[48]; //deg
3453  Double_t apertureAzPhoto[48]; //deg
3454  Double_t apertureElPhoto[48]; //deg
3455 
3456  for(int ant=0;ant<48;ant++) {
3457  line.ReadLine(Anita3PhotoFile);
3458  //std::cout << "Seavey:\t" << line.Data() << "\n";
3459  TObjArray *tokens = line.Tokenize(",");
3460  for(int j=0;j<8;j++) {
3461  const TString subString = ((TObjString*)tokens->At(j))->GetString();
3462  // TString *subString = (TString*) tokens->At(j);
3463  // std::cout << j << "\t" << subString.Data() << "\n";
3464  switch(j) {
3465  case 0:
3466  if (ant+1 != subString.Atoi()) {
3467  std::cerr << "Antenna number mismatch\n";
3468  }
3469  break;
3470  case 1:
3471  xAntPhoto[ant]=subString.Atof(); //inch
3472  break;
3473  case 2:
3474  yAntPhoto[ant]=subString.Atof(); //inch
3475  break;
3476  case 3:
3477  zAntPhoto[ant]=subString.Atof(); //inch
3478  break;
3479  case 4:
3480  rAntPhoto[ant]=subString.Atof(); //inch
3481  break;
3482  case 5:
3483  azCentrePhoto[ant]=subString.Atof(); //deg
3484  break;
3485  case 6:
3486  apertureAzPhoto[ant]=subString.Atof(); //deg
3487  break;
3488  case 7:
3489  apertureElPhoto[ant]=subString.Atof()*(-1); //deg // photogrammetry elevation defined as negative, here positive
3490  break;
3491  default:
3492  break;
3493  }
3494 
3495  }
3496  tokens->Delete();
3497 
3498  }
3499  Anita3PhotoFile.close();
3500 
3501  // Fill photogrammetry position for top rings
3502  for (int iant=0; iant<8;iant++){
3503  ANTENNA_POSITION_START[1][0][iant] = ANTENNA_POSITION_START[0][0][iant] = MINCH * Vector(xAntPhoto[iant*2], yAntPhoto[iant*2], zAntPhoto[iant*2]).RotateZ(-gps_offset_anita3); // top ring top antennas
3504  ANTENNA_POSITION_START[1][1][iant] = ANTENNA_POSITION_START[0][1][iant] = MINCH * Vector(xAntPhoto[iant*2+1], yAntPhoto[iant*2+1], zAntPhoto[iant*2+1]).RotateZ(-gps_offset_anita3); // top ring bottom antennas
3505 
3506  PHI_EACHLAYER[0][iant] = azCentrePhoto[iant*2] * RADDEG - gps_offset_anita3;
3507  PHI_EACHLAYER[1][iant] = azCentrePhoto[iant*2+1] * RADDEG - gps_offset_anita3;
3508  ANTENNA_DOWN[0][iant] = apertureElPhoto[iant*2] * RADDEG;
3509  ANTENNA_DOWN[1][iant] = apertureElPhoto[iant*2+1] * RADDEG;
3510 
3511  }
3512 
3513  // Fill photogrammetry position for middle and bottom rings
3514  for (int iant=0; iant<16;iant++){
3515  ANTENNA_POSITION_START[1][2][iant] = ANTENNA_POSITION_START[0][2][iant] = MINCH * Vector(xAntPhoto[iant+16], yAntPhoto[iant+16], zAntPhoto[iant+16]).RotateZ(-gps_offset_anita3); // middle ring antennas
3516  ANTENNA_POSITION_START[1][3][iant] = ANTENNA_POSITION_START[0][3][iant] = MINCH * Vector(xAntPhoto[iant+32], yAntPhoto[iant+32], zAntPhoto[iant+32]).RotateZ(-gps_offset_anita3); // bottom ring antennas
3517 
3518  PHI_EACHLAYER[2][iant] = azCentrePhoto[iant+16] * RADDEG - gps_offset_anita3;
3519  ANTENNA_DOWN[2][iant] = apertureElPhoto[iant+16] * RADDEG;
3520 
3521  PHI_EACHLAYER[3][iant] = azCentrePhoto[iant+32] * RADDEG - gps_offset_anita3;
3522  ANTENNA_DOWN[3][iant] = apertureElPhoto[iant+32] * RADDEG;
3523 
3524  }
3525 
3526  // HERE HPOL IS 0 AND VPOL IS 1
3527  string whichANITAcard="";
3528  if (settings1->WHICH==9) whichANITAcard+="3";
3529  else whichANITAcard+="4";
3530  string phaseCenterName;
3531 #ifdef ANITA_UTIL_EXISTS
3532  phaseCenterName += ( (string)getenv("ANITA_UTIL_INSTALL_DIR") +"/share/anitaCalib/phaseCenterPositionsRelativeToPhotogrammetryAnita"+whichANITAcard+".dat");
3533 #else
3534  phaseCenterName += (ICEMC_DATA_DIR+"/phaseCenterPositionsRelativeToPhotogrammetryAnita"+whichANITAcard+".dat");
3535 #endif
3536 
3537  std::ifstream PhaseCenterFile(phaseCenterName.c_str());
3538  Int_t antNum, tpol, pol;
3539  Double_t deltaR,deltaPhi,deltaZ;
3540  char firstLine[180];
3541  Double_t deltaRPhaseCentre[2][4][16]; //Relative to photogrammetry + ring offset
3542  Double_t deltaZPhaseCentre[2][4][16]; //Relative to photogrammetry + ring offset
3543  Double_t deltaPhiPhaseCentre[2][4][16]; //Relative to photogrammetry + ring offset
3544 
3545  PhaseCenterFile.getline(firstLine,179);
3546  // HERE HPOL IS 0 AND VPOL IS 1 that's why we invert pol here
3547  while(PhaseCenterFile >> antNum >> tpol >> deltaR >> deltaPhi >> deltaZ) {
3548  int ilayer = (antNum<16)*((antNum%2==0)*0 + (antNum%2==1)*1)+ (antNum>15)*(antNum<32)*2+(antNum>31)*3;
3549  int ifold = (ilayer<2)*((antNum-ilayer)/2)+(ilayer>1)*(antNum%16);
3550 
3551  if (tpol==1) pol=0;
3552  else if (tpol==0) pol=1;
3553 
3554  deltaRPhaseCentre[pol][ilayer][ifold]=deltaR;
3555  deltaPhiPhaseCentre[pol][ilayer][ifold]=deltaPhi*TMath::DegToRad();
3556  deltaZPhaseCentre[pol][ilayer][ifold]=deltaZ;
3557  }
3558  PhaseCenterFile.close();
3559 
3560  std::ifstream relativePhaseCenterToAmpaDelaysFile((ICEMC_DATA_DIR+"/relativePhaseCenterToAmpaDelaysAnita"+whichANITAcard+".dat").c_str());
3561 
3562 #ifdef ANITA_UTIL_EXISTS
3564  AnitaGeomTool *fGeomTool = AnitaGeomTool::Instance(stoi(whichANITAcard));
3565  int tempAnt, intTempPol;
3566  AnitaPol::AnitaPol_t tempPol;
3567  for(Int_t surf=0; surf<NUM_SURF; surf++){
3568  for(Int_t chan=0; chan<NUM_CHAN; chan++){
3569  fGeomTool->getAntPolFromSurfChan(surf,chan, tempAnt, tempPol);
3570  if (tempAnt!=-1){
3571  // in EventReaderRoot 0: HPOL, 1: VPOL, in icemc it's the opposite
3572  intTempPol = (tempPol==0) ? 1 : 0;
3573  extraCableDelays[intTempPol][tempAnt] = cal->relativePhaseCenterToAmpaDelays[surf][chan]*1e-9 ;
3574  // extraCableDelays[intTempPol][tempAnt] -= cal->relativeCableDelays[surf][chan][0]*1e-9 ;
3575  }
3576  }
3577  }
3578 
3579 #else
3580  for(int ipol=0; ipol<2; ipol++){
3581  for (int iant=0; iant<48; iant++){
3582  extraCableDelays[ipol][iant] = 0;
3583  }
3584  }
3585 
3586 #endif
3587 
3588 
3589  double x, y, z, r, phi;
3590  for(int ilayer = 0; ilayer < 4; ilayer++){
3591  for(int ifold = 0; ifold < NRX_PHI[ilayer]; ifold++){
3592  for (int ipol = 1; ipol >= 0; ipol--){
3593 
3594  // First attempt to define phase-centers is done by coming 20 cm
3595  // inwards from the antenna face end
3596  ANTENNA_POSITION_START[ipol][ilayer][ifold] = ANTENNA_POSITION_START[ipol][ilayer][ifold] - phase_center_anita3 * Vector(cos(PHI_EACHLAYER[ilayer][ifold])*cos(ANTENNA_DOWN[ilayer][ifold]), sin(PHI_EACHLAYER[ilayer][ifold])*cos(ANTENNA_DOWN[ilayer][ifold]), sin(ANTENNA_DOWN[ilayer][ifold]));
3597  x = ANTENNA_POSITION_START[ipol][ilayer][ifold].GetX();
3598  y = ANTENNA_POSITION_START[ipol][ilayer][ifold].GetY();
3599 
3600  r = sqrt(pow(x,2)+pow(y,2)) + deltaRPhaseCentre[ipol][ilayer][ifold];
3601  phi = atan2(y,x) + deltaPhiPhaseCentre[ipol][ilayer][ifold];
3602  z = ANTENNA_POSITION_START[ipol][ilayer][ifold].GetZ() + deltaZPhaseCentre[ipol][ilayer][ifold];
3603 
3604  if(phi<0) phi+=TMath::TwoPi();
3605  if(phi>TMath::TwoPi()) phi-=TMath::TwoPi();
3606 
3607  ANTENNA_POSITION_START[ipol][ilayer][ifold]= Vector(r*cos(phi),r*sin(phi),z);
3608 
3609  if (ipol==0) PHI_EACHLAYER[ilayer][ifold]=phi;
3610 
3611  }
3612  // Temp hack for ANITA-4
3613  // The different phase-centers between H and V create problems when
3614  // Making the LCP and RCP triggers
3615  // This hack uses the VPOL phase-centers for both VPOL and HPOL channels
3616  if (settings1->WHICH==10) ANTENNA_POSITION_START[1][ilayer][ifold] = ANTENNA_POSITION_START[0][ilayer][ifold];
3617  }
3618  }
3619  }
3620 
3621 
3622  else if (settings1->WHICH==11) { // satellite
3623 
3624 
3625  // layer 0 is antennas 1-8 on the payload
3626  // layer 1 is antennas 9-15
3627  settings1->CYLINDRICALSYMMETRY=1;
3628 
3629  //these are physical layers
3630  NRX_PHI[0]=8;
3631  NRX_PHI[1]=8;
3632 
3633  PHITRIG[0]=8; // number of positions in phi in each *trigger* layer
3634  PHITRIG[1]=8;
3635 
3636  //these are physical layers again
3637  PHI_OFFSET[0]=0.; // antenna 1 on 0th layer is rotated in phi wrt antenna 9 and antenna 17
3638  // it's rotated by 1/2 the azimuth that separates two antennas on the 0th layer
3639  PHI_OFFSET[1]=-2.*PI/(double)NRX_PHI[0]/2.;
3640 
3641  // sets their declination
3642  THETA_ZENITH[0]=PI/2+INCLINE_TOPTHREE*RADDEG;
3643  THETA_ZENITH[1]=PI/2+INCLINE_TOPTHREE*RADDEG;
3644 
3645  // radius from center axis of the payload
3646  RRX[0] = 0.9210802;
3647  RRX[1] = 0.7553198;
3648 
3649  // vertical separation between layers.
3650  LAYER_VPOSITION[0]=0;
3651  LAYER_VPOSITION[1] = -7.5;
3652 
3653  LAYER_HPOSITION[0]=0.;
3654  LAYER_HPOSITION[1] = 0.;
3655 
3656 
3657  } //else if (satellite)
3658 
3659  settings1->NANTENNAS=0;
3660  for (int i=0;i<settings1->NLAYERS;i++)
3661  settings1->NANTENNAS+=NRX_PHI[i];
3662 
3663  cout << "nantennas is " << settings1->NANTENNAS << "\n";
3664  number_all_antennas=settings1->NANTENNAS;
3665 
3666  // gets noise (vrms) for each bandwidth slice and antenna layer according to antenna theta
3667 
3668  if (settings1->WHICH==0) {
3669  temp_eachrx[0]=919.4;
3670  temp_eachrx[1]=1051.8;
3671  for (int j=2;j<16;j++) {
3672  temp_eachrx[j]=0.; // noise temperature of each antenna?
3673  }
3674  }
3675  else {
3676  for (int j=0;j<16;j++) {
3677 
3678  temp_eachrx[j]=(240.+200.); // temp of each antenna in kelvin
3679  }
3680  }
3681 
3682  for (int i=0;i<NRX_PHI[0];i++) {
3683  VNOISE_ANITALITE[i]=ChanTrigger::GetNoise(settings1,bn1->altitude_bn,bn1->surface_under_balloon,THETA_ZENITH[0],settings1->BW_SEAVEYS,temp_eachrx[i]);
3684  }
3685 }//GetPayload
3686 
3687 void Anita::calculate_all_offsets(void) {
3688 
3689  double angle_phi, angle_theta;
3690 
3691  double hypothesis_offset[3][3];
3692 
3693  vector<double> angles_tmp;
3694  vector< vector <double> > angles_diffthetas_tmp;
3695 
3696  double step_phi=(MAX_PHI_HYPOTHESIS-MIN_PHI_HYPOTHESIS)/(double)N_STEPS_PHI;
3697  double step_theta=(MAX_THETA_HYPOTHESIS-MIN_THETA_HYPOTHESIS)/(double)N_STEPS_THETA;
3698 
3699  cout << "step_theta is " << step_theta << "\n";
3700 
3701  for (unsigned center_phi_sector_index = 0; center_phi_sector_index < 1; ++center_phi_sector_index) {
3702  angles_tmp.clear();
3703  for (unsigned index_phi = 0; index_phi < N_STEPS_PHI; ++index_phi) {
3704  //angle_phi = (center_phi_sector_index + 3)%16 * 22.5 - 22.5 + index_phi * 3.;
3705  // angle of this phi sector (=index_phi) rel to center phi sector
3706  angle_phi = (double)center_phi_sector_index * 22.5 + MIN_PHI_HYPOTHESIS + (double)index_phi * step_phi;
3707  // Note that the zeroth phi sector is actually not the one with the phi = 0 direction, it's actually the third.
3708  // The above statement is probably false because of the gps_offset_anita2 rotation! [0][0] should be right after all...
3709  angles_diffthetas_tmp.clear();
3710  for (unsigned index_theta = 0; index_theta < N_STEPS_THETA; ++index_theta) {
3711  angle_theta = MIN_THETA_HYPOTHESIS + (double)index_theta*step_theta;
3712 
3713  // if (angle_phi==-11. && angle_theta==-20.)
3714  //if (fabs(angle_phi)<1. && angle_theta>15 && angle_theta<17)
3715  //cout << "angle phi, angle_theta are " << angle_phi << "\t" << angle_theta << "\n";
3716  angles_tmp.clear();
3717  angles_tmp.push_back(angle_phi);
3718  angles_tmp.push_back(angle_theta);
3719 
3720  angles_diffthetas_tmp.push_back(angles_tmp);
3721 
3722  calculate_single_offset(center_phi_sector_index, angle_phi, angle_theta, hypothesis_offset);
3723  //cout << "index_phi is " << index_phi << " " << "index_theta is " << index_theta << " ";
3724  for (unsigned i_layer = 0; i_layer < N_SUMMED_LAYERS; ++i_layer) {
3725  for (unsigned i_sector = 0; i_sector < N_SUMMED_PHI_SECTORS; ++i_sector) {
3726  hypothesis_offsets[center_phi_sector_index][index_phi][index_theta][i_sector][i_layer] = int(Tools::round(hypothesis_offset[i_sector][i_layer] / TRIG_TIMESTEP));
3727 
3728  }
3729  }
3730 
3731  }
3732  hypothesis_angles.push_back(angles_diffthetas_tmp);
3733  }
3734 
3735 
3736  }
3737  getDifferentOffsets();
3738  printDifferentOffsets();
3739  return;
3740 }
3741 void Anita::printDifferentOffsets() {
3742  ofstream ofile("outputs/offsets.txt");
3743  ofile << "number of offsets is " << vdifferent_offsets.size() << "\n";
3744 
3745 
3746  for (unsigned int i=0;i<vdifferent_offsets.size();i++) {
3747  for (int j=0;j<2;j++) {
3748  ofile << vdifferent_angles[i][j] << "\t";
3749  }
3750  for (unsigned int j=0;j<N_SUMMED_PHI_SECTORS;j++) {
3751  for (unsigned int k=0;k<N_SUMMED_LAYERS;k++) {
3752  // for (int j=0;j<vdifferent_offsets[i].size();j++) {
3753  ofile << vdifferent_offsets[i][N_SUMMED_LAYERS*j+k] << " ";
3754  //}
3755  }
3756  ofile << "\t";
3757  }
3758  ofile << "\n";
3759  }
3760  ofile.close();
3761 }
3762 void Anita::getDifferentOffsets() {
3763 
3764  vector<int> vtmp;
3765  vector<double> vangles_tmp;
3766 
3767  for (int center_phi_sector_index=0;center_phi_sector_index<1;center_phi_sector_index++) {
3768  for (unsigned index_phi = 0; index_phi < N_STEPS_PHI; ++index_phi) {
3769  for (unsigned index_theta = 0; index_theta < N_STEPS_THETA; ++index_theta) {
3770  vtmp.clear();
3771  vangles_tmp.clear();
3772  vangles_tmp.push_back(hypothesis_angles[index_phi][index_theta][0]);
3773  vangles_tmp.push_back(hypothesis_angles[index_phi][index_theta][1]);
3774 
3775  for (unsigned i_sector = 0; i_sector < N_SUMMED_PHI_SECTORS; ++i_sector) {
3776  for (unsigned i_layer = 0; i_layer < N_SUMMED_LAYERS; ++i_layer) {
3777  vtmp.push_back(hypothesis_offsets[center_phi_sector_index][index_phi][index_theta][i_sector][i_layer]);
3778  //if (hypothesis_angles[index_phi][index_theta][0]<-21 && hypothesis_angles[index_phi][index_theta][1] >-29 && hypothesis_angles[index_phi][index_theta][1]<-27)
3779  //cout << vtmp[vtmp.size()-1] << " ";
3780  } // end loop over layer
3781  } // end loop over sector
3782 
3783 
3784  // now loop over all previous offsets and see if it is new or a repeat
3785  int foundone=0;
3786 
3787 
3788  for (unsigned int i=0;i<vdifferent_offsets.size();i++) {
3789  if (vtmp==vdifferent_offsets[i]) {
3790  foundone++;
3791  //if (hypothesis_angles[index_phi][index_theta][0]<-21 && hypothesis_angles[index_phi][index_theta][1] >-29 && hypothesis_angles[index_phi][index_theta][1]<-27)
3792  //cout << "found one is " << foundone << "\n";
3793  }
3794  }
3795  //if (hypothesis_angles[index_phi][index_theta][0]<-21 && hypothesis_angles[index_phi][index_theta][1] >-29 && hypothesis_angles[index_phi][index_theta][1]<-27)
3796  //cout << "just before if statement, found one is " << foundone << "\n";
3797 
3798  if (foundone==0) {
3799  vdifferent_offsets.push_back(vtmp);
3800  vdifferent_angles.push_back(vangles_tmp);
3801  }
3802  //if (hypothesis_angles[index_phi][index_theta][0]<-21 && hypothesis_angles[index_phi][index_theta][1] >-29 && hypothesis_angles[index_phi][index_theta][1]<-27)
3803  //cout << "size of vdifferent_offsets is " << vdifferent_offsets.size() << "\n";
3804  } // end loop over hypotheses in theta
3805  } // end loop over hypotheses in phi
3806  } // end loop over center_phi_sector
3807 }
3808 void Anita::calculate_single_offset(const unsigned center_phi_sector_index, const double angle_phi, const double angle_theta, double hypothesis_offset[][3]) {
3809  double maximum_time = -2000E-9;
3810 
3811  double to_center_of_summed_phi_sectors=((double)N_SUMMED_PHI_SECTORS/2.)*22.5-11.25;
3812  // cout << "to_center_of_summed_phi_sectors is " << to_center_of_summed_phi_sectors << "\n";
3813  Vector normal_vector = Vector(cos(angle_theta * RADDEG) * cos((angle_phi+to_center_of_summed_phi_sectors) * RADDEG), cos(angle_theta * RADDEG) * sin((angle_phi+to_center_of_summed_phi_sectors) * RADDEG), sin(angle_theta * RADDEG));
3814 
3815  // cout << "normal vector is ";
3816  //normal_vector.Print();
3817 
3818  // Vector first_antenna_pos = ANTENNA_POSITION_START[0][3][center_phi_sector_index];
3819  Vector one_antenna_pos = antenna_positions[0][2*16+center_phi_sector_index];
3820  //cout << "one_antenna_pos is ";
3821  //one_antenna_pos.Print();
3822 
3823  int phi_start=-1*(int)((double)N_SUMMED_PHI_SECTORS/2.)+1;
3824 
3825  // cout << "new set of 6.\n";
3826  //cout << "phi_start, phi_end are " << phi_start << "\t" << phi_start+N_SUMMED_PHI_SECTORS << "\n";
3827  //for (signed int phi_sector_offset = phi_start; phi_sector_offset < phi_start+N_SUMMED_PHI_SECTORS; phi_sector_offset++) {
3828  for (signed int phi_sector_offset = phi_start; phi_sector_offset < (int)(phi_start+N_SUMMED_PHI_SECTORS); phi_sector_offset++) {
3829  unsigned i_sector = (phi_sector_offset + center_phi_sector_index + 16)%16; // Must map to {0, ..., 15}.
3830  //cout << "i_sector is " << i_sector << "\n";
3831  for (unsigned i_layer = 0; i_layer < N_SUMMED_LAYERS; ++i_layer) {
3832 
3833 
3834  Vector antenna_pos = antenna_positions[0][16*i_layer+i_sector];
3835  //cout << "i_layer, i_sector are " << i_layer << "\t" << i_sector << "\n";
3836  //cout << "antenna_pos is ";
3837  //antenna_pos.Print();
3838 
3839  double offset = (-1. / CLIGHT) * normal_vector * (antenna_pos - one_antenna_pos);
3840 
3841  // cout << "offset is " << offset << "\n";
3842  if (offset >= maximum_time) {
3843  maximum_time = offset;
3844  }
3845 
3846  //unsigned i_layer_trig = ((i_layer > 1) ? (i_layer - 1) : (0)); // Set i_layer_triger according to the following map:
3847  // 0 -> 0 (if in even phi_sector)
3848  // 1 -> 0 (if in odd phi_sector)
3849  // 2 -> 1
3850  // 3 -> 2
3851  // cout << "phi_sector_offset-phi_start is " << phi_sector_offset-phi_start << "\n";
3852  hypothesis_offset[phi_sector_offset-phi_start][i_layer] = offset; // Use phi_sector_offset + 1 so that it maps {-1, 0, 1} to {0, 1, 2}.
3853  }
3854  }
3855  // cout << "maximum_time is " << maximum_time << "\n";
3856  for (unsigned i_layer = 0; i_layer < N_SUMMED_LAYERS; ++i_layer) {
3857  for (unsigned i_sector = 0; i_sector < N_SUMMED_PHI_SECTORS; ++i_sector) {
3858  hypothesis_offset[i_sector][i_layer] -= maximum_time;
3859  hypothesis_offset[i_sector][i_layer]*=-1.;
3860  }
3861  }
3862  return;
3863 }
3864 
3865 
3866 void Anita::GetArrivalTimes(const Vector& rf_direction,Balloon *bn1, Settings *settings1) {
3867  //cout << "inside getarrivaltimes.\n";
3868 
3869 
3870  for (int ipol=0; ipol<2; ipol++){
3871 
3872  for (int antenna_index = 0; antenna_index < (number_all_antennas); antenna_index++) { //loop over layers on the payload
3873  arrival_times[ipol][antenna_index] = (antenna_positions[ipol][antenna_index] * rf_direction) / CLIGHT;
3874 
3875  //arrival_times[antenna_index] += extraCableDelays[0][antenna_index];
3876 
3877  // cout << "index is " << antenna_index << "\n";
3878  // cout << "antenna_positions are " << antenna_positions[antenna_index] << "\n";
3879  // cout << "rf direction is " << rf_direction << "\n";
3880  // cout << "arrival_times is " << arrival_times[antenna_index] << "\n";
3881  } // for: loop over antenna layers
3882 
3883  if( settings1->WHICH==8 ){//ANITA-II offboresight delay
3884 
3885  Vector rf_tmp_dir = bn1->unRotatePayload(-1*rf_direction);
3886 
3887  double theta_deg =rf_tmp_dir.Theta() * DEGRAD;//
3888 
3889  double phi_deg = rf_tmp_dir.Phi() *DEGRAD;
3890  double totalAngledeg;
3891  double extra_delay;
3892 
3893  double phi_eachlayer;
3894  double theta_offset;
3895  int ant_ctr=0;
3896 
3897  theta_offset = 10;//boresight_vector[ant_ctr].Theta()*DEGRAD;
3898 
3899  theta_deg = theta_deg -90;
3900 
3901 
3902  theta_deg = theta_deg - theta_offset;
3903  for(int iii = 0; iii < 4; iii++){
3904  for(int jjj = 0; jjj < NRX_PHI[iii]; jjj++){
3905 
3906  phi_deg = rf_tmp_dir.Phi();
3907 
3908  phi_eachlayer =atan2(ANTENNA_POSITION_START[ipol][iii][jjj][1],ANTENNA_POSITION_START[ipol][iii][jjj][0]);
3909 
3910  phi_deg =phi_deg- phi_eachlayer;
3911 
3912  if(fabs(phi_deg) > fabs(phi_deg+2*PI)) phi_deg+=2*PI;
3913  if(fabs(phi_deg) > fabs(phi_deg-2*PI)) phi_deg-=2*PI;
3914  phi_deg =phi_deg*DEGRAD;
3915  totalAngledeg = phi_deg*phi_deg + theta_deg*theta_deg;
3916  if(totalAngledeg > 2500) totalAngledeg=2500;
3917 
3918  extra_delay = (totalAngledeg*totalAngledeg)*1.45676e-8;//pulled from Abby analysis
3919  extra_delay -= (totalAngledeg)*5.01452e-6;//pulled from Abby analysis
3920 
3921  arrival_times[ipol][ant_ctr]+=extra_delay*1E-9;
3922  ant_ctr++;
3923  }
3924  }
3925  }
3926 
3927  }
3928 
3929  // double last_trigger_time=Tools::dMax(arrival_times,(number_all_antennas));
3930  //cout << "last_trigger_time is " << last_trigger_time << "\n";
3931  double minV = Tools::dMin(arrival_times[0],(number_all_antennas));
3932  double minH = Tools::dMin(arrival_times[1],(number_all_antennas));
3933  double first_trigger_time = Tools::dMin(minV, minH);
3934  for (int ipol=0; ipol<2; ipol++){
3935  for (int i=0;i<(number_all_antennas);i++){
3936  // cout << "antenna_positions is ";
3937  // antenna_positions[i].Print();
3938  // cout << "diff is ";
3939  // (antenna_positions[i]-one_antenna_position).Print();
3940 
3941  arrival_times[ipol][i] -= first_trigger_time;
3942  // cout << "arrivaltimes is " << arrival_times[i] << "\n";
3943  // arrival_times[i] -= last_trigger_time;
3944 
3945  // if (arrival_times[i] == 0){
3946  // first_phi_sector_hit = (int)((double)i/16.);
3947  // }
3948  }
3949  }
3950  // cout << "end of GetArrivalTimes.\n";
3951 } // GetArrivalTimes
3952 
3953 
3954 void Anita::GetArrivalTimesBoresights(const Vector rf_direction[NLAYERS_MAX][NPHI_MAX],Balloon *bn1, Settings *settings1) {
3955 
3956  for (int ipol=0; ipol<2; ipol++){
3957  for (int antenna_index = 0; antenna_index < (number_all_antennas); antenna_index++) { //loop over layers on the payload
3958  int ilayer = (antenna_index<8)*0 + (antenna_index>7)*(antenna_index<16)*1+ (antenna_index>15)*(antenna_index<32)*2+(antenna_index>31)*3;
3959  int ifold = (ilayer<2)*(antenna_index%8)+(ilayer>1)*(antenna_index%16);
3960  arrival_times[ipol][antenna_index] = (antenna_positions[ipol][antenna_index] * rf_direction[ilayer][ifold]) / CLIGHT;
3961 
3962  // cout << antenna_index << " " << arrival_times[antenna_index] << " " << extraCableDelays[0][antenna_index] << " " ;
3963  // arrival_times[ipol][antenna_index] += extraCableDelays[ipol][antenna_index];
3964  // cout << arrival_times[antenna_index] << endl;
3965 
3966  // arrival_times[antenna_index]=0;
3967 
3968 
3969  if(settings1->WHICH==8 ){//ANITA-II offboresight delay
3970 
3971  Vector rf_tmp_dir = bn1->unRotatePayload(-1*rf_direction[ilayer][ifold]);
3972 
3973  double theta_deg =rf_tmp_dir.Theta() * DEGRAD;//
3974 
3975  double phi_deg = rf_tmp_dir.Phi() *DEGRAD;
3976  double totalAngledeg;
3977  double extra_delay;
3978 
3979  double phi_eachlayer;
3980  double theta_offset;
3981  int ant_ctr=0;
3982 
3983  theta_offset = 10;//boresight_vector[ant_ctr].Theta()*DEGRAD;
3984 
3985  theta_deg = theta_deg -90;
3986 
3987 
3988  theta_deg = theta_deg - theta_offset;
3989 
3990  phi_deg = rf_tmp_dir.Phi();
3991 
3992  phi_eachlayer =atan2(ANTENNA_POSITION_START[ipol][ilayer][ifold][1],ANTENNA_POSITION_START[ipol][ilayer][ifold][0]);
3993 
3994  phi_deg =phi_deg- phi_eachlayer;
3995 
3996  if(fabs(phi_deg) > fabs(phi_deg+2*PI)) phi_deg+=2*PI;
3997  if(fabs(phi_deg) > fabs(phi_deg-2*PI)) phi_deg-=2*PI;
3998  phi_deg =phi_deg*DEGRAD;
3999  totalAngledeg = phi_deg*phi_deg + theta_deg*theta_deg;
4000  if(totalAngledeg > 2500) totalAngledeg=2500;
4001 
4002  extra_delay = (totalAngledeg*totalAngledeg)*1.45676e-8;//pulled from Abby analysis
4003  extra_delay -= (totalAngledeg)*5.01452e-6;//pulled from Abby analysis
4004 
4005  arrival_times[ipol][ant_ctr]+=extra_delay*1E-9;
4006  ant_ctr++;
4007 
4008  }
4009  }
4010  }
4011 
4012  double minV = Tools::dMin(arrival_times[0],(number_all_antennas));
4013  double minH = Tools::dMin(arrival_times[1],(number_all_antennas));
4014  double first_trigger_time = Tools::dMin(minV, minH);
4015  for (int ipol=0; ipol<2; ipol++){
4016  for (int i=0;i<(number_all_antennas);i++){
4017 
4018  arrival_times[ipol][i] -= first_trigger_time;
4019  //cout<<"arrival_times boresight["<<i<<"] is "<<arrival_times[i]<<"\n";
4020  }
4021  }
4022 } // GetArrivalTimesBoresights
4023 
4024 
4025 void Anita::GetArrivalTimesBoresights(const Vector rf_direction[NLAYERS_MAX][NPHI_MAX]) {
4026 
4027  for (int ipol=0; ipol<2; ipol++){
4028  for (int antenna_index = 0; antenna_index < (number_all_antennas); antenna_index++) { //loop over layers on the payload
4029  int ilayer = (antenna_index<8)*0 + (antenna_index>7)*(antenna_index<16)*1+ (antenna_index>15)*(antenna_index<32)*2+(antenna_index>31)*3;
4030  int ifold = (ilayer<2)*(antenna_index%8)+(ilayer>1)*(antenna_index%16);
4031  arrival_times[ipol][antenna_index] = (antenna_positions[ipol][antenna_index] * rf_direction[ilayer][ifold]) / CLIGHT;
4032 
4033  // cout << antenna_index << " " << arrival_times[antenna_index] << " " << extraCableDelays[0][antenna_index] << " " ;
4034  // arrival_times[ipol][antenna_index] += extraCableDelays[ipol][antenna_index];
4035  // cout << arrival_times[antenna_index] << endl;
4036 
4037  // arrival_times[antenna_index]=0;
4038  } // for: loop over antenna layers
4039  }
4040 
4041 
4042  double minV = Tools::dMin(arrival_times[0],(number_all_antennas));
4043  double minH = Tools::dMin(arrival_times[1],(number_all_antennas));
4044  double first_trigger_time = Tools::dMin(minV, minH);
4045  for (int ipol=0; ipol<2; ipol++){
4046  for (int i=0;i<(number_all_antennas);i++){
4047 
4048  arrival_times[ipol][i] = arrival_times[ipol][i] - first_trigger_time + additionalDt;
4049  //cout<<"arrival_times boresight["<<i<<"] is "<<arrival_times[i]<<"\n";
4050  }
4051  }
4052 } // GetArrivalTimesBoresights
4053 
4054 
4055 
4056 
4057 void Anita::setphiTrigMask(UInt_t realTime_flightdata) {
4058 
4059  if (realTime_flightdata<realTime_tr_min || realTime_flightdata>realTime_tr_max) {
4060  phiTrigMask=0; // if the realTime for this balloon position is out of range then just set mask to 0
4061  phiTrigMaskH=0;
4062  l1TrigMask=0;
4063  l1TrigMaskH=0;
4064  deadTime=0;
4065  }
4066  else { // if it's in range
4067 
4068  iturf=turfratechain->GetEntryNumberWithBestIndex(realTime_flightdata); // find entry in turfratechain that is closest to this realTime_flightdata
4069  if (iturf<0){ // if it didn't find one
4070  phiTrigMask=0; // set to zero
4071  phiTrigMaskH=0;
4072  l1TrigMask=0;
4073  l1TrigMaskH=0;
4074  deadTime=0;
4075  }else{
4076  turfratechain->GetEvent(iturf);
4077  }
4078  } // end if it's in range
4079 
4080 }
4081 
4082 
4083 
4084 void Anita::setTimeDependentThresholds(UInt_t realTime_flightdata){
4085 
4086  if (realTime_flightdata<realTime_surf_min || realTime_flightdata>realTime_surf_max) {
4087  for(int ipol=0;ipol<2;ipol++){
4088  for (int iant=0;iant<48;iant++){
4089  scalers[ipol][iant]=thresholds[ipol][iant]=0.;
4090  }
4091  }
4092  }
4093  else { // if it's in range
4094 
4095  isurf=surfchain->GetEntryNumberWithBestIndex(realTime_flightdata); // find entry in surfchain that is closest to this realTime_flightdata
4096  if (isurf<0){ // if it didn't find one
4097  for(int ipol=0;ipol<2;ipol++){
4098  for (int iant=0;iant<48;iant++){
4099  scalers[ipol][iant]=thresholds[ipol][iant]=0.;
4100  }
4101  }
4102  }else{
4103  surfchain->GetEvent(isurf);
4104  }
4105  } // end if it's in range
4106 
4107 
4108 }
4109 
4110 
4111 #ifdef ANITA_UTIL_EXISTS
4112 void Anita::readImpulseResponseDigitizer(Settings *settings1){
4113 
4114  // Set deltaT to be used in the convolution
4115  deltaT = 1./(2.6*16.);
4116  string graphNames[2][3][16];
4117  string fileName;
4118  double norm=1;
4119 
4120  // For ANITA-2 we have 1 impulse response for VPOL and 1 for HPOL
4121  // For ANITA-3 we have 3 impulse responses (Top, Middle, Bottom ring) for VPOL and 3 for HPOL.
4122  // Set Graph names for ANITA-2 and ANITA-3
4123  if (settings1->WHICH==8){
4124  fileName = ICEMC_DATA_DIR+"/sumPicoImpulse.root";
4125 
4126  for (int iring=0;iring<3;iring++){
4127  for (int iphi=1;iphi<17;iphi++){
4128  graphNames[0][iring][iphi]="grImpRespV";
4129  graphNames[1][iring][iphi]="grImpRespH";
4130  }
4131  }
4132  //Now need to scale our impulse response from unit areas to the area of kronecker-delta (i.e dt)
4133  norm*=0.1;
4134  } else if(settings1->WHICH==9 || settings1->WHICH==10){
4135 
4136  fileName = ICEMC_DATA_DIR+"/Anita3_ImpulseResponseDigitizer.root";
4137 
4138  string spol[2] ={"V", "H"};
4139  string sring[3]={"T", "M", "B"};
4140 
4141  for (int ipol=0;ipol<2;ipol++){
4142  for (int iring=0;iring<3;iring++){
4143  for (int iphi=0;iphi<16;iphi++){
4144  graphNames[ipol][iring][iphi] = Form("g%02d%s%s", iphi+1, sring[iring].c_str(), spol[ipol].c_str() ) ;
4145  }
4146  }
4147  }
4148 
4149  // Normalisation of digitizer impulse response might be off by 3dB
4150  // See LC's talk at icemc meeting of 2017 Nov 13
4151  norm *= TMath::Power(10., -3./20.);
4152 
4153  norm *= TMath::Power(10., +1./20.);
4154 
4155  }
4156 
4157  // Read in input file
4158  TFile fImpulse(fileName.c_str());
4159 
4160  if(!fImpulse.IsOpen()) {
4161  std::cerr << "Couldn't read siganl chain impulse response from " << fileName << "\n";
4162  exit(0);
4163  } else {
4164 
4165  for (int ipol=0;ipol<2;ipol++){
4166  for (int iring=0;iring<3;iring++){
4167  for (int iphi=0;iphi<16;iphi++){
4168  // Read graph
4169  TGraph *grTemp = (TGraph*) fImpulse.Get(graphNames[ipol][iring][iphi].c_str());
4170  if(!grTemp) {
4171  std::cerr << "Couldn't read signal chain impulse response" << graphNames[ipol][iring][iphi] << " from file " << fileName << "\n";
4172  exit(0);
4173  }
4174  // Interpolate to high sampling rate that will be used for the convolution
4175  TGraph *grInt = FFTtools::getInterpolatedGraph(grTemp,deltaT);
4176  Int_t nPoints = grInt->GetN();
4177  Double_t *newx = grInt->GetX();
4178  Double_t *newy = grInt->GetY();
4179  // Normalise
4180  for (int i=0;i<nPoints;i++){
4181  newy[i]=newy[i]*norm;
4182  // change time axis from ns to s
4183  newx[i]=newx[i]*1E-9;
4184  }
4185  // Pave to 0
4186  int paveNum = 8533;
4187  grTemp = new TGraph(nPoints, newx, newy);
4188 
4189  fSignalChainResponseDigitizer[ipol][iring][iphi] = new RFSignal(FFTtools::padWaveToLength(grTemp, paveNum));
4190 
4191  delete grInt;
4192  delete grTemp;
4193 
4194  TGraph *gDig = fSignalChainResponseDigitizer[ipol][iring][iphi]->getFreqMagGraph();
4195  // Smooth out the high frequency
4196  double temparray[512];
4197  for(int i=0;i<numFreqs;i++) {
4198  temparray[i] = gDig->Eval(freqs[i]*1e6);
4199  }
4200 
4201  // Smoothing magnitude response a bit to avoid trig/dig ratio explodes
4202  for (int i=0; i<numFreqs;i++){
4203  if (freqs[i]<900.){
4204  fSignalChainResponseA3DigitizerFreqDomain[ipol][iring][iphi][i] = temparray[i];
4205  } else {
4206  fSignalChainResponseA3DigitizerFreqDomain[ipol][iring][iphi][i] = (temparray[i-2] + temparray[i-1] + temparray[i] + temparray[i+1] + temparray[i+2])/5.;
4207  }
4208  fSignalChainResponseDigitizerFreqDomain[ipol][iring][iphi][0][i] = fSignalChainResponseA3DigitizerFreqDomain[ipol][iring][iphi][i];
4209  }
4210 
4211  delete gDig;
4212 
4213  }
4214  }
4215  }
4216  }
4217 
4218 }
4219 
4220 void Anita::readTuffResponseDigitizer(Settings *settings1){
4221  // for loops to make the RFSignal array that can be used in applyImpulseResponseDigitizer of ChanTrigger.cc
4222  // ipol is the polarization "v" or "H"
4223  // ring is the number 3 for tmb or bottom middle top
4224  // iphi is the antenna number
4225  // ituff is the notch directory
4226  TString filename;
4227  string snotch_dir[6]={"notches_260_0_0","notches_260_375_0","notches_260_0_460","notches_260_385_0","notches_260_365_0","notches_260_375_460"};
4228  string spol[2] = {"V","H"};
4229  string sring[3] = {"T","M","B"};
4230  // Set deltaT to be used in the convolution
4231  deltaT = 1./(2.6*16.);
4232 
4233  // Additional norm constant?
4234  // double norm = TMath::Power(10., +6./20.);
4235 // double norm = 100.; // LC: 2019 Dec 11 From John Russell's studies, additional factor of 54.4. 54.4*TMath::Power(10., +6./20.)~100
4236  double norm = 10.; // Let's see if this factor needed to be updated from John Russell's Sep 2020 studies.
4237 
4238  // JR: From 2020 Sep results from John Russell's studies, changing from a global normalization to a per-channel array. As clock channels aren't filled, I decided to set their normalization to 1 to indicate no change.
4239 // std::ifstream channelNormScaleFile(TString::Format("%s/channelNormScale-Anita%d.dat", ICEMC_DATA_DIR.data(), settings1 -> ANITAVERSION).Data()); // Read in file where channel normalization scales stored. Currently for ANITA-4 only.
4240 // int chanIdx = 0;
4241  // double scale;
4242 // double norms[108][6];
4243 
4244 // for (int chanIdx = 0; chanIdx < 108; ++chanIdx) channelNormScaleFile >> norms[chanIdx][0] >> norms[chanIdx][1] >> norms[chanIdx][2] >> norms[chanIdx][3] >> norms[chanIdx][4] >> norms[chanIdx][5];
4245 //
4246 // channelNormScaleFile.close();
4247 
4248  for(int ipol=0; ipol<=1; ipol++) {
4249  for(int iring = 0; iring<=2; iring++){
4250  for(int iphi=0; iphi<=15; iphi++) {
4251  for(int ituff=0; ituff <=6; ituff++) {
4252 
4253  if(ituff==6){
4254  filename = Form("%s/share/AnitaAnalysisFramework/responses/A4noNotches/%02d%s%s.imp",getenv("ANITA_UTIL_INSTALL_DIR"), iphi+1, sring[iring].c_str(), spol[ipol].c_str());
4255  }// if tuffs notches off but tuffs on, these files are loaded and in different directory than other tuff notch configurations
4256  else {
4257  filename = Form("%s/share/AnitaAnalysisFramework/responses/A4ImpulseTUFFs/%s/%02d%s%s.imp",getenv("ANITA_UTIL_INSTALL_DIR"), snotch_dir[ituff].c_str(), iphi+1, sring[iring].c_str(), spol[ipol].c_str());
4258  }// tuff responses with notches on are in different directory than with notches off
4259 
4260  TGraph *gtemp = new TGraph(filename);
4261  // interpolate
4262  TGraph *gint = Tools::getInterpolatedGraph(gtemp,deltaT);
4263 // edits for debugging volumes
4264  Int_t nPoints = gint->GetN();
4265  Double_t *newx = gint->GetX();
4266  Double_t *newy = gint->GetY();
4267 
4268  // Sep 2020, JR: Determine channel index based on ipol, iring, iphi for norms[108].
4269 // int chanIndex = AnitaGeomTool::getChanIndexFromRingPhiPol(AnitaRing::AnitaRing_t(iring), iphi, AnitaPol::AnitaPol_t(ipol));
4270 
4271  // Normalize
4272  for (int i=0;i<nPoints;i++){
4273  // change time axis from ns to s
4274  newx[i]=newx[i]*1E-9;
4275  newy[i]=newy[i]*norm;
4276 // newy[i]=newy[i]*norms[chanIndex][ituff];
4277  }
4278  *gint = TGraph(nPoints,newx,newy);
4279 // end edits for debugging volumes
4280  int paveNum=8533; // change for 0 to just signal back
4281  fSignalChainResponseDigitizerTuffs[ipol][iring][iphi][ituff] = new RFSignal(FFTtools::padWaveToLength(gint, paveNum));
4282  delete gint;
4283  delete gtemp;
4284 
4285  TGraph *gDig = fSignalChainResponseDigitizerTuffs[ipol][iring][iphi][ituff]->getFreqMagGraph();
4286  // Smooth out the high frequency
4287  double temparray[512];
4288  for(int i=0;i<numFreqs;i++) {
4289  temparray[i] = gDig->Eval(freqs[i]*1e6);
4290  }
4291 
4292  // Smoothing magnitude response a bit to avoid trig/dig ratio explodes
4293  for (int i=0; i<numFreqs;i++){
4294  if (freqs[i]<900.){
4295  fSignalChainResponseDigitizerFreqDomain[ipol][iring][iphi][ituff][i] = temparray[i];
4296  } else {
4297  fSignalChainResponseDigitizerFreqDomain[ipol][iring][iphi][ituff][i] = (temparray[i-2] + temparray[i-1] + temparray[i] + temparray[i+1] + temparray[i+2])/5.;
4298  }
4299  }
4300 
4301  delete gDig;
4302 
4303  }// end for loop ituff
4304  } // end for loop iphi
4305  }// end for loop iring
4306  }// end for loop ipol
4307 }
4308 
4309 void Anita::readTuffResponseTrigger(Settings *settings1){
4310  // for loops to make the RFSignal array that can be used in applyImpulseResponseTrigger of ChanTrigger.cc Do we need one for each antenna???
4311  TString filename;
4312  string snotch_dir[7]={"trigconfigA.imp","trigconfigB.imp","trigconfigC.imp","trigconfigG.imp","trigconfigO.imp","trigconfigP.imp","trigconfigK.imp"};
4313  // Set deltaT to be used in the convolution
4314  deltaT = 1./(2.6*16.);
4315  for(int ipol=0; ipol<=1; ipol++) {
4316  for(int iring = 0; iring<=2; iring++){
4317  for(int iphi=0; iphi<=15; iphi++) {
4318  for(int ituff=0; ituff <=6; ituff++) {
4319  filename = Form("%s/share/AnitaAnalysisFramework/responses/A4ImpulseTUFFs/%s",getenv("ANITA_UTIL_INSTALL_DIR"), snotch_dir[ituff].c_str());
4320  //debugging
4321  //cout << Form("%s/share/AnitaAnalysisFramework/responses/TUFFs/%s",getenv("ANITA_UTIL_INSTALL_DIR"), snotch_dir[ituff].c_str()) << endl;
4322  TGraph *gtemp = new TGraph(filename);
4323  // interpolate
4324  TGraph *gint = Tools::getInterpolatedGraph(gtemp,deltaT);
4325 // edits for debugging volumes
4326  Int_t nPoints = gint->GetN();
4327  Double_t *newx = gint->GetX();
4328  Double_t *newy = gint->GetY();
4329  // Normalise
4330  for (int i=0;i<nPoints;i++){
4331  // change time axis from ns to s
4332  newx[i]=newx[i]*1E-9;
4333  }
4334  *gint = TGraph(nPoints,newx,newy);
4335 // end edits for debugging volumes
4336  int paveNum=8533; // change for 0 to just signal back
4337  fSignalChainResponseTriggerTuffs[ipol][iring][iphi][ituff] = new RFSignal(FFTtools::padWaveToLength(gint, paveNum));
4338  delete gint;
4339  delete gtemp;
4340 
4341 
4342  TGraph *gTrig = fSignalChainResponseTriggerTuffs[ipol][iring][iphi][ituff]->getFreqMagGraph();
4343  // Smooth out the high frequency
4344  double temparray[512];
4345  for(int i=0;i<numFreqs;i++) {
4346  temparray[i] = gTrig->Eval(freqs[i]*1e6);
4347  }
4348 
4349  // Smoothing magnitude response a bit to avoid trig/dig ratio explodes
4350  for (int i=0; i<numFreqs;i++){
4351  if (freqs[i]<900.){
4352  fSignalChainResponseTriggerFreqDomain[ipol][iring][iphi][ituff][i] = temparray[i];
4353  } else {
4354  fSignalChainResponseTriggerFreqDomain[ipol][iring][iphi][ituff][i] = (temparray[i-2] + temparray[i-1] + temparray[i] + temparray[i+1] + temparray[i+2])/5.;
4355  }
4356  }
4357 
4358  delete gTrig;
4359  }// end for loop ituff
4360  } // end for loop iphi
4361  }// end for loop iring
4362  }// end for loop ipol
4363 }
4364 
4365 void Anita::readNoiseFromFlight(Settings *settings1){
4366 
4367  TFile *fRayleighAnita3 = new TFile((ICEMC_DATA_DIR+"/RayleighAmplitudesAnita3_noSun_Interp.root").c_str(), "read");
4368 
4369  for (int iant=0;iant<48;iant++){
4370  RayleighFits[0][iant] = (TGraph*)fRayleighAnita3->Get(Form("grSigma%dV_interp", iant+1));
4371  RayleighFits[1][iant] = (TGraph*)fRayleighAnita3->Get(Form("grSigma%dH_interp", iant+1));
4372  }
4373 
4374  Double_t *timeVals = new Double_t [780];
4375  Double_t *voltVals = new Double_t [780];
4376  for(int i=0;i<780;i++){
4377  timeVals[i] = i*1./2.6;
4378  voltVals[i] = 0.1;
4379  }
4380 
4381  RFSignal *rfTemplate = new RFSignal(780,timeVals,voltVals,true);
4382 
4383  numFreqs=rfTemplate->getNumFreqs();
4384  freqs=rfTemplate->getFreqs();
4385 
4386 
4387 }
4388 
4389 
4390 
4391 void Anita::readImpulseResponseTrigger(Settings *settings1){
4392 
4393  // So far only available for ANITA-3
4394 
4395  // Set deltaT to be used in the convolution
4396  deltaT = 1./(2.6*16.);
4397  string graphNames[2][3][16];
4398  string fileName;
4399  double norm=1;
4400 
4401  if(settings1->WHICH==9 || settings1->WHICH==10){
4402  if(settings1->WHICH==9){
4403  fileName = ICEMC_DATA_DIR+"/Anita3_ImpulseResponseTrigger.root";
4404  }
4405  else{
4406  fileName = ICEMC_DATA_DIR+"/Anita4_ImpulseResponseTrigger.root";
4407  }
4408  string spol[2] ={"V", "H"};
4409  string sring[3]={"T", "M", "B"};
4410 
4411  for (int ipol=0;ipol<2;ipol++){
4412  for (int iring=0;iring<3;iring++){
4413  for (int iphi=0;iphi<16;iphi++){
4414  graphNames[ipol][iring][iphi]= Form("gTrigPath") ;
4415  }
4416  }
4417  }
4418 
4419  // Impulse response accounts for trigger/digitizer splitter
4420  // norm *= sqrt(2);
4421  // if we are using the trigger impulse response and the old noise
4422  // we need to add this 7dB attenuation to have sensible results
4423  // see LC's talk on 2017 Nov 13
4424  if (!settings1->NOISEFROMFLIGHTTRIGGER) norm *= TMath::Power(10, -7/20.);
4425  }
4426 
4427  // Read in input file
4428  TFile fImpulse(fileName.c_str());
4429 
4430  if(!fImpulse.IsOpen()) {
4431  std::cerr << "Couldn't read signal chain impulse response from " << fileName << "\n";
4432  exit(0);
4433  } else {
4434 
4435  for (int ipol=0; ipol<2; ipol++){
4436  for (int iring=0; iring<3; iring++){
4437  for (int iphi=0; iphi<16; iphi++){
4438  // Read graph
4439  TGraph *grTemp = (TGraph*) fImpulse.Get(graphNames[ipol][iring][iphi].c_str());
4440  if(!grTemp) {
4441  std::cerr << "Couldn't read signal chain impulse response" << graphNames[ipol][iring][iphi] << " from file " << fileName << "\n";
4442  exit(0);
4443  }
4444  // Interpolate to high sampling rate that will be used for the convolution
4445  TGraph *grInt = FFTtools::getInterpolatedGraph(grTemp,deltaT);
4446  Int_t nPoints = grInt->GetN();
4447  Double_t *newx = grInt->GetX();
4448  Double_t *newy = grInt->GetY();
4449  // Normalise
4450  for (int i=0;i<nPoints;i++){
4451  newy[i]=newy[i]*norm;
4452  // change time axis from ns to s
4453  newx[i]=newx[i]*1E-9;
4454  }
4455  // Pave to 0
4456  int paveNum = 8533;
4457  grTemp = new TGraph(nPoints, newx, newy);
4458 
4459  fSignalChainResponseTrigger[ipol][iring][iphi] = new RFSignal(FFTtools::padWaveToLength(grTemp, paveNum));
4460 
4461  delete grInt;
4462  delete grTemp;
4463 
4464  if (settings1->TUFFSTATUS==0){
4465  TGraph *gTrig = fSignalChainResponseTrigger[ipol][iring][iphi]->getFreqMagGraph();
4466  for(int i=0;i<numFreqs;i++) {
4467  fSignalChainResponseTriggerFreqDomain[ipol][iring][iphi][0][i] = gTrig->Eval(freqs[i]*1e6);
4468  }
4469  delete gTrig;
4470  }
4471 
4472  }
4473  }
4474  }
4475  }
4476 
4477 }
4478 
4479 void Anita::calculateImpulseResponsesRatios(Settings *settings1){
4480 
4481  double denom, dig, trig;
4482 
4483  double norm = 1.;
4484  // thermal noise is calculated from ANITA-3 flight data
4485  // the ANITA-4 thermal noise was roughly 85% of the ANITA-3 one
4486  if (settings1->WHICH==10) norm=0.85;
4487 
4488  for (int ipol=0; ipol<2; ipol++){
4489  for (int iring=0; iring<3; iring++){
4490  for (int iphi=0; iphi<16; iphi++){
4491  for(int ituff=0; ituff<ntuffs; ituff++){
4492 
4493  for(int i=0;i<numFreqs;i++){
4494  denom = fSignalChainResponseA3DigitizerFreqDomain[ipol][iring][iphi][i];
4495  trig = fSignalChainResponseTriggerFreqDomain[ipol][iring][iphi][ituff][i];
4496  dig = fSignalChainResponseDigitizerFreqDomain[ipol][iring][iphi][ituff][i];
4497 
4498  if (freqs[i]<160.) {
4499  fRatioTriggerToA3DigitizerFreqDomain[ipol][iring][iphi][ituff][i] = 0.1;
4500  } else {
4501  fRatioTriggerToA3DigitizerFreqDomain[ipol][iring][iphi][ituff][i] = (trig/denom)*norm;
4502  }
4503 
4504  fRatioDigitizerToA3DigitizerFreqDomain[ipol][iring][iphi][ituff][i] = (dig/denom)*norm;
4505  // cout << "Numbers are " << dig << " " << trig << " " << denom << " " << trig/denom << " " << dig/denom << endl;
4506  }// end for loop to fill fRatioTriggerDigitizerFreqDomain
4507  }// end tuffIndex loop
4508 
4509  } // end for loop over iphi
4510  } // end for loop over iring
4511  } // end for loop over ipol
4512  // delete fout;
4513 
4514 
4515 
4516 
4517 
4518 
4519 }
4520 
4521 
4522 void Anita::readTriggerEfficiencyScanPulser(Settings *settings1){
4523 
4524  if(settings1->WHICH==10 || settings1->WHICH==9){
4525 
4526  if(settings1->WHICH==10){
4527  string fileName = ICEMC_DATA_DIR+"/TriggerEfficiencyScanPulser_anita4_33dB_avg_trimmed.root";
4528  TFile *f = new TFile(fileName.c_str(), "read");
4529  gPulseAtAmpa = (TGraph*)f->Get("Phisector_3_33dBCh1_trimmed");
4530 
4531 // change to nanoseconds from seconds
4532  Int_t nPoints = gPulseAtAmpa->GetN();
4533  Double_t *newx = gPulseAtAmpa->GetX();
4534  Double_t *newy = gPulseAtAmpa->GetY();
4535  Double_t meany = TMath::Mean(nPoints/10, newy);
4536 
4537  for (int i=0;i<nPoints;i++){
4538  // change time axis s to ns
4539  newx[i]=newx[i]*1E9;
4540  newy[i]-=meany;
4541  }
4542  *gPulseAtAmpa = TGraph(nPoints,newx,newy);
4543 // end change to ns
4544 // TCanvas *ctemp = new TCanvas("ctemp");
4545 // gPulseAtAmpa->Draw("AL");
4546 // ctemp->Print("pulse.png");
4547  f->Close();
4548  }
4549  else{
4550  string fileName = ICEMC_DATA_DIR+"/TriggerEfficiencyScanPulser_anita3.root";
4551  TFile *f = new TFile(fileName.c_str(), "read");
4552  // Get average pulse as measured by scope
4553  gPulseAtAmpa = (TGraph*)f->Get("gAvgPulseAtAmpa");
4554 // TCanvas *ctemp = new TCanvas("ctemp");
4555 // gPulseAtAmpa->Draw("AL");
4556 // ctemp->Print("pulse.png");
4557  f->Close();
4558 // cout << "Pulse has this many points " << gPulseAtAmpa->GetN() << endl;
4559 
4560  }
4561  bool useDelayGenerator = false;
4562 
4563  double maxDelays = (Tools::dMax(trigEffScanRingDelay, 3) + Tools::dMax(trigEffScanPhiDelay,5) );
4564  maxDelays -= (Tools::dMin(trigEffScanRingDelay, 3) + Tools::dMin(trigEffScanPhiDelay,5) );
4565 
4566  if (maxDelays!=0) useDelayGenerator=true;
4567 
4568  for (int i=0;i<gPulseAtAmpa->GetN();i++){
4569  if(settings1->WHICH==9){
4570  // 7db fixed attenuation
4571  gPulseAtAmpa->GetY()[i]*=TMath::Power(10,-7./20.);
4572  } else if(settings1->WHICH==10){
4573 
4574  // 0db fixed attenuation
4575 // if(i==1000){
4576 // cout << "y value for entry 1000 before attenuation of 0db is " << gPulseAtAmpa->GetY()[i] << endl;
4577 // }
4578  // Fixed attenuation was -25dB
4579  // Input is the pulse at -33dB variable attenuation
4580  gPulseAtAmpa->GetY()[i]*=TMath::Power(10,(-25.0+33.0)/20.);
4581 
4582 // if(i==1000){
4583 // cout << "y value for entry 1000 is after attenuation of 0db is " << gPulseAtAmpa->GetY()[i] << endl;
4584 // }
4585 
4586  }
4587 
4588  // Variable attenuation of central phi sector
4589  gPulseAtAmpa->GetY()[i]*=TMath::Power(10, trigEffScanAtt[2]*1./20.);
4590 
4591  if(settings1->WHICH==9){
4592  // Signal in a 12-way splitter
4593  gPulseAtAmpa->GetY()[i]*=TMath::Power(10, -10.8/20.);
4594  } else if(settings1->WHICH==10){
4595  // Signal in a 16-way splitter
4596  gPulseAtAmpa->GetY()[i]*=TMath::Power(10, -12./20.);
4597  }
4598 
4599  // Attenutation due to delay generator
4600  if (useDelayGenerator){
4601  gPulseAtAmpa->GetY()[i]*=TMath::Power(10, -12./20.);
4602  }
4603 
4604  // Splitter between digitizer and trigger path
4605  gPulseAtAmpa->GetY()[i]*=TMath::Power(10,-3./20.);
4606 
4607  }
4608 
4609 // TCanvas *ctemp2 = new TCanvas("ctemp2");
4610 // gPulseAtAmpa->Draw("AL");
4611 // ctemp2->Print("pulse_after_atten.png");
4612 
4613  // To get the correct interpolation we need to shift the waveform
4614  // We shift it by 8*(1/(2.6*16)) ns
4615 
4616  double *x = gPulseAtAmpa->GetX();
4617  double *y = gPulseAtAmpa->GetY();
4618  double xnew[10000], ynew[10000];
4619  int N = gPulseAtAmpa->GetN();
4620 
4621  int newn = N - 6;
4622 
4623  for (int j=6; j<N; j++){
4624  xnew[j-6] = x[j];
4625  ynew[j-6] = y[j];
4626  }
4627 
4628  TGraph *gtemp = new TGraph (newn, xnew, ynew);
4629 
4630  TGraph *gPulseAtAmpaInt = FFTtools::getInterpolatedGraph(gtemp, 1/2.6);
4631 
4632  for (int i=0;i<HALFNFOUR;i++){
4633  trigEffScanPulseAtAmpa[i] = gPulseAtAmpaInt->Eval(fTimes[i]);
4634  }
4635  if(settings1->WHICH==9){
4636  gPulseAtAmpa = FFTtools::translateGraph(gPulseAtAmpa, 77.5721);
4637  }
4638 // TCanvas *ctemp1 = new TCanvas("ctemp1");
4639 // gPulseAtAmpa->Draw("AL");
4640 // ctemp1->Print("pulse_after_interp.png");
4641 
4642  delete gPulseAtAmpaInt;
4643  delete gtemp;
4644 
4645  if(settings1->WHICH==9){
4646  string fileName = ICEMC_DATA_DIR+"/TriggerEfficiencyScanPulser_anita3.root";
4647  TFile *f = new TFile(fileName.c_str(), "read");
4648 
4649  for (int isample=0;isample<250;isample++){
4650  // Get average waveform at SURF as measured by scope
4651  TGraph *gPulseAtSurf = (TGraph*)f->Get(Form("gSamplePulseAtSurf_%i", isample));
4652 
4653  TGraph *gPulseAtSurfInt = FFTtools::getInterpolatedGraph(gPulseAtSurf, 1/(2.6));
4654  double *y2 = gPulseAtSurfInt->GetY();
4655  // 20dB attenuation was applied at the scope
4656  for (int i=0;i<HALFNFOUR;i++){
4657  trigEffScanPulseAtSurf[isample][i]=y2[i]/10.;
4658  }
4659 
4660  delete gPulseAtSurfInt;
4661  delete gPulseAtSurf;
4662  }
4663  f->Close();
4664 
4665  }
4666  }
4667  else {
4668  cout << "Impulse response on trigger path can only be used with ANITA-3 or ANITA-4" << endl;
4669  exit(1);
4670  }
4671 
4672 }
4673 
4674 #endif
4675 
4676 
4677 void Anita::calculateDelaysForEfficiencyScan(){
4678 
4679  int irx, phiIndex;
4680 
4681  for (int iant=0; iant<48; iant++){
4682 
4683  phiIndex = trigEffScanPhi - (iant%16);
4684  if (phiIndex>8) phiIndex=phiIndex-16;
4685 
4686  if(TMath::Abs(phiIndex)<=2){
4687 
4688  irx = iant;
4689  if (iant<16) {
4690  if (iant%2==0) irx = iant/2;
4691  else irx = 8 + iant/2;
4692  }
4693 
4694  // Add phi sector delay
4695  arrival_times[0][irx] += trigEffScanPhiDelay[phiIndex+2];
4696 
4697  // Check if we are adding the ring delay to this phi sector
4698  if (trigEffScanApplyRingDelay[phiIndex+2]>0){
4699  // Add ring delay (T-M, M-B, T-B)
4700  if (iant<16) arrival_times[0][irx] += trigEffScanRingDelay[0] + trigEffScanRingDelay[2];
4701  else if (iant<32) arrival_times[0][irx] += trigEffScanRingDelay[1];
4702 
4703  }
4704  }
4705 
4706  }
4707 
4708 }
double phi_bn
theta,phi of balloon wrt south pole
Definition: balloon.hh:65
static AnitaEventCalibrator * Instance(int version=0)
Instance generator.
int GetRxTriggerNumbering(int ilayer, int ifold)
get antenna number based on which layer and position it is
Definition: anita.cc:208
static Int_t getAntPolFromSurfChan(Int_t surf, Int_t chan, Int_t &ant, AnitaPol::AnitaPol_t &pol)
Convert surf-chan to ant-pol.
TGraph * padWaveToLength(const TGraph *grA, Int_t newLength)
Zero pad a wave making it up to newLength points.
Definition: FFTtools.cxx:1769
This is a wrapper class for an RF Signal.
Definition: RFSignal.h:12
const char * ICEMC_SRC_DIR()
void Initialize(Settings *settings1, ofstream &foutput, int inu, TString outputdir)
initialize a bunch of stuff
Definition: anita.cc:249
TGraph * getInterpolatedGraph(const TGraph *grIn, Double_t deltaT)
Interpolation Routines that use ROOT::Math::Interpolator.
Definition: FFTtools.cxx:32
AnitaEventCalibrator – The ANITA Event Calibrator.
TGraph * translateGraph(const TGraph *grWave, const Double_t deltaT)
Returns a graph translated by deltaT. Such that t&#39;=t+dt.
Definition: FFTtools.cxx:1619
Reads in and stores input settings for the run.
Definition: Settings.h:37
static double GetNoise(Settings *settings1, double altitude_bn, double geoid, double theta, double bw, double temp)
Get Noise.
double BN_LONGITUDE
balloon longitude for fixed balloon location
Definition: balloon.hh:88
void ConvertHVtoLRTimedomain(const int nfour, double *vvolts, double *hvolts, double *left, double *right)
Definition: Tools.cc:746
This is a wrapper class for a complex number.
Definition: FFTWComplex.h:12
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
int GetRx(int ilayer, int ifold)
get antenna number based on which layer and position it is
Definition: anita.cc:197
Handles everything related to balloon positions, payload orientation over the course of a flight...
Definition: balloon.hh:30
This class represents a three-vector. Operators are overloaded to provide for the familiar operations...
Definition: vector.hh:27
static const int NPHI_MAX
max number of antennas around in phi (in smex, 16)
Definition: anita.hh:61
Double_t relativePhaseCenterToAmpaDelays[12][9]
From phase center to AMPAs (hopefully)
enum AnitaPol::EAnitaPol AnitaPol_t
Polarisation enumeration.
static AnitaGeomTool * Instance(int anita_version=0)
Instance generator. If version_number == 0, uses AnitaVersion::get();.
AnitaGeomTool – The ANITA Geometry Tool.
Definition: AnitaGeomTool.h:48
Ice thicknesses and water depth.
Definition: icemodel.hh:103