testWAIS.cc
1 //saw Author: Linda Cremonesi
2  // Email: l.cremonesi@ucl.ac.uk
3 
4  //Description:
5  //Template to generate triggers coming from WAIS pulses
6 //***********************************************************************************************************/
7 #include <iostream>
8 #include <fstream>
9 #include <sstream>
10 #include <math.h>
11 #include <ctype.h>
12 #include <string>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <vector>
16 #include <array>
17 #include <time.h>
18 #include "TTreeIndex.h"
19 #include "TChain.h"
20 #include "TH1.h"
21 #include "TF1.h"
22 #include "TF2.h"
23 #include "TFile.h"
24 #include "icemc_random.h"
25 #include "TTree.h"
26 #include "TLegend.h"
27 #include "TLine.h"
28 #include "TROOT.h"
29 #include "TPostScript.h"
30 #include "TCanvas.h"
31 #include "TH2F.h"
32 #include "TText.h"
33 #include "TProfile.h"
34 #include "TGraphErrors.h"
35 #include "TGraphAsymmErrors.h"
36 #include "TStyle.h"
37 #include "TMath.h"
38 #include <unistd.h>
39 #include "TVector3.h"
40 #include "TRotation.h"
41 #include "TSpline.h"
42 #include "Math/InterpolationTypes.h"
43 #include "Math/Interpolator.h"
44 #include "signal.h"
45 
46 #include "EnvironmentVariable.h"
47 
48 //#include "rx.hpp"
49 #include "Constants.h"
50 #include "Settings.h"
51 #include "position.hh"
52 
53 #include "earthmodel.hh"
54 #include "Tools.h"
55 #include "vector.hh"
56 #include "roughness.hh"
57 #include "anita.hh"
58 #include "balloon.hh"
59 #include "icemodel.hh"
60 // #include "trigger.hh"
61 #include "Spectra.h"
62 #include "signal.hh"
63 #include "secondaries.hh"
64 #include "ray.hh"
65 #include "counting.hh"
66 #include "Primaries.h"
67 #include "Taumodel.hh"
68 #include "screen.hh"
69 #include "GlobalTrigger.h"
70 #include "ChanTrigger.h"
71 
72 #include <string>
73 #include <sstream>
74 
75 #if __cplusplus > 199711L
76 #include <type_traits>
77 #endif
78 
79 #include <typeinfo>
80 
81 #ifdef ANITA_UTIL_EXISTS
82 #include "UsefulAnitaEvent.h"
83 #include "AnitaGeomTool.h"
84 #include "AnitaConventions.h"
85 #include "RawAnitaHeader.h"
86 #include "Adu5Pat.h"
87 #include "FFTtools.h"
88 UsefulAnitaEvent* realEvPtr = NULL;
89 RawAnitaHeader* rawHeaderPtr = NULL;
90 Adu5Pat* Adu5PatPtr = NULL;
91 #ifdef ANITA3_EVENTREADER
92 #include "TruthAnitaEvent.h"
93 TruthAnitaEvent* truthEvPtr = NULL;
94 #endif
95 #endif
96 
97 Taumodel* TauPtr = NULL;
98 
99 const string ICEMC_SRC_DIR = EnvironmentVariable::ICEMC_SRC_DIR();
100 
101 ClassImp(RX);
102 
103 using namespace std;
104 
105 class EarthModel;
106 class Position;
107 
108 
109 // functions
110 
111 
112 #ifdef ANITA_UTIL_EXISTS
113 int GetIceMCAntfromUsefulEventAnt(Settings *settings1, int UsefulEventAnt);
114 #ifdef R_EARTH
115 #undef R_EARTH
116 #endif
117 #endif
118 
119 bool ABORT_EARLY = false; // This flag is set to true when interrupt_signal_handler() is called
120 
121 
122 double ScaleVmMHz(double vmmhz1m_max, const Position &posnu1, const Position &r_bn);
123 
124 void interrupt_signal_handler(int sig);
125 
126 //void read_pulser_electric_field(string efield_file_name, double *&time, double *&voltsperm);
127 //void read_pulser_electric_field(string efield_file_name, double *&time, double *&voltsperm){
128 void read_pulser_electric_field(string efield_file_name, vector<double> &time, vector<double> &voltsperm);
129 void read_pulser_electric_field(string efield_file_name, vector<double> &time, vector<double> &voltsperm){
130 
131  ifstream input_stream(efield_file_name.c_str());
132 
133  string buffer;
134  int c = 0;
135 
136  while(!input_stream.eof())
137  {
138  getline(input_stream,buffer,'\n');
139  //skip the header
140  if( c != 0){
141  //simple stringstream read which assumes each line is "index,volts,time" with no spaces
142  //or any other funny business. The ignore commands skip the commans
143  stringstream ss;
144  int ind=-999;
145  float v=-999., t=-999.;
146  ss << buffer;
147 
148  ss >> ind;
149  ss.ignore(1);
150  ss >> v;
151  ss.ignore(1);
152  ss >> t;
153  ss.ignore(1);
154 
155  if( ind != -999 )
156  {
157  voltsperm.push_back(v);
158  time.push_back(t);
159  //cout << buffer << endl;
160  cout << c-1 << "\t" << time[c-1] << "\t" << voltsperm[c-1] << endl;
161  }
162  }
163 
164  if(!input_stream.eof())
165  c = c + 1;
166  }
167  cout << "Counted " << c << " rows from electric field file" << efield_file_name.c_str() << endl;
168 
169  input_stream.close();
170 }
171 
172 int main(int argc, char **argv) {
173 
174  string stemp;
175 
176  Settings* settings1 = new Settings();
177 
178  string input="inputs.txt";
179  string run_num;//current run number as string
180  int run_no = 0;//current run number as integer
181  TString outputdir;
182 
183  if( (argc%3!=1)&&(argc%2!=1)) {
184  cout << "Syntax for options: -i inputfile -o outputdir -r run_number\n";
185  return 0;
186  }
187  int nnu_tmp=0;
188  double exp_tmp=0;
189  double trig_thresh=0.;
190  char clswitch; // command line switch
191  if (argc>1) {
192  while ((clswitch = getopt(argc, argv, "t:i:o:r:n:e:")) != EOF) {
193  switch(clswitch) {
194  case 'n':
195  nnu_tmp=atoi(optarg);
196  cout << "Changed number of simulated neutrinos to " << nnu_tmp << endl;
197  break;
198  case 't':
199  trig_thresh=atof(optarg);
200  break;
201  case 'i':
202  input=optarg;
203  cout << "Changed input file to: " << input << endl;
204  break;
205  case 'o':
206  outputdir=optarg;
207  cout << "Changed output directory to: " << outputdir.Data() << endl;
208  stemp="mkdir -p " + string(outputdir.Data());
209  system(stemp.c_str());
210  break;
211  case 'e':
212  exp_tmp=atof(optarg);
213  cout << "Changed neutrino energy exponent to " << exp_tmp << endl;
214  break;
215  case 'r':
216  run_num=optarg;
217  stringstream convert(run_num);
218  convert>>run_no;
219  break;
220  } // end switch
221  } // end while
222  } // end if arg>1
223 
224 
225  settings1->SEED=settings1->SEED +run_no;
226  cout <<"seed is " << settings1->SEED << endl;
227 
228  setSeed(settings1->SEED);
229 
230  Balloon *bn1=new Balloon(); // instance of the balloon
231  Anita *anita1=new Anita();// right now this constructor gets banding info
232  Secondaries *sec1=new Secondaries();
233  Primaries *primary1=new Primaries();
234  Signal *sig1=new Signal();
235  Ray *ray1=new Ray(); // create new instance of the ray class
236  Counting *count1=new Counting();
237  GlobalTrigger *globaltrig1;
238  // Taumodel *taus1 = new Taumodel();
239  // input parameters
240 
241  double vmmhz[Anita::NFREQ]; // V/m/MHz at balloon (after all steps)
242  // given the angle you are off the Cerenkov cone, the fraction of the observed e field that comes from the em shower
243  double vmmhz_em[Anita::NFREQ];
244  double vmmhz_max;
245  double vmmhz1m;
246 
247 
248  stemp=string(outputdir.Data())+"/output"+run_num+".txt";
249  ofstream foutput(stemp.c_str(), ios::app);
250 
251  int NNU;
252  double RANDOMISEPOL=0.;
253  int inu=0;
254  int neutrinos_passing_all_cuts=0;
255  double weight=0;
256  int discones_passing=0; // number of discones that pass
257 
258  settings1->ReadInputs(input.c_str(), foutput, NNU, RANDOMISEPOL);
259  settings1->ApplyInputs(anita1, sec1, sig1, bn1, ray1);
260  sig1->Initialize();
261 
262  settings1->SEED=settings1->SEED + run_no;
263  setSeed(settings1->SEED);
264 
265  bn1->InitializeBalloon();
266  anita1->Initialize(settings1, foutput, inu, outputdir);
267 
268  if (trig_thresh!=0)
269  anita1->powerthreshold[4]=trig_thresh;
270  if (nnu_tmp!=0)
271  NNU=nnu_tmp;
272  if (exp_tmp!=0)
273  settings1->EXPONENT=exp_tmp;
274 
275 
276 
277  Interaction *interaction1=new Interaction("nu", primary1, settings1, 0, count1);
278 
279  // create new instance of the screen class
280  // only using the specular case as we are ignoring the ice
281  Screen *panel1 = new Screen(0);
282 
283  time_t raw_start_time = time(NULL);
284  struct tm * start_time = localtime(&raw_start_time);
285 
286  cout << "Date and time at start of run are: " << asctime (start_time) << "\n";
287 
288 
289  Tools::Zero(anita1->NRX_PHI, Anita::NLAYERS_MAX);
290  for (int i=0;i<Anita::NLAYERS_MAX;i++) {
291  Tools::Zero(anita1->PHI_EACHLAYER[i], Anita::NPHI_MAX);
292  }
293  Tools::Zero(anita1->PHI_OFFSET, Anita::NLAYERS_MAX);
294  Tools::Zero(anita1->THETA_ZENITH, Anita::NLAYERS_MAX);
295  Tools::Zero(anita1->LAYER_VPOSITION, Anita::NLAYERS_MAX);
296  Tools::Zero(anita1->RRX, Anita::NLAYERS_MAX);
297 
298  double volts_rx_rfcm_lab_e_all[48][512];
299  double volts_rx_rfcm_lab_h_all[48][512];
300 
301 
302  Vector n_eplane = const_z;
303  Vector n_hplane = -const_y;
304  Vector n_normal = const_x;
305 
306  Vector n_pol; // direction of polarization
307  Vector n_pol_eachboresight[Anita::NLAYERS_MAX][Anita::NPHI_MAX]; // direction of polarization of signal seen at each antenna
308 
309  // variable declarations for functions GetEcompHcompEvector and GetEcompHcompkvector - oindree
310  double e_component[Anita::NANTENNAS_MAX]={0}; // E comp along polarization
311  double h_component[Anita::NANTENNAS_MAX]={0}; // H comp along polarization
312  double n_component[Anita::NANTENNAS_MAX]={0}; // normal comp along polarization
313 
314  double e_component_kvector[Anita::NANTENNAS_MAX]={0}; // component of e-field along the rx e-plane
315  double h_component_kvector[Anita::NANTENNAS_MAX]={0}; // component of the e-field along the rx h-plane
316  double n_component_kvector[Anita::NANTENNAS_MAX]={0}; // component of the e-field along the normal
317 
318 
319 
320 
321  double hitangle_e, hitangle_h; // angle the ray hits the antenna wrt e-plane, h-plane
322  double hitangle_e_all[Anita::NANTENNAS_MAX]; // hit angles rel. to e plane stored for each antenna
323  double hitangle_h_all[Anita::NANTENNAS_MAX]; // hit angles rel. to h plane stored for each antenna
324 
325  double sourceLon;
326  double sourceAlt;
327  double sourceLat;
328 
329  int l3trignoise[Anita::NPOL]; // 16 bit number which says which phi sectors pass L3 V-POL
330 
331  int l3trig[Anita::NPOL]; // 16 bit number which says which phi sectors pass L3 V-POL
332  // For each trigger layer, which "clumps" pass L2. 16 bit, 16 bit and 8 bit for layers 1 & 2 and nadirs
333  int l2trig[Anita::NPOL][Anita::NTRIGGERLAYERS_MAX];
334  //For each trigger layer, which antennas pass L1. 16 bit, 16 bit and 8 bit and layers 1, 2 and nadirs
335  int l1trig[Anita::NPOL][Anita::NTRIGGERLAYERS_MAX];
336 
337  // these are declared here so that they can be stuck into trees
338  int loctrig[Anita::NPOL][Anita::NLAYERS_MAX][Anita::NPHI_MAX]; //counting how many pass trigger requirement
339 
340  int loctrig_nadironly[Anita::NPOL][Anita::NPHI_MAX]; //counting how many pass trigger requirement
341 
342  int nchannels_triggered = 0; // total number of channels triggered
343  int nchannels_perrx_triggered[48]; // total number of channels triggered
344 
345 
346  Tools::Zero(count1->npass, 2); // sums events that pass, without weights
347 
348  UInt_t eventNumber;
349 
350 #ifdef ANITA_UTIL_EXISTS
351 
352  string outputAnitaFile =string(outputdir.Data())+"/SimulatedAnitaEventFile"+run_num+".root";
353  TFile *anitafileEvent = new TFile(outputAnitaFile.c_str(), "RECREATE");
354 
355  TTree *eventTree = new TTree("eventTree", "eventTree");
356  eventTree->Branch("event", &realEvPtr );
357  eventTree->Branch("run", &run_no, "run/I" );
358  eventTree->Branch("weight", &weight, "weight/D");
359 
360  outputAnitaFile =string(outputdir.Data())+"/SimulatedAnitaHeadFile"+run_num+".root";
361  TFile *anitafileHead = new TFile(outputAnitaFile.c_str(), "RECREATE");
362 
363  TTree *headTree = new TTree("headTree", "headTree");
364  headTree->Branch("header", &rawHeaderPtr );
365  headTree->Branch("weight", &weight, "weight/D");
366 
367  outputAnitaFile =string(outputdir.Data())+"/SimulatedAnitaGpsFile"+run_num+".root";
368  TFile *anitafileGps = new TFile(outputAnitaFile.c_str(), "RECREATE");
369 
370  TTree *adu5PatTree = new TTree("adu5PatTree", "adu5PatTree");
371  adu5PatTree->Branch("pat", &Adu5PatPtr );
372  adu5PatTree->Branch("eventNumber", &eventNumber, "eventNumber/I");
373  adu5PatTree->Branch("weight", &weight, "weight/D" );
374 
375  AnitaGeomTool *AnitaGeom1 = AnitaGeomTool::Instance();
376 
377 #ifdef ANITA3_EVENTREADER
378 
379  // Set AnitaVersion so that the right payload geometry is used
380  AnitaVersion::set(settings1->ANITAVERSION);
381 
382  outputAnitaFile =string(outputdir.Data())+"/SimulatedAnitaTruthFile"+run_num+".root";
383  TFile *anitafileTruth = new TFile(outputAnitaFile.c_str(), "RECREATE");
384 
385  TString icemcgitversion = TString::Format("%s", EnvironmentVariable::ICEMC_VERSION(outputdir));
386  printf("ICEMC GIT Repository Version: %s\n", icemcgitversion.Data());
387  unsigned int timenow = time(NULL);
388 
389  TTree *configAnitaTree = new TTree("configIcemcTree", "Config file and settings information");
390  configAnitaTree->Branch("gitversion", &icemcgitversion );
391  configAnitaTree->Branch("startTime", &timenow );
392  // configAnitaTree->Branch("settings", &settings1 );
393  configAnitaTree->Fill();
394 
395  TTree *triggerSettingsTree = new TTree("triggerSettingsTree", "Trigger settings");
396  triggerSettingsTree->Branch("dioderms", anita1->bwslice_dioderms_fullband_allchan, "dioderms[2][48][7]/D");
397  triggerSettingsTree->Branch("diodemean", anita1->bwslice_diodemean_fullband_allchan, "diodemean[2][48][7]/D");
398  triggerSettingsTree->Fill();
399 
400  TTree *truthAnitaTree = new TTree("truthAnitaTree", "Truth Anita Tree");
401  truthAnitaTree->Branch("truth", &truthEvPtr );
402 #endif
403 
404 #endif
405  //end ROOT variable definitions
407 
408 
409  IceModel *antarctica = new IceModel(settings1->ICE_MODEL + settings1->NOFZ*10, settings1->CONSTANTICETHICKNESS * 1000 + settings1->CONSTANTCRUST * 100 + settings1->FIXEDELEVATION * 10 + 0, settings1->WEIGHTABSORPTION);
410 
411  // fills arrays according to antenna specs
412  anita1->GetBeamWidths(settings1); // this is used if GAINS set to 0
413  // Antenna measured gain vs. frequency
414  anita1->ReadGains(); // this is used if GAINS set to 1
415  anita1->Set_gain_angle(settings1, sig1->NMEDIUM_RECEIVER);
416 
417 
418  // sets position of balloon and related quantities
419  // these are all passed as pointers
420  // theta, phi, altitude of balloon
421  // position of balloon, altitude and position of surface of earth (relative to the center of the earth) under balloon
422  bn1->SetDefaultBalloonPosition(antarctica);
423 
424  anita1->SetNoise(settings1, bn1, antarctica);
425  //pathtree->Fill(); //Added by Stephen for verification of path
426 
427  // find the maximum distance the interaction could be from the balloon and still be within the horizon.
428  antarctica->GetMAXHORIZON(bn1);
429 
430  // calculate the volume of ice seen by the balloon for all balloon positions
431  antarctica->CreateHorizons(settings1, bn1, bn1->theta_bn, bn1->phi_bn, bn1->altitude_bn, foutput);
432  cout << "Done with CreateHorizons.\n";
433 
434  // builds payload based on read inputs
435  anita1->GetPayload(settings1, bn1);
436 
437  if (settings1->TRIGGERSCHEME == 3 || settings1->TRIGGERSCHEME == 4 || settings1->TRIGGERSCHEME==5) {
438  Vector plusz(0., 0., 1.);
439  bn1->PickBalloonPosition(plusz, antarctica, settings1, anita1);
440  anita1->calculate_all_offsets();
441  double angle_theta=16.;
442  double angle_phi=0.;
443  Vector x = Vector(cos(angle_theta * RADDEG) * cos((angle_phi+11.25) * RADDEG),
444  cos(angle_theta * RADDEG) * sin((angle_phi+11.25) * RADDEG),
445  sin(angle_theta * RADDEG));
446  anita1->GetArrivalTimes(x,bn1,settings1);
447  cout << "end of getarrivaltimes\n";
448  }
449 
450  time_t raw_loop_start_time = time(NULL);
451  cout<<"Starting loop over events. Time required for setup is "<<(int)((raw_loop_start_time - raw_start_time)/60)<<":"<< ((raw_loop_start_time - raw_start_time)%60)<<endl;
452 
453  signal(SIGINT, interrupt_signal_handler); // This function call allows icemc to gracefully abort and write files as usual rather than stopping abruptly.
454 
455  int passes_thisevent=0;
456  int passestrigger=0;
457  int count_total=0;
458  int count_rx=0;
459  int antNum=0;
460 
461 
462  double justNoise_trig[2][48][512];
463  double justSignal_trig[2][48][512];
464  double justNoise_dig[2][48][512];
465  double justSignal_dig[2][48][512];
466 
467  double thresholdsAnt[48][2][5];
468 
469  // ANITA-3 WAIS location by default
470  // If ANITA_UTIL_EXISTS then the appropriate location will be loaded
471  Double_t latWAIS = sourceLat = - ( 79 + (27.93728/60) ) ;
472  Double_t lonWAIS = sourceLon = - (112 + ( 6.74974/60) ) ;
473  Double_t altWAIS = sourceAlt = 1775.68;
474 
475 #ifdef ANITA_UTIL_EXISTS
476  latWAIS = AnitaLocations::getWaisLatitude() ;
477  lonWAIS = AnitaLocations::getWaisLongitude() ;
478  altWAIS = AnitaLocations::getWaisAltitude() ;
479 #endif
480 
481  Double_t phiWAIS = EarthModel::LongtoPhi_0isPrimeMeridian(lonWAIS);
482  Double_t thetaWAIS = (90.+latWAIS)*RADDEG;
483  Double_t elevationWAIS = altWAIS + antarctica->Geoid(latWAIS);
484  Double_t distanceFromWAIS = 0.;
485 
486  Position positionWAIS = Position(lonWAIS, 90.+latWAIS, elevationWAIS);
487 
488  Vector surfaceNormalWAIS = antarctica->GetSurfaceNormal(positionWAIS);
489 
490  // LC: If we turn on this flag, then we can use different phases when applying the antenna gain
491  anita1->USEPHASES=1;
492 
493  Bool_t isDead;
494 
495  // SAW: Adding pulser model
496  // Not the most elegant...
497  cout << "Reading pulser model: " <<endl;
498  //SAW sample rate on this model is not quite right.
499  //string fname = ICEMC_SRC_DIR +"/data/var31_minialfa_icemc2icemc_input_electric_field_1m.dat";
500  //
501  // SAW The file below has the correct spacing for the phase and electric field in volts/m/mhz
502  //
503  // We need the frequency spectrum to have 256 frequency bins with a bin spacing of 5.07812 MHz
504  // so that it can be properly convolved with the ANITA signal electronics.
505  //
506  // Since RFSignal calculates a the frequency binning from the length of the waveform and the deltaT,
507  // that sets the requirements on the waveform to be
508  // length = 2 x NFREQ - 1 = 511
509  // deltaT = 1/(length x df ) = 3.85368436041e-10 s
510 
511  string fname = ICEMC_SRC_DIR + "/data/var31_minialfa_icemc2icemc_input_electric_field_1m_511points_window.dat";
512  cout << fname << endl;
513 
514  vector<double> time;
515  vector<double> voltsperm;
516  read_pulser_electric_field(fname,time,voltsperm);
517  RFSignal *wais_pulser = new RFSignal(time.size(), &time[0], &voltsperm[0], 0);
518 
519  Double_t *wais_pulser_freqs = wais_pulser->getFreqs();
520  Double_t *wais_pulser_mags = wais_pulser->getMags();
521  Double_t *wais_pulser_phases = wais_pulser->getPhases();
522  Int_t wais_nfreqs = wais_pulser->getNumFreqs() ;
523 
524  Double_t dt = time[1]-time[0];
525  Double_t df = wais_pulser_freqs[1] - wais_pulser_freqs[0];
526  cout << "Frequency spacing of the wais pulser model : "<< df << endl;
527  cout << "DeltaT of wais pulser model " << dt << endl;
528  cout << "N " << time.size() << " NFREQS " << wais_pulser->getNumFreqs() << " " << endl;
529  TGraph *gwaisFreqMagGraph = wais_pulser->getFreqMagGraph();
530  gwaisFreqMagGraph->Print();
531  cout << "Phases " << wais_pulser_phases[0] << " " << wais_pulser_phases[10] << " " << wais_pulser_phases[100] << endl;
532  //wais_pulser->fillFreqStuff(); //JS: edited
533  //cout <<wais_pulser_mags[1]<< endl; //JS: edited
534  // begin looping over NNU neutrinos doing the things
535  int a = 0;
536  //for (a = 1; a < run_no; a++) { //JS: trying to get it to do all runs at once
537  for (inu = 0; inu < NNU; inu++) {
538  settings1->MINBIAS=1;
539  if (NNU >= 100) {
540  if (inu % (NNU / 100) == 0)
541  cout << inu << " neutrinos. " << (double(inu)/double(NNU)) * 100 << "% complete.\n";
542  }
543  else
544  cout << inu << " neutrinos. " << (double(inu) / double(NNU)) * 100 << "% complete.\n";
545 
546 
547  eventNumber=(UInt_t)(run_no)*NNU+inu; //replaced a where run_no was
548 
549  // Set seed of all random number generators to be dependent on eventNumber
550  setSeed(eventNumber);
551 
552  anita1->passglobtrig[0]=0;
553  anita1->passglobtrig[1]=0;
554  passes_thisevent=0;
555  passestrigger=0;
556  count_total++;
557  //cout << "got to number 1!" << endl;
558  // initializing the voltage seen by each polarization of each antenna
559  bn1->dtryingposition=0;
560  for (int i=0; i<Anita::NFREQ;i++) {
561  vmmhz[i] = 0.; // the full signal with all factors accounted for (1/r, atten. etc.)
562  vmmhz_em[i]=0.; // for keeping track of just the em component of the shower
563  } //Zero the vmmhz array - helpful for banana plots, shouldn't affect anything else - Stephen
564  //cout << "got to number 2!" << endl;
565  // Fix interaction position to WAIS location
566  interaction1->posnu = positionWAIS;
567  interaction1->posnu_down = positionWAIS;
568 
569  // Picks the balloon position and at the same time sets the masks and thresholds
570  bn1->PickBalloonPosition(antarctica, settings1, inu, anita1, getRNG(RNG_BALLOON_POSITION)->Rndm());
571 
572  distanceFromWAIS = (interaction1->posnu.Distance(bn1->r_bn));
573  // cout << "distance is" << distanceFromWAIS << endl;
574  // eliminate stuff when we are more than 1000km from WAIS
575  if (distanceFromWAIS > 10e6) {
576  // std::cout << "Too far from WAIS " << interaction1->posnu << " and ballon is " << (bn1->r_bn) << " \t " << distanceFromWAIS <<std::endl;
577  continue;
578  }
579  interaction1->nnu = (bn1->r_bn - interaction1->posnu);
580  interaction1->nnu = interaction1->nnu.Unit();
581 
582 
583  isDead = false;
584  // Dead time
585  if (settings1->USEDEADTIME){
586  // cout << anita1->deadTime << endl;
587  if ( (getRNG(RNG_DEADTIME)->Uniform(1)<anita1->deadTime) ){
588  isDead = true;
589  // cout << "DEAD !" << endl;
590  if (settings1->MINBIAS!=1) {
591  continue;
592  }
593  }
594  }
595 
596 
597  // TEMPORARY UNTIL WE HAVE MINI ALFA MODEL
598  // FIRST PASS AT MINI ALFA MODEL
599  // SAW: REPLACE THIS CODE WITH WAIS PULSER MODEL
600  // ELECTRIC FIELD AT 1 m
601 
602  vmmhz1m = 0; //JS: edited
603  for (int i=0; i<wais_nfreqs; i++) {
604  if (wais_pulser_mags[i]>vmmhz1m) {
605  vmmhz1m = wais_pulser_mags[i];
606  //cout << wais_pulser_mags[i] << endl;
607  }
608  }
609  //cout << "vmmhz1m"<< vmmhz1m << endl;
610  //JS: edited
611  //trying to calculate attenuation JS
612  //Atdb = a*100*distanceFromWais*frequency/100000
613  //Gaindb = 80
614  // SAW: REPLACE THIS CODE WITH WAIS PULSER MODEL --> CONFUSING CHECK WITH EMAILS / LINDA ABOUT WHAT THIS MEANS
615  // ELECTRIC FIELD AT THE PAYLOAD CORRECTED FOR 1/R FACTOR. REPLACE NEUTRINO POSITION WITH WAIS POSITION AND VERIFY THAT
616  // bn1->r_bn is the position of ANITA
617  vmmhz_max = ScaleVmMHz(vmmhz1m, interaction1->posnu, bn1->r_bn);//JS: looks to me like "interaction1->posnu" is already the Wais position, "bn1->r_bn" is balloon position and radius
618  //cout << bn1->r_bn << endl ; //Anita position JS
619  //cout << interaction1->posnu << endl ; //Wais position JS
620  // TEMPORARY UNTIL WE HAVE MINI ALFA MODEL
621  // FIRST PASS AT MINI ALFA MODEL
622 
623  // here we get the array vmmhz by taking vmmhz1m_max (signal at lowest frequency bin) and
624  // vmmhz_max (signal at lowest frequency after applying 1/r factor and attenuation factor)
625  // and making an array across frequency bins by putting in frequency dependence.
626  // SAW: REPLACE THIS CODE WITH WAIS PULSER MODEL
627  // SET THE SIGNAL USING vmmhz_max and vmmhz1m
628  // sig1->GetVmMHz(vmmhz_max, vmmhz1m, 1e19, anita1->freq, anita1->NOTCH_MIN, anita1->NOTCH_MAX, vmmhz, Anita::NFREQ);
629 
630  for (int i=0;i<Anita::NFREQ;i++) {
631  vmmhz[i]=vmmhz_max*wais_pulser_mags[i]/vmmhz1m;
632  }
633 
634 
635  // Here we need also to define the anita1->v_phases in DEGREES :/
636  for (int i=0; i<anita1->NFOUR/4; i++){
637  // SAW: REPLACE THIS CODE WITH WAIS PULSER MODEL
638  // USE THE PHASES FROM THE WAIS PULSER MODEL
639 
640  anita1->v_phases[i]=wais_pulser_phases[i]; //JS: edited
641  }
642 
643  // VPOL
644  // Vector n_temp = interaction1->nnu.Cross(surfaceNormalWAIS);
645  // n_pol = n_temp.Cross(interaction1->nnu);
646 
647  // HPOL
648  n_pol = interaction1->nnu.Cross(surfaceNormalWAIS);
649 
650  n_pol = n_pol.Unit();
651 
652  if (settings1->BORESIGHTS) {
653  for(int ilayer=0;ilayer<settings1->NLAYERS;ilayer++) {
654  for(int ifold=0;ifold<anita1->NRX_PHI[ilayer];ifold++) {
655  n_pol_eachboresight[ilayer][ifold]=n_pol;
656  } // end looping over antennas in phi
657  } // end looping over layers
658  } // if we are calculating for all boresights
659 
660 
661  // Find direction from pulser to balloon
662  ray1->GetRFExit(settings1, anita1, 0, interaction1->posnu, interaction1->posnu_down, bn1->r_bn, bn1->r_boresights, 2, antarctica);
663 
664  // make a global trigger object (but don't touch the electric fences)
665  globaltrig1 = new GlobalTrigger(settings1, anita1);
666 
667  Tools::Zero(anita1->arrival_times[0], Anita::NLAYERS_MAX*Anita::NPHI_MAX);
668  Tools::Zero(anita1->arrival_times[1], Anita::NLAYERS_MAX*Anita::NPHI_MAX);
669 
670  if(settings1->BORESIGHTS)
671  anita1->GetArrivalTimesBoresights( ray1->n_exit2bn_eachboresight[2]);
672  else
673  anita1->GetArrivalTimes( ray1->n_exit2bn[2], bn1, settings1);
674 
675  anita1->rx_minarrivaltime=Tools::WhichIsMin(anita1->arrival_times[0], settings1->NANTENNAS);
676 
677 
678  globaltrig1->volts_rx_rfcm_trigger.assign(16, vector <vector <double> >(3, vector <double>(0)));
679  anita1->rms_rfcm_e_single_event = 0;
680 
681 
682 
683  //reset screen parameters (even for no roughness) for the new event
684  panel1->ResetParameters();
685 
686  panel1->SetNvalidPoints(1);
687 
688  for (int k=0;k<Anita::NFREQ;k++) {
689  panel1->AddVmmhz_freq(vmmhz[k]);
690  }
691  panel1->AddDelay( 0. );
692  panel1->AddVec2bln(ray1->n_exit2bn[2]);
693  // Use this to add direction of polarization
694  panel1->AddPol(n_pol);
695  panel1->AddWeight( 1. );
696  panel1->SetWeightNorm( 1. );
697 
698 
699  count_rx=0;
700  for (int ilayer=0; ilayer < settings1->NLAYERS; ilayer++) { // loop over layers on the payload
701  for (int ifold=0;ifold<anita1->NRX_PHI[ilayer];ifold++) { // ifold loops over phi
702 
703  ChanTrigger *chantrig1 = new ChanTrigger();
704  chantrig1->InitializeEachBand(anita1);
705 
706 
707  bn1->GetAntennaOrientation(settings1, anita1, ilayer, ifold, n_eplane, n_hplane, n_normal);
708 
709  // for this (hitangle_h_all[count_rx]=hitangle_h;) and histogram fill, use specular case
710  //although the GetEcomp..() functions are called in ConvertInputWFtoAntennaWF() to calculate the actual waveforms
711  if (!settings1->BORESIGHTS) {
712  bn1->GetEcompHcompkvector(n_eplane, n_hplane, n_normal, ray1->n_exit2bn[2], e_component_kvector[count_rx], h_component_kvector[count_rx], n_component_kvector[count_rx]);
713  bn1->GetEcompHcompEvector(settings1, n_eplane, n_hplane, n_pol, e_component[count_rx], h_component[count_rx], n_component[count_rx]);
714  }
715  else{ // i.e. if BORESIGHTS is true
716  bn1->GetEcompHcompkvector(n_eplane, n_hplane, n_normal, ray1->n_exit2bn_eachboresight[2][ilayer][ifold], e_component_kvector[count_rx], h_component_kvector[count_rx], n_component_kvector[count_rx]);
717  bn1->GetEcompHcompEvector(settings1, n_eplane, n_hplane, n_pol_eachboresight[ilayer][ifold], e_component[count_rx], h_component[count_rx], n_component[count_rx]);
718  }
719  bn1->GetHitAngles(e_component_kvector[count_rx], h_component_kvector[count_rx], n_component_kvector[count_rx], hitangle_e, hitangle_h);
720  // store hitangles for plotting
721  hitangle_h_all[count_rx]=hitangle_h;
722  hitangle_e_all[count_rx]=hitangle_e;
723  // for debugging
724 
725 
726  antNum = anita1->GetRxTriggerNumbering(ilayer, ifold);
727 
728  chantrig1->ApplyAntennaGain(settings1, anita1, bn1, panel1, antNum, n_eplane, n_hplane, n_normal);
729 
730  chantrig1->TriggerPath(settings1, anita1, antNum, bn1);
731 
732  chantrig1->DigitizerPath(settings1, anita1, antNum, bn1);
733 
734  chantrig1->TimeShiftAndSignalFluct(settings1, anita1, ilayer, ifold, volts_rx_rfcm_lab_e_all, volts_rx_rfcm_lab_h_all);
735 
736  chantrig1->saveTriggerWaveforms(anita1, justSignal_trig[0][antNum], justSignal_trig[1][antNum], justNoise_trig[0][antNum], justNoise_trig[1][antNum]);
737  chantrig1->saveDigitizerWaveforms(anita1, justSignal_dig[0][antNum], justSignal_dig[1][antNum], justNoise_dig[0][antNum], justNoise_dig[1][antNum]);
738 
739  //+++++//+++++//+++++//+++++//+++++//+++++//+++++
740  chantrig1->WhichBandsPass(settings1, anita1, globaltrig1, bn1, ilayer, ifold, 0, 0, 0, thresholdsAnt[antNum]);
741 
742 
743  delete chantrig1;
744 
745  count_rx++;
746  } //loop through the phi-fold antennas
747  } //loop through the layers of antennas
748 
749 
750  anita1->rms_rfcm_e_single_event = sqrt(anita1->rms_rfcm_e_single_event / (anita1->HALFNFOUR * settings1->NANTENNAS));
751 
752  for (int irx=0;irx<settings1->NANTENNAS;irx++) {
753  nchannels_perrx_triggered[irx]=globaltrig1->nchannels_perrx_triggered[irx];
754  }
755 
756  nchannels_triggered=Tools::iSum(globaltrig1->nchannels_perrx_triggered, settings1->NANTENNAS); // find total number of antennas that were triggered.
757 
759  // EVALUATE GLOBAL TRIGGER //
760  // FOR VPOL AND HPOL //
762 
763 
764  int thispasses[Anita::NPOL]={0,0};
765  int thispassesnoise[Anita::NPOL]={0,0};
766 
767  if (!isDead){
768 
769  // calculate global trigger on noise only waveforms
770  globaltrig1->PassesTrigger(settings1, anita1, discones_passing, 2, l3trignoise, l2trig, l1trig, settings1->antennaclump, loctrig, loctrig_nadironly, inu,
771  thispassesnoise, true);
772 
773  globaltrig1->PassesTrigger(settings1, anita1, discones_passing, 2, l3trig, l2trig, l1trig, settings1->antennaclump, loctrig, loctrig_nadironly, inu,
774  thispasses);
775  if ( (l3trignoise[0]>0 && l3trignoise[0]==l3trig[0]) || (l3trignoise[1]>0 && l3trignoise[1]==l3trig[1] ) ){
776  cout << "A thermal noise fluctuation generated this trigger!" << l3trignoise[0] << " " << l3trig[0] << " " << l3trignoise[1] << " " << l3trig[1] << endl;
777  delete globaltrig1;
778  continue;
779  }
780  }
781 
782  for (int i=0;i<2;i++) {
783  for (int j=0;j<16;j++) {
784  for (int k=0;k<anita1->HALFNFOUR;k++) {
785  count1->nl1triggers[i][0]+=anita1->l1trig_anita3and4_inanita[i][j][k];
786  }
787  }
788  }
789 
791  // Require that it passes //
792  // global trigger //
794  // for Anita-lite, Anita Hill, just L1 requirement on 2 antennas. This option is currently disabled
795  // Save events that generate an RF trigger or that are part of the min bias sample
796  // Minimum bias sample: save all events that we could see at the payload
797  // Independentely from the fact that they generated an RF trigger
798 
799  if ( (thispasses[0]==1 && anita1->pol_allowed[0]==1)
800  || (thispasses[1]==1 && anita1->pol_allowed[1]==1)
801  || (settings1->MINBIAS==1)) {
802 
803  // cout << inu << endl;
804 
805  anita1->passglobtrig[0]=thispasses[0];
806  anita1->passglobtrig[1]=thispasses[1];
807 
808 
809  // keep track of events passing trigger
810  count1->npassestrigger[0]++;
811  cout << count1->npassestrigger[0] << endl;
812  // tags this event as passing
813  passestrigger=1;
814 
815 
816 #ifdef ANITA_UTIL_EXISTS
817  realEvPtr = new UsefulAnitaEvent();
818  rawHeaderPtr = new RawAnitaHeader();
819  Adu5PatPtr = new Adu5Pat();
820 
821  Adu5PatPtr->latitude= bn1->latitude;
822  Adu5PatPtr->longitude=bn1->longitude;
823  Adu5PatPtr->altitude=bn1->altitude;
824  Adu5PatPtr->realTime=bn1->realTime_flightdata;
825  Adu5PatPtr->heading = bn1->heading;
826  Adu5PatPtr->pitch = bn1->pitch;
827  Adu5PatPtr->roll = bn1->roll;
828  Adu5PatPtr->run = run_no;
829 
830  memset(realEvPtr->fNumPoints, 0, sizeof(realEvPtr->fNumPoints) );
831  memset(realEvPtr->fVolts, 0, sizeof(realEvPtr->fVolts) );
832  memset(realEvPtr->fTimes, 0, sizeof(realEvPtr->fTimes) );
833 
834  int fNumPoints = 260;
835 
836  for (int iant = 0; iant < settings1->NANTENNAS; iant++){
837  //int IceMCAnt = GetIceMCAntfromUsefulEventAnt(anita1, AnitaGeom1, iant);
838  int IceMCAnt = GetIceMCAntfromUsefulEventAnt(settings1, iant);
839  int UsefulChanIndexH = AnitaGeom1->getChanIndexFromAntPol(iant, AnitaPol::kHorizontal);
840  int UsefulChanIndexV = AnitaGeom1->getChanIndexFromAntPol(iant, AnitaPol::kVertical);
841  realEvPtr->fNumPoints[UsefulChanIndexV] = fNumPoints;
842  realEvPtr->fNumPoints[UsefulChanIndexH] = fNumPoints;
843  realEvPtr->chanId[UsefulChanIndexV] = UsefulChanIndexV;
844  realEvPtr->chanId[UsefulChanIndexH] = UsefulChanIndexH;
845 
846  for (int j = 0; j < fNumPoints; j++) {
847  // convert seconds to nanoseconds
848  realEvPtr->fTimes[UsefulChanIndexV][j] = j * anita1->TIMESTEP * 1.0E9;
849  realEvPtr->fTimes[UsefulChanIndexH][j] = j * anita1->TIMESTEP * 1.0E9;
850  // convert volts to millivolts
851  realEvPtr->fVolts[UsefulChanIndexH][j] = volts_rx_rfcm_lab_h_all[IceMCAnt][j+128]*1000;
852  realEvPtr->fCapacitorNum[UsefulChanIndexH][j] = 0;
853  realEvPtr->fVolts[UsefulChanIndexV][j] = volts_rx_rfcm_lab_e_all[IceMCAnt][j+128]*1000;
854  realEvPtr->fCapacitorNum[UsefulChanIndexV][j] = 0;
855  }//end int j
856  }// end int iant
857 
858  realEvPtr->eventNumber = eventNumber;
859 
860  rawHeaderPtr->eventNumber = eventNumber;
861  rawHeaderPtr->surfSlipFlag = 0;
862  rawHeaderPtr->errorFlag = 0;
863  if (settings1->MINBIAS==1){
864  rawHeaderPtr->trigType = 8; // soft-trigger
865  cout << "MINBIASis one" << endl;
866  }
867  else {
868  rawHeaderPtr->trigType = 1; // RF trigger
869  cout << "MINBIAS isn't one" << endl;
870  }
871  rawHeaderPtr->run = run_no;
872  // put the vpol only as a placeholder - these are only used in Anita-2 anyway
873  rawHeaderPtr->upperL1TrigPattern = l1trig[0][0];
874  rawHeaderPtr->lowerL1TrigPattern = l1trig[0][1];
875  rawHeaderPtr->nadirL1TrigPattern = l1trig[0][2];
876 
877  rawHeaderPtr->upperL2TrigPattern = l2trig[0][0];
878  rawHeaderPtr->lowerL2TrigPattern = l2trig[0][1];
879  rawHeaderPtr->nadirL2TrigPattern = l2trig[0][2];
880 
881  if (settings1->WHICH<9){
882  rawHeaderPtr->phiTrigMask = (short) anita1->phiTrigMask;
883  rawHeaderPtr->l3TrigPattern = (short) l3trig[0];
884  }
885 
886  rawHeaderPtr->calibStatus = 31;
887  rawHeaderPtr->realTime = bn1->realTime_flightdata;
888  Adu5PatPtr->latitude= bn1->latitude;
889  Adu5PatPtr->longitude=bn1->longitude;
890  Adu5PatPtr->altitude=bn1->altitude;
891  Adu5PatPtr->realTime=bn1->realTime_flightdata;
892  Adu5PatPtr->heading = bn1->heading;
893  Adu5PatPtr->pitch = bn1->pitch;
894  Adu5PatPtr->roll = bn1->roll;
895  Adu5PatPtr->run = run_no;
896 
897 #ifdef ANITA3_EVENTREADER
898  if (settings1->WHICH==9 || settings1->WHICH==10) {
899  rawHeaderPtr->setTrigPattern((short) l3trig[0], AnitaPol::kVertical);
900  rawHeaderPtr->setTrigPattern((short) l3trig[1], AnitaPol::kHorizontal);
901  rawHeaderPtr->setMask( (short) anita1->l1TrigMask, (short) anita1->phiTrigMask, AnitaPol::kVertical);
902  rawHeaderPtr->setMask( (short) anita1->l1TrigMaskH, (short) anita1->phiTrigMaskH, AnitaPol::kHorizontal);
903  }
904 
905  truthEvPtr = new TruthAnitaEvent();
906  truthEvPtr->eventNumber = eventNumber;
907  truthEvPtr->realTime = bn1->realTime_flightdata;
908  truthEvPtr->run = run_no;
909  truthEvPtr->nuMom = 0; //pnu;
910  truthEvPtr->nu_pdg = 0; //pdgcode;
911  memcpy(truthEvPtr->e_component, e_component, sizeof(e_component));
912  memcpy(truthEvPtr->h_component, h_component, sizeof(h_component));
913  memcpy(truthEvPtr->n_component, n_component, sizeof(n_component));
914  memcpy(truthEvPtr->e_component_k ,e_component_kvector, sizeof(e_component_kvector));
915  memcpy(truthEvPtr->h_component_k ,h_component_kvector, sizeof(h_component_kvector));
916  memcpy(truthEvPtr->n_component_k ,n_component_kvector, sizeof(n_component_kvector));
917  truthEvPtr->sourceLon = sourceLon;
918  truthEvPtr->sourceLat = sourceLat;
919  truthEvPtr->sourceAlt = sourceAlt;
920  truthEvPtr->weight = weight;
921  for (int i=0;i<3;i++){
922  truthEvPtr->balloonPos[i] = bn1->r_bn[i];
923  truthEvPtr->balloonDir[i] = bn1->n_bn[i];
924  truthEvPtr->nuPos[i] = interaction1->posnu[i];
925  truthEvPtr->nuDir[i] = interaction1->nnu[i];
926  }
927  for (int i=0;i<5;i++){
928  for (int j=0;j<3;j++){
929  truthEvPtr->rfExitNor[i][j] = ray1->n_exit2bn[i][j];
930  truthEvPtr->rfExitPos[i][j] = ray1->rfexit[i][j];
931  }
932  }
933  for (int i=0;i<48;i++){
934  truthEvPtr->hitangle_e[i] = hitangle_e_all[i];
935  truthEvPtr->hitangle_h[i] = hitangle_h_all[i];
936  }
937  if(settings1->ROUGHNESS){
938  for (int i=0;i<Anita::NFREQ;i++)
939  truthEvPtr->vmmhz[i] = panel1->GetVmmhz_freq(i);
940  }
941 
942 
943  memset(truthEvPtr->SNRAtTrigger, 0, sizeof(truthEvPtr->SNRAtTrigger) );
944  memset(truthEvPtr->fSignalAtTrigger, 0, sizeof(truthEvPtr->fSignalAtTrigger) );
945  memset(truthEvPtr->fNoiseAtTrigger, 0, sizeof(truthEvPtr->fNoiseAtTrigger) );
946  memset(truthEvPtr->SNRAtDigitizer, 0, sizeof(truthEvPtr->SNRAtDigitizer) );
947  memset(truthEvPtr->thresholds, 0, sizeof(truthEvPtr->thresholds) );
948  memset(truthEvPtr->fDiodeOutput, 0, sizeof(truthEvPtr->fDiodeOutput) );
949 
950  truthEvPtr->maxSNRAtTriggerV=0;
951  truthEvPtr->maxSNRAtTriggerH=0;
952  truthEvPtr->maxSNRAtDigitizerV=0;
953  truthEvPtr->maxSNRAtDigitizerH=0;
954 
955  for (int iant = 0; iant < settings1->NANTENNAS; iant++){
956  int UsefulChanIndexH = AnitaGeom1->getChanIndexFromAntPol(iant, AnitaPol::kHorizontal);
957  int UsefulChanIndexV = AnitaGeom1->getChanIndexFromAntPol(iant, AnitaPol::kVertical);
958 
959  truthEvPtr->SNRAtTrigger[UsefulChanIndexV] = Tools::calculateSNR(justSignal_trig[0][iant], justNoise_trig[0][iant]);
960  truthEvPtr->SNRAtTrigger[UsefulChanIndexH] = Tools::calculateSNR(justSignal_trig[1][iant], justNoise_trig[1][iant]);
961 
962  if (truthEvPtr->SNRAtTrigger[UsefulChanIndexV]>truthEvPtr->maxSNRAtTriggerV) truthEvPtr->maxSNRAtTriggerV=truthEvPtr->SNRAtTrigger[UsefulChanIndexV];
963  if (truthEvPtr->SNRAtTrigger[UsefulChanIndexH]>truthEvPtr->maxSNRAtTriggerH) truthEvPtr->maxSNRAtTriggerH=truthEvPtr->SNRAtTrigger[UsefulChanIndexH];
964 
965  truthEvPtr->SNRAtDigitizer[UsefulChanIndexV] = Tools::calculateSNR(justSignal_dig[0][iant], justNoise_dig[0][iant]);
966  truthEvPtr->SNRAtDigitizer[UsefulChanIndexH] = Tools::calculateSNR(justSignal_dig[1][iant], justNoise_dig[1][iant]);
967 
968  if (truthEvPtr->SNRAtDigitizer[UsefulChanIndexV]>truthEvPtr->maxSNRAtDigitizerV) truthEvPtr->maxSNRAtDigitizerV=truthEvPtr->SNRAtDigitizer[UsefulChanIndexV];
969  if (truthEvPtr->SNRAtDigitizer[UsefulChanIndexH]>truthEvPtr->maxSNRAtDigitizerH) truthEvPtr->maxSNRAtDigitizerH=truthEvPtr->SNRAtDigitizer[UsefulChanIndexH];
970 
971 
972  truthEvPtr->thresholds[UsefulChanIndexV] = thresholdsAnt[iant][0][4];
973  truthEvPtr->thresholds[UsefulChanIndexH] = thresholdsAnt[iant][1][4];
974  int irx = iant;
975  if (iant<16){
976  if (iant%2) irx = iant/2;
977  else irx = iant/2 + 1;
978  }
979 
980  for (int j = 0; j < fNumPoints; j++) {
981  truthEvPtr->fTimes[UsefulChanIndexV][j] = j * anita1->TIMESTEP * 1.0E9;
982  truthEvPtr->fTimes[UsefulChanIndexH][j] = j * anita1->TIMESTEP * 1.0E9;
983 
984  truthEvPtr->fSignalAtTrigger[UsefulChanIndexV][j] = justSignal_trig[0][iant][j+128]*1000;
985  truthEvPtr->fSignalAtTrigger[UsefulChanIndexH][j] = justSignal_trig[1][iant][j+128]*1000;
986  truthEvPtr->fNoiseAtTrigger[UsefulChanIndexV][j] = justNoise_trig[0][iant][j+128]*1000;
987  truthEvPtr->fNoiseAtTrigger[UsefulChanIndexH][j] = justNoise_trig[1][iant][j+128]*1000;
988  truthEvPtr->fSignalAtDigitizer[UsefulChanIndexV][j] = justSignal_dig[0][iant][j+128]*1000;
989  truthEvPtr->fSignalAtDigitizer[UsefulChanIndexH][j] = justSignal_dig[1][iant][j+128]*1000;
990  truthEvPtr->fNoiseAtDigitizer[UsefulChanIndexV][j] = justNoise_dig[0][iant][j+128]*1000;
991  truthEvPtr->fNoiseAtDigitizer[UsefulChanIndexH][j] = justNoise_dig[1][iant][j+128]*1000;
992 
993  truthEvPtr->fDiodeOutput[UsefulChanIndexV][j] = anita1->timedomain_output_allantennas[0][irx][j];
994  truthEvPtr->fDiodeOutput[UsefulChanIndexH][j] = anita1->timedomain_output_allantennas[1][irx][j];
995  }//end int j
996 
997  }// end int iant
998 
999 
1000 
1001 
1002  truthAnitaTree->Fill();
1003  delete truthEvPtr;
1004 #endif
1005 
1006  headTree->Fill();
1007  eventTree->Fill();
1008  adu5PatTree->Fill();
1009 
1010  delete realEvPtr;
1011  delete rawHeaderPtr;
1012  delete Adu5PatPtr;
1013 #endif
1014 
1015  neutrinos_passing_all_cuts++;
1016 
1017 
1018  passes_thisevent=1; // flag this event as passing
1019  } // end if passing global trigger conditions
1020  else {
1021  passes_thisevent=0; // flag this event as not passing
1022  }// end else event does not pass trigger
1023 
1025  //
1026  // WE GET HERE REGARDLESS OF WHETHER THE TRIGGER PASSES
1027  //
1029 
1030  delete globaltrig1;
1031 
1032  // keeping track of intermediate counters, incrementing by weight1.
1033  // weight1 was not yet determined when integer counters were incremented.
1034 
1035 
1036  //looping over two types of rays - upgoing and downgoing.
1037  if (ABORT_EARLY){
1038  std::cout << "\n***********************************************************";
1039  std::cout << "\n* SIGINT received, aborting loop over events early.";
1040  std::cout << "\n* Stopped after event " << inu << " instead of " << NNU;
1041  std::cout << "\n* Any output which relied on NNU should be corrected for.";
1042  std::cout << "\n***********************************************************\n";
1043  foutput << "\n***********************************************************";
1044  foutput << "\n* SIGINT received, aborting loop over events early.";
1045  foutput << "\n* Stopped after event " << inu << " instead of " << NNU;
1046  foutput << "\n* Any output which relied on NNU should be corrected for.";
1047  foutput << "\n***********************************************************\n";
1048  break;
1049  }
1050  }//end NNU neutrino loop
1051 
1052  // Finished with individual neutrinos now ...
1053  //roughout.close();
1054 
1055 
1056 
1057 #ifdef ANITA_UTIL_EXISTS
1058 
1059  anitafileEvent->cd();
1060  eventTree->Write("eventTree");
1061  anitafileEvent->Close();
1062  delete anitafileEvent;
1063 
1064  anitafileHead->cd();
1065  headTree->Write("headTree");
1066  anitafileHead->Close();
1067  delete anitafileHead;
1068 
1069  anitafileGps->cd();
1070  adu5PatTree->Write("adu5PatTree");
1071  anitafileGps->Close();
1072  delete anitafileGps;
1073 
1074 #ifdef ANITA3_EVENTREADER
1075  anitafileTruth->cd();
1076  configAnitaTree->Write("configAnitaTree");
1077  truthAnitaTree->Write("truthAnitaTree");
1078  triggerSettingsTree->Write("triggerSettingsTree");
1079  anitafileTruth->Close();
1080  delete anitafileTruth;
1081 #endif
1082 
1083 #endif
1084 
1085 
1086 
1087  delete anita1;
1088  return 0;
1089 
1090 } //END MAIN PROGRAM
1091 
1092 //} //JS
1093 
1094 void interrupt_signal_handler(int sig){
1095  signal(sig, SIG_IGN);
1096  ABORT_EARLY = true;
1097  return;
1098 }
1099 //end interrupt_signal_handler()
1100 
1101 #ifdef ANITA_UTIL_EXISTS
1102 //int GetIceMCAntfromUsefulEventAnt(Anita *anita1, AnitaGeomTool *AnitaGeom1, int UsefulEventAnt){
1103 int GetIceMCAntfromUsefulEventAnt(Settings *settings1, int UsefulEventAnt){
1104  //int layer_temp = IceMCLayerPosition[UsefulEventIndex][0];
1105  //int position_temp = IceMCLayerPosition[UsefulEventIndex][1];
1106  //int IceMCIndex = anita1->GetRx(layer_temp, position_temp);
1107  int IceMCAnt = UsefulEventAnt;
1108  if ((settings1->WHICH==9 || settings1->WHICH==10) && UsefulEventAnt<16) {
1109  IceMCAnt = (UsefulEventAnt%2==0)*UsefulEventAnt/2 + (UsefulEventAnt%2==1)*(UsefulEventAnt/2+8);
1110  }
1111 
1112  return IceMCAnt;
1113 }
1114 //end GetIceMCAntfromUsefulEventAnt()
1115 
1116 
1117 #endif
1118 
1119 double ScaleVmMHz(double vmmhz1m_max, const Position &posnu1, const Position &r_bn) {
1120  double dtemp= r_bn.Distance(posnu1);
1121  vmmhz1m_max= vmmhz1m_max/dtemp;
1122  // scalefactor_distance=1/dtemp;
1123  //cout << "dtemp is " << dtemp << "\n";
1124  return vmmhz1m_max;
1125 }
1126 //end ScaleVmMHz()tryin
UInt_t eventNumber
Event number from software.
Definition: RawAnitaEvent.h:33
UShort_t lowerL2TrigPattern
Bit mask for lower ring l2 cluster triggers. eg. if the bit 1 (the lowest bit) is active it means the...
UChar_t surfSlipFlag
Sync Slip between SURF 2-9 and SURF 1.
Double_t h_component_k[48]
Component of the e-field along the rx h-plane.
Double_t rfExitPos[5][3]
Position where the RF exits the ice- 5 iterations, 3 dimensions each.
Double_t fNoiseAtDigitizer[12 *9][260]
Array of noise at digitizer.
UChar_t errorFlag
Error Flag.
void PassesTrigger(Settings *settings1, Anita *anita1, int discones_passing, int mode, int *l3trig, int l2trig[Anita::NPOL][Anita::NTRIGGERLAYERS_MAX], int l1trig[Anita::NPOL][Anita::NTRIGGERLAYERS_MAX], int antennaclump, int loctrig[Anita::NPOL][Anita::NLAYERS_MAX][Anita::NPHI_MAX], int loctrig_nadironly[Anita::NPOL][Anita::NPHI_MAX], int inu, int *thispasses, bool noiseOnly=false)
Evaluate the full trigger simulation for a given payload configuration.
Double_t weight
Weight assigned by icemc.
Int_t nu_pdg
Neutrino PDG code.
Position r_bn
position of balloon
Definition: balloon.hh:66
Double_t sourceLat
RF position when leaving the ice: Latitude (using icemc model)
double fVolts[12 *9][260]
Array of unwrapped (unless kNoCalib) voltages for each channel.
Float_t pitch
in degrees
Definition: Adu5Pat.h:46
double phi_bn
theta,phi of balloon wrt south pole
Definition: balloon.hh:65
Global Trigger.
Definition: GlobalTrigger.h:12
void InitializeEachBand(Anita *anita1)
Initialize trigger bands.
Definition: ChanTrigger.cc:711
UShort_t upperL1TrigPattern
Bit mask for upper ring l1 antenna triggers. eg. if the bit 1 (the lowest bit) is active it means the...
UShort_t l3TrigPattern
Bit mask for l3 global triggers. eg. if the bit 1 (the lowest bit) is active it means that phi sector...
Adu5Pat – The ADU5 Position and Attitude Data.
Definition: Adu5Pat.h:26
double Distance(const Position &second) const
Returns chord distance (direct distance between two vectors)
Definition: position.cc:37
void TriggerPath(Settings *settings1, Anita *anita1, int ant, Balloon *bn1)
Apply trigger path.
Definition: ChanTrigger.cc:871
static const int NPOL
number of polarizations
Definition: anita.hh:51
Double_t n_component_k[48]
Component of the e-field along the normal.
Double_t fDiodeOutput[12 *9][260]
Array of tunnel diode output.
UShort_t calibStatus
Calib/Relay Status.
Float_t latitude
In degrees.
Definition: Adu5Pat.h:42
void ApplyAntennaGain(Settings *settings1, Anita *anita1, Balloon *bn1, Screen *panel1, int ant, Vector &n_eplane, Vector &n_hplane, Vector &n_normal)
Apply the antenna gain.
Definition: ChanTrigger.cc:743
STL namespace.
static Int_t getChanIndexFromAntPol(Int_t ant, AnitaPol::AnitaPol_t pol)
Convert ant-pol to logical index.
Radiation from interaction.
Definition: signal.hh:13
double fTimes[12 *9][260]
Array of unwrapped (unless kNoCalib) times for each channel.
Double_t sourceLon
RF position when leaving the ice: Longitude (using icemc model)
void PickBalloonPosition(Vector straightup, IceModel *antarctica, Settings *settings1, Anita *anita1)
This function picks the balloon position.
Definition: balloon.cc:317
Double_t sourceAlt
RF position when leaving the ice: Altitude (using icemc model)
void TimeShiftAndSignalFluct(Settings *settings1, Anita *anita1, int ilayer, int ifold, double volts_rx_rfcm_lab_e_all[48][512], double volts_rx_rfcm_lab_h_all[48][512])
Time shift and fluctuate signal.
Float_t longitude
In degrees.
Definition: Adu5Pat.h:43
Double_t thresholds[12 *9]
Channel thresholds used in icemc.
This is a wrapper class for an RF Signal.
Definition: RFSignal.h:12
UInt_t realTime
Time from the GPS unit.
Definition: Adu5Pat.h:37
const char * ICEMC_SRC_DIR()
Double_t n_component[48]
Normal comp along polarization.
Double_t balloonPos[3]
Balloon position.
UChar_t nadirL2TrigPattern
8-bit trigger mask for L2 nadir triggers. Nadir L2 triggers are for the even phi sectors and are just...
void saveTriggerWaveforms(Anita *anita1, double sig0[48], double sig1[48], double noise0[48], double noise1[48])
Save signal and noise waveforms at trigger.
Double_t vmmhz[128]
V/m/MHz at balloon (128 frequency bins)
RawAnitaHeader – The Raw ANITA Event Header.
Double_t SNRAtDigitizer[12 *9]
Array of SNR at digitizer.
Class that handles the channel trigger.
Definition: ChanTrigger.h:18
Reads in and stores input settings for the run.
Definition: Settings.h:37
Double_t fSignalAtTrigger[12 *9][260]
Array of signal at trigger.
Vector n_bn
normalized r_bn
Definition: balloon.hh:73
Int_t run
Run number, assigned on ground.
Functions you need to generate a primary interaction including cross sections and picking charged cur...
Definition: Primaries.h:83
Double_t maxSNRAtTriggerV
Max SNR at trigger V-POL.
void InitializeBalloon()
This function initializes the balloon or the specific flight.
Definition: balloon.cc:188
This class is a 3-vector that represents a position on the Earth&#39;s surface.
Definition: position.hh:26
Secondary interactions.
Definition: secondaries.hh:28
void saveDigitizerWaveforms(Anita *anita1, double sig0[48], double sig1[48], double noise0[48], double noise1[48])
Save signal and noise waveforms at digitizer.
Double_t h_component[48]
H comp along polarization.
UInt_t realTime
unixTime of readout
Stores everything about a particular neutrino interaction. Interaction.
Definition: Primaries.h:135
Double_t rfExitNor[5][3]
Normal vector in direction of exit point to balloon - 5 iterations.
UsefulAnitaEvent – The Calibrated Useful Anita Event object.
void GetAntennaOrientation(Settings *settings1, Anita *anita1, int ilayer, int ifold, Vector &n_eplane, Vector &n_hplane, Vector &n_normal)
This function gets the antenna orientation.
Definition: balloon.cc:649
Float_t altitude
In metres.
Definition: Adu5Pat.h:44
UShort_t phiTrigMask
16-bit phi mask (from TURF)
Double_t hitangle_h[48]
Hit angles rel. to h plane stored for each antenna.
void SetDefaultBalloonPosition(IceModel *antarctica1)
This function sets the default balloon position.
Definition: balloon.cc:75
Double_t fSignalAtDigitizer[12 *9][260]
Array of signal at digitizer.
void DigitizerPath(Settings *settings1, Anita *anita1, int ant, Balloon *bn1)
Apply digitizer path.
UChar_t chanId[12 *9]
Definition: RawAnitaEvent.h:39
TruthAnitaEvent – The Truth ANITA Event.
Double_t e_component[48]
E comp along polarization.
Shape of the earth, ice thicknesses, profiles of earth layers, densities, neutrino absorption...
Definition: earthmodel.hh:40
static const int NLAYERS_MAX
max number of layers (in smex design, it&#39;s 4)
Definition: anita.hh:59
UShort_t lowerL1TrigPattern
Bit mask for lower ring l1 antenna triggers. eg. if the bit 1 (the lowest bit) is active it means the...
int fCapacitorNum[12 *9][260]
Array of capacitor numbers.
Double_t fNoiseAtTrigger[12 *9][260]
Array of noise at trigger.
Double_t nuDir[3]
Neutrino direction.
void WhichBandsPass(Settings *settings1, Anita *anita1, GlobalTrigger *globaltrig1, Balloon *bn1, int ilayer, int ifold, double dangle, double emfrac, double hadfrac, double thresholds[2][5])
Which bands passes the trigger.
Definition: ChanTrigger.cc:54
Vertical Polarisation.
void GetEcompHcompEvector(Settings *settings1, Vector n_eplane, Vector n_hplane, const Vector n_pol, double &e_component, double &h_component, double &n_component)
This function gets the e-component, h-component and e-vector.
Definition: balloon.cc:704
Double_t e_component_k[48]
Component of e-field along the rx e-plane.
Double_t maxSNRAtDigitizerV
Max SNR at digitizer V-POL.
Double_t nuMom
Neutrino momentum.
int fNumPoints[12 *9]
Number of poins per channel.
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
UShort_t upperL2TrigPattern
Bit mask for upper ring l2 cluster triggers. eg. if the bit 1 (the lowest bit) is active it means the...
static const int NPHI_MAX
max number of antennas around in phi (in smex, 16)
Definition: anita.hh:61
Horizontal Polarisation.
void GetHitAngles(double e_component_kvector, double h_component_kvector, double n_component_kvector, double &hitangle_e, double &hitangle_h)
This function gets the hit angles.
Definition: balloon.cc:726
Float_t heading
0 is facing north, 180 is facing south
Definition: Adu5Pat.h:45
Double_t maxSNRAtTriggerH
Max SNR at trigger H-POL.
Handles event counting as cuts are made.
Definition: counting.hh:10
UInt_t realTime
unixTime of readout
Definition: rx.hpp:23
UChar_t nadirL1TrigPattern
8-bit trigger mask for L1 nadir triggers. Here bit 1 is antenna 33 (phi 1), bit 2 is antenna 34 (phi ...
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
double dtryingposition
weighting factor: how many equivalent tries each neutrino counts for after having reduced possible in...
Definition: balloon.hh:43
UInt_t eventNumber
Software event number.
Double_t nuPos[3]
Neutrino position.
Ray tracing.
Definition: ray.hh:20
Double_t fTimes[12 *9][260]
Array of unwrapped (unless kNoCalib) times for each channel.
Double_t hitangle_e[48]
Hit angles rel. to e plane stored for each antenna.
Int_t run
Run number.
Double_t SNRAtTrigger[12 *9]
Array of SNR at trigger.
void GetEcompHcompkvector(Vector n_eplane, Vector n_hplane, Vector n_normal, const Vector n_exit2bn, double &e_component_kvector, double &h_component_kvector, double &n_component_kvector)
This function gets the e-component, h-component and k-vector.
Definition: balloon.cc:690
Double_t maxSNRAtDigitizerH
Max SNR at digitizer H-POL.
UChar_t trigType
Bit 0 is RF, 1 is ADU5, 2 is G12, 3 is software/external.
Double_t balloonDir[3]
Balloon direction.
Position r_boresights[Anita::NLAYERS_MAX][Anita::NPHI_MAX]
position of antenna boresights
Definition: balloon.hh:69
Ice thicknesses and water depth.
Definition: icemodel.hh:103
unsigned int realTime_flightdata
realtime from the flight data file
Definition: balloon.hh:51
Vector nnu
direction of neutrino (+z in south pole direction)
Definition: Primaries.h:187