1 #include "CrossCorrelator.h" 3 #include "AnitaDataset.h" 4 #include "FilterStrategy.h" 6 Acclaim::CrossCorrelator::CrossCorrelator(){
11 Acclaim::CrossCorrelator::~CrossCorrelator(){
16 void Acclaim::CrossCorrelator::initializeVariables(){
19 multiplyTopRingByMinusOne = 0;
24 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
25 interpRMS[pol][ant] = 0;
26 interpRMS2[pol][ant] = 0;
31 numSamples = PAD_FACTOR*NUM_SAMP;
32 numSamplesUpsampled = numSamples*UPSAMPLE_FACTOR;
34 nominalSamplingDeltaT = NOMINAL_SAMPLING_DELTAT;
35 correlationDeltaT = nominalSamplingDeltaT/UPSAMPLE_FACTOR;
37 do5PhiSectorCombinatorics();
43 void Acclaim::CrossCorrelator::do5PhiSectorCombinatorics(){
45 for(Int_t ant1=0; ant1 < NUM_SEAVEYS; ant1++){
46 for(Int_t ant2=0; ant2 < NUM_SEAVEYS; ant2++){
47 comboIndices[ant1][ant2] = -1;
52 for(Int_t ant1=0; ant1<NUM_SEAVEYS; ant1++){
53 Double_t phiSect1 = ant1%NUM_PHI;
54 for(Int_t ant2=ant1+1; ant2<NUM_SEAVEYS; ant2++){
55 Double_t phiSect2 = ant2%NUM_PHI;
57 if(TMath::Abs(phiSect1 - phiSect2) <= DELTA_PHI_SECT || TMath::Abs(phiSect1 - phiSect2) >= (NUM_PHI-DELTA_PHI_SECT)){
58 comboIndices[ant1][ant2] = numCombos;
59 comboIndices[ant2][ant1] = numCombos;
60 comboToAnt1s.push_back(ant1);
61 comboToAnt2s.push_back(ant2);
66 if(numCombos != NUM_COMBOS){
67 std::cerr <<
"Warning! in = " << __PRETTY_FUNCTION__ << std::endl;
68 std::cerr <<
"\tnumCombos = " << numCombos <<
"." << std::endl;
69 std::cerr <<
"\tNUM_COMBOS = " << NUM_COMBOS <<
"." << std::endl;
70 std::cerr <<
"\tExpecting NUM_COMBOS == numCombos." << std::endl;
71 std::cerr <<
"\tSeriously bad things are probably about to happen." << std::endl;
72 std::cerr <<
"\tCheck the combinatorics!" << std::endl;
83 Double_t Acclaim::CrossCorrelator::getCrossCorrelation(
AnitaPol::AnitaPol_t pol, Int_t combo, Double_t deltaT)
const{
85 Int_t ant1 = comboToAnt1s[combo];
86 Int_t ant2 = comboToAnt2s[combo];
89 deltaT += startTimes[pol][ant1];
90 deltaT -= startTimes[pol][ant2];
95 Int_t offsetLow = floor(deltaT/nominalSamplingDeltaT);
96 Double_t dt1 = offsetLow*nominalSamplingDeltaT;
97 Double_t interpPrefactor = (deltaT - dt1)/nominalSamplingDeltaT;
98 offsetLow += numSamples/2;
100 Double_t c1 = crossCorrelations[pol][combo][offsetLow];
101 Double_t c2 = crossCorrelations[pol][combo][offsetLow+1];
102 Double_t cInterp = interpPrefactor*(c2 - c1) + c1;
111 void Acclaim::CrossCorrelator::getNormalizedInterpolatedTGraphs(
const FilteredAnitaEvent* fEv,
114 for(Int_t ant=0; ant < NUM_SEAVEYS; ant++){
117 startTimes[pol][ant] = gr->GetX()[0];
120 Double_t invertFactor = multiplyTopRingByMinusOne > 0 && ant < NUM_PHI ? -1 : 1;
123 for(
int samp=0; samp < n; samp++){
124 Double_t V = invertFactor*gr->GetY()[samp];
125 fVolts[pol][ant][samp] = V;
129 Double_t meanV = sumOfV/n;
131 Double_t sumOfVSquared = 0;
132 for(
int samp=0; samp < n; samp++){
133 fVolts[pol][ant][samp] -= meanV;
134 sumOfVSquared += fVolts[pol][ant][samp]*fVolts[pol][ant][samp];
137 for(
int samp=n; samp < numSamples; samp++){
138 fVolts[pol][ant][samp] = 0;
141 interpRMS[pol][ant] = TMath::Sqrt(sumOfVSquared/numSamples);
142 interpRMS2[pol][ant] = TMath::Sqrt(sumOfVSquared/numSamplesUpsampled);
151 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
152 FancyFFTs::doFFT(numSamples, fVolts[pol][ant], ffts[pol][ant]);
153 renormalizeFourierDomain(pol, ant);
160 FancyFFTs::normalizeFourierDomain(numSamples, ffts[pol][ant]);
180 getNormalizedInterpolatedTGraphs(fEv, pol);
184 doCrossCorrelations(pol);
192 Double_t* ccInternalArray = FancyFFTs::getRealArray(std::pair<int, int>(numSamples, 0));
194 for(
int combo=0; combo<NUM_COMBOS; combo++){
195 Int_t ant1 = comboToAnt1s.at(combo);
196 Int_t ant2 = comboToAnt2s.at(combo);
197 FancyFFTs::crossCorrelatePadded(numSamples,
201 crossCorrelations[pol][combo],
205 const int offset = numSamples/2;
208 for(Int_t samp=0; samp < numSamples/2; samp++){
209 crossCorrelations[pol][combo][samp+offset] = ccInternalArray[samp];
213 for(Int_t samp=numSamples/2; samp < numSamples; samp++){
214 crossCorrelations[pol][combo][samp-offset] = ccInternalArray[samp];
222 void Acclaim::CrossCorrelator::doUpsampledCrossCorrelations(
AnitaPol::AnitaPol_t pol, Int_t phiSector){
225 const std::vector<Int_t>* combosToUse = &combosToUseGlobal[phiSector];
226 Int_t numCombosToUpsample = combosToUse->size();
228 Double_t* ccInternalArray = FancyFFTs::getRealArray(std::pair<int, int>(numSamplesUpsampled, 0));
230 for(
int comboInd=0; comboInd<numCombosToUpsample; comboInd++){
231 Int_t combo = combosToUse->at(comboInd);
233 Int_t ant1 = comboToAnt1s.at(combo);
234 Int_t ant2 = comboToAnt2s.at(combo);
236 FancyFFTs::crossCorrelatePadded(numSamples,
240 crossCorrelationsUpsampled[pol][combo],
244 const int offset = numSamplesUpsampled/2;
247 for(Int_t samp=0; samp < numSamplesUpsampled/2; samp++){
248 crossCorrelationsUpsampled[pol][combo][samp+offset] = ccInternalArray[samp];
251 for(Int_t samp=numSamplesUpsampled/2; samp < numSamplesUpsampled; samp++){
252 crossCorrelationsUpsampled[pol][combo][samp-offset] = ccInternalArray[samp];
261 Bool_t Acclaim::CrossCorrelator::useCombo(Int_t ant1, Int_t ant2, Int_t phiSector, Int_t deltaPhiSect){
268 Int_t absDeltaPhiSect = TMath::Abs(deltaPhiSect);
271 Int_t phiSectorOfAnt1 = ant1%NUM_PHI;
272 Bool_t ant1InRange = TMath::Abs(phiSector - (phiSectorOfAnt1))<=absDeltaPhiSect;
275 ant1InRange = ant1InRange || TMath::Abs(phiSector - (phiSectorOfAnt1))>=(NUM_PHI-absDeltaPhiSect);
277 Int_t phiSectorOfAnt2 = ant2%NUM_PHI;
278 Bool_t ant2InRange = TMath::Abs(phiSector - (phiSectorOfAnt2))<=absDeltaPhiSect;
279 ant2InRange = ant2InRange || TMath::Abs(phiSector - (phiSectorOfAnt2))>=(NUM_PHI-absDeltaPhiSect);
282 Bool_t extraCondition =
true;
283 if(deltaPhiSect < 0){
284 extraCondition = (phiSectorOfAnt1==phiSector || phiSectorOfAnt2==phiSector);
287 return (ant1InRange && ant2InRange && extraCondition);
291 void Acclaim::CrossCorrelator::fillCombosToUse(){
293 for(Int_t phiSector = 0; phiSector<NUM_PHI; phiSector++){
294 if(combosToUseGlobal[phiSector].size() == 0){
295 for(Int_t combo=0; combo<numCombos; combo++){
296 Int_t ant1 = comboToAnt1s.at(combo);
297 Int_t ant2 = comboToAnt2s.at(combo);
298 if(useCombo(ant1, ant2, phiSector, kDeltaPhiSect)){
299 combosToUseGlobal[phiSector].push_back(combo);
309 Double_t Acclaim::CrossCorrelator::getInterpolatedUpsampledCorrelationValue(
AnitaPol::AnitaPol_t pol,
310 Int_t combo, Double_t deltaT)
const{
312 Int_t offsetLow = floor(deltaT/correlationDeltaT);
314 Double_t dt1 = offsetLow*correlationDeltaT;
317 const Int_t offset = numSamplesUpsampled/2;
319 Int_t offsetHigh = offsetLow+1;
324 Double_t c1 = crossCorrelationsUpsampled[pol][combo][offsetLow];
325 Double_t c2 = crossCorrelationsUpsampled[pol][combo][offsetHigh];
327 Double_t cInterp = (deltaT - dt1)*(c2 - c1)/(correlationDeltaT) + c1;
334 Double_t Acclaim::CrossCorrelator::getTimeOfMaximumUpsampledCrossCorrelation(
AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2)
const{
335 Int_t combo = comboIndices[ant1][ant2];
339 Int_t maxSamp = TMath::LocMax(numSamplesUpsampled, crossCorrelationsUpsampled[pol][combo]);
340 maxSamp = maxSamp > numSamplesUpsampled/2 ? maxSamp - numSamplesUpsampled : maxSamp;
341 return maxSamp*correlationDeltaT;
346 TGraph* Acclaim::CrossCorrelator::getCrossCorrelationGraphWorker(Int_t numSamps,
AnitaPol::AnitaPol_t pol,
347 Int_t ant1, Int_t ant2)
const {
350 Int_t combo = comboIndices[ant1][ant2];
355 Double_t graphDt = correlationDeltaT;
356 const Double_t* corrPtr = crossCorrelationsUpsampled[pol][combo];
357 if(numSamps != numSamplesUpsampled){
358 numSamps = numSamples;
359 graphDt = nominalSamplingDeltaT;
360 corrPtr = crossCorrelations[pol][combo];
368 std::vector<Double_t> offsets = std::vector<Double_t>(numSamps, 0);
369 std::vector<Double_t> corrs = std::vector<Double_t>(numSamps, 0);
373 for(Int_t i=0; i<numSamps; i++){
374 Int_t offset = (i - numSamps/2);
375 offsets.at(i) = offset*graphDt;
376 corrs.at(i) = corrPtr[i];
380 TGraph* gr =
new TGraph(numSamps, &offsets[0], &corrs[0]);
381 if(numSamps != numSamplesUpsampled){
382 gr->SetName(TString::Format(
"grCorr_%d_%d", ant1, ant2));
383 gr->SetTitle(TString::Format(
"Cross Correlation ant1 = %d, ant2 = %d", ant1, ant2));
386 gr->SetName(TString::Format(
"grCorrUpsampled_%d_%d", ant1, ant2));
387 gr->SetTitle(TString::Format(
"Upsampled Cross Correlation ant1 = %d, ant2 = %d", ant1, ant2));
393 TGraph* Acclaim::CrossCorrelator::getCrossCorrelationGraph(
AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2)
const {
395 return getCrossCorrelationGraphWorker(numSamples, pol, ant1, ant2);
398 TGraph* Acclaim::CrossCorrelator::getUpsampledCrossCorrelationGraph(
AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2)
const {
399 return getCrossCorrelationGraphWorker(numSamplesUpsampled, pol, ant1, ant2);
429 initializeVariables();
430 initTemplate(run, eventNumber);
472 getNormalizedInterpolatedTGraphs(fEv, pol,
true);
492 this->correlateEvent(fEv, pol);
508 const int nf = GET_NUM_FREQS(numSamples);
509 std::vector<std::complex<double> > fftTemp(nf);
510 std::vector<double> vTemp(numSamples);
511 std::vector<double> ccTemp(numSamples);
514 for(
int ant=0; ant < NUM_SEAVEYS; ant++){
518 for(
int i=0; i < gr->GetN(); i++){
519 vTemp[i] = gr->GetY()[i];
521 for(
int i=gr->GetN(); i < numSamples; i++){
524 FancyFFTs::doFFT(numSamples, &vTemp[0], &fftTemp[0]);
528 interpRMS2[pol][ant] = gr->GetX()[0];
531 FancyFFTs::normalizeFourierDomain(numSamples, &fftTemp[0]);
533 FancyFFTs::crossCorrelatePadded(numSamples,
542 const int offset = numSamples/2;
545 for(Int_t samp=0; samp < numSamples/2; samp++){
546 crossCorrelations[pol][ant][samp+offset] = ccTemp[samp];
549 for(Int_t samp=numSamples/2; samp < numSamples; samp++){
550 crossCorrelations[pol][ant][samp-offset] = ccTemp[samp];
556 double norm = 1./(numSamples*numSamples);
558 for(
int ant=0; ant < NUM_SEAVEYS; ant++){
559 for(Int_t samp=0; samp < numSamples; samp++){
560 crossCorrelations[pol][ant][samp]*=norm;
579 deltaT += interpRMS2[pol][ant];
580 deltaT -= startTimes[pol][ant];
582 double offsetTime = -0.5*numSamples*NOMINAL_SAMPLING_DELTAT;
584 TGraph* gr =
new TGraph(numSamples);
585 TString title = TString::Format(
"Template Cross-correlation - ant %d ", ant+1);
588 for(
int i=0; i < numSamples; i++){
589 gr->SetPoint(i, offsetTime, crossCorrelations[pol][ant][i]);
590 offsetTime += NOMINAL_SAMPLING_DELTAT;
602 Double_t Acclaim::TemplateCorrelator::getCrossCorrelation(
AnitaPol::AnitaPol_t pol, Int_t ant, Double_t deltaT)
const{
604 deltaT += interpRMS2[pol][ant];
605 deltaT -= startTimes[pol][ant];
607 Int_t offsetLow = floor(deltaT/nominalSamplingDeltaT);
608 Double_t dt1 = offsetLow*nominalSamplingDeltaT;
609 Double_t interpPrefactor = (deltaT - dt1)/nominalSamplingDeltaT;
610 offsetLow += numSamples/2;
612 Double_t c1 = crossCorrelations[pol][ant][offsetLow];
613 Double_t c2 = crossCorrelations[pol][ant][offsetLow+1];
614 Double_t cInterp = interpPrefactor*(c2 - c1) + c1;
624 Double_t Acclaim::TemplateCorrelator::getPeakCorrelation(
AnitaPol::AnitaPol_t pol, Double_t minOffset, Double_t maxOffset, Double_t stepSize)
const{
626 double dt = minOffset;
628 double bestCorr = -DBL_MAX;
629 while(dt < maxOffset){
632 for(
int ant=0; ant < NUM_SEAVEYS; ant++){
633 thisCorr += this->getCrossCorrelation(pol, ant, dt);
636 if(thisCorr > bestCorr){
virtual void correlateEvent(const FilteredAnitaEvent *fEv)
TemplateCorrelator(Int_t run, UInt_t eventNumber)
int getEvent(int eventNumber, bool quiet=false)
A filter strategy defines the sets of filters that are used and provides some introspection abilities...
TGraph * getCrossCorrelationGraph(AnitaPol::AnitaPol_t pol, Int_t ant) const
virtual UsefulAnitaEvent * useful(bool force_reload=false)
virtual ~TemplateCorrelator()
void initTemplate(const FilteredAnitaEvent *fEv)
const AnalysisWaveform * getRawGraph(UInt_t i) const
Adu5Pat * gps(bool force_reload=false)
const AnalysisWaveform * getFilteredGraph(UInt_t i) const
virtual RawAnitaHeader * header(bool force_reload=false)
This class is intended to store all the necessary data about an ANITA event for filtering and analysi...
enum AnitaPol::EAnitaPol AnitaPol_t
Polarisation enumeration.
const RawAnitaHeader * getHeader() const