1 #include "AnitaEventSummary.h" 3 #include "RawAnitaHeader.h" 4 #include "UsefulAdu5Pat.h" 5 #include "TruthAnitaEvent.h" 14 const double C_IN_M_NS = 0.299792;
15 static double impulsivityFractionThreshold = -1;
62 : anitaLocation(dynamic_cast<
Adu5Pat*>(pat))
85 fLastEventNumber = -1;
94 for(Int_t dir=0; dir < maxDirectionsPerPol; dir++)
103 for(Int_t ant=0; ant < 48; ant++){
110 flags.pulser = EventFlags::NONE;
141 return int(fHighestPol);
153 return fHighestPeakIndex;
166 return peak[fHighestPol][fHighestPeakIndex];
178 return coherent[fHighestPol][fHighestPeakIndex];
190 return deconvolved[fHighestPol][fHighestPeakIndex];
235 findMostImpulsive(whichMetric);
236 return fMostImpulsivePol;
248 findMostImpulsive(whichMetric);
249 return int(fMostImpulsivePol);
261 findMostImpulsive(whichMetric);
262 return fMostImpulsiveIndex;
275 findMostImpulsive(whichMetric);
276 return peak[fMostImpulsivePol][fMostImpulsiveIndex];
288 findMostImpulsive(whichMetric);
289 return coherent[fMostImpulsivePol][fMostImpulsiveIndex];
301 findMostImpulsive(whichMetric);
302 return deconvolved[fMostImpulsivePol][fMostImpulsiveIndex];
316 findMostImpulsive(whichMetric);
329 findMostImpulsive(whichMetric);
343 for(Int_t ant=0; ant < 48; ant++){
344 if (
channels[polInd][ant].rms>threshold){
363 flags.isVPolTrigger = 0;
364 flags.isHPolTrigger = 0;
367 for(Int_t phi=0; phi<NUM_PHI; phi++){
368 Int_t phi2 = (phi+1)%NUM_PHI;
377 if(trigBit > 0 && trigBit2 > 0){
378 flags.isVPolTrigger = 1;
384 if(trigBitH > 0 && trigBitH2 > 0){
385 flags.isHPolTrigger = 1;
412 sun.distance = 150e9;
415 wais.theta *= 180/ TMath::Pi();
416 wais.phi *= 180/ TMath::Pi();
421 ldb.theta *= 180/ TMath::Pi();
422 ldb.phi *= 180/ TMath::Pi();
428 mc.theta*=TMath::RadToDeg();
429 mc.phi*=TMath::RadToDeg();
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);
445 mc.interactionTheta*=TMath::RadToDeg();
446 mc.interactionPhi*=TMath::RadToDeg();
449 Double_t rfExitPos[3];
453 geom->getLatLonAltFromCartesian(rfExitPos,
mc.rfExitLat,
mc.rfExitLon,
mc.rfExitAlt);
455 mc.rfExitTheta*=TMath::RadToDeg();
456 mc.rfExitPhi*=TMath::RadToDeg();
459 Double_t balloonPos[3];
463 geom->getLatLonAltFromCartesian(balloonPos,
mc.balloonLat,
mc.balloonLon,
mc.balloonAlt);
474 mc.theta*=TMath::RadToDeg();
475 mc.phi*=TMath::RadToDeg();
486 mc.nuTheta *= TMath::RadToDeg();
487 mc.nuPhi *= TMath::RadToDeg();
505 nuDirection.SetXYZ(0,0,0);
517 void AnitaEventSummary::WaveformInfo::cacheQuantitiesDerivedFromNarrowestWidths()
const{
518 if(!(fContainer && fContainer->eventNumber == fLastEventNumberCache)){
522 fracPowerWindow[i] = fracPowerWindowEnds[i] - fracPowerWindowBegins[i];
532 const double gradDenom = 0.1;
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;
540 nwInterceptCache = nwMeanCache - nwGradCache*0.3;
543 nwChisquareCache = 0;
545 double f = 0.1*(i+1);
546 double y = nwGradCache*f + nwInterceptCache;
547 double dy = (y - fracPowerWindow[i]);
548 nwChisquareCache += dy*dy;
560 cacheQuantitiesDerivedFromNarrowestWidths();
571 cacheQuantitiesDerivedFromNarrowestWidths();
582 cacheQuantitiesDerivedFromNarrowestWidths();
583 return nwInterceptCache;
593 cacheQuantitiesDerivedFromNarrowestWidths();
594 return nwChisquareCache;
609 double value = TMath::Sqrt( pow(Q,2) + pow(U,2) ) / I;
625 double value = (TMath::ATan(U/Q)/2)*TMath::RadToDeg();
643 double value = TMath::Abs(V)/I;
659 double value = TMath::Sqrt(pow(Q,2) + pow(U,2) + pow(V,2))/I;
675 double value = TMath::Sqrt( pow(max_dQ,2) + pow(max_dU,2) ) / max_dI;
691 double value = (TMath::ATan(max_dU/max_dQ)/2)*TMath::RadToDeg();
709 double value = TMath::Abs(max_dV)/max_dI;
725 double value = TMath::Sqrt(pow(max_dQ,2) + pow(max_dU,2) + pow(max_dV,2))/max_dI;
751 return peakMoments[k-1]/pow(peakMoments[1], 0.5*
double(k));
780 memset(mapHistoryVal,0,NUM_POLS*
sizeof(Double_t));
781 memset(mapValue,0,NUM_POLS*
sizeof(Double_t));
793 AnitaEventSummary::PayloadLocation::PayloadLocation(
const Adu5Pat* pat){
809 prevHeading = heading;
826 double AnitaEventSummary::PointingHypothesis::dPhiSource(
const SourceHypothesis& source)
const{
827 return dPhi(source.phi);
837 double dPhi = phi - phi2;
841 else if(dPhi >= 180){
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;
871 int factor = different_sign_conventions ? -1 : 1;
872 double dTheta = theta - factor*theta2;
887 double AnitaEventSummary::PointingHypothesis::dThetaSource(
const SourceHypothesis& source,
bool different_sign_conventions)
const{
888 return dTheta(source.theta, different_sign_conventions);
901 double bearing = -9999;
903 bearing = double(sum->anitaLocation.heading) - phi;
905 bearing = bearing < 0 ? bearing + 360 : bearing;
906 bearing = bearing >= 360 ? bearing - 360 : bearing;
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;
923 Double_t b = bearing();
924 return b > 180 ? b - 360 : b;
940 int AnitaEventSummary::trainingPolAsInt()
const {
942 return int(fTrainingPol);
945 int AnitaEventSummary::trainingPeakInd()
const {
947 return fTrainingPeakIndex;
952 return peak[fTrainingPol][fTrainingPeakIndex];
957 return coherent[fTrainingPol][fTrainingPeakIndex];
962 return deconvolved[fTrainingPol][fTrainingPeakIndex];
985 const AnitaEventSummary* AnitaEventSummary::PointingHypothesis::getContainer(
const char* funcName)
const{
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" 1003 if(TMath::Abs(hwAngle) < TMath::Abs(hwAngleXPol)){
1017 return (TMath::Abs(hwAngle) < TMath::Abs(hwAngleXPol));
1023 double AnitaEventSummary::PointingHypothesis::dPhiWais()
const {
1024 return getContainer(__PRETTY_FUNCTION__) ? dPhiSource(fContainer->wais) : dPhi(-9999);
1026 double AnitaEventSummary::PointingHypothesis::dThetaWais(
bool different_sign_conventions)
const {
1027 return getContainer(__PRETTY_FUNCTION__) ? dThetaSource(fContainer->wais, different_sign_conventions) : dPhi(-9999);
1029 double AnitaEventSummary::PointingHypothesis::dPhiSun()
const {
1030 return getContainer(__PRETTY_FUNCTION__) ? dPhiSource(fContainer->sun) : dPhi(-9999);
1032 double AnitaEventSummary::PointingHypothesis::dThetaSun(
bool different_sign_conventions)
const {
1033 return getContainer(__PRETTY_FUNCTION__) ? dThetaSource(fContainer->sun, different_sign_conventions) : dPhi(-9999);
1035 double AnitaEventSummary::PointingHypothesis::dPhiLDB()
const {
1036 return getContainer(__PRETTY_FUNCTION__) ? dPhiSource(fContainer->ldb) : dPhi(-9999);
1038 double AnitaEventSummary::PointingHypothesis::dThetaLDB(
bool different_sign_conventions)
const {
1039 return getContainer(__PRETTY_FUNCTION__) ? dThetaSource(fContainer->ldb, different_sign_conventions) : dPhi(-9999);
1041 double AnitaEventSummary::PointingHypothesis::dPhiMC()
const {
1042 return getContainer(__PRETTY_FUNCTION__) && fContainer->mc.weight > 0 ? dPhiSource(fContainer->mc) : -9999;
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;
1047 double AnitaEventSummary::PointingHypothesis::dPhiTagged()
const {
1048 return getContainer(__PRETTY_FUNCTION__) && fContainer->sourceFromTag() ? dPhiSource(*fContainer->sourceFromTag()) : -9999;
1051 return getContainer(__PRETTY_FUNCTION__) && fContainer->sourceFromTag() ? dThetaSource(*fContainer->sourceFromTag(), different_sign_conventions) : -9999;
1057 return TMath::Abs(dThetaMC()) < deltaThetaDeg && TMath::Abs(dPhiMC()) < deltaPhiDeg;
1059 Bool_t AnitaEventSummary::PointingHypothesis::closeToWais(
double deltaPhiDeg,
double deltaThetaDeg)
const {
1060 return TMath::Abs(dThetaWais()) < deltaThetaDeg && TMath::Abs(dPhiWais()) < deltaPhiDeg;
1062 Bool_t AnitaEventSummary::PointingHypothesis::closeToLDB(
double deltaPhiDeg,
double deltaThetaDeg)
const {
1063 return TMath::Abs(dThetaLDB()) < deltaThetaDeg && TMath::Abs(dPhiLDB()) < deltaPhiDeg;
1065 Bool_t AnitaEventSummary::PointingHypothesis::closeToSun(
double deltaPhiDeg,
double deltaThetaDeg)
const {
1066 return TMath::Abs(dThetaSun()) < deltaThetaDeg && TMath::Abs(dPhiSun()) < deltaPhiDeg;
1068 Bool_t AnitaEventSummary::PointingHypothesis::closeToTagged(
double deltaPhiDeg,
double deltaThetaDeg)
const {
1073 return TMath::Abs(dThetaSource(*taggedSource)) < deltaThetaDeg && TMath::Abs(dPhiSource(*taggedSource)) < deltaPhiDeg;
1081 void AnitaEventSummary::findHighestPeak()
const {
1082 resetNonPersistent();
1083 if(fHighestPeakIndex < 0){
1084 double highestVal = -1e99;
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;
1104 void AnitaEventSummary::findMostImpulsive(
int whichMetric)
const {
1105 resetNonPersistent();
1106 if(fMostImpulsiveIndex < 0){
1107 double highestVal = -1e99;
1111 for(
int peakInd=0; peakInd <
nPeaks[polInd]; peakInd++){
1123 switch (whichMetric)
1129 val = wave.impulsivityMeasure *
peak[polInd][peakInd].
value;
1133 val = wave.impulsivityMeasure;
1136 if(val > highestVal){
1138 fMostImpulsiveIndex = peakInd;
1139 fMostImpulsivePol = pol;
1144 if(whichMetric != 2 && impulsivityFractionThreshold > 0. && impulsivityFractionThreshold < 1.)
1146 int prevPol = int(fMostImpulsivePol);
1147 int prevInd = fMostImpulsiveIndex;
1149 double highestVal = whichMetric <= 0 ? wave.
impulsivityMeasure : -1*wave.fracPowerWindowGradient();
1150 double bright =
peak[prevPol][prevInd].
value;
1153 for(
int peakInd=0; peakInd <
nPeaks[polInd]; peakInd++)
1155 if((peakInd == prevInd) && (prevPol == polInd))
continue;
1158 double val = whichMetric <= 0 ? wave.
impulsivityMeasure : -1*wave.fracPowerWindowGradient();
1160 if(val/highestVal < impulsivityFractionThreshold)
continue;
1161 if(bright <
peak[polInd][peakInd].value)
1164 fMostImpulsiveIndex = peakInd;
1165 fMostImpulsivePol = pol;
1181 switch(
flags.pulser){
1182 case EventFlags::WAIS_V:
1183 case EventFlags::WAIS:
1186 case EventFlags::LDB:
1207 void AnitaEventSummary::findTrainingPeak()
const {
1208 resetNonPersistent();
1210 if(fTrainingPeakIndex < 0){
1217 const SourceHypothesis* peakOfInterest = sourceFromTag();
1220 double highestClosePeakVal = -1;
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)){
1229 double mp =
peak[polInd][peakInd].
value;
1230 if(mp > highestClosePeakVal){
1232 highestClosePeakVal = mp;
1233 fTrainingPeakIndex = peakInd;
1240 if(fTrainingPeakIndex < 0){
1245 fTrainingPeakIndex = fHighestPeakIndex;
1246 fTrainingPol = fHighestPol;
1262 void AnitaEventSummary::resetNonPersistent()
const{
1264 fHighestPeakIndex = -1;
1266 fMostImpulsiveIndex = -1;
1268 fTrainingPeakIndex = -1;
1271 for(Int_t dir=0; dir < maxDirectionsPerPol; dir++){
1283 void AnitaEventSummary::setThresholdForMostImpulsive(
double threshold)
1285 impulsivityFractionThreshold = threshold;
const WaveformInfo & highestCoherentFiltered() const
void update(const Adu5Pat *pat)
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
Adu5Pat – The ADU5 Position and Attitude Data.
PointingHypothesis peak[AnitaPol::kNotAPol][maxDirectionsPerPol]
Number of peaks stored in this AnitaEventSummary (might be less than maxDirectionsPerPol) ...
Int_t countChannelAboveThreshold(int threshold=100) const
Double_t dPhiNorth() 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.
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.
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
void getThetaAndPhiWave(Double_t sourceLon, Double_t sourceLat, Double_t sourceAlt, Double_t &thetaWave, Double_t &phiWave)
EventFlags flags
Summaries of each channel's waveform.
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
Bool_t absHwAngleLessThanAbsHwAngleXPol() 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.
AnitaEventSummary()
Reduced GPS data.
void getSunPosition(Double_t &phiDeg, Double_t &thetaDeg) const
Uses realTime, latitude, longitude to calculate the sun'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
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...
const WaveformInfo & mostImpulsiveCoherentFiltered(int whichMetric=0) const
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 minAbsHwAngle() 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
Double_t maxSNRAtTriggerH
Max SNR at trigger H-POL.
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
const WaveformInfo & mostImpulsiveDeconvolved(int whichMetric=0) const
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) ...
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)