UnivTimeKGGamma.cc
Go to the documentation of this file.
1 #include "UnivTimeKGConfig.h"
2 
3 #include <tls/UnivTimeKGGamma.h>
4 
5 #include <utl/GeometryUtilities.h>
6 #include <utl/AugerUnits.h>
7 #include <utl/Reader.h>
8 
9 #include <Math/PdfFuncMathCore.h>
10 #include <Math/ProbFuncMathCore.h>
11 #include <Math/QuantFuncMathCore.h>
12 
13 #include <TMath.h>
14 #include <TF1.h>
15 
16 #include <string>
17 #include <cmath>
18 #include <iostream>
19 #include <sstream>
20 #include <algorithm>
21 
22 using namespace std;
23 using namespace utl;
24 
25 
26 namespace UnivTimeKG {
27 
28  /*
29  Implementation of the time model based on the gumbel distribution
30  */
31 
32  GammaTimeModel::GammaTimeModel()
33  : m(0), s(0), l(0), moff(0), soff(0) { }
34 
35 
37  m(0),
38  s(0),
39  l(0),
40  moff(0),
41  soff(0)
42  {
43  nParams = 2; // m, s, l of generalized gamma distribution
44  icomp = i;
45 
46  for (unsigned int ipar = 0; ipar < nParams; ++ipar) {
47 
48  ostringstream stringStream;
49  string baseDir = DATA_DIR; // from settings.h
50  stringStream << baseDir << "/Gamma/parameters/"
51  << icomp << "_" << ipar << ".xml";
52 
53  Reader XMLReader(stringStream.str(), Reader::eNONE);
54 
55  Branch topB = XMLReader.GetTopBranch();
56 
57  vector<double> rps;
58  topB.GetChild("rpoints").GetData(rps);
59 
60  Branch parsB = topB.GetChild("parameters");
61 
62  fRpoints.push_back(rps);
63 
64  vector<Polynomial> ipolys;
65 
66  const string ptypes[8] = {"DX0", "DX1", "DX2", "DX3", "Zenith0", "Zenith1", "Energy0", "Energy1"};
67 
68  for (unsigned int j = 0; j < sizeof(ptypes) / sizeof(ptypes[0]); ++j) {
69 
70  vector<double> coeff;
71  parsB.GetChild(ptypes[j]).GetData(coeff);
72  ipolys.push_back(Polynomial(coeff));
73 
74  }
75 
76  fPolys.push_back(ipolys);
77 
78  }
79  }
80 
81 
82  double
83  GammaTimeModel::getShapeParameter(const unsigned int /*ipar*/, const vector<double>& /*pars*/, const double /*DX*/)
84  {
85  return 0;
86  }
87 
88 
89  void
90  GammaTimeModel::CalculateModel(const double DX, const double r, const double ppsi,
91  const double theta, const double lgE, vector<double>& output)
92  {
93  // left-right symmetry in showers
94  const double psi = fabs(utl::NormalizeAngleMinusPiPi(ppsi));
95 
96  const double r0 = 1e3;
97  const double rn = r / r0;
98  const double DXn = DX / 750;
99  const double lgEn = lgE - 19;
100 
101  for (unsigned int ipar = 0; ipar < nParams; ++ipar) {
102 
103  vector<Polynomial> ipoly = fPolys[ipar];
104  vector<double> pars;
105 
106  // const double rmin = *min_element(fRpoints[ipar].begin(), fRpoints[ipar].end());
107  // const double rmax = *max_element(fRpoints[ipar].begin(), fRpoints[ipar].end());
108  // const double rstep = 50;
109 
110  for (unsigned int i = 0; i < ipoly.size(); ++i) {
111 
112  double rpolyval;
113 
114  // Extrapolate before/after first/last point used to fit polynomial
115  // if (r < rmin) {
116  // const double fder = (ipoly[i]((rmin + rstep) / r0) - ipoly[i](rmin / r0)) / rstep;
117  // rpolyval = ipoly[i](rmin / r0) + (r - rmin) / r0 * fder;
118  // } else if (r > rmax) {
119  // const double fder = (ipoly[i](rmax / r0) - ipoly[i]((rmax - rstep) / r0)) / rstep;
120  // rpolyval = ipoly[i](rmax / r0) + (r - rmax) / r0 * fder;
121  // } else
122  // rpolyval = ipoly[i](rn);
123 
124  rpolyval = ipoly[i](rn);
125 
126  // debug output
127  // cout << "Parameter: " << ipar << ", rmin: " << rmin << ", rmax: " << rmax << ", value: " << rpolyval << endl;
128 
129  pars.push_back(rpolyval);
130 
131  }
132 
133  const double pari = pars[0] + DXn * (pars[1] + DXn * (pars[2] + DXn * pars[3]))
134  + sin(theta) * (pars[4] * cos(psi) + pars[5] * DXn)
135  + lgEn * (pars[6] + DXn * pars[7]);
136 
137  output.push_back(pari < 0 ? 0 : pari);
138 
139  }
140  }
141 
142 
143  void
144  GammaTimeModel::setShapeParameters(const double DX, const double r, const double psi,
145  const double theta, const double lgE)
146  {
147  vector<double> params;
148  CalculateModel(DX, r, psi, theta, lgE, params);
149  m = params[0] + moff;
150  s = params[1] + soff;
151  // l = params[2];
152  l = 0;
153  }
154 
155 
156  void
157  GammaTimeModel::setParameterOffsets(const double m, const double s)
158  {
159  moff = m;
160  soff = s;
161  }
162 
163 
164  void
165  GammaTimeModel::setShapeParametersDirectly(const double mm, const double ss, const double ll)
166  {
167  m = mm;
168  s = ss;
169  l = ll;
170  }
171 
172 
173  // Implementation of the generalized gamma distribution (log to be numerically more robust)
174  // reference: http://reliawiki.org/index.php/The_Generalized_Gamma_Distribution
175  double
176  GammaTimeModel::pdf(const double t)
177  {
178  if (t <= 0)
179  return 0;
180 
181  if (l == 0)
182  return ROOT::Math::lognormal_pdf(t, m, s, 0);
183 
184  const double lnres = (-TMath::Exp(l * (log(t) - m) / s) / l / l
185  - m / l / s + log(t) * (1 / s / l - 1)
186  + log(l) * (1 - 2 / l / l) - log(s)
187  - TMath::LnGamma(1 / l / l));
188 
189  return TMath::Exp(lnres);
190  }
191 
192 
193  // This is analytically correct due to defintion of TMath::Gamma := 1/Gamma(a) * usual defintion
194  // of lower incomplete gamma function
195  double
196  GammaTimeModel::cdf_analytical(const double* const x, const double* const /*p*/)
197  {
198  const double t = x[0];
199 
200  if (t <= 0)
201  return 0;
202 
203  if (l == 0)
204  return ROOT::Math::lognormal_cdf(t, m, s, 0);
205 
206  const double z = (log(t) - m) / s;
207  return TMath::Gamma(1 / l / l, 1 / l / l * TMath::Exp(l * z));
208  }
209 
210 
211  double
212  GammaTimeModel::cdf(const double t)
213  {
214  const double xs[] = { t };
215  return cdf_analytical(xs, 0);
216  }
217 
218 
219  double
220  GammaTimeModel::invcdf(const double quantile)
221  {
222  if (l == 0)
223  return ROOT::Math::lognormal_quantile(quantile, m, s);
224 
225  const TF1 cdfgamma("gamma_cdf", this, &GammaTimeModel::cdf_analytical, 0., 100000., 0);
226  return cdfgamma.GetX(quantile);
227  }
228 
229 }
double invcdf(const double)
Branch GetTopBranch() const
Definition: Branch.cc:63
constexpr double mm
Definition: AugerUnits.h:113
double NormalizeAngleMinusPiPi(const double x)
Normalize angle to lie between -pi and pi (-180 and 180 deg)
unsigned int nParams
Definition: UnivTimeKG.h:59
Simple polynomial container.
Definition: Polynomial.h:22
void setShapeParameters(const double DX, const double r, const double psi, const double theta, const double lgE)
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
double cdf(const double)
Utility for parsing XML files.
Definition: Reader.h:25
Class representing a document branch.
Definition: Branch.h:107
double pdf(const double)
constexpr double s
Definition: AugerUnits.h:163
unsigned int icomp
Definition: UnivTimeKG.h:61
std::vector< std::vector< utl::Polynomial > > fPolys
void setShapeParametersDirectly(const double mm, const double ss, const double ll)
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
double getShapeParameter(const unsigned int ipar, const std::vector< double > &pars, const double DX)
double cdf_analytical(const double *const x, const double *const p)
std::vector< std::vector< double > > fRpoints
void setParameterOffsets(const double m, const double s)
void CalculateModel(const double DX, const double r, const double psi, const double theta, const double lgE, std::vector< double > &output)
constexpr double m
Definition: AugerUnits.h:121

, generated on Tue Sep 26 2023.