AnitaEventSummary.cc
1 #include "AnitaEventSummary.h"
2 
3 #include "RawAnitaHeader.h"
4 #include "UsefulAdu5Pat.h"
5 #include "TruthAnitaEvent.h"
6 #include "TBuffer.h"
7 #include "TClass.h"
8 //are these even necessary anymore? Who knows!
9 //ClassImp(AnitaEventSummary)
10 //ClassImp(AnitaEventSummary::PointingHypothesis)
11 //ClassImp(AnitaEventSummary::SourceHypothesis)
12 
13 
14 const double C_IN_M_NS = 0.299792;
15 static double impulsivityFractionThreshold = -1; //modifies behavior of mostImpulsive() set of utils
16 
17 
18 //---------------------------------------------------------------------------------------------------------
25 : anitaLocation()
26 {
27  zeroInternals();
28 }
29 
30 
31 
32 
33 //---------------------------------------------------------------------------------------------------------
40 : anitaLocation()
41 {
42  zeroInternals();
43 
44  setTriggerInfomation(header);
45  eventNumber = header->eventNumber;
46  run = header->run;
47  realTime = header->realTime;
48 
49 }
50 
51 
52 
53 
54 
55 //---------------------------------------------------------------------------------------------------------
62 : anitaLocation(dynamic_cast<Adu5Pat*>(pat))
63 {
64 
65  zeroInternals();
66  setTriggerInfomation(header);
67  setSourceInformation(pat,truth);
68  eventNumber = header->eventNumber;
69  run = header->run;
70  realTime = header->realTime;
71 }
72 
73 
74 
75 
76 
77 
78 
79 
84 
85  fLastEventNumber = -1;
86  run = 0;
87  eventNumber = 0;
88  resetNonPersistent();
89 
90 
91  for(Int_t polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
93  nPeaks[polInd] = 0;
94  for(Int_t dir=0; dir < maxDirectionsPerPol; dir++)
95  {
96  memset(&peak[polInd][dir],0,sizeof(PointingHypothesis));
97  memset(&coherent[polInd][dir],0,sizeof(WaveformInfo));
98  memset(&deconvolved[polInd][dir],0,sizeof(WaveformInfo));
99  memset(&coherent_filtered[polInd][dir],0,sizeof(WaveformInfo));
100  memset(&deconvolved_filtered[polInd][dir],0,sizeof(WaveformInfo));
101 
102  }
103  for(Int_t ant=0; ant < 48; ant++){
104  memset(&channels[polInd][ant],0,sizeof(ChannelInfo));
105  channels[polInd][ant].pol = pol;
106  channels[polInd][ant].ant = ant;
107  }
108  }
109  memset(&flags,0, sizeof(EventFlags));
110  flags.pulser = EventFlags::NONE;
111 
112  sun.reset();
113  wais.reset();
114  ldb.reset();
115  mc.reset();
116 
117 }
118 
119 
120 
128  findHighestPeak();
129  return fHighestPol;
130 }
131 
132 
140  findHighestPeak();
141  return int(fHighestPol);
142 }
143 
144 
152  findHighestPeak();
153  return fHighestPeakIndex;
154 }
155 
156 
157 
165  findHighestPeak();
166  return peak[fHighestPol][fHighestPeakIndex];
167 }
168 
169 
177  findHighestPeak();
178  return coherent[fHighestPol][fHighestPeakIndex];
179 }
180 
181 
189  findHighestPeak();
190  return deconvolved[fHighestPol][fHighestPeakIndex];
191 }
192 
193 
194 
195 
203  findHighestPeak();
204  return coherent_filtered[fHighestPol][fHighestPeakIndex];
205 }
206 
207 
215  findHighestPeak();
216  return deconvolved_filtered[fHighestPol][fHighestPeakIndex];
217 }
218 
219 
220 
221 
222 
223 
224 
225 
226 
235  findMostImpulsive(whichMetric);
236  return fMostImpulsivePol;
237 }
238 
239 
247 int AnitaEventSummary::mostImpulsivePolAsInt(int whichMetric) const{
248  findMostImpulsive(whichMetric);
249  return int(fMostImpulsivePol);
250 }
251 
252 
260 int AnitaEventSummary::mostImpulsiveInd(int whichMetric) const{
261  findMostImpulsive(whichMetric);
262  return fMostImpulsiveIndex;
263 }
264 
265 
266 
275  findMostImpulsive(whichMetric);
276  return peak[fMostImpulsivePol][fMostImpulsiveIndex];
277 }
278 
279 
288  findMostImpulsive(whichMetric);
289  return coherent[fMostImpulsivePol][fMostImpulsiveIndex];
290 }
291 
292 
301  findMostImpulsive(whichMetric);
302  return deconvolved[fMostImpulsivePol][fMostImpulsiveIndex];
303 }
304 
305 
306 
307 
316  findMostImpulsive(whichMetric);
317  return coherent_filtered[fMostImpulsivePol][fMostImpulsiveIndex];
318 }
319 
320 
329  findMostImpulsive(whichMetric);
330  return deconvolved_filtered[fMostImpulsivePol][fMostImpulsiveIndex];
331 }
332 
333 
341  int count = 0;
342  for(Int_t polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
343  for(Int_t ant=0; ant < 48; ant++){
344  if (channels[polInd][ant].rms>threshold){
345  count++;
346  };
347  }
348  }
349  return count;
350 }
351 
352 
353 
354 
361 
362  // setting to zero, for testing this function.
363  flags.isVPolTrigger = 0;
364  flags.isHPolTrigger = 0;
365 
366  // need two adjacent L3 phi-sectors to trigger ANITA-3
367  for(Int_t phi=0; phi<NUM_PHI; phi++){
368  Int_t phi2 = (phi+1)%NUM_PHI; // adjacent phi-sector
369 
370  Int_t trigBit = (header->l3TrigPattern >> phi) & 1;
371  Int_t trigBit2 = (header->l3TrigPattern >> phi2) & 1;
372 
373  // std::cout << header->l3TrigPattern << "\t"
374  // << phi << "\t" << phi2 << "\t"
375  // << trigBit << "\t" << trigBit2 << std::endl;
376 
377  if(trigBit > 0 && trigBit2 > 0){
378  flags.isVPolTrigger = 1;
379  }
380 
381  Int_t trigBitH = (header->l3TrigPatternH >> phi) & 1;
382  Int_t trigBitH2 = (header->l3TrigPatternH >> phi2) & 1;
383 
384  if(trigBitH > 0 && trigBitH2 > 0){
385  flags.isHPolTrigger = 1;
386  }
387  }
388 
389  flags.isRF = header->getTriggerBitRF();
390  flags.isSoftwareTrigger = header->getTriggerBitADU5() | header->getTriggerBitG12() | header->getTriggerBitSoftExt();
391  flags.isAdu5Trigger = header->getTriggerBitADU5();
392  flags.isG12Trigger = header->getTriggerBitG12();
393  flags.isSoftwareTrigger = header->getTriggerBitSoftExt();
394  flags.isMinBiasTrigger = flags.isAdu5Trigger || flags.isG12Trigger || header->getTriggerBitG12() || flags.isSoftwareTrigger;
395 
396 
397 }
398 
399 
400 
401 
409 
410 
411  pat->getSunPosition(sun.phi, sun.theta);
412  sun.distance = 150e9; // I guess in theory we could compute this!
413 
414  pat->getThetaAndPhiWaveWaisDivide(wais.theta, wais.phi);
415  wais.theta *= 180/ TMath::Pi();
416  wais.phi *= 180/ TMath::Pi();
417  wais.distance = pat->getWaisDivideTriggerTimeNs() * C_IN_M_NS;
418 
419  pat->getThetaAndPhiWaveLDB(ldb.theta, ldb.phi);
420  ldb.distance = pat->getLDBTriggerTimeNs() * C_IN_M_NS;
421  ldb.theta *= 180/ TMath::Pi();
422  ldb.phi *= 180/ TMath::Pi();
423 
424 
425  if (truth)
426  {
427  pat->getThetaAndPhiWave(truth->sourceLon, truth->sourceLat, truth->sourceAlt, mc.theta,mc.phi);
428  mc.theta*=TMath::RadToDeg();
429  mc.phi*=TMath::RadToDeg();
430 
431  // Calculate information about the associated positions from mc
432  // Store lat, long, alt and angles.
433  // Note: lat, long etc are already calculated for some positions in icemc using position.cc
434  // This method converts the cartesian coords to lon/lat using usefulAdu5Pat
435  // The results are very similar
437  // nu interaction pos
438  Double_t nuPos[3];
439  nuPos[0] = truth->nuPos[0];
440  nuPos[1] = truth->nuPos[1];
441  nuPos[2] = truth->nuPos[2];
442  geom->getLatLonAltFromCartesian(nuPos,mc.interactionLat,mc.interactionLon,mc.interactionAlt);
443  // Note: This gets the angles from interaction pos to balloon pos, NOT interaction pos to rfExit pos.
444  pat->getThetaAndPhiWave(mc.interactionLon, mc.interactionLat, mc.interactionAlt, mc.interactionTheta,mc.interactionPhi);
445  mc.interactionTheta*=TMath::RadToDeg();
446  mc.interactionPhi*=TMath::RadToDeg();
447  // rfExit pos (in summary tree) calculated from raw cartesian coords from truth tree
448  // truth tree version = sourceLat/sourceLon/sourceAlt
449  Double_t rfExitPos[3];
450  rfExitPos[0] = truth->rfExitPos[2][0];
451  rfExitPos[1] = truth->rfExitPos[2][1];
452  rfExitPos[2] = truth->rfExitPos[2][2];
453  geom->getLatLonAltFromCartesian(rfExitPos,mc.rfExitLat,mc.rfExitLon,mc.rfExitAlt);
454  pat->getThetaAndPhiWave(mc.rfExitLon, mc.rfExitLat, mc.rfExitAlt, mc.rfExitTheta,mc.rfExitPhi);
455  mc.rfExitTheta*=TMath::RadToDeg();
456  mc.rfExitPhi*=TMath::RadToDeg();
457  // balloon pos (in summary tree) calculated from raw cartesian coords from truth tree
458  // truth tree version = latitude/longitude/altitude
459  Double_t balloonPos[3];
460  balloonPos[0] = truth->balloonPos[0];
461  balloonPos[1] = truth->balloonPos[1];
462  balloonPos[2] = truth->balloonPos[2];
463  geom->getLatLonAltFromCartesian(balloonPos,mc.balloonLat,mc.balloonLon,mc.balloonAlt);
464 
465 
466  if (truth->payloadPhi > 0 )
467  {
468  mc.theta = truth->payloadTheta;
469  mc.phi = truth->payloadPhi;
470  }
471  else
472  {
473  pat->getThetaAndPhiWave(truth->sourceLon, truth->sourceLat, truth->sourceAlt, mc.theta,mc.phi);
474  mc.theta*=TMath::RadToDeg();
475  mc.phi*=TMath::RadToDeg();
476  }
477 
478  mc.weight = truth->weight;
479  mc.distance = pat->getTriggerTimeNsFromSource(truth->sourceLat, truth->sourceLon, truth->sourceAlt);
480  mc.energy = truth->nuMom; // I guess this won't be true if icemc ever simulates non-relativistic neutrinos :P
481  mc.triggerSNR[0] = truth->maxSNRAtTriggerH;
482  mc.triggerSNR[1] = truth->maxSNRAtTriggerV;
483  TVector3 v(truth->nuDir[0], truth->nuDir[1], truth->nuDir[2]);
484  TVector3 p(truth->nuPos[0], truth->nuPos[1], truth->nuPos[2]);
485  pat->getThetaAndPhiWaveOfRayAtInfinity(p,v,mc.nuTheta,mc.nuPhi, true, 1e-5*TMath::DegToRad(), 1e7,&mc.nuDirection );
486  mc.nuTheta *= TMath::RadToDeg();
487  mc.nuPhi *= TMath::RadToDeg();
488  }
489 }
490 
491 
492 
497 {
499  memset(&wf[0],0,sizeof(WaveformInfo));
500  memset(&wf[1],0,sizeof(WaveformInfo));
501  weight = 0;
502  energy = 0;
503  triggerSNR[0] = 0;
504  triggerSNR[1] = 0;
505  nuDirection.SetXYZ(0,0,0);
506 }
507 
508 
509 
517 void AnitaEventSummary::WaveformInfo::cacheQuantitiesDerivedFromNarrowestWidths() const{
518  if(!(fContainer && fContainer->eventNumber == fLastEventNumberCache)){
519 
520  double fracPowerWindow[numFracPowerWindows];
521  for(int i=0; i < numFracPowerWindows; i++){
522  fracPowerWindow[i] = fracPowerWindowEnds[i] - fracPowerWindowBegins[i];
523  }
524 
525  // first do the mean
526  nwMeanCache = TMath::Mean(numFracPowerWindows, fracPowerWindow);
527 
528  // then the gradient
529  // The power fractions x[numFracPowerWindows] = {0.1, 0.2, 0.3, 0.4, 0.5} (sum = 1.5, mean = 0.3)
530  // the widths are y[numFracPowerWindows] = fracPowerWindow
531  // want least squres gradient = sum over (x - xbar)(y - ybar) / ((x - xbar)^{2})
532  const double gradDenom = 0.1; //0.04 + 0.01 + 0 + 0.01 + 0.04 = sum over (x[i] - mean_x)^{2}
533 
534  // gradNumerator = sum over (x[i] - mean_x)*(y[i] - mean_y), skip third term since x[i] - mean_x = 0
535  double gradNumerator = - 0.2*(fracPowerWindow[0] - nwMeanCache) + -0.1*(fracPowerWindow[1] - nwMeanCache)
536  + 0.1*(fracPowerWindow[3] - nwMeanCache) + 0.2*(fracPowerWindow[4] - nwMeanCache);
537  nwGradCache = gradNumerator/gradDenom;
538 
539  // then the intercept
540  nwInterceptCache = nwMeanCache - nwGradCache*0.3; // 0.3 = mean power fraction
541 
542  // finally the chisquare
543  nwChisquareCache = 0;
544  for(int i=0; i < numFracPowerWindows; i++){
545  double f = 0.1*(i+1);
546  double y = nwGradCache*f + nwInterceptCache;
547  double dy = (y - fracPowerWindow[i]);
548  nwChisquareCache += dy*dy;
549  }
550  }
551 }
552 
553 
560  cacheQuantitiesDerivedFromNarrowestWidths();
561  return nwMeanCache;
562 }
563 
571  cacheQuantitiesDerivedFromNarrowestWidths();
572  return nwGradCache;
573 }
574 
582  cacheQuantitiesDerivedFromNarrowestWidths();
583  return nwInterceptCache;
584 }
585 
586 
593  cacheQuantitiesDerivedFromNarrowestWidths();
594  return nwChisquareCache;
595 }
596 
597 
598 
608 
609  double value = TMath::Sqrt( pow(Q,2) + pow(U,2) ) / I;
610 
611  return value;
612 }
613 
614 
624 
625  double value = (TMath::ATan(U/Q)/2)*TMath::RadToDeg();
626 
627  return value;
628 
629 }
630 
631 
632 
642 
643  double value = TMath::Abs(V)/I;
644 
645  return value;
646 
647 }
648 
658 
659  double value = TMath::Sqrt(pow(Q,2) + pow(U,2) + pow(V,2))/I;
660 
661  return value;
662 
663 }
664 
674 
675  double value = TMath::Sqrt( pow(max_dQ,2) + pow(max_dU,2) ) / max_dI;
676 
677  return value;
678 }
679 
680 
690 
691  double value = (TMath::ATan(max_dU/max_dQ)/2)*TMath::RadToDeg();
692 
693  return value;
694 
695 }
696 
697 
698 
708 
709  double value = TMath::Abs(max_dV)/max_dI;
710 
711  return value;
712 
713 }
714 
724 
725  double value = TMath::Sqrt(pow(max_dQ,2) + pow(max_dU,2) + pow(max_dV,2))/max_dI;
726 
727  return value;
728 
729 }
730 
731 
732 
745 
746  // the first moment k=1, is stored in peakMoments[0]...
747  if(k <= 0){
748  return -1;
749  }
750  else if (k <= 5){
751  return peakMoments[k-1]/pow(peakMoments[1], 0.5*double(k));
752  }
753  else{
754  return -1;
755  }
756 }
757 
758 
759 
764  return AnitaGeomTool::Instance()->getPhiFromAnt(ant);
765 }
766 
767 
768 
769 
770 
775 
776  theta = -999;
777  phi = -999;
778  distance = -999;
779 
780  memset(mapHistoryVal,0,NUM_POLS*sizeof(Double_t));
781  memset(mapValue,0,NUM_POLS*sizeof(Double_t));
782 }
783 
784 
785 
786 
793 AnitaEventSummary::PayloadLocation::PayloadLocation(const Adu5Pat* pat){
794  update(pat);
795 }
796 
797 
804  if(pat){
805  latitude = pat->latitude;
806  longitude = pat->longitude;
807  altitude = pat->altitude;
808 
809  prevHeading = heading;
810  heading = pat->heading;
811 
812  }
813  else{
814  reset();
815  }
816 }
817 
818 
826 double AnitaEventSummary::PointingHypothesis::dPhiSource(const SourceHypothesis& source) const{
827  return dPhi(source.phi);
828 }
829 
830 
837  double dPhi = phi - phi2;
838  if(dPhi < -180){
839  dPhi += 360;
840  }
841  else if(dPhi >= 180){
842  dPhi -= 360;
843  }
844 
845  if(dPhi < -180 || dPhi >= 180){
846  std::cerr << "Warning in " << __PRETTY_FUNCTION__ << " dPhi = " << dPhi
847  << " is outside expected range, peak phi = " << phi << ", source phi = "
848  << phi2 << std::endl;
849  }
850 
851  return dPhi;
852 }
853 
854 
855 
856 
870 double AnitaEventSummary::PointingHypothesis::dTheta(double theta2, bool different_sign_conventions) const{
871  int factor = different_sign_conventions ? -1 : 1;
872  double dTheta = theta - factor*theta2; // + instead of - due to sign convention difference
873  return dTheta;
874 }
875 
876 
887 double AnitaEventSummary::PointingHypothesis::dThetaSource(const SourceHypothesis& source, bool different_sign_conventions) const{
888  return dTheta(source.theta, different_sign_conventions);
889 }
890 
891 
892 
899  // heading increases clockwise, payload phi increases anti-clockwise so we subtract it from heading.
900  const AnitaEventSummary* sum = getContainer(__PRETTY_FUNCTION__);
901  double bearing = -9999;
902  if(sum){
903  bearing = double(sum->anitaLocation.heading) - phi;
904 
905  bearing = bearing < 0 ? bearing + 360 : bearing;
906  bearing = bearing >= 360 ? bearing - 360 : bearing;
907 
908  if(bearing < 0 || bearing >= 360){
909  std::cerr << "Warning in " << __PRETTY_FUNCTION__ << ", peak bearing = "
910  << bearing << ", phi = " << phi << ", heading = " << sum->anitaLocation.heading << std::endl;
911  }
912  }
913  return bearing;
914 }
915 
922  // heading increases clockwise, payload phi increases anti-clockwise so we subtract it from heading.
923  Double_t b = bearing();
924  return b > 180 ? b - 360 : b;
925 }
926 
927 
928 
936  findTrainingPeak();
937  return fTrainingPol;
938 }
939 
940 int AnitaEventSummary::trainingPolAsInt() const {
941  findTrainingPeak();
942  return int(fTrainingPol);
943 }
944 
945 int AnitaEventSummary::trainingPeakInd() const {
946  findTrainingPeak();
947  return fTrainingPeakIndex;
948 }
949 
950 const AnitaEventSummary::PointingHypothesis& AnitaEventSummary::trainingPeak() const {
951  findTrainingPeak();
952  return peak[fTrainingPol][fTrainingPeakIndex];
953 }
954 
955 const AnitaEventSummary::WaveformInfo& AnitaEventSummary::trainingCoherent() const {
956  findTrainingPeak();
957  return coherent[fTrainingPol][fTrainingPeakIndex];
958 }
959 
960 const AnitaEventSummary::WaveformInfo& AnitaEventSummary::trainingDeconvolved() const {
961  findTrainingPeak();
962  return deconvolved[fTrainingPol][fTrainingPeakIndex];
963 }
964 
965 const AnitaEventSummary::WaveformInfo& AnitaEventSummary::trainingCoherentFiltered() const {
966  findTrainingPeak();
967  return coherent_filtered[fTrainingPol][fTrainingPeakIndex];
968 }
969 
970 const AnitaEventSummary::WaveformInfo& AnitaEventSummary::trainingDeconvolvedFiltered() const {
971  findTrainingPeak();
972  return deconvolved_filtered[fTrainingPol][fTrainingPeakIndex];
973 }
974 
975 
985 const AnitaEventSummary* AnitaEventSummary::PointingHypothesis::getContainer(const char* funcName) const{
986  if(!fContainer){
987  std::cerr << "Error in " << funcName << ", don't have access to AnitaEventSummary that contains me!\n"
988  << "To fix this error, try calling AnitaEventSummary()::update() as the first argument of the cuts in TTree::Draw(),\n"
989  << "Note: update() always returns true, so TTree::Draw(\"sum.peak[0][0].dPhiWais()\", "
990  << "\"sum.update() && TMath::Abs(sum.peak[0][0].dPhiWais()) < 5\") will select all events within 5 degrees of phi of WAIS.\n"
991  << std::endl;
992  }
993  return fContainer;
994 }
995 
996 
1003  if(TMath::Abs(hwAngle) < TMath::Abs(hwAngleXPol)){
1004  return hwAngle;
1005  }
1006  else{
1007  return hwAngleXPol;
1008  }
1009 }
1010 
1017  return (TMath::Abs(hwAngle) < TMath::Abs(hwAngleXPol));
1018 }
1019 
1020 
1021 
1022 
1023 double AnitaEventSummary::PointingHypothesis::dPhiWais() const {
1024  return getContainer(__PRETTY_FUNCTION__) ? dPhiSource(fContainer->wais) : dPhi(-9999); // should trigger warning message
1025 }
1026 double AnitaEventSummary::PointingHypothesis::dThetaWais(bool different_sign_conventions) const {
1027  return getContainer(__PRETTY_FUNCTION__) ? dThetaSource(fContainer->wais, different_sign_conventions) : dPhi(-9999); // should trigger warning message
1028 }
1029 double AnitaEventSummary::PointingHypothesis::dPhiSun() const {
1030  return getContainer(__PRETTY_FUNCTION__) ? dPhiSource(fContainer->sun) : dPhi(-9999); // should trigger warning message
1031 }
1032 double AnitaEventSummary::PointingHypothesis::dThetaSun(bool different_sign_conventions) const {
1033  return getContainer(__PRETTY_FUNCTION__) ? dThetaSource(fContainer->sun, different_sign_conventions) : dPhi(-9999); // should trigger warning message
1034 }
1035 double AnitaEventSummary::PointingHypothesis::dPhiLDB() const {
1036  return getContainer(__PRETTY_FUNCTION__) ? dPhiSource(fContainer->ldb) : dPhi(-9999); // should trigger warning message
1037 }
1038 double AnitaEventSummary::PointingHypothesis::dThetaLDB(bool different_sign_conventions) const {
1039  return getContainer(__PRETTY_FUNCTION__) ? dThetaSource(fContainer->ldb, different_sign_conventions) : dPhi(-9999); // should trigger warning message
1040 }
1041 double AnitaEventSummary::PointingHypothesis::dPhiMC() const {
1042  return getContainer(__PRETTY_FUNCTION__) && fContainer->mc.weight > 0 ? dPhiSource(fContainer->mc) : -9999;
1043 }
1044 double AnitaEventSummary::PointingHypothesis::dThetaMC(bool different_sign_conventions) const {
1045  return getContainer(__PRETTY_FUNCTION__) && fContainer->mc.weight > 0 ? dThetaSource(fContainer->mc, different_sign_conventions) : -9999;
1046 }
1047 double AnitaEventSummary::PointingHypothesis::dPhiTagged() const {
1048  return getContainer(__PRETTY_FUNCTION__) && fContainer->sourceFromTag() ? dPhiSource(*fContainer->sourceFromTag()) : -9999;
1049 }
1050 double AnitaEventSummary::PointingHypothesis::dThetaTagged(bool different_sign_conventions) const {
1051  return getContainer(__PRETTY_FUNCTION__) && fContainer->sourceFromTag() ? dThetaSource(*fContainer->sourceFromTag(), different_sign_conventions) : -9999;
1052 }
1053 
1054 
1055 
1056 Bool_t AnitaEventSummary::PointingHypothesis::closeToMC(double deltaPhiDeg, double deltaThetaDeg) const {
1057  return TMath::Abs(dThetaMC()) < deltaThetaDeg && TMath::Abs(dPhiMC()) < deltaPhiDeg;
1058 }
1059 Bool_t AnitaEventSummary::PointingHypothesis::closeToWais(double deltaPhiDeg, double deltaThetaDeg) const {
1060  return TMath::Abs(dThetaWais()) < deltaThetaDeg && TMath::Abs(dPhiWais()) < deltaPhiDeg;
1061 }
1062 Bool_t AnitaEventSummary::PointingHypothesis::closeToLDB(double deltaPhiDeg, double deltaThetaDeg) const {
1063  return TMath::Abs(dThetaLDB()) < deltaThetaDeg && TMath::Abs(dPhiLDB()) < deltaPhiDeg;
1064 }
1065 Bool_t AnitaEventSummary::PointingHypothesis::closeToSun(double deltaPhiDeg, double deltaThetaDeg) const {
1066  return TMath::Abs(dThetaSun()) < deltaThetaDeg && TMath::Abs(dPhiSun()) < deltaPhiDeg;
1067 }
1068 Bool_t AnitaEventSummary::PointingHypothesis::closeToTagged(double deltaPhiDeg, double deltaThetaDeg) const {
1069  const AnitaEventSummary* s = getContainer(__PRETTY_FUNCTION__);
1070  if(s){
1071  const AnitaEventSummary::SourceHypothesis* taggedSource = s->sourceFromTag();
1072  if(taggedSource){
1073  return TMath::Abs(dThetaSource(*taggedSource)) < deltaThetaDeg && TMath::Abs(dPhiSource(*taggedSource)) < deltaPhiDeg;
1074  }
1075  }
1076  return false;
1077 }
1078 
1079 
1080 
1081 void AnitaEventSummary::findHighestPeak() const {
1082  resetNonPersistent();
1083  if(fHighestPeakIndex < 0){ // then we've not done this before
1084  double highestVal = -1e99;
1085  for(int polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
1087  for(int peakInd=0; peakInd < nPeaks[polInd]; peakInd++){
1088  if(peak[polInd][peakInd].value > highestVal){
1089  highestVal = peak[polInd][peakInd].value;
1090  fHighestPeakIndex = peakInd;
1091  fHighestPol = pol;
1092  }
1093  }
1094  }
1095  }
1096 }
1097 
1098 
1104 void AnitaEventSummary::findMostImpulsive(int whichMetric) const {
1105  resetNonPersistent();
1106  if(fMostImpulsiveIndex < 0){ // then we've not done this before
1107  double highestVal = -1e99;
1108 
1109  for(int polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
1111  for(int peakInd=0; peakInd < nPeaks[polInd]; peakInd++){
1112 
1113  const WaveformInfo& wave = deconvolved_filtered[polInd][peakInd];
1114 
1115  // select which impulsivity measure to use...
1116  // 0 -> Cosmin's impulsivityMeasure
1117  // 1 -> Ben's fracPowerWindowGradient()
1118 
1119  // VERY IMPORTANT FACTOR OF -1 HERE
1120  // as lower == better for this metric
1121  // 2 -> Cosmins's impulsivityMeasure * peak.value
1122  double val;
1123  switch (whichMetric)
1124  {
1125  case 1:
1126  val = -1*wave.fracPowerWindowGradient();
1127  break;
1128  case 2:
1129  val = wave.impulsivityMeasure * peak[polInd][peakInd].value;
1130  break;
1131  case 0:
1132  default:
1133  val = wave.impulsivityMeasure;
1134  break;
1135  };
1136  if(val > highestVal){
1137  highestVal = val;
1138  fMostImpulsiveIndex = peakInd;
1139  fMostImpulsivePol = pol;
1140  }
1141  }
1142  }
1143 
1144  if(whichMetric != 2 && impulsivityFractionThreshold > 0. && impulsivityFractionThreshold < 1.)
1145  {
1146  int prevPol = int(fMostImpulsivePol);
1147  int prevInd = fMostImpulsiveIndex;
1148  const WaveformInfo& wave = deconvolved_filtered[prevPol][prevInd];
1149  double highestVal = whichMetric <= 0 ? wave.impulsivityMeasure : -1*wave.fracPowerWindowGradient();
1150  double bright = peak[prevPol][prevInd].value;
1151  for(int polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
1153  for(int peakInd=0; peakInd < nPeaks[polInd]; peakInd++)
1154  {
1155  if((peakInd == prevInd) && (prevPol == polInd)) continue;
1156  const WaveformInfo& wave2 = deconvolved_filtered[polInd][peakInd];
1157 
1158  double val = whichMetric <= 0 ? wave.impulsivityMeasure : -1*wave.fracPowerWindowGradient();
1159 
1160  if(val/highestVal < impulsivityFractionThreshold) continue;
1161  if(bright < peak[polInd][peakInd].value)
1162  {
1163  bright = peak[polInd][peakInd].value;
1164  fMostImpulsiveIndex = peakInd;
1165  fMostImpulsivePol = pol;
1166  }
1167  }
1168  }
1169  }
1170  }
1171 }
1172 
1173 
1180 const AnitaEventSummary::SourceHypothesis* AnitaEventSummary::sourceFromTag() const {
1181  switch(flags.pulser){
1182  case EventFlags::WAIS_V:
1183  case EventFlags::WAIS:
1184  // std::cerr << "wais" << std::endl;
1185  return &wais;
1186  case EventFlags::LDB:
1187  // std::cerr << "ldb" << std::endl;
1188  return &ldb;
1189  default:
1190  if(mc.weight > 0){
1191  // std::cerr << "mc" << std::endl;
1192  return &mc;
1193  }
1194  else{
1195  // std::cerr << "null" << std::endl;
1196  return NULL;
1197  }
1198  }
1199 }
1200 
1201 
1207 void AnitaEventSummary::findTrainingPeak() const {
1208  resetNonPersistent();
1209 
1210  if(fTrainingPeakIndex < 0){
1211  // then we've not done this before
1212  // and we need to figure out the peak of interest
1213 
1214  // Time to make this yet more complicated...
1215  // in the case we have a calPulser tagged event
1216  // return the peak closest to that source...
1217  const SourceHypothesis* peakOfInterest = sourceFromTag();
1218  if(peakOfInterest){
1219  // double lowestCloseFracPowWinGrad = DBL_MAX;
1220  double highestClosePeakVal = -1;
1221  for(int polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
1223  for(int peakInd=0; peakInd < nPeaks[polInd]; peakInd++){
1224  const double dPhiClose = 5.5;
1225  const double dThetaClose = 3.5;
1226  if(peak[polInd][peakInd].closeToTagged(dPhiClose, dThetaClose)){
1227  // double fpwg = deconvolved_filtered[polInd][peakInd].fracPowerWindowGradient();
1228  // if(fpwg < lowestCloseFracPowWinGrad){
1229  double mp = peak[polInd][peakInd].value;
1230  if(mp > highestClosePeakVal){
1231  // lowestCloseFracPowWinGrad = fpwg;
1232  highestClosePeakVal = mp;
1233  fTrainingPeakIndex = peakInd;
1234  fTrainingPol = pol;
1235  }
1236  }
1237  }
1238  }
1239  }
1240  if(fTrainingPeakIndex < 0){
1241  // didn't find one or no tagged source
1242  // so, just do highest peak in map
1243 
1244  findHighestPeak();
1245  fTrainingPeakIndex = fHighestPeakIndex;
1246  fTrainingPol = fHighestPol;
1247 
1248  // const int metric = 1;
1249  // findMostImpulsive(metric);
1250  // fTrainingPeakIndex = fMostImpulsiveIndex;
1251  // fTrainingPol = fMostImpulsivePol;
1252  }
1253  }
1254  }
1255 
1256 
1257 
1262  void AnitaEventSummary::resetNonPersistent() const{
1263  if(fLastEventNumber!=eventNumber){
1264  fHighestPeakIndex = -1;
1265  fHighestPol = AnitaPol::kNotAPol;
1266  fMostImpulsiveIndex = -1;
1267  fMostImpulsivePol = AnitaPol::kNotAPol;
1268  fTrainingPeakIndex = -1;
1269  fTrainingPol = AnitaPol::kNotAPol;
1270  for(Int_t polInd=0; polInd < AnitaPol::kNotAPol; polInd++){
1271  for(Int_t dir=0; dir < maxDirectionsPerPol; dir++){
1272  peak[polInd][dir].fContainer = const_cast<AnitaEventSummary*>(this); // Set non-persistent pointer to container in hacky fashion.
1273  coherent[polInd][dir].fContainer = const_cast<AnitaEventSummary*>(this); // Set non-persistent pointer to container in hacky fashion.
1274  coherent_filtered[polInd][dir].fContainer = const_cast<AnitaEventSummary*>(this); // Set non-persistent pointer to container in hacky fashion.
1275  deconvolved[polInd][dir].fContainer = const_cast<AnitaEventSummary*>(this); // Set non-persistent pointer to container in hacky fashion.
1276  deconvolved_filtered[polInd][dir].fContainer = const_cast<AnitaEventSummary*>(this); // Set non-persistent pointer to container in hacky fashion.
1277  }
1278  }
1279  fLastEventNumber=eventNumber;
1280  }
1281  }
1282 
1283  void AnitaEventSummary::setThresholdForMostImpulsive(double threshold)
1284  {
1285  impulsivityFractionThreshold = threshold;
1286  }
const WaveformInfo & highestCoherentFiltered() const
UShort_t l3TrigPatternH
Bit mask for l3 global triggers. eg. if the bit 1 (the lowest bit) is active it means that phi sector...
Double_t rfExitPos[5][3]
Position where the RF exits the ice- 5 iterations, 3 dimensions each.
WaveformInfo deconvolved[AnitaPol::kNotAPol][maxDirectionsPerPol]
Summaries of the (unfiltered) coherently summed waveforms, array index correponds to entry in peak[][...
Double_t payloadPhi
Phi of signal in payload coordinates (degrees)
Double_t weight
Weight assigned by icemc.
Double_t sourceLat
RF position when leaving the ice: Latitude (using icemc model)
const WaveformInfo & mostImpulsiveDeconvolvedFiltered(int whichMetric=0) const
UShort_t l3TrigPattern
Bit mask for l3 global triggers. eg. if the bit 1 (the lowest bit) is active it means that phi sector...
Adu5Pat – The ADU5 Position and Attitude Data.
Definition: Adu5Pat.h:26
Double_t instantaneousLinearPolAngle() const
PointingHypothesis peak[AnitaPol::kNotAPol][maxDirectionsPerPol]
Number of peaks stored in this AnitaEventSummary (might be less than maxDirectionsPerPol) ...
Int_t countChannelAboveThreshold(int threshold=100) const
void getThetaAndPhiWaveLDB(Double_t &thetaWave, Double_t &phiWave)
UInt_t getWaisDivideTriggerTimeNs() const
Gets the time of flight to Taylor Dome.
Float_t latitude
In degrees.
Definition: Adu5Pat.h:42
Int_t highestPolAsInt() const
Bool_t closeToMC(Double_t deltaPhiDeg, Double_t deltaThetaDeg) const
See AnitaEventSummary::sourceFromTag()
Double_t sourceLon
RF position when leaving the ice: Longitude (using icemc model)
Double_t sourceAlt
RF position when leaving the ice: Altitude (using icemc model)
MCTruth mc
Contains location of LDB cal pulser in map coordinates at time of event.
Float_t longitude
In degrees.
Definition: Adu5Pat.h:43
Double_t impulsivityMeasure
moments about Peak (1st - 5th moments)
Double_t standardizedPeakMoment(Int_t i) const
SourceHypothesis wais
Contains location of sun in map coordinates at time of event.
UInt_t getTriggerTimeNsFromSource(Double_t sourceLat, Double_t sourceLong, Double_t sourceAlt) const
Gets the time of flight to LDB camp.
AnitaPol::AnitaPol_t mostImpulsivePol(int whichMetric=0) const
value between 0 and 1, will find the brightest peak that is within threshold as impulsive as the most...
Double_t balloonPos[3]
Balloon position.
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...
const WaveformInfo & highestDeconvolved() const
RawAnitaHeader – The Raw ANITA Event Header.
void getThetaAndPhiWave(Double_t sourceLon, Double_t sourceLat, Double_t sourceAlt, Double_t &thetaWave, Double_t &phiWave)
Int_t getTriggerBitRF() const
EventFlags flags
Summaries of each channel&#39;s waveform.
USeful in for loops.
Int_t getTriggerBitADU5() const
Int_t run
Run number, assigned on ground.
UInt_t getLDBTriggerTimeNs() const
Gets the time of flight to Siple.
Double_t maxSNRAtTriggerV
Max SNR at trigger V-POL.
AnitaPol::AnitaPol_t highestPol() const
void setTriggerInfomation(const RawAnitaHeader *header)
const WaveformInfo & highestDeconvolvedFiltered() const
const PointingHypothesis & highestPeak() const
Double_t dTheta(Double_t theta, bool different_sign_conventions=false) const
const WaveformInfo & mostImpulsiveCoherent(int whichMetric=0) const
void getThetaAndPhiWaveWaisDivide(Double_t &thetaWave, Double_t &phiWave)
Float_t altitude
In metres.
Definition: Adu5Pat.h:44
AnitaEventSummary()
Reduced GPS data.
void getSunPosition(Double_t &phiDeg, Double_t &thetaDeg) const
Uses realTime, latitude, longitude to calculate the sun&#39;s position.
AnitaPol::AnitaPol_t trainingPol() const
Return the weight of the event, always returns 1 for data, the weight from MCTruth otherwise...
Double_t dPhi(Double_t phi) const
the average of channel peaks in this direction
TruthAnitaEvent – The Truth ANITA Event.
Int_t highestPeakInd() const
Int_t getTriggerBitSoftExt() const
SourceHypothesis ldb
Contains location of WAIS divide cal pulser in map coordinates at time of event.
As UsefulAnitaEvent is to RawAnitaEvent, UsefulAdu5Pat is to Adu5Pat. Well not quite as useful but yo...
Definition: UsefulAdu5Pat.h:39
const WaveformInfo & mostImpulsiveCoherentFiltered(int whichMetric=0) const
static Int_t getPhiFromAnt(Int_t ant)
get phi from ant
Stores information about a coherently summed waveform (filtered/unfiltered/deconvolved) The coherent ...
UInt_t realTime
Event number.
ChannelInfo channels[AnitaPol::kNotAPol][NUM_SEAVEYS]
Summaries of the filtered, de-dispersed, coherently summed waveforms, array index correponds to entry...
Double_t nuDir[3]
Neutrino direction.
const PointingHypothesis & mostImpulsivePeak(int whichMetric=0) const
Double_t nuMom
Neutrino momentum.
Int_t mostImpulsiveInd(int whichMetric=0) const
Double_t payloadTheta
Theta of signal in payload coordinates (degrees)
Int_t mostImpulsivePolAsInt(int whichMetric=0) const
Double_t value
peak theta, degrees
Common analysis format between UCorrelator and Acclaim.
Double_t dThetaTagged(bool different_sign_conventions=true) const
See AnitaEventSummary::sourceFromTag()
const WaveformInfo & highestCoherent() const
Float_t heading
0 is facing north, 180 is facing south
Definition: Adu5Pat.h:45
Double_t maxSNRAtTriggerH
Max SNR at trigger H-POL.
UInt_t realTime
unixTime of readout
void getThetaAndPhiWaveOfRayAtInfinity(const TVector3 &p0, const TVector3 &v0, Double_t &thetaWave, Double_t &phiWave, Bool_t plus_infinity=true, Double_t eps=0.00001 *TMath::DegToRad(), Double_t step=10e7, TVector3 *testPosition=0) const
Int_t getTriggerBitG12() const
const WaveformInfo & mostImpulsiveDeconvolved(int whichMetric=0) const
enum AnitaPol::EAnitaPol AnitaPol_t
Polarisation enumeration.
static AnitaGeomTool * Instance(int anita_version=0)
Instance generator. If version_number == 0, uses AnitaVersion::get();.
AnitaGeomTool – The ANITA Geometry Tool.
Definition: AnitaGeomTool.h:48
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) ...
Double_t nuPos[3]
Neutrino position.
WaveformInfo deconvolved_filtered[AnitaPol::kNotAPol][maxDirectionsPerPol]
Summaries of the filtered, coherently summed waveforms, array index correponds to entry in peak[][]...
void reset()
a history of the interferometric map value for the source location
void setSourceInformation(UsefulAdu5Pat *pat, const TruthAnitaEvent *truth=0)