FdEnergyDepositFinder.cc
Go to the documentation of this file.
2 
3 #include "../FdProfileReconstructorKG/UncorrelatedUncertainties.h"
4 
5 #include <fwk/CentralConfig.h>
6 #include <fwk/LocalCoordinateSystem.h>
7 
8 #include <utl/ErrorLogger.h>
9 #include <utl/AugerUnits.h>
10 #include <utl/Reader.h>
11 #include <utl/Transformation.h>
12 
13 #include <evt/Event.h>
14 #include <evt/GaisserHillas4Parameter.h>
15 
16 #include <fevt/FEvent.h>
17 #include <fevt/Eye.h>
18 #include <fevt/EyeHeader.h>
19 #include <fevt/Telescope.h>
20 #include <fevt/TelescopeRecData.h>
21 #include <evt/ShowerFRecData.h>
22 #include <fevt/EyeRecData.h>
23 
24 #include <det/Detector.h>
25 #include <fdet/FDetector.h>
26 #include <fdet/Eye.h>
27 
28 #include <atm/Atmosphere.h>
29 
30 #include <boost/io/ios_state.hpp>
31 
32 #include <iostream>
33 #include <sstream>
34 #include <iomanip>
35 
36 using namespace evt;
37 using namespace fevt;
38 using namespace utl;
39 using namespace fwk;
40 using namespace std;
41 using namespace atm;
42 
43 
44 namespace FdEnergyDepositFinderKG {
45 
46  const string gHRule = " --------------------------------------------------------------";
47 
48 
51  {
52  auto& cc = *CentralConfig::GetInstance();
53 
54  auto topB = cc.GetTopBranch("FdEnergyDepositFinder");
55 
56  // invisible energy options
57  auto eCalcB = topB.GetChild("invisibleEnergy");
58  const string compositionOption = eCalcB.GetChild("composition").Get<string>();
59 
60  fComposition =
61  (compositionOption == "eData") ?
63  (compositionOption == "eMixed") ?
65  (compositionOption == "eProton") ?
67 
68  const auto interactionOption = eCalcB.GetChild("interactionModel").Get<string>();
69  if (interactionOption == "eSIBYLL21")
70  fInvisibleEnergyModel = InvisibleEnergy::eSIBYLL21;
71  else if (interactionOption == "eQGSJET01")
72  fInvisibleEnergyModel = InvisibleEnergy::eQGSJET01;
73  else if (interactionOption == "eDATA")
74  fInvisibleEnergyModel = InvisibleEnergy::eDATA;
75  else {
76  ostringstream err;
77  err << "Unknown hadronic interaction model used: " << interactionOption;
78  ERROR(err);
79  return eFailure;
80  }
81 
82  if ((fInvisibleEnergyModel == InvisibleEnergy::eDATA) != (fComposition == InvisibleEnergy::eData)) {
83  ERROR("inconsistent invisible energy options (data options cannot "
84  "be mixed with other options)");
85  return eFailure;
86  }
87 
88  fGHShapePars = GHShapeParameters(topB);
89 
90  auto errPropB = topB.GetChild("errorPropagation");
91  errPropB.GetChild("verbosity").GetData(fErrPropVerbosity);
92  errPropB.GetChild("rescaleErrors").GetData(fRescaleErrors);
93  errPropB.GetChild("maxErrPropPoints").GetData(fMaxErrPropPoints);
94 
95  auto evSelB = topB.GetChild("eventSelection");
96  evSelB.GetChild("requireNonMono").GetData(fOnlyNonMono);
97  evSelB.GetChild("maxZenith").GetData(fMaxZenith);
98  topB.GetChild("denseMatrixDim").GetData(fDenseMatrixDim);
99  topB.GetChild("antiAliasingFilterCorrection").GetData(fAafCorrection);
100  topB.GetChild("useNoiseBins").GetData(fUseNoiseBins);
101 
102  ostringstream info;
103  info << "Parameters:\n"
104  "\tinvisible energy model: "
105  << interactionOption << '/'
106  << compositionOption << "\n"
107  "\t" << (fOnlyNonMono ? "" : "not ") << "skipping mono events\n"
108  "\tskipping upward showers with theta > " << fMaxZenith/deg;
109  INFO(info);
110 
111  fCFMatrixCalculator.Init();
112  fCFMatrixCalculatorDense.Init();
113  fProfileFitter.Init();
114 
115  return eSuccess;
116  }
117 
118 
120  FdEnergyDepositFinder::Run(evt::Event& event)
121  {
122  if (!event.HasFEvent())
123  return eSuccess;
124 
125  auto& fdEvent = event.GetFEvent();
126 
127  for (auto eyeIt = fdEvent.EyesBegin(ComponentSelector::eHasData),
128  end = fdEvent.EyesEnd(ComponentSelector::eHasData);
129  eyeIt != end; ++eyeIt) {
130 
131  auto& eye = *eyeIt;
132 
133  if (IsEventCandidate(eye)) {
134 
135  ostringstream info;
136  info << " calculating profile for eye " << eye.GetId();
137  INFO(info);
138 
139  fRecResultsPlus.clear();
140  fRecResultsMinus.clear();
141 
142  for (unsigned int i = 0; i < eNErrorPropagation; ++i) {
143 
144  fErrPropStage = EErrorPropStage(i);
145  bool fullCalculation = false;
146 
147  for (unsigned int j = 0; j < 2; ++j) {
148 
149  EErrorPropType errPropType = (j == 0) ? eMinus : ePlus;
150  fullCalculation = false;
151 
152  // create a copy of fevt::Eye via Event
153  Event eventCopy;
154  if (fErrPropStage != eDefaultReco) {
155  const auto id = eye.GetId();
156  eventCopy.MakeFEvent();
157  eventCopy.GetFEvent().MakeEye(id);
158  eventCopy.GetFEvent().GetEye(id) = eye;
159  if (!PrepareEyeCopy(eventCopy.GetFEvent().GetEye(id), errPropType))
160  break;
161  fCFMatrixCalculator.SetMethod(CFMatrixCalculator::eFast);
162  fCFMatrixCalculator.SetVerbosity(-1);
163  fCFMatrixCalculatorDense.SetMethod(CFMatrixCalculator::eFast);
164  fCFMatrixCalculatorDense.SetVerbosity(-1);
165  fProfileFitter.SetAafCorrection(false, false);
166  fProfileFitter.SetVerbosity(-1);
167  } else {
168  fCFMatrixCalculator.SetMethod(CFMatrixCalculator::ePrecise);
169  fCFMatrixCalculator.SetVerbosity(0);
170  fCFMatrixCalculatorDense.SetMethod(CFMatrixCalculator::ePrecise);
171  fCFMatrixCalculatorDense.SetVerbosity(0);
172  fProfileFitter.SetAafCorrection(fAafCorrection, fUseNoiseBins);
173  fProfileFitter.SetVerbosity(0);
174  }
175 
176  auto& eyeEvt =
177  (fErrPropStage == eDefaultReco) ? eye : eventCopy.GetFEvent().GetEye(eye.GetId());
178 
179  auto& shower = eyeEvt.GetRecData().GetFRecShower();
180  shower.SetEnergyCutoff(fElectronEnergyThreshold);
181 
182  // first version of matrix
183  fCFMatrixCalculator.BuildMatrix(eyeEvt);
184  fCFMatrixCalculator.SetVerbosity(-1);
185  fCFMatrixCalculatorDense.BuildMatrix(
186  eyeEvt,
187  false,
188  (fErrPropStage == eDefaultReco &&
189  fCFMatrixCalculator.GetFOVSize() > 0 &&
190  fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() > 0) ?
191  fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() : 1
192  );
193  fCFMatrixCalculatorDense.SetVerbosity(-1);
194 
195  if (fCFMatrixCalculator.HasMatrix() && fCFMatrixCalculatorDense.HasMatrix()) {
196 
197  // first version of profile
198  if (!fProfileCalculator.CalculateProfile(eyeEvt, fCFMatrixCalculator))
199  break;
200 
201  if (FitProfile(eyeEvt, eGH2dEdXChi2) && // prefit
202  FitProfile(eyeEvt, eGH4dEdXChi2) && // 4-GH fit
203  FitProfile(eyeEvt, eGH4LightLogLike)) // final fit
204  fullCalculation = true;
205 
206  }
207 
208  if (fErrPropStage == eDefaultReco && !fullCalculation) {
209  // reset intermediate results of not successful
210  shower.SetTotalEnergy(0, 1e20*eV);
211  shower.SetEmEnergy(0, 1e20*eV);
212  if (shower.HasGHParameters()) {
213  shower.GetGHParameters().SetXMax(0, 1000*g/cm2);
214  shower.GetGHParameters().SetNMax(0, 0);
215  shower.SetXmaxError(1000*g/cm2, ShowerFRecData::eStatistical);
216  }
217  } else if (fErrPropStage != eDefaultReco) {
218  const GaisserHillas4Parameter& gh4Pars =
219  shower.GetGHParameters<GaisserHillas4Parameter>();
220  auto& recoResult =
221  (errPropType == ePlus) ? fRecResultsPlus : fRecResultsMinus;
222  recoResult[fErrPropStage] = gh4Pars;
223  }
224 
225  // reset mie uncertainty (may have changed in PrepareEyeCopy())
226  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
227  atmo.SetUncertaintyBound(Atmosphere::eMie, 0);
228 
229  if (!fullCalculation || fErrPropStage == eDefaultReco)
230  break;
231 
232  } // plus/minus loop
233 
234  if (!fullCalculation)
235  break;
236 
237  } // error prop loop
238 
239  cout << gHRule << endl;
240 
241  PropagateUncertainties(eye);
242 
243  }
244  }
245 
246  return eSuccess;
247  }
248 
249 
250  bool
251  FdEnergyDepositFinder::FitProfile(fevt::Eye& eye,
252  const EFitFunctionType type)
253  {
254  auto& shower = eye.GetRecData().GetFRecShower();
255  shower.SetEnergyCutoff(fElectronEnergyThreshold);
256  fProfileFitter.ResetStartParameters();
257 
258  if (!shower.HasGHParameters()) {
259  shower.MakeGHParameters(GaisserHillas4Parameter(fGHShapePars.Type()));
260  if (!GuessGHParameters(shower))
261  return false;
262  DumpCurrentParameters(shower, false, eUndefined);
263  }
264 
265  fProfileFitter.SetFitMode(ProfileFitter::eNMax);
266  {
267  GaisserHillas4Parameter& gh4Pars =
268  shower.GetGHParameters<GaisserHillas4Parameter>();
269  fProfileFitter.SetStartParameters(gh4Pars);
270  }
271  fProfileFitter.SetLightFluxData(fCFMatrixCalculator, fCFMatrixCalculatorDense);
272 
273  fProfileFitter.SetProfileData(shower.GetEnergyDeposit());
274  fProfileFitter.SetFunctionType(type);
275 
276  if (fProfileFitter.Fit()) {
277 
278  GaisserHillas4Parameter& gh4Pars = shower.GetGHParameters<GaisserHillas4Parameter>();
279  fProfileFitter.FillGHParameters(gh4Pars);
280 
281  double calorEnergy = gh4Pars.GetIntegral();
282  double calorEnergyErr = calorEnergy * gh4Pars.GetIntegralError();
283 
284  // refit at final step using energy as parameter instead of Xmax
285  if (type == eFinalFitStep) {
286  fProfileFitter.SetFitMode(ProfileFitter::eIntegral);
287  fProfileFitter.SetStartParameters(gh4Pars);
288  if (fProfileFitter.Fit())
289  fProfileFitter.GetEnergy(calorEnergy, calorEnergyErr);
290  else
291  return false;
292  }
293  shower.SetEmEnergy(calorEnergy, calorEnergyErr, ShowerFRecData::eStatistical);
294  shower.SetEmEnergyError(0, ShowerFRecData::eAtmospheric);
295 
296  // rebuilt matrix if Xmax changed too much and not in final round
297  const double currXmax = gh4Pars.GetXMax();
298  const double maxDeltaXmax = 10*g/cm2;
299  const bool updateCFM =
300  (fabs(currXmax-fCFMatrixCalculatorDense.GetXmax()) > maxDeltaXmax &&
301  type != eFinalFitStep);
302 
303  if (updateCFM) {
304  fCFMatrixCalculator.BuildMatrix(eye);
305  fCFMatrixCalculatorDense.BuildMatrix(
306  eye,
307  false,
308  (fErrPropStage == eDefaultReco &&
309  fCFMatrixCalculator.GetFOVSize() > 0 &&
310  fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() > 0) ?
311  fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() : 1
312  );
313  }
314 
315  if (fCFMatrixCalculator.HasMatrix() && fCFMatrixCalculatorDense.HasMatrix()) {
316 
317  if (!fProfileCalculator.CalculateProfile(eye, fCFMatrixCalculator))
318  return false;
319  DumpCurrentParameters(shower, updateCFM, type);
320 
321  return true;
322  }
323 
324  }
325 
326  return false;
327  }
328 
329 
330  void
331  FdEnergyDepositFinder::PropagateUncertainties(fevt::Eye& eye)
332  const
333  {
334  auto& eyeRecData = eye.GetRecData();
335  auto& recShower = eyeRecData.GetFRecShower();
336 
337  if (!recShower.HasGHParameters())
338  return;
339 
340  GaisserHillas4Parameter& gh4 = recShower.GetGHParameters<GaisserHillas4Parameter>();
341 
342  const double dEdXmax = gh4.GetNMax();
343  const double xmax = gh4.GetXMax();
344  const double shapePar1 = gh4.GetShapeParameter(fGHShapePars.Type(eOne));
345  const double shapePar2 = gh4.GetShapeParameter(fGHShapePars.Type(eTwo));
346  const double calorEnergy = recShower.GetEmEnergy();
347 
348  // added by Matias Tueros
349  const auto& axis = recShower.GetAxis();
350  const auto& core = recShower.GetCorePosition();
351  const auto coreCS = fwk::LocalCoordinateSystem::Create(core);
352 
353  const double cosZenithAngle = axis.GetCosTheta(coreCS);
354  // end addition
355 
356  const double invEnergyFac =
357  utl::InvisibleEnergy::Factor(calorEnergy,
358  fInvisibleEnergyModel,
359  fComposition, cosZenithAngle);
360  const double totalEnergy = invEnergyFac * calorEnergy;
361 
362  // if one or more propagation steps failed, set all errors to 100%
363  if (fRecResultsPlus.size() != eNErrorPropagation - 1 ||
364  fRecResultsMinus.size() != eNErrorPropagation - 1) {
365 
366  if (fErrPropVerbosity > -1) {
367  int failStage = 0;
368  for (int j = eFirstErrProp; j < eNErrorPropagation; ++j) {
369  const EErrorPropStage tmp = EErrorPropStage(j);
370  if (fRecResultsPlus.find(tmp) == fRecResultsPlus.end() ||
371  fRecResultsMinus.find(tmp) == fRecResultsMinus.end()) {
372  failStage = j;
373  break;
374  }
375  }
376  cout << " ==[ErrProp]==> numerical error propagation failed at stage "
377  << failStage<< "\n"
378  " setting uncertainties to 100%!" << endl;
379  }
380 
381  gh4.SetXMax(xmax , xmax);
382  gh4.SetNMax(dEdXmax, dEdXmax, true);
383  gh4.SetShapeParameter(fGHShapePars.Type(eOne), shapePar1, fabs(shapePar1));
384  gh4.SetShapeParameter(fGHShapePars.Type(eTwo), shapePar2, fabs(shapePar2));
385 
386  recShower.SetXmaxError(xmax, ShowerFRecData::eStatistical);
387 
388  recShower.SetEmEnergyError(calorEnergy, ShowerFRecData::eStatistical);
389  recShower.SetEmEnergyError(0, ShowerFRecData::eAtmospheric);
390  recShower.SetTotalEnergy(totalEnergy, totalEnergy, ShowerFRecData::eStatistical);
391  recShower.SetTotalEnergyError(0, ShowerFRecData::eAtmospheric);
392  return;
393  }
394 
395  // --- propagate uncertainties for all shower parameters
396  enum EShowerParameter {
397  eShapePar1 = 0,
398  eXmax,
399  edEdXmax,
400  eShapePar2,
401  eCalorEnergy,
402  eLastFitParameter = eCalorEnergy
403  };
404 
405  double geomVariance[eLastFitParameter+1];
406  double atmVariance[eLastFitParameter+1];
407 
408  for (int i = 0; i <= eLastFitParameter; ++i) {
409 
410  EShowerParameter currentParameter = EShowerParameter(i);
411 
412  double uncertainty[eNErrorPropagation];
413  for (int j = eFirstErrProp; j < eNErrorPropagation; ++j) {
414  const evt::GaisserHillas4Parameter& ghPlus =
415  fRecResultsPlus.find(EErrorPropStage(j))->second;
416  const evt::GaisserHillas4Parameter& ghMinus =
417  fRecResultsMinus.find(EErrorPropStage(j))->second;
418  switch (currentParameter) {
419  case eShapePar1:
420  uncertainty[j] = 0.5*(ghPlus.GetShapeParameter(fGHShapePars.Type(eOne)) -
421  ghMinus.GetShapeParameter(fGHShapePars.Type(eOne)));
422  break;
423  case eXmax:
424  uncertainty[j] = 0.5*(ghPlus.GetXMax()-ghMinus.GetXMax());
425  break;
426  case edEdXmax:
427  uncertainty[j] = 0.5*(ghPlus.GetNMax()-ghMinus.GetNMax());
428  break;
429  case eShapePar2:
430  uncertainty[j] = 0.5*(ghPlus.GetShapeParameter(fGHShapePars.Type(eTwo)) -
431  ghMinus.GetShapeParameter(fGHShapePars.Type(eTwo)));
432  break;
433  case eCalorEnergy:
434  uncertainty[j] = 0.5*(ghPlus.GetIntegral()-ghMinus.GetIntegral());
435  break;
436  }
437  }
438 
439  const double rhoRT = eyeRecData.GetRpTZeroCorrelation();
440  const double rhoRC = eyeRecData.GetRpChi0Correlation();
441  const double rhoCT = eyeRecData.GetChi0TZeroCorrelation();
442 
443  const double timeFitVariance =
444  Sqr(uncertainty[eRp]) +
445  Sqr(uncertainty[eT0]) +
446  Sqr(uncertainty[eChi0]) +
447  2 * uncertainty[eRp] * uncertainty[eT0] * rhoRT +
448  2 * uncertainty[eRp] * uncertainty[eChi0] * rhoRC +
449  2 * uncertainty[eChi0] * uncertainty[eT0] * rhoCT;
450 
451  const double rhoPT = eyeRecData.GetSDPCorrThetaPhi();
452 
453  const double sdpFitVariance =
454  Sqr(uncertainty[eSDPTheta]) +
455  Sqr(uncertainty[eSDPPhi]) +
456  2 * uncertainty[eSDPPhi] * uncertainty[eSDPTheta] * rhoPT;
457 
458  geomVariance[i] = timeFitVariance + sdpFitVariance;
459  atmVariance[i] = Sqr(uncertainty[eMie]);
460 
461  }
462 
463  // ICRC 2013, Energy scale Table: 2, Uncorrelated uncertainties
464  // that go into the FD energy.
465  //const double atmVar1 = pow(gHorizontalUniformityError * calorEnergy, 2);
466  //const double atmVar2 = pow(gAtmVariability * calorEnergy, 2);
467  //const double atmVar3 = pow(gNightlyRelativeCalibration * calorEnergy, 2);
468 
469  // ICRC 2019 Uncorrelated uncertainties
470  // that go into the FD energy.
471  const double dEr = gHorizontalUniformityError_par[0];
472  const double logE = log10(calorEnergy);
473  const double logEs = gHorizontalUniformityError_par[1];
474  const double fp0 = gHorizontalUniformityError_par[2];
475  const double fp1 = gHorizontalUniformityError_par[3];
476  const double fp2 = gHorizontalUniformityError_par[4];
477  const double le = logE - 18;
478  const double fE = max(fp0 + le*(fp1 + fp2*le), 0.);
479  const double les = logEs - 18;
480  const double fEs = fp0 + les*(fp1 + fp2*les);
481  const double atmVar1 = Sqr(dEr*fE/fEs * calorEnergy);
482 
483  const double atmVar2 = Sqr(gAtmVariability * calorEnergy);
484  const double atmVar3 = Sqr(gNightlyRelativeCalibration * calorEnergy);
485  const double atmVar4 = Sqr(gEnergyTimeDrif * calorEnergy);
486  const double atmVar5 = Sqr(gEnergyEyeTel * calorEnergy);
487 
488  // optionally rescale stat. uncert. of GH fit using chi2
489  const double scaleFac = fRescaleErrors ?
490  sqrt(recShower.GetGHParameters().GetChiSquare() /
491  recShower.GetGHParameters().GetNdof()) :
492  1;
493  const double calorEnergyStatVar =
494  Sqr(recShower.GetEmEnergyError(ShowerFRecData::eStatistical)*scaleFac);
495  const double calorEnergyGeomVar = geomVariance[eCalorEnergy];
496 
497  // ICRC 2019
498  const double calorEnergyConexMissingVar = Sqr(gEnergyResolutionConexMissingFactor * calorEnergy);
499 
500  // ICRC 2013
501  //const double calorEnergyAtmVar =
502  //atmVariance[eCalorEnergy] + atmVar1 + atmVar2 + atmVar3;
503  // ICRC 2019
504  const double calorEnergyAtmVar =
505  atmVariance[eCalorEnergy] + atmVar1 + atmVar2 + atmVar3 + atmVar4 + atmVar5;
506 
507  // ICRC 2013
508  //recShower.SetEmEnergy(calorEnergy,sqrt(calorEnergyGeomVar+calorEnergyStatVar),
509  // ShowerFRecData::eStatistical);
510  // ICRC 2019
511  recShower.SetEmEnergy(
512  calorEnergy,
513  sqrt(calorEnergyGeomVar + calorEnergyStatVar + calorEnergyConexMissingVar),
515  );
516 
517  recShower.SetEmEnergyError(sqrt(calorEnergyAtmVar), ShowerFRecData::eAtmospheric);
518 
519  // total energy uncertainty including shower-to-shower fluctuations of invisible energy
520  const double invEnergyFacDeriv =
522  fInvisibleEnergyModel,
523  fComposition, cosZenithAngle);
524  // ICRC 2013
525  //const double invEVar = utl::InvisibleEnergy::FactorVariance(totalEnergy);
526  // ICRC 2019
527  const double invEVar = utl::InvisibleEnergy::FactorVariance(calorEnergy, totalEnergy);
528 
529  const double deriv = invEnergyFacDeriv * calorEnergy + invEnergyFac;
530  // invEnergyFac = (Ecal+Einv)/Ecal = 1 + Einv/Ecal
531  // invEnergyFacDeriv = d(Einv/Ecal)/d(Ecal) = d(Einv)/d(Ecal) / Ecal - Einv/Ecal/Ecal
532  // deriv = ( d(Einv)/d(Ecal) / Ecal - Einv/Ecal/Ecal ) * Ecal + 1 + Einv/Ecal = d(Einv)/d(Ecal) + 1
533  // Etot = Ecal + Einv
534  // dEtot/dEcal = 1 + d(Einv)/d(Ecal)
535  // dEtot = ( 1 + d(Einv)/d(Ecal) ) * dEcal
536  // deriv = 1 + d(Einv)/d(Ecal)
537  const double deriv2 = Sqr(deriv);
538  const double statVar = deriv2 * calorEnergyStatVar;
539  const double geomVar = deriv2 * calorEnergyGeomVar;
540  // ICRC 2019
541  const double ConexMissingVar = deriv2 * calorEnergyConexMissingVar;
542 
543  const double totalEnergyAtmErr = sqrt(deriv2 * calorEnergyAtmVar);
544 
545  // ICRC 2013
546  //const double totalEnergyStatErr = sqrt(invEVar + geomVar+statVar);
547  // ICRC 2019
548  const double totalEnergyStatErr = sqrt(invEVar + geomVar + statVar + ConexMissingVar);
549 
550  recShower.SetTotalEnergy(totalEnergy, totalEnergyStatErr, ShowerFRecData::eStatistical);
551  recShower.SetTotalEnergyError(totalEnergyAtmErr, ShowerFRecData::eAtmospheric);
552 
553  // finally set total GH uncertainties, note: atm. uncert. not included here
554  const double nmaxErr = scaleFac * gh4.GetNMaxError();
555  const double xmaxErr = scaleFac * gh4.GetXMaxError();
556  const double shapePar1Err = scaleFac * gh4.GetShapeParameterError(fGHShapePars.Type(eOne));
557  const double shapePar2Err = scaleFac * gh4.GetShapeParameterError(fGHShapePars.Type(eTwo));
558  const double shapePar1TotErr = sqrt(Sqr(shapePar1Err) + geomVariance[eShapePar1]);
559  const double xmaxTotErr = sqrt(Sqr(xmaxErr) + geomVariance[eXmax]);
560  const double nmaxTotErr = sqrt(Sqr(nmaxErr) + geomVariance[edEdXmax]);
561  const double shapePar2TotErr = sqrt(Sqr(shapePar2Err) + geomVariance[eShapePar2]);
562 
563  gh4.SetShapeParameter(fGHShapePars.Type(eOne), shapePar1, shapePar1TotErr);
564  gh4.SetShapeParameter(fGHShapePars.Type(eTwo), shapePar2, shapePar2TotErr);
565  gh4.SetXMax(xmax, xmaxTotErr);
566  gh4.SetNMax(dEdXmax, nmaxTotErr, true);
567 
568  recShower.SetXmaxError(sqrt(atmVariance[eXmax]), ShowerFRecData::eAtmospheric);
569  recShower.SetXmaxError(xmaxTotErr, ShowerFRecData::eStatistical);
570 
571  // do some printout ...
572  if (fErrPropVerbosity >- 1) {
573  boost::io::ios_all_saver save(cout);
574  cout.flags(std::ios::scientific);
575  cout << "\n E/EeV = " << totalEnergy/EeV;
576  cout.precision(1);
577  cout << " +/- " << sqrt(statVar)/EeV << " (stat.)"
578  " +/- " << sqrt(geomVar)/EeV << " (geom.)"
579  " +/- " << sqrt(invEVar)/EeV << " (inv.)"
580  " +/- " << totalEnergyAtmErr/EeV << " (atm.)\n"
581  " Xmax/(g/cm^2) = ";
582  cout.precision(2);
583  cout << xmax/(g/cm2);
584  cout.precision(1);
585  cout << " +/- " << xmaxErr/(g/cm2) << " (stat.)"
586  " +/- " << sqrt(geomVariance[eXmax])/(g/cm2) << " (geom.)"
587  " +/- " << sqrt(atmVariance[eXmax])/(g/cm2) << " (atm.)"
588  << endl;
589  }
590  }
591 
592 
593  bool
594  FdEnergyDepositFinder::PrepareEyeCopy(fevt::Eye& eye,
595  EErrorPropType errPropType)
596  const
597  {
598  auto& eyeRecData = eye.GetRecData();
599  for (auto telIt = eye.TelescopesBegin(fevt::ComponentSelector::eInDAQ),
601  telIt != end; ++telIt) {
602 
603  if (!telIt->HasRecData())
604  continue;
605 
606  auto& telRecData = telIt->GetRecData();
607  if (!telRecData.HasLightFlux(fevt::FdConstants::eTotal) ||
608  !telRecData.HasLightFlux(fevt::FdConstants::eBackground))
609  continue;
610 
611  auto& photonTrace = telRecData.GetLightFlux(fevt::FdConstants::eTotal);
612  auto& bgTrace = telRecData.GetLightFlux(fevt::FdConstants::eBackground);
613 
614  // combine data points to speed up re-fits
615  vector<double> x;
616  vector<double> y;
617  vector<double> ex;
618  vector<double> ey;
619  vector<double> vBkg;
620  unsigned int nInRange = 0;
621  for (unsigned int i = 0; i < photonTrace.GetNPoints(); ++i) {
622  x.push_back(photonTrace.GetX(i));
623  y.push_back(photonTrace.GetY(i));
624  ex.push_back(photonTrace.GetXErr(i));
625  ey.push_back(photonTrace.GetYErr(i));
626  vBkg.push_back(Sqr(bgTrace.GetYErr(i)));
627  if (telRecData.IsSpotFarFromBorder(photonTrace.GetX(i)))
628  ++nInRange;
629  }
630 
631  if (int(nInRange) > fMaxErrPropPoints) {
632 
633  photonTrace.Clear();
634  bgTrace.Clear();
635 
636  const double nCombi = max(1, int(double(nInRange) / fMaxErrPropPoints + 0.5));
637 
638  int combined = 0;
639  double t1 = x[0] - ex[0];
640  double sum = 0;
641  double sum2 = 0;
642  double bgVarianceSum = 0;
643 
644  for (unsigned int i = 0; i < x.size(); ++i) {
645  ++combined;
646  sum += y[i];
647  sum2 += Sqr(ey[i]);
648  bgVarianceSum += vBkg[i];
649 
650  if (t1 == 0)
651  t1 = x[i] - ex[i];
652 
653  if (combined >= nCombi || i == x.size()-1) {
654  const double dt = x[i] + ex[i] - t1;
655  photonTrace.PushBack(t1 + 0.5*dt, 0.5*dt, sum, sqrt(sum2));
656  bgTrace.PushBack(t1 + 0.5*dt, 0.5*dt, 0, sqrt(bgVarianceSum));
657  sum = 0;
658  sum2 = 0;
659  t1 = 0;
660  combined = 0;
661  bgVarianceSum = 0;
662  }
663  }
664  }
665 
666  }
667 
668  // clear energy deposit
669  auto& recShower = eye.GetRecData().GetFRecShower();
670  auto& dedxProf=recShower.GetEnergyDeposit();
671  dedxProf.Clear();
672 
673  // change geometry
674  if (fErrPropStage >= eFirstGeometryProp &&
675  fErrPropStage <= eLastGeometryProp) {
676 
677  const auto& detEye = det::Detector::GetInstance().GetFDetector().GetEye(eye);
678  const auto eyeCS = detEye.GetEyeCoordinateSystem();
679  const auto& eyepos = detEye.GetPosition();
680 
681  const double timeFitFactor = fRescaleErrors ?
682  (eyeRecData.GetTimeFitNDof() ?
683  sqrt(eyeRecData.GetTimeFitChiSquare()/eyeRecData.GetTimeFitNDof()) : 1) :
684  1;
685  const double sdpFitFactor = fRescaleErrors ?
686  (eyeRecData.GetSDPFitNDof() ?
687  sqrt(eyeRecData.GetSDPFitChiSquare()/eyeRecData.GetSDPFitNDof()) : 1) :
688  1;
689 
690  double t0 = eyeRecData.GetTZero();
691  double chi0 = eyeRecData.GetChiZero();
692  double rp = eyeRecData.GetRp();
693  double sdpTheta = eyeRecData.GetSDP().GetTheta(eyeCS);
694  double sdpPhi = eyeRecData.GetSDP().GetPhi(eyeCS);
695  if (fErrPropStage == eRp)
696  rp += eyeRecData.GetRpError()*errPropType*timeFitFactor;
697  else if (fErrPropStage == eChi0)
698  chi0 += eyeRecData.GetChiZeroError()*errPropType*timeFitFactor;
699  else if (fErrPropStage == eT0)
700  t0 += eyeRecData.GetTZeroError()*errPropType*timeFitFactor;
701  else if (fErrPropStage == eSDPTheta)
702  sdpTheta += eyeRecData.GetSDPThetaError()*errPropType*sdpFitFactor;
703  else if (fErrPropStage == eSDPPhi)
704  sdpPhi += eyeRecData.GetSDPPhiError()*errPropType*sdpFitFactor;
705 
706  const Vector sdp(1, sdpTheta, sdpPhi, eyeCS, Vector::kSpherical);
707  const Vector vertical(0,0,1, eyeCS);
708  const auto horizontalInSDP = Normalized(Cross(sdp, vertical)); // horizontal
709 
710  const auto rot = Transformation::Rotation(-chi0, sdp, eyeCS);
711  const auto axis = Normalized(rot*horizontalInSDP);
712  const double coreDistance = rp / sin(chi0);
713  const auto coreEyeVec = coreDistance * horizontalInSDP;
714  const auto core = eyepos + coreEyeVec;
715  recShower.SetAxis(axis);
716  recShower.SetCorePosition(core);
717  try {
718  recShower.SetCoreTime(eye.GetHeader().GetTimeStamp() -
719  TimeInterval(1000*100*ns),
720  rp, chi0, t0);
721  } catch (OutOfBoundException& e) {
722  ERROR(e.GetMessage());
723  return false;
724  }
725  } else if (fErrPropStage == eMie) {
726  const Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
727  atmo.SetUncertaintyBound(Atmosphere::eMie,errPropType);
728  }
729 
730  return true;
731  }
732 
733 
734  bool
735  FdEnergyDepositFinder::GuessGHParameters(ShowerFRecData& shower)
736  const
737  {
738  if (!shower.HasGHParameters())
740 
742 
743  // running average
744 
745  const auto& energyDeposit = shower.GetEnergyDeposit();
746  const unsigned int nPoints = energyDeposit.GetNPoints();
747  const double depthBin = 50*g/cm2;
748 
749  bool firstTime = true;
750  double xMax = 0;
751  double dEdXmax = 0;
752  for (unsigned int i = 0; i < nPoints; ++i) {
753  const double firstDepth = energyDeposit.GetX(i);
754  unsigned int nAverage = 0;
755  double wSum = 0;
756  double ywSum = 0;
757  double xSum = 0;
758  for (unsigned int j = i; j < nPoints; ++j) {
759  const double thisDepth = energyDeposit.GetX(j);
760  ++nAverage;
761  xSum += thisDepth;
762  const double w = 1 / Sqr(energyDeposit.GetYErr(j));
763  wSum += w;
764  ywSum += energyDeposit.GetY(j)*w;
765 
766  if (thisDepth - firstDepth > depthBin) {
767  const double yAverage = ywSum / wSum;
768  if (firstTime || yAverage > dEdXmax) {
769  dEdXmax = yAverage;
770  xMax = xSum / nAverage;
771  firstTime = false;
772  }
773  break;
774  }
775  }
776  }
777 
778  gh4Pars.SetShapeParameter(
779  fGHShapePars.Type(eOne),
780  fGHShapePars.Mean(eOne, 1e18*eV),
781  fGHShapePars.Sigma(eOne, 1e18*eV)
782  );
783  gh4Pars.SetShapeParameter(
784  fGHShapePars.Type(eTwo),
785  fGHShapePars.Mean(eTwo, 1e18*eV),
786  fGHShapePars.Sigma(eTwo, 1e18*eV)
787  );
788  if (firstTime) {
789  WARNING("can not estimate start parameters");
790  gh4Pars.SetXMax(700*g/cm2, 0);
791  gh4Pars.SetNMax(energyDeposit.GetY(0), 0, true);
792  return false;
793  } else {
794  gh4Pars.SetXMax(xMax, 0);
795  gh4Pars.SetNMax(dEdXmax, 0, true);
796  }
797  return true;
798  }
799 
800 
801  void
802  FdEnergyDepositFinder::DumpCurrentParameters(const ShowerFRecData& shower,
803  const bool cfmUpdate,
804  const EFitFunctionType funcType)
805  const
806  {
807  if (fErrPropVerbosity < 1 && fErrPropStage != eDefaultReco)
808  return;
809  else if (fErrPropStage > 0 && funcType == eGH2dEdXChi2)
810  cout << " ==[ErrProp]==> stage " << fErrPropStage << endl;
811 
812  switch (funcType) {
813  case eUndefined:
814  cout << " "
815  << setw(9) << "Xmax"
816  << setw(13) << "dEdXmax"
817  << setw(12) << fGHShapePars.Name(eOne)
818  << setw(12) << fGHShapePars.Name(eTwo)
819  << " chi2/ndf\n"
820  " "
821  << setw(9) << "[g/cm^2]"
822  << setw(13) << "[PeV cm^2/g]"
823  << setw(12-2-fGHShapePars.UnitName(eOne).length()) << " " << "[" << fGHShapePars.UnitName(eOne) << "]"
824  << setw(12-2-fGHShapePars.UnitName(eTwo).length()) << " " << "[" << fGHShapePars.UnitName(eTwo) << "]\n"
825  << gHRule << "\n"
826  " ==> init :";
827  break;
828  case eGH2dEdXChi2:
829  cout << " ==> prefit1:";
830  break;
831  case eGH4dEdXChi2:
832  cout << " ==> prefit2:";
833  break;
834  case eGH4LightLogLike:
835  cout << " ==> logLike:";
836  break;
837  default:
838  return;
839  }
840 
841  if (!shower.HasGHParameters()) {
842  cout << " --- " << endl;
843  return;
844  }
845 
846  const GaisserHillas4Parameter& gh4Pars =
848 
849  boost::io::ios_all_saver save(cout);
850  cout.flags(std::ios::scientific);
851  cout.precision(2);
852 
853  cout << setw(9) << fixed << gh4Pars.GetXMax()/g*cm2
854  << setw(13) << scientific << gh4Pars.GetNMax()/(PeV/(g/cm2))
855  << setw(12)
856  << gh4Pars.GetShapeParameter(fGHShapePars.Type(eOne))/fGHShapePars.Unit(eOne)
857  << setw(12)
858  << gh4Pars.GetShapeParameter(fGHShapePars.Type(eTwo))/fGHShapePars.Unit(eTwo)
859  << setw(5) << int(gh4Pars.GetChiSquare()) << "/"
860  << std::left << gh4Pars.GetNdof() << std::right
861  << (cfmUpdate ? " *" : "") << endl;
862  }
863 
864 
865  bool
866  FdEnergyDepositFinder::IsEventCandidate(const fevt::Eye& eye)
867  const
868  {
869  ostringstream info;
870 
871  if (!eye.HasRecData()) {
872  info << " skipping eye " << eye.GetId() << " without RecData";
873  INFO(info);
874  return false;
875  }
876 
877  if (!eye.GetRecData().HasFRecShower()) {
878  info << " skipping eye " << eye.GetId() << " without FRecShower";
879  INFO(info);
880  return false;
881  }
882 
883  if (eye.GetRecData().GetTimeFitNDof() <= 0) {
884  info << " skipping eye " << eye.GetId() << " with time-fit Ndf="
885  << eye.GetRecData().GetTimeFitNDof();
886  INFO(info);
887  return false;
888  }
889 
890  const auto& shower = eye.GetRecData().GetFRecShower();
891  if (fOnlyNonMono) {
892  const bool isMCgeo =
894  eye.GetRecData().GetRpError()/eye.GetRecData().GetRp() < 1e-4;
895  if (shower.GetStationIds().empty() && // not hybrid
896  eye.GetRecData().GetPCGF().empty() && // not PCGF
897  !isMCgeo) { // not MC axis
898  info << " skipping eye " << eye.GetId()
899  << " with mono geometry";
900  INFO(info);
901  return false;
902  }
903  }
904 
905  if (fMaxZenith < 180*degree) {
906  const auto& core = shower.GetCorePosition();
907  const auto& axis = shower.GetAxis();
908  const auto coreLocalCS = fwk::LocalCoordinateSystem::Create(core);
909  if (axis.GetTheta(coreLocalCS) > fMaxZenith) {
910  info << " skipping upward event in eye " << eye.GetId()
911  << " theta=" << axis.GetTheta(coreLocalCS)/degree << " deg.";
912  INFO(info);
913  return false;
914  }
915  }
916 
917  return true;
918  }
919 
920 }
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
double GetShapeParameter(const gh::EShapeParameter par) const
access to all variants of shape parameters (see GaisserHillasTypes.h)
unsigned int GetId() const
Definition: FEvent/Eye.h:54
const double eV
Definition: GalacticUnits.h:35
double Factor(const double energyEM, const EInteractionModel intMod, const ECompositionModel compMod, const double cosTheta)
invisible energy factor, finv=Etot/Eem, given Eem. CosTheta only needed when using data driven estima...
Top of the interface to Atmosphere information.
const double degree
constexpr T Sqr(const T &x)
double GetRpError() const
Definition: EyeRecData.h:91
const double PeV
double GetIntegralError() const
return relative error of integral
fevt::EyeHeader & GetHeader()
Header for this Eye Event.
Definition: FEvent/Eye.cc:180
bool HasRecData() const
Definition: FEvent/Eye.h:116
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
bool HasFEvent() const
double FactorDerivative(const double energyEM, const EInteractionModel intMod, const ECompositionModel compMod, const double cosTheta)
derivative of invisible energy factor dfinv/dEem given Eem. CosTheta only needed when using data driv...
static double gEnergyResolutionConexMissingFactor
unsigned int GetTimeFitNDof() const
Definition: EyeRecData.h:93
void SetXMax(const double xMax, const double error)
#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 SetShapeParameter(const gh::EShapeParameter par, const double value, const double error)
Setters.
void Init()
Initialise the registry.
static double gEnergyEyeTel
const double EeV
Definition: GalacticUnits.h:34
Exception for reporting variable out of valid range.
constexpr double deg
Definition: AugerUnits.h:140
#define max(a, b)
const std::vector< PCGFData > & GetPCGF() const
Definition: EyeRecData.h:335
const double ns
TelescopeIterator TelescopesEnd()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:230
bool HasFRecShower() const
Check if reconstructed shower info has been allocated.
Definition: EyeRecData.h:330
evt::ShowerFRecData & GetFRecShower()
Reconstructed shower info for this eye.
Definition: EyeRecData.h:323
constexpr double g
Definition: AugerUnits.h:200
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
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
static double gAtmVariability
TelescopeIterator TelescopesBegin()
first available tel of status eHasData (DEPRECATED)
Definition: FEvent/Eye.cc:207
void SetNMax(const double nMax, const double error, const bool isEnergyDeposit=false)
double GetTimeFitChiSquare() const
Definition: EyeRecData.h:92
fevt::FEvent & GetFEvent()
bool HasGHParameters() const
A TimeInterval is used to represent time elapsed between two events.
Definition: TimeInterval.h:43
ResultFlag
Flag returned by module methods to the RunController.
Definition: VModule.h:60
void SetEnergyCutoff(const double energy)
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
Vector object.
Definition: Vector.h:30
Interface class to access to Fluorescence reconstruction of a Shower.
static double gEnergyTimeDrif
static double gHorizontalUniformityError_par[5]
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
double GetShapeParameterError(const gh::EShapeParameter par) const
double GetIntegral() const
calculate integral
Gaisser Hillas with 4 parameters.
static Policy::type Create(const utl::Point &theOrigin)
Create the standard local coordinate system for a Point.
void MakeGHParameters(const VGaisserHillasParameter &gh)
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
double FactorVariance(const double eCal, const double eTot)
void SetUncertaintyBound(const ModelWithUncertainty model, const double nSigma) const
alter Model &quot;model&quot; by &quot;nSigma&quot; standard deviations
const std::string & GetMessage() const
Retrieve the message from the exception.
utl::TabulatedFunctionErrors & GetEnergyDeposit()
retrieve dE/dX
constexpr double cm2
Definition: AugerUnits.h:118
fevt::EyeRecData & GetRecData()
Reconstructed data for this eye.
Definition: FEvent/Eye.cc:130
static double gNightlyRelativeCalibration

, generated on Tue Sep 26 2023.