ChanTrigger.cc
1 #include <vector>
2 #include <array>
3 #include <iostream>
4 #include <fstream>
5 #include "vector.hh"
6 #include "position.hh"
7 #include "TF1.h"
8 #include "TCanvas.h"
9 #include "TGraph.h"
10 #include "TTree.h"
11 #include "TH2F.h"
12 #include "TMath.h"
13 #include "TVector3.h"
14 #include "TLine.h"
15 #include "TFile.h"
16 
17 #include "rx.hpp"
18 #include "Constants.h"
19 #include "anita.hh"
20 #include "balloon.hh"
21 #include "ChanTrigger.h"
22 #include <cmath>
23 #include "Tools.h"
24 #include "Settings.h"
25 #include "screen.hh"
26 #include "GlobalTrigger.h"
27 #include "icemc_random.h"
28 
29 using std::cout;
30 
31 #ifdef ANITA_UTIL_EXISTS
32 #include "FFTtools.h"
33 #include "SimulatedSignal.h"
34 #endif
35 
36 
37 
38 
39 void ChanTrigger::ConvertEHtoLREfield(double e_component,double h_component,double& lcp_component,double& rcp_component) {
40 
41  lcp_component=sqrt((e_component*e_component+h_component*h_component)/2);
42  rcp_component=lcp_component;
43 
44 } //ConvertEHtoLREfield
45 void ChanTrigger::ConvertEHtoLREnergy(double e_component,double h_component,double& lcp_component,double& rcp_component) {
46 
47  lcp_component=(e_component+h_component)/2;
48  rcp_component=lcp_component;
49 
50 } //ConvertEHtoLREnergy
51 
52 
53 
54 void ChanTrigger::WhichBandsPass(Settings *settings1, Anita *anita1, GlobalTrigger *globaltrig1, Balloon *bn1, int ilayer, int ifold, double dangle, double emfrac, double hadfrac, double thresholds[2][5]){
55 
56 
57  if (settings1->USETIMEDEPENDENTTHRESHOLDS==1 && (settings1->WHICH==9 || settings1->WHICH==10 ) ) {
58  for(int i=0;i<4;i++) thresholds[0][i] = thresholds[1][i] = anita1->powerthreshold[i];
59  int iring = (ilayer<2)*0 + (ilayer==2)*1 + (ilayer==3)*2;
60  int iphi = ifold;
61  if (ilayer==0) iphi = ifold*2;
62  else if (ilayer==1) iphi = ifold*2+1;
63  // we invert VPOL and HPOL because in AnitaEventReader (0:HPOL 1:VPOL) and in icemc (0:VPOL 1:HPOL)
64  // convert scalers to power thresholds using fitted function got from ANITA-1, are they too old?
65  // thresholds[1][4] = ADCCountstoPowerThreshold(anita1,0,iring*16+iphi)*(-1.);
66  // thresholds[0][4] = ADCCountstoPowerThreshold(anita1,1,iring*16+iphi)*(-1.);
67 
68 
69  // Use thresholds converted from flight scalers
70  thresholds[0][4] = anita1->fakeThresholds2[0][iring*16+iphi]*(-1.);
71  thresholds[1][4] = anita1->fakeThresholds2[1][iring*16+iphi]*(-1.);
72 
73  // cout << thresholds[0][4] << " " << thresholds[1][4] << " \n";
74  } else {
75  GetThresholds(settings1,anita1,ilayer,thresholds); // get the right thresholds for this layer
76  }
77  globaltrig1->volts[0][ilayer][ifold]=0.;
78  globaltrig1->volts[1][ilayer][ifold]=0.;
79 
80 
81  // This is the old way used for ANITA 1 where we integrate in frequency
82  // to get an estimate of the signal strength
83  if (settings1->TRIGGERSCHEME <= 1){
84  WhichBandsPassTrigger1(settings1, anita1, globaltrig1, bn1, ilayer, ifold, thresholds);
85 
86  } else if (settings1->TRIGGERSCHEME >= 2){
87  // this scheme is used for ANITA 2 on.
88  //cout << "i'm here.\n";
89  WhichBandsPassTrigger2(settings1, anita1, globaltrig1, bn1, ilayer, ifold, dangle, emfrac, hadfrac, thresholds);
90 
91  }
92 } // end which bands pass
93 
94 
96 
103 void ChanTrigger::WhichBandsPassTrigger1(Settings *settings1, Anita *anita1, GlobalTrigger *globaltrig1, Balloon *bn1, int ilayer, int ifold, double thresholds[2][5]){
104 
105  double volts_thischannel;
106  double energy_thischannel;
107  double voltagethresh_thischannel,energythresh_thischannel;
108 
109  // add noise, then find lcp, rcp components
110  for (int ibw=0;ibw<anita1->NBANDS+1;ibw++) {
111 
112  // cout << "ibw, bwslice_volts_pole are " << ibw << " " << bwslice_volts_pole[ibw] << "\n";
113 
114  if (settings1->SIGNAL_FLUCT) {// add noise fluctuations if requested
115  bwslice_volts_pole[ibw] += getRNG(RNG_SIGNAL_FLUCT)->Gaus(0.,anita1->bwslice_vnoise[ilayer][ibw]);
116  bwslice_volts_polh[ibw] += getRNG(RNG_SIGNAL_FLUCT)->Gaus(0.,anita1->bwslice_vnoise[ilayer][ibw]);
117  }
118 
119  // Convert e-plane and h-plane components into lcp,rcp
121 
122  // do the same for energy
124 
125  globaltrig1->volts[0][ilayer][ifold]+=bwslice_volts_pol0[ibw];
126  globaltrig1->volts[1][ilayer][ifold]+=bwslice_volts_pol1[ibw];
127  }
128 
129  for (int ibw=0;ibw<anita1->NBANDS+1;ibw++) { // subbands+full band
130 
131  // first lcp or v pol (here called pole)
132  // if we're implementing masking and the channel has been masked
133  if (settings1->CHMASKING && !ChanTrigger::IsItUnmasked(bn1->surfTrigBandMask,ibw,ilayer,ifold,0)) {
134 
135  globaltrig1->channels_passing[ilayer][ifold][0][ibw]=0;// channel does not pass
136  globaltrig1->vchannels_passing[ilayer][ifold][0][ibw]=0;// channel does not pass
137  }
138  // note the last element of the array is 0 because this is lcp or e pol
139  else {
140 
141 
142  if (settings1->LCPRCP ) {// if we're considering lcp, rcp
143  volts_thischannel=bwslice_volts_pol0[ibw];
144  energy_thischannel=bwslice_energy_pol0[ibw];
145  }
146  else {// if we're considering v and h pol
147  volts_thischannel=bwslice_volts_pole[ibw];
148  energy_thischannel=bwslice_energy_pole[ibw];
149 
150  }
151 
152 
153 
154  // isurf=Anita::AntennaNumbertoSurfNumber(ilayer,ifold)-1;
155  // ichan=Anita::GetSurfChannel(Anita::GetAntennaNumber(ilayer,ifold),ibw,AnitaPol::kLeft)-1; // for vertical trigger, arbitrarily use threshold scans from left polarisation
156  // get the treshold in adc counts for this channel.
157  // powerthresh_thischannel=bn1->powerthresh[isurf][ichan];
158 
159  energythresh_thischannel=thresholds[0][ibw];
160  //meanp_thischannel=bn1->meanp[isurf][ichan];
161  //energy_thischannel+=meanp_thischannel*INTEGRATION_TIME;
162 
163  voltagethresh_thischannel=anita1->bwslice_thresholds[ibw];
164 
165 
166  if (settings1->ZEROSIGNAL) {
167  volts_thischannel=0.;
168  energy_thischannel=0.;
169  }
170 
171  if (settings1->TRIGGERSCHEME==0) {
172  signal_eachband[0][ibw]=(double)fabs(volts_thischannel);
173  threshold_eachband[0][ibw]=voltagethresh_thischannel;
174  noise_eachband[0][ibw]=anita1->bwslice_vnoise[ilayer][ibw];
175 
176  vsignal_eachband[0][ibw]=(double)fabs(volts_thischannel);
177  vthreshold_eachband[0][ibw]=voltagethresh_thischannel;
178  vnoise_eachband[0][ibw]=anita1->bwslice_vnoise[ilayer][ibw];
179 
180 
181  }
182  if (settings1->TRIGGERSCHEME==1) {
183  signal_eachband[0][ibw]=energy_thischannel;
184  threshold_eachband[0][ibw]=energythresh_thischannel;
185  noise_eachband[0][ibw]=anita1->bwslice_enoise[ibw];
186 
187  vsignal_eachband[0][ibw]=energy_thischannel;
188  vthreshold_eachband[0][ibw]=energythresh_thischannel;
189  vnoise_eachband[0][ibw]=anita1->bwslice_enoise[ibw];
190  }
191 
192  // compare the signal to noise and see if it passes
193  //cout << "ibw, signal, noise, threshold are " << ibw << " " << signal_eachband[0][ibw] << " " << noise_eachband[0][ibw] << " " << threshold_eachband[0][ibw] << "\n";
194  if (signal_eachband[0][ibw]/noise_eachband[0][ibw]>=threshold_eachband[0][ibw]) {
195  // if (fabs(volts_thischannel)/anita1->bwslice_vnoise[ilayer][ibw]>=bwslice_thresholds[ibw]) {
196  if (anita1->pol_allowed[0] && anita1->bwslice_allowed[ibw]) { // are this pol and bandwidth allowed to pass
197  globaltrig1->nchannels_perrx_triggered[anita1->GetRx(ilayer,ifold)]++; //Records number of first level triggers on each antenna for a single neutrino
198  globaltrig1->channels_passing[ilayer][ifold][0][ibw]=1; // if it does then flag the element of the channels_passing array that corresponds to lcp or v pol for this band
199  globaltrig1->vchannels_passing[ilayer][ifold][0][ibw]=1; // if it does then flag the element of the channels_passing array that corresponds to lcp or v pol for this band
200  passes_eachband[0][ibw]=1;
201  vpasses_eachband[0][ibw]=1;
202 
203  } // end if this polarization and bandwidth are allowed to pass
204  } // does this channel pass
205 
206 
207  } // end of the else
208 
209 
210 
211 
212  // now rcp or h pol (here called polh)
213  // if we're implementing masking and the channel has been masked
214  if (!settings1->JUSTVPOL) { // if we're considering just vpol then there's not a second polarization to consider
215  if (settings1->CHMASKING && !ChanTrigger::IsItUnmasked(bn1->surfTrigBandMask,ibw,ilayer,ifold,1)) {
216  globaltrig1->channels_passing[ilayer][ifold][1][ibw]=0;// channel does not pass
217  globaltrig1->vchannels_passing[ilayer][ifold][1][ibw]=0;// channel does not pass
218 
219 
220  // note the last element of the array is 1 because this is rcp or h pol
221  passes_eachband[1][ibw]=0;
222  }
223  else {
224 
225  if (settings1->LCPRCP) { // if we're considering lcp, rcp
226  volts_thischannel=bwslice_volts_pol1[ibw];
227  energy_thischannel=bwslice_energy_pol1[ibw];
228  }
229  else { // if we're considering just e and h
230  volts_thischannel=bwslice_volts_polh[ibw];
231  energy_thischannel=bwslice_energy_polh[ibw];
232  }
233 
234  energythresh_thischannel=thresholds[1][ibw];
235  //meanp_thischannel=bn1->meanp[isurf][ichan];
236 
237  //energy_thischannel+=meanp_thischannel*INTEGRATION_TIME;
238 
239  voltagethresh_thischannel=anita1->bwslice_thresholds[ibw];
240 
241 
242  if (settings1->ZEROSIGNAL) {
243  volts_thischannel=0.;
244  energy_thischannel=0.;
245  }
246 
247 
248  if (settings1->TRIGGERSCHEME==0) {
249  signal_eachband[1][ibw]=(double)fabs(volts_thischannel);
250  threshold_eachband[1][ibw]=voltagethresh_thischannel;
251  noise_eachband[1][ibw]=anita1->bwslice_vnoise[ilayer][ibw];
252  }
253  if (settings1->TRIGGERSCHEME==1) {
254  signal_eachband[1][ibw]=energy_thischannel;
255  threshold_eachband[1][ibw]=energythresh_thischannel;
256  noise_eachband[1][ibw]=anita1->bwslice_enoise[ibw];
257  }
258 
259 
260  // compare the signal to noise and see if it passes
261  if (signal_eachband[1][ibw]/noise_eachband[1][ibw]>=threshold_eachband[1][ibw]) {
262  if (anita1->pol_allowed[1] && anita1->bwslice_allowed[ibw]) {
263  globaltrig1->nchannels_perrx_triggered[anita1->GetRx(ilayer,ifold)]++; //Records number of first level triggers on each antenna for a single neutrino
264  globaltrig1->channels_passing[ilayer][ifold][1][ibw]=1; // if it does then flag the element of the channels_passing array that corresponds to rcp for this band
265  globaltrig1->vchannels_passing[ilayer][ifold][1][ibw]=1; // if it does then flag the element of the channels_passing array that corresponds to rcp for this band
266  passes_eachband[1][ibw]=1;
267  } // is this band and polarization allowed to pass
268  } //does this channel pass
269 
270  } // end of the else (channel isn't masked)
271 
272  } // if not justvpol
273  } // end loop over bands
274 
275 } // end WhichBandsPassTrigger1
276 
278 
285 void ChanTrigger::WhichBandsPassTrigger2(Settings *settings1, Anita *anita1, GlobalTrigger *globaltrig1, Balloon *bn1, int ilayer, int ifold, double dangle, double emfrac, double hadfrac, double thresholds[2][5]){
286 
287  double psignal[2][5][Anita::NFOUR]; memset(psignal,0,sizeof(psignal));
288 
289  double mindiodeconvl[2][5]; memset(mindiodeconvl,0,sizeof(mindiodeconvl));
290 
291  double onediodeconvl[2][5]; memset(onediodeconvl,0,sizeof(onediodeconvl));
292 
293  double timedomain_output[2][5][Anita::NFOUR]; memset(timedomain_output,0,sizeof(timedomain_output));
294  double timedomain_output_justNoise[2][5][Anita::NFOUR]; memset(timedomain_output_justNoise,0,sizeof(timedomain_output_justNoise));
295 
296 
297  int iant=anita1->GetRxTriggerNumbering(ilayer, ifold);
298 
299  if (settings1->NOISEFROMFLIGHTTRIGGER){
300  anita1->bwslice_rmsdiode[0][4] = anita1->bwslice_dioderms_fullband_allchan[0][iant][anita1->tuffIndex];
301  anita1->bwslice_rmsdiode[1][4] = anita1->bwslice_dioderms_fullband_allchan[1][iant][anita1->tuffIndex];
302  anita1->bwslice_rmsdiode[1][4] = anita1->bwslice_rmsdiode[0][4];
303  }
304 
305  // if we use the diode to perform an integral
306  // this is the number of bins to the left of center where the diode function starts to be completely overlapping with the waveform in the convolution.
307  int ibinshift=(anita1->NFOUR/4-(int)(anita1->maxt_diode/anita1->TIMESTEP));
308 
309  // now we have converted the signal to time domain waveforms for all the bands of the antenna
310 
311  double integrateenergy[5]={0.,0.,0.,0.,0.};
312 
313  for (int iband=0;iband<5;iband++) { // Only loop over allowed bands
314  if (anita1->bwslice_allowed[iband]!=1) continue;
315 
316  if (settings1->TRIGGERSCHEME == 2 || settings1->TRIGGERSCHEME == 3 || settings1->TRIGGERSCHEME == 4 || settings1->TRIGGERSCHEME == 5){
317  for (int itime=0;itime<anita1->NFOUR/2-(int)(anita1->maxt_diode/anita1->TIMESTEP);itime++) {
318  anita1->maxbin_fortotal[iband]=anita1->NFOUR/2-(int)(anita1->maxt_diode/anita1->TIMESTEP);
319 
320  // The below line seems to shorten the length of the waveform to less than HALFNFOUR
321  int itimenoisebin=anita1->NFOUR/2-(int)(anita1->maxt_diode/anita1->TIMESTEP)-itime;
322 
323  // this is just the straight sum of the two
324  anita1->total_vpol_inanita[iband][itime]=anita1->timedomainnoise_rfcm_banding[0][iband][itime]+anita1->signal_vpol_inanita[iband][itime];
325 
326  integrateenergy[iband]+=anita1->timedomainnoise_rfcm_banding[0][iband][itime]*anita1->timedomainnoise_rfcm_banding[0][iband][itime]*anita1->TIMESTEP;
327  if ( settings1->SIGNAL_FLUCT && (!settings1->NOISEFROMFLIGHTTRIGGER) ) {
328  // this reverses the noise is time, and starts with bin anita1->NFOUR/2-(int)(anita1->maxt_diode/anita1->TIMESTEP)
329  justNoise_trigPath[0][itime] = anita1->timedomainnoise_rfcm_banding[0][iband][itimenoisebin];
330  justNoise_trigPath[1][itime] = anita1->timedomainnoise_rfcm_banding[1][iband][itimenoisebin];
331  v_banding_rfcm_forfft[0][iband][itime]=v_banding_rfcm_forfft[0][iband][itime]+anita1->timedomainnoise_rfcm_banding[0][iband][itimenoisebin];
332  v_banding_rfcm_forfft[1][iband][itime]=v_banding_rfcm_forfft[1][iband][itime]+anita1->timedomainnoise_rfcm_banding[1][iband][itimenoisebin];
333  }
334  }
335  for (int itime=anita1->NFOUR/2-(int)(anita1->maxt_diode/anita1->TIMESTEP);itime<anita1->NFOUR/2;itime++) {
336  anita1->total_vpol_inanita[iband][itime]=0.;
337  v_banding_rfcm_forfft[0][iband][itime]=0.;
338  v_banding_rfcm_forfft[1][iband][itime]=0.;
339  }
340  }
341  else if ( settings1->SIGNAL_FLUCT && (!settings1->NOISEFROMFLIGHTTRIGGER) ) {
342  for (unsigned int itime = 0; itime < anita1->HALFNFOUR; ++itime){
343  // this is just a straight sum
344  anita1->total_vpol_inanita[iband][itime]=anita1->timedomainnoise_rfcm_banding[0][iband][itime]+anita1->signal_vpol_inanita[iband][itime];
345  integrateenergy[iband]+=anita1->timedomainnoise_rfcm_banding[0][iband][itime]*anita1->timedomainnoise_rfcm_banding[0][iband][itime]*anita1->TIMESTEP;
346  // this one is the one actually used by the diode
347  v_banding_rfcm_forfft[0][iband][itime] += anita1->timedomainnoise_rfcm_banding[0][iband][itime];
348  }
349  }
350  } // end loop over bands
351 
352  // Translate Anita physical layer to Anita trigger layer and phi sector
353  // (4 layers with 8,8,16,8 phi sector to 3 layers with 16 phi sectors each.
354  // In the nadir layer, 8 of the 16 slots are empty on the trigger layer.)
355  int whichlayer,whichphisector;
356  globaltrig1->GetAnitaLayerPhiSector(settings1,ilayer,ifold,whichlayer,whichphisector);
357 
358  for (int iband=0;iband<5;iband++) {
359  if (anita1->bwslice_allowed[iband]!=1) continue;
360 
361  if (settings1->LCPRCP
362  // && !(settings1->WHICH==10 && !globaltrig1->WHICHLAYERSLCPRCP[whichlayer])
363  ) {
364 
365  // Convert Horiz and Vert polarization
366  // To Left and Right circular polarization
369 
370  } else {
371 
372  for (int itime=0;itime<anita1->NFOUR/2;itime++) {
373 
374  vm_banding_rfcm_forfft[0][iband][itime] = v_banding_rfcm_forfft[0][iband][itime];
375  vm_banding_rfcm_forfft[1][iband][itime] = v_banding_rfcm_forfft[1][iband][itime];
376  vm_banding_rfcm_forfft_justNoise[0][iband][itime] = justNoise_trigPath[0][itime];
377  vm_banding_rfcm_forfft_justNoise[1][iband][itime] = justNoise_trigPath[1][itime];
378 
379 
380  }
381  }
382 
383  for (int itime=0;itime<anita1->NFOUR/2;itime++) {
384  anita1->total_diodeinput_1_inanita[iband][itime] = vm_banding_rfcm_forfft[0][iband][itime];
385  anita1->total_diodeinput_2_inanita[iband][itime] = vm_banding_rfcm_forfft[1][iband][itime];
386 
387  }
388  //volts_fullband_trigger_path_e.push_back(;
389  } // end loop over bands
390 
391 
392  for (int itime=0;itime<Anita::NFOUR/2;itime++) {
393  anita1->total_diodeinput_1_allantennas[anita1->GetRxTriggerNumbering(ilayer,ifold)][itime]=anita1->total_diodeinput_1_inanita[4][itime];
394  anita1->total_diodeinput_2_allantennas[anita1->GetRxTriggerNumbering(ilayer,ifold)][itime]=anita1->total_diodeinput_2_inanita[4][itime];
395  }
396 
397  DiodeConvolution(settings1, anita1, globaltrig1, ilayer, ifold, mindiodeconvl[0], onediodeconvl[0], psignal[0], timedomain_output[0], timedomain_output_justNoise[0], ibinshift, 0, thresholds);
398  DiodeConvolution(settings1, anita1, globaltrig1, ilayer, ifold, mindiodeconvl[1], onediodeconvl[1], psignal[1], timedomain_output[1], timedomain_output_justNoise[1], ibinshift, 1, thresholds);
399 
400  // fill channels_passing
401  // } // end if the signal is big enough the be considered
402  // now we've made the diode outputs
403  // now step in time and find the most number of bands that pass in the
404  // right time window
405  // then fills channels_passing
406  int npass, npassnoise;
407 
408  L1Trigger(anita1,timedomain_output_justNoise[0],timedomain_output_justNoise[1],thresholds, //inputs
409  globaltrig1->channels_passing_justNoise[ilayer][ifold][0],globaltrig1->channels_passing_justNoise[ilayer][ifold][1],npassnoise); //outputs
410  L1Trigger(anita1,timedomain_output[0],timedomain_output[1],thresholds, //inputs
411  globaltrig1->channels_passing[ilayer][ifold][0],globaltrig1->channels_passing[ilayer][ifold][1],npass); //outputs
412 
413 
414  // if (npass==1) std::cout << "L1 trigger " << ilayer << " " << ifold << " " << npass << std::endl;
415 
416  // if it's the closest antenna,
417  // save flag_e,h in anita class for writing to tsignals tree
418  int startbin=TMath::MinElement(5,anita1->iminbin);
419 
420  if (ilayer==anita1->GetLayer(anita1->rx_minarrivaltime) && ifold==anita1->GetIfold(anita1->rx_minarrivaltime)) {
421  for (int iband=0;iband<5;iband++) {
422  if (anita1->bwslice_allowed[iband]!=1) continue;
423  // cout << "zeroeing here 1.\n";
424  anita1->ston[iband]=0.;
425  for (int i=anita1->iminbin[iband];i<anita1->imaxbin[iband];i++) {
426  // if (iband==0 && i==anita1->NFOUR/4) {
427  // cout << "output is " << anita1->inu << "\t" << timedomain_output[0][iband][i] << "\n";
428  // }
429  // cout << "output, bwslice_rmsdiode are " << timedomain_output[0][iband][i] << "\t" << anita1->bwslice_rmsdiode[iband] << "\n";
430  if (timedomain_output[0][iband][i]/anita1->bwslice_rmsdiode[0][iband]<anita1->ston[iband]) {
431  anita1->ston[iband]=timedomain_output[0][iband][i]/anita1->bwslice_rmsdiode[0][iband];
432  // if (iband==4 && anita1->ston[iband]<0.)
433  // cout << "ston is " << anita1->ston[iband] << "\n";
434  }
435  }
436 
437 
438  for (int i=0;i<anita1->HALFNFOUR;i++) {
439  anita1->flag_e_inanita[iband][i]=0;
440  anita1->flag_h_inanita[iband][i]=0;
441  anita1->timedomain_output_inanita[0][iband][i]=timedomain_output[0][iband][i];
442  anita1->timedomain_output_inanita[1][iband][i]=timedomain_output[1][iband][i];
443 
444  }
445  for (int i=0;i<(int)flag_e[iband].size();i++) {
446  anita1->flag_e_inanita[iband][i+startbin]=flag_e[iband][i];
447  }
448  for (int i=0;i<(int)flag_h[iband].size();i++) {
449  anita1->flag_h_inanita[iband][i+startbin]=flag_h[iband][i];
450 
451  }
452  }
453 
454  }
455 
456 
457 
458  for (int iband=0;iband<5;iband++) {
459  if (anita1->bwslice_allowed[iband]!=1) continue;
460  // this is for the e polarization
461  // if we're implementing masking and the channel has been masked
462  if (settings1->CHMASKING && !ChanTrigger::IsItUnmasked(bn1->surfTrigBandMask,iband,ilayer,ifold,0)) {
463  if (globaltrig1->channels_passing[ilayer][ifold][0][iband])
464  globaltrig1->nchannels_perrx_triggered[anita1->GetRx(ilayer,ifold)]--;
465  globaltrig1->channels_passing[ilayer][ifold][0][iband]=0;// channel does not pass
466  globaltrig1->channels_passing_justNoise[ilayer][ifold][0][iband]=0;// channel does not pass
467  }
468 
469  // if we're implementing masking and the channel has been masked
470  if (settings1->CHMASKING && !ChanTrigger::IsItUnmasked(bn1->surfTrigBandMask,iband,ilayer,ifold,1)) {
471  if (globaltrig1->channels_passing[ilayer][ifold][1][iband])
472  globaltrig1->nchannels_perrx_triggered[anita1->GetRx(ilayer,ifold)]--;
473  globaltrig1->channels_passing[ilayer][ifold][1][iband]=0;// channel does not pass
474  globaltrig1->channels_passing_justNoise[ilayer][ifold][1][iband]=0;// channel does not pass
475  // note the last element of the array is 0 because this is lcp or e pol
476  }
477  } // end loop over first four bands
478 
479  // this l1_passing is only used for output to tsignals file, but really need to re-evaluate npass after the masking has been imposed before deciding whether it passes an L1 trigger
480  if (npass>=anita1->trigRequirements[0]) {
481  anita1->l1_passing=1;
482  anita1->l1_passing_allantennas[anita1->GetRxTriggerNumbering(ilayer,ifold)]=1;
483  } else {
484  anita1->l1_passing=0;
485  anita1->l1_passing_allantennas[anita1->GetRxTriggerNumbering(ilayer,ifold)]=0;
486  }
487 
488  anita1->dangle_inanita=dangle; // viewangle - changle
489  anita1->emfrac_inanita=emfrac; // viewangle - changle
490  anita1->hadfrac_inanita=hadfrac; // viewangle - changle
491 
492 
493 
494  anita1->irx=anita1->GetRx(ilayer,ifold);
495 
496  if (Anita::GetLayer(anita1->rx_minarrivaltime)==ilayer && Anita::GetIfold(anita1->rx_minarrivaltime)==ifold && anita1->tsignals->GetEntries()<settings1->HIST_MAX_ENTRIES && !settings1->ONLYFINAL && settings1->HIST==1) {
497  anita1->tsignals->Fill();
498  }
499 
500 
501  if (settings1->TRIGGERSCHEME == 3 || settings1->TRIGGERSCHEME == 4 || settings1->TRIGGERSCHEME == 5){
502  // If TRIGGERSCHEME == 3, allow all bands to pass here. This allows the coherent waveform sum trigger scheme to be used.
503  for (unsigned int ichannel = 0; ichannel < 5; ichannel++){
504  globaltrig1->channels_passing[ilayer][ifold][0][ichannel] = 1;
505  globaltrig1->channels_passing[ilayer][ifold][1][ichannel] = 1;
506  anita1->channels_passing[0][ichannel] = 1;
507  anita1->channels_passing[1][ichannel] = 1;
508  }
509 
510  unsigned int ilayer_trigger;
511  unsigned int iphisector_trigger;
512 
513  if (ilayer <= 1){
514  iphisector_trigger = ifold * 2 + ilayer;
515  ilayer_trigger = 0;
516  }else{
517  iphisector_trigger = ifold;
518  ilayer_trigger = ilayer - 1;
519  }
520  globaltrig1->volts_rx_rfcm_trigger[iphisector_trigger][ilayer_trigger].assign(anita1->total_diodeinput_1_inanita[4], anita1->total_diodeinput_1_inanita[4] + 512);
521  }
522 
523 
524 
525 
526  for (int i=0;i<2;i++) {
527 
528  for (unsigned int ibin=0;ibin<globaltrig1->arrayofhitsall[whichlayer][whichphisector][i][4].size();ibin++) {
529  anita1->arrayofhits_inanita[whichlayer][whichphisector][i][ibin]=globaltrig1->arrayofhitsall[whichlayer][whichphisector][i][4][ibin];
530  }
531  for (unsigned int ibin=globaltrig1->arrayofhitsall[whichlayer][whichphisector][i][4].size();ibin<HALFNFOUR;ibin++) {
532  anita1->arrayofhits_inanita[whichlayer][whichphisector][i][ibin]=0.;
533  }
534  // if (iband==4 && i==0)
535  // cout << "whichlayer, whichphisector, size of arrayofhits is " << whichlayer << "\t" << whichphisector << "\t" << anita1->arrayofhits_inanita[whichlayer][whichphisector][i][iband].size() << "\n";
536  }
537 
538 
539 
540 
541 
542 }// end WhichBandsPassTrigger2
543 
544 
545 
546 void ChanTrigger::DiodeConvolution(Settings *settings1, Anita *anita1, GlobalTrigger *globaltrig1, int ilayer, int ifold, double mindiodeconvl[5], double onediodeconvl[5], double psignal[5][Anita::NFOUR], double timedomain_output[5][Anita::NFOUR], double timedomain_output_justNoise[5][Anita::NFOUR], int ibinshift, int ipol, double thresholds[2][5]){
547 
548  int tempChansPassing[5]={0,0,0,0,0};
549  int tempChansPassingNoise[5]={0,0,0,0,0};
550 
551  // Translate Anita physical layer to Anita trigger layer and phi sector
552  // (4 layers with 8,8,16,8 phi sector to 3 layers with 16 phi sectors each.
553  // In the nadir layer, 8 of the 16 slots are empty on the trigger layer.)
554  int whichlayer,whichphisector;
555  globaltrig1->GetAnitaLayerPhiSector(settings1,ilayer,ifold,whichlayer,whichphisector);
556 
557 
558 
559  for (int iband=0;iband<5;iband++) {
560 
561  anita1->channels_passing[ipol][iband]=0;
562  anita1->channels_passing_justNoise[ipol][iband]=0;
563  if (anita1->bwslice_allowed[iband]!=1) continue;
564 
565  // myconvl
566  // this performs the convolution with the diode response
567  anita1->myconvlv(vm_banding_rfcm_forfft_justNoise[ipol][iband],anita1->NFOUR,anita1->fdiode_real[iband],mindiodeconvl[iband],onediodeconvl[iband],psignal[iband],timedomain_output_justNoise[iband]);
568  anita1->myconvlv(vm_banding_rfcm_forfft[ipol][iband],anita1->NFOUR,anita1->fdiode_real[iband],mindiodeconvl[iband],onediodeconvl[iband],psignal[iband],timedomain_output[iband]);
569  // loop from the ibinshift left + some delay + 10 ns
570 
571 
572  // // TEMPORARY CODE FOR PRINTING DIODE INPUT/OUTPUT
573  // if (anita1->inu==1){
574  // TCanvas *c = new TCanvas("c");
575  // string name = "newnoise";
576  // TGraph *gV = new TGraph(anita1->HALFNFOUR, anita1->fTimes, vm_banding_rfcm_forfft[ipol][iband]);
577  // gV->SetTitle("Diode Input;Time [s];Amplitude [V]");
578  // gV->Draw("Al");
579  // c->Print(Form("%s_%d_%d_%d_%d_diodeInput.png", name.c_str(), anita1->inu, ipol, ilayer, ifold));
580  // c->Print(Form("%s_%d_%d_%d_%d_diodeInput.pdf", name.c_str(), anita1->inu, ipol, ilayer, ifold));
581  // c->Print(Form("%s_%d_%d_%d_%d_diodeInput.C", name.c_str(), anita1->inu, ipol, ilayer, ifold));
582  // c->Print(Form("%s_%d_%d_%d_%d_diodeInput.root", name.c_str(), anita1->inu, ipol, ilayer, ifold));
583 
584 
585  // TGraph *g2 = new TGraph(anita1->HALFNFOUR, anita1->fTimes, timedomain_output[iband]);
586  // g2->SetTitle("Diode Output;Time [s];Diode Output [J]");
587  // g2->Draw("Al");
588  // TLine *l = new TLine (0, thresholds[ipol][iband] * anita1->bwslice_rmsdiode[iband], 200, thresholds[ipol][iband] * anita1->bwslice_rmsdiode[iband]);
589  // l->SetLineColor(kRed);
590  // l->Draw();
591  // c->Print(Form("%s_%d_%d_%d_%d_diodeOutput.png", name.c_str(), anita1->inu, ipol, ilayer, ifold));
592  // c->Print(Form("%s_%d_%d_%d_%d_diodeOutput.pdf", name.c_str(), anita1->inu, ipol, ilayer, ifold));
593  // c->Print(Form("%s_%d_%d_%d_%d_diodeOutput.C", name.c_str(), anita1->inu, ipol, ilayer, ifold));
594  // c->Print(Form("%s_%d_%d_%d_%d_diodeOutput.root", name.c_str(), anita1->inu, ipol, ilayer, ifold));
595  // delete gV;
596  // delete g2;
597  // delete c;
598  // }
599 
600 
601  // now shift right to account for arrival times
602  // this is done inside the impulse response function normally
603  // but if we don't use it, we need to apply it manually here
604  if (!settings1->APPLYIMPULSERESPONSETRIGGER){
605  Tools::ShiftRight(timedomain_output[iband],anita1->NFOUR,(int)(anita1->arrival_times[ipol][anita1->GetRx(ilayer,ifold)]/anita1->TIMESTEP));
606  Tools::ShiftRight(timedomain_output_justNoise[iband],anita1->NFOUR,(int)(anita1->arrival_times[ipol][anita1->GetRx(ilayer,ifold)]/anita1->TIMESTEP));
607  }
608 
609  if (settings1->TRIGGERSCHEME == 2 || settings1->TRIGGERSCHEME == 3 || settings1->TRIGGERSCHEME == 4 || settings1->TRIGGERSCHEME == 5){
610  // if (anita1->inu==1570)
611  //cout << "shifting left.\n";
612  Tools::ShiftLeft(timedomain_output[iband],anita1->NFOUR,ibinshift);
613  Tools::ShiftLeft(timedomain_output_justNoise[iband],anita1->NFOUR,ibinshift);
614  }
615 
616 
617  for (int itime=0;itime<Anita::NFOUR/2;itime++) {
618  anita1->timedomain_output_allantennas[ipol][anita1->GetRxTriggerNumbering(ilayer,ifold)][itime]=timedomain_output[4][itime];
619  //cerr<<iband<<" "<<i<<" "<<vm_banding_rfcm_forfft[ipol] <<" "<<timedomain_output[iband][i]<<endl;
620  }
621 
622 
623  // want the bits in arrayofhits to each represent a 2 ns interval =TRIGTIMESTEP
624  // but TIMESTEP doesn't necessarily go into TRIGTIMESTEP nicely
625 
626  int whichtrigbin=0;
627  //cout << "1 whichtrigbin is " << whichtrigbin << "\n";
628  // nextbreakpoint is how many time steps in digitization that we have to go
629  // to equal the length we want for the trigger bin
630  int nextbreakpoint=(int)((double)(whichtrigbin+1)*(globaltrig1->TRIGTIMESTEP/anita1->TIMESTEP));
631 
632  // if (whichlayer==2 && whichphisector==15)
633  // cout << "1 nextbreakpoint is " << nextbreakpoint << "\n";
634 
635  // cout << "1 nextbreakpoint is " << nextbreakpoint << "\n";
636  // keep advancing in trigger timesteps until we're past the iminbin.
637  while (nextbreakpoint<anita1->iminbin[iband]) {
638  nextbreakpoint=(int)((double)(whichtrigbin+1)*(globaltrig1->TRIGTIMESTEP/anita1->TIMESTEP));
639  whichtrigbin++;
640  // if (whichlayer==2 && whichphisector==15) {
641  // cout << "2 nextbreakpoint is " << nextbreakpoint << "\n";
642  // cout << "whichtrigbin is " << whichtrigbin << "\n";
643  // }
644  }
645  // keep track of whether each trigger bin has a hit
646  int thisisaone=0;
647  int thisisaonenoise=0;
648 
649  for (int ibin = anita1->iminbin[iband]; ibin < anita1->imaxbin[iband]; ibin++) {
650 
651  if (timedomain_output[iband][ibin] < thresholds[ipol][iband] * anita1->bwslice_rmsdiode[ipol][iband] && anita1->pol_allowed[ipol] && anita1->bwslice_allowed[iband]) { // is this polarization and bw slice allowed to pass
652  //std::cout << "VPOL : " << iband << " " << timedomain_output_1[iband][ibin] << " " << thresholds[0][iband] << " " << anita1->bwslice_rmsdiode[ipol][iband] << std::endl;
653  tempChansPassing[iband] = 1;// channel passes
654 
655 
656  thisisaone=1;
657  // cout << "got a hit.\n";
658  }
659 
660  if (timedomain_output_justNoise[iband][ibin] < thresholds[ipol][iband] * anita1->bwslice_rmsdiode[ipol][iband] && anita1->pol_allowed[ipol] && anita1->bwslice_allowed[iband]) { // is this polarization and bw slice allowed to pass
661  //std::cout << "VPOL : " << iband << " " << timedomain_output_1[iband][ibin] << " " << thresholds[0][iband] << " " << anita1->bwslice_rmsdiode[ipol][iband] << std::endl;
662  tempChansPassingNoise[iband] = 1;// channel passes
663 
664 
665  thisisaonenoise=1;
666  // cout << "got a hit.\n";
667  }
668 
669 
670  // if (whichlayer==2 && whichphisector==15)
671  //cout << "ibin, nextbreakpoint are " << ibin << "\t" << nextbreakpoint << "\n";
672  if (ibin>nextbreakpoint) {
673  //if (whichlayer==2 && whichphisector==15)
674  //cout << "I'm filling. size is " << "\t" << globaltrig1->arrayofhits[whichlayer][whichphisector][0][iband].size() << "\n";
675 
676  globaltrig1->arrayofhitsall[whichlayer][whichphisector][ipol][iband].push_back(thisisaone);
677  globaltrig1->arrayofhitsnoise[whichlayer][whichphisector][ipol][iband].push_back(thisisaonenoise);
678  // if (thisisaone) {
679  // cout << "filling with 1. phi is " << whichphisector << "\n";
680  // }
681  //if (thisisaone)
682  //cout << "filling with 1.\n";
683  //cout << "filling arrayofhits with " << thisisaone << "\n";
684  //cout << "size of arrayofhits is " << globaltrig1->arrayofhits[ilayer][ifold][0][iband].size() << "\n";
685  nextbreakpoint=(int)((double)(whichtrigbin+1)*(globaltrig1->TRIGTIMESTEP/anita1->TIMESTEP));
686  //cout << "3 nextbreakpoint is " << nextbreakpoint << "\n";
687  whichtrigbin++;
688  //cout << "3 whichtrigbin is " << whichtrigbin << "\n";
689  thisisaone=0;
690  thisisaonenoise=0;
691  }
692 
693  } // end loop over bins in the window
694 
695  anita1->channels_passing[ipol][iband]=tempChansPassing[iband];
696  anita1->channels_passing_justNoise[ipol][iband]=tempChansPassingNoise[iband];
697 
698 
699  if (tempChansPassing[iband]) {
700  //Records number of first level triggers on each antenna for a single neutrino
701  globaltrig1->nchannels_perrx_triggered[anita1->GetRx(ilayer,ifold)]++;
702 
703  }
704  } // end loop over bands
705 
706 
707 
708 }
709 
710 
712 {
713  unwarned=1;
714  for (int ipol=0;ipol<2;ipol++) {
715  for (int iband=0;iband<anita1->NBANDS+1;iband++) {
716 
717  vsignal_eachband[ipol].push_back(0.);
718  vthreshold_eachband[ipol].push_back(0.);
719  vnoise_eachband[ipol].push_back(0.);
720  vpasses_eachband[ipol].push_back(0);
721 
722  signal_eachband[ipol][iband]=0.;
723  threshold_eachband[ipol][iband]=0.;
724  noise_eachband[ipol][iband]=0.;
725  passes_eachband[ipol][iband]=0;
726  }
727  }
728 
729  Tools::Zero(bwslice_volts_pol0,5);
730  Tools::Zero(bwslice_volts_pol1,5);
731  Tools::Zero(bwslice_energy_pol0,5);
732  Tools::Zero(bwslice_energy_pol1,5);
733  Tools::Zero(bwslice_volts_pol0_em,5);
734  Tools::Zero(bwslice_volts_pol1_em,5);
735  Tools::Zero(bwslice_energy_pole,5);
736  Tools::Zero(bwslice_energy_polh,5);
737  Tools::Zero(bwslice_volts_polh,5);
738  Tools::Zero(bwslice_volts_pole,5);
739 }
740 
741 
742 
743 void ChanTrigger::ApplyAntennaGain(Settings *settings1, Anita *anita1, Balloon *bn1, Screen *panel1, int ant, Vector &n_eplane, Vector &n_hplane, Vector &n_normal){
744 
745  e_component=0;
746  h_component=0;
747  n_component=0;
748  e_component_kvector=0;
749  h_component_kvector=0;
750  n_component_kvector=0;
751  hitangle_e=0;
752  hitangle_h=0;
753 
754  int numBinShift;
755 
756 
757  double tmp_vhz[2][anita1->NFREQ];
758  double tmp_volts[2][anita1->NFOUR/2];
759 
760  for (int iband=0;iband<5;iband++) { // loop over bands
761 
762  Tools::Zero(volts_rx_forfft[0][iband], anita1->NFOUR/2);
763  Tools::Zero(volts_rx_forfft[1][iband], anita1->NFOUR/2);
764  Tools::Zero(vhz_rx[0][iband], anita1->NFREQ);
765  Tools::Zero(vhz_rx[1][iband], anita1->NFREQ);
766 
767  if (anita1->bwslice_allowed[iband]!=1) continue;
768 
769  anita1->iminbin[iband]=0.;
770  anita1->imaxbin[iband]=anita1->NFOUR/2;
771 
772  for (int jpt=0; jpt<panel1->GetNvalidPoints(); jpt++){
773 
774 
775  // CD: moved these out of the loop, since they' don't need to be there!
776  bn1->GetEcompHcompkvector(n_eplane, n_hplane, n_normal, panel1->GetVec2bln(jpt), e_component_kvector, h_component_kvector, n_component_kvector);
777  bn1->GetEcompHcompEvector(settings1, n_eplane, n_hplane, panel1->GetPol(jpt), e_component, h_component, n_component);
778  bn1->GetHitAngles(e_component_kvector, h_component_kvector, n_component_kvector, hitangle_e, hitangle_h);
779 
780 
781  for (int k=0;k<Anita::NFREQ;k++) {
782  if (anita1->freq[k]>=settings1->FREQ_LOW_SEAVEYS && anita1->freq[k]<=settings1->FREQ_HIGH_SEAVEYS){
783 
784  //Copy frequency amplitude to screen point
785  tmp_vhz[0][k]=tmp_vhz[1][k]=panel1->GetVmmhz_freq(jpt*Anita::NFREQ + k)/sqrt(2)/(anita1->TIMESTEP*1.E6);
786  // cout << tmp_vhz[0][k] << endl;
787  anita1->AntennaGain(settings1, hitangle_e, hitangle_h, e_component, h_component, k, tmp_vhz[0][k], tmp_vhz[1][k]);
788 
789  if (settings1->TUFFSTATUS==3){
790  tmp_vhz[0][k]=applyButterworthFilter(anita1->freq[k], tmp_vhz[0][k], anita1->TUFFstatus);
791  tmp_vhz[1][k]=applyButterworthFilter(anita1->freq[k], tmp_vhz[1][k], anita1->TUFFstatus);
792  }
793 
794  } // end if (seavey frequencies)
795  else {
796  tmp_vhz[0][k]=0;
797  tmp_vhz[1][k]=0;
798  }
799  } // end looping over frequencies.
800 
801  anita1->MakeArrayforFFT(tmp_vhz[0],tmp_volts[0], 90., true);
802  anita1->MakeArrayforFFT(tmp_vhz[1],tmp_volts[1], 90., true);
803 
804  // now v_banding_rfcm_h_forfft is in the time domain
805  // and now it is really in units of V
806  Tools::realft(tmp_volts[0],-1,anita1->NFOUR/2);
807  Tools::realft(tmp_volts[1],-1,anita1->NFOUR/2);
808 
809  // put it in normal time ording -T to T
810  // instead of 0 to T, -T to 0
811  Tools::NormalTimeOrdering(anita1->NFOUR/2,tmp_volts[0]);
812  Tools::NormalTimeOrdering(anita1->NFOUR/2,tmp_volts[1]);
813 
814  numBinShift = int(panel1->GetDelay(jpt) / anita1->TIMESTEP);
815  if(fabs(numBinShift) >= anita1->HALFNFOUR){
816  //cout<<"skipping"<<"\n";
817  //don't bother adding it to the total since it's shifted out of range
818  }
819  else{
820  if( panel1->GetDelay(jpt)>0 ){
821  Tools::ShiftLeft(tmp_volts[0], anita1->NFOUR/2, numBinShift );
822  Tools::ShiftLeft(tmp_volts[1], anita1->NFOUR/2, numBinShift );
823  }
824  else if( panel1->GetDelay(jpt)<0 ){
825  Tools::ShiftRight(tmp_volts[0], anita1->NFOUR/2, -1*numBinShift );
826  Tools::ShiftRight(tmp_volts[1], anita1->NFOUR/2, -1*numBinShift );
827  }
828 
829  for (int k=0;k<anita1->NFOUR/2;k++) {
830  volts_rx_forfft[0][iband][k] += tmp_volts[0][k];// * panel1->GetWeight(jpt) / panel1->GetWeightNorm();
831  volts_rx_forfft[1][iband][k] += tmp_volts[1][k];// * panel1->GetWeight(jpt) / panel1->GetWeightNorm();
832  }
833  }
834 
835  } // end loop over screen points
836 
837  // Now need to convert time domain to frequency domain
838  for (int k=0; k<anita1->NFOUR/2;k++){
839  tmp_volts[0][k]=volts_rx_forfft[0][iband][k];
840  tmp_volts[1][k]=volts_rx_forfft[1][iband][k];
841  // cout << anita1->fTimes[k] << " " << tmp_volts[0][k] << endl;
842  }
843 
844 
845  // find back the frequency domain
846  Tools::realft(tmp_volts[0],1,anita1->NFOUR/2);
847  Tools::realft(tmp_volts[1],1,anita1->NFOUR/2);
848 
849 
850  // Convert FFT arrays into standard icemc frequency amplitudes array
851  anita1->GetArrayFromFFT(tmp_volts[0], vhz_rx[0][iband]);
852  anita1->GetArrayFromFFT(tmp_volts[1], vhz_rx[1][iband]);
853 
854 
855  } // end loop over bands
856 
857 
858 #ifdef ANITA_UTIL_EXISTS
859  if (settings1->SIGNAL_FLUCT && (settings1->NOISEFROMFLIGHTDIGITIZER || settings1->NOISEFROMFLIGHTTRIGGER) )
860  getNoiseFromFlight(settings1, anita1, ant, settings1->SIGNAL_FLUCT > 0);
861 
862  if (settings1->ADDCW){
863  memset(cw_digPath, 0, sizeof(cw_digPath));
864  calculateCW(anita1, 460E6, 0, 0.00001);
865  }
866 
867 #endif
868 
869 }
870 
871 void ChanTrigger::TriggerPath(Settings *settings1, Anita *anita1, int ant, Balloon *bn1){
872 
873 
874  double integrate_energy_freq[5]={0.,0.,0.,0.,0.};
875 
876  for (int iband=0;iband<5;iband++) { // loop over bands
877  if (anita1->bwslice_allowed[iband]!=1) continue;
878 
879  anita1->iminbin[iband]=0.;
880  anita1->imaxbin[iband]=anita1->NFOUR/2;
881 
882  Tools::Zero(v_banding_rfcm_forfft[0][iband],anita1->NFOUR/2);
883  Tools::Zero(v_banding_rfcm_forfft[1][iband],anita1->NFOUR/2);
884 
885  for (int ifreq=0; ifreq<anita1->NFOUR/2; ifreq++){
886  v_banding_rfcm[0][iband][ifreq]=vhz_rx[0][iband][ifreq];
887  v_banding_rfcm[1][iband][ifreq]=vhz_rx[1][iband][ifreq];
888  }
889 
890  // If not applying the trigger impulse response
891  // Apply banding and RFCM
892  // And then convert to time domain
893  if (!settings1->APPLYIMPULSERESPONSETRIGGER){
894 
895  anita1->Banding(iband,anita1->freq,v_banding_rfcm[0][iband],Anita::NFREQ);
896  anita1->Banding(iband,anita1->freq,v_banding_rfcm[1][iband],Anita::NFREQ);
897  anita1->RFCMs(1,1,v_banding_rfcm[0][iband]);
898  anita1->RFCMs(1,1,v_banding_rfcm[1][iband]);
899 
900 
901  for (int ifreq=0;ifreq<Anita::NFREQ;ifreq++) {
902  if (anita1->freq[ifreq]>=settings1->FREQ_LOW_SEAVEYS && anita1->freq[ifreq]<=settings1->FREQ_HIGH_SEAVEYS){
903  addToChannelSums(settings1, anita1, iband, ifreq);
904  }
905  } // end loop over nfreq
906 
907 
908  anita1->MakeArrayforFFT(v_banding_rfcm[0][iband],v_banding_rfcm_forfft[0][iband], 90., true);
909  anita1->MakeArrayforFFT(v_banding_rfcm[1][iband],v_banding_rfcm_forfft[1][iband], 90., true);
910 
911  // for some reason I'm averaging over 10 neighboring bins
912  // to get rid of the zero bins
913  for (int i=0;i<anita1->NFOUR/4;i++) {
914  for (int ipol=0;ipol<2;ipol++){
915 
916  v_banding_rfcm_forfft_temp[ipol][iband][2*i] =0.;
917  v_banding_rfcm_forfft_temp[ipol][iband][2*i+1]=0.;
918 
919  int tempcount = 0;
920  for (int k=i;k<i+10;k++) {
921  if (k<anita1->NFOUR/4) {
922  v_banding_rfcm_forfft_temp[ipol][iband][2*i] +=v_banding_rfcm_forfft[ipol][iband][2*k];
923  v_banding_rfcm_forfft_temp[ipol][iband][2*i+1]+=v_banding_rfcm_forfft[ipol][iband][2*k+1];
924  tempcount++;
925  }
926  }
927 
928  v_banding_rfcm_forfft[ipol][iband][2*i] =v_banding_rfcm_forfft_temp[ipol][iband][2*i]/tempcount;
929  v_banding_rfcm_forfft[ipol][iband][2*i+1]=v_banding_rfcm_forfft_temp[ipol][iband][2*i+1]/tempcount;
930 
931  v_banding_rfcm_forfft_temp[ipol][iband][2*i] =v_banding_rfcm_forfft[ipol][iband][2*i];
932  v_banding_rfcm_forfft_temp[ipol][iband][2*i+1]=v_banding_rfcm_forfft[ipol][iband][2*i+1];
933  }
934  }
935 
936  // now v_banding_rfcm_h_forfft is in the time domain
937  // and now it is really in units of V
938  Tools::realft(v_banding_rfcm_forfft[0][iband],-1,anita1->NFOUR/2);
939  Tools::realft(v_banding_rfcm_forfft[1][iband],-1,anita1->NFOUR/2);
940 
941  // put it in normal time ording -T to T
942  // instead of 0 to T, -T to 0
943  Tools::NormalTimeOrdering(anita1->NFOUR/2,v_banding_rfcm_forfft[0][iband]);
944  Tools::NormalTimeOrdering(anita1->NFOUR/2,v_banding_rfcm_forfft[1][iband]);
945 
946  for (int itime=0; itime<anita1->NFOUR/2; itime++){
947  justSig_trigPath[0][itime] = v_banding_rfcm_forfft[0][iband][itime];
948  justSig_trigPath[1][itime] = v_banding_rfcm_forfft[1][iband][itime];
949  }
950 
951 
952  } else {
953 
954  for (int itime=0; itime<anita1->NFOUR/2 ; itime++){
955  v_banding_rfcm_forfft[0][iband][itime]=volts_rx_forfft[0][iband][itime];
956  v_banding_rfcm_forfft[1][iband][itime]=volts_rx_forfft[1][iband][itime];
957  }
958 
959 #ifdef ANITA_UTIL_EXISTS
960  // if applying the impulse response
961  applyImpulseResponseTrigger(settings1, anita1, ant, v_banding_rfcm_forfft[0][iband], v_banding_rfcm[0][iband], 0);
962  applyImpulseResponseTrigger(settings1, anita1, ant, v_banding_rfcm_forfft[1][iband], v_banding_rfcm[1][iband], 1);
963 #endif
964  }
965 
966 
967  if (settings1->ZEROSIGNAL) {
968  Tools::Zero(v_banding_rfcm_forfft[0][iband],anita1->NFOUR/2);
969  Tools::Zero(v_banding_rfcm_forfft[1][iband],anita1->NFOUR/2);
970  }
971 
972 
973  for (int i=0;i<anita1->NFOUR/4;i++) {
974  integrate_energy_freq[iband]+=v_banding_rfcm_forfft[0][iband][2*i]*v_banding_rfcm_forfft[0][iband][2*i]+v_banding_rfcm_forfft[0][iband][2*i+1]*v_banding_rfcm_forfft[0][iband][2*i+1];
975  }
976 
977  // write the signal events to a tree
978  for (int k=0;k<anita1->NFOUR/2;k++) {
979  anita1->signal_vpol_inanita[iband][k]=v_banding_rfcm_forfft[0][iband][k];
980  }
981  anita1->integral_vmmhz_foranita=integral_vmmhz;
982 
983  // Find the p2p value before adding noise
984  anita1->peak_v_banding_rfcm[0][iband]=FindPeak(v_banding_rfcm_forfft[0][iband],anita1->NFOUR/2);
985  anita1->peak_v_banding_rfcm[1][iband]=FindPeak(v_banding_rfcm_forfft[1][iband],anita1->NFOUR/2);
986 
987  // Find the p2p value before adding noise
988  for (int iband=0;iband<5;iband++) {
989  if (anita1->bwslice_allowed[iband]!=1) continue;
990  for (int ipol=0; ipol<2; ipol++) {
991  anita1->peak_v_banding_rfcm[ipol][iband]=FindPeak(v_banding_rfcm_forfft[ipol][iband],anita1->NFOUR/2);
992  }
993  }
994  } // end loop over bands
995 
996 
997 
998 }
999 
1000 
1001 
1002 
1003 
1004 
1005 void ChanTrigger::DigitizerPath(Settings *settings1, Anita *anita1, int ant, Balloon *bn1)
1006 {
1007  double vhz_rx_rfcm_e[Anita::NFREQ]; // V/Hz after rx, rfcm
1008  double vhz_rx_rfcm_h[Anita::NFREQ];
1009 
1010  int fNumPoints = anita1->HALFNFOUR;
1011 
1012  // Apply anita-3 measured impulse response
1013  if (settings1->APPLYIMPULSERESPONSEDIGITIZER){
1014  anita1->GetNoiseWaveforms(); // get noise waveforms
1015  for (int i=0;i<fNumPoints;i++){
1016  volts_rx_rfcm_lab[0][i] = volts_rx_forfft[0][4][i];
1017  volts_rx_rfcm_lab[1][i] = volts_rx_forfft[1][4][i];
1018  }
1019 
1020 #ifdef ANITA_UTIL_EXISTS
1021  applyImpulseResponseDigitizer(settings1, anita1, fNumPoints, ant, anita1->fTimes, volts_rx_rfcm_lab[0], 0);
1022  applyImpulseResponseDigitizer(settings1, anita1, fNumPoints, ant, anita1->fTimes, volts_rx_rfcm_lab[1], 1);
1023 #endif
1024 
1025  if (settings1->SIGNAL_FLUCT > 0 && !settings1->NOISEFROMFLIGHTDIGITIZER){
1026  for (int i=0;i<anita1->NFOUR/2;i++) {
1027  for (int ipol=0;ipol<2;ipol++){
1028  volts_rx_rfcm_lab[ipol][i]+=anita1->timedomainnoise_lab[ipol][i]; // add noise
1029  }
1030  }
1031  }
1032 
1033  } else {
1034 
1035 
1036  for (int ifreq=0; ifreq<anita1->NFREQ; ifreq++){
1037  vhz_rx_rfcm_e[ifreq]=vhz_rx[0][4][ifreq];
1038  vhz_rx_rfcm_h[ifreq]=vhz_rx[1][4][ifreq];
1039  }
1040  // for frequency-domain voltage-based trigger (triggerscheme==0)
1041  // we do not apply rfcm's
1042  // for other trigger types we do
1043 
1044  // apply rfcm's
1045  if (settings1->TRIGGERSCHEME==1 || settings1->TRIGGERSCHEME==2 || settings1->TRIGGERSCHEME == 3 || settings1->TRIGGERSCHEME == 4 || settings1->TRIGGERSCHEME == 5) {
1046  anita1->RFCMs(1,1,vhz_rx_rfcm_e);
1047  anita1->RFCMs(1,1,vhz_rx_rfcm_h);
1048  }
1049 
1050  double scale;
1051  double sumpower=0.;
1052  if (settings1->PULSER) { // if we are using the pulser spectrum instead of simulating neutrinos
1053  scale=Tools::dMax(vhz_rx_rfcm_e,Anita::NFREQ)/Tools::dMax(anita1->v_pulser,anita1->NFOUR/4);
1054  sumpower=0.;
1055  int ifour;// index for fourier transform
1056  for (int i=0;i<Anita::NFREQ;i++) {
1057  ifour=Tools::Getifreq(anita1->freq[i],anita1->freq_forfft[0],anita1->freq_forfft[anita1->NFOUR/2-1],anita1->NFOUR/4);
1058  vhz_rx_rfcm_e[i]=scale*anita1->v_pulser[ifour];
1059  vhz_rx_rfcm_h[i]=0.;
1060  sumpower+=vhz_rx_rfcm_e[i]*vhz_rx_rfcm_e[i];
1061  }
1062  } // end if we are just using the pulser spectrum
1063 
1064 
1065  for (int ifreq=0;ifreq<Anita::NFREQ;ifreq++) {
1066  anita1->avgfreq_rfcm[ifreq]+=vhz_rx_rfcm_e[ifreq];
1067  }
1068 
1069  // change their length from Anita::NFREQ to HALFNFOUR
1070  anita1->MakeArrayforFFT(vhz_rx_rfcm_e,volts_rx_rfcm[0], 90., true);
1071  anita1->MakeArrayforFFT(vhz_rx_rfcm_h,volts_rx_rfcm[1], 90., true);
1072 
1073 
1074  // now the last two are in the frequency domain
1075  // convert to the time domain
1076  // still don't have any noise
1077 
1078  Tools::realft(volts_rx_rfcm[0],-1,anita1->HALFNFOUR);
1079  Tools::realft(volts_rx_rfcm[1],-1,anita1->HALFNFOUR);
1080 
1081  anita1->GetNoiseWaveforms(); // get noise waveforms
1082 
1083  // find the peak right here and it might be the numerator of the horizontal axis of matt's plot
1084  anita1->peak_rx_rfcm_signalonly[0]=ChanTrigger::FindPeak(volts_rx_rfcm[0],anita1->HALFNFOUR); // with no noise
1085  anita1->peak_rx_rfcm_signalonly[1]=ChanTrigger::FindPeak(volts_rx_rfcm[1],anita1->HALFNFOUR);
1086 
1087  if (settings1->SIGNAL_FLUCT) {
1088  for (int i=0;i<anita1->NFOUR/2;i++) {
1089  for (int ipol=0;ipol<2;ipol++){
1090  volts_rx_rfcm[ipol][i]+=anita1->timedomainnoise_rfcm[ipol][i]; // add noise.
1091  }
1092  }
1093  }
1094 
1095 
1096  anita1->peak_rx_rfcm[0]=ChanTrigger::FindPeak(volts_rx_rfcm[0],anita1->HALFNFOUR); // with noise
1097  anita1->peak_rx_rfcm[1]=ChanTrigger::FindPeak(volts_rx_rfcm[1],anita1->HALFNFOUR); // with noise
1098 
1099 
1100  double vhz_rx_rfcm_lab_e[Anita::NFREQ]; // V/Hz after rx, rfcm and lab
1101  double vhz_rx_rfcm_lab_h[Anita::NFREQ];
1102 
1103  for (int i=0;i<Anita::NFREQ;i++) {
1104  vhz_rx_rfcm_lab_e[i]=vhz_rx_rfcm_e[i];
1105  vhz_rx_rfcm_lab_h[i]=vhz_rx_rfcm_h[i];
1106  }
1107  // now go back to vhz_rx_e,h and apply rfcm's and surf attn. and then we will write the time domain waveforms to tsignals for andres
1108  // apply surf (lab) attn.
1109  anita1->labAttn(vhz_rx_rfcm_lab_e);
1110  anita1->labAttn(vhz_rx_rfcm_lab_h);
1111 
1112  for (int i=0;i<Anita::NFREQ;i++) {
1113  anita1->avgfreq_rfcm_lab[i]+=vhz_rx_rfcm_lab_e[i];
1114  }
1115 
1116  // change their length from Anita::NFREQ to HALFNFOUR
1117  anita1->MakeArrayforFFT(vhz_rx_rfcm_lab_e,volts_rx_rfcm_lab[0], 90., true);
1118  anita1->MakeArrayforFFT(vhz_rx_rfcm_lab_h,volts_rx_rfcm_lab[1], 90., true);
1119 
1120  // now the last two are in the frequency domain
1121  // convert to the time domain
1122  // still don't have any noise
1123  Tools::realft(volts_rx_rfcm_lab[0],-1,anita1->HALFNFOUR);
1124  Tools::realft(volts_rx_rfcm_lab[1],-1,anita1->HALFNFOUR);
1125 
1126  // put it in normal time ording -T to T
1127  // instead of 0 to T, -T to 0
1128  Tools::NormalTimeOrdering(anita1->NFOUR/2,volts_rx_rfcm_lab[0]); // EH, why only this has NormalTimeOrdering applied? Why not before?
1129  Tools::NormalTimeOrdering(anita1->NFOUR/2,volts_rx_rfcm_lab[1]);
1130 
1131  if (settings1->SIGNAL_FLUCT > 0) {
1132  for (int i=0;i<anita1->NFOUR/2;i++) {
1133  for (int ipol=0;ipol<2;ipol++){
1134  justSig_digPath[ipol][i] = volts_rx_rfcm_lab[ipol][i];
1135  volts_rx_rfcm_lab[ipol][i]+=anita1->timedomainnoise_lab[ipol][i]; // add noise
1136  }
1137  }
1138  }//end if signal_fluct
1139 
1140  } // END ELSE IMPULSE RESPONSE
1141 }// end DigitizerPath()
1142 
1143 
1144 
1145 
1146 void ChanTrigger::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])
1147 {
1148  int ant = anita1->GetRxTriggerNumbering(ilayer, ifold);
1149 
1150 
1151  // now shift right to account for arrival times
1152  // this is done inside the impulse response function normally
1153  // if we don't use it, we need to do it here
1154  if (!settings1->APPLYIMPULSERESPONSEDIGITIZER){
1155  // for (int i=0;i<48;i++) std::cout << "Arrival times " << anita1->arrival_times[0][anita1->GetRx(ilayer,ifold)] << std::endl;
1156  Tools::ShiftRight(volts_rx_rfcm_lab[0],anita1->NFOUR/2, int(anita1->arrival_times[0][anita1->GetRx(ilayer,ifold)]/anita1->TIMESTEP));
1157  Tools::ShiftRight(volts_rx_rfcm_lab[1],anita1->NFOUR/2, int(anita1->arrival_times[1][anita1->GetRx(ilayer,ifold)]/anita1->TIMESTEP));
1158  }
1159 
1160  for (int i=0;i<anita1->NFOUR/2;i++) {
1161  volts_rx_rfcm_lab_e_all[anita1->GetRx(ilayer, ifold)][i] = volts_rx_rfcm_lab[0][i];
1162  volts_rx_rfcm_lab_h_all[anita1->GetRx(ilayer, ifold)][i] = volts_rx_rfcm_lab[1][i];
1163  }
1164 
1165  // now vmmhz_rx_rfcm_lab_e,h_forfft are the time domain waveforms after the antenna and lab attenuation
1166  // now find peak voltage
1167  // these get written to a tree
1168  anita1->peak_rx_rfcm_lab[0]=ChanTrigger::FindPeak(volts_rx_rfcm_lab[0],anita1->HALFNFOUR);
1169  anita1->peak_rx_rfcm_lab[1]=ChanTrigger::FindPeak(volts_rx_rfcm_lab[1],anita1->HALFNFOUR);
1170 
1171 
1172  // END OF DIGITIZER PATH
1174 
1175 
1176 }
1177 
1178 
1179 
1181 
1182 }
1183 
1184 
1185 double ChanTrigger::FindPeak(double *waveform,int n) {
1186 
1187  // find peak abs(voltage) of this waveform
1188 
1189  double peak=0.; // positive peak
1190 
1191  for (int i=0;i<n;i++) {
1192  if (fabs(waveform[i])>peak)
1193  peak=fabs(waveform[i]);
1194  }
1195  return peak;
1196 
1197 }
1198 
1199 
1200 void ChanTrigger::addToChannelSums(Settings *settings1,Anita *anita1,int ibw, int k) {
1201 
1202  double term_e= v_banding_rfcm[0][ibw][k]* // for the integral over e-field
1203  (settings1->BW/(double)Anita::NFREQ/1.E6); // width of a frequency bin
1204  // uses e- and h-components instead of lcp,rcp, for Anita-lite
1205 
1206  double energyterm_e=v_banding_rfcm[0][ibw][k]*v_banding_rfcm[0][ibw][k]* // for the integral of energy of time T=N delta t = 1/delta f
1207  (settings1->BW/(double)Anita::NFREQ/1.E6)*(settings1->BW/(double)Anita::NFREQ/1.E6)/50.*
1208  anita1->INTEGRATIONTIME; // divide by width of a freq. bin
1209  // end divide by 50 ohms
1210 
1211 
1212  double term_h=v_banding_rfcm[1][ibw][k]* // for the integral over e-field
1213  (settings1->BW/(double)Anita::NFREQ/1.E6);
1214 
1215  double energyterm_h=v_banding_rfcm[1][ibw][k]*v_banding_rfcm[1][ibw][k]* // for the integral over energy
1216  (settings1->BW/(double)Anita::NFREQ/1.E6)*(settings1->BW/(double)Anita::NFREQ/1.E6)/50.*
1217  anita1->INTEGRATIONTIME; // multiply by frequency bin and divide by 50 ohms
1218 
1219 
1220  bwslice_volts_pole[ibw]+=term_e;
1221  bwslice_energy_pole[ibw]+=energyterm_e;
1222  bwslice_volts_polh[ibw]+=term_h;
1223  bwslice_energy_polh[ibw]+=energyterm_h;
1224 
1225 }
1226 
1227 
1228 double ChanTrigger::ADCCountstoPowerThreshold(Anita *anita1, int ipol, int iant) {
1229  // first convert threshold in adc counts to the singles rate
1230  // do this using threshold scans taken before the flight
1231 
1232  // For Anita-3 using run 11927
1233  // these curves were read in the Balloon constructor
1234  // first check if the threshold in adc counts is in the allowable range
1235  Float_t threshadc = (Float_t)anita1->thresholds[ipol][iant];
1236 
1237  // If there was a problem reading the flight threshold
1238  // return 5
1239  // 5 is the average relative threshold corresponding to
1240  // 500kHz scalers in a full band trigger
1241  if (threshadc<10){
1242  return 5;
1243  }
1244 
1245  // Broken channel during ANITA-3 flight
1246  if (ipol==1 && iant==7){
1247  return 5;
1248  }
1249 
1250  if (threshadc<anita1->minadcthresh[ipol][iant]) {
1251  if (unwarned) {
1252  cout << "Warning! ADC threshold is outside range of measured threshold scans.";
1253  cout << "It is below the minimum so set it to the minimum. Will not be warned again.\n";
1254  unwarned=0;
1255  }
1256  threshadc=anita1->minadcthresh[ipol][iant];
1257  }
1258  if (threshadc>anita1->maxadcthresh[ipol][iant]) {
1259  if (unwarned) {
1260  cout << "Warning! ADC threshold is outside range of measured threshold scans.";
1261  cout << "It is higher than the maximum so set it to the maximum. Will not be warned again.\n";
1262  unwarned=0;
1263  }
1264  threshadc=anita1->maxadcthresh[ipol][iant];
1265  }
1266 
1267  // Now find singles rate for this threshold
1268  // first sort thresholds
1269  int index=TMath::BinarySearch(anita1->npointThresh, anita1->threshScanThresh[ipol][iant], threshadc);
1270 
1271  thisrate=(double)anita1->threshScanScaler[ipol][iant][index]; // these scalers are in kHz
1272 
1273  thisrate=(double)anita1->scalers[ipol][iant];
1274 
1275  // now find threshold for this scaler. Here, scalers have to be in MHz.
1276  thisrate=thisrate/1.E3; // put it in MHz
1277 
1278  // figure out what band we're talking about
1279  // int iband=Anita::SurfChanneltoBand(ichan);
1280  // FOR THE MOMENT JUST USING THE FULL BAND
1281  int iband =3;
1282  thispowerthresh=rateToThreshold(thisrate,iband);
1283 
1284  // Avoid inf and nan: 5 is the relative power threshold corresponding to 450kHz scalers
1285  if (thispowerthresh>999999) return 5.40247;
1286  if (thispowerthresh<0.0001) return 5.40247;
1287 
1288  // // Limit on relative power threshold to avoid thermal noise to trigger
1289  // if (thispowerthresh<4.5) return 4.5;
1290 
1291  return thispowerthresh;
1292 
1293 }
1294 
1295 
1297 
1298  return thisrate;
1299 }
1300 
1301 
1302 
1303 double ChanTrigger::rateToThreshold(double rate, int band)
1304 {
1305  double constant=0.;
1306  double slope=0.;
1307  //Note: This method is currently very specific. It assumes ANITA 06 parameters and
1308  //an exponential diode model with time constant 3.75e-9 s.
1309  //The rate to threshold relationship is modeled as rate = exp(constant + slope * threshold).
1310  //The values of the constant and the slope were found by running the diode over noise traces with
1311  //different thresholds, and measuring the trigger rate at each threshold.
1312  switch (band) {
1313  case 0:
1314  constant = 5.15629;
1315  slope = -0.94107;
1316  break;
1317  case 1:
1318  constant = 5.33636;
1319  slope = -1.04554;
1320  break;
1321  case 2:
1322  constant = 5.76685;
1323  slope = -1.28046;
1324  break;
1325  case 3:
1326  constant = 5.87953;
1327  slope = -1.32115;
1328  break;
1329  default:
1330  std::cerr<<"[AnitaHardwareTrigger::rateToThreshold] : Unknown band selected (band "<<band<<"?)!\n";
1331  exit(1);
1332  break;
1333  } //end switch (band)
1334  return (log(rate) - constant) / slope;
1335 } //method AnitaHardwareTrigger::rateToThreshold(double rate, int band)
1336 
1337 
1338 
1339 int ChanTrigger::IsItUnmasked(unsigned short surfTrigBandMask[9][2],int ibw,int ilayer, int ifold, int ipol) {
1340 
1341  if (ibw>3)
1342  return 1;
1343 
1344  int whichband= Anita::WhichBand(ibw,ipol); // from 1 to 8, which scalar channel on an antenna this band corresponds to.
1345 
1346  int surf=Anita::AntennaNumbertoSurfNumber(ilayer,ifold); // which surf, 1-9
1347 
1348  int antenna=Anita::GetAntennaNumber(ilayer,ifold); // which antenna, 1-32
1349 
1350  if (antenna%2==0) // if it's divisible by 2, increase whichband by 8 so it runs 1 to 16
1351  whichband+=8;
1352 
1353  int antennaonsurf=(antenna-1)%4; // number that runs 0-3 for four antennas on the surf
1354 
1355  unsigned short whichbit= 1 << (whichband-1); // which bit of surfTrigBandMask we're interested in. Starts with 1 and multiplies it by whichband-1 powers of 2
1356  // the max this can be is 2^15
1357  // which we & with surfTrigBandMask we get whether that bit is 1 or 0
1358 
1359  if (antennaonsurf<2) {
1360  if ((surfTrigBandMask[surf-1][0] & whichbit)>0)
1361  return 0;
1362  }
1363  else {
1364  if ((surfTrigBandMask[surf-1][1] & whichbit)>0)
1365  return 0;
1366  }
1367 
1368  return 1;
1369 
1370 
1371 }
1372 
1373 
1374 
1375 
1376 
1377 void ChanTrigger::L1Trigger(Anita *anita1,double timedomain_output_1[5][Anita::NFOUR],double timedomain_output_2[5][Anita::NFOUR],double powerthreshold[2][5],
1378  int *channels_passing_e_forglob,int *channels_passing_h_forglob,int &npass) {
1379 
1380  int maxsample=TMath::MaxElement(5,anita1->imaxbin);
1381  int minsample=TMath::MinElement(5,anita1->iminbin);
1382 
1383  for (int j=0;j<5;j++) {
1384  flag_e[j].clear();
1385  flag_h[j].clear();
1386 
1387  for (int i=minsample;i<maxsample;i++) {
1388  // std::cout << anita1->inu << " " << timedomain_output_1[j][i] << " " << powerthreshold[0][j] << " " << anita1->bwslice_rmsdiode[j] << std::endl;
1389  if (timedomain_output_1[j][i]<powerthreshold[0][j]*anita1->bwslice_rmsdiode[0][j] && anita1->bwslice_allowed[j]==1) {
1390  flag_e[j].push_back(1);
1391 
1392  }
1393  else
1394  flag_e[j].push_back(0);
1395 
1396 
1397  if (timedomain_output_2[j][i]<powerthreshold[1][j]*anita1->bwslice_rmsdiode[1][j] && anita1->bwslice_allowed[j]==1)
1398  flag_h[j].push_back(1);
1399  else
1400  flag_h[j].push_back(0);
1401 
1402  } // end loop over samples in window where we look for single channel trigger firing
1403  } // end loop over bands
1404 
1405  int nstayhigh=(int)(anita1->l1window/anita1->TIMESTEP);
1406  // now make each flag stay high for the required amount to time
1407  for (int j=0;j<5;j++) {
1408  for (int i=minsample;i<maxsample;i++) { // loop over samples in window where we looked for a single channel trigger
1409 
1410  if (flag_e[j][i-minsample]==1) // if the flag is high (remember the second index of flag_e counts from the start of the window)
1411  for(int k=nstayhigh-1; k>0 && i<maxsample-1; k--) { // then for nstayhigh-1 samples after than we keep it high
1412  // i<maxsample-1 makes sure that the second index of flag_e is always less than maxsample-minsample-1.
1413  i++;
1414  flag_e[j][i-minsample]=1;
1415 
1416  }
1417 
1418  // if (flag_e[j][i]==1) {
1419  // for (int k=i;k<i+nstayhigh;k++) {
1420  // if (k<NSAMPLES)
1421  // flag_e[j][k]=1;
1422  // } // end loop over samples where we want it to stay high
1423 
1424  // } // end if flag is high
1425  }
1426 
1427  for (int i=minsample;i<maxsample;i++) {
1428  if (flag_h[j][i-minsample]==1)
1429  for(int k=nstayhigh-1; k>0 && i<maxsample-1; k--) {
1430  i++;
1431  flag_h[j][i-minsample]=1;
1432  }
1433 
1434  // if (flag_h[j][i]==1) {
1435  // for (int k=i;k<i+nstayhigh;k++) {
1436  // if (k<NSAMPLES)
1437  // flag_h[j][k]=1;
1438  // } // end loop over samples where we want it to stay high
1439 
1440  // } // end if flag is high
1441 
1442  } // end loop over samples
1443  } // end loop over bands
1444 
1445  // now find the sample with the highest number of bands that pass
1446  int maxbands=0;
1447  int nbands_pass=0;
1448  for (int i=minsample;i<maxsample;i++) {
1449  nbands_pass=0;
1450  for (int j=0;j<5;j++) {
1451 
1452  if (flag_e[j][i-minsample]==1)
1453  nbands_pass++;
1454  if (flag_h[j][i-minsample]==1)
1455  nbands_pass++;
1456  }
1457 
1458  if (nbands_pass>maxbands) {
1459 
1460  maxbands=nbands_pass;
1461  for (int j=0;j<5;j++) {
1462  channels_passing_e_forglob[j]=flag_e[j][i-minsample];
1463  channels_passing_h_forglob[j]=flag_h[j][i-minsample];
1464  }
1465  }
1466  }
1467  npass=maxbands;
1468 
1469 
1470 }
1471 
1472 
1473 
1474 double ChanTrigger::GetNoise(Settings *settings1,double altitude_bn,double geoid,double theta_zenith,double bw,double temp) {
1475 
1476  int NSTEPS=1000;
1477  // double VSKY=150;
1478  double VSKY=15;
1479  double VICE=240;
1480  double VSYSTEM=200;
1481 
1482  double sum=0;
1483  double theta_pos=0;
1484  double theta_signed=0;
1485  double theta_cant=theta_zenith-PI/2;
1486  double theta_horizon=acos(geoid/(geoid+altitude_bn)); // angle between horizontal on the payload and line of sight to horizon
1487  // double theta_horizon=sqrt(2*altitude_bn/geoid); // angle between horizontal on the payload and line of sight to horizon
1488  //double theta_horizon=-1;
1489  double theta_0=50*RADDEG;
1490  double integral=0.;
1491  double integral_firsthalf=0;
1492  double integral_secondhalf=0;
1493  double vnoise=0;
1494 
1495  if (settings1->WHICH != 0) {
1496 
1497  for (int i=0;i<NSTEPS;i++) {
1498 
1499  // step in theta
1500  theta_pos=(double)fabs(-PI+(double)i/(double)NSTEPS*2*PI); // this is always a positive number
1501  theta_signed=(double)(-PI+(double)i/(double)NSTEPS*2*PI); // this is allowed to be signed
1502 
1503  if (theta_signed<theta_horizon-theta_cant) {
1504  vnoise=VSKY+VSYSTEM;
1505  integral_firsthalf+=exp(-2*ALOG2*pow(theta_pos/theta_0,2))*2*PI/NSTEPS;
1506  } //if
1507  else {
1508  vnoise=VICE+VSYSTEM;
1509  integral_secondhalf+=exp(-2*ALOG2*pow(theta_pos/theta_0,2))*2*PI/NSTEPS;
1510  } //else
1511 
1512  sum+=vnoise*exp(-2*ALOG2*pow(theta_pos/theta_0,2))*2*PI/NSTEPS;
1513  integral+=exp(-2*ALOG2*pow(theta_pos/theta_0,2))*2*PI/NSTEPS;
1514  } //if
1515 
1516  sum=sum/integral;
1517 
1518  // cout << "sum, KBOLTZ, bw, sqrt are " << sum << " " << KBOLTZ << " " << bw << " " << sqrt(sum*50.*KBOLTZ*bw) << "\n";
1519  return sqrt(sum*50.*KBOLTZ*bw);
1520  } //if (settings1->WHICH != 0)
1521  else if (settings1->WHICH == 0)
1522  return sqrt(temp*50.*KBOLTZ*bw);
1523 
1524  return 0;
1525 }//GetNoise
1526 
1527 
1528 
1529 void ChanTrigger::GetThresholds(Settings *settings1,Anita *anita1,int ilayer,double thresholds[2][5]) {
1530 
1531  if (ilayer==3 && settings1->DISCONES==2) // if it's a nadir layer
1532  for (int i=0;i<5;i++) {
1533  thresholds[0][i]=anita1->powerthreshold_nadir[i];
1534  thresholds[1][i]=anita1->powerthreshold_nadir[i];
1535  }
1536  else
1537  for (int i=0;i<5;i++) {
1538  thresholds[0][i]=anita1->powerthreshold[i];
1539  thresholds[1][i]=anita1->powerthreshold[i];
1540  }
1541 }
1542 
1543 
1544 
1545 double ChanTrigger::applyButterworthFilter(double ff, double ampl, int notchStatus[3]){
1546  // Butterworth filter for two ANITA notches.
1547  // order0 = order1 = 1 may be closer to hardware notch
1548  // but 2 gives better SW rejection in analysis spectrum.
1549  // f0 is fairly constant, f1 does vary with time.
1550  double f[3] = {250e6, 360e6, 460e6};
1551  double W[3] = { 45e6, 55e6, 50e6};
1552  double order[3] = { 2., 2., 2.};
1553 
1554  double denominator = 1.;
1555  for (int i=0; i<3; i++){
1556  denominator += notchStatus[i]*pow(ff*W[i]/(ff*ff-f[i]*f[i]),2.*order[i]);
1557  }
1558 
1559  return ampl/sqrt(denominator);
1560 }
1561 
1562 
1563 
1564 
1565 
1566 
1567 #ifdef ANITA_UTIL_EXISTS
1568 void ChanTrigger::applyImpulseResponseDigitizer(Settings *settings1, Anita *anita1, int nPoints, int ant, double *x, double y[512], bool pol){
1569 
1570  int ipol=0;
1571  int iring=2;
1572  if (pol) ipol = 1;
1573  if (ant<16) iring=0;
1574  else if (ant<32) iring=1;
1575 
1576  int iphi = ant - (iring*16);
1577 
1578  if (settings1->ADDCW){
1579  for (int i=0;i<nPoints;i++){
1580  y[i]+=cw_digPath[ipol][i];
1581  }
1582  }
1583 
1584 
1585  if (settings1->ZEROSIGNAL){
1586  for (int i=0;i<nPoints;i++) y[i]=0;
1587  }
1588 
1589  TGraph *graph1;
1590  if (settings1->TRIGGEREFFSCAN && !pol){
1591  graph1 = getPulserAtAMPA(anita1, ant);
1592  } else {
1593  graph1 = new TGraph(nPoints, x, y);
1594  }
1595 
1596 
1597  // Upsample waveform to same deltaT of the signal chain impulse response
1598  TGraph *graphUp = FFTtools::getInterpolatedGraph(graph1, anita1->deltaT);
1599 
1600 
1601  TGraph *surfSignal;
1602 
1603 
1604  //Calculate convolution
1605  if(settings1->TUFFSTATUS==0){
1606  surfSignal = FFTtools::getConvolution(graphUp, anita1->fSignalChainResponseDigitizer[ipol][iring][iphi]);
1607  }
1608  else
1609  {
1610  // keith editing 1/24/18
1611  surfSignal = FFTtools::getConvolution(graphUp, anita1->fSignalChainResponseDigitizerTuffs[ipol][iring][iphi][anita1->tuffIndex]);
1612  // end keith editing
1613  }// end else for ANITA-4
1614 
1615  int irx = ant;
1616  if (iring==0) {
1617  if (ant%2==0) irx = ant/2;
1618  else irx = 8 + ant/2;
1619  }
1620 
1621  // Translate waveform according to arrival times
1622  TGraph *surfTrans = FFTtools::translateGraph(surfSignal, anita1->arrival_times[ipol][irx]*1e9 ) ;
1623 
1624  //Downsample again
1625  TGraph *surfSignalDown = FFTtools::getInterpolatedGraph(surfTrans, 1/2.6);
1626 
1627  // add thermal noise for anita-3 flight
1628  if (settings1->SIGNAL_FLUCT && settings1->NOISEFROMFLIGHTDIGITIZER) {
1629  for (int i=0;i<nPoints;i++){
1630  justSig_digPath[ipol][i] = surfSignalDown->Eval(x[i]);
1631  if(settings1->ADDCW){
1632  y[i] += justSig_digPath[ipol][i];
1633  y[i] += justNoise_digPath[ipol][i];
1634  }
1635  else{
1636  y[i] = justSig_digPath[ipol][i] + justNoise_digPath[ipol][i];
1637  }
1638  }
1639  } else {
1640  for (int i=0;i<nPoints;i++) justSig_digPath[ipol][i] = y[i] = surfSignalDown->Eval(x[i]);
1641  }
1642 
1643 
1644 // if ((iphi ==11 && pol==0)){
1645 // TCanvas *c = new TCanvas("c");
1646 // graph1->Draw("Al");
1647 // c->Print("DigitPath_graph1.png");
1648 // graphUp->Draw("Al");
1649 // c->Print("DigitPath_graphUp.png");
1650 // surfSignal->Draw("Al");
1651 // c->Print("DigitPath_surfSignal.png");
1652 // surfSignalDown->Draw("Al");
1653 // c->Print("DigitPath_surfSignalDown.png");
1654 // }
1655 
1656 
1657  // Cleaning up
1658  delete surfSignalDown;
1659  delete surfTrans;
1660  delete surfSignal;
1661  delete graphUp;
1662  delete graph1;
1663 }
1664 
1665 void ChanTrigger::applyImpulseResponseTrigger(Settings *settings1, Anita *anita1, int ant, double y[512], double *vhz, bool pol){
1666 
1667  int nPoints = anita1->HALFNFOUR;
1668  double *x = anita1->fTimes;
1669 
1670  if (settings1->ZEROSIGNAL){
1671  for (int i=0;i<nPoints;i++) y[i]=0;
1672  }
1673 
1674  TGraph *graph1;
1675  if (settings1->TRIGGEREFFSCAN && !pol){
1676  graph1 = getPulserAtAMPA(anita1, ant);
1677  } else {
1678  graph1 = new TGraph(nPoints, x, y);
1679  }
1680 
1681  // Upsample waveform to same deltaT of the signal chain impulse response
1682  TGraph *graphUp = FFTtools::getInterpolatedGraph(graph1, anita1->deltaT);
1683 
1684  double voltsArray[512];
1685  int ipol=0;
1686  int iring=2;
1687  if (pol) ipol = 1;
1688  if (ant<16) iring=0;
1689  else if (ant<32) iring=1;
1690 
1691  int iphi = ant - (iring*16);
1692 
1693  //Calculate convolution
1694 
1695 // begin keith edits
1696  TGraph *surfSignal;
1697  if (settings1->TUFFSTATUS==0){
1698  surfSignal = FFTtools::getConvolution(graphUp, anita1->fSignalChainResponseTrigger[ipol][iring][iphi]);
1699  }
1700  else
1701  {
1702  // keith editing 1/24/18
1703  surfSignal = FFTtools::getConvolution(graphUp, anita1->fSignalChainResponseTriggerTuffs[ipol][iring][iphi][anita1->tuffIndex]);
1704  // cout << anita1->tuffIndex << " is the tuff Index" << endl;
1705  // end keith editing
1706  }// end else anita 4
1707 // end keith edits
1708 
1709  int irx = ant;
1710  if (iring==0) {
1711  if (ant%2==0) irx = ant/2;
1712  else irx = 8 + ant/2;
1713  }
1714 
1715  // Translate signal
1716  TGraph *surfTrans = FFTtools::translateGraph(surfSignal, anita1->arrival_times[ipol][irx]*1e9 ) ;
1717 
1718  //Downsample again
1719  TGraph *surfSignalDown = FFTtools::getInterpolatedGraph(surfTrans, 1/2.6);
1720 
1721  // add thermal noise for anita-3 flight
1722  if (settings1->SIGNAL_FLUCT && settings1->NOISEFROMFLIGHTTRIGGER) {
1723  for (int i=0;i<nPoints;i++){
1724  justSig_trigPath[ipol][i] = surfSignalDown->Eval(x[i]);
1725  y[i] = voltsArray[i] = justSig_trigPath[ipol][i] + justNoise_trigPath[ipol][i];
1726  // std::cout << i << " " << justNoise_trigPath[ipol][i] << std::endl;
1727  }
1728  } else {
1729  for (int i=0;i<nPoints;i++) justSig_trigPath[ipol][i] = y[i] = voltsArray[i] = surfSignalDown->Eval(x[i]);
1730  }
1731 
1732  // find back the frequency domain
1733  Tools::realft(voltsArray,1,anita1->NFOUR/2);
1734 
1735  //convert the V pol time waveform into frequency amplitudes
1736  anita1->GetArrayFromFFT(voltsArray, vhz);
1737 
1738  // if (anita1->inu==1 && pol==0 && (ant==16 || ant==31 || ant==32 || ant==47)){
1739  // TCanvas *c = new TCanvas("c");
1740  // graph1->Draw("Al");
1741  // c->Print(Form("TriggerPath_ant%i_graph1.png", ant));
1742  // graphUp->Draw("Al");
1743  // c->Print(Form("TriggerPath_ant%i_graphUp.png", ant));
1744  // surfSignal->Draw("Al");
1745  // c->Print(Form("TriggerPath_ant%i_surfSignal.png", ant));
1746  // surfSignalDown->Draw("Al");
1747  // c->Print(Form("TriggerPath_ant%i_surfSignalDown.png", ant));
1748  // TGraph *gtemp = new TGraph (nPoints, x, y);
1749  // gtemp->Draw("Al");
1750  // c->Print(Form("TriggerPath_ant%i_surfSignalDown_noise.png", ant));
1751  // // TFile *out = new TFile("Icemc_signalChainTrigger.root", "recreate");
1752  // // graph1->Write("gInput");
1753  // // graphUp->Write("gInputUp");
1754  // // surfSignal->Write("gImpResp");
1755  // // surfSignalDown->Write("gImpRespDown");
1756  // // gtemp->Write("gImpRespDownNoise");
1757  // // out->Close();
1758  // }
1759 
1760  // Cleaning up
1761  delete surfSignalDown;
1762  delete surfTrans;
1763  delete surfSignal;
1764  delete graphUp;
1765  delete graph1;
1766 }
1767 
1768 
1769 void ChanTrigger::getNoiseFromFlight(Settings *settings1, Anita* anita1, int ant, bool also_digi){
1770 // std::cout << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << std::endl;
1771  Int_t numFreqs = anita1->numFreqs;
1772  FFTWComplex *phasorsDig = new FFTWComplex[numFreqs];
1773  FFTWComplex *phasorsTrig = new FFTWComplex[numFreqs];
1774  phasorsDig[0].setMagPhase(0,0);
1775  phasorsTrig[0].setMagPhase(0,0);
1776  double *freqs = anita1->freqs;
1777  Double_t sigma, realPart, imPart, trigNorm, digNorm;
1778  int iring=2;
1779  if (ant<16) iring=0;
1780  else if (ant<32) iring=1;
1781  TRandom * rng = getRNG(RNG_SIGNAL_FLUCT);
1782 
1783  int iphi = ant - (iring*16);
1784 
1785  for (int ipol=0; ipol<2; ipol++){
1786 
1787  for(int i=1;i<numFreqs;i++) {
1788 
1789  if (freqs[i]*1e6>=settings1->FREQ_LOW_SEAVEYS && freqs[i]*1e6<=settings1->FREQ_HIGH_SEAVEYS){
1790  trigNorm = anita1->fRatioTriggerToA3DigitizerFreqDomain[ipol][iring][iphi][anita1->tuffIndex][i];
1791  digNorm = anita1->fRatioDigitizerToA3DigitizerFreqDomain[ipol][iring][iphi][anita1->tuffIndex][i];
1792  sigma = anita1->RayleighFits[ipol][ant]->Eval(freqs[i])*4./TMath::Sqrt(numFreqs);
1793  realPart = rng->Gaus(0,sigma);
1794  imPart = rng->Gaus(0,sigma);
1795  } else {
1796  trigNorm=digNorm=realPart=imPart=0.;
1797  }
1798  phasorsDig[i] = FFTWComplex(realPart*digNorm, imPart*digNorm );
1799  phasorsTrig[i] = FFTWComplex(realPart*trigNorm, imPart*trigNorm );
1800  }
1801 
1802  RFSignal *rfNoiseDig = new RFSignal(numFreqs,freqs,phasorsDig,1);
1803  Double_t *justNoiseDig = rfNoiseDig->GetY();
1804 
1805  RFSignal *rfNoiseTrig = new RFSignal(numFreqs,freqs,phasorsTrig,1);
1806  Double_t *justNoiseTrig = rfNoiseTrig->GetY();
1807 
1808 
1809  for (int i=0; i<anita1->HALFNFOUR; i++){
1810  justNoise_digPath[ipol][i] = also_digi ? justNoiseDig[i]*anita1->THERMALNOISE_FACTOR : 0;
1811  justNoise_trigPath[ipol][i] = justNoiseTrig[i]*anita1->THERMALNOISE_FACTOR;
1812  }
1813 
1814  delete rfNoiseDig;
1815  delete rfNoiseTrig;
1816 
1817  }
1818 
1819  // Cleaning up
1820  delete[] phasorsDig;
1821  delete[] phasorsTrig;
1822 
1823 
1824 }
1825 
1826 void ChanTrigger::calculateCW(Anita *anita1, double frequency, double phase, double amplitude){
1827 
1828  double omega;
1829 
1830  for (int itime=0; itime<anita1->HALFNFOUR; itime++){
1831  omega=TMath::Pi()*2.0*frequency;
1832  cw_digPath[0][itime]+=amplitude*TMath::Sin(omega*anita1->TIMESTEP*itime + phase);
1833  cw_digPath[1][itime]+=amplitude*TMath::Sin(omega*anita1->TIMESTEP*itime + phase);
1834  }
1835 
1836 }
1837 
1838 TGraph *ChanTrigger::getPulserAtAMPA(Anita *anita1, int ant){
1839 
1840  // phiIndex is 0 for central antenna in trigger efficiency scan
1841  int phiIndex = anita1->trigEffScanPhi - (ant%16);
1842  if (phiIndex>8) phiIndex=phiIndex-16;
1843  double tmp_volts[10000];
1844  memset(tmp_volts, 0, sizeof(tmp_volts));
1845  int iring=2;
1846  if (ant<16) iring=0;
1847  else if (ant<32) iring=1;
1848  double norm = 0;
1849  double att = 0;
1850  // only 2 phi sectors adjecent to the central one are considered in efficiency scan
1851  if(TMath::Abs(phiIndex)<=2){
1852  att = anita1->trigEffScanAtt[phiIndex+2]-anita1->trigEffScanAtt[2];
1853  norm = (anita1->trigEffScanAtt[phiIndex+2]==0)*0 + (anita1->trigEffScanAtt[phiIndex+2]!=0)*1;
1854  norm *= anita1->trigEffScanRingsUsed[iring];
1855  }
1856  int n = anita1->gPulseAtAmpa->GetN();
1857  n=n/4;
1858  for (int i=0;i<n;i++){
1859  tmp_volts[i]=norm*anita1->gPulseAtAmpa->GetY()[i]*TMath::Power(10, att/20.);
1860  }
1861 
1862  return new TGraph(n, anita1->gPulseAtAmpa->GetX(), tmp_volts);
1863 
1864 }
1865 
1866 void ChanTrigger::injectImpulseAfterAntenna(Anita *anita1, int ant){
1867  // phiIndex is 0 for central antenna in trigger efficiency scan
1868  int phiIndex = anita1->trigEffScanPhi - (ant%16);
1869  if (phiIndex>8) phiIndex=phiIndex-16;
1870  int fNumPoints=anita1->HALFNFOUR;
1871  double tmp_volts[2][1000];
1872  int iring=2;
1873  if (ant<16) iring=0;
1874  else if (ant<32) iring=1;
1875  // only 2 phi sectors adjecent to the central one are considered in efficiency scan
1876  if(TMath::Abs(phiIndex)<=2){
1877  double att = anita1->trigEffScanAtt[phiIndex+2]-anita1->trigEffScanAtt[2];
1878  double norm = (anita1->trigEffScanAtt[phiIndex+2]==0)*0 + (anita1->trigEffScanAtt[phiIndex+2]!=0)*1;
1879  norm*=anita1->trigEffScanRingsUsed[iring];
1880  for (int i=0;i<fNumPoints;i++){
1881  tmp_volts[0][i]=norm*anita1->trigEffScanPulseAtAmpa[i]*TMath::Power(10, att/20.);
1882  tmp_volts[1][i]=0;
1883  }
1884  for (int i=0;i<fNumPoints;i++){
1885  volts_rx_forfft[0][4][i]=tmp_volts[0][i];
1886  volts_rx_forfft[1][4][i]=tmp_volts[1][i];
1887  }
1888 
1889  // put it in normal time ording -T to T
1890  // instead of 0 to T, -T to 0
1891  Tools::NormalTimeOrdering(anita1->NFOUR/2,volts_rx_forfft[0][4]);
1892  Tools::NormalTimeOrdering(anita1->NFOUR/2,volts_rx_forfft[1][4]);
1893 
1894 
1895  // find back the frequency domain
1896  Tools::realft(tmp_volts[0],1,anita1->NFOUR/2);
1897  Tools::realft(tmp_volts[1],1,anita1->NFOUR/2);
1898 
1899  //convert the V pol time waveform into frequency amplitudes
1900  anita1->GetArrayFromFFT(tmp_volts[0], vhz_rx[0][4]);
1901  anita1->GetArrayFromFFT(tmp_volts[1], vhz_rx[1][4]);
1902 
1903 
1904 
1905  }else{
1906  for (int i=0;i<fNumPoints;i++){
1907  volts_rx_forfft[0][4][i]=0;
1908  volts_rx_forfft[1][4][i]=0;
1909  }
1910  for (int i=0;i<anita1->NFREQ;i++){
1911  vhz_rx[0][4][i]=vhz_rx[1][4][i]=0;
1912  }
1913  }
1914 
1915 
1916 }
1917 
1918 void ChanTrigger::injectImpulseAtSurf(Anita *anita1, double volts_triggerPath_e[Anita::HALFNFOUR], double volts_triggerPath_h[Anita::HALFNFOUR], int ant){
1919  // phiIndex is 0 for central antenna in trigger efficiency scan
1920  int phiIndex = anita1->trigEffScanPhi - (ant%16);
1921  if (phiIndex>8) phiIndex=phiIndex-16;
1922  int fNumPoints=anita1->HALFNFOUR;
1923  // only 2 phi sectors adjecent to the central one are considered in efficiency scan
1924  if(TMath::Abs(phiIndex)<=2){
1925  int randomIndex=getRNG(RNG_INJECT)->Integer(250);
1926  double att = anita1->trigEffScanAtt[phiIndex+2];
1927  double norm = (anita1->trigEffScanAtt[phiIndex+2]==999)*0 + (anita1->trigEffScanAtt[phiIndex+2]!=999)*1;
1928 
1929  for (int i=0;i<fNumPoints;i++){
1930  volts_triggerPath_e[i]=norm*anita1->trigEffScanPulseAtSurf[randomIndex][i]*TMath::Power(10, att/20);
1931  volts_triggerPath_h[i]=0;
1932  }
1933  }else{
1934  for (int i=0;i<fNumPoints;i++){
1935  volts_triggerPath_e[i]=0;
1936  volts_triggerPath_h[i]=0;
1937  }
1938  }
1939 }
1940 #endif
1941 
1942 
1943 void ChanTrigger::saveTriggerWaveforms(Anita *anita1, double sig0[48], double sig1[48], double noise0[48], double noise1[48]){
1944 
1945  for (int i=0; i<anita1->NFOUR/2; i++){
1946  sig0[i] = justSig_trigPath[0][i];
1947  noise0[i] = justNoise_trigPath[0][i];
1948  sig1[i] = justSig_trigPath[1][i];
1949  noise1[i] = justNoise_trigPath[1][i];
1950  }
1951 }
1952 
1953 void ChanTrigger::saveDigitizerWaveforms(Anita *anita1, double sig0[48], double sig1[48], double noise0[48], double noise1[48]){
1954 
1955  for (int i=0; i<anita1->NFOUR/2; i++){
1956  sig0[i] = justSig_digPath[0][i];
1957  noise0[i] = justNoise_digPath[0][i];
1958  sig1[i] = justSig_digPath[1][i];
1959  noise1[i] = justNoise_digPath[1][i];
1960  }
1961 }
double total_diodeinput_1_allantennas[48][HALFNFOUR]
this is across all antennas, just the full band
Definition: anita.hh:173
void injectImpulseAtSurf(Anita *anita1, double volts_triggerPath_e[Anita::HALFNFOUR], double volts_triggerPath_h[Anita::HALFNFOUR], int ant)
Inject pulse at the surf (used for trigger efficiency scans)
double cw_digPath[2][Anita::HALFNFOUR]
For digitizer path, time domain cw.
Definition: ChanTrigger.h:433
void WhichBandsPassTrigger2(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 (for trigger scheme larger than 2)
Definition: ChanTrigger.cc:285
double total_diodeinput_2_allantennas[48][HALFNFOUR]
needs comment
Definition: anita.hh:174
double justNoise_digPath[2][Anita::HALFNFOUR]
For digitizer path, time domain noise from flight.
Definition: ChanTrigger.h:431
double bwslice_energy_polh[5]
Square the sum of voltage for each slice in bandwidth for h polarization. The 5th element is the full...
Definition: ChanTrigger.h:427
unsigned short surfTrigBandMask[9][2]
Ryan&#39;s 16 bit masks for 9 surfs. 2x16 bit masks gives 32 channels per surf.
Definition: balloon.hh:60
ChanTrigger()
Channel trigger constructur.
double justNoise_trigPath[2][Anita::HALFNFOUR]
For trigger path, time domain noise from flight.
Definition: ChanTrigger.h:432
double peak_v_banding_rfcm[2][5]
peak V in e/h polarization after rfcm&#39;s and banding
Definition: anita.hh:229
double getRate()
Returns the thisrate variable value (in MHz)
Global Trigger.
Definition: GlobalTrigger.h:12
void InitializeEachBand(Anita *anita1)
Initialize trigger bands.
Definition: ChanTrigger.cc:711
double bwslice_volts_pol0[5]
Sum voltage for each slice in bandwidth for the lcp polarization.
Definition: ChanTrigger.h:418
double bwslice_energy_pol0[5]
Square the sum of voltage for each slice in bandwidth for the 0th polarization.
Definition: ChanTrigger.h:420
void TriggerPath(Settings *settings1, Anita *anita1, int ant, Balloon *bn1)
Apply trigger path.
Definition: ChanTrigger.cc:871
void WhichBandsPassTrigger1(Settings *settings1, Anita *anita1, GlobalTrigger *globaltrig1, Balloon *bn1, int ilayer, int ifold, double thresholds[2][5])
Which bands passes the trigger (for trigger scheme 0 and 1)
Definition: ChanTrigger.cc:103
double rateToThreshold(double rate, int band)
Calculates the trigger threshold for an antenna via a fit from the "singles" rate and band identifier...
double bwslice_energy_pole[5]
Square the sum of voltage for each slice in bandwidth for e polarization. The 5th element is the full...
Definition: ChanTrigger.h:425
Float_t threshScanScaler[2][48][npointThresh]
scalers from threshold scan
Definition: anita.hh:162
vector< double > vthreshold_eachband[2]
Threshold in each band.
Definition: ChanTrigger.h:444
void L1Trigger(Anita *anita1, double timedomain_output_1[5][Anita::NFOUR], double timedomain_output_2[5][Anita::NFOUR], double powerthreshold[2][5], int *channels_passing_e_forglob, int *channels_passing_h_forglob, int &npass)
The L1 trigger of the Anita trigger scheme.
vector< int > flag_e[5]
Which bands pass trigger e.
Definition: ChanTrigger.h:416
double bwslice_volts_pol0_em[5]
Component of the voltage that comes from the em shower for 0th polarization.
Definition: ChanTrigger.h:422
void applyImpulseResponseDigitizer(Settings *settings1, Anita *anita1, int nPoints, int ant, double *x, double y[512], bool pol)
Apply impulse response to digitizer path.
Definition: screen.hh:22
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
int GetRxTriggerNumbering(int ilayer, int ifold)
get antenna number based on which layer and position it is
Definition: anita.cc:208
double vhz_rx[2][5][Anita::NFREQ]
Array of amplitudes in the Fourier domain (V/Hz) after the antenna gain. Indeces stand for [ipol][iba...
Definition: ChanTrigger.h:414
void applyImpulseResponseTrigger(Settings *settings1, Anita *anita1, int ant, double y[512], double *vhz, bool pol)
Apply impulse response to trigger path.
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.
double bwslice_volts_pol1[5]
Sum voltage for each slice in bandwidth for the rcp polarization.
Definition: ChanTrigger.h:419
double total_diodeinput_1_inanita[5][HALFNFOUR]
this is the waveform that is input to the tunnel diode in the first (LCP or vertical) polarization ...
Definition: anita.hh:170
static void ConvertEHtoLREnergy(double, double, double &, double &)
Convert E and H to left and right energy.
Definition: ChanTrigger.cc:45
double volts_rx_forfft[2][5][Anita::HALFNFOUR]
Array of time domain after the antenna gain. Indeces stand for [ipol][iband][itime].
Definition: ChanTrigger.h:415
This is a wrapper class for an RF Signal.
Definition: RFSignal.h:12
double GetVmmhz_freq(int i)
Get the Vmmhz value stored at the specified index.
Definition: screen.cc:121
vector< double > vnoise_eachband[2]
Noise in each band.
Definition: ChanTrigger.h:445
void saveTriggerWaveforms(Anita *anita1, double sig0[48], double sig1[48], double noise0[48], double noise1[48])
Save signal and noise waveforms at trigger.
double GetNvalidPoints()
Gets the total number of points.
Definition: screen.cc:158
UShort_t scalers[2][48]
scalers as read from the surf file: first index is pol, second is antenna number (only working for An...
Definition: anita.hh:151
double noise_eachband[2][Anita::NBANDS_MAX]
Noise in each band.
Definition: ChanTrigger.h:441
double volts_rx_rfcm_lab[2][Anita::HALFNFOUR]
For digitizer path, time domain voltage vs. time after rx, rfcm&#39;s and lab.
Definition: ChanTrigger.h:428
TGraph * getInterpolatedGraph(const TGraph *grIn, Double_t deltaT)
Interpolation Routines that use ROOT::Math::Interpolator.
Definition: FFTtools.cxx:32
double applyButterworthFilter(double ff, double ampl, int notchStatus[3])
Apply Butterworth Filter.
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:35
void GetAnitaLayerPhiSector(Settings *settings1, int i, int j, int &whichlayer, int &whichphisector)
Provides a mapping between the 4 layers and 16 phi sectors physically to the 3 layers and 16 sectors ...
static double GetNoise(Settings *settings1, double altitude_bn, double geoid, double theta, double bw, double temp)
Get Noise.
double peak_rx_rfcm_lab[2]
peaks of the previous arrays
Definition: anita.hh:235
double total_diodeinput_2_inanita[5][HALFNFOUR]
this is the waveform that is input to the tunnel diode in the second (RCP or horizontal) polarization...
Definition: anita.hh:171
void saveDigitizerWaveforms(Anita *anita1, double sig0[48], double sig1[48], double noise0[48], double noise1[48])
Save signal and noise waveforms at digitizer.
int NBANDS
number of frequency sub-bands (not counting full band)
Definition: anita.hh:122
int iminbin[5]
this is the minimum bin to start
Definition: anita.hh:225
UShort_t thresholds[2][48]
thresholds as read from the surf file: first index is pol, second is antenna number (only working for...
Definition: anita.hh:150
void ConvertHVtoLRTimedomain(const int nfour, double *vvolts, double *hvolts, double *left, double *right)
Definition: Tools.cc:746
void getNoiseFromFlight(Settings *settings1, Anita *anita1, int ant, bool also_digi=true)
Add noise from ANITA-3 flight to the time domain waveforms.
double timedomain_output_inanita[2][5][HALFNFOUR]
this is just for writing out to the following tree
Definition: anita.hh:177
This is a wrapper class for a complex number.
Definition: FFTWComplex.h:12
double v_banding_rfcm[2][5][Anita::NFREQ]
This is Volts/m as a function of frequency after rfcm&#39;s and banding.
Definition: ChanTrigger.h:448
double integral_vmmhz
Electric field integral.
Definition: ChanTrigger.h:453
static void ConvertEHtoLREfield(double, double, double &, double &)
Convert E and H to left and right e field.
Definition: ChanTrigger.cc:39
vector< int > vpasses_eachband[2]
Whether the signal passes or not each band.
Definition: ChanTrigger.h:446
Vector GetVec2bln(int i)
Gets the to-balloon vector at the specified index.
Definition: screen.cc:168
double GetDelay(int i)
Get the delay value stores at the specified index.
Definition: screen.cc:148
void DigitizerPath(Settings *settings1, Anita *anita1, int ant, Balloon *bn1)
Apply digitizer path.
Contains everything about positions within payload and signals it sees for each event, in both the trigger and signal paths.
Definition: anita.hh:32
void addToChannelSums(Settings *settings1, Anita *anita1, int ibw, int k)
Increment the volts in each band.
double justSig_trigPath[2][Anita::HALFNFOUR]
Just signal in trigger path.
Definition: ChanTrigger.h:434
double threshold_eachband[2][Anita::NBANDS_MAX]
Threshold in each band.
Definition: ChanTrigger.h:440
double bwslice_volts_pol1_em[5]
Component of the voltage that comes from the em shower for 1st polarization.
Definition: ChanTrigger.h:423
double peak_rx_rfcm_signalonly[2]
peak voltage in e/h polarization received by the antenna
Definition: anita.hh:233
static double FindPeak(double *waveform, int n)
Find peak voltage of a waveform.
double v_banding_rfcm_forfft[2][5][HALFNFOUR]
Starts out as V/s vs. freq after banding, rfcm, after fft it is V vs. t.
Definition: ChanTrigger.h:449
double justSig_digPath[2][Anita::HALFNFOUR]
Just signal in trigger path.
Definition: ChanTrigger.h:435
int passes_eachband[2][Anita::NBANDS_MAX]
Whether the signal passes or not each band.
Definition: ChanTrigger.h:442
double ston[5]
signal to noise;
Definition: anita.hh:223
double vm_banding_rfcm_forfft[2][5][HALFNFOUR]
Tunnel diode input (signal + noise)
Definition: ChanTrigger.h:450
int unwarned
Whether we have warned the user about resetting thresholds when they are beyond the measured bounds...
Definition: ChanTrigger.h:454
int GetRx(int ilayer, int ifold)
get antenna number based on which layer and position it is
Definition: anita.cc:197
double THERMALNOISE_FACTOR
factor to multiply thermal noise for error analysis
Definition: anita.hh:90
int channels_passing[2][5]
channels passing. This is reset for every antenna for every event
Definition: anita.hh:241
double bwslice_volts_polh[5]
Sum voltage for each slice in bandwidth for the h polarization.
Definition: ChanTrigger.h:426
double timedomain_output_allantennas[2][48][HALFNFOUR]
this is across all antennas, just the full band
Definition: anita.hh:216
TGraph * getPulserAtAMPA(Anita *anita1, int ant)
Get time domain graph of pulse at AMPA (used for trigger efficiency scans)
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
void DiodeConvolution(Settings *settings1, Anita *anita1, GlobalTrigger *globaltrig1, int ilayer, int ifold, double mindiodeconvl[5], double onediodeconvl[5], double psignal[5][Anita::NFOUR], double timedomain_output[5][Anita::NFOUR], double timedomain_output_justNoise[5][Anita::NFOUR], int ibinshift, int ipol, double thresholds[2][5])
Apply the diode convolution.
Definition: ChanTrigger.cc:546
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
static int IsItUnmasked(unsigned short surfTrigBandMask[9][2], int ibw, int ilayer, int ifold, int ipol)
Returns whether the indicated antenna and band are "masked".
vector< double > vsignal_eachband[2]
Signal in each band.
Definition: ChanTrigger.h:443
double peak_rx_rfcm[2]
peak voltage in e/h polarization received by the antenna
Definition: anita.hh:231
Handles everything related to balloon positions, payload orientation over the course of a flight...
Definition: balloon.hh:30
Double_t fakeThresholds2[2][48]
Fake thresholds 2 (coming from converting flight scalers to thresholds)
Definition: anita.hh:153
This class represents a three-vector. Operators are overloaded to provide for the familiar operations...
Definition: vector.hh:27
Float_t threshScanThresh[2][48][npointThresh]
adc thresholds from threshold scan
Definition: anita.hh:161
void GetThresholds(Settings *settings1, Anita *anita1, int ilayer, double thresholds[2][5])
Sets the threshold values based on which payload and where the antenna is located physically...
double bwslice_volts_pole[5]
Sum voltage for each slice in bandwidth for the e polarization.
Definition: ChanTrigger.h:424
TGraph * getConvolution(const TGraph *grA, const TGraph *grB)
Convolution.
Definition: FFTtools.cxx:2309
Vector GetPol(int i)
Gets the polarization vector at the specified index.
Definition: screen.cc:178
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
void injectImpulseAfterAntenna(Anita *anita1, int ant)
Inject pulse after the antenna (used for trigger efficiency scans)
vector< int > flag_h[5]
Which bands pass trigger h.
Definition: ChanTrigger.h:417
double bwslice_energy_pol1[5]
Square the sum of voltage for each slice in bandwidth for the 1st polarization.
Definition: ChanTrigger.h:421
double signal_vpol_inanita[5][HALFNFOUR]
this is the signal waveform in the vertical polarization, before converting to LCP, RCP where applicable
Definition: anita.hh:127
double v_banding_rfcm_forfft_temp[2][5][HALFNFOUR]
Use for the averaging over 10 neighboring bins.
Definition: ChanTrigger.h:452
double signal_eachband[2][Anita::NBANDS_MAX]
Signal in each band.
Definition: ChanTrigger.h:439
int maxbin_fortotal[5]
when it sums the noise and signal together it shortens the waveform
Definition: anita.hh:227
double total_vpol_inanita[5][HALFNFOUR]
this is the sum of the signal and noise in the vertical polarization, before converting to LCP...
Definition: anita.hh:129
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 vm_banding_rfcm_forfft_justNoise[2][5][HALFNFOUR]
Tunnel diode input (just noise)
Definition: ChanTrigger.h:451
double volts_rx_rfcm[2][Anita::HALFNFOUR]
For digitizer path, time domain voltage vs. time after rx, rfcm&#39;s.
Definition: ChanTrigger.h:430
void calculateCW(Anita *anita1, double frequency, double phase, double amplitude)
Add CW.
int channels_passing_justNoise[2][5]
channels passing. This is reset for every antenna for every event
Definition: anita.hh:242