LDFFitFunction.h
Go to the documentation of this file.
1 #ifndef _RdHASLDFFitter_LDFFitFunction_h_
2 #define _RdHASLDFFitter_LDFFitFunction_h_
3 
4 #include "RdHASLDFFitter.h"
5 
6 #include <det/Detector.h>
7 
8 #include <utl/Minou.h>
9 #include <utl/AugerUnits.h>
10 #include <utl/Point.h>
11 #include <utl/Vector.h>
12 #include <utl/RadioGeometryUtilities.h>
13 
14 #include <fwk/LocalCoordinateSystem.h>
15 
16 // Atmosphere
17 #include <atm/ProfileResult.h>
18 #include <atm/InclinedAtmosphericProfile.h>
19 
20 #include <vector>
21 
22 #include <TMath.h>
23 
24 using namespace utl;
25 
26 
27 namespace RdHASLDFFitter {
28 
29  struct FitConfig {
30  bool fUseStationsWithoutSignal = false;
31  bool fFitLog = false;
32  bool fUseParam = true;
33  bool fUseSoftExponent = true;
34  };
35 
36 
37  struct StationFitData {
38  int fId = 0;
39  Point fPosition; // = Point(0, 0, 0, det::Detector::GetInstance().GetReferenceCoordinateSystem());
40  double fEnergyFluenceVxB = 0;
41  double fEnergyFluenceVxBErr = 0;
42  double fEnergyFluenceVxVxB = 0;
43  double fEnergyFluenceVxVxBErr = 0;
44  mutable double fEnergyFluenceVxBPredict = 0;
45  mutable double fEnergyFluenceGeomagnetic = 0;
46  mutable double fEnergyFluenceGeomagneticErr = 0;
47  mutable double fCEarlyLate = 0;
48  mutable double fCeFraction = 0;
49  mutable bool fRejected = false;
50  };
51 
52 
53  struct ShowerFitData {
54  double fSineAlpha = 0;
55  double fZenith = 0;
56  double fDistanceTo750 = 0;
63  };
64 
65 
66  class LDFFitFunction : public Minou::Base {
67 
68  public:
69  LDFFitFunction(const std::vector<StationFitData>& stationData,
70  ShowerFitData showerData,
71  const std::vector<Minou::ParameterDef>& pars,
72  const FitConfig fitconfig = FitConfig(),
73  const double egeoCorr = 1) :
74  fStationData(stationData),
75  fShowerData(showerData),
76  fFitConfig(fitconfig),
77  fTransformationRefCore(
79  fShowerData.fRefShowerAxis,
80  fwk::LocalCoordinateSystem::Create(fShowerData.fRefShowerCore),
81  fShowerData.fMagneticField)),
82  fEgeoCorr(egeoCorr)
83  {
84  GetParameterDefs() = pars;
85  }
86 
87  double operator()(const std::vector<double>& pars) const;
88 
89  // return number of degree of freedom.
90  int GetNDF();
91 
92  // returns final lost
93  double GetChi2(const std::vector<double>& pars);
94 
95  // predicts (asymmetric) energy fluence in vxB
96  double FVxBPrediction(const double xvBvvB, const double yvBvvB, const double cEarlyLate) const;
97 
98  // symmetrized signal: Predicts geomagnetic energy fluence from (measured) energy fluence in vxB
99  double FGeomagneticParam(const double xvBvvB, const double yvBvvB,
100  const double efvxB, const double cEarlyLate) const;
101 
102  // Determine geomagnetic energy fluence from polarisation and pulse position in shower plane (wo any param.)
103  double FGeomagneticPos(const double xvBvvB, const double yvBvvB, const double cEarlyLate,
104  const StationFitData& station) const;
105 
106  // Determine geomagnetic energy fluence error from polarisation and pulse position in shower plane (wo any param.)
107  double FGeomagneticPosErr(const double xvBvvB, const double yvBvvB, const double efGeoPos,
108  const StationFitData station) const;
109 
110  // Param of charge-excees fraction as function of the (early-late corredted) axis distrance
111  // and the distance to Xmax (resp. density at Xmax)
112  double GetChargeExcessFraction(const double axisDistance) const;
113 
114  // updates member variables with given set of parameter
115  void GetPrediction(const std::vector<double>& pars);
116 
117  // implementation of the (param.) geomagnetic LDF for the different models
118  virtual double FEgeo(const double r) const = 0;
119 
120  // implementation of the integral over the geomagnetic LDF (shape)
121  virtual double GetNormalization() const = 0;
122 
123  // Updates parameterized parameter in each iteration of the fit
124  virtual void UpdateParameterParam(const std::vector<double>& pars) const = 0;
125 
126  // return parametrized charge-excess fraction which is defined as a = sin(alpha) ** 2 * f_ce / f_geo
127  static double ChargeExcessFractionParamICRC19(const double axisDistance,
128  const double distanceToXmax,
129  const double densityXmax);
130 
131  // return parametrized charge-excess fraction which is defined as a = sin(alpha) ** 2 * f_ce / f_geo
132  static double ChargeExcessFractionParamICRC21(const double axisDistance,
133  const double distanceToXmax,
134  const double densityXmax);
135 
136  // return factor c_geo in: f_geo = f_vxB * c_geo
137  static double GeomagneticEmissionFactor(const double ceFraction,
138  const double sineAlpha,
139  const double cosAzimuth);
140 
141  // return factor c_geo in: f_geo = f_vxB * c_geo
142  static double GeomagneticEmissionFactor(const double ceFraction,
143  const double sineAlpha,
144  const utl::Vector& showerAxis,
145  const utl::Vector& magneticFieldVector,
146  const utl::Point& showerCore,
147  const utl::Point& stationPosition);
148 
149  protected:
150  // lost function (chi^2)
151  double GetLoss(const double model, const double data, const double uncertainty) const;
152 
153  // lost function with log
154  double GetLossLog(const double model, const double data, const double uncertainty) const;
155 
156 
157  //void TestStations(const std::vector<double>& pars, const double chi2Mean);
158 
159  // Get transformation for updated core position
160  RadioGeometryUtilities GetFittedRadioCoreTransformation() const;
161 
162  const std::vector<StationFitData>& fStationData;
166 
167  const double fEgeoCorr = 1; // To correct an overall bias (used in GetNormalization())
168 
169  // generic fit parameter
170  mutable double fEgeo = 0;
171  mutable double fRnorm = 0;
172  mutable double fNorm = 1;
173 
174  mutable double fCoreX = 0;
175  mutable double fCoreY = 0;
176 
177  mutable double fDistanceToXmax = 0; // should be given in meter
178  mutable double fDensityAtXmax = 0; // not fitted but calculated from fDistanceToXmax
179  mutable double fHeight = 0; // not fitted but calculated from fDistanceToXmax
180 
181  };
182 
183 
185 
186  public:
187  using LDFFitFunction::LDFFitFunction;
188 
189  // Returns integral over FABCD form 0 to fRnorm * 2pi
190  double GetNormalization() const override;
191 
192  // LDF model (of the shape) of the geomagnetic emission
193  static double FABCD(const double r, const double r0, const double a,
194  const double b, const double c, const double d);
195 
196  /* LDF model of the geomagnetic emission:
197  FEgeo = E_geo * FABCD / GetNormalization() */
198  double FEgeo(const double r) const override;
199 
200  // param of C': C = exp(C') (with C' beeing the fit parameter)
201  static
202  double
203  GetC(const double dxmax)
204  {
205  const double dx = dxmax / 1000;
206  return dx * (6.283649656834273e-05 * dx - 0.02574916964033989) + 20.865090319962185 / dx + 1.6373732045578846; // conversion in km
207  }
208 
209  // param of D': D = exp(D') (with D' beeing the fit parameter)
210  static
211  double
212  GetD(const double dxmax)
213  {
214  const double dx = dxmax / 1000;
215  return dx * (9.113744732999866e-05 * dx - 0.037475161541008134) + 33.83363364863988 / dx + 1.9430065360834818; // conversion in km
216  }
217 
218  // simple parameterisation of the cherenkov radius. Systematically lower than CalculateR0
219  static
220  double
221  CherenkovRadius(const double densitymax, const double dxmax)
222  {
223  const double cherenkovAngleInDeg = 0.24905864 * std::log(densitymax) + 0.92165234;
224  return std::tan(cherenkovAngleInDeg * utl::deg) * dxmax;
225  }
226 
227  private:
228  // specific fit parameter
229 
230  const double fB = 0; // fixed
231  mutable double fC = 0;
232  mutable double fD = 0;
233  const double fr0 = 800; // fixed
234 
235  void
236  UpdateParameterParam(const std::vector<double>& pars)
237  const override
238  {
239  // Fit parameter
240  fEgeo = pars[0];
241  fDistanceToXmax = pars[1];
242  fCoreX = pars[2];
243  fCoreY = pars[3];
244 
245  // parametrized parameter
246  fC = GetC(fDistanceToXmax);
247  fD = GetD(fDistanceToXmax);
248 
249  // calculate density from distance
250  // the -1 is needed because of convention of the table (opposit direction of the init vector)
251  const double height = fShowerData.fHeightFromDistance.Y(-fDistanceToXmax);
252  fDensityAtXmax = fShowerData.fDensityFromHeight.Y(height) / (kg / m3);
253 
254  fRnorm = 5 * CherenkovRadius(fDensityAtXmax, fDistanceToXmax);
255  fNorm = GetNormalization(); // integral over FABCD from 0 to fRnorm * 2pi
256  }
257 
258  };
259 
260 
262 
263  public:
264  using LDFFitFunction::LDFFitFunction;
265 
266  // Returns integral over FGaussSigmoid form 0 to fRnorm * 2pi
267  double GetNormalization() const override;
268 
269  // Model of the geomagnetic LDF (shape) with soft exponent
270  static double FGaussSigmoidSoft(const double r, const double r0, const double sig,
271  const double p, const double arel, const double slope, const double r02);
272 
273  // Model of the geomagnetic LDF (shape) with hard exponent
274  static double FGaussSigmoidHard(const double r, const double r0, const double sig,
275  const double p, const double arel, const double slope, const double r02);
276 
277  // Model of the geomagnetic LDF (shape)
278  double FGaussSigmoid(const double r, const double r0, const double sig,
279  const double p, const double arel, const double slope, const double r02) const
280  { return (fFitConfig.fUseSoftExponent) ? FGaussSigmoidSoft(r, r0, sig, p, arel, slope, r02)
281  : FGaussSigmoidHard(r, r0, sig, p, arel, slope, r02); }
282 
283  /* LDF model of the geomagnetic emission:
284  FEgeo = E_geo * FGaussSigmoid / GetNormalization() */
285  double FEgeo(const double r) const override;
286 
287  /* Returns the cherenkov radius calculated with simple model: Radius of a cone with its apex at Xmax
288  and an opening angle equal the cherenkov angle at that height given by alpha = arccos(1 / n(h)) */
289  double CalculateR0() const;
290 
291  //New, "hard p", /wo d750
292  static double GetSigHard(const double dmax) {
293  return 0.16460107 * std::pow(dmax - 5000, 0.69675388) + 39.46602294;
294  }
295 
296  static double GetPHard(const double dmax) {
297  return -4.91997573e-01 * exp(-3.88166824e-05 * dmax) + 1.85788594e+00;
298  }
299 
300  static double GetR02Hard(const double dmax) {
301  return 5.48029929e-01 + 7.06584317e-07 * dmax + 5.06592690e+07 / dmax / dmax;
302  }
303 
304  static double GetArelHard(const double dmax) {
305  return 7.57300343e-01 + 7.76904953e-07 * dmax + 1.63545932e+07 / dmax / dmax;
306  }
307 
308  /*// New p soft, only dmax, with d750
309  double GetSig(const double dmax) const {
310  return 1.39506207e-01 * std::pow(dmax - 5000, 7.09861340e-01) +
311  5.39164661e+01 - 1.84052852e-03 * (dmax - fShowerData.fDistanceTo750);
312  }
313 
314  static double GetPSoft(const double dmax) {
315  return 1.63989873e+02 * exp(-2.75777834e-05 * dmax) + 6.81576551e+01;
316  }
317 
318  static double GetR02(const double dmax) {
319  return 5.41470307e-01 + 7.18512356e-07 * dmax + 6.62411621e+07 / dmax / dmax;
320  }
321 
322  double GetArel(const double dmax) const {
323  return 7.52546909e-01 + 7.92709635e-07 * dmax + 2.23641574e+07 / dmax / dmax
324  + 2.99174458e-06 * (dmax - fShowerData.fDistanceTo750);
325  }*/
326 
327  // New p soft, only dmax, without d750
328  static double GetSigSoft(const double dmax)
329  { return 0.13176183 * std::pow(dmax - 5000, 0.71437054) + 56.30941015; }
330 
331  static double GetPSoft(const double dmax)
332  { return 1.54942405e+02 * exp(-2.50177591e-05 * dmax) + 6.49133050e+01; }
333 
334  static double GetR02Soft(const double dmax)
335  { return 5.51709206e-01 + 6.87661913e-07 * dmax + 6.61581738e+07 / dmax / dmax; }
336 
337  static double GetArelSoft(const double dmax)
338  { return 7.57449757e-01 + 7.68399447e-07 * dmax + 1.98026585e+07 / dmax / dmax; }
339 
340  double GetSig(const double dmax) const
341  { return (fFitConfig.fUseSoftExponent) ? GetSigSoft(dmax) : GetSigHard(dmax); }
342 
343  double GetP(const double dmax) const
344  { return (fFitConfig.fUseSoftExponent) ? GetPSoft(dmax) : GetPHard(dmax); }
345 
346  double GetR02(const double dmax) const
347  { return (fFitConfig.fUseSoftExponent) ? GetR02Soft(dmax) : GetR02Hard(dmax); }
348 
349  double GetArel(const double dmax) const
350  { return (fFitConfig.fUseSoftExponent) ? GetArelSoft(dmax) : GetArelHard(dmax); }
351 
352 
353  private:
354  // specific fit parameter
355  mutable double fR0 = 0;
356  mutable double fSig = 0;
357  mutable double fP = 0;
358  mutable double fR02 = 0;
359  mutable double fArel = 0;
360  const double fSlope = 5; // fixed
361 
362  void
363  UpdateParameterParam(const std::vector<double>& pars)
364  const override
365  {
366  // Fit parameter
367  fEgeo = pars[0];
368  fDistanceToXmax = pars[1];
369  fCoreX = pars[2];
370  fCoreY = pars[3];
371 
372  // calculate density from distance
373  // the -1 is needed because of convention of the table (opposit direction of the init vector)
374  fHeight = fShowerData.fHeightFromDistance.Y(-fDistanceToXmax);
375  fDensityAtXmax = fShowerData.fDensityFromHeight.Y(fHeight) / (kg / m3);
376 
377  // parametrized parameter
378  fSig = GetSig(fDistanceToXmax);
379  fP = GetP(fDistanceToXmax);
380  fR02 = GetR02(fDistanceToXmax);
381  fArel = GetArel(fDistanceToXmax);
382 
383  fR0 = CalculateR0(); // needs fDensityAtXmax to be updated
384  fRnorm = 5 * fR0;
385  fNorm = GetNormalization(); // needs fRnorm to be updated
386  }
387  };
388 
389 }
390 
391 
392 #endif
static double GetArelHard(const double dmax)
static double GetSigHard(const double dmax)
Point object.
Definition: Point.h:32
static double CherenkovRadius(const double densitymax, const double dxmax)
static double GetC(const double dxmax)
static double GetPSoft(const double dmax)
atm::ProfileResult fDensityFromHeight
Provide an easy way to create a local coordinate system.
static double GetArelSoft(const double dmax)
RadioGeometryUtilities fTransformationRefCore
double pow(const double x, const unsigned int i)
double GetArel(const double dmax) const
constexpr double deg
Definition: AugerUnits.h:140
atm::ProfileResult fHeightFromDistance
static double GetR02Soft(const double dmax)
Class describing the Atmospheric profile.
Definition: ProfileResult.h:25
double GetSig(const double dmax) const
double GetR02(const double dmax) const
constexpr double m3
Definition: AugerUnits.h:123
static double GetD(const double dxmax)
static double GetPHard(const double dmax)
const std::vector< StationFitData > & fStationData
LDFFitFunction(const std::vector< StationFitData > &stationData, ShowerFitData showerData, const std::vector< Minou::ParameterDef > &pars, const FitConfig fitconfig=FitConfig(), const double egeoCorr=1)
double FGaussSigmoid(const double r, const double r0, const double sig, const double p, const double arel, const double slope, const double r02) const
static double GetSigSoft(const double dmax)
uint16_t * data
Definition: dump1090.h:228
Vector object.
Definition: Vector.h:30
static double GetR02Hard(const double dmax)
atm::ProfileResult fRefracFromHeight
double GetP(const double dmax) const
constexpr double kg
Definition: AugerUnits.h:199

, generated on Tue Sep 26 2023.