AnitaTemplates.cc
1 #include "AnitaTemplates.h"
2 
3 //---------------------------------------------------------------------------------------------------------
10  zeroInternals();
11 }
12 
14  //don't need to do anything I don't think
15 }
16 
17 
18 void AnitaTemplateSummary::zeroInternals(){
19 
20  for (Int_t poli=0; poli<NUM_POLS; poli++) {
21  for (Int_t dir=0; dir < maxDirectionsPerPol; dir++)
22  {
23  memset(&coherent[poli][dir],0,sizeof(SingleTemplateResult));
24 
25  memset(&deconvolved[poli][dir],0,sizeof(SingleTemplateResult));
26  }
27  }
28 
29  return;
30 }
31 
32 
33 
34 
35 //---------------------------------------------------------------------------------------------------------
42  : length(inLength), dT(0.1)
43 {
44 
45  kTmpltsLoaded = false;
46  kTmpltsDeconv = false;
47 
48  fNotchStr = "";
49 
50  //initialize the TGraphs to NULL at least, the FFTs are allocated in the "get" stuff.
51  theImpTemplate = NULL;
52  theWaisTemplate = NULL;
53  fUseAverageCRTemplate = false;
54  fDoWindow = false;
55 
56  for (int i=0; i < numCRTemplates; i++) {
57  theCRTemplates[i] = NULL;
58  }
59  if(AnitaVersion::get() == 4) fillNotchConfigs();
60 
61  zeroInternals();
62 }
63 
65  zeroInternals();
66 }
67 
68 
70  /* in case you want to delete everything */
71 
72  if (theImpTemplate != NULL) { delete theImpTemplate; theImpTemplate = NULL; }
73  if (theWaisTemplate != NULL) { delete theWaisTemplate; theWaisTemplate = NULL; }
74  for (int i=0; i < numCRTemplates; i++) {
75  delete theCRTemplates[i];
76  theCRTemplates[i] = NULL;
77  }
78 
79  /* if it is loaded, free the FFT stuff too */
80  if (kTmpltsLoaded) {
81  delete[] theImpTemplateFFT;
82  delete[] theWaisTemplateFFT;
83  for (int i=0; i < numCRTemplates; i++) {
84  delete[] theCRTemplates[i];
85  }
86  std::cout << "delete CR ffts" << std::endl;
87  }
88 
89  kTmpltsLoaded = false;
90  return;
91 }
92 
93 void AnitaTemplateMachine::fillNotchConfigs()
94 {
95  int tempTime;
96  std::string tempStr;
97  char* installDir = getenv("ANITA_UTIL_INSTALL_DIR");
98  std::ifstream inf(Form("%s/share/AnitaAnalysisFramework/responses/TUFFs/index.txt", installDir));
99  while(inf >> tempStr >> tempTime)
100  {
101  payloadTimes.push_back(tempTime);
102  notchConfigs.push_back(tempStr);
103  }
104  inf.close();
105 }
106 
107 void AnitaTemplateMachine::getImpulseResponseTemplate(int version) {
108 
109  //and get the "averaged" impulse response as the template"
110  char* installDir = getenv("ANITA_UTIL_INSTALL_DIR");
111  TString name;
112  if(version == 4)
113  {
114  name = Form("%s/share/AnitaAnalysisFramework/responses/TUFFs/averages/%s.imp", installDir, fNotchStr.c_str());
115  }
116  else name = Form("%s/share/AnitaAnalysisFramework/responses/SingleBRotter/all.imp", installDir);
117  TGraph *grTemplateRaw = new TGraph(name.Data());
118  //waveforms are normally a little over 1024 so lets pad to 2048 (defined in length above)
119  TGraph *grTemplatePadded = FFTtools::padWaveToLength(grTemplateRaw,length);
120  delete grTemplateRaw;
121 
122 
123  //Make it start at zero
124  double xStart = grTemplatePadded->GetX()[0];
125  for (int pt=0; pt<grTemplatePadded->GetN(); pt++) grTemplatePadded->GetX()[pt] -= xStart;
126 
127 
128  //then cut it back down with a window function (or not)
129  // int peakHilb = -1;
130  // TGraph *grTemplateCut = windowDispersed(grTemplatePadded,peakHilb);
131  // delete grTemplatePadded;
132  //and finally normalize it (last step!)
133 
134 
135  TGraph *grTemplate = FFTtools::normalizeWaveform(grTemplatePadded);
136  delete grTemplatePadded;
137 
138  //give it a name
139  grTemplate->SetName("templateImp");
140 
141  theImpTemplate = grTemplate;
142 
143  //and get the FFT of it as well, since we don't want to do this every single event
144  theImpTemplateFFT = FFTtools::doFFT(grTemplate->GetN(),grTemplate->GetY());
145 
146  return;
147 }
148 
149 
150 
151 void AnitaTemplateMachine::getCRTemplates(int version) {
152 
153  char* installDir = getenv("ANITA_UTIL_INSTALL_DIR");
154  TString fname;
155  if(version == 4 && !fUseAverageCRTemplate)
156  {
157  fname = Form("%s/share/AnitaAnalysisFramework/templates/crTmpltsA4_%s.root", installDir, fNotchStr.c_str());
158  }
159  else if(version == 4 && fUseAverageCRTemplate)
160  {
161  fname = Form("%s/share/AnitaAnalysisFramework/templates/averageA4CR_%s.txt", installDir, fNotchStr.c_str());
162  }
163  else if(version != 4 && fUseAverageCRTemplate)
164  {
165  fname = Form("%s/share/AnitaAnalysisFramework/templates/averageA3CR.txt", installDir);
166  }
167  else fname = Form("%s/share/AnitaAnalysisFramework/templates/crTmpltsA3.root", installDir);
168 
169  if(!fUseAverageCRTemplate)
170  {
171  TFile *inFile = TFile::Open(fname.Data());
172  std::stringstream name;
173 
174  for (int i=0; i<numCRTemplates; i++) {
175  //want to get graphs 13 through 24 (like in makeTemplate.C)
176  int wave = i+13; //peak seems to be at around the 13th one, then by 23 it is basically zero
177  name.str("");
178  name << "disp" << wave;
179  TGraph *grTemplateRaw = (TGraph*)inFile->Get(name.str().c_str());
180 
181  //waveforms are super long so we can just cut it to the window dimentions
182  int peakHilb = -1;
183  TGraph *grTemplateCut = WindowingTools::windowCut(grTemplateRaw,length);
184  delete grTemplateRaw;
185 
186  //Make them start at zero
187  double xStart = grTemplateCut->GetX()[0];
188  for (int pt=0; pt<grTemplateCut->GetN(); pt++) grTemplateCut->GetX()[pt] -= xStart;
189 
190 
191  //and finally normalize it (last step!)
192  TGraph *grTemplate = FFTtools::normalizeWaveform(grTemplateCut);
193  delete grTemplateCut;
194 
195  //give it a name
196  grTemplate->SetName(name.str().c_str());
197 
198  // std::cout << "CR Template " << i << " Length: " << grTemplate->GetN() << std::endl;
199 
200  //and get the FFT of it as well, since we don't want to do this every single event
201  FFTWComplex *theTemplateFFT=FFTtools::doFFT(grTemplate->GetN(),grTemplate->GetY());
202  theCRTemplates[i] = grTemplate;
203  theCRTemplateFFTs[i] = theTemplateFFT;
204  }
205 
206  inFile->Close();
207  }
208 
209  if(fUseAverageCRTemplate)
210  {
211  TGraph* grTemplateCut = new TGraph(fname.Data());
212 
213  TGraph *grTemplate = FFTtools::normalizeWaveform(grTemplateCut);
214  delete grTemplateCut;
215 
216  //give it a name
217  grTemplate->SetName("disp0");
218 
219  //and get the FFT of it as well, since we don't want to do this every single event
220  FFTWComplex *theTemplateFFT=FFTtools::doFFT(grTemplate->GetN(),grTemplate->GetY());
221  theCRTemplates[0] = grTemplate;
222  theCRTemplateFFTs[0] = theTemplateFFT;
223 
224  //this second one is for polarity tests
225  fname = Form("%s/share/AnitaAnalysisFramework/templates/crTmpltsA4_%s.root", installDir, fNotchStr.c_str());
226  TFile *inFile = TFile::Open(fname.Data());
227  std::stringstream name;
228 
229  //want to get graphs 13 through 24 (like in makeTemplate.C)
230  int wave = 13; //peak seems to be at around the 13th one, then by 23 it is basically zero
231  name.str("");
232  name << "disp" << wave;
233  TGraph *grTemplateRaw = (TGraph*)inFile->Get(name.str().c_str());
234 
235  //waveforms are super long so we can just cut it to the window dimentions
236  int peakHilb = -1;
237  grTemplateCut = WindowingTools::windowCut(grTemplateRaw,length);
238  delete grTemplateRaw;
239 
240  //Make them start at zero
241  double xStart = grTemplateCut->GetX()[0];
242  for (int pt=0; pt<grTemplateCut->GetN(); pt++) grTemplateCut->GetX()[pt] -= xStart;
243 
244 
245  //and finally normalize it (last step!)
246  grTemplate = FFTtools::normalizeWaveform(grTemplateCut);
247  delete grTemplateCut;
248 
249  //give it a name
250  grTemplate->SetName(name.str().c_str());
251 
252  //and get the FFT of it as well, since we don't want to do this every single event
253  theTemplateFFT=FFTtools::doFFT(grTemplate->GetN(),grTemplate->GetY());
254  theCRTemplates[1] = grTemplate;
255  theCRTemplateFFTs[1] = theTemplateFFT;
256  }
257  return;
258 }
259 
260 
261 
262 void AnitaTemplateMachine::getWaisTemplate(int version) {
263 
264  char* installDir = getenv("ANITA_UTIL_INSTALL_DIR");
265  std::stringstream name;
266  name.str("");
267  if(AnitaVersion::get() == 4) name << installDir << "/share/AnitaAnalysisFramework/templates/waisTemplateA4.root";
268  else name << installDir << "/share/AnitaAnalysisFramework/templates/waisTemplateA3.root";
269  TFile *inFile = TFile::Open(name.str().c_str());
270  TGraph *grTemplateRaw = (AnitaVersion::get() == 4) ? (TGraph*)inFile->Get("wais") : (TGraph*)inFile->Get("wais01TH");
271  //the wais waveform is like N=2832, but most of it is dumb, so cut off the beginning
272  //actually just window it!
273  // dont need windowing for a4 !!
274  int peakHilb = -1;
275  TGraph *grTemplateCut = (AnitaVersion::get() == 4) ? new TGraph(grTemplateRaw->GetN(), grTemplateRaw->GetX(), grTemplateRaw->GetY()) : WindowingTools::windowCut(grTemplateRaw,length);
276  //TGraph *grTemplateCut = WindowingTools::windowCut(grTemplateRaw,length);
277  delete grTemplateRaw;
278 
279  //Make it start at zero
280  double xStart = grTemplateCut->GetX()[0];
281  for (int pt=0; pt<grTemplateCut->GetN(); pt++) grTemplateCut->GetX()[pt] -= xStart;
282 
283 
284  //and then normalize it
285  TGraph *grTemplate = FFTtools::normalizeWaveform(grTemplateCut);
286  delete grTemplateCut;
287 
288  //give it a name
289  grTemplate->SetName("templateWais");
290 
291  // std::cout << "Wais Template Length: " << grTemplate->GetN() << std::endl;
292 
293  //and get the FFT of it as well, since we don't want to do this every single event
294  theWaisTemplateFFT = FFTtools::doFFT(grTemplate->GetN(),grTemplate->GetY());
295  theWaisTemplate = grTemplate;
296 
297  inFile->Close();
298 
299  return;
300 }
301 
302 void AnitaTemplateMachine::loadTemplates(unsigned int evTime, int version) {
303 
304  std::cout << "Loading templates, length=" << length << std::endl;
305  std::string tempStr = "";
306  int i = 0;
307  if(version == 4)
308  {
309  while(i < payloadTimes.size())
310  {
311  if(evTime < payloadTimes.at(i)) break;
312  i++;
313  }
314  tempStr = notchConfigs.at(i);
315  if(kTmpltsLoaded)
316  {
317  if(tempStr.compare(fNotchStr) == 0) return;
318  }
319  kTmpltsDeconv = false;
320  }
321  fNotchStr = tempStr;
322  if (kTmpltsLoaded) zeroInternals();
323  getImpulseResponseTemplate(version);
324  getWaisTemplate(version);
325  getCRTemplates(version);
326 
327  kTmpltsLoaded = true;
328 
329  return;
330 }
331 
332 
333 
335  if(kTmpltsDeconv) return;
336 
337  std::cout << "Deconvolving templates" << std::endl;
338 
339  std::stringstream name;
340 
341  if (!isTmpltsLoaded()) {
342  std::cout << "Error in AnitaTemplateAnalyzer::deconvolveTemplates(): AnitaTemplateMachine says it has no templates!" << std::endl;
343  std::cout << " Try doing AnitaTemplateMachine::loadTemplates() at some point maybe? " << std::endl;
344  return;
345  }
346 
347  double dF = 1./(dT*length);
348 
349  int lengthFFT = (length/2 + 1);
350 
352  std::cout << "0" << std::endl;
353  theImpTemplateFFT_deconv = (FFTWComplex*)malloc(lengthFFT*sizeof(FFTWComplex));
354  for (int i=0; i<lengthFFT; i++) {
355  theImpTemplateFFT_deconv[i] = theImpTemplateFFT[i];
356  }
357  std::cout << "1" << std::endl;
358  deconv->deconvolve(lengthFFT,dF,theImpTemplateFFT_deconv,theImpTemplateFFT);
359  double* theImpTemplate_deconv_y = FFTtools::doInvFFT(length,theImpTemplateFFT_deconv);
360  std::cout << "2" << std::endl;
361  theImpTemplate_deconv = new TGraph(length,theImpTemplate->GetX(),theImpTemplate_deconv_y);
362  theImpTemplate_deconv->SetName("deconvImp");
363 
365  theWaisTemplateFFT_deconv = (FFTWComplex*)malloc(lengthFFT*sizeof(FFTWComplex));
366  for (int i=0; i<(length/2 + 1); i++) {
367  theWaisTemplateFFT_deconv[i] = theWaisTemplateFFT[i];
368  }
369  deconv->deconvolve(lengthFFT,dF,theWaisTemplateFFT_deconv,theImpTemplateFFT);
370  double* theWaisTemplate_deconv_y = FFTtools::doInvFFT(length,theWaisTemplateFFT_deconv);
371  theWaisTemplate_deconv = new TGraph(length,theWaisTemplate->GetX(),theWaisTemplate_deconv_y);
372  theWaisTemplate_deconv->SetName("deconvWais");
373 
374 
376  if(!fUseAverageCRTemplate)
377  {
378  for (int cr = 0; cr<numCRTemplates; cr++ ) {
379  theCRTemplateFFTs_deconv[cr] = (FFTWComplex*)malloc(lengthFFT*sizeof(FFTWComplex));
380  for (int i=0; i<(length/2 + 1); i++) {
381  theCRTemplateFFTs_deconv[cr][i] = theCRTemplateFFTs[cr][i];
382  }
383  deconv->deconvolve(lengthFFT,dF,theCRTemplateFFTs_deconv[cr],theImpTemplateFFT);
384  double* theCRTemplate_deconv_y = FFTtools::doInvFFT(length,theCRTemplateFFTs_deconv[cr]);
385  theCRTemplates_deconv[cr] = new TGraph(length,theCRTemplates[cr]->GetX(),theCRTemplate_deconv_y);
386  name.str("");
387  name << "deconvCR" << cr;
388  theCRTemplates_deconv[cr]->SetName(name.str().c_str());
389  }
390  }
391 
392  if(fUseAverageCRTemplate)
393  {
394  char* installDir = getenv("ANITA_UTIL_INSTALL_DIR");
395  TString crfname = Form("%s/share/AnitaAnalysisFramework/templates/deconvolvedCRA4average.txt", installDir);
396 
397  TGraph* grTemplateCut = new TGraph(crfname.Data());
398  TGraph *grTemplate = FFTtools::normalizeWaveform(grTemplateCut);
399  delete grTemplateCut;
400 
401  //give it a name
402  grTemplate->SetName("disp0");
403  int phl = -1;
404  if(fDoWindow) grTemplate = WindowingTools::windowWave(grTemplate, phl, 30, 30, 50, 50);
405 
406  //and get the FFT of it as well, since we don't want to do this every single event
407  FFTWComplex *theTemplateFFT=FFTtools::doFFT(grTemplate->GetN(),grTemplate->GetY());
408  theCRTemplates_deconv[0] = grTemplate;
409  theCRTemplateFFTs_deconv[0] = theTemplateFFT;
410  }
411 
412  kTmpltsDeconv = true;
413 
414  return;
415 
416 }
417 
418 
419 
420 
421 void AnitaTemplateMachine::doTemplateAnalysis(const AnalysisWaveform *waveform, int poli, int dir, AnitaTemplateSummary *templateSummary, bool do_impulse, bool do_wais, bool do_cr) {
422  /* copied out of templateSearch.cc */
423 
424 
425  if (!isTmpltsLoaded()) {
426  std::cout << "Error in AnitaTemplateAnalyzer::doTemplateAnalysis(): AnitaTemplateMachine says it has no templates!" << std::endl;
427  std::cout << " Try doing AnitaTemplateMachine::loadTemplates() at some point maybe? " << std::endl;
428  return;
429  }
430 
431 
432  //I actually want to do SOME filtering though... so sine subtract a single one?
433  // sineSub->processOne(coherentAnalysis,data->header(),);
434  const TGraphAligned *coherentAligned = waveform->even();
435  TGraph *coherent = new TGraph(coherentAligned->GetN(),coherentAligned->GetX(),coherentAligned->GetY());
436  //make sure it is the same sampling rate as the templates and default
437  TGraph *coherentResamp = FFTtools::getInterpolatedGraph(coherent,dT);
438  delete coherent;
439  //make sure it is the same length as the template
440  TGraph *coherentPad = FFTtools::padWaveToLength(coherentResamp,length);
441  delete coherentResamp;
442 
443  //normalize coherently summed waveform
444  TGraph *normCoherent = FFTtools::normalizeWaveform(coherentPad);
445  delete coherentPad;
446  FFTWComplex *coherentFFT=FFTtools::doFFT(length,normCoherent->GetY());
447  delete normCoherent;
448 
449 
450  //set up variables for calculating
451  double maxValue,minValue,value,value_loc;
452  bool value_pol;
453  double *dCorr;
454 
455  //Impulse Response
456  if (do_impulse)
457  {
458  dCorr = FFTtools::getCorrelationFromFFT(length,theImpTemplateFFT,coherentFFT);
459  maxValue = TMath::MaxElement(length,dCorr);
460  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
461  if (TMath::Max(maxValue,minValue) == maxValue) {
462  value = maxValue;
463  value_loc = TMath::LocMax(length,dCorr);
464  value_pol = true;
465  }
466  else {
467  value = minValue;
468  value_loc = TMath::LocMin(length,dCorr);
469  value_pol = false;
470  }
471  templateSummary->coherent[poli][dir].impulse = value;
472  templateSummary->coherent[poli][dir].impulse_loc = value_loc;
473  templateSummary->coherent[poli][dir].impulse_pol = value_pol;
474 
475  delete[] dCorr;
476  }
477 
478  //Wais
479 
480  if (do_wais)
481  {
482  dCorr = FFTtools::getCorrelationFromFFT(length,theWaisTemplateFFT,coherentFFT);
483  maxValue = TMath::MaxElement(length,dCorr);
484  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
485  if (TMath::Max(maxValue,minValue) == maxValue) {
486  value = maxValue;
487  value_loc = TMath::LocMax(length,dCorr);
488  value_pol = true;
489  }
490  else {
491  value = minValue;
492  value_loc = TMath::LocMin(length,dCorr);
493  value_pol = false;
494  }
495  templateSummary->coherent[poli][dir].wais = value;
496  templateSummary->coherent[poli][dir].wais_loc = value_loc;
497  templateSummary->coherent[poli][dir].wais_pol = value_pol;
498 
499  delete[] dCorr;
500  }
501 
502 
503  //Cosmic Ray Templates
504  if(!fUseAverageCRTemplate)
505  {
506  for (int i=0; i<numCRTemplates; i++) {
507  if (!do_cr) break;
508  dCorr = FFTtools::getCorrelationFromFFT(length,theCRTemplateFFTs[i],coherentFFT);
509  maxValue = TMath::MaxElement(length,dCorr);
510  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
511  if (TMath::Max(maxValue,minValue) == maxValue) {
512  value = maxValue;
513  value_loc = TMath::LocMax(length,dCorr);
514  value_pol = true;
515  }
516  else {
517  value = minValue;
518  value_loc = TMath::LocMin(length,dCorr);
519  value_pol = false;
520  }
521  templateSummary->coherent[poli][dir].cRay[i] = value;
522  templateSummary->coherent[poli][dir].cRay_loc[i] = value_loc;
523  templateSummary->coherent[poli][dir].cRay_pol[i] = value_pol;
524 
525  delete[] dCorr;
526  }
527  }
528  if(fUseAverageCRTemplate && do_cr)
529  {
530  dCorr = FFTtools::getCorrelationFromFFT(length,theCRTemplateFFTs[0],coherentFFT);
531  maxValue = TMath::MaxElement(length,dCorr);
532  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
533  if (TMath::Max(maxValue,minValue) == maxValue) {
534  value = maxValue;
535  value_loc = TMath::LocMax(length,dCorr);
536  value_pol = true;
537  }
538  else {
539  value = minValue;
540  value_loc = TMath::LocMin(length,dCorr);
541  value_pol = false;
542  }
543  templateSummary->coherent[poli][dir].cRay[0] = value;
544  templateSummary->coherent[poli][dir].cRay_loc[0] = value_loc;
545  templateSummary->coherent[poli][dir].cRay_pol[0] = value_pol;
546  }
547 
548  delete[] coherentFFT;
549 
550  return;
551 
552 }
553 
554 void AnitaTemplateMachine::doDeconvolvedTemplateAnalysis(const AnalysisWaveform *waveform,
556  int poli, int dir, AnitaTemplateSummary *templateSummary,
557  bool do_impulse, bool do_wais, bool do_cr) {
558  /* copied out of templateSearch.cc */
559 
560 
561  if (!isTmpltsLoaded()) {
562  std::cout << "Error in AnitaTemplateAnalyzer::doTemplateAnalysis(): AnitaTemplateMachine says it has no templates!" << std::endl;
563  std::cout << " Try doing AnitaTemplateMachine::loadTemplates() at some point maybe? " << std::endl;
564  return;
565  }
566 
567  //I actually want to do SOME filtering though... so sine subtract a single one?
568  // sineSub->processOne(deconvolvedAnalysis,data->header(),);
569  const TGraphAligned *deconvolvedAligned = waveform->even();
570  if (!deconvolvedAligned || deconvolvedAligned->GetN() == 0) {
571  return; //apparently sometimes the deconvolved waveform doesn't get filled?
572  }
573  TGraph *deconvolved = new TGraph(deconvolvedAligned->GetN(),deconvolvedAligned->GetX(),deconvolvedAligned->GetY());
574  //make sure it is the same length as the template
575  TGraph *deconvolvedPad = FFTtools::padWaveToLength(deconvolved,length);
576  delete deconvolved;
577 
578  //normalize deconvolvedly summed waveform
579  int phl = -1;
580  if(fDoWindow)
581  {
582  deconvolvedPad = WindowingTools::windowWave(deconvolvedPad, phl, 30, 30, 50, 50);
583  phl = -1;
584  }
585  TGraph *normDeconvolved = FFTtools::normalizeWaveform(deconvolvedPad);
586  delete deconvolvedPad;
587  FFTWComplex *deconvolvedFFT=FFTtools::doFFT(length,normDeconvolved->GetY());
588 
589 
590 
591  //set up variables for calculating
592  double maxValue,minValue,value,value_loc;
593  bool value_pol;
594  double *dCorr;
595 
596  //Impulse Response
597  if (do_impulse)
598  {
599  dCorr = FFTtools::getCorrelationFromFFT(length,theImpTemplateFFT_deconv,deconvolvedFFT);
600  maxValue = TMath::MaxElement(length,dCorr);
601  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
602  if (TMath::Max(maxValue,minValue) == maxValue) {
603  value = maxValue;
604  value_loc = TMath::LocMax(length,dCorr);
605  value_pol = true;
606  }
607  else {
608  value = minValue;
609  value_loc = TMath::LocMin(length,dCorr);
610  value_pol = false;
611  }
612  templateSummary->deconvolved[poli][dir].impulse = value;
613  templateSummary->deconvolved[poli][dir].impulse_loc = value_loc;
614  templateSummary->deconvolved[poli][dir].impulse_pol = value_pol;
615 
616  delete[] dCorr;
617  }
618 
619  //Wais
620  if (do_wais)
621  {
622  dCorr = FFTtools::getCorrelationFromFFT(length,theWaisTemplateFFT_deconv,deconvolvedFFT);
623  maxValue = TMath::MaxElement(length,dCorr);
624  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
625  if (TMath::Max(maxValue,minValue) == maxValue) {
626  value = maxValue;
627  value_loc = TMath::LocMax(length,dCorr);
628  value_pol = true;
629  }
630  else {
631  value = minValue;
632  value_loc = TMath::LocMin(length,dCorr);
633  value_pol = false;
634  }
635  templateSummary->deconvolved[poli][dir].wais = value;
636  templateSummary->deconvolved[poli][dir].wais_loc = value_loc;
637  templateSummary->deconvolved[poli][dir].wais_pol = value_pol;
638 
639  delete[] dCorr;
640  }
641 
642  //Cosmic Ray Templates
643  if(!fUseAverageCRTemplate)
644  {
645  for (int i=0; i<numCRTemplates; i++) {
646  if (!do_cr) break;
647  dCorr = FFTtools::getCorrelationFromFFT(length,theCRTemplateFFTs_deconv[i],deconvolvedFFT);
648  maxValue = TMath::MaxElement(length,dCorr);
649  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
650  if (TMath::Max(maxValue,minValue) == maxValue) {
651  value = maxValue;
652  value_loc = TMath::LocMax(length,dCorr);
653  value_pol = true;
654  }
655  else {
656  value = minValue;
657  value_loc = TMath::LocMin(length,dCorr);
658  value_pol = false;
659  }
660  templateSummary->deconvolved[poli][dir].cRay[i] = value;
661  templateSummary->deconvolved[poli][dir].cRay_loc[i] = value_loc;
662  templateSummary->deconvolved[poli][dir].cRay_pol[i] = value_pol;
663 
664  delete[] dCorr;
665  }
666  }
667 
668  if(fUseAverageCRTemplate && do_cr)
669  {
670  if(fDoWindow) {
671  TGraph* gCorr = FFTtools::getCorrelationGraph(normDeconvolved, theCRTemplates_deconv[0]);
672  double normalization = 1./(normDeconvolved->GetRMS(2) * theCRTemplates_deconv[0]->GetRMS(2) * normDeconvolved->GetN()/TMath::Power(2, int(TMath::Log2(normDeconvolved->GetN()))));
673  maxValue = normalization * TMath::MaxElement(gCorr->GetN(), gCorr->GetY());
674  minValue = normalization * TMath::Abs(TMath::MinElement(gCorr->GetN(), gCorr->GetY()));
675  if (TMath::Max(maxValue,minValue) == maxValue) {
676  value = maxValue;
677  value_loc = TMath::LocMax(gCorr->GetN(), gCorr->GetY());
678  value_pol = true;
679  }
680  else {
681  value = minValue;
682  value_loc = TMath::LocMin(gCorr->GetN(), gCorr->GetY());
683  value_pol = false;
684  }
685 
686  delete gCorr;
687  }
688 
689  else {
690  dCorr = FFTtools::getCorrelationFromFFT(length,theCRTemplateFFTs_deconv[0],deconvolvedFFT);
691  maxValue = TMath::MaxElement(length,dCorr);
692  minValue = TMath::Abs(TMath::MinElement(length,dCorr));
693  if (TMath::Max(maxValue,minValue) == maxValue) {
694  value = maxValue;
695  value_loc = TMath::LocMax(length,dCorr);
696  value_pol = true;
697  }
698  else {
699  value = minValue;
700  value_loc = TMath::LocMin(length,dCorr);
701  value_pol = false;
702  }
703  delete[] dCorr;
704  }
705 
706  templateSummary->deconvolved[poli][dir].cRay[0] = value;
707  templateSummary->deconvolved[poli][dir].cRay_loc[0] = value_loc;
708  templateSummary->deconvolved[poli][dir].cRay_pol[0] = value_pol;
709 
710  }
711 
712  delete[] deconvolvedFFT;
713  delete normDeconvolved;
714 
715  return;
716 
717 }
718 
719 
720 
722 
723  if (!isTmpltsLoaded() || !isTmpltsDeconv()) {
724  std::cout << "Error in AnitaTemplateAnalyzer::writeTemplatesToFile(): AnitaTemplateMachine says it is missing templates!" << std::endl;
725  std::cout << " Try doing AnitaTemplateMachine::loadTemplates() and deconvolveTempaltes() at some point maybe? " << std::endl;
726  return;
727  }
728 
729  outFile->cd();
730  theImpTemplate->Write();
731  theImpTemplate_deconv->Write();
732  theWaisTemplate->Write();
733  theWaisTemplate_deconv->Write();
734  for (int i=0; i<numCRTemplates; i++) {
735  theCRTemplates[i]->Write();
736  theCRTemplates_deconv[i]->Write();
737  }
738 
739 
740  return;
741 }
742 
743 
744 
745 
746 //---------------------------------------------------------------------------------------------------------
752 TGraph *FFTtools::normalizeWaveform(TGraph *inGraph) {
753 
754  TGraph *outGraph = (TGraph*)inGraph->Clone();
755 
756  //normalize it ( as seen in macros/testTemplate.C )
757  double waveSum = 0;
758  for (int pt=0; pt<outGraph->GetN(); pt++) waveSum += pow(outGraph->GetY()[pt],2);
759  for (int pt=0; pt<outGraph->GetN(); pt++) outGraph->GetY()[pt] /= TMath::Sqrt(waveSum / (outGraph->GetN()/4));
760 
761  return outGraph;
762 
763 }
764 
765 
766 double *FFTtools::getCorrelationFromFFT(int length,const FFTWComplex *theFFT1, const FFTWComplex *theFFT2)
767 {
768 
769 
770  int newLength=(length/2)+1;
771 // std::cout << "newLength " << newLength << std::endl;
772  FFTWComplex *tempStep = new FFTWComplex [newLength];
773  int no2=length>>1;
774  for(int i=0;i<newLength;i++) {
775  double reFFT1=theFFT1[i].re;
776  double imFFT1=theFFT1[i].im;
777  double reFFT2=theFFT2[i].re;
778  double imFFT2=theFFT2[i].im;
779 
780  //Real part of output
781  tempStep[i].re=(reFFT1*reFFT2+imFFT1*imFFT2)/double(no2/2);
782  //Imaginary part of output
783  tempStep[i].im=(imFFT1*reFFT2-reFFT1*imFFT2)/double(no2/2);
784  }
785 // std::cout << "finished messing around" << std::endl;
786  double *theOutput=FFTtools::doInvFFT(length,tempStep);
787 // std::cout << "got inverse" << std::endl;
788  delete [] tempStep;
789  return theOutput;
790 
791 }
792 
793 
794 
795 //---------------------------------------------------------------------------------------------------------------------
803 TGraph *WindowingTools::windowCut(TGraph *inGraph,int length) {
804  /* cut whatever to this length with a nice little tail */
805  int tempPeak = -1;
806  const int beforeTime = 500;
807  const int wings = 10;
808  int afterTime = length - beforeTime - 2*wings;
809 
810  return windowWave(inGraph,tempPeak,beforeTime,afterTime,wings,wings);
811  }
812 
813 TGraph *WindowingTools::windowDispersed(TGraph *inGraph, int &peakHilbertLoc) {
814  return windowWave(inGraph,peakHilbertLoc,
815  500,750,20,20);
816  }
817 
818 
819 TGraph *WindowingTools::windowDispersed(TGraph *inGraph) {
820  //overload!
821  int tempPeak = -1;
822  return windowDispersed(inGraph,tempPeak);
823  }
824 
825 
826 TGraph *WindowingTools::windowEField(TGraph *inGraph, int &peakHilbertLoc) {
827  return windowWave(inGraph,peakHilbertLoc,
828  30,30,2,2);
829 }
830 
831 
832 TGraph *WindowingTools::windowEField(TGraph *inGraph) {
833  //overload!
834  int tempPeak = -1;
835  return windowEField(inGraph,tempPeak);
836 }
837 
838 
839 
840 TGraph *WindowingTools::windowWave(TGraph *inGraph, int &peakHilbertLoc,
841  const int upRampLoc, const int downRampLoc,
842  const int upRampLen, const int downRampLen) {
843  //defaults are for the impulse response
844 
845  bool debug =false;
846 
847  /*
848 
849  The noise after the waveform part is useless. I need to window it to increase the correlation value
850 
851  Find the peak of the hilbert envelope, then go 5ns before it (50pts) and then do a hamming maybe like 60 after it?
852 
853  */
854 
855 
856  //the following are window config params, in POINTS (not nanoseconds)
857  // downRampLoc - how far after peak hilbert env to start tail hamming
858  // upRampLoc - how far before peak hilbert to start hamming (well close)
859 
860  // upRampLen: how "long" the hamming should be (half period)
861  // downRampLen - how "long" the hamming should be at the end (well close)
862 
863 
864  //If I don't tell it where to window, it should figure it out
865  if (peakHilbertLoc == -1) {
866  TGraph *hilbert = FFTtools::getHilbertEnvelope(inGraph);
867  peakHilbertLoc = TMath::LocMax(hilbert->GetN(),hilbert->GetY());
868  delete hilbert; //no memory leaks!
869  }
870 
871  int startLoc = peakHilbertLoc - upRampLoc;
872  int stopLoc = peakHilbertLoc + downRampLoc;
873 
874  if (stopLoc+downRampLen > inGraph->GetN()) {
875  if (debug) std::cout << "****";
876  int overrun = (stopLoc+downRampLen) - inGraph->GetN() + 1;
877  startLoc -= overrun;
878  stopLoc -= overrun;
879  }
880 
881  if (debug) std::cout << "inGraph->GetN()=" << inGraph->GetN() << " startLoc=" << startLoc << " stopLoc=" << stopLoc;
882 
883 
884 
885  TGraph *outGraph = new TGraph();
886  for (int pt=0; pt<inGraph->GetN(); pt++) {
887  if (pt <= (startLoc-upRampLen)) {
888  // outGraph->SetPoint(outGraph->GetN(),inGraph->GetX()[pt],0); //not zero out, CUT
889  if (debug) std::cout << pt << " - 1" << std::endl;
890  }
891  else if (pt > (startLoc-upRampLen) && pt <= startLoc ) {
892  int ptMod = pt - (startLoc-upRampLen);
893  double modValue = 0.5-(TMath::Cos(ptMod * ( TMath::Pi()/upRampLen ))/2.);
894  double value = modValue * inGraph->GetY()[pt];
895  outGraph->SetPoint(outGraph->GetN(),inGraph->GetX()[pt],value);
896  if (debug) std::cout << pt << " - 2 - " << ptMod << " - " << modValue << std::endl;
897  }
898  else if (pt > startLoc && pt <= stopLoc) {
899  outGraph->SetPoint(outGraph->GetN(),inGraph->GetX()[pt],inGraph->GetY()[pt]);
900  if (debug) std::cout << pt << " - 3" << std::endl;
901  }
902  else if (pt > stopLoc && pt <= (stopLoc+downRampLen)) {
903  double ptMod = pt - stopLoc;
904  double modValue = (1+TMath::Cos(ptMod*( TMath::Pi()/downRampLen ))/2.) - 0.5;
905  double value = modValue * inGraph->GetY()[pt];
906  outGraph->SetPoint(outGraph->GetN(),inGraph->GetX()[pt],value);
907  if (debug) std::cout << pt << " - 4 - " << ptMod << " - " << modValue << std::endl;
908  }
909  else if (pt > stopLoc+downRampLen) {
910  // outGraph->SetPoint(outGraph->GetN(),inGraph->GetX()[pt],0); //not zero out, CUT
911  if (debug) std::cout << pt << " - 5" << std::endl;
912  }
913  }
914 
915  if (debug) std::cout << " outGraph->GetN()=" << outGraph->GetN() << std::endl;
916  return outGraph;
917 
918 }
919 
920 
921 
922 
923 
924 
FFTWComplex * theImpTemplateFFT
double im
The imaginary part.
Definition: FFTWComplex.h:18
virtual ~AnitaTemplateSummary()
static const Int_t maxDirectionsPerPol
TGraph * getHilbertEnvelope(const TGraph *grWave)
The Hilbert envelope of the input TGraph. This is defined as e_i=sqrt(v_i^2 + h_i^2), where e_i, v_i and h_i are the i-th sample of the envelope, input graph and hilbert transform of the input graph repsectively.
Definition: FFTtools.cxx:964
AnitaTemplateMachine(const int inLength=2048)
Default Constructor.
FFTWComplex * doFFT(int length, const double *theInput)
Computes an FFT of an array of real numbers.
Definition: FFTtools.cxx:436
void loadTemplates(unsigned int evTime=0, int version=AnitaVersion::get())
void deconvolveTemplates(AnitaResponse::DeconvolutionMethod *deconv)
TGraph * padWaveToLength(const TGraph *grA, Int_t newLength)
Zero pad a wave making it up to newLength points.
Definition: FFTtools.cxx:1769
double * doInvFFT(int length, const FFTWComplex *theInput)
Computes an inverse FFT.
Definition: FFTtools.cxx:482
TGraph * getInterpolatedGraph(const TGraph *grIn, Double_t deltaT)
Interpolation Routines that use ROOT::Math::Interpolator.
Definition: FFTtools.cxx:32
This is a wrapper class for a complex number.
Definition: FFTWComplex.h:12
TGraph * windowCut(TGraph *inGraph, int length)
TGraph * getCorrelationGraph(const TGraph *gr1, const TGraph *gr2, Int_t *zeroOffset=0)
Returns the correlation of two TGraphs.
Definition: FFTtools.cxx:754
TGraph * normalizeWaveform(TGraph *inGraph)
double re
Destructor.
Definition: FFTWComplex.h:15
void doTemplateAnalysis(const AnalysisWaveform *waveform, int poli, int dir, AnitaTemplateSummary *summary, bool do_impulse=true, bool do_wais=true, bool do_cr=true)
void writeTemplatesToFile(TFile *outFile)
const TGraphAligned * even() const
This class is intended to be the main storage vessel for ANITA waveforms. It is similar in principle ...
AnitaTemplateSummary()
Default Constructor.