1 #include "CrossCorrelator.h" 20 for(Int_t pol = AnitaPol::kHorizontal; pol < AnitaPol::kNotAPol; pol++){
36 for(Int_t pol = AnitaPol::kHorizontal; pol < AnitaPol::kNotAPol; pol++){
37 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
57 AnitaGeomTool* geom = AnitaGeomTool::Instance();
58 for(Int_t pol=0; pol < NUM_POL; pol++){
59 for(
int ant=0; ant<NUM_SEAVEYS; ant++){
60 rArray[pol].push_back(geom->getAntR(ant, AnitaPol::AnitaPol_t(pol)));
61 zArray[pol].push_back(geom->getAntZ(ant, AnitaPol::AnitaPol_t(pol)));
62 phiArrayDeg[pol].push_back(geom->getAntPhiPositionRelToAftFore(ant, AnitaPol::AnitaPol_t(pol))*TMath::RadToDeg());
65 aftForeOffset = geom->aftForeOffsetAngleVertical*TMath::RadToDeg();
69 for(Int_t pol=0; pol < NUM_POL; pol++){
70 for(Int_t peakInd=0; peakInd < MAX_NUM_PEAKS; peakInd++){
88 for(Long_t threadInd=0; threadInd<NUM_THREADS; threadInd++){
91 threadArgVals.
ptr =
this;
92 threadArgsVec.push_back(threadArgVals);
110 std::cerr << __PRETTY_FUNCTION__ << std::endl;
111 std::cerr <<
"\tupsample factor = " << UPSAMPLE_FACTOR << std::endl;
112 std::cerr <<
"\tBin size theta (deg) = " << Double_t(THETA_RANGE)/NUM_BINS_THETA << std::endl;
113 std::cerr <<
"\tBin size phi (deg) = " << Double_t(PHI_RANGE)/NUM_BINS_PHI << std::endl;
114 std::cerr <<
"\tdeltaTs array size = " 115 <<
sizeof(Double_t)*NUM_POL*
numCombos*NUM_PHI*NUM_BINS_PHI*NUM_BINS_THETA
116 <<
" bytes" << std::endl;
130 Double_t phi0 = -aftForeOffset;
131 if(phi0 < -DEGREES_IN_CIRCLE/2){
132 phi0+=DEGREES_IN_CIRCLE;
134 else if(phi0 >= DEGREES_IN_CIRCLE/2){
135 phi0-=DEGREES_IN_CIRCLE;
137 return phi0 - PHI_RANGE/2;
147 Double_t peakValue, peakPhiDeg, peakThetaDeg;
148 TH2D* hBlank =
getMap(AnitaPol::kVertical, peakValue, peakPhiDeg, peakThetaDeg);
150 const double maxDeltaAngleDeg = 45;
152 std::set<std::vector<Int_t> > theSet;
154 Int_t newComboIndices[NUM_SEAVEYS][NUM_SEAVEYS];
155 for(
int ant1=0; ant1 < NUM_SEAVEYS; ant1++){
156 for(
int ant2=0; ant2 < NUM_SEAVEYS; ant2++){
157 newComboIndices[ant1][ant2] = -1;
160 std::vector<int> newComboToAnt1s;
161 std::vector<int> newComboToAnt2s;
163 for(
int biny=0; biny <= hBlank->GetNbinsY(); biny++){
164 Double_t recoTheta = -1*hBlank->GetYaxis()->GetBinLowEdge(biny);
168 for(
int binx=0; binx <= hBlank->GetNbinsX(); binx++){
169 hBlank->SetBinContent(binx, biny, 0);
172 std::vector<Int_t> theCombos;
173 Double_t recoPhi = recoPhi = hBlank->GetXaxis()->GetBinLowEdge(binx);
175 for(
int ant1=0; ant1 < NUM_SEAVEYS; ant1++){
176 Double_t antPhi1 =
phiArrayDeg[AnitaPol::kVertical].at(ant1);
179 if(TMath::Sqrt(dPhi1*dPhi1 + dTheta*dTheta) < maxDeltaAngleDeg){
180 for(
int ant2=ant1+1; ant2 < NUM_SEAVEYS; ant2++){
181 Double_t antPhi2 =
phiArrayDeg[AnitaPol::kVertical].at(ant2);
184 if(TMath::Sqrt(dPhi2*dPhi2 + dTheta*dTheta) < maxDeltaAngleDeg){
187 Int_t thisCombo = newComboIndices[ant1][ant2];
189 newComboIndices[ant1][ant2] = newComboToAnt1s.size();
190 newComboIndices[ant2][ant1] = newComboToAnt1s.size();
191 newComboToAnt1s.push_back(newComboToAnt1s.size());
192 newComboToAnt2s.push_back(newComboToAnt2s.size());
193 thisCombo = newComboIndices[ant1][ant2];
195 theCombos.push_back(thisCombo);
201 std::pair<std::set<std::vector<int> >::iterator,
bool>ret = theSet.insert(theCombos);
203 hBlank->SetBinContent(binx, biny, theCombos.size());
208 std::cout <<
"This combinatorics has " << theSet.size()
209 <<
", vs. the 16 you would have in a phi-sector based method" << std::endl;
210 std::cout <<
"This method also gives us... " << newComboToAnt1s.size()
211 <<
" = " << newComboToAnt2s.size() <<
" combos, vs. " << NUM_COMBOS << std::endl;
212 hBlank->SetTitle(
"Number of antenna pairs in reconstruction; Azimuth (Degrees); Elevation (Degrees)");
234 Double_t dt, Int_t nSamp){
238 std::vector<Double_t> newTimes = std::vector<Double_t>(nSamp, 0);
239 std::vector<Double_t> newVolts = std::vector<Double_t>(nSamp, 0);
240 std::vector<Int_t> isPadding = std::vector<Int_t>(nSamp, 1);
241 Double_t thisStartTime = grIn->GetX()[0];
242 Double_t lastTime = grIn->GetX()[grIn->GetN()-1];
250 std::vector<Double_t> tVec(grIn->GetX(), grIn->GetX() + grIn->GetN());
251 std::vector<Double_t> vVec(grIn->GetY(), grIn->GetY() + grIn->GetN());
254 ROOT::Math::Interpolator chanInterp(tVec,vVec,ROOT::Math::Interpolation::kAKIMA);
258 Double_t time = startTime;
260 for(Int_t samp = 0; samp < nSamp; samp++){
261 newTimes.at(samp) = time;
262 if(time >= thisStartTime && time <= lastTime){
263 Double_t V = chanInterp.Eval(time);
264 newVolts.at(samp) = V;
266 isPadding.at(samp) = 0;
270 newVolts.at(samp) = 0;
276 Double_t mean = sum/meanCount;
277 for(Int_t samp=0; samp < nSamp; samp++){
278 if(isPadding.at(samp)==0){
279 newVolts.at(samp) -= mean;
283 return new TGraph(nSamp, &newTimes[0], &newVolts[0]);
297 AnitaPol::AnitaPol_t pol){
303 std::vector<Double_t> earliestStart(NUM_POL, 100);
304 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
305 grs[pol][ant] = usefulEvent->getGraph(ant, (AnitaPol::AnitaPol_t)pol);
308 if(
grs[pol][ant]->GetX()[0]<earliestStart.at(pol)){
309 earliestStart.at(pol) =
grs[pol][ant]->GetX()[0];
313 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
317 Double_t sumOfVSquared = 0;
318 for(
int samp=0; samp <
grsResampled[pol][ant]->GetN(); samp++){
320 sumOfVSquared += V*V;
324 for(
int samp=0; samp <
grsResampled[pol][ant]->GetN(); samp++){
329 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
332 TString name2, title2;
333 if(pol==AnitaPol::kHorizontal){
334 name = TString::Format(
"gr%dH_%u", ant, usefulEvent->eventNumber);
335 name2 = TString::Format(
"grInterp%dH_%u", ant, usefulEvent->eventNumber);
336 title = TString::Format(
"Antenna %d HPOL eventNumber %u", ant, usefulEvent->eventNumber);
337 title2 = TString::Format(
"Antenna %d HPOL eventNumber %u (evenly resampled)",
338 ant, usefulEvent->eventNumber);
340 else if(pol==AnitaPol::kVertical){
341 name = TString::Format(
"gr%dV_%u", ant, usefulEvent->eventNumber);
342 name2 = TString::Format(
"grInterp%dV_%u", ant, usefulEvent->eventNumber);
343 title = TString::Format(
"Antenna %d VPOL eventNumber %u", ant, usefulEvent->eventNumber);
344 title2 = TString::Format(
"Antenna %d VPOL eventNumber %u (evenly resampled)",
345 ant, usefulEvent->eventNumber);
347 title +=
"; Time (ns); Voltage (mV)";
348 grs[pol][ant]->SetName(name);
350 grs[pol][ant]->SetTitle(title);
369 const Double_t anitaBandLowEdge = 200;
370 const Double_t anitaBandHighEdge = 1200;
372 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
434 Double_t notchLowEdgeMHz, Double_t notchHighEdgeMHz){
439 for(
int freqInd=0; freqInd < numFreqs; freqInd++){
440 if(deltaF_MHz*freqInd >= notchLowEdgeMHz && deltaF_MHz*freqInd < notchHighEdgeMHz){
442 ffts[pol][ant][freqInd].real(0);
443 ffts[pol][ant][freqInd].imag(0);
463 Double_t sumOfVSquared = 0;
464 for(
int freqInd=0; freqInd < numFreqs; freqInd++){
465 Double_t re =
ffts[pol][ant][freqInd].real();
466 Double_t im =
ffts[pol][ant][freqInd].imag();
467 Double_t factor = freqInd == numFreqs - 1 ? 0.5 : 1;
468 sumOfVSquared += factor*(re*re + im*im);
472 Double_t norm = TMath::Sqrt(timeDomainVSquared);
474 for(
int freqInd=0; freqInd < numFreqs; freqInd++){
475 Double_t re =
ffts[pol][ant][freqInd].real();
476 Double_t im =
ffts[pol][ant][freqInd].imag();
478 ffts[pol][ant][freqInd].real(re/norm);
479 ffts[pol][ant][freqInd].imag(im/norm);
502 Double_t* phiDegs, Double_t* thetaDegs){
506 if(numPeaks > MAX_NUM_PEAKS){
507 std::cerr <<
"Warning in "<< __PRETTY_FUNCTION__ <<
" in " << __FILE__
508 <<
". numPeaks = " << numPeaks <<
", CrossCorrelator compiled with MAX_NUM_PEAKS = " 509 << MAX_NUM_PEAKS <<
", setting numPeaks = " << MAX_NUM_PEAKS << std::endl;
510 numPeaks = MAX_NUM_PEAKS;
516 for(Int_t peakInd=0; peakInd < numPeaks; peakInd++){
517 peakValues[peakInd] = -999;
518 phiDegs[peakInd] = -999;
519 thetaDegs[peakInd] = -999;
522 Int_t allowedBins[NUM_BINS_PHI*NUM_PHI][NUM_BINS_THETA];
523 for(Int_t phiBin=0; phiBin<NUM_BINS_PHI*NUM_PHI; phiBin++){
524 for(Int_t thetaBin = 0; thetaBin < NUM_BINS_THETA; thetaBin++){
525 allowedBins[phiBin][thetaBin] = 1;
529 for(Int_t peakInd=0; peakInd < numPeaks; peakInd++){
530 for(Int_t phiBin=0; phiBin<NUM_BINS_PHI*NUM_PHI; phiBin++){
531 for(Int_t thetaBin = 0; thetaBin < NUM_BINS_THETA; thetaBin++){
532 if(
coarseMap[pol][phiBin][thetaBin] > peakValues[peakInd]){
533 if(allowedBins[phiBin][thetaBin] > 0){
534 peakValues[peakInd] =
coarseMap[pol][phiBin][thetaBin];
536 thetaDegs[peakInd] =
thetaWaves[thetaBin]*TMath::RadToDeg();
544 if(peakValues[peakInd]){
545 for(Int_t phiBin=0; phiBin<NUM_BINS_PHI*NUM_PHI; phiBin++){
550 for(Int_t thetaBin = 0; thetaBin < NUM_BINS_THETA; thetaBin++){
551 Double_t thetaDeg =
thetaWaves[thetaBin]*TMath::RadToDeg();
555 allowedBins[phiBin][thetaBin] = 0;
579 for(Int_t polInd = AnitaPol::kHorizontal; polInd < AnitaPol::kNotAPol; polInd++){
580 AnitaPol::AnitaPol_t pol = (AnitaPol::AnitaPol_t)polInd;
588 if(numFinePeaks > 0 && numFinePeaks <= numCoarsePeaks){
589 for(Int_t peakInd=numFinePeaks-1; peakInd >= 0; peakInd--){
624 Double_t& value, Double_t& phiDeg, Double_t& thetaDeg){
626 if(peakIndex < MAX_NUM_PEAKS){
632 std::cerr <<
"Warning in "<< __PRETTY_FUNCTION__ <<
" in " << __FILE__ <<
"." 633 <<
"Requested peak info with index too large. peakIndex = " 634 << peakIndex <<
", MAX_NUM_PEAKS = " << MAX_NUM_PEAKS <<
"." << std::endl;
657 Double_t& value, Double_t& phiDeg, Double_t& thetaDeg){
659 if(peakIndex < MAX_NUM_PEAKS){
665 std::cerr <<
"Warning in "<< __PRETTY_FUNCTION__ <<
" in " << __FILE__ <<
"." 666 <<
"Requested peak info with index too large. peakIndex = " 667 << peakIndex <<
", MAX_NUM_PEAKS = " << MAX_NUM_PEAKS <<
"." << std::endl;
691 for(Int_t pol = AnitaPol::kHorizontal; pol < AnitaPol::kNotAPol; pol++){
741 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
742 TString name = TString::Format(
"threadCorr%ld", threadInd);
745 (
void*)&threadArgsVec.at(threadInd))
749 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
753 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
757 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
780 AnitaPol::AnitaPol_t pol = ptr->
threadPol;
784 Int_t numCombosAllThreads = combosToUse->size();
785 Int_t numCorrPerThread = numCombosAllThreads/NUM_THREADS;
786 Int_t numRemainder = numCombosAllThreads%NUM_THREADS;
788 Int_t startComboInd = threadInd*numCorrPerThread;
790 Double_t stash[NUM_SAMPLES*UPSAMPLE_FACTOR*PAD_FACTOR];
792 for(
int comboInd=startComboInd; comboInd<startComboInd+numCorrPerThread; comboInd++){
793 Int_t combo = combosToUse->at(comboInd);
819 if(threadInd < numRemainder){
820 Int_t numDoneInAllThreads = NUM_THREADS*numCorrPerThread;
821 Int_t comboInd = numDoneInAllThreads + threadInd;
822 Int_t combo = combosToUse->at(comboInd);
866 AnitaPol::AnitaPol_t pol = ptr->
threadPol;
868 Int_t numCorrPerThread = NUM_COMBOS/NUM_THREADS;
869 Int_t startCombo = threadInd*numCorrPerThread;
871 Double_t stash[NUM_SAMPLES*PAD_FACTOR];
873 for(
int combo=startCombo; combo<startCombo+numCorrPerThread; combo++){
877 ptr->
ffts[pol][ant2],
878 ptr->
ffts[pol][ant1],
883 for(Int_t samp=0; samp < ptr->
numSamples; samp++){
889 for(Int_t samp=0; samp < ptr->
numSamples/2; samp++){
916 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
917 TString name = TString::Format(
"threadUpsampledCorr%ld", threadInd);
920 (
void*)&threadArgsVec.at(threadInd))
924 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
928 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
932 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
955 Double_t& time, Double_t& value){
978 Double_t& time, Double_t& value){
997 Double_t& time, Double_t& value){
1020 Double_t& time, Double_t& value){
1059 const Int_t numPowers = 13;
1060 const Double_t params[numPowers] = {0.00000e+00, 0.00000e+00, -1.68751e-05, 0.00000e+00,
1061 2.77815e-08, 0.00000e+00, -8.29351e-12, 0.00000e+00,
1062 1.15064e-15, 0.00000e+00, -7.71170e-20, 0.00000e+00,
1066 Double_t offBoresightDelay = 0;
1067 for(
int power=0; power < numPowers; power++){
1068 offBoresightDelay += params[power]*TMath::Power(deltaPhiDeg, power);
1071 return offBoresightDelay;
1108 return (delay1-delay2);
1128 Double_t tanThetaW = tan(thetaWave);
1129 Double_t part1 =
zArray[pol].at(ant1)*tanThetaW -
rArray[pol].at(ant1)*cos(phiWave-TMath::DegToRad()*
phiArrayDeg[pol].at(ant1));
1130 Double_t part2 =
zArray[pol].at(ant2)*tanThetaW -
rArray[pol].at(ant2)*cos(phiWave-TMath::DegToRad()*
phiArrayDeg[pol].at(ant2));
1131 Double_t tdiff = 1e9*((cos(thetaWave) * (part2 - part1))/SPEED_OF_LIGHT);
1146 AnitaGeomTool* geom = AnitaGeomTool::Instance();
1147 geom->useKurtAnita3Numbers(1);
1148 for(Int_t pol=0; pol < NUM_POL; pol++){
1149 for(
int ant=0; ant<NUM_SEAVEYS; ant++){
1150 rArray[pol].at(ant) = geom->getAntR(ant, AnitaPol::AnitaPol_t(pol));
1151 zArray[pol].at(ant) = geom->getAntZ(ant, AnitaPol::AnitaPol_t(pol));
1152 phiArrayDeg[pol].at(ant) = geom->getAntPhiPositionRelToAftFore(ant, AnitaPol::AnitaPol_t(pol))*TMath::RadToDeg();
1156 AnitaEventCalibrator* cal = AnitaEventCalibrator::Instance();
1157 for(
int surf=0; surf < NUM_SURF; surf++){
1158 for(
int chan=0; chan < NUM_CHAN; chan++){
1159 cal->relativePhaseCenterToAmpaDelays[surf][chan] = 0;
1164 geom->useKurtAnita3Numbers(0);
1187 for(Int_t ant1=0; ant1 < NUM_SEAVEYS; ant1++){
1188 for(Int_t ant2=0; ant2 < NUM_SEAVEYS; ant2++){
1194 for(Int_t ant1=0; ant1<NUM_SEAVEYS; ant1++){
1195 Double_t phiSect1 = ant1%NUM_PHI;
1196 for(Int_t ant2=ant1+1; ant2<NUM_SEAVEYS; ant2++){
1197 Double_t phiSect2 = ant2%NUM_PHI;
1199 if(TMath::Abs(phiSect1 - phiSect2) <= DELTA_PHI_SECT || TMath::Abs(phiSect1 - phiSect2) >= (NUM_PHI-DELTA_PHI_SECT)){
1209 std::cerr <<
"Warning! in = " << __PRETTY_FUNCTION__ << std::endl;
1210 std::cerr <<
"\tnumCombos = " <<
numCombos <<
"." << std::endl;
1211 std::cerr <<
"\tNUM_COMBOS = " << NUM_COMBOS <<
"." << std::endl;
1212 std::cerr <<
"\tExpecting NUM_COMBOS == numCombos." << std::endl;
1213 std::cerr <<
"\tSeriously bad things are probably about to happen." << std::endl;
1214 std::cerr <<
"\tCheck the combinatorics!" << std::endl;
1231 const Double_t phiBinSize = Double_t(PHI_RANGE)/NUM_BINS_PHI;
1232 for(Int_t phiIndex=0; phiIndex < NUM_BINS_PHI*NUM_PHI; phiIndex++){
1233 Double_t phiDeg = phi0 + phiIndex*phiBinSize;
1234 Double_t phiWave = TMath::DegToRad()*phiDeg;
1238 const Double_t thetaBinSize = (Double_t(THETA_RANGE)/NUM_BINS_THETA);
1239 for(Int_t thetaIndex=0; thetaIndex < NUM_BINS_THETA; thetaIndex++){
1240 Double_t thetaWaveDeg = (thetaIndex-NUM_BINS_THETA/2)*thetaBinSize;
1241 Double_t thetaWave = thetaWaveDeg*TMath::DegToRad();
1245 for(Int_t polInd=0; polInd<NUM_POL; polInd++){
1246 AnitaPol::AnitaPol_t pol = (AnitaPol::AnitaPol_t) polInd;
1247 for(Int_t combo=0; combo<
numCombos; combo++){
1251 for(Int_t phiSector = 0; phiSector<NUM_PHI; phiSector++){
1252 for(Int_t phiInd = 0; phiInd < NUM_BINS_PHI; phiInd++){
1253 Int_t phiBin = phiSector*NUM_BINS_PHI + phiInd;
1256 for(Int_t thetaBin = 0; thetaBin < NUM_BINS_THETA; thetaBin++){
1263 offsetLows[pol][combo][phiBin][thetaBin] = offsetLow;
1265 interpPreFactors[pol][combo][phiBin][thetaBin] = (deltaT - dt1)/nominalSamplingDeltaT;
1277 minThetaDegZoom = -THETA_RANGE/2 - THETA_RANGE_ZOOM/2;
1280 for(Int_t thetaIndex=0; thetaIndex < NUM_BINS_THETA_ZOOM_TOTAL; thetaIndex++){
1281 Double_t thetaWaveDeg = minThetaDegZoom + thetaIndex*ZOOM_BIN_SIZE_THETA;
1282 Double_t thetaWave = thetaWaveDeg*TMath::DegToRad();
1288 for(Int_t pol=0; pol<AnitaPol::kNotAPol; pol++){
1289 for(Int_t combo=0; combo < NUM_COMBOS; combo++){
1292 for(Int_t thetaIndex=0; thetaIndex < NUM_BINS_THETA_ZOOM_TOTAL; thetaIndex++){
1298 for(Int_t pol=0; pol<AnitaPol::kNotAPol; pol++){
1299 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
1300 for(Int_t phiIndex=0; phiIndex < NUM_BINS_PHI_ZOOM_TOTAL; phiIndex++){
1301 Double_t phiDeg = minPhiDegZoom + phiIndex*ZOOM_BIN_SIZE_PHI;
1302 Double_t phiWave = phiDeg*TMath::DegToRad();
1307 for(Int_t combo=0; combo < NUM_COMBOS; combo++){
1311 for(Int_t phiIndex=0; phiIndex < NUM_BINS_PHI_ZOOM_TOTAL; phiIndex++){
1313 Double_t phiDeg = minPhiDegZoom + phiIndex*ZOOM_BIN_SIZE_PHI;
1346 Int_t absDeltaPhiSect = TMath::Abs(deltaPhiSect);
1349 Int_t phiSectorOfAnt1 = ant1%NUM_PHI;
1350 Bool_t ant1InRange = TMath::Abs(phiSector - (phiSectorOfAnt1))<=absDeltaPhiSect;
1353 ant1InRange = ant1InRange || TMath::Abs(phiSector - (phiSectorOfAnt1))>=(NUM_PHI-absDeltaPhiSect);
1355 Int_t phiSectorOfAnt2 = ant2%NUM_PHI;
1356 Bool_t ant2InRange = TMath::Abs(phiSector - (phiSectorOfAnt2))<=absDeltaPhiSect;
1357 ant2InRange = ant2InRange || TMath::Abs(phiSector - (phiSectorOfAnt2))>=(NUM_PHI-absDeltaPhiSect);
1360 Bool_t extraCondition =
true;
1361 if(deltaPhiSect < 0){
1362 extraCondition = (phiSectorOfAnt1==phiSector || phiSectorOfAnt2==phiSector);
1365 return (ant1InRange && ant2InRange && extraCondition);
1378 for(Int_t phiSector = 0; phiSector<NUM_PHI; phiSector++){
1380 for(Int_t combo=0; combo<
numCombos; combo++){
1404 Int_t combo, Double_t deltaT){
1412 offsetLow += offset;
1413 Int_t offsetHigh = offsetLow+1;
1443 Double_t& peakPhiDeg, Double_t& peakThetaDeg,
1444 UShort_t l3TrigPattern){
1447 name += pol == AnitaPol::kVertical ?
"ImageV" :
"ImageH";
1450 TString title = TString::Format(
"Event %u ",
eventNumber[pol]);
1451 title += (pol == AnitaPol::kVertical ?
"VPOL" :
"HPOL");
1455 Double_t phiMax = phiMin + DEGREES_IN_CIRCLE;
1456 Double_t thetaMin = -THETA_RANGE/2;
1457 Double_t thetaMax = THETA_RANGE/2;
1459 TH2D* hImage =
new TH2D(name, title,
1460 NUM_BINS_PHI*NUM_PHI, phiMin, phiMax,
1461 NUM_BINS_THETA, thetaMin, thetaMax);
1462 hImage->GetXaxis()->SetTitle(
"Azimuth (Degrees)");
1463 hImage->GetYaxis()->SetTitle(
"Elevation (Degrees)");
1470 peakThetaDeg = -9999;
1472 for(Int_t phiSector=0; phiSector<NUM_PHI; phiSector++){
1475 for(Int_t phiBin = phiSector*NUM_BINS_PHI; phiBin < NUM_BINS_PHI*(phiSector+1); phiBin++){
1476 for(Int_t thetaBin = 0; thetaBin < NUM_BINS_THETA; thetaBin++){
1477 hImage->SetBinContent(phiBin+1, thetaBin+1,
coarseMap[pol][phiBin][thetaBin]);
1478 if(
coarseMap[pol][phiBin][thetaBin] > peakValue){
1479 peakValue =
coarseMap[pol][phiBin][thetaBin];
1480 peakPhiDeg = hImage->GetXaxis()->GetBinLowEdge(phiBin+1);
1481 peakThetaDeg = hImage->GetYaxis()->GetBinLowEdge(thetaBin+1);
1504 TString name =
"hZoom";
1505 name += pol == AnitaPol::kVertical ?
"ImageV" :
"ImageH";
1508 TString title = TString::Format(
"Event %u ",
eventNumber[pol]);
1509 title += (pol == AnitaPol::kVertical ?
"VPOL" :
"HPOL");
1510 title +=
" Zoomed In";
1513 TH2D* hImage =
new TH2D(name, title,
1514 NUM_BINS_PHI_ZOOM, zoomPhiMin, zoomPhiMin + PHI_RANGE_ZOOM,
1515 NUM_BINS_THETA_ZOOM, zoomThetaMin, zoomThetaMin + THETA_RANGE_ZOOM);
1516 hImage->GetXaxis()->SetTitle(
"Azimuth (Degrees)");
1517 hImage->GetYaxis()->SetTitle(
"Elevation (Degrees)");
1519 for(Int_t thetaBin = 0; thetaBin < NUM_BINS_THETA_ZOOM; thetaBin++){
1520 for(Int_t phiBin = 0; phiBin < NUM_BINS_PHI_ZOOM; phiBin++){
1521 hImage->SetBinContent(phiBin+1, thetaBin+1,
fineMap[pol][thetaBin][phiBin]);
1545 Double_t& peakThetaDeg){
1551 return getMap(pol, imagePeak, peakPhiDeg, peakThetaDeg);
1566 Double_t imagePeak, peakPhiDeg, peakThetaDeg;
1586 Double_t& peakPhiDeg, Double_t& peakThetaDeg,
1587 UShort_t l3TrigPattern){
1593 return getMap(pol, imagePeak, peakPhiDeg, peakThetaDeg, l3TrigPattern);
1613 Double_t& imagePeak, Double_t& peakPhiDeg, Double_t& peakThetaDeg,
1614 Double_t zoomCenterPhiDeg, Double_t zoomCenterThetaDeg){
1620 zoomCenterPhiDeg, zoomCenterThetaDeg);
1642 Double_t& peakThetaDeg, UShort_t l3TrigPattern,
1643 Double_t zoomCenterPhiDeg, Double_t zoomCenterThetaDeg){
1648 zoomCenterPhiDeg, zoomCenterThetaDeg);
1668 Double_t zoomCenterPhiDeg,Double_t zoomCenterThetaDeg){
1670 Double_t imagePeak, peakPhiDeg, peakThetaDeg;
1674 zoomCenterPhiDeg, zoomCenterThetaDeg);
1699 Double_t& peakPhiDeg, Double_t& peakThetaDeg){
1704 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1705 TString name = TString::Format(
"threadMap%ld", threadInd);
1706 mapThreads.push_back(
new TThread(name.Data(),
1708 (
void*)&threadArgsVec.at(threadInd))
1712 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1716 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1720 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1726 imagePeak = -DBL_MAX;
1727 for(Long_t threadInd=0; threadInd<NUM_THREADS; threadInd++){
1757 AnitaPol::AnitaPol_t pol = ptr->
threadPol;
1765 const Int_t numPhiBinsPerThread = (NUM_BINS_PHI*NUM_PHI)/NUM_THREADS;
1766 const Int_t startThetaBin = 0;
1767 const Int_t endThetaBin = NUM_BINS_THETA;
1768 const Int_t startPhiBin = threadInd*numPhiBinsPerThread;
1769 const Int_t endPhiBin = startPhiBin+numPhiBinsPerThread;
1772 Int_t peakPhiBin = -1;
1773 Int_t peakThetaBin = -1;
1776 for(Int_t phiBin = startPhiBin; phiBin < endPhiBin; phiBin++){
1777 for(Int_t thetaBin = startThetaBin; thetaBin < endThetaBin; thetaBin++){
1778 ptr->
coarseMap[pol][phiBin][thetaBin] = 0;
1782 Int_t phiSector = -1;
1783 std::vector<Int_t>* combosToUse = NULL;
1784 for(Int_t phiBin = startPhiBin; phiBin < endPhiBin; phiBin++){
1785 Int_t thisPhiSector = phiBin/NUM_BINS_PHI;
1786 if(phiSector!=thisPhiSector){
1787 phiSector = thisPhiSector;
1790 for(UInt_t comboInd=0; comboInd<combosToUse->size(); comboInd++){
1791 Int_t combo = combosToUse->at(comboInd);
1795 for(Int_t thetaBin = startThetaBin; thetaBin < endThetaBin; thetaBin++){
1796 Int_t offsetLow = ptr->
offsetLows[pol][combo][phiBin][thetaBin];
1799 Double_t cInterp = ptr->
interpPreFactors[pol][combo][phiBin][thetaBin]*(c2 - c1) + c1;
1800 ptr->
coarseMap[pol][phiBin][thetaBin] += cInterp;
1805 for(Int_t phiBin = startPhiBin; phiBin < endPhiBin; phiBin++){
1806 for(Int_t thetaBin = startThetaBin; thetaBin < endThetaBin; thetaBin++){
1809 ptr->
coarseMap[pol][phiBin][thetaBin] /= combosToUse->size();
1813 peakPhiBin = phiBin;
1814 peakThetaBin = thetaBin;
1844 Double_t& peakPhiDeg, Double_t& peakThetaDeg,
1845 Double_t zoomCenterPhiDeg,
1846 Double_t zoomCenterThetaDeg){
1849 if(zoomCenterPhiDeg < -500 || zoomCenterThetaDeg < -500 ||
1850 zoomCenterPhiDeg >= 500 || zoomCenterThetaDeg >= 500){
1852 std::cerr <<
"Warning in "<< __PRETTY_FUNCTION__ <<
" in " << __FILE__ <<
". zoomCenterPhiDeg = " 1853 << zoomCenterPhiDeg <<
" and zoomCenterThetaDeg = " << zoomCenterThetaDeg
1854 <<
" these values look suspicious so I'm skipping this reconstruction." << std::endl;
1857 peakThetaDeg = -9999;
1863 deltaPhiDegPhi0 = deltaPhiDegPhi0 < 0 ? deltaPhiDegPhi0 + DEGREES_IN_CIRCLE : deltaPhiDegPhi0;
1865 Int_t phiSector = floor(deltaPhiDegPhi0)/PHI_RANGE;
1870 zoomCenterPhiDeg = (TMath::Nint(zoomCenterPhiDeg/ZOOM_BIN_SIZE_PHI))*ZOOM_BIN_SIZE_PHI;
1871 zoomCenterThetaDeg = (TMath::Nint(zoomCenterThetaDeg/ZOOM_BIN_SIZE_THETA))*ZOOM_BIN_SIZE_THETA;
1873 zoomPhiMin = zoomCenterPhiDeg - PHI_RANGE_ZOOM/2;
1874 zoomThetaMin = zoomCenterThetaDeg - THETA_RANGE_ZOOM/2;
1877 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1878 TString name = TString::Format(
"threadZoomMap%ld", threadInd);
1879 mapThreads.push_back(
new TThread(name.Data(),
1881 (
void*)&threadArgsVec.at(threadInd))
1885 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1889 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1893 for(
long threadInd=0; threadInd<NUM_THREADS; threadInd++){
1899 imagePeak = -DBL_MAX;
1900 for(Long_t threadInd=0; threadInd<NUM_THREADS; threadInd++){
1928 AnitaPol::AnitaPol_t pol = ptr->
threadPol;
1936 const Int_t numPhiBinsPerThread = NUM_BINS_PHI_ZOOM/NUM_THREADS;
1937 const Int_t startThetaBin = 0;
1938 const Int_t endThetaBin = NUM_BINS_THETA_ZOOM;
1939 const Int_t startPhiBin = threadInd*numPhiBinsPerThread;
1940 const Int_t endPhiBin = startPhiBin+numPhiBinsPerThread;
1947 Int_t peakPhiBin = -1;
1948 Int_t peakThetaBin = -1;
1955 Int_t phiZoomBase = TMath::Nint((ptr->zoomPhiMin - ptr->minPhiDegZoom)/ZOOM_BIN_SIZE_PHI);
1956 Int_t thetaZoomBase = TMath::Nint((ptr->zoomThetaMin - ptr->minThetaDegZoom)/ZOOM_BIN_SIZE_THETA);
1958 for(Int_t thetaBin = startThetaBin; thetaBin < endThetaBin; thetaBin++){
1959 for(Int_t phiBin = startPhiBin; phiBin < endPhiBin; phiBin++){
1960 ptr->
fineMap[pol][thetaBin][phiBin]=0;
1965 for(UInt_t comboInd=0; comboInd<combosToUse->size(); comboInd++){
1966 Int_t combo = combosToUse->at(comboInd);
1970 for(Int_t thetaBin = startThetaBin; thetaBin < endThetaBin; thetaBin++){
1971 Int_t zoomThetaInd = thetaZoomBase + thetaBin;
1972 Double_t partBA = ptr->
partBAsZoom[pol][combo][zoomThetaInd];
1974 for(Int_t phiBin = startPhiBin; phiBin < endPhiBin; phiBin++){
1975 Int_t zoomPhiInd = phiZoomBase + phiBin;
1976 Double_t deltaT = dtFactor*(partBA - ptr->
part21sZoom[pol][combo][zoomPhiInd]);
1978 if(kUseOffAxisDelay != 0){
1979 deltaT += kUseOffAxisDelay*ptr->
offAxisDelays[pol][combo][zoomPhiInd];
1988 Int_t offsetLow = (int) offsetLowDouble - (offsetLowDouble < (
int) offsetLowDouble);
1992 offsetLow += offset;
1995 Double_t cInterp = deltaT*(c2 - c1) + c1;
1997 ptr->
fineMap[pol][thetaBin][phiBin] += cInterp;
2002 for(Int_t thetaBin = startThetaBin; thetaBin < endThetaBin; thetaBin++){
2003 for(Int_t phiBin = startPhiBin; phiBin < endPhiBin; phiBin++){
2005 ptr->
fineMap[pol][thetaBin][phiBin] /= combosToUse->size();
2010 peakPhiBin = phiBin;
2011 peakThetaBin = thetaBin;
2018 ptr->
threadPeakPhiDeg[threadInd] = ptr->zoomPhiMin + peakPhiBin*ZOOM_BIN_SIZE_PHI;
2019 ptr->
threadPeakThetaDeg[threadInd] = ptr->zoomThetaMin + peakThetaBin*ZOOM_BIN_SIZE_THETA;
2040 for(Int_t ant=0; ant<NUM_SEAVEYS; ant++){
2042 delete grs[pol][ant];
2043 grs[pol][ant] = NULL;
2072 AnitaGeomTool* geom = AnitaGeomTool::Instance();
2073 geom->useKurtAnita3Numbers(0);
2074 AnitaEventCalibrator* cal = AnitaEventCalibrator::Instance();
2077 std::ifstream lindasNums(pathToLindasFile.Data());
2078 if(lindasNums.is_open()==0){
2083 Double_t dr, dPhiRad, dz, dt;
2085 while(lindasNums >> ant >> dr >> dz >> dPhiRad >> dt){
2087 Int_t surf, chan, ant2;
2088 geom->getSurfChanAntFromRingPhiPol(AnitaRing::AnitaRing_t (ant/NUM_PHI), ant%NUM_PHI, pol,
2091 Double_t newR = geom->rPhaseCentreFromVerticalHornKurtAnita3[ant][pol] + dr;
2092 Double_t newPhi = geom->azPhaseCentreFromVerticalHornKurtAnita3[ant][pol] + dPhiRad;
2093 Double_t newZ = geom->zPhaseCentreFromVerticalHornKurtAnita3[ant][pol] + dz;
2096 if(newPhi >= TMath::TwoPi()){
2097 newPhi -= TMath::TwoPi();
2099 else if(newPhi < 0){
2100 newPhi += TMath::TwoPi();
2103 geom->rPhaseCentreFromVerticalHorn[ant][pol] = newR;
2104 geom->azPhaseCentreFromVerticalHorn[ant][pol] = newPhi;
2105 geom->zPhaseCentreFromVerticalHorn[ant][pol] = newZ;
2106 cal->relativePhaseCenterToAmpaDelays[surf][chan] = newT;
2111 if(ant != NUM_SEAVEYS - 1){
2113 std::cerr <<
"Warning in " << __PRETTY_FUNCTION__ <<
" in " << __FILE__ << std::endl;
2114 std::cerr <<
"It looks like you didn't read to the end of Linda's geometry file!" << std::endl;
2139 Int_t ant1, Int_t ant2){
2160 std::vector<Double_t> offsets = std::vector<Double_t>(numSamps, 0);
2161 std::vector<Double_t> corrs = std::vector<Double_t>(numSamps, 0);
2163 for(Int_t i=0; i<numSamps; i++){
2164 Int_t offset = (i - numSamps/2);
2165 offsets.at(i) = offset*graphDt;
2166 corrs.at(i) = corrPtr[i];
2170 TGraph* gr =
new TGraph(numSamps, &offsets[0], &corrs[0]);
2172 gr->SetName(TString::Format(
"grCorr_%d_%d", ant1, ant2));
2173 gr->SetTitle(TString::Format(
"Cross Correlation ant1 = %d, ant2 = %d", ant1, ant2));
2176 gr->SetName(TString::Format(
"grCorrUpsampled_%d_%d", ant1, ant2));
2177 gr->SetTitle(TString::Format(
"Upsampled Cross Correlation ant1 = %d, ant2 = %d", ant1, ant2));
2230 Int_t phiSectorOfPeak = -1;
2231 Double_t bestDeltaPhiOfPeakToAnt = DEGREES_IN_CIRCLE;
2232 for(
int ant=0; ant < NUM_SEAVEYS; ant++){
2235 if(deltaPhiOfPeakToAnt < bestDeltaPhiOfPeakToAnt){
2236 bestDeltaPhiOfPeakToAnt = deltaPhiOfPeakToAnt;
2237 phiSectorOfPeak = (ant % NUM_PHI);
2240 return phiSectorOfPeak;
2256 Double_t thetaDeg, Int_t maxDeltaPhiSect,
2276 Double_t thetaDeg, Int_t maxDeltaPhiSect,
2297 Double_t thetaDeg, Int_t maxDeltaPhiSect,
2305 Double_t phiRad = phiDeg*TMath::DegToRad();
2306 Double_t thetaRad = thetaDeg*TMath::DegToRad();
2311 const Int_t firstAnt = centerPhiSector;
2313 std::pair<Int_t, Int_t> key(nSamp, 0);
2324 std::vector<Double_t> tArray(nSamp, 0);
2326 for(Int_t samp=0; samp<nSamp; samp++){
2327 tArray.at(samp) = t0 + samp*theDeltaT;
2328 vArray[samp] *=
interpRMS[pol][firstAnt];
2336 TGraph* grCoherent =
new TGraph(nSamp/2, &tArray[0], &vArray[0]);
2338 for(Int_t deltaPhiSect=-maxDeltaPhiSect; deltaPhiSect<=maxDeltaPhiSect; deltaPhiSect++){
2340 Int_t phiSector = deltaPhiSect + centerPhiSector;
2341 phiSector = phiSector < 0 ? phiSector + NUM_PHI : phiSector;
2342 phiSector = phiSector >= NUM_PHI ? phiSector - NUM_PHI : phiSector;
2344 for(Int_t ring=0; ring<NUM_RING; ring++){
2345 Int_t ant= phiSector + ring*NUM_PHI;
2361 Int_t offset1 = floor(deltaT/theDeltaT);
2362 Int_t offset2 = ceil(deltaT/theDeltaT);
2367 Double_t tOverDeltaT = (deltaT - theDeltaT*offset1)/theDeltaT;
2369 for(Int_t samp=0; samp<grCoherent->GetN(); samp++){
2370 Int_t samp1 = samp + offset1;
2371 Int_t samp2 = samp + offset2;
2372 if(samp1 >= 0 && samp1 < grCoherent->GetN() && samp2 >= 0 && samp2 < grCoherent->GetN()){
2374 Double_t v1 = vArray[samp1];
2375 Double_t v2 = vArray[samp2];
2377 Double_t vInterp = tOverDeltaT*(v2 - v1) + v1;
2379 grCoherent->GetY()[samp] += vInterp*
interpRMS[pol][ant];
2385 const Double_t timeToEvalRms = 10;
2386 for(Int_t samp3=0; samp3 <
grs[pol][ant]->GetN(); samp3++){
2387 if(
grs[pol][ant]->GetX()[samp3] -
grs[pol][ant]->GetX()[0] < timeToEvalRms){
2388 rms +=
grs[pol][ant]->GetY()[samp3]*
grs[pol][ant]->GetY()[samp3];
2397 TString name = nSamp ==
numSamples ?
"grCoherent" :
"grInterpCoherent";
2399 for(Int_t samp=0; samp<grCoherent->GetN(); samp++){
2400 grCoherent->GetY()[samp]/=numAnts;
2403 if(pol==AnitaPol::kHorizontal){
2404 name += TString::Format(
"H_%u",
eventNumber[pol]);
2408 name += TString::Format(
"V_%u",
eventNumber[pol]);
2412 title += TString::Format(
"Coherently Summed Waveform for arrival direction elevation %4.2lf (Deg) and azimuth %4.2lf (Deg); Time (ns); Voltage (mV)", thetaDeg, phiDeg);
2414 grCoherent->SetName(name);
2415 grCoherent->SetTitle(title);
2418 rms = TMath::Sqrt(rms);
2425 snr = (maxY - minY)/(2*rms);
TH2D * makeGlobalImage(AnitaPol::AnitaPol_t pol, Double_t &imagePeak, Double_t &peakPhiDeg, Double_t &peakThetaDeg)
Creates an interferometric map using plane wave deltaTs and antenna pairs from all phi-sectors...
Double_t singleAntennaOffAxisDelay(Double_t deltaPhiDeg)
Get the off-axis delay for an off boresight angle.
Int_t numSamplesUpsampled
Number of samples in waveform after padding and up sampling.
void findPeakValues(AnitaPol::AnitaPol_t pol, Int_t numPeaks, Double_t *peakValues, Double_t *phiDegs, Double_t *thetaDegs)
Goes through the coarseMap and finds the top N values.
TString zoomModeNames[kNumZoomModes]
Maps text to the zoomMode_t enum, used for histogram names/titles.
void fillCombosToUse()
Creates vectors of antenna combo indices and puts them in the combosToUseGlobal map.
void deleteAllWaveforms(AnitaPol::AnitaPol_t pol)
Deletes the waveform TGraphs in memory and removes dangling pointers.
UInt_t lastEventNormalized[NUM_POL]
Prevents cross-correlation of the same event twice.
Double_t fineMap[NUM_POL][NUM_BINS_THETA_ZOOM][NUM_BINS_PHI_ZOOM]
Internal storage for the finely binned map.
A class to take in UsefulAnitaEvents and get interferometric maps with a single function.
Int_t comboIndices[NUM_SEAVEYS][NUM_SEAVEYS]
Array mapping ant1+ant2 to combo index.
Int_t offsetLows[NUM_POL][NUM_COMBOS][NUM_PHI *NUM_BINS_PHI][NUM_BINS_THETA]
The interpolation factor for neighbouring samples.
std::vector< TThread * > upsampledCorrThreads
TThreads for doing upsampled cross correlations.
Double_t threadImagePeak[NUM_THREADS]
Store image peaks found by different threads.
static void * doSomeCrossCorrelationsThreaded(void *voidPtrArgs)
Static member function which generates the coarsely binned set of cross correlations from the FFTs he...
TGraph * getCrossCorrelationGraphWorker(Int_t numSamps, AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2)
Called by wrapper functions. Turns internal correlation arrays into TGraphs to be seen by humans...
Int_t kDeltaPhiSect
Specifies how many phi-sectors around peak use in reconstruction.
TGraph * getUpsampledCrossCorrelationGraph(AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2)
Turns internal upsampled correlation arrays into TGraphs to be seen by humans.
std::vector< Double_t > rArray[NUM_POL]
Vector of antenna radial positions.
std::vector< TThread * > corrThreads
TThreads for doing cross correlations.
Double_t zoomedPhiWaveLookup[NUM_BINS_PHI_ZOOM_TOTAL]
Cached phi for zoomed image.
Int_t threadPhiSector
phi-sector to use in thread functions.
TGraph * grs[NUM_POL][NUM_SEAVEYS]
Raw waveforms obtained from the UsefulAnitaEvent.
void reconstructEvent(UsefulAnitaEvent *usefulEvent, Int_t numFinePeaks=MAX_NUM_PEAKS, Int_t numCoarsePeaks=MAX_NUM_PEAKS)
Reconstruct event.
Double_t coarseMapPeakThetaDegs[NUM_POL][MAX_NUM_PEAKS]
Stores the peak theta (degrees) of the interally stored map.
Double_t coarseMap[NUM_POL][NUM_BINS_PHI *NUM_PHI][NUM_BINS_THETA]
Internal storage for the coarsely binned map.
complex< double > * zeroPadFFT(complex< double > *fft, int numSamples, int numSamplesUpsampled)
Zero padds FFTts,.
~CrossCorrelator()
Destructor.
double * crossCorrelate(int len, double *v1, double *v2, int threadInd=0)
Cross correlates the two input arrays.
TH2D * getZoomMap(AnitaPol::AnitaPol_t pol)
Gets an actual histogram of the zoomed in map.
complex< double > * doFFT(int len, double *input, bool copyOutputToNewArray, int threadInd=0)
Does a forward fast fourier transform on a real input array.
TGraph * grsResampled[NUM_POL][NUM_SEAVEYS]
Evenly resampled TGraphs.
void do5PhiSectorCombinatorics()
Function to index all possible antenna pairs for use in reconstuction.
TString mapModeNames[kNumMapModes]
Maps text to the mapMode_t enum, used for histogram names/titles.
TH2D * getMap(AnitaPol::AnitaPol_t pol, Double_t &peakValue, Double_t &peakPhiDeg, Double_t &peakThetaDeg, UShort_t l3TrigPattern=ALL_PHI_TRIGS)
Gets an actual histogram of the zoomed in map.
Int_t kDoSimpleSatelliteFiltering
Does a simple 52MHz wide notch at 260 if flag is greater than 0.
void printInfo()
Prints some summary information about the CrossCorrelator to stdout.
Double_t threadPeakPhiDeg[NUM_THREADS]
Store phi of image peaks found by different threads.
void correlateEvent(UsefulAnitaEvent *realEvent)
Correlate the event.
Int_t kUseOffAxisDelay
Flag for whether or not to apply off axis delay to deltaT expected.
static void * makeSomeOfZoomImageThreaded(void *voidPtrArgs)
Static member function which fills the interferometric maps.
Int_t getPhiSectorOfAntennaClosestToPhiDeg(AnitaPol::AnitaPol_t pol, Double_t phiDeg)
Finds the phi-sector closest to a particular phi direction.
Double_t part21sZoom[NUM_POL][NUM_COMBOS][NUM_BINS_PHI_ZOOM_TOTAL]
Yet more geometric caching.
Double_t interpRMS[NUM_POL][NUM_SEAVEYS]
RMS of interpolated TGraphs.
UInt_t eventNumber[NUM_POL]
For tracking event number.
void reconstruct(AnitaPol::AnitaPol_t pol, Double_t &imagePeak, Double_t &peakPhiDeg, Double_t &peakThetaDeg)
Wrapper function which launches the threaded functions, which fill the interferometric maps...
std::vector< TThread * > mapThreads
TThreads for doing interferometric map making.
std::complex< Double_t > ffts[NUM_POL][NUM_SEAVEYS][GETNUMFREQS(NUM_SAMPLES *PAD_FACTOR)]
FFTs of evenly resampled waveforms.
void getFinePeakInfo(AnitaPol::AnitaPol_t pol, Int_t peakIndex, Double_t &value, Double_t &phiDeg, Double_t &thetaDeg)
Gets the results from the fine reconstruction.
Double_t zoomedCosPartLookup[NUM_POL][NUM_SEAVEYS][NUM_BINS_PHI_ZOOM_TOTAL]
Cached part of the deltaT calculation.
std::complex< Double_t > fftsPadded[NUM_POL][NUM_SEAVEYS][GETNUMFREQS(NUM_SAMPLES *PAD_FACTOR *UPSAMPLE_FACTOR)]
FFTs of evenly resampled waveforms, padded with zeros so that the inverse fourier transform is interp...
Double_t offAxisDelays[NUM_POL][NUM_COMBOS][NUM_BINS_PHI_ZOOM_TOTAL]
Off-axis delays for fine binned images.
static void * makeSomeOfImageThreaded(void *voidPtrArgs)
Static member function which fills the interferometric maps.
CrossCorrelator()
Constructor.
Double_t crossCorrelations[NUM_POL][NUM_COMBOS][NUM_SAMPLES *PAD_FACTOR]
Cross correlations.
void renormalizeFourierDomain(AnitaPol::AnitaPol_t pol, Int_t ant)
Scales the fft such that the inverse fft would have mean=0 and rms=1. For use after notching...
Double_t zoomedThetaWaves[NUM_BINS_THETA_ZOOM_TOTAL]
Cached theta for zoomed image.
void doAllCrossCorrelationsThreaded(AnitaPol::AnitaPol_t pol)
Wrapper function which launches the threads for generating all the cross correlations.
TGraph * getCrossCorrelationGraph(AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2)
Turns internal correlation arrays into TGraphs to be seen by humans.
TH2D * makeTriggeredImage(AnitaPol::AnitaPol_t pol, Double_t &imagePeak, Double_t &peakPhiDeg, Double_t &peakThetaDeg, UShort_t l3TrigPattern)
Creates an interferometric map using plane wave deltaTs and l3Triggered pairs from all phi-sectors...
CrossCorrelator * ptr
Pointer to the CrossCorrelator.
Double_t getDeltaTExpected(AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2, Double_t phiWave, Double_t thetaWave)
Function to calculate the time taken by a plane wave to cross the payload.
void simple370MHzSatelliteNotch(AnitaPol::AnitaPol_t pol, Int_t ant)
Applies a 40MHz wide notch centered at 370 MHz to filter another satellite frequency.
std::vector< Int_t > combosToUseGlobal[NUM_PHI]
Depends on L3 trigger for global image.
Double_t interpRMS2[NUM_POL][NUM_SEAVEYS]
RMS of interpolated TGraphs with extra zero padding.
Double_t correlationDeltaT
nominalSamplingDeltaT/UPSAMPLE_FACTOR, deltaT of for interpolation.
Double_t partBAsZoom[NUM_POL][NUM_COMBOS][NUM_BINS_THETA_ZOOM_TOTAL]
Yet more geometric caching.
Double_t getBin0PhiDeg()
Single function to get the angle of the first bin of the interferometric histogram.
int getNumFreqs(int len)
Get the number of frequencies from the number of samples.
void doFFTs(AnitaPol::AnitaPol_t pol)
Takes FFTs of the normalized, evenly resampled waveforms and puts them in memory. ...
bool makeNewPlanIfNeeded(int len, int threadInd=0)
Creates new fftw plan to handle 1D transforms of length len if they haven't been allocated already...
Long_t threadInd
The thread index.
Double_t fineMapPeakValues[NUM_POL][MAX_NUM_PEAKS]
Stores the peak of the interally stored map.
void fillDeltaTLookup()
Fills in an array of cached deltaTs between antenna pairs as a function of arrival direction...
std::set< std::vector< int > >::iterator comboSetIterator[NUM_BINS_THETA][NUM_BINS_PHI *NUM_PHI]
Pointer to a vector of combo indices (actually an iterator over a set, but you know what I mean)...
Int_t kOnlyThisCombo
For debugging, only fill histograms with one particular antenna pair.
std::vector< Int_t > comboToAnt1s
Vector mapping combo index to ant1.
TGraph * makeCoherentlySummedWaveform(AnitaPol::AnitaPol_t pol, Double_t phiDeg, Double_t thetaDeg, Int_t maxDeltaPhiSect, Double_t &snr)
Creates the coherently summed waveform from the FFTs held in memory.
AnitaPol::AnitaPol_t threadPol
Polarization to use in thread functions.
std::vector< Double_t > zArray[NUM_POL]
Vector of antenna heights.
void getCoarsePeakInfo(AnitaPol::AnitaPol_t pol, Int_t peakIndex, Double_t &value, Double_t &phiDeg, Double_t &thetaDeg)
Gets the results from the coarse reconstruction.
std::vector< Int_t > comboToAnt2s
Vector mapping combo index to ant2.
TGraph * interpolateWithStartTimeAndZeroMean(TGraph *grIn, Double_t startTime, Double_t dt, Int_t nSamp)
Creates an interpolated TGraph with zero mean.
Double_t coarseMapPeakValues[NUM_POL][MAX_NUM_PEAKS]
Stores the peak of the interally stored map.
Int_t numSamples
Number of samples in waveform after padding.
TH2D * initializeNewCombinatorics()
static Int_t directlyInsertGeometry(TString pathToLindasFile, AnitaPol::AnitaPol_t pol)
Used to insert phase center geometry files from Linda.
Double_t relativeOffAxisDelay(AnitaPol::AnitaPol_t pol, Int_t ant1, Int_t ant2, Double_t phiDeg)
Get the relative off-axis delay between an antenna pair.
double * getRealArray(std::pair< Int_t, Int_t > key)
Get the real array of the internal fftw memory. Do not delete this!
TH2D * makeZoomedImage(AnitaPol::AnitaPol_t pol, UShort_t l3TrigPattern, Double_t zoomCenterPhiDeg, Double_t zoomCenterThetaDeg)
Creates an interferometric map using plane wave deltaTs centered around a particular phi/theta...
Double_t coarseMapPeakPhiDegs[NUM_POL][MAX_NUM_PEAKS]
Stores the peak phi (degrees) of the interally stored map.
void simpleNotch(AnitaPol::AnitaPol_t pol, Int_t ant, Double_t notchLowEdgeMHz, Double_t notchHighEdgeMHz)
Applies a simple notch between the given frequencies.
Container required to get threading to work inside a class, includes the thread index and the pointer...
Int_t numCombos
Number of possible antenna pairs, counted during initialization. Should equal NUM_COMBOS.
void getNormalizedInterpolatedTGraphs(UsefulAnitaEvent *realEvent, AnitaPol::AnitaPol_t pol)
Makes evenly re-sampled, normalized waveform graphs from the UsefulAnitaEvent.
void initializeVariables()
Workhorse function to set internal variables.
void getMaxUpsampledCorrelationTimeValue(AnitaPol::AnitaPol_t pol, Int_t combo, Double_t &time, Double_t &value)
Get the maximum upsampled correlation time and value from a polarization and antenna combo index...
Double_t phiWaveLookup[NUM_BINS_PHI *NUM_PHI]
Cached phi for image.
static void * doSomeUpsampledCrossCorrelationsThreaded(void *voidPtrArgs)
Static member function which generates the finely binned set of cross correlations from the FFTs held...
void insertPhotogrammetryGeometry()
Inserts the photogrammetry geometry into the CrossCorrelator internals AND the AnitaEventCalibrator i...
Double_t nominalSamplingDeltaT
ANITA-3 => 1./2.6 ns, deltaT for evenly resampling.
Double_t interpPreFactors[NUM_POL][NUM_COMBOS][NUM_PHI *NUM_BINS_PHI][NUM_BINS_THETA]
The interpolation factor for neighbouring samples.
Double_t thetaWaves[NUM_BINS_THETA]
Cached theta for image.
TGraph * makeUpsampledCoherentlySummedWaveform(AnitaPol::AnitaPol_t pol, Double_t phiDeg, Double_t thetaDeg, Int_t maxDeltaPhiSect, Double_t &snr)
Creates the coherently summed waveform from the zero padded FFTs held in memory.
double * doInvFFT(int len, complex< double > *input, bool copyOutputToNewArray, int threadInd=0)
Does an inverse fast fourier transform on an array of complex<double>s.
void doUpsampledCrossCorrelationsThreaded(AnitaPol::AnitaPol_t pol, Int_t phiSector)
Static member function which generates the finely binned set of cross correlations from the FFTs held...
Double_t zoomedTanThetaWaves[NUM_BINS_THETA_ZOOM_TOTAL]
Cached tan(theta) for zoomed image.
Double_t maxDPhiDeg
Variable for testing how wide an off axis angle is used in reconstruction.
Double_t threadPeakThetaDeg[NUM_THREADS]
Store theta of image peaks found by different threads.
TGraph * makeCoherentWorker(AnitaPol::AnitaPol_t pol, Double_t phiDeg, Double_t thetaDeg, Int_t maxDeltaPhiSect, Double_t &snr, Int_t nSamp)
Worker function to create the coherently summed waveform from either the regular ffts or the padded f...
void getMaxCorrelationTimeValue(AnitaPol::AnitaPol_t pol, Int_t combo, Double_t &time, Double_t &value)
Get the maximum correlation time and value from a polarization and antenna combo index.
std::vector< Double_t > phiArrayDeg[NUM_POL]
Vector of antenna azimuth positions.
void reconstructZoom(AnitaPol::AnitaPol_t pol, Double_t &imagePeak, Double_t &peakPhiDeg, Double_t &peakThetaDeg, Double_t zoomCenterPhiDeg=0, Double_t zoomCenterThetaDeg=0)
Wrapper function which launches the threaded functions, which fill the zoomed maps.
void simple260MHzSatelliteNotch(AnitaPol::AnitaPol_t pol, Int_t ant)
Applies a 52MHz wide notch centered at 260 MHz to filter the most problematic satellite frequency...
Double_t crossCorrelationsUpsampled[NUM_POL][NUM_COMBOS][NUM_SAMPLES *PAD_FACTOR *UPSAMPLE_FACTOR *PAD_FACTOR]
Upsampled cross correlations.
Bool_t useCombo(Int_t ant1, Int_t ant2, Int_t phiSector, Int_t deltaPhiSect)
This function encodes whether a pair of antennas should be used in a particular phi sector...
Double_t fineMapPeakThetaDegs[NUM_POL][MAX_NUM_PEAKS]
Stores the peak theta (degrees) of the interally stored map.
Double_t getInterpolatedUpsampledCorrelationValue(AnitaPol::AnitaPol_t pol, Int_t combo, Double_t deltaT)
Linearly interpolates between upsampled correlation points.
Double_t zoomedCosThetaWaves[NUM_BINS_THETA_ZOOM_TOTAL]
Cached cos(theta) for zoomed image.
Double_t fineMapPeakPhiDegs[NUM_POL][MAX_NUM_PEAKS]
Stores the peak phi (degrees) of the interally stored map.