1 #include "AnalysisReco.h" 2 #include "InterferometricMap.h" 3 #include "InterferometryCache.h" 4 #include "AcclaimFilters.h" 5 #include "ResponseManager.h" 6 #include "NoiseMonitor.h" 9 #include "TGraphInteractive.h" 10 #include "ImpulsivityMeasure.h" 11 #include "TPaveText.h" 30 if(fSpawnedCrossCorrelator && (fCrossCorr !=
nullptr)){
34 nicelyDeleteInternalFilteredEvents();
39 if(fEvMin !=
nullptr){
43 if(fEvMinDeco !=
nullptr){
47 if(fEvDeco !=
nullptr){
62 std::vector<double>& I,
63 std::vector<double>& Q,
64 std::vector<double>& U,
65 std::vector<double>& V) {
80 Int_t peakPhiSector = h->getPeakPhiSector();
81 const std::vector<Int_t>& theAnts = phiSectorToCoherentAnts(peakPhiSector);
83 Double_t peak, phiDeg, thetaDeg;
84 h->getPeakInfo(peak, phiDeg, thetaDeg);
85 Double_t largestPeakToPeak = 0;
86 AnalysisWaveform* coherentWave = coherentlySum(fEv, pol, theAnts, phiDeg, thetaDeg, &largestPeakToPeak);
89 if(waveStore[0] !=
nullptr){
92 waveStore[0] = coherentWave;
97 for(
int ant : theAnts){
99 if(noiseMonitor !=
nullptr){
103 static int warnCount = 0;
105 thisRMS = gr->GetRMS(2);
106 const int numWarnings = 10;
107 if(warnCount < numWarnings){
108 std::cerr <<
"Warning ("<< warnCount + 1 <<
"/" << numWarnings <<
") in " 109 << __PRETTY_FUNCTION__ <<
", getting RMS from entire waveform rather than NoiseMonitor." 110 <<
" this many overestimate the noise... thisRMS = " << thisRMS << std::endl;
117 noise /= theAnts.size();
119 info.snr = largestPeakToPeak/(2*noise);
126 info.peakHilbert = TMath::MaxElement(grHilbert->GetN(), grHilbert->GetY());
129 info.peakVal = TMath::MaxElement(gr->GetN(), gr->GetY());
132 Double_t largestPeakToPeakXPol = 0;
133 AnalysisWaveform* xPolCoherentWave = coherentlySum(fEv, xPol, theAnts, phiDeg, thetaDeg, &largestPeakToPeakXPol, &gr->GetX()[0]);
136 if(waveStore[1] !=
nullptr){
139 waveStore[1] = xPolCoherentWave;
142 info.xPolPeakHilbert = TMath::MaxElement(grHilbertX->GetN(), grHilbertX->GetY());
145 info.xPolPeakVal = TMath::MaxElement(grX->GetN(), grX->GetY());
154 const TGraphAligned* grH_hilbert = hWave->hilbertTransform()->even();
165 FFTtools::stokesParameters(grH->GetN(),
166 grH->GetY(), grH_hilbert->GetY(),
167 grV->GetY(), grV_hilbert->GetY(),
168 &info.I, &info.Q, &info.U, &info.V,
169 &info.
max_dI, &info.max_dQ,&info.max_dU,&info.max_dV,
173 if(fInstantaneousStokes > 0){
175 I.resize(grH->GetN());
176 Q.resize(grH->GetN());
177 U.resize(grH->GetN());
178 V.resize(grH->GetN());
180 FFTtools::stokesParameters(grH->GetN(),
181 grH->GetY(), grH_hilbert->GetY(),
182 grV->GetY(), grV_hilbert->GetY(),
183 &info.I, &info.Q, &info.U, &info.V,
184 I.data(), Q.data(), U.data(), V.data(),
191 info.
totalPower = RootTools::getTimeIntegratedPower(coherentWave->
even());
207 int maxIndex = std::find(grHilbert->GetY(), grHilbert->GetY() + grHilbert->GetN(), info.peakHilbert) - grHilbert->GetY();
208 if(maxIndex >= grHilbert->GetN()){
209 std::cerr <<
"Error in " << __PRETTY_FUNCTION__
210 <<
", unable to find time of Hilbert envelope peak using std::find()." 211 <<
"peakHilbert = " << info.peakHilbert <<
", numPoints = " << grHilbert->GetN()
212 <<
", maxIndex = " << maxIndex << std::endl;
214 info.
peakTime = grHilbert->GetX()[maxIndex];
216 grHilbert->getMoments(
sizeof(info.peakMoments)/
sizeof(
double), info.
peakTime, info.peakMoments);
219 info.
impulsivityMeasure = impulsivity::impulsivityMeasure(coherentWave,
nullptr, maxIndex,
true);
222 const double powerFraction = (w+1)*0.1;
223 std::pair<double, double> window = RootTools::findSmallestWindowContainingFracOfPower(grHilbert, powerFraction);
225 info.fracPowerWindowBegins[w] = window.first;
226 info.fracPowerWindowEnds[w] = window.second;
241 if(fFillSpectrumInfo != 0){
242 const double maxFreqIfIHadNotIntepolated = FancyFFTs::getNumFreqs(NUM_SAMP)*(1./(NOMINAL_SAMPLING_DELTAT*NUM_SAMP));
243 const double df = coherentWave->
deltaF();
244 int numGoodFreqBins = floor(maxFreqIfIHadNotIntepolated/df);
249 if(numGoodFreqBins > grPow->GetN()){
250 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" for run " << fCurrentRun <<
", eventNumber " << fCurrentEventNumber
251 <<
", expected at least " << numGoodFreqBins <<
" frequency bins, only got " << grPow->GetN()
252 <<
". Did you downsample the coherently summed waveform?" << std::endl;
253 numGoodFreqBins = grPow->GetN();
257 for(
int i=1; i < numGoodFreqBins-1; i++){
258 if(grPow->GetY()[i] > grPow->GetY()[i-i] && grPow->GetY()[i] > grPow->GetY()[i+i] ){
259 grMaxima.SetPoint(grMaxima.GetN(), grPow->GetX()[i], grPow->GetY()[i]);
263 if(grPow->GetX()[i] >= maxFreqIfIHadNotIntepolated){
270 grMaxima.Sort(TGraph::CompareY,
false);
274 if(i < grMaxima.GetN()){
276 info.peakPower[i] = grMaxima.GetY()[i];
277 info.peakFrequency[i] = grMaxima.GetX()[i];
281 info.peakPower[i] = 0;
282 info.peakFrequency[i] = 0;
288 const int firstSlopeBin = TMath::Nint(fSlopeFitStartFreqGHz/df);
289 const int lastSlopeBin = TMath::Nint(fSlopeFitEndFreqGHz/df);
290 const int numSlopeBins = lastSlopeBin - firstSlopeBin;
292 const double mean_f = TMath::Mean(numSlopeBins, &grPow_db->GetX()[firstSlopeBin]);
293 const double mean_pow_db = TMath::Mean(numSlopeBins, &grPow_db->GetY()[firstSlopeBin]);
295 double gradNumerator = 0;
296 double gradDenominator = 0;
297 for(
int i=firstSlopeBin; i < lastSlopeBin; i++){
298 double dx = grPow_db->GetX()[i] - mean_f;
299 double dy = grPow_db->GetY()[i] - mean_pow_db;
301 gradNumerator += dy*dx;
302 gradDenominator += dx*dx;
305 if(gradDenominator <= 0){
306 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" for run " 307 << fCurrentRun <<
", eventNumber " << fCurrentEventNumber
308 <<
", got gradDenominator = " << gradDenominator <<
" will get NaN or Inf..." << std::endl;
310 info.spectrumSlope = gradNumerator/gradDenominator;
311 info.spectrumIntercept = mean_pow_db - info.spectrumSlope*mean_f;
329 for(
int ant=0; ant<NUM_SEAVEYS; ant++){
334 sum->channels[polInd][ant].rms = gr->GetRMS();
335 sum->channels[polInd][ant].avgPower = RootTools::getTimeIntegratedPower(gr);
336 Double_t maxY, maxX, minY, minX;
337 RootTools::getLocalMaxToMin(gr, maxY, maxX, minY, minX);
338 sum->channels[polInd][ant].snr = (maxY - minY)/sum->channels[polInd][ant].rms;
339 sum->channels[polInd][ant].peakHilbert = TMath::MaxElement(he->GetN(), he->GetY());
352 if(fCrossCorr ==
nullptr){
354 fSpawnedCrossCorrelator =
true;
355 fDtCache.init(fCrossCorr,
this);
361 nicelyDeleteInternalFilteredEvents();
366 if(fFillChannelInfo != 0){
367 fillChannelInfo(fEv, sum);
372 chooseAntennasForCoherentlySumming(fCoherentDeltaPhi);
378 fCrossCorr->correlateEvent(fEv, pol);
383 std::vector<Double_t> coarseMapPeakValues;
384 std::vector<Double_t> coarseMapPeakPhiDegs;
385 std::vector<Double_t> coarseMapPeakThetaDegs;
386 coarseMaps[pol]->findPeakValues(fNumPeaks, coarseMapPeakValues, coarseMapPeakPhiDegs, coarseMapPeakThetaDegs);
387 coarseMaps[pol]->addGpsInfo(fEv->
getGPS());
388 coarseMaps[pol]->addTruthInfo(truth);
390 sum->nPeaks[pol] = fNumPeaks;
392 for(Int_t peakInd=0; peakInd < fNumPeaks; peakInd++){
393 reconstructZoom(pol, peakInd, coarseMapPeakPhiDegs.at(peakInd), coarseMapPeakThetaDegs.at(peakInd));
399 h->addGpsInfo(fEv->
getGPS());
400 h->addTruthInfo(truth);
403 h->getPeakInfo(sum->peak[pol][peakInd].value,
404 sum->peak[pol][peakInd].phi,
405 sum->peak[pol][peakInd].theta,
406 sum->peak[pol][peakInd].chisq);
409 sum->peak[pol][peakInd].dphi_rough = sum->peak[pol][peakInd].phi - coarseMapPeakPhiDegs.at(peakInd);
410 sum->peak[pol][peakInd].dtheta_rough = sum->peak[pol][peakInd].theta - coarseMapPeakThetaDegs.at(peakInd);
413 sum->peak[pol][peakInd].phi_separation = RootTools::getDeltaAngleDeg(sum->peak[pol][peakInd].phi, sum->peak[pol][0].phi);
416 setTriggerInfoFromPeakPhi(fEv->
getHeader(), pol, h->getPeakPhiSector(), sum->peak[pol][peakInd]);
424 fillWaveformInfo(pol, peakInd, sum->coherent_filtered[pol][peakInd], fEv, fCoherentFiltered[pol][peakInd], h, noiseMonitor,
425 f_dICoherentFiltered[pol][peakInd], f_dQCoherentFiltered[pol][peakInd],
426 f_dUCoherentFiltered[pol][peakInd], f_dVCoherentFiltered[pol][peakInd]);
427 fillWaveformInfo(pol, peakInd, sum->deconvolved_filtered[pol][peakInd], fEvDeco, fDeconvolvedFiltered[pol][peakInd], h, noiseMonitor,
428 f_dIDeconvolvedFiltered[pol][peakInd], f_dQDeconvolvedFiltered[pol][peakInd],
429 f_dUDeconvolvedFiltered[pol][peakInd], f_dVDeconvolvedFiltered[pol][peakInd]);
431 h->setResolutionEstimateFromWaveformSNR(sum->deconvolved_filtered[pol][peakInd].snr);
433 if(fFillUnfiltered != 0){
434 std::vector<double> dI ,dQ ,dU ,dV;
435 fillWaveformInfo(pol, peakInd, sum->coherent[pol][peakInd], fEvMin, fCoherent[pol][peakInd], h, noiseMonitor, dI, dQ, dU, dV);
436 fillWaveformInfo(pol, peakInd, sum->deconvolved[pol][peakInd], fEvMinDeco, fDeconvolved[pol][peakInd], h, noiseMonitor, dI, dQ, dU, dV);
447 if(fEv->
getGPS() !=
nullptr){
450 if(sum->peak[pol][peakInd].theta < 0){
451 Double_t phiWave = TMath::DegToRad()*sum->peak[pol][peakInd].phi;
452 Double_t thetaWave = -1*TMath::DegToRad()*sum->peak[pol][peakInd].theta;
454 success = usefulPat.traceBackToContinent3(phiWave, thetaWave,
455 &sum->peak[pol][peakInd].longitude,
456 &sum->peak[pol][peakInd].latitude,
457 &sum->peak[pol][peakInd].altitude,
458 &sum->peak[pol][peakInd].theta_adjustment_needed);
461 sum->peak[pol][peakInd].longitude = -9999;
462 sum->peak[pol][peakInd].latitude = -9999;
463 sum->peak[pol][peakInd].altitude = -9999;
464 sum->peak[pol][peakInd].theta_adjustment_needed = -9999;
465 sum->peak[pol][peakInd].distanceToSource = -9999;
468 sum->peak[pol][peakInd].distanceToSource = SPEED_OF_LIGHT_NS*usefulPat.getTriggerTimeNsFromSource(sum->peak[pol][peakInd].latitude,
469 sum->peak[pol][peakInd].longitude,
470 sum->peak[pol][peakInd].altitude);
486 const double bandsLowGHz[AnitaEventSummary::numBlastPowerBands] = {0.15-1e-10, 0};
487 const double bandsHighGHz[AnitaEventSummary::numBlastPowerBands] = {0.25+1e-10, 999};
490 for(
int band=0; band < AnitaEventSummary::numBlastPowerBands; band++){
491 flags.middleOrBottomPower[band] = 0;
492 flags.middleOrBottomAnt[band] = -1;
493 flags.middleOrBottomPol[band] = 2;
494 flags.topPower[band] = 0;
499 for(UInt_t phi=0; phi < NUM_PHI; phi++){
501 Int_t ant = ring*NUM_PHI + phi;
505 const double df_GHz = grPow->GetX()[1] - grPow->GetX()[0];
507 Double_t powThisAnt[AnitaEventSummary::numBlastPowerBands] = {0};
509 for(
int i=0; i < grPow->GetN(); i++){
510 const double f_GHz = grPow->GetX()[i];
511 for(
int band=0; band < AnitaEventSummary::numBlastPowerBands; band++){
512 if(f_GHz >= bandsLowGHz[band] && f_GHz < bandsHighGHz[band]){
513 powThisAnt[band] +=grPow->GetY()[i]*df_GHz;
518 for(
int band=0; band < AnitaEventSummary::numBlastPowerBands; band++){
519 if(powThisAnt[band] > flags.middleOrBottomPower[band]){
520 flags.middleOrBottomPower[band] = powThisAnt[band];
521 flags.middleOrBottomAnt[band] = ant;
522 flags.middleOrBottomPol[band] = polInd;
530 for(
int band=0; band < AnitaEventSummary::numBlastPowerBands; band++){
531 int ant = flags.middleOrBottomAnt[band] % NUM_PHI;
535 const double df_GHz = grPow->GetX()[1] - grPow->GetX()[0];
537 for(
int i=0; i < grPow->GetN(); i++){
538 const double f_GHz = grPow->GetX()[i];
539 for(
int band=0; band < AnitaEventSummary::numBlastPowerBands; band++){
540 if(f_GHz >= bandsLowGHz[band] && f_GHz < bandsHighGHz[band]){
541 flags.topPower[band] +=grPow->GetY()[i]*df_GHz;
562 for(
int phi=0; phi < NUM_PHI; phi++){
564 if(phiWasTriggered > 0){
566 double dPhi = RootTools::getDeltaAngleDeg(peak.phi, phiSectorPhi);
567 if(TMath::Abs(dPhi) < TMath::Abs(peak.
hwAngle)){
572 if(phiWasTriggeredXPol > 0){
574 double dPhi = RootTools::getDeltaAngleDeg(peak.phi, phiSectorPhi);
575 if(TMath::Abs(dPhi) < TMath::Abs(peak.
hwAngleXPol)){
584 peak.
masked = (header->isInPhiMaskOffline(peakPhiSector, pol) != 0) || (header->isInL1MaskOffline(peakPhiSector, pol) != 0);
585 peak.
masked_xpol = (header->isInPhiMaskOffline(peakPhiSector, xPol) != 0) || (header->isInL1MaskOffline(peakPhiSector, xPol) != 0);
591 fCrossCorr =
nullptr;
592 fSpawnedCrossCorrelator =
false;
593 fWhichResponseDir = 0;
596 for(
int ant=0; ant<NUM_SEAVEYS; ant++){
604 coarseMaps[polInd] =
nullptr;
605 for(
int peakInd=0; peakInd < AnitaEventSummary::maxDirectionsPerPol; peakInd++){
606 fineMaps[polInd][peakInd] =
nullptr;
608 fCoherentFiltered[polInd][peakInd][xPol] =
nullptr;
609 fCoherent[polInd][peakInd][xPol] =
nullptr;
610 fDeconvolved[polInd][peakInd][xPol] =
nullptr;
611 fDeconvolvedFiltered[polInd][peakInd][xPol] =
nullptr;
617 fUseOffAxisDelay = 1;
618 fCoherentDeltaPhi = 2;
619 fLastCoherentDeltaPhi = -1;
621 fCoherentDtNs = 0.01;
622 fSlopeFitStartFreqGHz = 0.18;
623 fSlopeFitEndFreqGHz = 1.3;
624 fFillChannelInfo = 0;
625 fFillSpectrumInfo = 0;
627 fMeanPowerFlagLowFreqGHz = 0;
628 fMeanPowerFlagHighFreqGHz = 0;
629 fCurrentEventNumber = 0;
633 fDrawDomain = kTimeDomain;
637 fDrawXPolDedispersed=1;
639 const TString minFiltName =
"Minimum";
640 fMinFilter = Filters::findDefaultStrategy(minFiltName);
641 if(fMinFilter ==
nullptr){
642 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", unable to find default filter " << minFiltName << std::endl;
645 const TString minDecoFiltName =
"Deconvolve";
646 fMinDecoFilter = Filters::findDefaultStrategy(minDecoFiltName);
647 if(fMinDecoFilter ==
nullptr){
648 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", unable to find default filter " << minDecoFiltName << std::endl;
652 fEvMinDeco =
nullptr;
655 chooseAntennasForCoherentlySumming(fCoherentDeltaPhi);
685 const Int_t numPowers = 13;
686 static const Double_t params[numPowers] = {0.00000e+00, 0.00000e+00, -1.68751e-05, 0.00000e+00,
687 2.77815e-08, 0.00000e+00, -8.29351e-12, 0.00000e+00,
688 1.15064e-15, 0.00000e+00, -7.71170e-20, 0.00000e+00,
692 Double_t offBoresightDelay = 0;
693 for(
int power=0; power < numPowers; power++){
694 offBoresightDelay += params[power]*TMath::Power(deltaPhiDeg, power);
697 return offBoresightDelay;
703 Double_t phiDeg)
const {
705 Double_t deltaPhiDeg1 = RootTools::getDeltaAngleDeg(fPhiArrayDeg[pol].at(ant1), phiDeg);
706 Double_t deltaPhiDeg2 = RootTools::getDeltaAngleDeg(fPhiArrayDeg[pol].at(ant2), phiDeg);
707 Double_t delay1 = singleAntennaOffAxisDelay(deltaPhiDeg1);
708 Double_t delay2 = singleAntennaOffAxisDelay(deltaPhiDeg2);
709 return (delay1-delay2);
718 Double_t tanThetaW = tan(-1*thetaWave);
719 Double_t part1 = fZArray[pol].at(ant1)*tanThetaW - fRArray[pol].at(ant1)*cos(phiWave-TMath::DegToRad()*fPhiArrayDeg[pol].at(ant1));
720 Double_t part2 = fZArray[pol].at(ant2)*tanThetaW - fRArray[pol].at(ant2)*cos(phiWave-TMath::DegToRad()*fPhiArrayDeg[pol].at(ant2));
721 Double_t tdiff = 1e9*((cos(thetaWave) * (part2 - part1))/SPEED_OF_LIGHT);
730 Double_t tanThetaW = tan(-1*thetaWave);
731 Double_t part = fZArray[pol].at(ant)*tanThetaW - fRArray[pol].at(ant)*cos(phiWave-TMath::DegToRad()*fPhiArrayDeg[pol].at(ant));
732 Double_t tdiff = 1e9*((cos(thetaWave) * (part))/SPEED_OF_LIGHT);
742 geom->usePhotogrammetryNumbers(1);
744 for(
int ant=0; ant<NUM_SEAVEYS; ant++){
753 for(
double& delayThisChannel : delaysPerSurf){
754 delayThisChannel = 0;
758 if(fCrossCorr ==
nullptr){
760 fSpawnedCrossCorrelator =
true;
763 fDtCache.init(fCrossCorr,
this,
true);
764 geom->usePhotogrammetryNumbers(0);
775 coarseMaps[pol] =
nullptr;
788 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" for run " 789 << fCurrentRun <<
", eventNumber " << fCurrentEventNumber
790 <<
", unable to find fineMap with pol " << pol
791 <<
" for peakInd = " << peakInd <<
" about to return NULL." << std::endl;
793 fineMaps[pol][peakInd] =
nullptr;
806 if(coarseMaps[pol]==
nullptr)
814 coarseMaps[pol]->Reset();
818 coarseMaps[pol]->addGpsInfo(pat);
821 coarseMaps[pol]->Fill(pol, fCrossCorr, &fDtCache);
830 if(zoomCenterPhiDeg < -500 || zoomCenterThetaDeg < -500 ||
831 zoomCenterPhiDeg >= 500 || zoomCenterThetaDeg >= 500){
833 std::cerr <<
"Warning in "<< __PRETTY_FUNCTION__ <<
" in " << __FILE__
834 <<
". zoomCenterPhiDeg = " << zoomCenterPhiDeg
835 <<
" and zoomCenterThetaDeg = " << zoomCenterThetaDeg
836 <<
" ...these values look suspicious so I'm skipping this reconstruction." 837 <<
" eventNumber = " << fCrossCorr->eventNumber[pol] << std::endl;
842 deltaPhiDegPhi0 = deltaPhiDegPhi0 < 0 ? deltaPhiDegPhi0 + DEGREES_IN_CIRCLE : deltaPhiDegPhi0;
844 Int_t phiSector = floor(deltaPhiDegPhi0/PHI_RANGE);
846 auto* h =
new InterferometricMap(peakIndex, phiSector, zoomCenterPhiDeg, PHI_RANGE_ZOOM, zoomCenterThetaDeg, THETA_RANGE_ZOOM);
850 h->Fill(pol, fCrossCorr, &fDtCache);
854 if(fineMaps[pol][peakIndex] !=
nullptr){
855 delete fineMaps[pol][peakIndex];
857 fineMaps[pol][peakIndex] = h;
867 geom->usePhotogrammetryNumbers(0);
871 std::ifstream lindasNums(pathToLindasFile.Data());
872 if(static_cast<int>(lindasNums.is_open())==0){
877 Double_t dr, dPhiRad, dz, dt;
879 while(lindasNums >> ant >> dr >> dz >> dPhiRad >> dt){
881 Int_t surf, chan, ant2;
885 Double_t newR = geom->rPhaseCentreFromVerticalHornPhotogrammetry[ant][pol] + dr;
886 Double_t newPhi = geom->azPhaseCentreFromVerticalHornPhotogrammetry[ant][pol] + dPhiRad;
887 Double_t newZ = geom->zPhaseCentreFromVerticalHornPhotogrammetry[ant][pol] + dz;
890 if(newPhi >= TMath::TwoPi()){
891 newPhi -= TMath::TwoPi();
894 newPhi += TMath::TwoPi();
897 geom->rPhaseCentreFromVerticalHorn[ant][pol] = newR;
898 geom->azPhaseCentreFromVerticalHorn[ant][pol] = newPhi;
899 geom->zPhaseCentreFromVerticalHorn[ant][pol] = newZ;
905 if(ant != NUM_SEAVEYS - 1){
907 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" in " << __FILE__ << std::endl;
908 std::cerr <<
"It looks like you didn't read to the end of Linda's geometry file!" << std::endl;
919 if(coherentDeltaPhi!=fLastCoherentDeltaPhi){
921 for(
int peakPhiSector = 0; peakPhiSector < NUM_PHI; peakPhiSector++){
922 fPhiSectorToAnts[peakPhiSector] = std::vector<Int_t>();
925 for(
int deltaPhiSect=-fCoherentDeltaPhi; deltaPhiSect <= fCoherentDeltaPhi; deltaPhiSect++){
927 Int_t phiSector = peakPhiSector + deltaPhiSect;
928 phiSector = phiSector < 0 ? phiSector + NUM_PHI : phiSector;
929 phiSector = phiSector >= NUM_PHI ? phiSector - NUM_PHI : phiSector;
933 fPhiSectorToAnts[peakPhiSector].push_back(ant);
937 fLastCoherentDeltaPhi = fCoherentDeltaPhi;
942 Double_t peakPhiDeg, Double_t peakThetaDeg, std::vector<double>& dts) {
945 dts.reserve(theAnts.size());
947 Double_t phiWave = peakPhiDeg*TMath::DegToRad();
948 Double_t thetaWave = peakThetaDeg*TMath::DegToRad();
949 for(
int ant : theAnts){
951 Double_t dt = getDeltaTExpected(pol, ant, phiWave, thetaWave);
957 const std::vector<Int_t>& theAnts,
958 Double_t peakPhiDeg, Double_t peakThetaDeg,
959 Double_t* biggestPeakToPeak, Double_t* forceT0) {
962 Double_t largestPeakToPeak = 0;
963 std::vector<const AnalysisWaveform*> waves;
964 waves.reserve(theAnts.size());
966 for(
int ant : theAnts){
971 Double_t vMax, vMin, tMax, tMin;
972 RootTools::getLocalMaxToMin((TGraph *)gr, vMax, tMax, vMin, tMin);
974 if(vMax - vMin > largestPeakToPeak){
975 largestPeakToPeak = vMax - vMin;
978 else if(largestPeakToPeak <= 0){
979 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" for run " 980 << fCurrentRun <<
", eventNumber " << fCurrentEventNumber <<
", the waveform max/min aren't sensible?" << std::endl;
981 std::cerr << vMax <<
"\t" << vMin <<
"\t" << tMax <<
"\t" << tMin << std::endl;
985 if(biggestPeakToPeak !=
nullptr){
986 (*biggestPeakToPeak) = largestPeakToPeak;
989 if(biggest < 0 || biggest >= NUM_SEAVEYS){
990 std::cerr <<
"Error in " << __PRETTY_FUNCTION__
991 <<
", I couldn't find a waveform where vMax - vMin > 0. " 992 <<
"Something's wrong!" << std::endl;
995 std::vector<double> dts;
996 directionAndAntennasToDeltaTs(theAnts, pol, peakPhiDeg, peakThetaDeg, dts);
998 return coherentlySum(waves, dts, forceT0);
1002 size_t s = waves.size();
1004 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" for run " << fCurrentRun
1005 <<
", eventNumber " << fCurrentEventNumber <<
", nothing to sum." << std::endl;
1007 else if(s != dts.size()){
1008 const char* action = dts.size() < waves.size() ?
"padding" :
"trimming";
1009 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" for run " << fCurrentRun
1010 <<
", eventNumber " << fCurrentEventNumber <<
", unequal vectors (waves.size() = " 1011 << waves.size() <<
", dts.size() = " << dts.size() <<
")\n" 1012 << action <<
" dts..." << std::endl;
1013 while(s != dts.size()){
1027 if(checkWavesAndDtsMatch(waves, dts)==0){
1028 std::cerr <<
"Nothing to sum.. about to return NULL" << std::endl;
1032 const double extraTimeNs = 20;
1033 const TGraph* gr0 = waves[0]->even();
1034 const double totalTime = gr0->GetX()[gr0->GetN()-1] - gr0->GetX()[0] + extraTimeNs;
1035 const int interpN = floor(totalTime/fCoherentDtNs);
1037 std::vector<double> zeros(interpN, 0);
1038 double t0 = forceT0 !=
nullptr ? *forceT0 : gr0->GetX()[0] - 0.5*extraTimeNs;
1039 auto* coherentWave =
new AnalysisWaveform(interpN, &zeros[0], fCoherentDtNs, t0);
1042 for(UInt_t i=0; i < waves.size(); i++){
1046 const double t0 = grU->GetX()[0];
1047 const double tN = grU->GetX()[grU->GetN()-1];
1050 std::cerr <<
"Debug in " << __PRETTY_FUNCTION__ <<
", waves[" << i <<
"] has even with " << grU->GetN() <<
" points. ";
1053 std::cerr <<
"(uneven has " << grA->GetN() <<
" points)." << std::endl;
1054 for(
int samp=1; samp < grU->GetN(); samp++){
1055 if(grU->GetX()[samp] - grU->GetX()[samp-1] <= 0){
1056 std::cerr <<
"Debug in " << __PRETTY_FUNCTION__ <<
", x not monotonically increasing!" << std::endl;
1057 std::cerr <<
"x[" << samp-1 <<
"] = " << grU->GetX()[samp-1] << std::endl;
1058 std::cerr <<
"x[" << samp <<
"] = " << grU->GetX()[samp] << std::endl;
1065 for(
int samp=0; samp < grCoherent->GetN(); samp++){
1066 double t = grCoherent->GetX()[samp];
1068 double tPlusDt = t + dts[i];
1069 if(tPlusDt > t0 && tPlusDt < tN){
1070 double y = waves[i]->evalEven(tPlusDt, AnalysisWaveform::EVAL_AKIMA);
1071 if(TMath::IsNaN(y)){
1075 grCoherent->GetY()[samp] += y;
1081 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" for run " 1082 << fCurrentRun <<
", eventNumber " << fCurrentEventNumber <<
" interpolation returned " 1083 << numNan <<
" NaNs for wave " << i << std::endl;
1087 for(
int samp=0; samp < grCoherent->GetN(); samp++){
1088 grCoherent->GetY()[samp]/=waves.size();
1091 return coherentWave;
1096 for(
unsigned w=0; w < waves.size(); w++){
1098 auto* gr =
new TGraphAligned(grOld->GetN(), grOld->GetX(), grOld->GetY());
1100 for(
int i=0; i < gr->GetN(); i++){
1101 gr->GetX()[i] -= dts[w];
1109 inline TString nameLargestPeak(Int_t peakInd){
1112 case 0: title =
"Largest Peak ";
break;
1113 case 1: title =
"2nd Largest Peak ";
break;
1114 case 2: title =
"3rd Largest Peak ";
break;
1115 default: title = TString::Format(
"%dth Largest Peak", peakInd+1);
break;
1123 constexpr
int numColsForNow = 3;
1124 EColor peakColors[
AnitaPol::kNotAPol][numColsForNow] = {{kBlack, EColor(kMagenta+2), EColor(kViolet+2)},
1125 {kBlue, EColor(kSpring+4), EColor(kPink + 10)}};
1127 constexpr
int nStokesVecs = 4;
1128 EColor stokesCols[nStokesVecs] = {kBlack, kRed, kBlue, kGreen};
1136 std::vector<double> wholePadVLayers = {1, 0.95, 0.75, 0.72, 0.3, 0};
1137 Int_t wholePadLayer = 0;
1140 wholePadVLayers = {1, 0.95, 0.65, 0.62, 0.35, 0};
1143 if(wholePad==
nullptr){
1144 UInt_t eventNumber = fCrossCorr->eventNumber[pol];
1145 TString canName = TString::Format(
"can%u", eventNumber);
1147 canName += polSuffix;
1148 TString canTitle = TString::Format(
"Event %u - ", eventNumber) + polSuffix;
1149 wholePad =
new TCanvas(canName);
1153 TPad* wholeTitlePad = RootTools::makeSubPad(wholePad,
1154 0, wholePadVLayers.at(wholePadLayer+1),
1155 1, wholePadVLayers.at(wholePadLayer),
1156 TString::Format(
"%d_title", (
int)pol));
1159 (void) wholeTitlePad;
1160 auto *wholeTitle =
new TPaveText(0, 0, 1, 1);
1161 TString wholeTitleText;
1163 wholeTitleText +=
" Reconstruction";
1164 wholeTitle->AddText(wholeTitleText);
1165 wholeTitle->SetBit(kCanDelete,
true);
1166 wholeTitle->SetLineWidth(0);
1169 TPad* coarseMapPad = RootTools::makeSubPad(wholePad,
1170 0, wholePadVLayers.at(wholePadLayer+1),
1171 1, wholePadVLayers.at(wholePadLayer),
1172 TString::Format(
"%d_coarse", (
int)pol));
1177 const double fracFinePeak = 0.2;
1178 const EColor xPolColor = kRed;
1179 const double xPolTitleBoxWidth = 0.1;
1181 TPad* tempPad = RootTools::makeSubPad(wholePad,
1182 0, wholePadVLayers.at(wholePadLayer+1),
1183 1, wholePadVLayers.at(wholePadLayer),
1188 std::vector<TPaveText*> paves;
1189 paves.push_back(
new TPaveText(0, 0, fracFinePeak, 1));
1190 paves.back()->AddText(
"Fine Map");
1191 paves.back()->SetTextAlign(kVAlignCenter + kHAlignCenter);
1193 paves.push_back(
new TPaveText(fracFinePeak, 0, fracFinePeak+0.5*(1-fracFinePeak)-0.1, 1));
1194 paves.back()->AddText(
"Coherent");
1195 paves.back()->SetTextAlign(kVAlignCenter + kHAlignCenter);
1196 if(fDrawXPol != 0 && fDrawDomain!=kStokesParams){
1197 double x2 = paves.back()->GetX2();
1198 double x1 = x2 - xPolTitleBoxWidth;
1199 paves.back()->SetX2(x1);
1200 paves.back()->SetTextAlign(kVAlignCenter + kHAlignRight);
1202 paves.push_back(
new TPaveText(x1, 0, x2, 1));
1203 paves.back()->AddText(
"(Cross-Pol)");
1204 paves.back()->SetTextAlign(kVAlignCenter + kHAlignLeft);
1205 ((TText*)paves.back()->GetListOfLines()->Last())->SetTextColor(xPolColor);
1208 paves.push_back(
new TPaveText(fracFinePeak+0.5*(1-fracFinePeak), 0, 1, 1));
1209 paves.back()->AddText(
"Dedispersed");
1210 paves.back()->SetTextAlign(kVAlignCenter + kHAlignCenter);
1212 if(fDrawXPolDedispersed != 0 && fDrawDomain!=kStokesParams){
1213 double x2 = paves.back()->GetX2();
1214 double x1 = x2 - xPolTitleBoxWidth;
1215 paves.back()->SetX2(x1);
1216 paves.back()->SetTextAlign(kVAlignCenter + kHAlignRight);
1218 paves.push_back(
new TPaveText(x1, 0, x2, 1));
1219 paves.back()->AddText(
"(Cross-Pol)");
1220 ((TText*)paves.back()->GetListOfLines()->Last())->SetTextColor(xPolColor);
1221 paves.back()->SetTextAlign(kVAlignCenter + kHAlignLeft);
1224 for(
auto & pave : paves){
1225 pave->SetBit(kCanDelete);
1226 pave->SetShadowColor(0);
1227 pave->SetLineWidth(0);
1228 pave->SetLineColor(0);
1232 TPad* finePeaksAndCoherent = RootTools::makeSubPad(wholePad,
1233 0, wholePadVLayers.at(wholePadLayer+1),
1234 1, wholePadVLayers.at(wholePadLayer),
1238 std::list<InterferometricMap*> drawnFineMaps;
1240 const int nFine = TMath::Min(fNumPeaks, fDrawNPeaks);
1241 for(
int peakInd = 0; peakInd < nFine; peakInd++){
1242 double yUp = 1 - double(peakInd)/nFine;
1243 double yLow = yUp - double(1)/nFine;
1244 TPad* finePeak = RootTools::makeSubPad(finePeaksAndCoherent, 0, yLow, fracFinePeak, yUp,
"fine");
1250 h->GetXaxis()->SetTitleSize(0.01);
1251 h->GetYaxis()->SetTitleSize(0.01);
1252 h->SetLineColor(peakColors[pol][peakInd]);
1255 h->DrawGroup(
"col");
1256 drawnFineMaps.push_back(h);
1261 hCoarse->addGuiChild(*grEdge,
"l");
1264 double x0 = fCoherentFiltered[pol][peakInd][0]->even()->GetX()[0] - 10;
1265 double xN = fCoherentFiltered[pol][peakInd][0]->even()->GetX()[fCoherentFiltered[pol][peakInd][0]->even()->GetN()-1] + 10;
1267 for(
int j=0; j <= 1; j++){
1268 std::vector<AnalysisWaveform*> wavesToDraw;
1269 std::vector<const AnitaEventSummary::WaveformInfo*> waveInfo;
1270 std::vector<EColor> waveColors;
1271 std::vector<Style_t> lineStyles;
1272 std::vector<TString> legText;
1274 if(fDrawCoherent > 0){
1275 wavesToDraw.push_back(fCoherentFiltered[pol][peakInd][0]);
1276 waveInfo.push_back(&fSummary.coherent_filtered[pol][peakInd]);
1277 waveColors.push_back(peakColors[pol][peakInd]);
1278 lineStyles.push_back(1);
1279 legText.emplace_back(
"Co-pol");
1282 wavesToDraw.push_back(fCoherentFiltered[pol][peakInd][1]);
1283 waveInfo.push_back(
nullptr);
1285 waveColors.push_back(xPolColor);
1286 lineStyles.push_back(7);
1287 legText.emplace_back(
"Cross-pol");
1291 if(fDrawDedispersed > 0){
1292 wavesToDraw.push_back(fDeconvolvedFiltered[pol][peakInd][0]);
1293 waveInfo.push_back(&fSummary.deconvolved_filtered[pol][peakInd]);
1294 waveColors.push_back(peakColors[pol][peakInd]);
1295 lineStyles.push_back(1);
1296 legText.emplace_back(
"Co-pol");
1298 if(fDrawXPolDedispersed > 0){
1299 wavesToDraw.push_back(fDeconvolvedFiltered[pol][peakInd][1]);
1300 waveInfo.push_back(
nullptr);
1301 waveColors.push_back(xPolColor);
1302 lineStyles.push_back(7);
1303 legText.emplace_back(
"Cross-pol");
1311 for(
int i=0; i < wavesToDraw.size(); i++){
1313 if(fDrawDomain==kTimeDomain){
1317 gr3->SetFillColor(0);
1318 gr3->SetLineColor(waveColors[i]);
1319 gr3->SetMarkerColor(waveColors[i]);
1320 gr3->SetLineStyle(lineStyles[i]);
1322 gr3->GetXaxis()->SetTitleSize(1);
1323 gr3->GetYaxis()->SetTitleSize(1);
1325 gr3->SetBit(kCanDelete);
1328 gr->addGuiChild(gr3);
1333 TString title = nameLargestPeak(peakInd);
1334 title += (j == 0 ?
"Coherent Waveform" :
"Dedispersed Waveform");
1336 title +=
";Time (ns);Amplitude (mV)";
1338 gr->SetTitle(title);
1339 gr->GetXaxis()->SetRangeUser(x0, xN);
1342 else if(fDrawDomain==kFreqDomain){
1347 grPower->SetLineColor(waveColors[i]);
1348 grPower->SetMarkerColor(waveColors[i]);
1349 grPower->SetLineStyle(lineStyles[i]);
1351 grPower->SetBit(kCanDelete);
1355 const double maxFreqGHz = 1.3;
1356 gr->GetXaxis()->SetRangeUser(0, maxFreqGHz);
1357 TString title = nameLargestPeak(peakInd);
1358 title += (j == 0 ?
"Coherent Waveform Spectrum" :
"Dedispersed Waveform Spectrum");
1360 title +=
";Frequency (GHz);Power Spectral Density (dBm/MHz)";
1361 grPower->SetTitle(title);
1364 gr->addGuiChild(grPower);
1367 if((waveInfo[i] !=
nullptr) && (fFillSpectrumInfo != 0) && (gr !=
nullptr)){
1368 double y0 = waveInfo[i]->spectrumSlope*fSlopeFitStartFreqGHz + waveInfo[i]->spectrumIntercept;
1370 grSlope->SetPoint(1, fSlopeFitEndFreqGHz, waveInfo[i]->spectrumSlope*fSlopeFitEndFreqGHz + waveInfo[i]->spectrumIntercept);
1371 grSlope->SetLineColor(grPower->GetLineColor());
1372 gr->addGuiChild(grSlope);
1374 double df = wavesToDraw[i]->deltaF();
1376 grCoherentPeakMarker->SetMarkerStyle(4);
1377 grCoherentPeakMarker->SetMarkerSize(0.75);
1378 grCoherentPeakMarker->SetMarkerColor(grPower->GetLineColor());
1380 for(
double k : waveInfo[i]->peakFrequency){
1382 int powerBin = TMath::Nint(k/df);
1383 grCoherentPeakMarker->SetPoint(grCoherentPeakMarker->GetN(), grPower->GetX()[powerBin], grPower->GetY()[powerBin]);
1386 gr->addGuiChild(grCoherentPeakMarker);
1390 auto gr2 = j == 0 ? fCoherentFiltered[pol][peakInd][0]->even() : fDeconvolvedFiltered[pol][peakInd][0]->even();
1391 const double t0 = gr2->GetX()[0];
1392 const double dt = gr2->GetX()[1] - t0;
1394 std::vector<double> times;
1396 times.reserve(gr2->GetN());
1398 while(times.size() < times.capacity()){
1405 const std::vector<double>& I = (j == 0
1406 ? f_dICoherentFiltered[pol][peakInd]
1407 : f_dIDeconvolvedFiltered[pol][peakInd]);
1408 const std::vector<double>& Q = (j == 0
1409 ? f_dQCoherentFiltered[pol][peakInd]
1410 : f_dQDeconvolvedFiltered[pol][peakInd]);
1411 const std::vector<double>& U = (j == 0
1412 ? f_dUCoherentFiltered[pol][peakInd]
1413 : f_dUDeconvolvedFiltered[pol][peakInd]);
1414 const std::vector<double>& V = (j == 0
1415 ? f_dVCoherentFiltered[pol][peakInd]
1416 : f_dVDeconvolvedFiltered[pol][peakInd]);
1418 for(
const auto& v : {I, Q, U, V}){
1420 const int n = v.size();
1424 TString title = nameLargestPeak(peakInd);
1425 title += (j == 0 ?
"Coherent Stokes Parameters" :
"Dedispersed Stokes Parameters");
1427 title +=
";Time (ns);Amplitude (mV)";
1428 gr->SetTitle(title);
1429 gr->GetXaxis()->SetRangeUser(x0, xN);
1432 gr->addGuiChild(gr3);
1434 gr3->SetFillColor(0);
1435 gr3->SetLineColor(stokesCols[k]);
1436 gr3->SetBit(kCanDelete);
1440 if(fDrawDomain==kStokesParams){
1445 TPad* coherentPad = RootTools::makeSubPad(finePeaksAndCoherent, fracFinePeak, yLow, fracFinePeak + 0.5*(1 - fracFinePeak), yUp,
"coherent");
1449 TPad* dedispersedPad = RootTools::makeSubPad(finePeaksAndCoherent, fracFinePeak + 0.5*(1 - fracFinePeak), yLow, 1, yUp,
"dedispersed");
1450 dedispersedPad->cd();
1468 if(!drawnFineMaps.empty()){
1469 auto it = drawnFineMaps.begin();
1470 Double_t polMax = -1e9;
1471 Double_t polMin = 1e9;
1472 for(; it!=drawnFineMaps.end(); ++it){
1473 polMax = (*it)->GetMaximum() > polMax ? (*it)->GetMaximum() : polMax;
1474 polMin = (*it)->GetMinimum() < polMin ? (*it)->GetMinimum() : polMin;
1476 for(it=drawnFineMaps.begin(); it!=drawnFineMaps.end(); ++it){
1477 (*it)->SetMaximum(polMax);
1478 (*it)->SetMinimum(polMin);
1480 if(hCoarse !=
nullptr){
1481 hCoarse->SetMaximum(polMax);
1484 while(!drawnFineMaps.empty()){
1485 drawnFineMaps.pop_back();
1490 const double epsilon = 0.001;
1491 TPad* textPad = RootTools::makeSubPad(wholePad,
1492 0, wholePadVLayers.at(wholePadLayer+1),
1493 1, wholePadVLayers.at(wholePadLayer),
1497 for(
int peakInd=0; peakInd < nFine; peakInd++){
1498 double xlow = double(peakInd)/nFine;
1499 double xup = xlow + double(1.)/nFine - epsilon;
1501 auto *title =
new TPaveText(xlow, 0.9, xup, 1);
1503 title->SetBit(kCanDelete,
true);
1504 title->SetTextColor(peakColors[pol][peakInd]);
1505 title->SetLineColor(peakColors[pol][peakInd]);
1508 TString titleText = nameLargestPeak(peakInd);
1509 if(fDrawDomain==kStokesParams){
1510 titleText +=
"Stokes";
1512 title->AddText(titleText);
1516 if(fDrawDomain!=kStokesParams){
1517 auto *pt =
new TPaveText(xlow, epsilon, xup, 0.9);
1519 pt->SetBit(kCanDelete,
true);
1520 pt->SetTextColor(peakColors[pol][peakInd]);
1521 pt->SetLineColor(peakColors[pol][peakInd]);
1522 pt->AddText(TString::Format(
"Image peak = %4.4lf", fSummary.peak[pol][peakInd].value));
1523 pt->AddText(TString::Format(
"#phi_{fine} = %4.2lf#circ", fSummary.peak[pol][peakInd].phi));
1524 pt->AddText(TString::Format(
"#theta_{fine} = %4.2lf#circ",fSummary.peak[pol][peakInd].theta));
1525 pt->AddText(TString::Format(
"Hilbert peak = %4.2lf mV, ", fSummary.coherent[pol][peakInd].peakHilbert));
1527 pt->AddText(TString::Format(
"Latitude = %4.2lf #circ", fSummary.peak[pol][peakInd].latitude));
1528 pt->AddText(TString::Format(
"Longitude = %4.2lf #circ", fSummary.peak[pol][peakInd].longitude));
1529 pt->AddText(TString::Format(
"Altitude = %4.2lf #circ", fSummary.peak[pol][peakInd].altitude));
1533 const double width = 0.03;
1534 auto e =
new TPaveText(xlow, 0.8, xlow+width, 0.9);
1535 auto f =
new TPaveText(xlow, 0.7, xlow+width, 0.8);
1537 auto ept =
new TPaveText(xlow, epsilon, xlow+width, 0.7);
1538 ept->AddText(
"I")->SetTextColor(stokesCols[0]);
1539 ept->AddText(
"Q")->SetTextColor(stokesCols[1]);
1540 ept->AddText(
"U")->SetTextColor(stokesCols[2]);
1541 ept->AddText(
"V")->SetTextColor(stokesCols[3]);
1544 const double xmid = (xlow + xup)/2;
1546 auto lpt_t =
new TPaveText(xlow, 0.8, xmid, 0.9);
1547 lpt_t->AddText(
"Coherent");
1548 auto lpt_f =
new TPaveText(xlow, 0.7, xmid, 0.8);
1549 lpt_f->AddText(
"max (mean)");
1551 auto rpt_t =
new TPaveText(xmid, 0.8, xup, 0.9);
1552 rpt_t->AddText(
"Dedispersed");
1553 auto rpt_f =
new TPaveText(xmid, 0.7, xup, 0.8);
1554 rpt_f->AddText(
"max (mean)");
1556 auto* lpt =
new TPaveText(xlow, epsilon, xmid, 0.7);
1557 auto& ci = fSummary.coherent_filtered[pol][peakInd];
1558 lpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", ci.max_dI, ci.I))->SetTextColor(stokesCols[0]);
1559 lpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", ci.max_dQ, ci.Q))->SetTextColor(stokesCols[1]);
1560 lpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", ci.max_dU, ci.U))->SetTextColor(stokesCols[2]);
1561 lpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", ci.max_dV, ci.V))->SetTextColor(stokesCols[3]);
1563 auto* rpt =
new TPaveText(xmid, epsilon, xup, 0.7);
1564 auto& di = fSummary.deconvolved_filtered[pol][peakInd];
1565 rpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", di.max_dI, di.I))->SetTextColor(stokesCols[0]);
1566 rpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", di.max_dQ, di.Q))->SetTextColor(stokesCols[1]);
1567 rpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", di.max_dU, di.U))->SetTextColor(stokesCols[2]);
1568 rpt->AddText(TString::Format(
"%4.2lf (%4.2lf)", di.max_dV, di.V))->SetTextColor(stokesCols[3]);
1571 for(
auto pt : {e, ept, f, lpt_t, rpt_t, lpt_f, rpt_f, lpt, rpt}){
1572 pt->SetBit(kCanDelete,
true);
1573 pt->SetTextColor(peakColors[pol][peakInd]);
1574 pt->SetLineColor(peakColors[pol][peakInd]);
1575 pt->SetShadowColor(0);
1581 wholePad->SetBorderSize(2);
1589 fCoherentFiltered[pol][peakInd][xPol] =
nullptr;
1596 fCoherent[pol][peakInd][xPol] =
nullptr;
1604 fDeconvolved[pol][peakInd][xPol] =
nullptr;
1612 fDeconvolvedFiltered[pol][peakInd][xPol] =
nullptr;
1629 fEvMinDeco =
nullptr;
AnalysisWaveform * getCoherentFiltered(AnitaPol::AnitaPol_t pol, Int_t peakInd=0, bool xPol=false)
Coherently summed filtered (un-deconvolved) waveform accessor for external processes. Only works once per event processed as ownership is transferred to the function caller.
void process(const FilteredAnitaEvent *fEv, AnitaEventSummary *sum, NoiseMonitor *noiseMonitor=NULL, TruthAnitaEvent *truth=NULL)
Bool_t masked_xpol
was this in a masked phi sector?
static Int_t directlyInsertGeometry(TString pathToLindasFile, AnitaPol::AnitaPol_t pol)
Double_t hwAngleXPol
angle with respect to triggering phi sector
const UsefulAnitaEvent * getUsefulAnitaEvent() const
void directionAndAntennasToDeltaTs(const std::vector< Int_t > &theAnts, AnitaPol::AnitaPol_t pol, Double_t peakPhiDeg, Double_t peakThetaDeg, std::vector< double > &dts)
From a list of antennas, get a set of dts relative to the first antenna.
AnalysisWaveform * getCoherent(AnitaPol::AnitaPol_t pol, Int_t peakInd=0, bool xPol=false)
Coherently summed (un-filtered, un-deconvolved) waveform accessor for external processes. Only works once per event processed as ownership is transferred to the function caller.
Adu5Pat – The ADU5 Position and Attitude Data.
Does the event reconstruction, and produces a summary of it.
static AnitaEventCalibrator * Instance(int version=0)
Instance generator.
void fillPowerFlags(const FilteredAnitaEvent *fEv, AnitaEventSummary::EventFlags &flags)
Double_t hwAngle
value of average of the peak location over the past 60 min-bias events
Double_t relativeOffAxisDelay(AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2, Double_t phiDeg) const
Get the off axis delay between two antennas for a given phi angle.
static void setTriggerInfoFromPeakPhi(const RawAnitaHeader *header, AnitaPol::AnitaPol_t pol, Int_t peakPhiSector, AnitaEventSummary::PointingHypothesis &peak)
Calculate and fill the info the AnitaEventSummary relating the compatibility of the hardware trigger ...
InterferometricMap * getZoomMap(AnitaPol::AnitaPol_t pol, UInt_t peakInd=0)
Get a pointer to a finely binned interferometric map stored in memory, once called, you own this InterferometricMap and must delete it.
void reconstructZoom(AnitaPol::AnitaPol_t pol, Int_t peakIndex, Double_t zoomCenterPhiDeg, Double_t zoomCenterThetaDeg, const Adu5Pat *pat=NULL)
produce and store a finely binned interferometric map, (overwrites fineMaps)
static const Int_t numFracPowerWindows
The maximum number of frequency peaks per waveform spectrum.
static const Int_t peaksPerSpectrum
The maximum number of hypotheses storable per polarization */.
Double_t getDeltaTExpected(AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2, Double_t phiWave, Double_t thetaWave) const
Get the expected delay between antenna pairs for a given direction.
AnalysisWaveform * getDeconvolved(AnitaPol::AnitaPol_t pol, Int_t peakInd=0, bool xPol=false)
Coherently summed (un-filtered) deconvolved waveform accessor for external processes. Only works once per event processed as ownership is transferred to the function caller.
Bool_t triggered
theta - theta rough
AnitaEventCalibrator – The ANITA Event Calibrator.
const UsefulAdu5Pat * getGPS() const
static Double_t getBin0PhiDeg()
static void fillChannelInfo(const FilteredAnitaEvent *fEv, AnitaEventSummary *sum)
Calculate and fill the numbers for Peng's ChannelInfo object.
AnalysisReco()
Constructor.
Bool_t masked
was this in a triggered xpol phi sector?
void reconstruct(AnitaPol::AnitaPol_t pol, const Adu5Pat *pat=NULL)
produce and store the coarsely binned interferometric map, (overwrites coarseMaps) ...
A minimalistic extension to TGraphAligned for some GUI bells and whistles.
Double_t singleAntennaOffAxisDelay(Double_t deltaPhiDeg) const
virtual void DrawGroup(Option_t *opt="")
Must be overloaded by children (TGraphInteractive*) to return pointer to parent
enum AnitaRing::EAnitaRing AnitaRing_t
Ring enumeration.
size_t checkWavesAndDtsMatch(std::vector< const AnalysisWaveform *> &waves, std::vector< Double_t > &dts)
Bounds checking for coherent averaging. Checks input vectors are the same length and zero pads/trims ...
FilteredAnitaEvent * getEvMinDeco()
void initializeInternals()
Sets default values and zeros pointers for dynamically initialised heap members.
void fillWaveformInfo(AnitaPol::AnitaPol_t pol, Int_t peakInd, AnitaEventSummary::WaveformInfo &info, const FilteredAnitaEvent *fEv, AnalysisWaveform **waveStore, InterferometricMap *h, NoiseMonitor *noiseMonitor, std::vector< double > &I, std::vector< double > &Q, std::vector< double > &U, std::vector< double > &V)
virtual void DrawGroup(Option_t *opt="")
Must be overloaded by children (TGraphInteractive*) to return pointer to parent
const AnalysisWaveform * getRawGraph(UInt_t i) const
TruthAnitaEvent – The Truth ANITA Event.
static Double_t getPhiSectorCenterPhiDeg(int phi)
As UsefulAnitaEvent is to RawAnitaEvent, UsefulAdu5Pat is to Adu5Pat. Well not quite as useful but yo...
virtual ~AnalysisReco()
Destructor.
void drawSummary(TPad *wholePad, AnitaPol::AnitaPol_t pol)
Draw everything interesting onto a TPad.
AnalysisWaveform * coherentlySum(const FilteredAnitaEvent *fEv, AnitaPol::AnitaPol_t pol, const std::vector< Int_t > &theAnts, Double_t peakPhiDeg, Double_t peakThetaDeg, Double_t *biggestPeakToPeak=NULL, double *forceT0=NULL)
Make a coherently summed waveform for a given polarization, set of antennas in a particular direction...
FilteredAnitaEvent * getEvDeco()
Double_t relativePhaseCenterToAmpaDelays[12][9]
From phase center to AMPAs (hopefully)
void nicelyDeleteInternalFilteredEvents()
does NULL pointer checking deletion on the internally generated FilteredAnitaEvents, fEvMin, fEvMinDeco, fEvDeco
const AnalysisWaveform * getFilteredGraph(UInt_t i) const
A class to take in FiteredAnitaEvents and cross-correlate nearby channels.
void chooseAntennasForCoherentlySumming(int coherentDeltaPhi)
Generate a set of antennas to use to generate the coherent waveform.
void wavesInCoherent(std::vector< const AnalysisWaveform *> &waves, std::vector< Double_t > &dts, std::vector< TGraphAligned *> &grs)
Generate a new set of TGraphAligned such that the peaks are aligned,.
AnalysisWaveform * getDeconvolvedFiltered(AnitaPol::AnitaPol_t pol, Int_t peakInd=0, bool xPol=false)
Coherently summed filtered deconvolved waveform accessor for external processes. Only works once per ...
Common analysis format between UCorrelator and Acclaim.
InterferometricMap * getMap(AnitaPol::AnitaPol_t pol)
Get a pointer to the coarsely binned interferometric map stored in memory, once called, you own this InterferometricMap and must delete it.
void insertPhotogrammetryGeometry()
Inserts the photogrammetry geometry from AnitaGeomTool into this classes copy of the antenna position...
This class is intended to store all the necessary data about an ANITA event for filtering and analysi...
FilteredAnitaEvent * getEvMin()
enum AnitaPol::EAnitaPol AnitaPol_t
Polarisation enumeration.
Bool_t triggered_xpol
was this in a triggered phi sector?
const RawAnitaHeader * getHeader() const