icemc
 All Classes Namespaces Files Functions Variables Friends Macros Pages
anita.hh
Go to the documentation of this file.
1 
2 //class Anita:
4 
5 #include "rx.hpp"
6 
7 class RX;
8 class TGraph;
9 class TFile;
10 class TTree;
11 class TH1F;
12 class Vector;
13 class Position;
14 class Balloon;
15 class IceModel;
16 class TF1;
17 class Settings;
18 class TRandom3;
19 
20 using std::ofstream;
21 using std::vector;
22 
24 class Anita {
25 
26 private:
27 
28  TRandom Rand3;
29 
30  double GaintoHeight(double gain,double freq,double nmedium_receiver);
31  TGraph *gshort[4];
32  void setTrigRequirement(int WHICH);
33 
34 
35 public:
36  int number_all_antennas; // this keeps count of the number of antennas for use with timing calculations, etc.
37 
38 
39  static const int NBANDS_MAX=100; // max number of bands
40  static const int NFREQ=128; // number of frequency bins
41  //const int NFREQ=4096;
42 
43 
44  static const int NTRIG=5;
45  // these should all be in anita
46  static const int NANTENNAS_MAX=2000;
47  static const int NLAYERS_MAX=5; // max number of layers (in smex design, it's 4)
48  static const int NTRIGGERLAYERS_MAX=3;
49  static const int NPHI_MAX=400; // max number of antennas around in phi (in smex, 16)
50  Vector ANTENNA_POSITION_START[NLAYERS_MAX][NPHI_MAX]; // antenna positions from Kurt's measurements
51  double ANTENNA_DOWN[NLAYERS_MAX][NPHI_MAX]; // down angles of antennas from Kurt's measurements
52 
53  Vector antenna_positions[NLAYERS_MAX * NPHI_MAX]; // these are the antenna positions in space in a coordinate system where x=north and y=west and the origin is at the center of the payload
54 
55  int NRX_PHI[NLAYERS_MAX]; // number of antennas around in each layer. (radians)
56  double PHI_EACHLAYER[NLAYERS_MAX][NPHI_MAX];// phi of the center of each antenna on each layer
57  //before correcting for offset for the layer.
58  //only used if it is cylindrically symmetric (radians)
59  double PHI_OFFSET[NLAYERS_MAX]; // antenna offset in phi for each layer (radians)
60  double THETA_ZENITH[NLAYERS_MAX]; // how the antenna is tilted in theta (in radians with 0=up)
61  // 0=horizontal,+90=down
62 
63  // what the payload looks like
64 
65  double LAYER_VPOSITION[Anita::NLAYERS_MAX]; // position of layers in z relative to vertical center of the payload
66  // anita proposal "says that the separation between upper and lower
67  // 2 layers of antennas is just under 4m.
68  // for anita hill, consider the positions of the "layers" of the "payload" (the stations) to be sitting on the horizontal grid defined by polar coordinates
69  double LAYER_HPOSITION[Anita::NLAYERS_MAX]; // distance in horizontal plane between center axis of the "payload" and each "layer".
70  double LAYER_PHIPOSITION[Anita::NLAYERS_MAX];//phi corresponding to the position of each "layer" on the "payload"
71  double RRX[Anita::NLAYERS_MAX]; // radius that the antenna sits from the axis of the payload (feedpoint)
72 
73  Anita(); // constructor
74  ~Anita();
75  void Initialize(Settings *settings1,ofstream &foutput,int inu); // initialize a bunch of stuff
76  // takes arrays that span NFREQ and turn them into arrays that span HALFNFOUR
77  void MakeArraysforFFT(double *vsignalarray_e,double *vsignalarray_h,double *vsignal_e_forfft,double *vsignal_h_forfft);
78  int Match(int ilayer,int ifold,int rx_minarrivaltime);
79  int getLabAttn(int NPOINTS_LAB,double *freqlab,double *labattn);
80 
81  void labAttn(double *vhz);
82  void SetNoise(Settings *settings1,Balloon *bn1,IceModel *antarctica);
83  void calculate_antenna_positions(Settings *settings1,double pitch, double roll, double phi_spin,Vector n_north,Vector n_east);// this calculates the above
84 
85  TFile *fnoise;
86  TTree *tdiode;
87 
88  static const int NFOUR=1024;
89  static const int HALFNFOUR=512;
90 
91  // these are used for the satellite thing
92  int NBANDS; // number of frequency sub-bands (not counting full band)
93  int PERCENTBW; // percent bandwidth
94 
95  // these variables are for filling the tsignals tree
96  double signal_vpol_inanita[5][HALFNFOUR]; // this is the signal waveform in the vertical polarization, before converting to LCP, RCP where applicable
97  //double noise_vpol_inanita[5][HALFNFOUR]; // this is the noise waveform in the vertical polarization, before converting to LCP, RCP where applicable
98  double total_vpol_inanita[5][HALFNFOUR];// this is the sum of the signal and noise in the vertical polarization, before converting to LCP, RCP where applicable
99 
102 
103 
104 
105 
106 
107  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
108  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
109 
110  double total_diodeinput_1_allantennas[48][HALFNFOUR]; // this is across all antennas, just the full band
112 
113  // these are just for the antenna that receives the signal first
114  double timedomain_output_1_inanita[5][HALFNFOUR]; // this is just for writing out to the following tree
115  double timedomain_output_2_inanita[5][HALFNFOUR]; // this is just for writing out to the following tree
116 
117  double timedomain_output_1_corrected_forplotting[6][HALFNFOUR]; // this is just for writing out to the following tree
118  double timedomain_output_2_corrected_forplotting[6][HALFNFOUR]; // this is just for writing out to the following tree
119 
120 
121  double timedomain_output_1_allantennas[48][HALFNFOUR]; // this is across all antennas, just the full band
123 
124 
125 
129  double ston[5]; // signal to noise;
130 
131  int iminbin[5]; // this is the minimum bin to start
132  int imaxbin[5];
133  int maxbin_fortotal[5]; // when it sums the noise and signal together it shortens the waveform
134 
135  double peak_v_banding_rfcm_e[5]; // peak V in e polarization after rfcm's and banding
136  double peak_v_banding_rfcm_h[5]; // peak V in h polarization
137  double peak_e_rx_signalonly; // peak voltage in e polarization received by the antenna
138  double peak_h_rx_signalonly; // peak voltage in h polarization received by the antenna
139  double peak_e_rx_rfcm; // peak voltage in e polarization received by the antenna
140  double peak_h_rx_rfcm; // peak voltage in h polarization received by the antenna
141 
142  double peak_e_rx_rfcm_signalonly; // peak voltage in e polarization received by the antenna
143  double peak_h_rx_rfcm_signalonly; // peak voltage in h polarization received by the antenna
144 
145  double peak_e_rx_rfcm_lab; // peaks of the previous arrays
147  //I think this is the numerator of the vertical axis on Matt's plot
148 
149 
150 
151 
152  int channels_passing_e[5]; // channels passing. This is reset for every antenna for every event
153  int channels_passing_h[5]; // channels passing
154  int l1_passing; // l1 passing
155  int l1_passing_allantennas[48]; // l1 passing
156 
157  double volts_rx_rfcm_lab_e[HALFNFOUR]; // time domain voltage vs. time after rx, rfcm's and lab
158  double volts_rx_rfcm_lab_h[HALFNFOUR]; // for one specific antenna
159  double volts_rx_rfcm_lab_e_all[48][HALFNFOUR]; // time domain voltage vs. time after rx, rfcm's and lab
160  double volts_rx_rfcm_lab_h_all[48][HALFNFOUR]; // for all antennas
161 
162  int irx;
163  void BoxAverageComplex(double *array,const int n,int navg);
164  void BoxAverage(double *array,const int n,int navg);
165  int GetRx(int ilayer, int ifold); // get antenna number based on which layer and position it is
166  int GetRxTriggerNumbering(int ilayer, int ifold); // get antenna number based on which layer and position it is
167 
168 
171 
172 
173  double volts_rx_rfcm_e[HALFNFOUR]; // time domain voltage vs. time after rx, rfcm's and lab
175 
176 
177 
178  double vmmhz_banding[NFREQ]; // V/m/MHz after banding
179  double vmmhz_banding_rfcm[NFREQ]; // V/m/MHz after banding and rfcms
180 
181  double rms_rfcm_e_single_event; // This is in Volts, not mV!
182 
183  // Note: The following 4 RMS noise variables are for all antennas of all events.
184  // In fact, they don't represent RMS until after all events are finished!
185  double rms_rfcm_e; // rms noise just after rfcm's
186  double rms_lab_e;// rms noise at lab chip
187  double rms_rfcm_h; // rms noise just after rfcm's
188  double rms_lab_h;// rms noise at lab chip
189 
190 
191  TFile *fsignals;
192  TTree *tsignals;
193 
194  TFile *fdata;
195  TTree *tdata; // writing data out for the analysers
196 
197  TTree *tglob;
198 
199  TH1F *hsignals[5]; // s/n (max diode output/mean diode output) for vertical polarization in each band
200 
201  int PULSER;
202 
203  double f_pulser[NFOUR/4];
204  double f_phases[NFOUR/4];
205  double f_noise[NFOUR/4];
206  double v_pulser[NFOUR/4];
207  double v_phases[NFOUR/4];
208  double v_noise[NFOUR/4];
209 
210 
211 
212  double cumulat_prob[9];
214 
215 
216  // for filling tsignals tree
223 
224  double phases[5][HALFNFOUR];
225 
226  // for filling tglob
229 
230 
231  int nnoiseevents; // total number of noise events we're choosing from
232  int noiseeventcounter; // counts which event we're on so we go in order
233 
234  double FREQ_LOW; // lowest frequency
235  double FREQ_HIGH; // highest frequency
236 
237  double NOTCH_MIN; // low edge of notch filter. This is set in the input file
238  double NOTCH_MAX; // upper edge of notch filter
239 
240  int BANDING;// set in the input file
241  // whether or not you set your own banding (1)
242  // or use anita-1 banding
243 
244  double freq[NFREQ]; // frequency for each bin
245  double freq_forfft[NFOUR]; // frequencies for taking fft of signal
246  double freq_forplotting[NFOUR/4]; // just one entry for frequency, unlike the above.
247  double time[NFOUR/2];
248  double time_long[NFOUR];
249 
250  double time_centered[NFOUR/2];
251  double freqdomain_rfcm_banding[5][HALFNFOUR/2]; // average noise in frequency domain
252  double freqdomain_rfcm[HALFNFOUR/2]; // average noise in frequency domain
253  double freqdomain_rfcm_theory[HALFNFOUR/2]; // average noise in frequency domain
254  double avgfreqdomain_lab[HALFNFOUR/2]; // average noise in frequency domain
257 
262 
263 
264  // this goes from 0 to Fmax, and represents both real and imaginary components
265 
266 
267 
268 
269  void getDiodeModel();
270  TF1 fdiode;
271  double maxt_diode;
273  int iwindow[5];
274  double diode_real[5][NFOUR]; // This is the time domain of the diode response. (actually NFOUR/2 array is used.)
275  double fdiode_real[5][NFOUR]; // This is the fft of the diode response. (use all NFOUR array. This is for doubling array size for zero padding)
276 
277 
278  void myconvlv(double *timedomain_forconvl,const int NFOUR,double *fdiode,double &maxdiodeconvl,double &onediodeconvl,double *power_noise,double *diodeconv);
279 
280  void GetArrivalTimes(int inu, const Vector& rf_direction);
283 
284  static int SurfChanneltoBand(int isurf);
285  int AntennaWaveformtoSurf(int ilayer,int ifold); // find surf that generates this antenna's waveform
286  static int AntennaNumbertoSurfNumber(int ilayer,int ifold); // find surf where this antenna is triggered
287  static int GetAntennaNumber(int ilayer,int ifold); // given icemc indices ilayer, ifold, find antenna number as defined officially on anita
288  static int GetLayer(int rx);
289  static int GetIfold(int rx);
290  static int GetSurfChannel(int antenna, int ibw,int ipol); // which channel on the surf this channel on this antenna corresponds to.
291  static int WhichBand(int ibw,int ipol); // which band, 1-8, in order as they are on the surf
292  void Banding(int j,double *freq_noise,double *powerperfreq,int NPOINTS_NOISE);
293  void Banding(int iband,double *vmmhz);
294  void RFCMs(int ilayer,int ifold,double *freq_noise,double *vmmhz,int NPOINTS_NOISE);
295  void normalize_for_nsamples(double *spectrum, double nsamples, double nsamp);
296  void convert_power_spectrum_to_voltage_spectrum_for_fft(double *spectrum, double domain[], double phase[]);
297  void GetNoiseWaveforms(); // make time domain noise waveform based on avgnoise being the v^2
298  //void GetNoiseWaveform(int iband); // make time domain noise waveform based on avgnoise being the v^2
299  void GetPhases();
300  int count_getnoisewaveforms; //count how many times we're in GetNoiseWaveforms for calculating rms voltages
301 
302  // each of the above graphs has 601 bins in it
303  static const int NPOINTS_BANDS=601;
304 
305  double freq_bands[5][NPOINTS_BANDS]; // a frequency array for each of the four bands
306  double attn_bands[5][NPOINTS_BANDS]; // attn array for each of the four bands in dB
307  double bandsattn[5][NPOINTS_BANDS]; // as a fraction
308  //double correl[4][NPOINTS_BANDS]; // correlation between each band and the fullband
309  double correl_banding[5][NPOINTS_BANDS]; // correlation between each band and the fullband
310  double correl_lab[NPOINTS_BANDS]; // correlation between each band and the fullband
311  //double correl[5][NPOINTS_BANDS]; // correlation between each band and the fullband
312 
313 
314  static const int NPOINTS_AMPL=58;// bins in amplification
315  double freq_ampl[NANTENNAS_MAX][NPOINTS_AMPL]; // frequencies for each amp bin
316  double ampl[NANTENNAS_MAX][NPOINTS_AMPL]; // amplification
317  double ampl_notdb[NANTENNAS_MAX][NPOINTS_AMPL];// amplification again, but as a fraction
318  double noisetemp[NANTENNAS_MAX][NPOINTS_AMPL]; // noise temp each amp bin
319 
320 
321  static const int NPOINTS_NOISE=2000;
322 
323 
324  //double bwslice_thresholds[4]={2.319,2.308,2.300,2.290}; // this allows you to set different thresholds for each band
325  double bwslice_vnoise[NLAYERS_MAX][5]; // expected noise voltage for antenna layer and
326  //each slice in bandwidth
327 
328  double probability[5];
329  double bwslice_enoise[5]; // average integrated power in each band
330  double bwslice_fwhmnoise[5]; // 1/2 of fwhm of hnoise
331  double bwslice_rmsdiode[5]; // average rms diode output across noise waveforms in each band
332  double bwslice_meandiode[5]; // mean diode output across all samples in a sample of noise waveforms generated for each band
333  double bwslice_vrms[5]; // rms noise voltage for this bandwidth slice
334  double freq_noise[5][NPOINTS_NOISE]; // frequency array that goes with vnoise array
335 
336 
337  double impedence;
338  double phase;
339  double powerthreshold[5];
341  int NCH_PASS; // for ANITA 3 trigger - requires some number of channels pass
342 
343  double l1window; // time window where we require coincidences at L1
344 
345  double minsignalstrength; // minimum signal strength (measured as output of the diode) that a signal has to be for it to be worth adding to noise and performing the diode integration (each time we do this is uses up a noise waveform)
346 
347  double INTEGRATIONTIME; // integration time of the tunnel diode
348  static const int nsamp=100; // number of samples that were used to measure the noise data
349  double TIMESTEP; // time step between samples
350  double DEADTIME;
351 
352  double TRIG_TIMESTEP; // this is the l1 trigger window for the anita 3 trigger.
353  unsigned N_STEPS_PHI;
354  unsigned N_STEPS_THETA;
355 
356  static const unsigned N_SUMMED_PHI_SECTORS = 4;
357  static const unsigned N_SUMMED_LAYERS = 3;
358 
359 
360 
361  double energythreshold; // relative to expected energy from noise
366 
367 
368 
369  int NTRIGGERLAYERS; // number of layers considered by the trigger. may be different from nlayers, the number of physical layers on the payload.
370  // In Anita 1 and Anita 2, the number of physical layers were 3 while the number of trigger layers were 2.
371  int PHITRIG[NLAYERS_MAX]; // number of positions in phi for each trigger layer
372  int REQUIRE_CENTRE; // require centre antenna in clump to be one of those hit
373  static const int NTRIGPHISECTORS=16; // number of phi sectors in the trigger
374 
375  int GAINS;// whether to use constant gains as entered in GetBeamWidths (0) or to use Ped's measurements as entered in ReadGains (1)
376  static const int NPOINTS_GAIN =131; // number of pointqs within bandwidth that gain is measured. from 200 MHz to 1.5 GHz with step size of 10 MHz
377  double gainv_measured[NPOINTS_GAIN]; // may way of making the program use 3994760 fewer bytes than if these five arrays had still had 100000 elements
382 
383  double gain_angle[4][NPOINTS_GAIN][7]; /* first term: 0 = v polarization channel, a angle
384  1 = h polarization channel, a angle
385  2 = h polarization channel, e angle
386  3 = v polarization channel, e angle
387  second term: frequency
388  third term: angle */
389 
390  // frequency binning
391  // anita proposal says frequency range is 0.2-1.2 GHz.
392  // specs for the quad ridge antenna Model 0312-810 say 0.3-1.5 GHz
393  double flare[4][NFREQ]; // for coarse antenna models: beam width: e-plane: vp/hp, h-plane: vp/hp
394  double gain[2][NFREQ]; // for coarse antenna models: gain vert pol,h pol
395 
396  int GetBeamWidths(Settings *settings1); // for getting beam widths using coarse models (horn specs or simple model for EeVA)
397  void Set_gain_angle(Settings *settings1,double nmedium_receiver);
398  double Get_gain_angle(int gain_type, int k, double hitangle);
399  void ReadGains();
400 
401  void AntennaGain(Settings *settings1,double hitangle_e,double hitangle_h,double e_component,double h_component,int k,double &vsignalarray_e,double &vsignalarray_h);
402 
403 
404 
405  double reference_angle[7]; // reference angles for finding gains of antenna
406 
408  int whichbin[NFREQ]; // these are for finding gains as a function of frequency
409  double scalef2[NFREQ], scalef1[NFREQ]; // they are set in Set_gain_angle
410  double vvGaintoHeight[NFREQ], hhGaintoHeight[NFREQ], hvGaintoHeight[NFREQ], vhGaintoHeight[NFREQ]; // holds results of the function double GaintoHeight
411 
412  double diffraction[2][89][NFREQ];
413  void SetDiffraction();
414  double GetDiffraction(int ilayer, double zenith_angle, int ifreq);
415 
416 
417 
418  static const int NPOINTS_LAB=272; // from note 137
419 
420  double freqlab[NPOINTS_LAB]; // frequency for each lab attn. bin
421 
422  double labattn[NPOINTS_LAB]; // lab attenuation
423 
424 
425  double VNOISE[NLAYERS_MAX]; // noise calculated for each antenna layer depending on cant angle- this is only used right now for the chance in hell cuts
426 
427 
428  int trigRequirements[NLAYERS_MAX];// 0th element - L1 - how many channels per antenna should pass
429  // 1st element- L2 - how many antennas on a layer
430  // 2nd element - L3 - how many L2 triggers should be coincident
431 
432  int antennatosurf[32];
433 
434  double maxthreshold;
435  double bwslice_thresholds[5]; // thresholds for each band -- this is just an initialization- this is set in the input file
436  int bwslice_allowed[5]; // these bands are allowed to contribute to the trigger sum -- this is set in the input file
437  int bwslice_required[5]; // these bands are required to be among the channels that pass -- this is set in the input file
438  int pol_allowed[2];// which polarisations are allowed to have channels that fire (V,H)
439 
440 
441 
442  double bwslice_center[5]; // center frequencies
443  double bwslice_width[5]; // 3 dB bandwidths, without overlap
444 
445 
446  double bwslice_min[5]; //minimum of each bandwidth slice
447 
448  double bwslice_max[5]; //minimum of each bandwidth slice
449  double bwmin; // minimum width of any allowed bandwidth slice
450 
454  static const unsigned int NUM_COHERENT_ANTENNAS = 9;
455  unsigned hypothesis_offsets[16][200][200][4][3]; // Time bin offsets for each hypothesis - [center_phi_sector_index][phi_angle_index][theta_angle_index][phi_sector_index][layer_index]
456  vector< vector< vector <double> > > hypothesis_angles; // Time bin offsets for each hypothesis - [center_phi_sector_index][phi_angle_index][theta_angle_index][phi_sector_index][layer_index]
457  //unsigned antenna_indices[16][9]; // These are the indices of the antennas used for a given hypothesis' center phi center index - [center_phi_sector-index][which of the nine]
458  vector< vector <int> > vdifferent_offsets;
459  vector< vector <double> > vdifferent_angles;
460 
461  void calculate_all_offsets(void); // This function creates offsets for coherent sum trigger
462  void getDifferentOffsets();
463  void printDifferentOffsets();
464  void calculate_single_offset(const unsigned center_phi_sector_index, const double angle_phi, const double angle_theta, double hypothesis_offset[][3]);
465  void calculate_single_offset(const unsigned center_phi_sector_index, const unsigned index_phi, const unsigned index_theta, double hypothesis_offset[][3]);
472  unsigned cwst_window_end;
474  double cwst_deg_phi;
482  //vector <double>* cwst_whole_wfms[NUM_COHERENT_ANTENNAS];
483  //vector <double>* cwst_wfms[NUM_COHERENT_ANTENNAS];
484  //vector <double>* cwst_aligned_wfms[NUM_COHERENT_ANTENNAS];
485  vector <double> cwst_summed_wfm;
486  vector <double> cwst_power_of_summed_wfm;
487  double cwst_power;
488  void fill_coherent_waveform_sum_tree(unsigned inu, unsigned center_phi_sector, Settings* settings1, double rms_noise, double actual_rms, unsigned window_start, unsigned window_end, double deg_theta, double deg_phi, double actual_deg_theta, double actual_deg_phi, vector <double>& summed_wfm, vector <double>& power_of_summed_wfm, double power);
489  void GetPayload(Settings*, Balloon*);
490  double VNOISE_ANITALITE[NPHI_MAX]; // noise for each antenna, for the anita-lite trigger configuration.
491  double INCLINE_TOPTHREE; // cant angle of top three layers of antennas
492  double INCLINE_NADIR; // cant angle of nadir (bottom) layer of antennas
493  double INCLUDE_NADIRONLY; // cant angle of nadir (bottom) layer of antennas
494  double LIVETIME;
495 
496  double SIGMA_THETA; // resolution on the polar angle of the signal
497 }; //class Anita
498 
500 //namespace AnitaPol {
501 // typedef enum EAnitaPol {
502 // kLeft=0,
503 // kRight=1
504 // } AnitaPol_t;
505 //}
506