G/ProfileChi2.cc
Go to the documentation of this file.
1 #include "ProfileChi2.h"
2 
3 #include <fevt/EyeRecData.h>
4 
5 #include <evt/GaisserHillas4Parameter.h>
6 
7 #include "../FdEnergyDepositFinderKG/ProfileFitFunctions.h"
8 #include "../FdEnergyDepositFinderKG/GHShapeParameters.h"
9 #include "../FdEnergyDepositFinderKG/LateralLightCalculator.h"
10 
11 
12 #include <utl/ErrorLogger.h>
13 #include <limits>
14 
15 #include <fwk/CentralConfig.h>
16 #include <det/Detector.h>
17 
18 using namespace fevt;
19 using namespace utl;
20 using namespace std;
21 
22 namespace FdProfileConstrainedGeometryFitPG {
23 
25  Branch topBranch = fwk::CentralConfig::GetInstance()->GetTopBranch("FdProfileConstrainedGeometryFitPG");
26  topBranch.GetChild("leavingAtmoIsError").GetData(fLeavingAtmoIsError);
27  topBranch.GetChild("antiAliasingFilterCorrection").GetData(fAafCorrection); //VN: fitter is static
28  topBranch.GetChild("useNoiseBins").GetData(fUseNoiseBins);
29  topBranch.GetChild("denseMatrixDim").GetData(fDenseMatrixDim);
30  ostringstream info;
31  info<<"\n\t leavingAtmoIsError is " << (fLeavingAtmoIsError?"on":"off");
32  info<<"\n\t antiAliasingFilterCorrection is " << (fAafCorrection?"on":"off");
33  info<<"\n\t useNoiseBins is " << (fUseNoiseBins?"on":"off");
34  info<<"\n\t denseMatrixDim set to " << (fDenseMatrixDim);
35  INFO(info);
36  topBranch.GetChild("onlyDirectLight").GetData(fOnlyDirectLight);
37 
38  const Branch profileBranch = topBranch.GetChild("profile");
39  //VN to manage static fitter
40  //FdEnergyDepositFinderKG::GHShapeParameters ghPars(profileBranch);
41 
42  //fProfileFitter.SetShapePars(ghPars);
43  ghPars = FdEnergyDepositFinderKG::GHShapeParameters(profileBranch);
44 
45  Branch kUnivBranch = profileBranch.GetChild("kUnivConstrained");
46 
47  if (kUnivBranch.GetChild("constrained").Get<bool>()) {
48  fIsUnivConstrained = true;
49  kUnivBranch.GetChild("function").GetData(fUnivFunction);
50  kUnivBranch.GetChild("ksigma").GetData(fksigma);
51  }
52 }
53 
54 double
55 ProfileChi2::operator()(Eye &eyeCopy, bool precise)
56 {
57  fCFMatrixCalculator.SetLDFMethod(FdEnergyDepositFinderKG::LateralLightCalculator::ECalculationMethod::eCircle);
58  fCFMatrixCalculatorDense.SetLDFMethod(FdEnergyDepositFinderKG::LateralLightCalculator::ECalculationMethod::eCircle);
60  fCFMatrixCalculator.SetOnlyDirect(fOnlyDirectLight);
61  fCFMatrixCalculator.SetVerbosity(-1);
62  fCFMatrixCalculatorDense.SetMethod(precise ? FdEnergyDepositFinderKG::CFMatrixCalculator::ePrecise : FdEnergyDepositFinderKG::CFMatrixCalculator::eFast);
63  fCFMatrixCalculatorDense.SetOnlyDirect(fOnlyDirectLight);
64  fCFMatrixCalculatorDense.SetVerbosity(-1);
65  if (precise) {
66  fProfileFitter.SetAafCorrection(fAafCorrection, fUseNoiseBins);
67  } else {
68  fProfileFitter.SetAafCorrection(0, false);
69  }
70 
71  try {
72  fCFMatrixCalculator.BuildMatrix(eyeCopy, fLeavingAtmoIsError);
73  fCFMatrixCalculatorDense.BuildMatrix(eyeCopy, fLeavingAtmoIsError, (precise && fCFMatrixCalculator.GetFOVSize() > 0 && fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() > 0) ? fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() : 1);
74  // } catch (OutOfBoundException&) {
75  } catch (std::exception&) {
76  return numeric_limits<double>::infinity();
77  }
78  if (!fCFMatrixCalculator.HasMatrix() || !fCFMatrixCalculatorDense.HasMatrix()
79  || fCFMatrixCalculator.GetSize() < 2)
80  {
81  ERROR( "No Matrix built.");
82  return numeric_limits<double>::infinity();
83  }
84 
85  fProfileCalculator.CalculateProfile(eyeCopy, fCFMatrixCalculator, true);
86 
87  if (!fUseLightFlux) {
88  if (FitProfile(eyeCopy,FdEnergyDepositFinderKG::eGH4dEdXChi2)
89  /*&& FitProfile(eyeCopy,FdEnergyDepositFinderKG::eGH2dEdXChi2)*/)
90  {
91  const double chi2pfl =
92  eyeCopy.GetRecData().GetFRecShower().GetGHParameters().GetChiSquare();
93  // /eyeCopy.GetRecData().GetFRecShower().GetGHParameters().GetNdof();
94  return chi2pfl;
95  }
96  else return numeric_limits<double>::infinity();
97  } else {
98  if (FitProfile(eyeCopy,FdEnergyDepositFinderKG::eGH2dEdXChi2, precise)
99  && FitProfile(eyeCopy,FdEnergyDepositFinderKG::eGH4dEdXChi2, precise) //VN GH2 not precise enough -> Xmax bias
100  && FitProfile(eyeCopy,FdEnergyDepositFinderKG::eGH4LightLogLike, precise))
101  {
102  const double chi2pfl = fProfileFitter.GetLHChi2();
103  //VN from Chi2 to Likelihood
104  //eyeCopy.GetRecData().GetFRecShower().GetGHParameters().GetChiSquare();
105  // /eyeCopy.GetRecData().GetFRecShower().GetGHParameters().GetNdof();
106  return chi2pfl;
107  }
108  else return numeric_limits<double>::infinity();
109  }
110 }
111 
112 
113 bool
114 ProfileChi2::FitProfile(Eye& eye,
115  const FdEnergyDepositFinderKG::EFitFunctionType type, bool precise)
116 {
117  using namespace FdEnergyDepositFinderKG;
118  using namespace evt;
119 
120  ShowerFRecData& shower = eye.GetRecData().GetFRecShower();
121  //shower.SetEnergyCutoff(fElectronEnergyThreshold);
122  fProfileFitter.ResetStartParameters();
123 
124  if (!shower.HasGHParameters()) {
125  shower.MakeGHParameters(GaisserHillas4Parameter(ghPars.Type()));
126  if (!GuessGHParameters(shower))
127  return false;
128  //DumpCurrentParameters(shower, false, eUndefined);
129  }
130  // GaisserHillas4Parameter& gh4Pars = shower.GetGHParameters<GaisserHillas4Parameter>();
131 
132  // cout<<"Type: "<< GetFunctionTypeName(ghPars.Type())<<endl;
133  // cout<<"L: "<< gh4Pars.GetShapeParameter(gh::eUSP_L)/(g/cm2)<< endl;
134  // cout<<"R: "<< gh4Pars.GetShapeParameter(gh::eUSP_R)<< endl;
135 
136 
137  //if (!shower.HasGHParameters<GaisserHillas4Parameter>()) {
138  // return false; // we really need GH4 parameters
139  //}
140 
141 
142  fProfileFitter.SetFitMode(ProfileFitter::eNMax);
143  {
144  const GaisserHillas4Parameter& gh4Pars = shower.GetGHParameters<GaisserHillas4Parameter>();
145  fProfileFitter.SetStartParameters(gh4Pars);
146  }
147  fProfileFitter.SetLightFluxData(fCFMatrixCalculator, fCFMatrixCalculatorDense);
148 
149  fProfileFitter.SetProfileData(shower.GetEnergyDeposit());
150  fProfileFitter.SetFunctionType(type);
151 
152  //VN: in separate inicialization function because fitter is static
153  //fProfileFitter.SetUnivConstrained(fIsUnivConstrained, fA1, fA2, fksigma);
154 
155  if(fProfileFitter.Fit()){
156  GaisserHillas4Parameter& gh4Pars = shower.GetGHParameters<GaisserHillas4Parameter>();
157  fProfileFitter.FillGHParameters(gh4Pars);
158 
159  // return true;
160  double calorEnergy = gh4Pars.GetIntegral();
161  double calorEnergyErr = calorEnergy * gh4Pars.GetIntegralError();
162 
163  // refit at final step using energy as parameter instead of Xmax
164  if (type == eFinalFitStep) {
165  fProfileFitter.SetFitMode(ProfileFitter::eIntegral);
166  fProfileFitter.SetStartParameters(gh4Pars);
167  if (fProfileFitter.Fit())
168  fProfileFitter.GetEnergy(calorEnergy, calorEnergyErr);
169  else
170  return false;
171  }
172  shower.SetEmEnergy(calorEnergy, calorEnergyErr, ShowerFRecData::eStatistical);
173  shower.SetEmEnergyError(0, ShowerFRecData::eAtmospheric);
174 
175  // rebuilt matrix if Xmax changed too much and not in final round
176  const double currXmax = gh4Pars.GetXMax();
177  const double maxDeltaXmax = 10*g/cm2;
178  const bool updateCFM =
179  fabs(currXmax-fCFMatrixCalculatorDense.GetXmax()) > maxDeltaXmax &&
180  type != eFinalFitStep;
181 
182  if (updateCFM) {
183  try {
184  fCFMatrixCalculator.BuildMatrix(eye, fLeavingAtmoIsError);
185  fCFMatrixCalculatorDense.BuildMatrix(eye, fLeavingAtmoIsError, (precise && fCFMatrixCalculator.GetFOVSize() > 0 && fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() > 0) ? fDenseMatrixDim/fCFMatrixCalculator.GetFOVSize() : 1);
186  } catch (OutOfBoundException&) {
187  return false;
188  }
189  }
190  if (fCFMatrixCalculator.HasMatrix()) {
191 
192  fProfileCalculator.CalculateProfile(eye, fCFMatrixCalculator);
193  //DumpCurrentParameters(shower, updateCFM, type);
194 
195  return true;
196  }
197  }
198 
199  return false;
200 }
201 
202 bool
203 ProfileChi2::GuessGHParameters(evt::ShowerFRecData& shower)
204  const
205 {
206  using namespace FdEnergyDepositFinderKG;
207  using namespace evt;
208 
210 
211  // running average
212 
213  if (!shower.HasEnergyDeposit()) {
214  WARNING("can not estimate start parameters");
215  gh4Pars.SetXMax(700*g/cm2, 0);
216  gh4Pars.SetNMax(1*PeV/g*cm2, 0, true);
217  // gh4Pars.SetNMax(energyDeposit.GetY(0), 0, true);
218  return false;
219  }
220 
221  const TabulatedFunctionErrors& energyDeposit = shower.GetEnergyDeposit();
222  const unsigned int nPoints = energyDeposit.GetNPoints();
223  const double depthBin = 50*g/cm2;
224 
225  bool firstTime = true;
226  double xMax = 0;
227  double dEdXmax = 0;
228  for (unsigned int i = 0; i < nPoints; ++i) {
229  const double firstDepth = energyDeposit.GetX(i);
230  unsigned int nAverage = 0;
231  double wSum = 0;
232  double ywSum = 0;
233  double xSum = 0;
234  for (unsigned int j = i; j < nPoints; ++j) {
235  const double thisDepth = energyDeposit.GetX(j);
236  ++nAverage;
237  xSum += thisDepth;
238  const double w = 1 / pow(energyDeposit.GetYErr(j), 2);
239  wSum += w;
240  ywSum += energyDeposit.GetY(j)*w;
241 
242  if (thisDepth - firstDepth > depthBin) {
243  const double yAverage = ywSum/wSum;
244  if (firstTime || yAverage > dEdXmax) {
245  dEdXmax = yAverage;
246  xMax = xSum / nAverage;
247  firstTime = false;
248  }
249  break;
250  }
251  }
252  }
253 
254  if (ghPars.Type() == gh::eClassic) {
255  //VN: values better for low energies?
256  gh4Pars.SetShapeParameter(gh::eX0, /*-120*/1*g/cm2, 0);
257  gh4Pars.SetShapeParameter(gh::eLambda, /*61*/86*g/cm2, 0);
258  }
259 
260  if (ghPars.Type() == gh::eUSP) {
261 
262  gh4Pars.SetShapeParameter(ghPars.Type(eOne),
263  ghPars.Mean(eOne,1e18*eV), ghPars.Sigma(eOne,1e18*eV));
264  gh4Pars.SetShapeParameter(ghPars.Type(eTwo),
265  ghPars.Mean(eTwo,1e18*eV), ghPars.Sigma(eTwo,1e18*eV));
266  }
267  if (ghPars.Type() == gh::eWidth) {
268  gh4Pars.SetShapeParameter(gh::eFWHM, 525*g/cm2, 0);
269  gh4Pars.SetShapeParameter(gh::eAsym, 0.455, 0);
270  }
271 
272  if (firstTime) {
273  WARNING("can not estimate start parameters");
274  gh4Pars.SetXMax(700*g/cm2, 0);
275  gh4Pars.SetNMax(1*PeV/g*cm2, 0, true);
276  //gh4Pars.SetNMax(energyDeposit.GetY(0), 0, true);
277  return false;
278  } else {
279  gh4Pars.SetXMax(xMax, 0);
280  gh4Pars.SetNMax(dEdXmax, 0, true);
281  }
282  return true;
283 }
284 
285 } //namespace
const double eV
Definition: GalacticUnits.h:35
unsigned int GetNPoints() const
const double PeV
double GetIntegralError() const
return relative error of integral
Fluorescence Detector Eye Event.
Definition: FEvent/Eye.h:29
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
void Init()
Initialise the registry.
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)
Exception for reporting variable out of valid range.
T Get() const
Definition: Branch.h:271
Class representing a document branch.
Definition: Branch.h:107
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
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
Interface class to access to Fluorescence reconstruction of a Shower.
double GetIntegral() const
calculate integral
Gaisser Hillas with 4 parameters.
void MakeGHParameters(const VGaisserHillasParameter &gh)
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
bool HasEnergyDeposit() const
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
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

, generated on Tue Sep 26 2023.