FdEnergyDepositFinderKG/ProfileFitter.cc
Go to the documentation of this file.
1 #include "ProfileFitter.h"
2 #include "CFMatrixCalculator.h"
3 #include <utl/TabulatedFunctionErrors.h>
4 #include <evt/GaisserHillas4Parameter.h>
5 #include <utl/ErrorLogger.h>
6 #include <utl/Math.h>
7 #include <utl/MathConstants.h>
8 #include <utl/Reader.h>
9 #include <utl/AugerException.h>
10 #include <fwk/CentralConfig.h>
11 #include <evt/GaisserHillas4Parameter.h>
12 #include <det/Detector.h>
13 #include <fdet/FDetector.h>
14 #include <fdet/Camera.h>
15 #include <fdet/Eye.h>
16 
17 #include <TMinuit.h>
18 #include <TMath.h>
19 #include <TF1.h>
20 
21 #include <iostream>
22 #include <sstream>
23 #include <algorithm>
24 #include <limits>
25 
26 using namespace std;
27 using namespace utl;
28 using namespace FdEnergyDepositFinderKG;
29 
31 
32 
33 
34 // Defining a function for managing a non-gaussian exponential tail for the L parameter in the USP reconstruction
35 
36 inline double
37 GaussExp(const double x, const double mu, const double v, const double tau_sigma)
38 {
39  TF1 *fGaussExp_L = new TF1("fGaussExp_L","[0] * [3]/2. * exp( [3]/2. * ( 2.*[1] + [3]*[2]*[2] - 2.*(x+[4]) ) ) * TMath::Erfc( ( [1] + [3]*[2]*[2] - (x+[4]) ) / (sqrt(2.)*[2]) )",10.,2000.);
40  const double grammage = g/(cm*cm);
41  const double Lc_e = mu / grammage;
42  const double Lc_sigma_e = sqrt(v) / grammage;
43  const double Lc_tau = tau_sigma * Lc_sigma_e;
44 
45  fGaussExp_L->SetParameters(1., Lc_e, Lc_sigma_e , 1/Lc_tau, 0.);
46  const double Lc_shift = fGaussExp_L->GetMaximumX() - mu / grammage;
47  fGaussExp_L->SetParameter(4,Lc_shift);
48  double ff = fGaussExp_L->Eval( x / grammage);
49 
50  fGaussExp_L->Delete();
51  return ff;
52 }
53 
54 
55 
56 
57 unsigned int ProfileFitter::fNdof = 0;
58 vector<double> ProfileFitter::fDepth;
59 vector<double> ProfileFitter::fSize;
60 vector<double> ProfileFitter::fSizeVariance;
61 EFitFunctionType ProfileFitter::fFunctionType = eGH4dEdXChi2;
62 bool ProfileFitter::fIsConstrained = false;
63 
64 std::string ProfileFitter::fGaisserHillasType = "";
65 
66 bool ProfileFitter::fIsUnivConstrained = false;
67 utl::Function ProfileFitter::fUnivFunction;
68 double ProfileFitter::fVarK = 0;
69 
70 bool ProfileFitter::fEMGLConstrained = false;
71 double ProfileFitter::fTauOverSigma = 0;
72 
73 
74 const CFMatrixCalculator* ProfileFitter::fCFMatrixData = nullptr;
75 const CFMatrixCalculator* ProfileFitter::fCFMatrixDataDense = nullptr;
76 GHShapeParameters ProfileFitter::fGHShapePars;
77 ProfileFitter::EFitMode ProfileFitter::fFitMode = eNMax;
78 
79 double ProfileFitter::fShapeConstraintChi2[3] = { 0, 0, 0 };
80 
81 int ProfileFitter::fAafCorrection = 0;
82 bool ProfileFitter::fUseNoiseBins = false;
83 vector<vector<double>> ProfileFitter::fErrFuncFactorsBuf;
84 
85 
86 ProfileFitter::ProfileFitter() :
87  fVerbosity(0)
88 {
89  for (int i = 0; i < 3; ++i)
90  fShapeConstraintChi2[i] = 0;
91 }
92 
93 
94 void
96 {
97  Branch topBranch =
98  fwk::CentralConfig::GetInstance()->GetTopBranch("FdEnergyDepositFinder");
99 
100  fGHShapePars = GHShapeParameters(topBranch);
101 
102  fGaisserHillasType = topBranch.GetChild("gaisserHillasType").Get<string>();
103 
104  Branch kUnivBranch = topBranch.GetChild("kUnivConstrained");
105 
106  if (kUnivBranch.GetChild("constrained").Get<bool>()) {
107  fIsUnivConstrained = true;
108  kUnivBranch.GetChild("function").GetData(fUnivFunction);
109  const double kRMS = kUnivBranch.GetChild("ksigma").Get<double>();
110  fVarK = pow(kRMS, 2); // / (g/cm2), 2);
111  }
112 
113 
114 // Introducing a non-gaussian exponential tail for the L parameter in the USP reconstruction
115 
116  Branch EMGLConstraintBranch = topBranch.GetChild("ExponentiallyModifiedGaussianLConstraint");
117 
118  if (EMGLConstraintBranch.GetChild("activateEMGLConstraint").Get<bool>()) {
119  fEMGLConstrained = true;
120  fTauOverSigma = EMGLConstraintBranch.GetChild("tauOverSigma").Get<double>();
121  if (fGaisserHillasType != "eUSP")
122  WARNING("The exponentially modified gaussian constraint is defined only for USP Gaisser-Hillas function (L parameter). "
123  "For the other Gaisser-Hillas functions the constraint is always gaussian");
124  }
125 
126 
127 
128  topBranch.GetChild("antiAliasingFilterCorrection").GetData(fAafCorrection);
129  topBranch.GetChild("useNoiseBins").GetData(fUseNoiseBins);
130 
131  if (topBranch.GetChild("kUnivConstrained").GetChild("constrained").Get<bool>() &&
132  fGaisserHillasType == "eUSP") {
133  WARNING("k-constraint used in USP Gaisser-Hillas function - k is a "
134  "function of L and R and should be already constrained"
135  " through them.");
136  }
137 
138  ostringstream info;
139  info << "\n"
140  "\t anti-aliasing filter correction is " << (fAafCorrection ? "on" : "off") << "\n"
141  "\t use noise bins is " << (fUseNoiseBins ? "on" : "off") << '\n';
142  for (int index = 0; index < 2; ++index) {
143  const EOneTwo i = EOneTwo(index);
144  info << "\t " << fGHShapePars.Name(i) << " is constrained at (E=1e19eV) "
145  << fGHShapePars.Mean(i, 1e19*eV)/fGHShapePars.Unit(i) << "+/-" << fGHShapePars.Sigma(i, 1e19*eV)/fGHShapePars.Unit(i) << " "
146  "[" << fGHShapePars.Min(i)/fGHShapePars.Unit(i) << ", " << fGHShapePars.Max(i)/fGHShapePars.Unit(i) << "] "
147  << fGHShapePars.UnitName(i) << '\n';
148  }
149  INFO(info);
150  for (int i = 0; i < 3; ++i)
151  fShapeConstraintChi2[i] = 0;
152 }
153 
154 
155 void
156 ProfileFitter::SetLightFluxData(const CFMatrixCalculator& cfMatrixData, const CFMatrixCalculator& cfMatrixDataDense)
157 {
158  fCFMatrixData = &cfMatrixData;
159  fCFMatrixDataDense = &cfMatrixDataDense;
160 
161  //prepare anti-aliasing filter convolution parameters for telescopes in FOV
162  if (fAafCorrection) {
163  fErrFuncFactorsBuf.clear();
166  ++telIter) {
167  if (telIter->GetType() == TelescopeData::eInsideFOV) {
168  const fdet::FDetector& detFD = det::Detector::GetInstance().GetFDetector();
169  const unsigned int eyeId = fCFMatrixData->GetEyeId();
170  const unsigned int telId = telIter->GetId();
171  const fdet::Telescope& detTel = detFD.GetEye(eyeId).GetTelescope(telId);
172  PrepareTimeConvolution(detTel);
173  }
174  }
175  //copy zeta pixel light fractions to noise data bins
176  if (fUseNoiseBins && fAafCorrection == 2) {
177  auto telIterNoNoise = fCFMatrixDataDense->AllTelDataBegin();
178  for (auto telIter = fCFMatrixDataDense->NoiseTelDataBegin(); telIter != fCFMatrixDataDense->NoiseTelDataEnd(); ++telIter) {
179  if (telIter->GetType() == TelescopeData::eInsideFOV) {
180  while (telIterNoNoise->GetType() == TelescopeData::eOutsideFOV) {
181  ++telIterNoNoise;
182  }
183  vector<TelescopeDataBin>::const_iterator binIterNoNoise = telIterNoNoise->TelDataBinsBegin();
184  for (auto binIter = telIter->TelDataBinsBegin(); binIter != telIter->TelDataBinsEnd(); ++binIter) {
185  if (binIter->fMinDepth != 0 || binIter->fMaxDepth != 0) { //not a noise bin
186  auto& zp = binIter->GetZetaPixels();
187  for (unsigned int z = 0, n = zp.size(); z < n; ++z) {
188  zp[z].fLightFraction = binIterNoNoise->GetZetaPixels()[z].fLightFraction;
189  }
190  ++binIterNoNoise;
191  }
192  }
193  ++telIterNoNoise;
194  }
195  }
196  }
197  }
198 }
199 
200 
201 void
203 {
204  fDepth.clear();
205  fSize.clear();
206  fSizeVariance.clear();
207 
208  for (unsigned int i = 0, n = dEdXProfile.GetNPoints(); i < n; ++i) {
209  fDepth.push_back(dEdXProfile.GetX(i));
210  fSize.push_back(dEdXProfile.GetY(i));
211  fSizeVariance.push_back(pow(dEdXProfile.GetYErr(i), 2));
212  }
213 }
214 
215 
216 void
218 {
219  fGHShapePars = pars;
220 }
221 
222 
223 void
224 ProfileFitter::SetUnivConstrained(const bool constrained,
225  const utl::Function& func,
226  const double ksigma)
227 {
228  fIsUnivConstrained = constrained;
229  fUnivFunction = func;
230  fVarK = pow(ksigma, 2);
231 }
232 
233 
234 bool
236 {
237  if (fSizeVariance.empty()) {
238  ERROR("no data to fit!");
239  return false;
240  }
241 
242  fIsConstrained = true;
243 
244  switch (fFunctionType) {
245  case eUndefined:
246  return false;
247  case eGH2dEdXChi2:
248  case eGH4dEdXChi2:
249  case eGH4LightLogLike:
250  return GHFit();
251  }
252 
253  return false;
254 }
255 
256 
257 bool
259 {
260  for (int i = 0; i < 3; ++i)
261  fShapeConstraintChi2[i] = 0;
262 
263  const unsigned int nPar = eNGHpars;
264  TMinuit theMinuit(nPar);
265  theMinuit.SetFCN(ProfileFitter::GHFitFunction);
266  InitMinuit(theMinuit);
267 
268  if (fStartParameters.size() < eNGHpars) {
269  ERROR("too few start parameters for fit");
270  return false;
271  }
272 
273  int ierflag = 0;
274  theMinuit.mnparm(eGHnMax, "nMax", fStartParameters[eGHnMax],
275  fabs(fStartParameters[eGHnMax])*5e-2, 0, 0, ierflag);
276  theMinuit.mnparm(eGHXmax, "xMax", fStartParameters[eGHXmax],
277  10*g/cm2, 0, 0, ierflag);
278  theMinuit.mnparm(eGHShape1, fGHShapePars.Name(eOne),
280  fGHShapePars.Min(eOne), fGHShapePars.Max(eOne), ierflag);
281  theMinuit.mnparm(eGHShape2, fGHShapePars.Name(eTwo),
283  fGHShapePars.Min(eTwo), fGHShapePars.Max(eTwo), ierflag);
284  if (fFunctionType == eGH2dEdXChi2) {
285  theMinuit.FixParameter(eGHShape1);
286  theMinuit.FixParameter(eGHShape2);
287  }
288 
289  bool retVal = Minimize(theMinuit);
290 
292  fNdof -= 2;
293 
294  return retVal;
295 }
296 
297 
298 void
299 ProfileFitter::GHFitFunction(int& /*npar*/, double* const /*gin*/,
300  double& value, double* const par,
301  const int /*iFlag*/)
302 {
303  double fitParameters[eNGHpars];
304  for (int i = 0; i < eNGHpars; ++i)
305  fitParameters[i] = par[i];
306 
307  // nMax from integral
308  if (fFitMode == eIntegral) {
309  const GaisserHillas4Parameter::ShapeParameter xPar(fGHShapePars.Type(eOne), par[eGHShape1]);
310  const GaisserHillas4Parameter::ShapeParameter lPar(fGHShapePars.Type(eTwo), par[eGHShape2]);
311  const GaisserHillas4Parameter gh4(1, par[eGHXmax], xPar, lPar, fGHShapePars.Type());
312  fitParameters[eGHnMax] = par[eGHIntegral] / gh4.GetIntegral();
313  }
314 
315  if (fAafCorrection ||
316  fUseNoiseBins ||
318  value = fFunctionType == eGH4LightLogLike ?
319  GaisserHillasLogLikeConvoluted(fitParameters) : GaisserHillasChi2(fitParameters);
320  else
321  value = fFunctionType == eGH4LightLogLike ?
322  GaisserHillasLogLike(fitParameters) : GaisserHillasChi2(fitParameters);
323 }
324 
325 
326 // calculates -2*log(L) of data wrt.
327 // forward folded Gaisser-Hillas function
328 double
329 ProfileFitter::GaisserHillasLogLike(const double* const par)
330 {
331  double logLikeSum = 0;
332  fNdof = 0;
333 
334  // threshold for gaussian approximation
335  const double maxNpe = 30;
336  // maximum n for folding of Gauss and Poisson
337  const int maxSum = 100;
338 
339  const GaisserHillas4Parameter::ShapeParameter xPar(fGHShapePars.Type(eOne), par[eGHShape1]);
340  const GaisserHillas4Parameter::ShapeParameter lPar(fGHShapePars.Type(eTwo), par[eGHShape2]);
341  const GaisserHillas4Parameter ghFunction(par[eGHnMax], par[eGHXmax], xPar, lPar, fGHShapePars.Type());
342 
343  if (std::isnan(par[eGHXmax]) || std::isnan(par[eGHnMax]) ||
344  std::isnan(par[eGHShape1]) || std::isnan(par[eGHShape2]))
346 
348  const unsigned int matrixSize = cfMatrix.GetSize();
349 
350  // vectors with GH-values and light at aperture values
351  ColumnVector energyDeposit;
352  energyDeposit.SetSize(matrixSize);
353 
354  int i = 0;
355  for (auto telIter = fCFMatrixData->AllTelDataBegin(); telIter != fCFMatrixData->AllTelDataEnd(); ++telIter) {
356  for (auto binIter = telIter->TelDataBinsBegin(); binIter != telIter->TelDataBinsEnd(); ++binIter) {
357  energyDeposit(i) = ghFunction.Eval(binIter->GetMeanDepth());
358  ++i;
359  }
360  }
361 
362  ColumnVector predictedLightFlux = cfMatrix*energyDeposit;
363 
364  double nPeObsTot = 0;
365  double nPeExpTot = 0;
366 
367  double gainVariance = 0;
368 
369  // sum up log-likelihoods
370  i = 0;
371  for (auto telIter = fCFMatrixData->AllTelDataBegin(); telIter != fCFMatrixData->AllTelDataEnd(); ++telIter) {
372 
373  if (telIter->GetType() == TelescopeData::eInsideFOV) {
374 
375  // conversion factors for this telescope
376  const double kFluxToPe = telIter->GetDiaphragmArea() * telIter->GetPhotonToPhotoElectron();
377  const double kFluxToPe2 = kFluxToPe * kFluxToPe;
378  gainVariance = telIter->GetGainVariance();
379 
380  for (auto binIter = telIter->TelDataBinsBegin(); binIter != telIter->TelDataBinsEnd(); ++binIter) {
381 
382  const double lightFlux = binIter->fSignal;
383  const double bgVariance = binIter->fBackgroundVariance;
384 
385  // expected and observed photo electrons
386  const double nPeBackground = bgVariance*kFluxToPe2 / (1 + gainVariance);
387  const double nPeSignalExp = predictedLightFlux(i) * kFluxToPe;
388  const double nPeExp = nPeSignalExp + nPeBackground;
389  const double nPeObs = lightFlux*kFluxToPe + nPeBackground;
390 
391  nPeObsTot += nPeObs;
392  nPeExpTot += nPeExp;
393 
394  double logLike;
395  if (nPeObs < maxNpe) {
396 
397  const double gaussVar = nPeExp*gainVariance;
398 
399  const double lnNpe = log(nPeExp);
400 
401  // do the Poisson/Gauss folding
402  double sum = 0;
403  for (int k = 0; k < maxSum; ++k) {
404  const double gaussArg = -0.5*pow(k - nPeObs, 2) / gaussVar;
405  const double lnFaculty = LogGamma(k + 1);
406  const double expArg = gaussArg - nPeExp + k*lnNpe - lnFaculty;
407  const double value = exp(expArg);
408  sum += value;
409  }
410  logLike = log(sum) - 0.5*log(gaussVar);
411 
412  } else { // Gaussian approximation
413  const double gaussVar = nPeExp*(1 + gainVariance);
414  logLike = -0.5*pow(nPeExp - nPeObs, 2) / gaussVar - 0.5*log(gaussVar);
415  }
416 
417  logLikeSum += logLike;
418  ++fNdof;
419  ++i;
420  }
421  } else
422  i += telIter->GetTelescopeDataBins().size();
423 
424  }
425 
426  // extended logLike: total number of nPe's
427  const double gaussVar = nPeExpTot*(1 + gainVariance);
428  logLikeSum += -0.5*pow(nPeExpTot - nPeObsTot, 2) / gaussVar - 0.5*log(gaussVar);
429  --fNdof;
430 
431  // add constraints
433 
434  const double Xmax = par[eGHXmax];
435  const double dEdXmax = par[eGHnMax];
436  const double X0 = ghFunction.GetShapeParameter(evt::gh::eX0);
437  const double lambda = ghFunction.GetShapeParameter(evt::gh::eLambda);
438  const double myEta = (Xmax -X0)/lambda;
439  const double myEcal = lambda * dEdXmax * pow(kE/myEta,myEta) * TMath::Gamma(myEta+1);
440 
441  if (fIsConstrained) {
442  const double p[2] = {par[eGHShape1], par[eGHShape2]};
443  for (int index = 0; index < 2; ++index) {
444 
445 
446  const EOneTwo i = EOneTwo(index);
447  const double v = fGHShapePars.Variance(i, myEcal);
448  const double mu = fGHShapePars.Mean(i, myEcal);
449 
450  if (fEMGLConstrained==true && fGHShapePars.Name(i)=="L_{USP}"){
451 
452  double ff = GaussExp(p[i], mu, v , fTauOverSigma);
453 
454  logLikeSum += (log(ff));
455  fShapeConstraintChi2[index] = -2.*(log(ff));
456 
457  } else {
458 
459  logLikeSum += (-0.5*log(v) - 0.5*pow(p[i]-mu, 2)/v);
460  fShapeConstraintChi2[index] = -2.*(-0.5*log(v) - 0.5*pow(p[i]-mu, 2)/v);
461 
462  }
463  }
464  }
465 
466  if (fIsUnivConstrained) {
467  const double fkUniv = myEcal/dEdXmax;
468  const double fkUnivTrue = fUnivFunction(myEcal);
469  logLikeSum +=(-0.5*log(fVarK) - 0.5*pow(fkUniv - fkUnivTrue, 2)/fVarK);
470  fShapeConstraintChi2[2] = -2.*(-0.5*log(fVarK)-0.5*pow(fkUniv-fkUnivTrue ,2)/fVarK);
471  }
472  }
473 
474  return -2 * logLikeSum;
475 }
476 
477 
478 // version with forward folded anti-aliasing filter convolution
479 double
481 {
482  double logLikeSum = 0;
483  fNdof = 0;
484 
485  // threshold for gaussian approximation
486  const double maxNpe = 30;
487  // maximum n for folding of Gauss and Poisson
488  const int maxSum = 100;
489 
490  const GaisserHillas4Parameter::ShapeParameter xPar(fGHShapePars.Type(eOne), par[eGHShape1]);
491  const GaisserHillas4Parameter::ShapeParameter lPar(fGHShapePars.Type(eTwo), par[eGHShape2]);
492  const GaisserHillas4Parameter ghFunction(par[eGHnMax], par[eGHXmax], xPar, lPar, fGHShapePars.Type());
493 
494  if (std::isnan(par[eGHXmax]) || std::isnan(par[eGHnMax]) ||
495  std::isnan(par[eGHShape1]) || std::isnan(par[eGHShape2]))
497 
499  const unsigned int matrixSize = cfMatrix.GetSize();
500 
501  // vectors with GH-values and light at aperture values
502  ColumnVector energyDeposit;
503  energyDeposit.SetSize(matrixSize);
504 
505  int i = 0;
506  for (auto telIter = fCFMatrixDataDense->AllTelDataBegin(); telIter != fCFMatrixDataDense->AllTelDataEnd(); ++telIter) {
507  for (auto binIter = telIter->TelDataBinsBegin(); binIter != telIter->TelDataBinsEnd(); ++binIter) {
508  energyDeposit(i) = ghFunction.Eval(binIter->GetMeanDepth());
509  ++i;
510  }
511  }
512 
513  ColumnVector predictedLightFlux = cfMatrix*energyDeposit;
514 
515  vector<double> predLF;
516  vector<int> telBinSizes;
517  vector<int> telBinSizesPredictedLightFlux;
518  // include noise bins and sum dense bins
519  i = 0;
522  ++telIter) {
523 
524  int lastParentBin = -1;
525  int telBinSize = 0;
526  int k = 0;
527  for (auto binIter = telIter->TelDataBinsBegin(); binIter != telIter->TelDataBinsEnd(); ++binIter) {
528  if (telIter->GetType() == TelescopeData::eInsideFOV) {
529  if (binIter->fParentBin == lastParentBin) {
530  if (binIter->fMinDepth != 0 || binIter->fMaxDepth != 0) {
531  predLF.back() += predictedLightFlux(i);
532  ++i;
533  ++k;
534  } //nothing for noise bins
535  } else { //new real bin in aperture light
536  if (binIter->fMinDepth != 0 || binIter->fMaxDepth != 0) {
537  predLF.push_back(predictedLightFlux(i));
538  ++i;
539  ++k;
540  } else { //noise bin
541  predLF.push_back(0);
542  }
543  lastParentBin = binIter->fParentBin;
544  ++telBinSize;
545  }
546  } else { //outside FOV bins are "not dense"
547  predLF.push_back(predictedLightFlux(i));
548  ++telBinSize;
549  ++i;
550  ++k;
551  }
552  }
553  telBinSizes.push_back(telBinSize);
554  telBinSizesPredictedLightFlux.push_back(k);
555  }
556 
557  // prepare expected photo electrons
558 
559  double gainVariance = 0;
560 
561  i = 0;
562  // vector<double> nPeExpArray(predictedLightFlux.GetSize(),0);
563  vector<double> nPeExpArray(predLF.size(), 0);
566  ++telIter) {
567 
568  if (telIter->GetType() == TelescopeData::eInsideFOV) {
569  const double kFluxToPe = telIter->GetDiaphragmArea() * telIter->GetPhotonToPhotoElectron();
570  //const double kFluxToPe2 = kFluxToPe * kFluxToPe;
571  gainVariance = telIter->GetGainVariance();
572 
573  int lastParentBin = -1;
574  for (auto binIter = telIter->TelDataBinsBegin(); binIter != telIter->TelDataBinsEnd(); ++binIter) {
575 
576  if (binIter->fParentBin != lastParentBin) { //sum only for real aperture light bins
577  // const double bgVariance = binIter->fBackgroundVariance;
578 
579  // expected and observed photo electrons
580  //const double nPeBackground = bgVariance*kFluxToPe2/(1.+gainVariance);
581  //const double nPeSignalExp = predictedLightFlux(i)*kFluxToPe;
582  const double nPeSignalExp = predLF[i]*kFluxToPe;
583  const double nPeExp = nPeSignalExp; // +nPeBackground;
584  nPeExpArray[i] = nPeExp;
585  ++i;
586  lastParentBin = binIter->fParentBin;
587  }
588 
589  }
590  } else
591  i += telIter->GetTelescopeDataBins().size(); // for outside of FOV the same as in telBinSizes
592  }
593 
594  // do anti-aliasing filter convolution
595  i = 0;
596  int k = 0;
597  int t = 0;
598  if (fAafCorrection) {
599  unsigned int telIndex = 0;
602  ++telIter) {
603 
604  unsigned int telBinSize = telBinSizes[t];
605 
606  if (telIter->GetType() == TelescopeData::eInsideFOV) {
607  //const double kFluxToPe = telIter->GetDiaphragmArea() * telIter->GetPhotonToPhotoElectron();
608  //const double kFluxToPe2 = kFluxToPe * kFluxToPe;
609  gainVariance = telIter->GetGainVariance();
610 
611  const unsigned int nSafety = fErrFuncFactorsBuf[telIndex].size() - 1;
612 
613  const unsigned int convTraceSize = telBinSize;
614 
615  const unsigned int origTraceSize = convTraceSize + 2*nSafety;
616  vector<double> originalTrace(origTraceSize, 0.);
617  for (unsigned int j = 0; j < convTraceSize; j++) {
618  originalTrace[j+nSafety] = nPeExpArray[i+j];
619  }
620 
621  vector<double> convolutedTrace(convTraceSize, 0.);
622 
623  DoTimeConvolution(originalTrace, convolutedTrace, nSafety, telIndex, *telIter, predictedLightFlux, predLF, k, i);
624 
625  for (unsigned int j = 0; j < convTraceSize; ++j) {
626  nPeExpArray[i+j] = convolutedTrace[j];
627  }
628  ++telIndex;
629  }
630  i += telBinSize;
631  k += telBinSizesPredictedLightFlux[t];
632  ++t;
633  }
634  }
635 
636  double nPeObsTot = 0;
637  double nPeExpTot = 0;
638 
639  // sum up log-likelihoods
640  i = 0;
643  ++telIter) {
644 
645  if (telIter->GetType() == TelescopeData::eInsideFOV) {
646 
647  // conversion factors for this telescope
648  const double kFluxToPe = telIter->GetDiaphragmArea() * telIter->GetPhotonToPhotoElectron();
649  const double kFluxToPe2 = kFluxToPe * kFluxToPe;
650  gainVariance = telIter->GetGainVariance();
651 
652  int lastParentBin = -1;
653 
654  for (auto binIter = telIter->TelDataBinsBegin(); binIter != telIter->TelDataBinsEnd(); ++binIter) {
655 
656  if (binIter->fParentBin != lastParentBin) { //sum only for real aperture light bins
657 
658  const double lightFlux = binIter->fSignal;
659  const double bgVariance = binIter->fBackgroundVariance;
660 
661  // expected and observed photo electrons
662  const double nPeBackground = bgVariance * kFluxToPe2 / (1 + gainVariance);
663  const double nPeExp = nPeExpArray[i] + nPeBackground;
664  const double nPeObs = lightFlux * kFluxToPe + nPeBackground;
665 
666  nPeObsTot += nPeObs;
667  nPeExpTot += nPeExp;
668 
669  double logLike;
670  if (nPeObs < maxNpe) {
671 
672  const double gaussVar = nPeExp*gainVariance;
673 
674  const double lnNpe = log(nPeExp);
675 
676  // do the Poisson/Gauss folding
677  double sum = 0;
678  for (int k = 0; k < maxSum; ++k) {
679  const double gaussArg = -0.5 * pow(k - nPeObs, 2) / gaussVar;
680  const double lnFaculty = LogGamma(k + 1);
681  const double expArg = gaussArg - nPeExp + k*lnNpe - lnFaculty;
682  const double value = exp(expArg);
683  sum += value;
684  }
685  logLike = log(sum) - 0.5*log(gaussVar);
686 
687  } else { // Gaussian approximation
688  const double gaussVar = nPeExp*(1 + gainVariance);
689  logLike = -0.5*pow(nPeExp - nPeObs, 2) / gaussVar - 0.5*log(gaussVar);
690  }
691 
692  logLikeSum += logLike;
693  ++fNdof;
694  ++i;
695  lastParentBin = binIter->fParentBin;
696  }
697 
698  }
699 
700  } else
701  i += telIter->GetTelescopeDataBins().size(); // for outside of FOV the same as in telBinSizes
702 
703  }
704 
705  // extended logLike: total number of nPe's
706  const double gaussVar = nPeExpTot * (1 + gainVariance);
707  logLikeSum += -0.5*pow(nPeExpTot - nPeObsTot, 2) / gaussVar - 0.5*log(gaussVar);
708  --fNdof;
709 
710  // add constraints
712 
713  const double Xmax = par[eGHXmax];
714  const double dEdXmax = par[eGHnMax];
715  const double X0 = ghFunction.GetShapeParameter(evt::gh::eX0);
716  const double lambda = ghFunction.GetShapeParameter(evt::gh::eLambda);
717  const double myEta = (Xmax -X0)/lambda;
718  const double myEcal = lambda * dEdXmax * pow(kE/myEta,myEta) * TMath::Gamma(myEta+1);
719 
720  if (fIsConstrained) {
721  const double p[2] = {par[eGHShape1], par[eGHShape2]};
722  for (int index = 0; index < 2; ++index) {
723  const EOneTwo i = EOneTwo(index);
724  const double v = fGHShapePars.Variance(i, myEcal);
725  const double mu = fGHShapePars.Mean(i, myEcal);
726 
727 
728  if (fEMGLConstrained==true && fGHShapePars.Name(i)=="L_{USP}"){
729 
730  double ff = GaussExp(p[i], mu, v , fTauOverSigma);
731 
732  logLikeSum += (log(ff));
733  fShapeConstraintChi2[index] = -2.*(log(ff));
734 
735  } else {
736 
737  logLikeSum += (-0.5*log(v) - 0.5*pow(p[i]-mu, 2)/v);
738  fShapeConstraintChi2[index] = -2.*(-0.5*log(v) - 0.5*pow(p[i]-mu, 2)/v);
739 
740  }
741  }
742  }
743 
744  if (fIsUnivConstrained) {
745  const double fkUniv = myEcal/dEdXmax;
746  const double fkUnivTrue = fUnivFunction(myEcal);
747  logLikeSum += -0.5*log(fVarK) - 0.5*pow(fkUniv - fkUnivTrue, 2) / fVarK;
748  fShapeConstraintChi2[2] = log(fVarK) + pow(fkUniv - fkUnivTrue, 2) / fVarK;
749  }
750  }
751 
752  return -2*logLikeSum;
753 }
754 
755 
756 // calculates chi2 of dE/dX profile wrt.
757 // Gaisser-Hillas function
758 double
760 {
761  double chi2 = 0;
762  const GaisserHillas4Parameter::ShapeParameter xPar(fGHShapePars.Type(eOne), par[eGHShape1]);
763  const GaisserHillas4Parameter::ShapeParameter lPar(fGHShapePars.Type(eTwo), par[eGHShape2]);
764  const GaisserHillas4Parameter ghFunction(par[eGHnMax], par[eGHXmax], xPar, lPar, fGHShapePars.Type());
765  fNdof = 0;
766  if (std::isnan(par[eGHXmax]) || std::isnan(par[eGHnMax]) ||
767  std::isnan(par[eGHShape1]) || std::isnan(par[eGHShape2]))
769 
770  for (unsigned int i = 0; i < fDepth.size(); ++i) {
771 
772  const double y = fSize[i];
773 
774  const double x = fDepth[i];
775  const double fx = ghFunction.Eval(x);
776  const double vy = fSizeVariance[i];
777 
778  chi2 += pow(y - fx, 2) / vy;
779  ++fNdof;
780  }
781 
782  // constraints a la FdProfileReconstructor
784 
785  const double Xmax = par[eGHXmax];
786  const double dEdXmax = par[eGHnMax];
787  const double X0 = ghFunction.GetShapeParameter(evt::gh::eX0);
788  const double lambda = ghFunction.GetShapeParameter(evt::gh::eLambda);
789  const double myEta = (Xmax - X0) / lambda;
790  const double myEcal = lambda * dEdXmax * pow(kE / myEta, myEta) * TMath::Gamma(myEta+1);
791 
792  if (fIsConstrained) {
793 
794  const double p[2] = { par[eGHShape1], par[eGHShape2] };
795  for (int index = 0; index < 2; ++index) {
796  const EOneTwo i = EOneTwo(index);
797  const double v = fGHShapePars.Variance(i, myEcal);
798  const double mu = fGHShapePars.Mean(i, myEcal);
799 
800  if (fEMGLConstrained==true && fGHShapePars.Name(i)=="L_{USP}"){
801 
802  double ff = GaussExp(p[i], mu, v , fTauOverSigma);
803 
804  chi2 += -2.*log(ff);
805  fShapeConstraintChi2[index] = -2.*log(ff);
806 
807  } else {
808 
809  const double addchi2 = pow(p[i] - mu, 2) / v;
810  chi2 += addchi2;
811  fShapeConstraintChi2[index] = addchi2;
812 
813  }
814  }
815  }
816 
817  if (fIsUnivConstrained) {
818  const double fkUniv = myEcal/dEdXmax;
819  const double fkUnivTrue = fUnivFunction(myEcal);
820  const double addchi2 = pow(fkUniv - fkUnivTrue, 2) / fVarK;
821  chi2 += addchi2;
822  fShapeConstraintChi2[2] = addchi2;
823  }
824  }
825 
826  return chi2;
827 }
828 
829 
830 bool
831 ProfileFitter::Minimize(TMinuit& theMinuit)
832 {
833  int ierflag = 0;
834  double arglist[2] = { 1000, 1 };
835  theMinuit.mnexcm("MINIMIZE", arglist, 2, ierflag);
836 
837  if (ierflag) {
838  if (fVerbosity > -1)
839  cerr << " MINIMIZE failed " << ierflag << endl;
840  return false;
841  }
842 
843  theMinuit.mnexcm("HESSE", arglist, 2, ierflag);
844 
845  double amin, edm, errdef;
846  int nvpar, nparx, icstat;
847  theMinuit.mnstat(amin, edm, errdef, nvpar, nparx, icstat);
848  fStatus = icstat;
849 
850  if (fStatus != 3) {
851  // from TMinuit.cxx:
852  // matrix: 0= not calculated at all
853  // 1= approximation only, not accurate
854  // 2= full matrix, but forced positive-definite
855  // 3= full accurate covariance matrix
856  if (fVerbosity > -1)
857  cerr << " ProfileFitter::Minimize(): status from mnstat "
858  << fStatus << endl;
859  return false;
860  }
861 
862  if (nparx != eNGHpars) {
863  cerr << " ProfileFitter::Minimize(): parameter mismatch??? " << endl;
864  return false;
865  }
866 
867  fFitParameters.resize(nparx);
868  double dummy = 0;
869  for (int i = 0; i < nparx; ++i)
870  theMinuit.GetParameter(i, fFitParameters[i], dummy);
871  theMinuit.mnemat(&fCovariance[0][0], eNGHpars);
872 
874  fChi2 = amin;
875 
876  //VN: to be able to use fFitModes and fill fShapeConstrainChi2
877  int dummy1 = 0;
878  double dummy2 = 0;
879  double dummy3 = 0;
880  int dummy4 = 0;
881  GHFitFunction(dummy1, &dummy2, dummy3, &fFitParameters.front(), dummy4);
882  //GaisserHillasChi2(&fFitParameters.front()); // in order to fill fShapeConstrainChi2 !
883 
884  fLHChi2 = amin;
885  } else {
886  //VN: to be able to use fFitModes and fill fShapeConstrainChi2
887  int dummy1 = 0;
888  double dummy2 = 0;
889  double dummy3 = 0;
890  int dummy4 = 0;
891  // simple chi2 for logLike
893  GHFitFunction(dummy1, &dummy2, fChi2, &fFitParameters.front(), dummy4);
894  //fChi2 = GaisserHillasChi2(&fFitParameters.front());
895 
896  //VN: light fit for fShapeConstrainChi2
898  GHFitFunction(dummy1, &dummy2, dummy3, &fFitParameters.front(), dummy4);
899  fLHChi2 = amin;
900  }
901 
902  return true;
903 }
904 
905 
906 void
907 ProfileFitter::InitMinuit(TMinuit& theMinuit)
908  const
909 {
910  int ierflag;
911  if (fVerbosity == 2)
912  theMinuit.SetPrintLevel(0);
913  else if (fVerbosity >= 3)
914  theMinuit.SetPrintLevel(fVerbosity);
915  else {
916  theMinuit.SetPrintLevel(-1);
917  theMinuit.mnexcm("SET NOW", 0 ,0,ierflag);
918  }
919 
920  double arglist = 1;
921  theMinuit.mnexcm("SET ERR", &arglist, 1, ierflag);
922  arglist = 2;
923  theMinuit.mnexcm("SET STRAT", &arglist, 1, ierflag);
924 }
925 
926 
927 void
929 {
930  fStartParameters.resize(eNGHpars);
931  if (fFitMode == eIntegral)
933  else
938 }
939 
940 
941 void
943  const
944 {
945  if (ghPars.GetFunctionType() != fGHShapePars.Type()) {
946  using namespace evt::gh;
947  ostringstream errMsg;
948  throw DoesNotComputeException("GH type mismatch: " +
950  "!=" +
952  } else if (fFitParameters.size() != eNGHpars) {
953  ERROR("FillGHParameters() without data!");
954  ghPars.SetXMax(0, 0);
955  ghPars.SetNMax(0, 0, true);
956  ghPars.SetShapeParameter(fGHShapePars.Type(eOne), 0, 0);
957  ghPars.SetShapeParameter(fGHShapePars.Type(eTwo), 0, 0);
958  ghPars.SetChiSquare(0, 0);
959  } else {
960  ghPars.SetXMax(fFitParameters[eGHXmax], sqrt(fCovariance[eGHXmax][eGHXmax]));
961  ghPars.SetNMax(fFitParameters[eGHnMax], sqrt(fCovariance[eGHnMax][eGHnMax]), true);
964  ghPars.SetChiSquare(fChi2, fNdof);
965 
966  ghPars.SetNMaxXMaxCorrelation(CorrCoeff(eGHnMax, eGHXmax));
967  ghPars.SetCorrelationNMaxShapeParameter(fGHShapePars.Type(eTwo), CorrCoeff(eGHnMax, eGHShape2));
968  ghPars.SetCorrelationNMaxShapeParameter(fGHShapePars.Type(eOne), CorrCoeff(eGHnMax, eGHShape1));
969  ghPars.SetCorrelationXMaxShapeParameter(fGHShapePars.Type(eTwo), CorrCoeff(eGHXmax, eGHShape2));
970  ghPars.SetCorrelationXMaxShapeParameter(fGHShapePars.Type(eOne), CorrCoeff(eGHXmax, eGHShape1));
971  ghPars.SetCorrelationShapeParameters(CorrCoeff(eGHShape2, eGHShape1));
972  }
973 }
974 
975 
976 void
977 ProfileFitter::GetEnergy(double& energy, double& energyError)
978  const
979 {
980  if (fFitParameters.size() != eNGHpars) {
981  ERROR(" cannot calculate energy without fit!");
982  energy = 0;
983  energyError = 0;
984  return;
985  }
986 
987  if (fFitMode == eIntegral) {
988  energy = fFitParameters[eGHIntegral];
989  energyError = sqrt(fCovariance[eGHIntegral][eGHIntegral]);
990  } else {
992  FillGHParameters(ghPars);
993  energy = ghPars.GetIntegral();
994  energyError = energy * ghPars.GetIntegralError();
995  }
996 }
997 
998 
999 void
1001 {
1002  const fdet::Camera& detCamera = detTel.GetCamera();
1003  const double timeBinSize = detCamera.GetFADCBinSize();
1004 
1005  // see IEEE Trans.Nucl.Sci.50:1208-1213,2003
1006  const double cutoffFrequency = detCamera.GetCutoffFrequency();
1007  const double tau = sqrt(log(2.)) / (kTwoPi * cutoffFrequency);
1008 
1009  vector<double> fErrFuncFactors;
1010  fErrFuncFactors.clear();
1011 
1012  const double epsilon = 1e-6;
1013  const int maxIter = 50;
1014  int iter = 0;
1015 
1016  double sumE = 0;
1017  double sumESquare = 0;
1018 
1019  while (sumE < 1 - epsilon && iter < maxIter) {
1020 
1021  const double t1 = (iter - 0.5) * timeBinSize;
1022  const double t2 = (iter + 0.5) * timeBinSize;
1023 
1024  const double E1 = 0.5 * erf(t1 / (sqrt(2.)*tau));
1025  const double E2 = 0.5 * erf(t2 / (sqrt(2.)*tau));
1026  const double E = E2 - E1;
1027 
1028  fErrFuncFactors.push_back(E);
1029 
1030  if (iter == 0) {
1031  sumESquare += E*E;
1032  sumE += E;
1033  } else {
1034  sumESquare += 2*E*E;
1035  sumE += 2*E;
1036  }
1037 
1038  ++iter;
1039  }
1040 
1041  if (iter+1 >= maxIter || fErrFuncFactors.empty()) {
1042  ostringstream msg;
1043  msg << " Error filling fErrFuncFactors !!! "
1044  << iter << ' ' << fErrFuncFactors.size();
1045  ERROR(msg);
1046  throw AugerException(msg.str());
1047  }
1048 
1049  fErrFuncFactorsBuf.push_back(fErrFuncFactors);
1050 }
1051 
1052 
1053 void
1054 ProfileFitter::DoTimeConvolution(const vector<double>& originalTrace,
1055  vector<double>& convolutedTrace,
1056  unsigned int timeOffset,
1057  unsigned int ErrFuncFactorsIndex,
1058  const TelescopeData& telData,
1059  const ColumnVector& predictedLightFlux,
1060  const std::vector<double>& predLF,
1061  const int startBinDense,
1062  const int startBin)
1063 {
1064  const int convolutedTraceSize = convolutedTrace.size();
1065  const int originialTraceSize = originalTrace.size();
1066  vector<double> fErrFuncFactors;
1067 
1068  const std::vector<TelescopeDataBin>& telDataBins = telData.GetTelescopeDataBins();
1069 
1070  if (ErrFuncFactorsIndex < fErrFuncFactorsBuf.size()) {
1071  fErrFuncFactors = fErrFuncFactorsBuf[ErrFuncFactorsIndex];
1072  } else {
1073  ostringstream msg;
1074  msg << " ErrFuncFactorIndex out of range ";
1075  ERROR(msg);
1076  throw AugerException(msg.str());
1077  }
1078  const int nConv = int(fErrFuncFactors.size());
1079 
1080  // check trace sizes...
1081  if (originialTraceSize-convolutedTraceSize < 2*(nConv - 1)) {
1082  // that should never happend !!!!
1083  ostringstream msg;
1084  msg << " Trace size mismatch!!! "
1085  << convolutedTraceSize << ' ' << originialTraceSize << ' ' << fErrFuncFactors.size();
1086  ERROR(msg);
1087  throw AugerException(msg.str());
1088  }
1089 
1090  //prepare zeta pixel signals
1091  vector<vector<pair<int, double>>> telDataBinZeta;
1092  int lastParentBin = -1;
1093  int i = 0;
1094  if (fAafCorrection == 2) {
1095  for (unsigned int t = 0; t < telDataBins.size(); ++t) {
1096  if (telDataBins[t].fParentBin == lastParentBin) {
1097  if (telDataBins[t].fMinDepth != 0 || telDataBins[t].fMaxDepth != 0) {
1098  bool noZeta = bool(telDataBinZeta.back().size());
1099  for (unsigned int z = 0; z < telDataBins[t].GetZetaPixels().size(); ++z) {
1100  if (noZeta) {
1101  telDataBinZeta.back()[z].second += telDataBins[t].GetZetaPixels()[z].fLightFraction * predictedLightFlux(i+startBinDense);
1102  } else {
1103  telDataBinZeta.back().push_back(make_pair(telDataBins[t].GetZetaPixels()[z].fPixelId, telDataBins[t].GetZetaPixels()[z].fLightFraction * predictedLightFlux(i+startBinDense)));
1104  }
1105  }
1106  ++i;
1107  } //nothing for noise bins
1108  } else { //new real bin in aperture light
1109  vector<pair<int, double>> zetaLF;
1110  if (telDataBins[t].fMinDepth != 0 || telDataBins[t].fMaxDepth != 0) { //not a noise bin
1111  for (unsigned int z = 0; z < telDataBins[t].GetZetaPixels().size(); ++z) {
1112  zetaLF.push_back(make_pair(telDataBins[t].GetZetaPixels()[z].fPixelId, telDataBins[t].GetZetaPixels()[z].fLightFraction * predictedLightFlux(i+startBinDense)));
1113  }
1114  ++i;
1115  }
1116  telDataBinZeta.push_back(zetaLF);
1117  lastParentBin = telDataBins[t].fParentBin;
1118  }
1119  }
1120  for (unsigned int t = 0, nt = telDataBinZeta.size(); t < nt; ++t) {
1121  for (unsigned int z = 0, nz = telDataBinZeta[t].size(); z < nz; ++z) {
1122  if (predLF[startBin+t] > 0)
1123  telDataBinZeta[t][z].second /= predLF[startBin + t];
1124  else
1125  telDataBinZeta[t][z].second = 0;
1126  }
1127  }
1128  }
1129 
1130  const int tOff = timeOffset;
1131  for (int i = -nConv + 1; i < nConv; ++i) {
1132  const double w = fErrFuncFactors[abs(i)];
1133  for (int tConv = 0; tConv < convolutedTraceSize; ++tConv) {
1134  const int tOrig = tConv + tOff + i;
1135  // zeta weight factors
1136  double wzeta = 1;
1137  if (fAafCorrection == 2 && tOrig >= tOff && tOrig < (convolutedTraceSize + tOff)) {
1138  wzeta = 0;
1139  const int tO = tOrig - tOff;
1140  const int tC = tConv;
1141  for (unsigned int zO = 0, nO = telDataBinZeta[tO].size(); zO < nO; ++zO) {
1142  for (unsigned int zC = 0, nC = telDataBinZeta[tC].size(); zC < nC; ++zC) {
1143  if (telDataBinZeta[tO][zO].first == telDataBinZeta[tC][zC].first) {
1144  wzeta += telDataBinZeta[tO][zO].second; // relative to the total ldf light fraction -> same zeta pixels => wzeta == 1
1145  break;
1146  }
1147  }
1148  }
1149  }
1150  convolutedTrace[tConv] += wzeta * w * originalTrace[tOrig];
1151  }
1152  }
1153 }
double GetShapeParameter(const gh::EShapeParameter par) const
access to all variants of shape parameters (see GaisserHillasTypes.h)
static void PrepareTimeConvolution(const fdet::Telescope &detTel)
const double eV
Definition: GalacticUnits.h:35
unsigned int GetNPoints() const
double GetFADCBinSize() const
static double GaisserHillasLogLikeConvoluted(const double *const par)
std::string Name(const EOneTwo par) const
parameter name
constexpr double kE
Definition: MathConstants.h:28
double CorrCoeff(const EGHFunctionPar i, const EGHFunctionPar j) const
static std::vector< std::vector< double > > fErrFuncFactorsBuf
Base class for all exceptions used in the auger offline code.
void SetNMaxXMaxCorrelation(const double rho)
static double GaisserHillasLogLike(const double *const par)
evt::gh::EFunctionType Type() const
function type
void SetSize(const int n)
Set the size of the vector. Does NOT initialize elements to 0.
Definition: LinearAlgebra.h:47
double GetCutoffFrequency() const
void SetXMax(const double xMax, const double error)
void SetProfileData(const utl::TabulatedFunctionErrors &)
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
double Unit(const EOneTwo par) const
parameter unit value
double Step(const EOneTwo par) const
step size for fit
void SetShapeParameter(const gh::EShapeParameter par, const double value, const double error)
Setters.
const Eye & GetEye(const unsigned int eyeId) const
Find eye by numerical Id.
Definition: FDetector.cc:68
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double pow(const double x, const unsigned int i)
ConstTelDataIterator AllTelDataBegin() const
const Camera & GetCamera() const
Get the Camera object that belongs to the telescope.
Detector description interface for FDetector-related data.
Definition: FDetector.h:44
static void GHFitFunction(int &, double *const, double &, double *const, const int)
std::string GetFunctionTypeName(const EFunctionType type)
void SetUnivConstrained(const bool constrained, const utl::Function &func, const double ksigma)
T Get() const
Definition: Branch.h:271
void SetStartParameters(const evt::GaisserHillas4Parameter &)
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
const double & GetYErr(const unsigned int idx) const
double Variance(const EOneTwo par, const double E) const
constraint variance
double LogGamma(const double x)
void SetLightFluxData(const CFMatrixCalculator &cfMatrixData)
ConstTelDataIterator NoiseTelDataEnd() const
double abs(const SVector< n, T > &v)
const LowerTriangularMatrix & GetCFMatrix() const
const Telescope & GetTelescope(const unsigned int telescopeId) const
Find Telescope by numerical Id.
constexpr double kTwoPi
Definition: MathConstants.h:27
constexpr double g
Definition: AugerUnits.h:200
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
void SetChiSquare(const double chi, const unsigned int ndof)
a second level trigger
Definition: XbT2.h:8
Base class for inconsistency/illogicality exceptions.
Evaluate functions given in a string. The real work is done by the ExpressionParser class...
Definition: Function.h:27
const double & GetY(const unsigned int idx) const
void SetNMax(const double nMax, const double error, const bool isEnergyDeposit=false)
double GaussExp(const double x, const double mu, const double v, const double tau_sigma)
Detector description interface for Telescope-related data.
double Sigma(const EOneTwo par, const double E) const
constraint sigma
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
ConstTelDataIterator NoiseTelDataBegin() const
constexpr double cm
Definition: AugerUnits.h:117
static void DoTimeConvolution(const std::vector< double > &originalTrace, std::vector< double > &convolutedTrace, unsigned int timeOffset, unsigned int ErrFuncFactorsIndex, const TelescopeData &telData, const ColumnVector &predictedLightFlux, const std::vector< double > &predLF, const int startBinDense, const int startBin)
const double & GetX(const unsigned int idx) const
const std::vector< TelescopeDataBin > & GetTelescopeDataBins() const
void SetCorrelationNMaxShapeParameter(const gh::EShapeParameter par, const double rho)
double Min(const EOneTwo par) const
minimum value for fit
double Mean(const EOneTwo par, const double E) const
constraint mean
static double GaisserHillasChi2(const double *const par)
double Max(const EOneTwo par) const
maximum value for fit
void GetEnergy(double &energy, double &energyError) const
double GetIntegral() const
calculate integral
gh::EFunctionType GetFunctionType() const
Gaisser Hillas with 4 parameters.
void SetCorrelationShapeParameters(const double rho)
const int nPar
Definition: GeomAsym.h:37
void SetCorrelationXMaxShapeParameter(const gh::EShapeParameter par, const double rho)
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
ConstTelDataIterator AllTelDataEnd() const
void FillGHParameters(evt::GaisserHillas4Parameter &ghPars) const
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
std::string UnitName(const EOneTwo par) const
parameter unit name
Description of a camera.
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.