Analyzer.cc
1 #include "Analyzer.h"
2 #include "AnalysisConfig.h"
3 #include "Polarimetry.h"
4 #include "TPaveText.h"
5 #include "AnalysisWaveform.h"
6 #include "AnitaVersion.h"
7 #include "AnitaFlightInfo.h"
8 #include "TCanvas.h"
9 #include "ImpulsivityMeasure.h"
10 #include "BandwidthMeasure.h"
11 #include "TStyle.h"
12 #include "TMarker.h"
13 #include "TEllipse.h"
14 #include "FilteredAnitaEvent.h"
15 #include "UsefulAnitaEvent.h"
16 #include "UCUtil.h"
17 #include "DigitalFilter.h"
18 #include "FFTtools.h"
19 #include "UsefulAdu5Pat.h"
20 #include "RawAnitaHeader.h"
21 #include "PeakFinder.h"
22 #include "UCFlags.h"
23 #include "ShapeParameters.h"
24 #include "SpectrumParameters.h"
25 #include "TF1.h"
26 #include "TGraphErrors.h"
27 #include "simpleStructs.h"
28 #include "UCImageTools.h"
29 #include <stdint.h>
30 #include "TimeDependentAverage.h"
31 
32 #ifdef UCORRELATOR_OPENMP
33 #include <omp.h>
34 #include "TThread.h"
35 
36 #define SECTIONS _Pragma("omp parallel sections")
37 #define SECTION _Pragma("omp section")
38 
39 #else
40 
41 #define SECTIONS if(true)
42 #define SECTION if(true)
43 
44 #endif
45 
46 static UCorrelator::AnalysisConfig defaultConfig;
47 static int instance_counter = 0;
48 
49 #ifndef DEG2RAD
50 #define DEG2RAD (TMath::Pi()/ 180)
51 #endif
52 
53 #ifndef RAD2DEG
54 #define RAD2DEG (180 / TMath::Pi())
55 #endif
56 
57 
58 
59 
60 
61 
62  UCorrelator::Analyzer::Analyzer(const AnalysisConfig * conf, bool interactive_mode)
63 : cfg(conf ? conf: &defaultConfig),
64  corr(cfg->correlator_nphi,0,360, cfg->correlator_ntheta, -cfg->correlator_theta_lowest, cfg->correlator_theta_highest, cfg->use_bin_center, cfg->scale_by_cos_theta, cfg->baseline_weight, cfg->correlation_gain_correction ) ,
65  responses(cfg->response_option == AnalysisConfig::ResponseCustomString ? cfg->response_string : AnalysisConfig::getResponseString(cfg->response_option), cfg->response_npad, cfg->deconvolution_method),
66  wfcomb(cfg->combine_nantennas, cfg->combine_npad, true, cfg->response_option!=AnalysisConfig::ResponseNone, &responses),
67  wfcomb_xpol(cfg->combine_nantennas, cfg->combine_npad, true, cfg->response_option!=AnalysisConfig::ResponseNone, &responses),
68  wfcomb_filtered(cfg->combine_nantennas, cfg->combine_npad, false, cfg->response_option!=AnalysisConfig::ResponseNone, &responses),
69  wfcomb_xpol_filtered(cfg->combine_nantennas, cfg->combine_npad, false, cfg->response_option!=AnalysisConfig::ResponseNone, &responses),
70  interactive(interactive_mode)
71 {
72 #ifdef UCORRELATOR_OPENMP
73  TThread::Initialize();
74  ROOT::EnableThreadSafety();
75 #endif
76  zoomed = new TH2D(TString::Format("zoomed_%d", instance_counter), "Zoomed!", cfg->zoomed_nphi, 0 ,1, cfg->zoomed_ntheta, 0, 1);
77  zoomed->SetDirectory(0);
78 
79  avg_spectra[0] = 0;
80  avg_spectra[1] = 0;
81 
82  disallowedAnts[0] = 0;
83  disallowedAnts[1] = 0;
84 
85  phiRange[0] = 0.;
86  phiRange[1] = 0.;
87  thetaRange[0] = 0.;
88  thetaRange[1] = 0.;
89  exclude = false;
90  dPhi = 0;
91  dTheta = 0;
92  trackSource = false;
93  trackSun = false;
94  sourceLon = 0; sourceLat = 0; sourceAlt = 0;
95 
98 
99  wfcomb.setGroupDelayFlag(cfg->enable_group_delay);
100  wfcomb_xpol.setGroupDelayFlag(cfg->enable_group_delay);
101  wfcomb_filtered.setGroupDelayFlag(cfg->enable_group_delay);
102  wfcomb_xpol_filtered.setGroupDelayFlag(cfg->enable_group_delay);
103 
104  wfcomb.setBottomFirst(cfg->set_bottom_first);
105  wfcomb_xpol.setBottomFirst(cfg->set_bottom_first);
106  wfcomb_filtered.setBottomFirst(cfg->set_bottom_first);
107  wfcomb_xpol_filtered.setBottomFirst(cfg->set_bottom_first);
108 
109  wfcomb.setDelayToCenter(cfg->delay_to_center);
110  wfcomb_xpol.setDelayToCenter(cfg->delay_to_center);
111  wfcomb_filtered.setDelayToCenter(cfg->delay_to_center);
112  wfcomb_xpol_filtered.setDelayToCenter(cfg->delay_to_center);
113 
114  wfcomb.setRTimeShiftFlag(cfg->r_time_shift_correction);
115  wfcomb_xpol.setRTimeShiftFlag(cfg->r_time_shift_correction);
116  wfcomb_filtered.setRTimeShiftFlag(cfg->r_time_shift_correction);
117  wfcomb_xpol_filtered.setRTimeShiftFlag(cfg->r_time_shift_correction);
118  wfcomb.setSimulationTimeShiftFlag(cfg->simulation_time_shift_correction);
119  wfcomb_xpol.setSimulationTimeShiftFlag(cfg->simulation_time_shift_correction);
120  wfcomb_filtered.setSimulationTimeShiftFlag(cfg->simulation_time_shift_correction);
121  wfcomb_xpol_filtered.setSimulationTimeShiftFlag(cfg->simulation_time_shift_correction);
122 
123 
124 
125  instance_counter++;
126  power_filter = new FFTtools::GaussianFilter(2,3) ; //TODO make this configurable
127 
128  if (interactive)
129  {
130  correlation_maps[0] = 0;
131  correlation_maps[1] = 0;
132 
133  for (int i = 0; i < cfg->nmaxima; i++)
134  {
135  zoomed_correlation_maps[0].push_back(0);
136  zoomed_correlation_maps[1].push_back(0);
137 
138  for (int ipol =0; ipol <2;ipol++)
139  {
140  for (int ifilt = 0; ifilt <2; ifilt++)
141  {
142  coherent[ipol][ifilt].push_back(new AnalysisWaveform);
143  deconvolved[ipol][ifilt].push_back(new AnalysisWaveform);
144  coherent_xpol[ipol][ifilt].push_back(new AnalysisWaveform);
145  deconvolved_xpol[ipol][ifilt].push_back(new AnalysisWaveform);
146  coherent_power[ipol][ifilt].push_back(new TGraphAligned);
147  deconvolved_power[ipol][ifilt].push_back(new TGraphAligned);
148  coherent_power_xpol[ipol][ifilt].push_back(new TGraphAligned);
149  deconvolved_power_xpol[ipol][ifilt].push_back(new TGraphAligned);
150  }
151  }
152  }
153  }
154 }
155 
156 
157 
158 static double computeCombinedRMS(double t, AnitaPol::AnitaPol_t pol, const UCorrelator::WaveformCombiner * wfcomb, int use_antenna_level_snr)
159 {
160  double rms = 0 ;
161 
162  for (int ant =0; ant < wfcomb->getNAntennas(); ant++)
163  {
164  double ant_rms = UCorrelator::TimeDependentAverageLoader::getRMS(t, pol, wfcomb->getUsedAntennas()[ant]);
165  if(use_antenna_level_snr) rms += ant_rms;
166  else rms += ant_rms * ant_rms;
167  }
168 
169  if(use_antenna_level_snr) rms = rms / wfcomb->getNAntennas();
170  else rms = sqrt(rms) / wfcomb->getNAntennas();
171 
172  return rms;
173 }
174 
175 
176 
178 {
179 
180  const RawAnitaHeader * hdr = event->getHeader();
181  //this is for time dependent responses (right now only TUFFs)
182  responses.checkTime(hdr->payloadTime);
183  //we need a UsefulAdu5Pat for this event
184  UsefulAdu5Pat * pat = (UsefulAdu5Pat*) event->getGPS(); //unconstifying it .. hopefully that won't cause problems
185 
186  /* Initialize the summary */
187  summary = new (summary) AnitaEventSummary(hdr, (UsefulAdu5Pat*) event->getGPS(),truth);
188 
189  //just right away store where the payload is
190  summary->anitaLocation.update(pat);
191 
192  //check if were blocking out/looking at a source
193  if(trackSource)
194  {
195  pat->getThetaAndPhiWave(sourceLon, sourceLat, sourceAlt, thetaRange[0], phiRange[0]);
196  phiRange[0] *= 180./TMath::Pi();
197  thetaRange[0] *= -180./TMath::Pi();
198  phiRange[1] = phiRange[0] + dPhi;
199  thetaRange[1] = thetaRange[0] + dTheta;
200  phiRange[0] -= dPhi;
201  thetaRange[0] -= dTheta;
202  }
203  //sun is done separately because its easier this way
204  if(trackSun)
205  {
206  pat->getSunPosition(summary->sun.phi, summary->sun.theta);
207  phiRange[0] = summary->sun.phi - dPhi;
208  phiRange[1] = summary->sun.phi + dPhi;
209  thetaRange[0] = -summary->sun.theta - dTheta;
210  thetaRange[1] = -summary->sun.theta + dTheta;
211  }
212 
213  //check for saturation
214  ULong64_t saturated[2] = {0,0};
215  event->checkSaturation( &saturated[AnitaPol::kHorizontal],
216  &saturated[AnitaPol::kVertical],
217  cfg->saturation_threshold);
218 
219  //also disable missing sectors
220  UCorrelator::flags::checkEmpty(event->getUsefulAnitaEvent(), &saturated[AnitaPol::kHorizontal], &saturated[AnitaPol::kVertical]);
221 
222  // loop over wanted polarizations
223  for (int pol = cfg->start_pol; pol <= cfg->end_pol; pol++)
224  {
225 
226  UShort_t triggeredPhi = AnitaPol::AnitaPol_t(pol) == AnitaPol::kHorizontal ? event->getHeader()->l3TrigPatternH : event->getHeader()->l3TrigPattern;
227  UShort_t triggeredPhiXpol = AnitaPol::AnitaPol_t(pol) == AnitaPol::kVertical ? event->getHeader()->l3TrigPatternH : event->getHeader()->l3TrigPattern;
228 
229 
230  UShort_t maskedL2 = 0;
231  UShort_t maskedPhi = 0 ;
232  UShort_t maskedL2Xpol = 0;
233  UShort_t maskedPhiXpol = 0 ;
234 
235  if (cfg->use_offline_mask)
236  {
237  maskedPhi = event->getHeader()->getPhiMaskOffline(AnitaPol::AnitaPol_t(pol));
238  maskedPhiXpol = event->getHeader()->getPhiMaskOffline(AnitaPol::AnitaPol_t(1-pol));
239 
240  if (AnitaVersion::get() == 3)
241  {
242  maskedL2 = event->getHeader()->getL1MaskOffline(AnitaPol::AnitaPol_t(pol));
243  maskedL2Xpol = event->getHeader()->getL1MaskOffline(AnitaPol::AnitaPol_t(1-pol));
244  }
245  else
246  {
247 
248  //for now do this until we merge anita_3and4 to master
249 #ifdef MULTIVERSION_ANITA_ENABLED
250  maskedL2 = event->getHeader()->getL2Mask();
251 #else
252 #if VER_EVENT_HEADER>=40
253  maskedL2 = event->getHeader()->l2TrigMask;
254 #else
255  maskedL2 = event->getHeader()->l1TrigMask;
256 #endif
257 #endif
258  maskedL2Xpol = maskedL2;
259 
260  }
261  }
262  else
263  {
264  maskedPhi = AnitaPol::AnitaPol_t(pol) == AnitaPol::kHorizontal ? event->getHeader()->phiTrigMaskH : event->getHeader()->phiTrigMask;
265  maskedPhiXpol = AnitaPol::AnitaPol_t(pol) == AnitaPol::kVertical ? event->getHeader()->phiTrigMaskH : event->getHeader()->phiTrigMask;
266 
267  if (AnitaVersion::get() == 3)
268  {
269  maskedL2 = event->getHeader()->getL1Mask(AnitaPol::AnitaPol_t(pol));
270  maskedL2Xpol = event->getHeader()->getL1Mask(AnitaPol::AnitaPol_t(1-pol));
271  }
272  else
273  {
274 
275  //for now do this until we merge anita_3and4 to master
276 #ifdef MULTIVERSION_ANITA_ENABLED
277  maskedL2 = event->getHeader()->getL2Mask();
278 #else
279 #if VER_EVENT_HEADER>=40
280  maskedL2 = event->getHeader()->l2TrigMask;
281 #else
282  maskedL2 = event->getHeader()->l1TrigMask;
283 #endif
284 #endif
285 
286  maskedL2Xpol = maskedL2;
287  }
288 
289 
290  }
291 
292 
293  //alright, we need a little song and dance here to combine Phi masks and L2 masks
294  //
295  // Someone should check my logic here.
296  //
297  // An L2 mask effectively masks both phi sector N and N+1 (since it'll prevent L3 triggers in both).
298  // An L3 mask has contributions from both phi sector N and N-1.
299  //
300  // I'm going to take the aggressive approach where an L3 mask means we mark a pointing hypothesis as masked
301  // if it falls in phi sector N or N-1.
302 
303 
304 #ifdef __cpp_static_assert
305  static_assert(sizeof(maskedPhi == NUM_PHI),"masked phi must be same size as num phi ");
306 #endif
307 
308  maskedPhi |= ( (maskedPhi >> 1) | ( maskedPhi << (NUM_PHI-1))) ;
309  //or with l2 mask
310  maskedPhi |= maskedL2;
311 
312 
313 #ifdef __cpp_static_assert
314  static_assert(sizeof(maskedPhiXpol == NUM_PHI),"masked phi xpol must be same size as num phi ");
315 #endif
316 
317  //ditto for xpol
318  maskedPhiXpol |= (maskedPhiXpol >> 1) | ((maskedPhiXpol << (NUM_PHI-1)));
319  maskedPhiXpol |= maskedL2Xpol;
320 
321  //TODO: check this
322  TVector2 triggerAngle(0,0);
323 
324  int ntriggered = __builtin_popcount(triggeredPhi);
325  int ntriggered_xpol = __builtin_popcount(triggeredPhiXpol);
326 
327  UShort_t which_trigger = ntriggered ? triggeredPhi : triggeredPhiXpol;
328  int which_ntriggered = ntriggered ?: ntriggered_xpol;
329 
330  const double phi_sector_width = 360. / NUM_PHI;
331 
332  for (int i = 0; i < NUM_PHI; i++)
333  {
334  if (which_trigger & (1 << i))
335  {
336  //TODO: this 45 is hardcoded here. Should come from GeomTool or something...
337  double ang = (i * phi_sector_width - 45) * TMath::Pi()/180;
338  triggerAngle += TVector2(cos(ang), sin(ang)) / which_ntriggered;
339  }
340  }
341 
342  double avgHwAngle = triggerAngle.Phi() * RAD2DEG;
343 
344  // tell the correlator not to use saturated events or disallowed antennas and make the correlation map
345  saturated[pol] |= disallowedAnts[pol];
346  if(cfg->only_use_usable) saturated[pol] |= ~AnitaFlightInfo::getUsableAntennas(hdr, event->getUsefulAnitaEvent(), AnitaPol::AnitaPol_t(pol));
347 
348 
349  //if we are only considering antennas that are unmasked, figure out which ones are
350  uint64_t maskedAnts= 0;
351  if (cfg->min_peak_distance_from_unmasked >=0)
352  {
353  for (uint64_t iphi = 0; iphi < 16; iphi++)
354  {
355  bool unmasked = !(maskedPhi & (1ul << iphi)) ;
356 
357  for (int neighboring = 0; neighboring < cfg->min_peak_distance_from_unmasked; neighboring++)
358  {
359  if (unmasked) break;
360  unmasked = unmasked || !(maskedPhi & (1ul << ( (iphi + neighboring) % NUM_PHI)));
361  unmasked = unmasked || !(maskedPhi & (1ul << ( (iphi + neighboring + NUM_PHI - 1) % NUM_PHI)));
362  }
363 
364  if (!unmasked)
365  {
366  maskedAnts |= 1ul << iphi;
367  maskedAnts |= 1ul << (iphi+NUM_PHI);
368  maskedAnts |= 1ul << (iphi+2*NUM_PHI);
369  }
370  }
371  }
372 
373  corr.setDisallowedAntennas(saturated[pol] | disallowedAnts[pol] | maskedAnts);
374  corr.compute(event, AnitaPol::AnitaPol_t(pol));
375 
376  //compute RMS of correlation map
377  // maprms = corr.getHist()->GetRMS(3); //This doesn't work! Probably because ROOT is dumb
378 
379 
380  if (cfg->max_peak_trigger_angle)
381  {
382  phiRange[0] = FFTtools::wrap(avgHwAngle - cfg->max_peak_trigger_angle,360);
383  phiRange[1] = FFTtools::wrap(avgHwAngle + cfg->max_peak_trigger_angle,360);
384  }
385 
386  // Find the isolated peaks in the image
387  peakfinder::RoughMaximum maxima[cfg->nmaxima];
388  int npeaks = UCorrelator::peakfinder::findIsolatedMaxima((const TH2D*) corr.getHist(),
389  cfg->peak_isolation_requirement,
390  cfg->nmaxima, maxima, phiRange[0], phiRange[1],
391  thetaRange[0], thetaRange[1], exclude, cfg->use_bin_center);
392  // printf("npeaks: %d\n", npeaks);
393  summary->nPeaks[pol] = npeaks;
394 
395  rough_peaks[pol].clear();
396 
397 
398  //get the average spectra
399  if (!avg_spectra[pol])
400  {
401  avg_spectra[pol] = new TGraph;
402  avg_spectra[pol]->GetXaxis()->SetTitle("Frequency (GHz)");
403  avg_spectra[pol]->GetYaxis()->SetTitle("Power (dBish)");
404  avg_spectra[pol]->SetTitle(TString::Format("Average spectra for %s", pol == AnitaPol::kHorizontal ? "HPol" : "VPol"));
405  }
406 
407  event->getMedianSpectrum(avg_spectra[pol], AnitaPol::AnitaPol_t(pol),0.5);
408 
409  //optionally fill the channel info
410  if (cfg->fill_channel_info)
411  {
412  fillChannelInfo(event, summary);
413  }
414 
415 
416 
417  int rms_lims[4];
418  rms_lims[0] = (cfg->correlator_nphi/6 + maxima[0].xbin) % cfg->correlator_nphi;
419  rms_lims[1] = (-cfg->correlator_nphi/6 + maxima[0].xbin) % cfg->correlator_nphi;
420  rms_lims[2] = 1;
421  rms_lims[3] = cfg->correlator_ntheta;
422  maprms = UCorrelator::getZRMS(corr.getHist(), rms_lims);
423 
424  // Loop over found peaks
425  for (int i = 0; i < npeaks; i++)
426  {
427  // zoom in on the values
428  // printf("rough phi:%f, rough theta: %f\n", maxima[i].x, -maxima[i].y);
429 
430 
431  fillPointingInfo(maxima[i].x, maxima[i].y, &summary->peak[pol][i], pat, avgHwAngle, triggeredPhi, maskedPhi, triggeredPhiXpol, maskedPhiXpol);
432 
433  if (interactive)
434  {
435  if (zoomed_correlation_maps[pol][i]) delete zoomed_correlation_maps[pol][i];
436  zoomed_correlation_maps[pol][i] = new gui::Map(*zoomed, event, &wfcomb, &wfcomb_filtered,AnitaPol::AnitaPol_t(pol), summary);
437  zoomed_correlation_maps[pol][i]->SetName(TString::Format("zoomed_%d_%d", pol,i));
438  }
439 
440 
441  //fill in separation
442  summary->peak[pol][i].phi_separation = 1000;
443  for (int j = 0; j < i; j++)
444  {
445  summary->peak[pol][i].phi_separation = TMath::Min(summary->peak[pol][i].phi_separation, fabs(FFTtools::wrap(summary->peak[pol][i].phi - summary->peak[pol][j].phi, 360, 0)));
446  }
447 
448  // printf("phi:%f, theta:%f\n", summary->peak[pol][i].phi, summary->peak[pol][i].theta);
449 
450 
451  }
452 
453  for (int i = 0; i < npeaks; i++)
454  {
455  rough_peaks[pol].push_back(std::pair<double,double>(maxima[i].x, maxima[i].y));
456  //now make the combined waveforms
457  if(cfg->use_antenna_level_snr > 0)
458  {
459  wfcomb.setCheckVpp(cfg->use_antenna_level_snr);
460  wfcomb_xpol.setCheckVpp(cfg->use_antenna_level_snr);
461  wfcomb_filtered.setCheckVpp(cfg->use_antenna_level_snr);
462  wfcomb_xpol_filtered.setCheckVpp(cfg->use_antenna_level_snr);
463  }
464 
465 
466  SECTIONS
467  {
468  SECTION
469  wfcomb.combine(summary->peak[pol][i].phi, summary->peak[pol][i].theta, event, (AnitaPol::AnitaPol_t) pol, saturated[pol],
470  cfg->combine_t0, cfg->combine_t1, &summary->peak[pol][i].antennaPeakAverage, cfg->use_hilbert_for_antenna_average);
471  SECTION
472  wfcomb_xpol.combine(summary->peak[pol][i].phi, summary->peak[pol][i].theta, event, (AnitaPol::AnitaPol_t) (1-pol), saturated[pol], cfg->combine_t0, cfg->combine_t1);
473  SECTION
474  wfcomb_filtered.combine(summary->peak[pol][i].phi, summary->peak[pol][i].theta, event, (AnitaPol::AnitaPol_t) pol, saturated[pol], cfg->combine_t0, cfg->combine_t1);
475  SECTION
476  wfcomb_xpol_filtered.combine(summary->peak[pol][i].phi, summary->peak[pol][i].theta, event, (AnitaPol::AnitaPol_t) (1-pol), saturated[pol], cfg->combine_t0, cfg->combine_t1);
477  }
478 
479  double rms = cfg->use_forced_trigger_rms ? computeCombinedRMS(event->getHeader()->triggerTime, (AnitaPol::AnitaPol_t) pol, &wfcomb, cfg->use_antenna_level_snr) : 0 ;
480 
481  SECTIONS
482  {
483  SECTION
484  fillWaveformInfo(wfcomb.getCoherent(), wfcomb_xpol.getCoherent(), wfcomb.getCoherentAvgSpectrum(), &summary->coherent[pol][i], (AnitaPol::AnitaPol_t) pol, rms, wfcomb.getMaxAntennaVpp());
485  SECTION
486  fillWaveformInfo(wfcomb.getDeconvolved(), wfcomb_xpol.getDeconvolved(), wfcomb.getDeconvolvedAvgSpectrum(), &summary->deconvolved[pol][i], (AnitaPol::AnitaPol_t)pol, 0);
487  SECTION
488  fillWaveformInfo(wfcomb_filtered.getCoherent(), wfcomb_xpol_filtered.getCoherent(), wfcomb_filtered.getCoherentAvgSpectrum(), &summary->coherent_filtered[pol][i], (AnitaPol::AnitaPol_t) pol, rms, wfcomb_filtered.getMaxAntennaVpp());
489  SECTION
490  fillWaveformInfo(wfcomb_filtered.getDeconvolved(), wfcomb_xpol_filtered.getDeconvolved(), wfcomb_filtered.getDeconvolvedAvgSpectrum(), &summary->deconvolved_filtered[pol][i], (AnitaPol::AnitaPol_t)pol, 0);
491  }
492 
493 
494  if (interactive) //copy everything
495  {
496  coherent[pol][0][i]->~AnalysisWaveform();
497  coherent[pol][0][i] = new (coherent[pol][0][i]) AnalysisWaveform(*wfcomb.getCoherent());
498 
499  coherent[pol][1][i]->~AnalysisWaveform();
500  coherent[pol][1][i] = new (coherent[pol][1][i]) AnalysisWaveform(*wfcomb_filtered.getCoherent());
501 
502  coherent_power[pol][0][i]->~TGraphAligned();
503  coherent_power[pol][0][i] = new (coherent_power[pol][0][i]) TGraphAligned(*wfcomb.getCoherentAvgSpectrum());
504  coherent_power[pol][0][i]->dBize();
505 
506  coherent_power[pol][1][i]->~TGraphAligned();
507  coherent_power[pol][1][i] = new (coherent_power[pol][1][i]) TGraphAligned(*wfcomb_filtered.getCoherentAvgSpectrum());
508  coherent_power[pol][1][i]->dBize();
509 
510 
511  if (wfcomb.getDeconvolved())
512  {
513  deconvolved[pol][0][i]->~AnalysisWaveform();
514  deconvolved[pol][0][i] = new (deconvolved[pol][0][i]) AnalysisWaveform(*wfcomb.getDeconvolved());
515  deconvolved[pol][0][i]->updateEven()->SetLineColor(2);
516  deconvolved[pol][0][i]->updateEven()->SetMarkerColor(2);
517 
518  deconvolved[pol][1][i]->~AnalysisWaveform();
519  deconvolved[pol][1][i] = new (deconvolved[pol][1][i]) AnalysisWaveform(*wfcomb_filtered.getDeconvolved());
520  deconvolved[pol][1][i]->updateEven()->SetLineColor(2);
521  deconvolved[pol][1][i]->updateEven()->SetMarkerColor(2);
522 
523  deconvolved_power[pol][0][i]->~TGraphAligned();
524  deconvolved_power[pol][0][i] = new (deconvolved_power[pol][0][i]) TGraphAligned(*wfcomb.getDeconvolvedAvgSpectrum());
525  deconvolved_power[pol][0][i]->dBize();
526  deconvolved_power[pol][0][i]->SetLineColor(2);
527 
528  deconvolved_power[pol][1][i]->~TGraphAligned();
529  deconvolved_power[pol][1][i] = new (deconvolved_power[pol][1][i]) TGraphAligned(*wfcomb_filtered.getDeconvolvedAvgSpectrum());
530  deconvolved_power[pol][1][i]->dBize();
531  deconvolved_power[pol][1][i]->SetLineColor(2);
532 
533  interactive_deconvolved = true;
534  }
535  else
536  {
537  interactive_deconvolved = false;
538  }
539 
540 
541  coherent_xpol[pol][0][i]->~AnalysisWaveform();
542  coherent_xpol[pol][0][i] = new (coherent_xpol[pol][0][i]) AnalysisWaveform(*wfcomb_xpol.getCoherent());
543  coherent_xpol[pol][0][i]->updateEven()->SetLineColor(11);
544  coherent_xpol[pol][0][i]->updateEven()->SetLineStyle(3);
545 
546  coherent_xpol[pol][1][i]->~AnalysisWaveform();
547  coherent_xpol[pol][1][i] = new (coherent_xpol[pol][1][i]) AnalysisWaveform(*wfcomb_xpol_filtered.getCoherent());
548  coherent_xpol[pol][1][i]->updateEven()->SetLineColor(11);
549  coherent_xpol[pol][1][i]->updateEven()->SetLineStyle(3);
550 
551 
552  coherent_power_xpol[pol][0][i]->~TGraphAligned();
553  coherent_power_xpol[pol][0][i] = new (coherent_power_xpol[pol][0][i]) TGraphAligned(*wfcomb_xpol.getCoherentAvgSpectrum());
554  coherent_power_xpol[pol][0][i]->dBize();
555  coherent_power_xpol[pol][0][i]->SetLineStyle(3);
556  coherent_power_xpol[pol][0][i]->SetLineColor(11);
557 
558  coherent_power_xpol[pol][1][i]->~TGraphAligned();
559  coherent_power_xpol[pol][1][i] = new (coherent_power_xpol[pol][1][i]) TGraphAligned(*wfcomb_xpol_filtered.getCoherentAvgSpectrum());
560  coherent_power_xpol[pol][1][i]->dBize();
561  coherent_power_xpol[pol][1][i]->SetLineStyle(3);
562  coherent_power_xpol[pol][1][i]->SetLineColor(11);
563 
564 
565  if (wfcomb_xpol.getDeconvolved())
566  {
567  deconvolved_xpol[pol][0][i]->~AnalysisWaveform();
568  deconvolved_xpol[pol][0][i] = new (deconvolved_xpol[pol][0][i]) AnalysisWaveform(*wfcomb_xpol.getDeconvolved());
569  deconvolved_xpol[pol][0][i]->updateEven()->SetLineColor(45);
570  deconvolved_xpol[pol][0][i]->updateEven()->SetMarkerColor(45);
571  deconvolved_xpol[pol][0][i]->updateEven()->SetLineStyle(3);
572 
573  deconvolved_power_xpol[pol][0][i]->~TGraphAligned();
574  deconvolved_power_xpol[pol][0][i] = new (deconvolved_power_xpol[pol][0][i]) TGraphAligned(*wfcomb_xpol.getDeconvolvedAvgSpectrum());
575  deconvolved_power_xpol[pol][0][i]->dBize();
576  deconvolved_power_xpol[pol][0][i]->SetLineStyle(3);
577  deconvolved_power_xpol[pol][0][i]->SetLineColor(46);
578 
579  deconvolved_xpol[pol][1][i]->~AnalysisWaveform();
580  deconvolved_xpol[pol][1][i] = new (deconvolved_xpol[pol][1][i]) AnalysisWaveform(*wfcomb_xpol_filtered.getDeconvolved());
581  deconvolved_xpol[pol][1][i]->updateEven()->SetLineColor(45);
582  deconvolved_xpol[pol][1][i]->updateEven()->SetMarkerColor(45);
583  deconvolved_xpol[pol][1][i]->updateEven()->SetLineStyle(3);
584 
585  deconvolved_power_xpol[pol][1][i]->~TGraphAligned();
586  deconvolved_power_xpol[pol][1][i] = new (deconvolved_power_xpol[pol][1][i]) TGraphAligned(*wfcomb_xpol_filtered.getDeconvolvedAvgSpectrum());
587  deconvolved_power_xpol[pol][1][i]->dBize();
588  deconvolved_power_xpol[pol][1][i]->SetLineStyle(3);
589  deconvolved_power_xpol[pol][1][i]->SetLineColor(46);
590 
591 
592 
593  interactive_xpol_deconvolved = true;
594  }
595  else
596  {
597  interactive_xpol_deconvolved = false;
598  }
599  }
600  }
601  if (interactive)
602  {
603  if (correlation_maps[pol]) delete correlation_maps[pol];
604  correlation_maps[pol] = new gui::Map(*corr.getHist(), event, &wfcomb, &wfcomb_filtered,AnitaPol::AnitaPol_t(pol), summary );
605  }
606  }
607 
608  fillFlags(event, summary, pat);
609 
610 
611  if (truth)
612  {
613  // SECTIONS
614  {
615  // SECTION
616  if(cfg->use_antenna_level_snr > 0)
617  {
618  wfcomb.setCheckVpp(cfg->use_antenna_level_snr);
619  wfcomb_xpol.setCheckVpp(cfg->use_antenna_level_snr);
620  }
621 
622  wfcomb.combine(summary->mc.phi, summary->mc.theta, event, AnitaPol::kHorizontal, 0, cfg->combine_t0, cfg->combine_t1);
623  // SECTION
624  wfcomb_xpol.combine(summary->mc.phi, summary->mc.theta, event, AnitaPol::kVertical, 0, cfg->combine_t0, cfg->combine_t1);
625  }
626 
627  double hpol_rms = cfg->use_forced_trigger_rms ? computeCombinedRMS(event->getHeader()->triggerTime, AnitaPol::kHorizontal, &wfcomb, cfg->use_antenna_level_snr) : 0 ;
628  double vpol_rms = cfg->use_forced_trigger_rms ? computeCombinedRMS(event->getHeader()->triggerTime, AnitaPol::kVertical, &wfcomb_xpol, cfg->use_antenna_level_snr) : 0 ;
629 
630  // SECTIONS
631  {
632  // SECTION
633  fillWaveformInfo(wfcomb.getCoherent(), wfcomb_xpol.getCoherent(), wfcomb.getCoherentAvgSpectrum(), &(summary->mc.wf[AnitaPol::kHorizontal]), AnitaPol::kHorizontal, hpol_rms, wfcomb.getMaxAntennaVpp());
634  // SECTION
635  fillWaveformInfo(wfcomb_xpol.getCoherent(), wfcomb.getCoherent(), wfcomb_xpol.getCoherentAvgSpectrum(), &(summary->mc.wf[AnitaPol::kVertical]), AnitaPol::kVertical, vpol_rms, wfcomb_xpol.getMaxAntennaVpp());
636  }
637  }
638 
639  if (interactive) last = *summary;
640 
641 }
642 
643 static bool outside(const TH2 * h, double x, double y)
644 {
645 
646  return x > h->GetXaxis()->GetXmax() ||
647  x < h->GetXaxis()->GetXmin() ||
648  y < h->GetYaxis()->GetXmin() ||
649  y > h->GetYaxis()->GetXmax();
650 
651 }
652 
653 void UCorrelator::Analyzer::fillPointingInfo(double rough_phi, double rough_theta, AnitaEventSummary::PointingHypothesis * point,
654  UsefulAdu5Pat * pat, double hwPeakAngle, UShort_t triggered_sectors, UShort_t masked_sectors, UShort_t triggered_sectors_xpol, UShort_t masked_sectors_xpol)
655 {
656  corr.computeZoomed(rough_phi, rough_theta, cfg->zoomed_nphi, cfg->zoomed_dphi, cfg->zoomed_ntheta, cfg->zoomed_dtheta, cfg->zoomed_nant, zoomed);
657 
658  //get pointer to the pointing hypothesis we are about to fill
659 
660  // This will fill in phi, theta, value, var_theta, var_phi and covar
661 
662  peakfinder::FineMaximum max;
663  switch (cfg->fine_peak_finding_option)
664  {
665  case AnalysisConfig::FinePeakFindingAbby:
666  UCorrelator::peakfinder::doInterpolationPeakFindingAbby(zoomed, &max);
667  break;
669  UCorrelator::peakfinder::doInterpolationPeakFindingBicubic(zoomed, &max);
670  break;
672  UCorrelator::peakfinder::doPeakFindingHistogram(zoomed, &max);
673  break;
675  UCorrelator::peakfinder::doPeakFindingQuadratic16(zoomed, &max);
676  break;
678  UCorrelator::peakfinder::doPeakFindingQuadratic25(zoomed, &max);
679  break;
681  UCorrelator::peakfinder::doPeakFindingGaussian(zoomed, &max);
682  break;
684  default:
685  UCorrelator::peakfinder::doPeakFindingQuadratic9(zoomed, &max);
686  break;
687  };
688 
689 
690  //Check to make sure that fine max isn't OUTSIDE of zoomed window
691  // If it is, revert to very stupid method of just using histogram
692 
693  if (outside(zoomed, max.x, max.y))
694  {
696  }
697 
698 
699 
700 
701  max.copyToPointingHypothesis(point);
702 
703  //snr is ratio of point value to map rms
704  point->snr = point->value / maprms;
705  point->mapRMS = maprms;
706  point->dphi_rough = FFTtools::wrap(point->phi - rough_phi, 360,0);
707  point->dtheta_rough = FFTtools::wrap(point->theta - (-rough_theta), 360,0); //sign reversal. doh.
708 
709  point->hwAngle = FFTtools::wrap(point->phi - hwPeakAngle,360,0);
710 
711  //TODO: I don't believe this really yet
712  int sector = 2+fmod(point->phi + 11.25,360) / 22.5;
713 
714  point->masked = masked_sectors & ( 1 << sector);
715  point->triggered = triggered_sectors & ( 1 << sector);
716  point->masked_xpol = masked_sectors_xpol & ( 1 << sector);
717  point->triggered_xpol = triggered_sectors_xpol & ( 1 << sector);
718 
719  if(cfg->trace_to_continent)
720  {
721  //Compute intersection with continent, or set values to -9999 if no intersection
722  if (!pat->traceBackToContinent3(point->phi * DEG2RAD, point->theta * DEG2RAD,
723  &point->longitude, &point->latitude, &point->altitude, &point->theta_adjustment_needed)
724  || point->theta_adjustment_needed > cfg->max_theta_adjustment * DEG2RAD)
725  {
726  point->latitude = -9999;
727  point->longitude = -9999;
728  point->altitude = -9999;
729  point->distanceToSource = -9999;
730  point->theta_adjustment_needed = -9999;
731  }
732  else
733  {
734  point->distanceToSource=pat->getDistanceFromSource(point->latitude, point->longitude, point->altitude);
735  point->theta_adjustment_needed *= RAD2DEG;
736  }
737  }
738  else
739  {
740  point->latitude = 0;
741  point->longitude = 0;
742  point->altitude = 0;
743  point->distanceToSource = 0;
744  point->theta_adjustment_needed = 0;
745  }
746 }
747 
748 
749 void UCorrelator::Analyzer::fillWaveformInfo(const AnalysisWaveform * wf, const AnalysisWaveform * xpol_wf, const TGraph* pwr, AnitaEventSummary::WaveformInfo * info, AnitaPol::AnitaPol_t pol, double rms, double vpp)
750 {
751  if (!wf || wf->Neven() == 0)
752  {
753  if (wf && !wf->Neven())
754  fprintf(stderr,"wf passed to fillWaveformInfo has no points\n");
755 
756  memset(info, 0, sizeof(AnitaEventSummary::WaveformInfo));
757  return;
758  }
759  const TGraphAligned * even = wf->even();
760  const TGraphAligned * xpol_even= xpol_wf->even();
761  int peakBin;
762 
763  int peakHilbertBin;
764  info->peakVal = FFTtools::getPeakVal((TGraph*) even,&peakBin);
765  info->xPolPeakVal = FFTtools::getPeakVal( xpol_even);
766  info->peakHilbert = FFTtools::getPeakVal((TGraph*) wf->hilbertEnvelope(),&peakHilbertBin);
767  double minHilbert = *std::min_element(wf->hilbertEnvelope()->GetY(), wf->hilbertEnvelope()->GetY() + wf->Neven());
768 
769  info->xPolPeakHilbert = FFTtools::getPeakVal((TGraph*) xpol_wf->hilbertEnvelope());
770  info->numAntennasInCoherent = cfg->combine_nantennas;
771 
772  info->totalPower = even->getSumV2();
773  info->totalPowerXpol = xpol_even->getSumV2();
774  info->peakTime = even->GetX()[peakHilbertBin];
775 
776  double hilbertRange = info->peakHilbert - minHilbert;
777 
778  if(cfg->compute_shape_parameters)
779  {
780  info->riseTime_10_90 = shape::getRiseTime((TGraph*) wf->hilbertEnvelope(), minHilbert + 0.1*hilbertRange, minHilbert + 0.9*hilbertRange,peakHilbertBin);
781  info->riseTime_10_50 = shape::getRiseTime((TGraph*) wf->hilbertEnvelope(), minHilbert + 0.1*hilbertRange, minHilbert + 0.5*hilbertRange,peakHilbertBin);
782  info->fallTime_90_10 = shape::getFallTime((TGraph*) wf->hilbertEnvelope(), minHilbert + 0.1*hilbertRange, minHilbert + 0.9*hilbertRange,peakHilbertBin);
783  info->fallTime_50_10 = shape::getFallTime((TGraph*) wf->hilbertEnvelope(), minHilbert + 0.1*hilbertRange, minHilbert + 0.5*hilbertRange,peakHilbertBin);
784 
785  int ifirst, ilast;
786  info->width_50_50 = shape::getWidth((TGraph*) wf->hilbertEnvelope(), minHilbert + 0.5*hilbertRange, &ifirst, &ilast,peakHilbertBin);
787  info->power_50_50 = even->getSumV2(ifirst, ilast);
788  even->getMoments(sizeof(info->peakMoments)/sizeof(double), info->peakTime, info->peakMoments);
789  info->width_10_10 = shape::getWidth((TGraph*) wf->hilbertEnvelope(), minHilbert + 0.1*hilbertRange, &ifirst, &ilast,peakHilbertBin);
790  info->power_10_10 = even->getSumV2(ifirst, ilast);
791  }
792  if(!cfg->compute_shape_parameters)
793  {
794  info->riseTime_10_90 = 0;
795  info->riseTime_10_50 = 0;
796  info->fallTime_90_10 = 0;
797  info->fallTime_50_10 = 0;
798 
799  info->width_50_50 = 0;
800  info->power_50_50 = 0;
801  info->width_10_10 = 0;
802  info->power_10_10 = 0;
803  }
804 
805  polarimetry::StokesAnalysis stokes( pol == AnitaPol::kHorizontal ? wf : xpol_wf, pol == AnitaPol::kHorizontal ? xpol_wf: wf, cfg->cross_correlate_hv);
806  info->I = stokes.getAvgI();
807  info->Q = stokes.getAvgQ();
808  info->U = stokes.getAvgU();
809  info->V = stokes.getAvgV();
810  info->NPointsMaxStokes = stokes.computeWindowedAverage(cfg->stokes_fracI, &info->max_dI, &info->max_dQ, &info->max_dU, &info->max_dV, &info->polErr);
811 
812  TGraph distance_cdf;
813  info->impulsivityMeasure = impulsivity::impulsivityMeasure(wf, &distance_cdf);
814  info->bandwidthMeasure = bandwidth::lowness(wf);
815 
816  //fill in narrowest widths
817  for (int iw = 0; iw < AnitaEventSummary::numFracPowerWindows; iw++)
818  {
819  int half_width = TMath::BinarySearch(distance_cdf.GetN(), distance_cdf.GetY(), 0.1 * (iw+1));
820  info->fracPowerWindowBegins[iw] = peakHilbertBin < half_width ? wf->even()->GetX()[0] : wf->even()->GetX()[peakHilbertBin - half_width];
821  info->fracPowerWindowEnds[iw] = peakHilbertBin + half_width >= distance_cdf.GetN() ? wf->even()->GetX()[distance_cdf.GetN()-1] : wf->even()->GetX()[half_width + peakHilbertBin];
822  }
823 
824  if (!rms)
825  {
826  double dt = wf->deltaT();
827  double t0 = even->GetX()[0];
828 
829  int i0 = TMath::Max(0.,floor((cfg->noise_estimate_t0 - t0)/dt));
830  int i1 = TMath::Min(even->GetN()-1.,ceil((cfg->noise_estimate_t1 - t0)/dt));
831  int n = i1 - i0 + 1;
832  // printf("%d-%d -> %d \n", i0, i1, n);
833  if (n < 0 || n > even->GetN()) n = even->GetN();
834  rms = TMath::RMS(n, even->GetY() + i0);
835  }
836 
837  info->snr = info->peakHilbert / rms;
838  if(vpp > 0 && cfg->use_antenna_level_snr) info->snr = vpp/(2*rms);
839 
840  if(cfg->use_coherent_spectra) pwr = wf->powerdB();
841 
842  TGraphAligned power(pwr->GetN(),pwr->GetX(),pwr->GetY());
843 
844  if (!cfg->use_coherent_spectra) power.dBize();
845 
846  if (power_filter)
847  {
848  power_filter->filterGraph(&power);
849  }
850 
851  spectrum::fillSpectrumParameters(&power, avg_spectra[pol], info, cfg);
852 }
853 
857 void UCorrelator::Analyzer::fillChannelInfo(const FilteredAnitaEvent* event, AnitaEventSummary* summary){
858  for(int polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
860 #ifdef UCORRELATOR_OPENMP
861 #pragma omp parallel for
862 #endif
863  for (int ant=0; ant<NUM_SEAVEYS; ant++)
864  {
865  const AnalysisWaveform* wf = event->getFilteredGraph(ant, pol);
866  const TGraphAligned* hilbertEnvelope= wf->hilbertEnvelope();
867  const TGraphAligned* gr = wf->even();
868  double rms = cfg->use_forced_trigger_rms ? UCorrelator::TimeDependentAverageLoader::getRMS( event->getHeader()->triggerTime, pol, ant) : gr->GetRMS(2);
869 
870  summary->channels[polInd][ant].rms = rms;
871  summary->channels[polInd][ant].avgPower = gr->getSumV2() / gr->GetN();
872  summary->channels[polInd][ant].peakHilbert = hilbertEnvelope->peakVal();
873  summary->channels[polInd][ant].snr = FFTtools::getPeakVal(gr) / rms;
874  }
875  }
876 }
877 
878 
880 {
881 
882  delete zoomed;
883  if (interactive)
884  {
885  delete correlation_maps[0];
886  delete correlation_maps[1];
887 
888 
889  for (int pol = 0; pol < 2; pol++)
890  {
891  for (int i = 0; i < cfg->nmaxima; i++)
892  {
893  delete zoomed_correlation_maps[pol][i];
894 
895  for (int ifilt = 0; ifilt < 2; ifilt++)
896  {
897 
898  delete coherent[pol][ifilt][i];
899  delete deconvolved[pol][ifilt][i];
900 
901  delete coherent_xpol[pol][ifilt][i];
902  delete deconvolved_xpol[pol][ifilt][i];
903 
904  delete coherent_power[pol][ifilt][i];
905  delete deconvolved_power[pol][ifilt][i];
906 
907  delete coherent_power_xpol[pol][ifilt][i];
908  delete deconvolved_power_xpol[pol][ifilt][i];
909  }
910 
911  }
912  }
913 
914  clearInteractiveMemory(1);
915  }
916 
917  if (power_filter)
918  delete power_filter;
919 }
920 
921 void UCorrelator::Analyzer::clearInteractiveMemory(double frac) const
922 {
923 
924  for (unsigned i = (1-frac) * delete_list.size(); i < delete_list.size(); i++)
925  {
926  delete delete_list[i];
927  }
928 
929  delete_list.clear();
930 }
931 
932 
933 /* Nevermind this... wanted to zoom in on analyzer canvas on click, but too much work :(
934  static void setOnClickHandler(TPad * pad)
935  {
936 
937  }
938  */
939 
940 
941 
942 
943 
944 void UCorrelator::Analyzer::drawSummary(TPad * ch, TPad * cv, int draw_filtered) const
945 {
946  TPad * pads[2] = {ch,cv};
947 
948  clearInteractiveMemory();
949 
950  // gStyle->SetOptStat(0);
951  for (int ipol = cfg->start_pol; ipol <= cfg->end_pol; ipol++)
952  {
953  if (!pads[ipol])
954  {
955  pads[ipol] = new TCanvas(ipol == 0 ? "analyzer_ch" : "analyzer_cv", ipol == 0 ? "hpol" : "vpol",1920,500);
956  }
957 
958  pads[ipol]->Clear();
959  pads[ipol]->Divide(2,1);
960 
961  pads[ipol]->cd(1)->Divide(1,2);
962 
963  pads[ipol]->cd(1)->cd(1);
964  correlation_maps[ipol]->SetTitle(ipol == 0 ? "HPol map" : "VPol map" );
965  correlation_maps[ipol]->addRough(rough_peaks[ipol]);
966  correlation_maps[ipol]->Draw("colz");
967 
968  for (int i = 0; i < last.nPeaks[ipol]; i++)
969  {
970  pads[ipol]->cd(1)->cd(2);
971  UCorrelator::gui::SummaryText * pt = new gui::SummaryText(i, AnitaPol::AnitaPol_t(ipol), this, draw_filtered);
972  delete_list.push_back(pt);
973  pt->Draw();
974  }
975 
976 
977  pads[ipol]->cd(2)->Divide(last.nPeaks[ipol], interactive_deconvolved ? 5 : 3);
978 
979  for (int i = 0; i < last.nPeaks[ipol]; i++)
980  {
981  pads[ipol]->cd(2)->cd(i+1);
982 
983  zoomed_correlation_maps[ipol][i]->SetTitle(TString::Format("Zoomed peak %d", i+1));
984  zoomed_correlation_maps[ipol][i]->addFine(last.peak[ipol][i]);
985  zoomed_correlation_maps[ipol][i]->Draw("colz");
986 
987  pads[ipol]->cd(2)->cd(i+last.nPeaks[ipol]+1);
988 
989  ((TGraph*) coherent[ipol][draw_filtered][i]->even())->SetTitle(TString::Format ( "Coherent (+ xpol) %d", i+1));
990  coherent[ipol][draw_filtered][i]->drawEven("al");
991 
992 
993  coherent_xpol[ipol][draw_filtered][i]->drawEven("lsame");
994 
995 
996  pads[ipol]->cd(2)->cd(i+2*last.nPeaks[ipol]+1);
997 
998 
999  if (cfg->use_coherent_spectra)
1000  {
1001  ((TGraph*) coherent[ipol][draw_filtered][i]->powerdB())->SetTitle(TString::Format ( "Power Coherent (+ xpol) %d", i+1));
1002  ((TGraph*) coherent[ipol][draw_filtered][i]->powerdB())->GetXaxis()->SetRangeUser(0,1.3);
1003  coherent[ipol][draw_filtered][i]->drawPowerdB("al");
1004  ((TGraph*)coherent_xpol[ipol][draw_filtered][i]->powerdB())->SetLineColor(15);
1005  ((TGraph*)coherent_xpol[ipol][draw_filtered][i]->powerdB())->SetName("powerdBXpol");
1006  coherent_xpol[ipol][draw_filtered][i]->drawPowerdB("lsame");
1007  }
1008  else
1009  {
1010  (((TGraph*)coherent_power[ipol][draw_filtered][i]))->SetTitle(TString::Format ( "Power Coherent (+ xpol) %d", i+1));
1011  ((TGraph*)coherent_power[ipol][draw_filtered][i])->Draw("al");
1012  ((TGraph*)coherent_power[ipol][draw_filtered][i])->GetXaxis()->SetRangeUser(0,1.3);
1013  coherent_power_xpol[ipol][draw_filtered][i]->Draw("lsame");
1014  ((TGraph*)avg_spectra[ipol])->SetLineColor(2);
1015  ((TGraph*)avg_spectra[ipol])->Draw("lsame");
1016  }
1017 
1018 
1019 
1020  /*
1021  TF1 * spectral_slope = new TF1(TString::Format("__slope_%d", i), "pol1",0.2,0.7);
1022  spectral_slope->SetParameter(0, last.coherent[ipol][i].spectrumIntercept) ;
1023  spectral_slope->SetParameter(1, last.coherent[ipol][i].spectrumSlope) ;
1024 
1025 
1026  TGraphErrors *gbw = new TGraphErrors(AnitaEventSummary::peaksPerSpectrum);
1027  gbw->SetTitle("Bandwidth Peaks");
1028  for (int bwpeak = 0; bwpeak < AnitaEventSummary::peaksPerSpectrum; bwpeak++)
1029  {
1030  double bwf = last.coherent[ipol][i].peakFrequency[bwpeak];
1031  gbw->SetPoint(bwpeak, bwf, avg_spectra[ipol]->Eval(bwf)+ last.coherent[ipol][i].peakPower[bwpeak]);
1032  gbw->SetPointError(bwpeak , last.coherent[ipol][i].bandwidth[bwpeak]/2,0);
1033  }
1034  gbw->SetMarkerColor(4);
1035  gbw->SetMarkerStyle(20);
1036  gbw->Draw("psame");
1037 
1038 
1039  delete_list.push_back(spectral_slope);
1040  delete_list.push_back(gbw);
1041 
1042 */
1043 
1044  if (interactive_deconvolved)
1045  {
1046  pads[ipol]->cd(2)->cd(i+3*last.nPeaks[ipol]+1);
1047  ((TGraph*) deconvolved[ipol][draw_filtered][i]->even())->SetTitle(TString::Format ( "Deconvolved (+ xpol) %d", i+1));
1048  deconvolved[ipol][draw_filtered][i]->drawEven("alp");
1049  if (interactive_xpol_deconvolved)
1050  {
1051  deconvolved_xpol[ipol][draw_filtered][i]->drawEven("lsame");
1052  }
1053 
1054  pads[ipol]->cd(2)->cd(i+4*last.nPeaks[ipol]+1);
1055 
1056  if (cfg->use_coherent_spectra)
1057  {
1058 
1059  ((TGraph*) deconvolved[ipol][draw_filtered][i]->powerdB())->SetTitle(TString::Format ( "Power Deconvolved (+ xpol) %d", i+1));
1060  ((TGraph*) deconvolved[ipol][draw_filtered][i]->powerdB())->GetXaxis()->SetRangeUser(0,1.3);
1061  (deconvolved[ipol][draw_filtered][i])->drawPowerdB();;
1062  if (interactive_xpol_deconvolved)
1063  {
1064  ((TGraph*) deconvolved_xpol[ipol][draw_filtered][i]->powerdB())->SetLineColor(15);
1065  ((TGraph*) deconvolved_xpol[ipol][draw_filtered][i]->powerdB())->SetName("powerdBXpol");
1066  (deconvolved_xpol[ipol][draw_filtered][i])->drawPowerdB("lsame");
1067  }
1068 
1069  }
1070  else
1071  {
1072  (((TGraph*)deconvolved_power[ipol][draw_filtered][i]))->SetTitle(TString::Format ( "Power Deconvolved (+ xpol) %d", i+1));
1073  ((TGraph*)deconvolved_power[ipol][draw_filtered][i])->Draw();;
1074  if (interactive_xpol_deconvolved)
1075  {
1076  ((TGraph*)deconvolved_power_xpol[ipol][draw_filtered][i])->Draw("lsame");
1077  }
1078  }
1079 
1080 
1081  }
1082 
1083  }
1084  }
1085 }
1086 
1087 void UCorrelator::Analyzer::fillFlags(const FilteredAnitaEvent * fae, AnitaEventSummary* summary, UsefulAdu5Pat * pat)
1088 {
1089  AnitaEventSummary::EventFlags * flags = &summary->flags;
1090  flags->nadirFlag = true; // we should get rid of htis I guess?
1091 
1092  if (cfg->fill_blast_fraction)
1093  flags->blastFraction = TimeDependentAverageLoader::getPayloadBlastFraction(fae->getHeader()->triggerTime);
1094 
1095  flags->meanPower[0] = fae->getAveragePower();
1096  flags->medianPower[0] = fae->getMedianPower();
1097  flags->meanPowerFiltered[0] = fae->getAveragePower(AnitaPol::kNotAPol, AnitaRing::kNotARing, true);
1098  flags->medianPowerFiltered[0] = fae->getMedianPower(AnitaPol::kNotAPol, AnitaRing::kNotARing, true);
1099 
1100  for (int ring = 0; ring <AnitaRing::kNotARing; ring++)
1101  {
1102  flags->meanPower[1+ring] = fae->getAveragePower(AnitaPol::kNotAPol, AnitaRing::AnitaRing_t(ring));
1103  flags->medianPower[1+ring] = fae->getMedianPower(AnitaPol::kNotAPol, AnitaRing::AnitaRing_t(ring));
1104  flags->meanPowerFiltered[1+ring] = fae->getAveragePower(AnitaPol::kNotAPol, AnitaRing::AnitaRing_t(ring), true);
1105  flags->medianPowerFiltered[1+ring] = fae->getMedianPower(AnitaPol::kNotAPol, AnitaRing::AnitaRing_t(ring), true);
1106  }
1107 
1108 
1109  flags->nSectorsWhereBottomExceedsTop = 0;
1110  for (int pol = AnitaPol::kHorizontal; pol <= AnitaPol::kVertical; pol++)
1111  {
1112  int n_above_this_pol;
1113  fae->getMinMaxRatio(AnitaPol::AnitaPol_t(pol), &flags->maxBottomToTopRatio[pol], &flags->minBottomToTopRatio[pol], &flags->maxBottomToTopRatioSector[pol], &flags->minBottomToTopRatioSector[pol], AnitaRing::kBottomRing, AnitaRing::kTopRing,1, &n_above_this_pol);
1114  flags->nSectorsWhereBottomExceedsTop += n_above_this_pol;
1115  }
1116 
1117 
1118  if ( isLDB(fae->getHeader(), cfg))
1119  {
1120  flags->pulser = AnitaEventSummary::EventFlags::LDB;
1121  }
1122  else if ( isWAISHPol(pat, fae->getHeader(), cfg) )
1123  {
1124  flags->pulser = AnitaEventSummary::EventFlags::WAIS;
1125  }
1126  else if( isWAISVPol (pat, fae->getHeader(), cfg)){
1127  flags->pulser = AnitaEventSummary::EventFlags::WAIS_V;
1128  }
1129  else
1130  {
1131  flags->pulser = AnitaEventSummary::EventFlags::NONE;
1132  }
1133 
1134  // more than 80 percent filterd out
1135  flags->strongCWFlag = flags->medianPowerFiltered[0] / flags->medianPower[0] < 0.2;
1136 
1137  if(AnitaVersion::get() == 4){
1138  //Blast event multi variant selector
1139  // 1)more than 30 channels that waveform rms > 100mV 2)p2p bottom to top ratio 3)meanPower bottom to top ratio
1140  flags->isPayloadBlast =
1141  summary->countChannelAboveThreshold(100)>30 ||
1142  flags->maxBottomToTopRatio[0] <0.9 || flags->maxBottomToTopRatio[0] >2.6 ||
1143  flags->maxBottomToTopRatio[1] <0.9 || flags->maxBottomToTopRatio[1] >2.6 ||
1144  flags->meanPower[3]/flags->meanPower[1] <0.2 || flags->meanPower[3]/flags->meanPower[1] >1.7;
1145  }else{
1146  flags->isPayloadBlast =
1147  (cfg->max_mean_power_filtered && flags->meanPowerFiltered[0] > cfg->max_mean_power_filtered) ||
1148  (cfg->max_median_power_filtered && flags->medianPowerFiltered[0] > cfg->max_median_power_filtered) ||
1149  (cfg->max_bottom_to_top_ratio && flags->maxBottomToTopRatio[0] > cfg->max_bottom_to_top_ratio) ||
1150  (cfg->max_bottom_to_top_ratio && flags->maxBottomToTopRatio[1] > cfg->max_bottom_to_top_ratio);
1151  }
1152 
1153  flags->isVarner = false;
1154  flags->isVarner2 = false;
1155 
1156  flags->isGood = !flags->isVarner && !flags->isVarner2 && !flags->strongCWFlag;
1157 
1158  //added for a class of anita 4 events that only happens on one lab and channel
1159  //also added in a check for glitches in surf 11 on lab c and surf 0 on lab b and c and surf8 lab c since i also want to remove those
1160  if(AnitaVersion::get() == 4)
1161  {
1162  flags->isStepFunction |= fae->checkStepFunction(1, AnitaRing::kMiddleRing, 8, AnitaPol::kVertical);
1163  flags->isStepFunction |= (fae->checkSurfForGlitch(0 , 1, 500)<<1);
1164  flags->isStepFunction |= (fae->checkSurfForGlitch(0 , 2, 500)<<2);
1165  flags->isStepFunction |= (fae->checkSurfForGlitch(11, 2, 500)<<2);
1166  flags->isStepFunction |= (fae->checkSurfForGlitch(8, 2, 500)<<2);
1167  flags->isStepFunction |= (fae->checkSurfForGlitch(6, 3, 500)<<3);
1168 
1169  if(fae->checkSaturation( 0, 0, cfg->saturation_threshold) > 0)
1170  {
1171  flags->isStepFunction |= (1<<4);
1172  }
1173  flags->hasGlitch = fae->getUsefulAnitaEvent()->fRFSpike;
1174  }
1175  else flags->isStepFunction = 0;
1176 
1177  //might as well use the power flags that Ben Strutt added
1178  const double bandsLowGHz[AnitaEventSummary::numBlastPowerBands] = {0.15-1e-10, 1.1-1e-10, 0};
1179  const double bandsHighGHz[AnitaEventSummary::numBlastPowerBands] = {0.26-1e-10, 999, 999};
1180 
1181  //reset values
1182  for(int band = 0; band < AnitaEventSummary::numBlastPowerBands; band++)
1183  {
1184  flags->middleOrBottomPower[band] = 0;
1185  flags->middleOrBottomAnt[band] = -1;
1186  flags->middleOrBottomPol[band] = 2;
1187  flags->topPower[band] = 0;
1188  }
1189 
1190  for(Int_t polInd = 0; polInd < AnitaPol::kNotAPol; polInd++)
1191  {
1193  for(UInt_t phi = 0; phi < NUM_PHI; phi++)
1194  {
1195  for(UInt_t ring = AnitaRing::kMiddleRing; ring < AnitaRing::kNotARing; ring++)
1196  {
1197  Int_t ant = ring*NUM_PHI + phi;
1198 
1199  const AnalysisWaveform* wf = fae->getRawGraph(ant,pol);
1200  const TGraphAligned* grPow = wf->power();
1201  const double df_GHz = grPow->GetX()[1] - grPow->GetX()[0];
1202 
1203  Double_t powThisAnt[AnitaEventSummary::numBlastPowerBands] = {0};
1204  for(int i = 0; i < grPow->GetN(); i++)
1205  {
1206  const double f_GHz = grPow->GetX()[i];
1207  for(int band = 0; band < AnitaEventSummary::numBlastPowerBands; band++)
1208  {
1209  if(f_GHz >= bandsLowGHz[band] && f_GHz < bandsHighGHz[band])
1210  {
1211  powThisAnt[band] += grPow->GetY()[i]*df_GHz;
1212  }
1213  }
1214  }
1215 
1216  for(int band = 0; band < AnitaEventSummary::numBlastPowerBands; band++)
1217  {
1218  if(powThisAnt[band] > flags->middleOrBottomPower[band])
1219  {
1220  flags->middleOrBottomPower[band] = powThisAnt[band];
1221  flags->middleOrBottomAnt[band] = ant;
1222  flags->middleOrBottomPol[band] = polInd;
1223  }
1224  }
1225  }
1226  }
1227  }
1228 
1229  for(int band = 0; band < AnitaEventSummary::numBlastPowerBands; band++)
1230  {
1231  int ant = flags->middleOrBottomAnt[band] % NUM_PHI;
1232  AnitaPol::AnitaPol_t pol = (AnitaPol::AnitaPol_t) flags->middleOrBottomPol[band];
1233  const AnalysisWaveform* wf = fae->getRawGraph(ant, pol);
1234  const TGraphAligned* grPow = wf->power();
1235  const double df_GHz = grPow->GetX()[1] - grPow->GetX()[0];
1236 
1237  for(int i = 0; i < grPow->GetN(); i++)
1238  {
1239  const double f_GHz = grPow->GetX()[i];
1240  for(int band = 0; band < AnitaEventSummary::numBlastPowerBands; band++)
1241  {
1242  if(f_GHz >= bandsLowGHz[band] && f_GHz < bandsHighGHz[band])
1243  {
1244  flags->topPower[band] += grPow->GetY()[i]*df_GHz;
1245  }
1246  }
1247  }
1248  }
1249 }
1250 
1252 {
1253  wfcomb_filtered.setExtraFilters(extra);
1254  wfcomb_xpol_filtered.setExtraFilters(extra);
1255 }
1256 
1258 {
1259  wfcomb_filtered.setExtraFiltersDeconvolved(extra);
1260  wfcomb_xpol_filtered.setExtraFiltersDeconvolved(extra);
1261 }
bool isLDB(const RawAnitaHeader *hdr, const AnalysisConfig *cfg=0)
Definition: Util.cc:92
const TGraphAligned * power() const
Double_t getPeakVal(const TGraph *gr, int *index=0)
Find the peak (maximum positive) in a TGraph.
Definition: FFTtools.cxx:1510
WaveformInfo deconvolved[AnitaPol::kNotAPol][maxDirectionsPerPol]
Summaries of the (unfiltered) coherently summed waveforms, array index correponds to entry in peak[][...
Bool_t masked_xpol
was this in a masked phi sector?
void analyze(const FilteredAnitaEvent *event, AnitaEventSummary *summary, const TruthAnitaEvent *truth=0)
Definition: Analyzer.cc:177
Double_t totalPower
The number of points used in the above estimates.
const TGraphAligned * powerdB() const
Bicubic interpolation (not implemented yet)
const UsefulAnitaEvent * getUsefulAnitaEvent() const
PointingHypothesis peak[AnitaPol::kNotAPol][maxDirectionsPerPol]
Number of peaks stored in this AnitaEventSummary (might be less than maxDirectionsPerPol) ...
bool isWAISVPol(const UsefulAdu5Pat *pat, const RawAnitaHeader *hdr, const AnalysisConfig *cfg=0)
Definition: Util.cc:26
Int_t countChannelAboveThreshold(int threshold=100) const
bool isWAISHPol(const UsefulAdu5Pat *pat, const RawAnitaHeader *hdr, const AnalysisConfig *cfg=0)
Definition: Util.cc:39
Analyzer(const AnalysisConfig *cfg=0, bool interactive=false)
Definition: Analyzer.cc:62
Double_t dphi_rough
angular separation from higher value peak in same event. 1000 if highest value event (i...
Double_t phi_separation
If an event barely missed the ground, it is useful to see the coordinates at which it would hit if th...
double correlation_gain_correction
exponent for baseline weighting of correlation maps (since longer baselines give you better resolutio...
Double_t hwAngle
value of average of the peak location over the past 60 min-bias events
TGraphAligned * updateEven()
MCTruth mc
Contains location of LDB cal pulser in map coordinates at time of event.
Double_t meanPower[1+AnitaRing::kNotARing]
Double_t impulsivityMeasure
moments about Peak (1st - 5th moments)
void setExtraFiltersDeconvolved(FilterStrategy *extra)
Definition: Analyzer.cc:1257
virtual ~TGraphAligned()
static const Int_t numFracPowerWindows
The maximum number of frequency peaks per waveform spectrum.
WaveformInfo coherent_filtered[AnitaPol::kNotAPol][maxDirectionsPerPol]
Summaries of the (unfiltered) de-dispersed coherently summed waveforms, array index correponds to ent...
A filter strategy defines the sets of filters that are used and provides some introspection abilities...
Double_t max_dI
Integral Stokes Parameters (over the entire waveform)
void doPeakFindingHistogram(const TH2D *hist, FineMaximum *peak)
Definition: PeakFinder.cc:875
RawAnitaHeader – The Raw ANITA Event Header.
Bool_t triggered
theta - theta rough
void getThetaAndPhiWave(Double_t sourceLon, Double_t sourceLat, Double_t sourceAlt, Double_t &thetaWave, Double_t &phiWave)
const UsefulAdu5Pat * getGPS() const
Double_t totalPowerXpol
Total power in waveform.
EventFlags flags
Summaries of each channel&#39;s waveform.
USeful in for loops.
Bool_t masked
was this in a triggered xpol phi sector?
int zoomed_ntheta
number of phi bins in zoomed correlation map
int zoomed_nphi
enable group delay in interferometer
void combine(double phi, double theta, const FilteredAnitaEvent *event, AnitaPol::AnitaPol_t pol, ULong64_t disallowed=0, double t0=0, double t1=100, double *avg_of_peaks=0, bool use_hilbert=true)
enum AnitaRing::EAnitaRing AnitaRing_t
Ring enumeration.
UInt_t payloadTime
unixTime of readout
void setGroupDelayFlag(bool flag)
Definition: Correlator.h:51
Double_t antennaPeakAverage
was this in a masked phi xpol sector?
Double_t power_50_50
Power enclosed within 10_10 width.
const AnalysisWaveform * getRawGraph(UInt_t i) const
Double_t theta_adjustment_needed
chisq/ndof of peak finding process, if available (otherwise zero)
void getSunPosition(Double_t &phiDeg, Double_t &thetaDeg) const
Uses realTime, latitude, longitude to calculate the sun&#39;s position.
double deltaT() const
TruthAnitaEvent – The Truth ANITA Event.
Int_t NPointsMaxStokes
instantanteous stokes parameters (computed near max_dI).
quadratic fit near peak, using 25 bins
As UsefulAnitaEvent is to RawAnitaEvent, UsefulAdu5Pat is to Adu5Pat. Well not quite as useful but yo...
Definition: UsefulAdu5Pat.h:39
PayloadLocation anitaLocation
Contains summary information about MC truth, if real data then this filled with constant, unphysical values.
Double_t longitude
on continent, or -9999 if doesn&#39;t intersect
Stores information about a coherently summed waveform (filtered/unfiltered/deconvolved) The coherent ...
Double_t theta
peak phi, degrees
ChannelInfo channels[AnitaPol::kNotAPol][NUM_SEAVEYS]
Summaries of the filtered, de-dispersed, coherently summed waveforms, array index correponds to entry...
Double_t dtheta_rough
phi - phi rough
bool enable_group_delay
Highest elevation considered, measured as positive above horizon. (negative would be below horizon) ...
Double_t getDistanceFromSource(Double_t sourceLat, Double_t sourceLong, Double_t sourceAlt) const
Gets time of flight from any source.
void wrap(size_t N, double *vals, double period=360)
Definition: FFTtools.cxx:2851
Vertical Polarisation.
Useful in for loops.
const TGraphAligned * hilbertEnvelope() const
Int_t fRFSpike
Flag raised if the ADC value is too large or small in RF.
void setExtraFilters(FilterStrategy *extra)
Definition: Analyzer.cc:1251
Double_t value
peak theta, degrees
Common analysis format between UCorrelator and Acclaim.
const TGraphAligned * even() const
Horizontal Polarisation.
Double_t peakTime
Power enclosed within 50_50 width.
int traceBackToContinent3(Double_t phiWave, Double_t thetaWave, Double_t *lon, Double_t *lat, Double_t *alt, Double_t *theta_adjustment_required) const
void setMaxAntennaMaxPhiDistance(double max_ant_phi)
Definition: Correlator.h:48
This class is intended to store all the necessary data about an ANITA event for filtering and analysi...
enum AnitaPol::EAnitaPol AnitaPol_t
Polarisation enumeration.
SourceHypothesis sun
Flags corresponding the event quality, trigger type, calibration pulser timing, etc.
Int_t nPeaks[AnitaPol::kNotAPol]
Time of the event.
WaveformInfo coherent[AnitaPol::kNotAPol][maxDirectionsPerPol]
Summaries of the event peak directions (indices of all WaveformInfo member arrays match peak index) ...
Bool_t triggered_xpol
was this in a triggered phi sector?
Double_t latitude
angle with respect to triggering phi sector in opposite polarisation
This class is intended to be the main storage vessel for ANITA waveforms. It is similar in principle ...
void drawSummary(TPad *chpol=0, TPad *cvpol=0, int draw_filtered=0) const
Definition: Analyzer.cc:944
Double_t distanceToSource
on continent, or -9999 if doesn&#39;t intersect
static double getRMS(double t, int ipol, int ant, int nsecs=10)
WaveformInfo deconvolved_filtered[AnitaPol::kNotAPol][maxDirectionsPerPol]
Summaries of the filtered, coherently summed waveforms, array index correponds to entry in peak[][]...
const RawAnitaHeader * getHeader() const
UInt_t triggerTime
Trigger time from TURF converted to unixTime.
Double_t altitude
on continent, or -9999 if doesn&#39;t intersect