ICRC2019/FittingFunctions.hh
Go to the documentation of this file.
1 /* FITTING FUNCTIONS */
2 
3 /* Different power-law-like fit functions to describe the measured flux */
4 
5 
6 double SpectrumLgSmoothFitFunction2013(double* x, double* par) {
7 
8  /* ICRC 2013 model:
9 
10  0: J0 (normalization);
11  1: log10(Eankle) (energy in log10 at ankle position);
12  2: gamma1 (spectral index before ankle);
13  3: gamma2 (spectral index after ankle);
14  4: log10(Es) (energy in log10 at the 1/2 suppression);
15  5: log10(Wc) (suppression smoothness )
16  */
17 
18  const double lgE = x[0];
19 
20  double lgJ;
21 
22  if (lgE < par[1])
23  lgJ = par[0] - par[2] * (lgE - par[1]);
24  else {
25  double lgJ_exp = -par[3] * lgE - log10(1.0 + exp((lgE - par[4]) / par[5]));
26  double lgJ_ankle = -par[3] * par[1] - log10(1.0 + exp((par[1] - par[4]) / par[5]));
27  lgJ = par[0] + lgJ_exp - lgJ_ankle;
28  }
29 
30  return pow(10, lgJ);
31 }
32 
33 Double_t Spectrum2015_2017SmoothAnkle(Double_t *v, Double_t *par) {
34  Double_t J;
35  //par[0] J0
36  //par[1] E12
37  //par[2] gamma1
38  //par[3] gamma2
39  //par[4] E23
40  //par[5] Delta gamma
41  double J0 = pow(10, par[0]);
42  double E12 = pow(10, par[1]);
43  double E23 = pow(10, par[4]);
44 
45  double E = pow(10, v[0]);
46 
47  J = pow(E / E12, -par[2]) * ( 1 + pow(E / E12, par[2]) ) / (1 + pow(E / E12, par[3] ) ) * (1. + pow(E12 / E23, par[5]) ) / (1 + pow(E / E23, par[5]));
48 
49  J *= J0;
50  return J;
51 }
52 
53 
54 double SpectrumLgSmoothFitFunction2015(double* x, double* par) {
55 
56  /* ICRC 2015/2017 model:
57 
58  0: J0 (normalization);
59  1: log10(Eankle) (energy in log10 at ankle position);
60  2: gamma1 (spectral index before ankle);
61  3: gamma2 (spectral index after ankle);
62  4: log10(Es) (energy in log10 at the 1/2 suppression);
63  5: Delta gamma (increment of the spectral index beyond suppression)
64  */
65 
66 
67  const double lgE = x[0];
68 
69  double lgJ;
70 
71  if (lgE < par[1])
72  lgJ = par[0] - par[2] * (lgE - par[1]);
73  else {
74  double E = pow(10., lgE);
75  double Ea = pow(10, par[1]);
76  double Es = pow(10, par[4]);
77 
78  double lgJ_exp = log10(1.0 + pow(E / Es, par[5]));
79  double lgJ_ankle = log10(1.0 + pow(Ea / Es, par[5]));
80  lgJ = par[0] - par[3] * (lgE - par[1]) + lgJ_ankle - lgJ_exp ;
81  }
82 
83  return pow(10, lgJ);
84 }
85 
86 
87 double
88 FluxModelMultiSmoothBreak(double* x, double* par) {
89  /* ICRC 2017? model for unfolding (not for spectrum fit):
90  Smooth model with additional break as proposed by Oliver
91  Should be used only for the unfolding to avoid non-diff features in correction factor
92 
93  0: J0 (normalization);
94  1: log10(Eankle) (energy in log10 at ankle position);
95  2: log10(Ex) (energy in log10 at additional break);
96  3: log10(Es) (energy in log10 at the 1/2 suppression);
97  4: gamma1 (spectral index before ankle);
98  5: gamma2 (spectral index after ankle but before x-break);
99  6: gamma3 (spectral index after x-break but before suppression);
100  7: gamma4 (spectral index after suppression);
101 
102  */
103  const size_t n = 8;
104  const size_t breaks = n / 2 - 1;
105  const double lgE = x[0];
106 
107  double lgJ = par[0] - par[breaks + 1] * (lgE - 18.5);
108 
109  for (size_t i = 1; i <= breaks; ++i) {
110  lgJ += TMath::Log10(1 + pow(10, par[breaks + i] * (lgE - par[i])));
111  lgJ -= TMath::Log10(1 + pow(10, par[breaks + i + 1] * (lgE - par[i])));
112  }
113 
114  return pow(10, lgJ);
115 }
116 
117 
118 double SpectrumInfillFitFunction(double* x, double* par) {
119  // Model: only upto ankle --> J0, Eank, gamma1, gamma2
120 
121  const double lgE = x[0];
122 
123  double lgJ;
124 
125  if (lgE < par[1])
126  lgJ = par[0] - par[2] * (lgE - par[1]);
127  else
128  lgJ = par[0] - par[3] * (lgE - par[1]);
129 
130  return pow(10, lgJ);
131 }
132 
133 double SpectrumInfillICRC2019(double* x, double* par) {
134  /*
135  0: J0 (normalization at break)
136  1: log10(E0)
137  2: log10(Eankle)
138  3: gamma0
139  4: gamma1
140  5: gamma2
141  6: dGamma0
142  */
143 
144  const double lgNorm = par[0];
145  const double lgEbreak = par[1];
146  const double lgEa = par[2];
147  const double gamma0 = par[3];
148  const double gamma1 = par[4];
149  const double gamma2 = par[5];
150  const double rate = par[6];
151 
152  const double lgE = x[0];
153 
154  //Maybe one day we can actually fit curve
155  //For now, set to infinity
156  const double lgEs = 1000000;//log10(39.e18);
157  const double dGamma = 2.5;
158 
159  double lgJ;
160 
161  if (lgE < lgEa) {
162  const double factor = pow(10, lgE) / pow(10, lgEbreak);
163  lgJ = lgNorm - gamma0 * (lgE - lgEbreak) + (gamma0 - gamma1) / rate * log10(1 + pow(factor, rate));
164  } else {
165  const double factor = pow(10, lgEa) / pow(10, lgEbreak);
166  double E = pow(10., lgE);
167  double Ea = pow(10, lgEa);
168  double Es = pow(10, lgEs);
169  double lgJ_exp = log10(1.0 + pow(E / Es, dGamma));
170  double lgJ_ankle = log10(1.0 + pow(Ea / Es, dGamma));
171  lgJ = lgNorm - gamma0 * (lgEa - lgEbreak) + (gamma0 - gamma1) / rate * log10(1 + pow(factor, rate)) - gamma2 * (lgE - lgEa) + lgJ_ankle - lgJ_exp;
172  }
173 
174  return pow(10, lgJ);
175 }
176 
177 
178 // TVectorD versions of the above functions
179 TVectorD SpectrumLgSmoothFitFunction2013(TVectorD x, double* par) {
180  int ncol = x.GetNoElements();
181  TVectorD J(ncol);
182 
183  for (int i = 0; i < ncol; ++i)
184  J[i] = SpectrumLgSmoothFitFunction2013(&x[i], par);
185 
186  return J;
187 }
188 
189 
190 TVectorD SpectrumLgSmoothFitFunction2015(TVectorD x, double* par) {
191  int ncol = x.GetNoElements();
192  TVectorD J(ncol);
193 
194  for (int i = 0; i < ncol; ++i)
195  J[i] = SpectrumLgSmoothFitFunction2015(&x[i], par);
196 
197  return J;
198 }
199 
200 TVectorD Spectrum2015_2017SmoothAnkle(TVectorD x, double* par) {
201  int ncol = x.GetNoElements();
202  TVectorD J(ncol);
203 
204  for (int i = 0; i < ncol; ++i)
205  J[i] = Spectrum2015_2017SmoothAnkle(&x[i], par);
206 
207  return J;
208 }
209 
210 TVectorD FluxModelMultiSmoothBreak(TVectorD x, double* par) {
211  int ncol = x.GetNoElements();
212  TVectorD J(ncol);
213 
214  for (int i = 0; i < ncol; ++i)
215  J[i] = FluxModelMultiSmoothBreak(&x[i], par);
216 
217  return J;
218 }
219 
220 
221 TVectorD SpectrumInfillFitFunction(TVectorD x, double* par) {
222  int ncol = x.GetNoElements();
223  TVectorD J(ncol);
224 
225  for (int i = 0; i < ncol; ++i)
226  J[i] = SpectrumInfillFitFunction(&x[i], par);
227 
228  return J;
229 }
230 
231 
232 TVectorD SpectrumInfillICRC2019(TVectorD x, double* par) {
233  int ncol = x.GetNoElements();
234  TVectorD J(ncol);
235 
236  for (int i = 0; i < ncol; ++i)
237  J[i] = SpectrumInfillICRC2019(&x[i], par);
238 
239  return J;
240 }
241 
242 
243 
244 // selects one of the implemented models according to the modeltype
245 TVectorD FluxModel(string model, TVectorD x, double* par) {
246  if (model == "StandardICRC2013")
247  return SpectrumLgSmoothFitFunction2013(x, par);
248  else if (model == "StandardICRC2015")
249  return SpectrumLgSmoothFitFunction2015(x, par);
250  else if (model == "StandardMultiSmooth")
251  return FluxModelMultiSmoothBreak(x, par);
252  else if (model == "InfillHard")
253  return SpectrumInfillFitFunction(x, par);
254  else if (model == "Spectrum2015_2017SmoothAnkle")
255  return Spectrum2015_2017SmoothAnkle(x, par);
256  else if (model == "SpectrumInfillICRC2019")
257  return SpectrumInfillICRC2019(x, par);
258  else {
259  cerr << endl;
260  cerr << model << ": no valid unfolding function chosen " << endl;
261  throw std::exception();
262  }
263 
264  return SpectrumLgSmoothFitFunction2013(x, par);
265 }
266 
267 double
268 (*FluxModels(string model))(double*, double*) {
269 
270  if (model == "StandardICRC2013")
272  else if (model == "StandardICRC2015")
274  else if (model == "StandardMultiSmooth")
276  else if (model == "InfillHard")
278  else if (model == "Spectrum2015_2017SmoothAnkle")
280  else if (model == "SpectrumInfillICRC2019")
281  return &SpectrumInfillICRC2019;
282  else {
283  cerr << endl;
284  cerr << model << ": no valid unfolding function chosen " << endl;
285  throw std::exception();
286  }
287 
289 
290 }
291 
292 
293 TVectorD GetCorrectionFactor(const TVectorD x, const TMatrixD m, double* par, string model) {
294  int ncol = x.GetNoElements();
295  TVectorD f0s = FluxModel(model, x, par);
296 
297  for (int i = 0; i < ncol; ++i)
298  f0s[i] = f0s[i] * pow(10, x[i]);
299 
300  TVectorD f1s = m * f0s;
301  f1s *= (x[1] - x[0]);
302 
303  TVectorD corr(ncol);
304  for (int i = 0; i < ncol; ++i)
305  corr[i] = f0s[i] / f1s[i];
306 
307  return corr;
308 
309 }
310 
311 
312 TVectorD GetCorrectionFactor(TVectorD parsFit, string model) {
313  int ncol = vecLgE.GetNoElements();
314 
315  double* par = &parsFit[0];
316  TVectorD f0s = FluxModel(model, vecLgE, par);
317 
318  for (int i = 0; i < ncol; ++i)
319  f0s[i] = f0s[i] * pow(10, vecLgE[i]);
320 
321  TVectorD f1s = kmatrix * f0s;
322  f1s *= (vecLgE[1] - vecLgE[0]);
323 
324  TVectorD corr(ncol);
325  for (int i = 0; i < ncol; ++i)
326  corr[i] = f0s[i] / f1s[i];
327 
328  return corr;
329 }
double FluxModel(const modeltype mtype, double *x, double *par)
double SpectrumInfillFitFunction(double *x, double *par)
double pow(const double x, const unsigned int i)
double FluxModelMultiSmoothBreak(double *x, double *par)
Double_t Spectrum2015_2017SmoothAnkle(Double_t *v, Double_t *par)
TVectorD parsFit
double(*)(double *, double *) FluxModels(const modeltype mtype)
double SpectrumLgSmoothFitFunction2013(double *x, double *par)
TMatrixD kmatrix
double SpectrumInfillICRC2019(double *x, double *par)
TVectorD vecLgE
constexpr double m
Definition: AugerUnits.h:121
TVectorD GetCorrectionFactor(const TVectorD x, const TMatrixD m, double *par, const modeltype mtype)
double SpectrumLgSmoothFitFunction2015(double *x, double *par)

, generated on Tue Sep 26 2023.