PCGFitter.cc
Go to the documentation of this file.
1 #define DEBUG 1
2 #include "PCGFitter.h"
3 
4 #include <utl/Point.h>
5 #include <utl/Vector.h>
6 #include <utl/CoordinateSystemPtr.h>
7 #include <utl/Transformation.h>
8 #include <utl/TimeInterval.h>
9 #include <utl/AugerUnits.h>
10 #include <utl/PhysicalConstants.h>
11 #include <utl/TabulatedFunctionErrors.h>
12 
13 #include <fevt/FEvent.h>
14 #include <fevt/Eye.h>
15 #include <fevt/EyeRecData.h>
16 #include <fevt/EyeHeader.h>
17 #include <fevt/Pixel.h>
18 
19 #include <fevt/Telescope.h>
20 #include <fevt/TelescopeRecData.h>
21 
22 #include <det/Detector.h>
23 #include <fdet/FDetector.h>
24 #include <fdet/Eye.h>
25 
26 #include <fwk/LocalCoordinateSystem.h>
27 #include <fwk/CentralConfig.h>
28 #include <TMath.h>
29 
30 #include "ChiZeroRegression.h"
31 #include "ProfileChi2.h"
32 
33 #include "../../General/RecDataWriterNG/ConversionUtil.h"
34 
35 #include <limits>
36 
37 #define PCGF_DEBUGLOG(x) { cerr << "DEBUGLOG " << x << endl;}
38 
39 
40 using namespace std;
41 using namespace fevt;
42 using namespace utl;
43 
44 namespace FdProfileConstrainedGeometryFit {
45 
46 void
48 {
49  Branch topBranch = fwk::CentralConfig::GetInstance()->GetTopBranch("FdProfileConstrainedGeometryFit");
50 
51  string apLightOption;
52  topBranch.GetChild("apLightMethod").GetData(apLightOption);
53  fApLightMethod =
54  (apLightOption=="eExternal") ? eExternal :
55  (apLightOption == "eInternal") ? eInternal : eCallForEach;
56 
57  topBranch.GetChild("checkUnderground").GetData(fCheckUnderground);
58  topBranch.GetChild("prescan").GetData(fPrescan);
59  topBranch.GetChild("scanOnly").GetData(fScanOnly);
60  topBranch.GetChild("scanStep").GetData(fScanStep);
61  topBranch.GetChild("scanStart").GetData(fScanStart);
62  topBranch.GetChild("scanStop").GetData(fScanStop);
63  topBranch.GetChild("useLightFlux").GetData(fUseLightFlux);
64  topBranch.GetChild("delZeroLightFlux").GetData(fDelZeroFlux);
65  topBranch.GetChild("TimeFitModel").GetData(fRealAtm);
66  topBranch.GetChild("TimeFitDeexcitation").GetData(fDeex);
67  ostringstream info;
68  info << "\n"
69  "\t apLightMethod is " << apLightOption << "\n"
70  "\t checkUnderground is " << (fCheckUnderground?"on":"off") << "\n"
71  "\t prescan is " << (fPrescan?"on":"off") << "\n"
72  "\t scanOnly is " << (fScanOnly?"on":"off") << "\n"
73  "\t scanStep: " << fScanStep/degree << " deg\n"
74  "\t scanStart: " << fScanStart/degree << " deg\n"
75  "\t scanStop: " << fScanStop/degree << " deg\n"
76  "\t delZeroLightFlux is " << (fDelZeroFlux?"on":"off") << "\n"
77  "\t useLightFlux is " << (fUseLightFlux?"on":"off") << "\n"
78  "\t TimeFitModel is " << (fRealAtm?"RealisticAtm":"VacuumAtm") << "\n"
79  "\t TimeFitDeexcitation is " << (fDeex?"on":"off") << "\n";
80  INFO(info);
81 
82  if (fApLightMethod == eCallForEach) {
83  fApertureLightFinder.Init();
84  } else if (fApLightMethod == eInternal) {
85  fApLight.Init();
86  }
87 
88  fProfileFit.Init();
89 
90  // fChi0Regression->
91  fProfileFit.SetUseLightFlux(fUseLightFlux);
92 }
93 
94 
95 inline
96 bool
97 PCGFitter::Underground(const double chi0, const Eye &eye)
98 {
99  if (!fCheckUnderground)
100  return false;
101 
102  const EyeRecData& eyeRec = eye.GetRecData();
103 
105  end = eyeRec.TimeFitPixelsEnd(); pix != end; ++pix) {
106  const PixelRecData& pixRec = pix->GetRecData();
107  const double chii = pixRec.GetChi_i();
108  //cout << "chii " << chii << "pixel " << (*pix).GetId() << "\n";
109  if (sin(chi0 - chii) < 0) {
110  PCGF_DEBUGLOG("Under ground");
111  return true;
112  }
113  }
114  return false;
115 }
116 
117 
118 double
119 PCGFitter::operator()(const vector<double>& par)
120 {
121  const double chi0 = par[0];
122 
123  double rp = 0;
124  double t0 = 0;
125  const double chi2 = CombinedChi2(chi0, rp, t0, PCGFData::eFit, true);
126  return chi2;
127 }
128 
129 
130 double
131 PCGFitter::CombinedChi2(const double chi0, double &rp, double &t0,
132  const fevt::PCGFData::EPCGFStatus status,
133  const bool verbose)
134 {
135  const Eye& eye = *fEye;
136 
137  double chi2timing; // rp, t0;
138  const ChiZeroRegression& chi0reg = *fChi0Regression;
139  chi0reg(chi0, chi2timing, rp, t0);
140 
141  if (verbose)
142  cout << "Chi0: " << chi0/degree << "\t"
143  "Rp: " << rp/m << "\t"
144  "T0: " << t0/ns << "\t "
145  "Chi^2_t: " << chi2timing << "\n";
146 
147  //Check after regression: fill rp, t0 correctly anyway; probably never needed ...
148  if (Underground(chi0, eye))
149  return numeric_limits<double>::infinity();
150 
151  evt::Event eventCopy;
152  Eye& eyeCopy = CopyEye(eye, eventCopy);
153 
154  FillParams(eyeCopy, chi0, rp, t0);
155  if (!AdjustGeometry(eyeCopy)) {
156  //ERROR("could not adjust geometry");
157  return numeric_limits<double>::infinity();
158  }
159 
160  if (fApLightMethod == eCallForEach) {
161  const bool haveLight =
162  fApertureLightFinder.Run(eventCopy) == fwk::VModule::eSuccess && eyeCopy.GetRecData().HasLightFlux();
163  if (!haveLight)
164  return numeric_limits<double>::infinity();
165 
166  if (fDelZeroFlux) {
167  //VN remove all light flux bins comatible with zero
170  vector<double> phX, phXerr, phY, phYerr;
171  vector<double> bgX, bgXerr, bgY, bgYerr;
172  for (unsigned int i = 0; i < photonTrace.GetNPoints(); ++i) {
173  if ((photonTrace.GetY(i)-photonTrace.GetYErr(i)) > 0.) {
174  phX.push_back(photonTrace.GetX(i));
175  phXerr.push_back(photonTrace.GetXErr(i));
176  phY.push_back(photonTrace.GetY(i));
177  phYerr.push_back(photonTrace.GetYErr(i));
178  bgX.push_back(bgTrace.GetX(i));
179  bgXerr.push_back(bgTrace.GetXErr(i));
180  bgY.push_back(bgTrace.GetY(i));
181  bgYerr.push_back(bgTrace.GetYErr(i));
182  }
183  }
184  photonTrace.Clear();
185  bgTrace.Clear();
186  for (unsigned int i = 0; i < phX.size(); ++i) {
187  photonTrace.PushBack(phX[i], phXerr[i], phY[i], phYerr[i]);
188  bgTrace.PushBack(bgX[i], bgXerr[i], bgY[i], bgYerr[i]);
189  }
190 
191  for (fevt::Eye::TelescopeIterator telIter =
194  ++telIter) {
195  if (!telIter->HasRecData()) continue;
196  TelescopeRecData& telRecData = telIter->GetRecData();
197  if (!telRecData.HasLightFlux()) continue;
200  vector<double> phX, phXerr, phY, phYerr;
201  vector<double> bgX, bgXerr, bgY, bgYerr;
202  for (unsigned int i = 0; i < photonTrace.GetNPoints(); ++i) {
203  if (photonTrace.GetY(i)-photonTrace.GetYErr(i) > 0.) {
204  phX.push_back(photonTrace.GetX(i));
205  phXerr.push_back(photonTrace.GetXErr(i));
206  phY.push_back(photonTrace.GetY(i));
207  phYerr.push_back(photonTrace.GetYErr(i));
208  bgX.push_back(bgTrace.GetX(i));
209  bgXerr.push_back(bgTrace.GetXErr(i));
210  bgY.push_back(bgTrace.GetY(i));
211  bgYerr.push_back(bgTrace.GetYErr(i));
212  }
213  }
214  photonTrace.Clear();
215  bgTrace.Clear();
216  for (unsigned int i = 0; i < phX.size(); ++i) {
217  photonTrace.PushBack(phX[i], phXerr[i], phY[i], phYerr[i]);
218  bgTrace.PushBack(bgX[i], bgXerr[i], bgY[i], bgYerr[i]);
219  }
220  }
221  }
222  }
223 
224  const double chi2profile = fProfileFit(eyeCopy);
225  const double constraint1 = fProfileFit.GetShapeConstraint1Chi2();
226  const double constraint2 = fProfileFit.GetShapeConstraint2Chi2();
227  const double constraint3 = fProfileFit.GetShapeConstraint3Chi2();
228  if (verbose)
229  cout << "Chi^2_prof: " << chi2profile << ", including constraints 1/2/3: " << constraint1 << "/" << constraint2 << "/" << constraint3 << '\n';
230 
231  map<string, double> mapchi2;
232  mapchi2["time"] = chi2timing;
233  mapchi2["prof"] = chi2profile-constraint1-constraint2-constraint3;//sqrt(pow(chi2profile,2) - pow(constraint1,2) - pow(constraint2,2) - pow(constraint3,2) );
234  mapchi2["constraint1"] = constraint1;
235  mapchi2["constraint2"] = constraint2;
236  mapchi2["constraint3"] = constraint3;
237  map<string, double> mapNDof;
238  mapNDof["time"] = chi0reg.GetNDof();
239  mapNDof["prof"] = fProfileFit.GetNDof();
240  mapNDof["constraint1"] = 1;
241  mapNDof["constraint2"] = 1;
242  mapNDof["constraint3"] = 1;
243  fPCGFData.push_back(PCGFData(chi0, rp, t0, status, mapchi2, mapNDof));
244 
245  return chi2profile+chi2timing;
246 }
247 
248 
249 bool
250 PCGFitter::Run(Eye &eye)
251 {
252  fEye = &eye;
253 
254  //VN to manage static fitter
255  fProfileFit.SetFitterPars();
256 
257  fPCGFData.clear();
258 
259  // keep initial value
260  {
261  const EyeRecData& eyeRecData = eye.GetRecData();
262  const double t0 = eyeRecData.GetTZero();
263  const double chi0 = eyeRecData.GetChiZero();
264  const double rp = eyeRecData.GetRp();
265 
266  map<string, double> mapchi2;
267  mapchi2["time"] = eyeRecData.GetTimeFitChiSquare();
268  map<string, double> mapNDof;
269  mapNDof["time"] = eyeRecData.GetTimeFitNDof();
270  // typically we have no profile fit at this stage...
271  /*
272  ShowerFRecData& recShower = eyeRecData.GetFRecShower();
273  mapchi2["prof"] = sqrt(recShower.GetGHParameters().GetChiSquare();
274  //recShower.GetGHParameters().GetNdof()) :
275  */
276  fPCGFData.push_back(PCGFData(chi0, rp, t0, PCGFData::ePreFit, mapchi2, mapNDof));
277  }
278 
279  // {
280  // const double startchi0=ScanChi0(eye, fScanStep,fScanStart,fScanStop)?
281  // eye.GetRecData().GetChiZero() : 90*degree;
282  // SetInitialValueStep(0, startchi0, 3.0*degree);
283  // }
284 
285  const EyeRecData& eyeRec = eye.GetRecData();
286  ChiZeroRegression chi0reg(eyeRec);
287  chi0reg.SetUseLightFlux(fUseLightFlux);
288  chi0reg.SetRealAtm(fRealAtm, fDeex);
289  fChi0Regression = &chi0reg;
290 
291  evt::Event eventCopy1;
292  Eye& eyeCopy1 = CopyEye(eye, eventCopy1);
293 
294  if (fApLightMethod == eInternal) {
295  fApLight.SetStripMode(true);
296  const bool haveLight = fApLight.Run(eventCopy1) && eyeCopy1.GetRecData().HasLightFlux();
297  if (!haveLight) {
298  fProfileFit.UnSetFitterPars();
299  return false;
300  }
301  fEye = &eyeCopy1;
302  }
303 
304  double from = fScanStart;
305  double to = fScanStop;
306  if ((fPrescan && !Prescan(fScanStep, from, to)) || !ScanChi0(eye, fScanStep, from, to)) {
307  fProfileFit.UnSetFitterPars();
308  return false;
309  }
310  const double startchi0 = eye.GetRecData().GetChiZero();
311  {
312  Minou::ParameterDef& chi0Par = GetParameterDefs()[0];
313  chi0Par.fValue = startchi0;
314  chi0Par.fStep = 0.5*fScanStep;
315  }
316 
317  // fChi0Regression = &chi0reg; //changed in scanchi0 -- this should be refactored
318 
319  double chi0 = startchi0;
320  double chi0Err = fScanStep;
321 
322  double chi2timing = 0;
323  double rp = 0;
324  double rpErr = 0;
325  double t0 = 0;
326  double t0Err = 0;
327 
328  evt::Event eventCopy2;
329  Eye& eyeCopy2 = CopyEye(eye, eventCopy2);
330 
331  if (fApLightMethod == eInternal) {
332  chi0reg(chi0, chi2timing, rp, t0);
333  FillParams(eyeCopy2, chi0, rp, t0);
334  if (!AdjustGeometry(eyeCopy2)) {
335  fProfileFit.UnSetFitterPars();
336  return false;
337  }
338  fApLight.SetStripMode(false);
339  const bool haveLight = fApLight.Run(eventCopy2) && eyeCopy2.GetRecData().HasLightFlux();
340  if (!haveLight) {
341  fProfileFit.UnSetFitterPars();
342  return false;
343  }
344  fEye = &eyeCopy2;
345  }
346 
347  if (!fScanOnly) {
348  Minou::Minimizer<PCGFitter> min(*this);
349  if (min.Migrad()) {
350  ERROR ("MIGRAD failed.");
351  fProfileFit.UnSetFitterPars();
352  return false;
353  }
354 
355  const auto result = min.GetParameterAndError(0);
356 
357  chi0 = result.first;
358  chi0Err = result.second;
359  } else {
360  if (!ScanChi0(eye, 0.1*fScanStep, startchi0 - 3*fScanStep, startchi0 + 3*fScanStep)) {
361  fProfileFit.UnSetFitterPars();
362  return false;
363  }
364  chi0 = eye.GetRecData().GetChiZero();
365  chi0Err = eye.GetRecData().GetChiZeroError();
366  }
367 
368  if (std::isnan(chi0Err) || chi0Err > 90*degree || chi0 < 5*degree || chi0 > 175*degree) {
369  cerr << "FIT RESULT:\n\tchi0 = (" << chi0 / degree
370  << " +/- " << chi0Err / degree << ") degree\n";
371  ERROR ("Fit result not regarded sane.");
372  fProfileFit.UnSetFitterPars();
373  return false;
374  }
375 
376  chi0reg(chi0, chi2timing, rp, rpErr, t0, t0Err);
377 
378  ostringstream info;
379  info << "FIT RESULT:\n\tchi0 = (" << chi0 / degree
380  << " +/- " << chi0Err / degree << ") degree\n"
381  << "\trp = ( " << rp / km
382  << " +/- " << rpErr/km << " ) km\n"
383  << "\tt0 = ( " << t0 / microsecond
384  << " +/- " << t0Err / microsecond << " ) us";
385  INFO(info);
386 
387  FillParams(eye, chi0, chi0Err, rp, rpErr, t0, t0Err);
388  AdjustGeometry(eye);
389 
390  // fill the PCGF data
391  {
392  CombinedChi2(chi0, rp, t0, PCGFData::eFinal, true);
393 
394  EyeRecData& eyeRecWrite = eye.GetRecData();
395  eyeRecWrite.SetPCGF(fPCGFData);
396  }
397 
398  fProfileFit.UnSetFitterPars();
399 
400  return true;
401 }
402 
403 
404 bool
405 PCGFitter::Prescan(const double step, double& from, double& to)
406 {
407  //calling CombinedChi2, so fChi0Regression must be set
408  const double bigstep = 4*step;
409  const double inf = numeric_limits<double>::infinity();
410 
411  double rp = 0;
412  double t0 = 0;
413  for ( ; ; from += bigstep) {
414  if (from >= to) {
415  PCGF_DEBUGLOG("Pescan failed leave: All profile fits failed.");
416  return false;
417  }
418 
419  if (CombinedChi2(from, rp, t0, PCGFData::eScan, true) < inf) {
420  break;
421  }
422  }
423  //to be sure that we do not miss anything
424  from -= bigstep;
425 
426  for ( ; ; to -= bigstep) {
427  if (from > to) {
428  PCGF_DEBUGLOG("Pescan failed leave: All profile fits failed backwards. This should not happen.");
429  return false;
430  }
431 
432  if (CombinedChi2(to, rp, t0, PCGFData::eScan, true) < inf) {
433  break;
434  }
435  }
436  to += bigstep;
437  PCGF_DEBUGLOG( "Prescan: chi^2 finite for chi0 from : "<< from << "\t to: " << to);
438  if (from >= to) {
439  return false;
440  }
441 
442  return true;
443 }
444 
445 
446 bool
447 PCGFitter::ScanChi0(Eye &eye, const double step, double from, double to)
448 {
449  const double inf = numeric_limits<double>::infinity();
450 
451  PCGF_DEBUGLOG("ScanChi0 enter");
452  //const EyeRecData& eyeRec = eye.GetRecData();
453  //ChiZeroRegression chi0reg(eyeRec);
454  //chi0reg.SetUseLightFlux(fUseLightFlux);
455  //fChi0Regression = &chi0reg;
456  //ChiZeroRegression &chi0reg = *fChi0Regression;
457 
458  vector<double> chi0s;
459  vector<double> chi2s;
460  vector<double> rps;
461  vector<double> t0s;
462 
463  for (double chi0 = from; chi0 <= to; chi0 += step) {
464  double rp = 0;
465  double t0 = 0;
466  double chi2 = CombinedChi2(chi0, rp, t0, PCGFData::eScan, true);
467 
468  chi0s.push_back(chi0);
469  chi2s.push_back(chi2);// > 0.1 ? chi2 : inf); // WARNING: what is this check good for? - removed
470  rps.push_back(rp);
471  t0s.push_back(t0);
472  }
473 
474  int min_i = TMath::LocMin(chi2s.size(), &chi2s[0]);
475 
476  PCGF_DEBUGLOG( "ScanChi0: min i:" << min_i << "\t size: " << chi2s.size());
477  PCGF_DEBUGLOG( "ScanChi0: min chi2: " << chi2s[min_i]);
478 
479  if (!(chi2s[min_i] < inf)) {
480  PCGF_DEBUGLOG("ScanChi0 failed leave: All profile fits failed.");
481  return false;
482  }
483 
484  /*const double tooMuch = numeric_limits<double>::max(); //but not infinity! //TODO: ask Vladimir why
485  //VN : imagine example [..66,55,33,inf..] -> [..66,55,tooMuch,inf..] -> 55 is OK
486  // if tooMuch=inf :[..66,55,33,inf..] -> [..66,55,inf,inf..] -> [..66,inf,inf,inf..] etc.
487  while (!((min_i > 0) ? chi2s[min_i-1] : inf < inf &&
488  (min_i < chi2s.size()-1) ? chi2s[min_i+1] : inf < inf) &&
489  (chi2s[min_i] != tooMuch)) { //What about the margins? - VN : true, fixed
490  chi2s[min_i] = tooMuch;
491  min_i = TMath::LocMin(chi2s.size(), &chi2s[0]);
492  }
493  if (chi2s[min_i] == tooMuch) {
494  PCGF_DEBUGLOG("ScanChi0 failed leave: No smooth minimum.");
495  return false;
496  }*/
497 
498  //VN: different estimate of smooth minimum
499  const double tooMuch = numeric_limits<double>::max();
500  while (chi2s[min_i] < tooMuch) {
501  vector<double> chi2s_trial(chi2s);
502  chi2s_trial[min_i] = tooMuch;
503  int min_i_trial1 = TMath::LocMin(chi2s_trial.size(), &chi2s_trial[0]);
504  chi2s_trial[min_i_trial1] = tooMuch;
505  int min_i_trial2 = TMath::LocMin(chi2s_trial.size(), &chi2s_trial[0]);
506  chi2s_trial[min_i_trial2] = tooMuch;
507  if (chi2s_trial[min_i-1] == tooMuch && chi2s_trial[min_i+1] == tooMuch) {
508  break;
509  } else {
510  chi2s[min_i] = tooMuch;
511  min_i = TMath::LocMin(chi2s.size(), &chi2s[0]);
512  }
513  }
514  if (!(chi2s[min_i] < tooMuch)) {
515  PCGF_DEBUGLOG("ScanChi0 failed leave: No smooth minimum.");
516  return false;
517  }
518  /* check perhaps not needed any more: - VN : not needed + eye not filled yet => drop off showers
519  if (!(chi2s[min_i] < numeric_limits<double>::infinity()) ||
520  eye.GetRecData().GetChiZero() <= (from+2*step) ||
521  eye.GetRecData().GetChiZero() >= (to-2*step)) {
522  PCGF_DEBUGLOG("ScanChi0 failed leave: No minimum in range-margin");
523  return false;
524  }
525  */
526 
527  //estimate chi0 error
528  double xmin = chi0s[min_i];
529  double ymin = chi2s[min_i];
530  vector<double> x;
531  vector<double> y;
532  vector<double> yerr;
533  x.push_back(0.);
534  y.push_back(0.);
535  yerr.push_back(1.);
536  for (unsigned int i = 1; i < 5; ++i) {
537  int j = min_i - i;
538  unsigned int k = min_i + i;
539  if ((j > 0) && std::isfinite(chi2s[j]) && (chi2s[j] < tooMuch)) {
540  x.push_back(std::abs(chi0s[j] - xmin));
541  y.push_back(((chi2s[j] - ymin) > 0) ? sqrt(chi2s[j] - ymin) : 0.);
542  yerr.push_back(1.);
543  }
544  if (k < chi0s.size() && std::isfinite(chi2s[k]) && chi2s[k] < tooMuch) {
545  x.push_back(abs(chi0s[k] - xmin));
546  y.push_back(((chi2s[k] - ymin) > 0) ? sqrt(chi2s[k] - ymin) : 0.);
547  yerr.push_back(1.);
548  }
549  }
550  double a = 0.;
551  double b = 0.;
552  double chi2 = 0.;
553  otoa::LinearFit(x, y, yerr, a, b, chi2);
554  double chi0err = (b != 0) ? (1./b) : 90*degree;
555  //end of chi0 error estimation
556 
557  FillParams(eye, chi0s[min_i], chi0err, rps[min_i], 0.1*kilometer, t0s[min_i], 0.1*microsecond);
558 
559  cout << "calculating result geometry\n";
560  AdjustGeometry(eye);
561  {
562  const evt::ShowerFRecData& recShower = eye.GetRecData().GetFRecShower();
563  const Point& corePos = recShower.GetCorePosition();
565  const Vector& axis = recShower.GetAxis();
566  cout << "chi0: " << chi0s[min_i]/degree << " deg "
567  "rp: " << rps[min_i] / meter << " m "
568  " -> "
569  "theta: " << axis.GetTheta(coreCS)/degree << " deg "
570  "phi: " << axis.GetPhi(coreCS)/degree << " deg"
571  << endl;
572  }
573 
574  PCGF_DEBUGLOG("ScanChi0 sucessful leave");
575  return true;
576 }
577 
578 
579 Eye&
580 PCGFitter::CopyEye(const Eye& eye, evt::Event& eventCopy)
581  const
582 {
583  eventCopy.MakeFEvent();
584  eventCopy.GetFEvent().MakeEye(eye.GetId());
585  eventCopy.GetFEvent().GetEye(eye.GetId()) = eye;
586  return eventCopy.GetFEvent().GetEye(eye.GetId());
587 }
588 
589 
590 void
591 PCGFitter::FillParams(Eye& eyeCopy,
592  const double chi0, const double chi0Err,
593  const double rp, const double rpErr,
594  const double t0, const double t0Err)
595  const
596 {
597  EyeRecData& eyeReco = eyeCopy.GetRecData();
598  eyeReco.SetChiZero(chi0, chi0Err);
599  eyeReco.SetTZero(t0, t0Err);
600  eyeReco.SetRp(rp, rpErr );
601 
602  //VN: set telescope data to show real geometry in ti-chii plot in EventBrowser
603  for (fevt::Eye::TelescopeIterator telIt = eyeCopy.TelescopesBegin(ComponentSelector::eHasData);
604  telIt != eyeCopy.TelescopesEnd(ComponentSelector::eHasData); ++telIt) {
605  if (!telIt->HasRecData())
606  telIt->MakeRecData();
607  fevt::TelescopeRecData& telRecData = telIt->GetRecData();
608  telRecData.SetChiZero(chi0,chi0Err);
609  telRecData.SetTZero(t0,t0Err);
610  telRecData.SetRp(rp,rpErr);
611  telRecData.SetTimeFitChiSquare(0,0);
612  telRecData.SetTimeFitCorrelations(0,0,0);
613  }
614 }
615 
616 
617 void
618 PCGFitter::FillParams(Eye& eyeCopy,
619  const double chi0,
620  const double rp,
621  const double t0)
622  const
623 {
624  FillParams(eyeCopy, chi0, 0.5*degree, rp, 0.1*km, t0, 0.1*microsecond);
625 }
626 
627 
628 bool
629 PCGFitter::AdjustGeometry(Eye& eyeCopy)
630  const
631 {
632  EyeRecData& eyeRecData = eyeCopy.GetRecData();
633 
634  const double t0 = eyeRecData.GetTZero();
635  const double chi0 = eyeRecData.GetChiZero();
636  const double rp = eyeRecData.GetRp();
637 
638  const fdet::Eye& detEye =
639  det::Detector::GetInstance().GetFDetector().GetEye(eyeCopy);
640  const CoordinateSystemPtr eyeCS = detEye.GetEyeCoordinateSystem();
641  const double sdpTheta = eyeRecData.GetSDP().GetTheta(eyeCS);
642  const double sdpPhi = eyeRecData.GetSDP().GetPhi(eyeCS);
643 
644  const Vector sdp = Vector(1, sdpTheta, sdpPhi, eyeCS, Vector::kSpherical);
645  const Vector vertical(0,0,1, eyeCS);
646  const Vector horizontalInSDP = Normalized(Cross(sdp, vertical));
647 
648  const Transformation rot = Transformation::Rotation(-chi0, sdp, eyeCS);
649  const Vector axis = Normalized(rot*horizontalInSDP);
650  const double coreDistance = rp / sin(chi0);
651  const Vector coreEyeVec = coreDistance * horizontalInSDP;
652  const Point& eyepos = detEye.GetPosition();
653  const Point core = eyepos + coreEyeVec;
654  evt::ShowerFRecData& recShower = eyeRecData.GetFRecShower();
655  recShower.SetAxis(axis);
656  recShower.SetCorePosition(core);
657  try {
658  recShower.SetCoreTime(eyeCopy.GetHeader().GetTimeStamp() -
659  TimeInterval(1000*100*ns), rp, chi0, t0);
660  } catch (OutOfBoundException& e) {
661  ERROR(e.GetMessage());
662  return false;
663  }
664  return true;
665 }
666 
667 }
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
unsigned int GetId() const
Definition: FEvent/Eye.h:54
#define PCGF_DEBUGLOG(x)
Definition: PCGFitter.cc:37
double GetChi_i() const
Definition: PixelRecData.h:117
unsigned int GetNPoints() const
void SetChiZero(const double chiZero, const double error)
Definition: EyeRecData.h:237
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
Definition: EyeRecData.h:297
const double degree
Point object.
Definition: Point.h:32
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
Report success to RunController.
Definition: VModule.h:62
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Definition: FEvent/Eye.cc:180
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
void SetPCGF(const std::vector< PCGFData > &pcgf)
Definition: EyeRecData.h:334
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
double GetChiZero() const
Definition: EyeRecData.h:85
void SetCorePosition(const utl::Point &core)
unsigned int GetTimeFitNDof() const
Definition: EyeRecData.h:93
const double meter
Definition: GalacticUnits.h:29
void SetTimeFitCorrelations(double rRpT0, double rRpChi0, double rChi0T0)
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void MakeEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
Definition: FEvent.cc:115
void SetRp(const double rp, const double error)
Definition: EyeRecData.h:239
void Init()
Initialise the registry.
Detector description interface for Eye-related data.
Definition: FDetector/Eye.h:45
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
int Migrad(const int n=500)
Definition: Minou.h:266
double GetChiZeroError() const
Definition: EyeRecData.h:86
boost::indirect_iterator< ConstInternalPixelIterator, const Pixel & > ConstPixelIterator
Const iterator over pixels used in reconstruction.
Definition: EyeRecData.h:117
Exception for reporting variable out of valid range.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
Class representing a document branch.
Definition: Branch.h:107
const double & GetYErr(const unsigned int idx) const
void SetCoreTime(const utl::TimeStamp &coreTime, const utl::TimeInterval &coreTimeErr)
const double ns
utl::CoordinateSystemPtr GetEyeCoordinateSystem() const
Returns the Eye Coordinate system.
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
bool HasLightFlux(const FdConstants::LightSource source=FdConstants::eTotal) const
Check that light profile for source /par source is present.
void SetAxis(const utl::Vector &axis)
double abs(const SVector< n, T > &v)
const Data result[]
Active transformations of geometrical objects.
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
void SetChiZero(const double chiZero, const double error)
const double km
Telescope-specific shower reconstruction data.
boost::filter_iterator< ComponentSelector, AllTelescopeIterator > TelescopeIterator
selective Telescope iterators
Definition: FEvent/Eye.h:72
void PushBack(const double x, const double xErr, const double y, const double yErr)
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
const double & GetXErr(const unsigned int idx) const
Eye-specific shower reconstruction data.
Definition: EyeRecData.h:65
AxialVector Normalized(const AxialVector &v)
Definition: AxialVector.h:81
Eye & GetEye(const unsigned int eyeId, const ComponentSelector::Status status=ComponentSelector::eHasData)
return Eye by id
Definition: FEvent.cc:70
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
const double & GetY(const unsigned int idx) const
const utl::AxialVector & GetSDP() const
Definition: EyeRecData.h:75
double GetTimeFitChiSquare() const
Definition: EyeRecData.h:92
fevt::FEvent & GetFEvent()
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
void SetTZero(const double tzero, const double error)
double GetRp() const
Definition: EyeRecData.h:87
utl::TimeStamp GetTimeStamp() const
Time of the Eye Event as tagged by FD-DAS (== eye trigger time plus pixel trace length) ...
Definition: EyeHeader.h:118
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
void SetTimeFitChiSquare(const double tfitChi2, const unsigned int ndof)
PixelIterator TimeFitPixelsEnd()
Definition: EyeRecData.h:171
constexpr double kilometer
Definition: AugerUnits.h:93
Vector object.
Definition: Vector.h:30
const double & GetX(const unsigned int idx) const
Interface class to access to Fluorescence reconstruction of a Shower.
void SetRp(const double rp, const double error)
double GetTZero() const
Definition: EyeRecData.h:83
void SetTZero(const double tzero, const double error)
Definition: EyeRecData.h:235
utl::TabulatedFunctionErrors & GetLightFlux(const FdConstants::LightSource source=fevt::FdConstants::eTotal)
Light flux at diaphragm, photons/m^2 versus time in ns.
Definition: EyeRecData.h:286
void LinearFit(const vector< double > &x, const vector< double > &y, const vector< double > &ey, double &a0, double &a1, double &chi2)
Do a linear fit and return coefficients and chi2.
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
PixelIterator TimeFitPixelsBegin()
Definition: EyeRecData.h:167
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
constexpr double microsecond
Definition: AugerUnits.h:147
const utl::Point & GetCorePosition() const
Shower core as reconstructed by the FD or FD eye.
Fluorescence Detector Pixel Reconstructed Data.
Definition: PixelRecData.h:27
const std::string & GetMessage() const
Retrieve the message from the exception.
utl::Point GetPosition() const
Eye position.
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130
const utl::Vector & GetAxis() const
Shower Axis as reconstructed by the FD or FD eye.

, generated on Tue Sep 26 2023.