4 #include "AntennaPositions.h" 6 #include "AnalysisWaveform.h" 10 #include "Minuit2/Minuit2Minimizer.h" 11 #include "FilteredAnitaEvent.h" 12 #include "FreqDomainFunction.h" 13 #include "TimeDependentAverage.h" 14 #include "RawAnitaHeader.h" 15 #include "ResponseManager.h" 19 static TH2D * hpower =0;
20 static TH2D * hphase =0;
21 static std::vector<TGraph*> vpower;
22 static std::vector<TGraph*> vphase;
25 static double getOffAxisPowerMultiplier(
int pol,
int plane,
double f,
double deg)
28 static TFile foff(Form(
"%s/share/data/A3offaxis.root", getenv(
"ANITA_UTIL_INSTALL_DIR")));
29 static bool init =
false;
30 static TGraph2D * data[2][2];
34 data[0][1]= (TGraph2D*) foff.Get(
"Hpol_Hplane");
35 data[0][0]= (TGraph2D*) foff.Get(
"Hpol_Eplane");
36 data[1][1]= (TGraph2D*) foff.Get(
"Vpol_Hplane");
37 data[1][0] = (TGraph2D*) foff.Get(
"Vpol_Eplane");
41 return pow(10,data[pol][plane]->Interpolate(f, deg)/10);
44 static void setupHists()
47 TFile f(Form(
"%s/share/data/templates/crTmpltsA3.root",getenv(
"ANITA_UTIL_INSTALL_DIR")));
49 for (
int i = 0; i < 27; i++)
52 g->SetTitle(Form(
"Template %d",i));
55 wf->setTitle(g->GetTitle());
66 double val = gpower->peakVal(&peak);
68 for (
int j = 0; j < gpower->GetN(); j++)
70 if (j < peak)
continue;
72 if (gpower->GetY()[j] / val < 1e-3)
79 gpower->SetTitle(g->GetTitle());
80 gphase->SetTitle(g->GetTitle());
81 vpower.push_back(gpower);
82 vphase.push_back(gphase);
85 double df = vpower[0]->GetX()[1] - vpower[0]->GetX()[0];
87 hpower =
new TH2D(
"hpower",
"POWER;freq;T", vpower[0]->GetN(), -df/2, vpower[0]->GetX()[vpower[0]->GetN()-1]+df/2,
89 hphase =
new TH2D(
"hphase",
"PHASE;freq;T", vpower[0]->GetN(), -df/2, vpower[0]->GetX()[vpower[0]->GetN()-1]+df/2,
92 hpower->SetDirectory(0);
93 hphase->SetDirectory(0);
95 for (
int x = 1; x <= hpower->GetNbinsX(); x++)
97 for (
int y = 1; y <= hpower->GetNbinsY(); y++)
99 hpower->SetBinContent(x,y, vpower[y-1]->GetY()[x-1]);
100 hphase->SetBinContent(x,y, vphase[y-1]->GetN() < x ? vphase[y-1]->GetY()[vphase[y-1]->GetN()-1] : vphase[y-1]->GetY()[x-1]);
106 static std::complex<double> crfitfn (
double f,
const double * pars)
109 if (!hpower) setupHists();
112 if (T < -13 || T > 13)
return 0;
113 if (f < 0 || f> hpower->GetXaxis()->GetBinCenter(hpower->GetNbinsX()))
return 0;
114 double dphi = pars[1];
115 double dtheta = pars[2];
116 int ipol = int(pars[3]);
119 double atten_phi = dphi == 0 ? 1 : getOffAxisPowerMultiplier(ipol, ipol == 0,f, dphi);
120 double atten_theta = dtheta == 0 ? 1 : getOffAxisPowerMultiplier(ipol, ipol == 1,f, dtheta);
123 double pow = hpower->Interpolate(f,T) * atten_phi*atten_theta;
124 double phase = hphase->Interpolate(f,T);
125 double amp = sqrt(pow);
127 return std::complex<double>( cos(phase) * amp, sin(phase)*amp);
133 class EASFitFn :
public ROOT::Math::IBaseFunctionMultiDim
141 for (
unsigned i = 0; i < fns.size(); i++)
150 : dedisperse(dedisperse), freqonly(freqonly), nants(nants), pol(pol), ants(ants), rms(nants), event(ev),wfs(nants), fns(nants), t(t), phi(phi), theta(theta), rm(rm)
154 for (
int i = 0; i < nants; i++)
158 if (!freqonly && dedisperse) rm->response(0,ants[i])->deconvolveInPlace(wfs[i], &allpass);
159 fns[i] =
new FreqDomainFunction(crfitfn, 4, rm->response(0,ants[i]),wfs[i]->deltaT()/4,-wfs[i]->even()->GetX()[wfs[i]->Neven()-1], wfs[i]->even()->GetX()[wfs[i]->Neven()-1]);
160 if (!freqonly && dedisperse) fns[i]->dedisperseResponse(
true);
163 virtual ROOT::Math::IBaseFunctionMultiDim * Clone()
const {
return new EASFitFn(rms.size(), ants, event, pol, t, phi,theta,rm,freqonly,dedisperse); }
164 virtual unsigned int NDim()
const {
return 2 *nants+3; }
167 virtual double DoEval(
const double *x)
const 175 for (
int i = 0; i < nants; i++)
178 double dphi =
FFTtools::wrap(UCorrelator::AntennaPositions::instance()->phiAnt[0][ants[i]] -phi,360,0);
179 double dtheta = 10 - theta;
181 double p[6] = { A*x[2*i+3], freqonly ? 0 : t0-delta_t + x[2*i+4], T, dphi, dtheta,(double)pol};
183 fns[i]->setParameters(p);
187 double df = wfs[i]->deltaF();
188 for (
int j = 0; j < wfs[i]->Nfreq(); j++)
190 chisq += pow(wfs[i]->power()->GetY()[j] - fns[i]->evalPower(j*df),2);
195 for (
int j = 0; j < wfs[i]->Neven(); j++)
198 chisq += pow(wfs[i]->even()->GetY()[j] - fns[i]->eval(wfs[i]->even()->GetX()[j]),2)/((wfs[i]->Neven() - 3) *rms[i]*rms[i]);
200 chisq += pow(wfs[i]->uneven()->GetY()[j] - fns[i]->eval(wfs[i]->uneven()->GetX()[j]),2)/((wfs[i]->Nuneven() - 3) *rms[i]*rms[i]);
208 void plot(TCanvas *c, std::vector<TObject*> *save = 0)
210 c->Divide(nants/3,3);
212 for (
int i = 0; i < nants; i++)
216 wf->
updateEven()->SetTitle(Form(
"Ant %d", ants[i]));
217 wf->
updateEven()->setPlottingLimits(1.1,
true,20);
228 TF1 * f = fns[i]->makeTF1(Form(
"fn_%d",i));
229 if (save) save->push_back(f);
241 std::vector<double> rms;
243 std::vector<AnalysisWaveform *> wfs;
244 mutable std::vector<FreqDomainFunction *> fns;
253 int UCorrelator::EASFitter::fitEvent(
int nants,
const int * ants,
255 double phi,
double theta,
bool dedisperse)
261 double freq_scale = freq_fit.fns[0]->waveform()->power()->peakVal();
264 double scale = time_fit.fns[0]->waveform()->even()->peakVal(&toffset_loc,0,-1,
true);
266 for (
int side_of_cone = -1; side_of_cone <=1; side_of_cone+=2)
270 ROOT::Minuit2::Minuit2Minimizer min_freq;
273 double fA = wf->
even()->peakVal(&loc, 0,-1,
true) / freq_scale ;
275 min_freq.SetLimitedVariable(ivar++,
"A", fA, fA*0.1, 0, 2*fA);
276 min_freq.SetFixedVariable(ivar++,
"t0", 0);
277 min_freq.SetLimitedVariable(ivar++,
"T", side_of_cone*7,0.1,side_of_cone > 0 ? 0 : -13, side_of_cone > 0 ? 13 : 0);
279 for (
int i =0; i < nants; i++)
282 min_freq.SetFixedVariable(ivar++, Form(
"relA_%d",i), 1);
283 min_freq.SetFixedVariable(ivar++, Form(
"tadj_%d",i), 0);
286 min_freq.SetFunction(freq_fit);
289 printf(
"Side of Cone: %d, status: %d. T: %g, A: %g\n",
290 side_of_cone, min_freq.Status(), min_freq.X()[2], min_freq.X()[0]);
293 for (
int polarity = -1; polarity <=1; polarity+=2)
297 ROOT::Minuit2::Minuit2Minimizer min_time;
299 min_time.SetFunction(time_fit);
304 double A = wf->
even()->peakVal(&loc, 0,-1,
true) / scale ;
305 double t0 = wf->
even()->GetX()[loc];
308 min_time.SetLimitedVariable(ivar++,
"A", A, A*0.1, 0, 2*A);
309 min_time.SetVariable(ivar++,
"t0", t0, 0.5);
310 min_time.SetLimitedVariable(ivar++,
"T", 7,0.1,-13,13);
312 for (
int i =0; i < nants; i++)
314 printf(
"ant: %d\n", ants[i]);
316 min_time.SetFixedVariable(ivar++, Form(
"relA_%d",i), 1);
317 min_time.SetLimitedVariable(ivar++, Form(
"tadj_%d",i), 0, 0.1 , -1, 1);
321 min_time.PrintResults();
329 UCorrelator::EASFitter::~EASFitter()
331 for (
unsigned i = 0; i < plots.size(); i++)
delete plots[i];
332 for (
unsigned i = 0; i < save.size(); i++)
delete plots[i];
double getDeltaT(int ant1, int ant2, double phi, double theta, AnitaPol::AnitaPol_t pol, bool includeGroupDelay=false)
const AnalysisWaveform * getRawGraph(UInt_t i) const
This class is intended to store all the necessary data about an ANITA event for filtering and analysi...
static double getRMS(double t, int ipol, int ant, int nsecs=10)
const RawAnitaHeader * getHeader() const