FitterUtil.cc
Go to the documentation of this file.
1 #include <FitterUtil.h>
2 #include <TVector3.h>
3 #include <cmath>
4 #include <iostream>
5 
6 #include <tls/UnivTimeKG.h>
7 
8 using namespace std;
9 
10 namespace FitterUtil {
11 
12  double getDistToFirstInteraction(double hfi, double sHeight, double zenith, double dist, double psi)
13  {
14  //dist, psi given in SP coordinates. This affects the x coordinate: x_G = x_SP/cos(zenith)
15  TVector3 sPosition(dist * cos(psi) / cos(zenith), dist * sin(psi), sHeight);
16  TVector3 core(0., 0., sHeight) ;
17  TVector3 axis(sin(zenith), 0., cos(zenith));
18  double d_core_fi = (hfi - sHeight) / cos(zenith);
19  TVector3 fiPosition = core + axis * d_core_fi;
20  double d_station_fi = (sPosition - fiPosition).Mag();
21  return d_station_fi;
22  }
23 
24  // compute the time difference between the arrival of the plane and curved shower front (see GAP 2013-105, fig. 4.17)
25  double getFirstParticleArrivalTime(double r, double dx0)
26  {
27  //computes the delay referred to the plane front time
28  //dist is given in SP coordinates.
29  double a = 1. / (2 * utl::kSpeedOfLight); // just using a sphere that travels with the speed of light
30  return a * (r * r / dx0);
31  }
32 
33  // mean reconstructed Xmax bias = f(theta, log10(E))
34  // derived from continuous library of QGSJetII-03 (mean of p+Fe)
35  // CORSIKA showers from
36  // http://augerdb.lal.in2p3.fr:8080/augerdb/simdb/Library-en.do?libraryId=11963710
37  // http://augerdb.lal.in2p3.fr:8080/augerdb/simdb/Library-en.do?libraryId=9136660
38  // see GAP 2013-105, fig. 6.6
39  double getMeanXmaxBias(double loge, double theta, bool saturated)
40  {
41  double bias = 0.;
42  if (saturated)
43  bias = -1.655868e+03 + 8.171344e+01 * loge + 3.401878e+01 * theta;
44  else
45  bias = -9.512000e+02 + 4.997809e+01 * loge + -4.301163e+01 * theta;
46 
47  return bias * gpercm2;
48  }
49 
50 
51 
52  // parametrization of the mean Xmax from simulations
53  // mean of proton and iron, used as starting value for the Xmax(SD) reconstruction
54  double getMeanParametrizedXmax(double loge)
55  {
56 
57  double xmax_proton, xmax_iron;
58  {
59  // proton QGSJet II-03
60  const double p0 = 7.36508298967330802e+02;
61  const double p1 = 4.89094109886878101e+01;
62  const double p2 = -2.27145404084728142e+00;
63  xmax_proton = (p0 + p1 * (loge - 18) + p2 * pow(loge - 18, 2)) * gpercm2;
64  }
65  {
66  // iron QGSJet II-03
67  const double p0 = 6.45205996945714332e+02;
68  const double p1 = 5.76560096429448592e+01;
69  const double p2 = -3.60856107551782701e+00;
70  xmax_iron = (p0 + p1 * (loge - 18) + p2 * pow(loge - 18, 2)) * gpercm2;
71  }
72 
73  return (xmax_proton + xmax_iron) / 2.;
74  }
75 
76  // fit to data from long Xmax paper 2014 (phys rev D 90, 122005 (2014))
77  double getMeanParametrizedXmaxData(double loge)
78  {
79  double meanxmax;
80 
81  const double logE0 = 18.27, Xmax0 = 746.8, ER0 = 86.4, ER1 = 26.4;
82 
83  if (loge < logE0)
84  meanxmax = Xmax0 + (loge - logE0) * ER0;
85  else
86  meanxmax = Xmax0 + (loge - logE0) * ER1;
87 
88  return meanxmax;
89  }
90 
91  // parameterized with golden hybrids from 2004 - 2014
92  double getMeanParametrizedNmuData(double loge, double theta)
93  {
94  // const double pars[3] = {2.18275629, 0.07113437, 0.37852463};
95  const double pars[3] = {2.12606249, 0.09410723, 0.29323277};
96 
97  return pars[0] + pars[1] * (loge - 19.) + pars[2] * (1. / cos(theta) - 2);
98  }
99 
100  double getMeanParametrizedNmuData(double loge, double theta, double Xmax)
101  {
102  // const double pars[2] = {2.29841005e-01, 7.57069565e+02}; // uncs: 0.35998355, 3.05089875
103  // const double pars[2] = {9.43590516e-02, 7.56011955e+02}; // uncs: 0.35998355, 3.05089875
104  const double pars[2] = {41.10517485, 756.92655277}; // uncs: 0.35974395, 3.07881652
105 
106  const double mval = getMeanParametrizedNmuData(loge, theta);
107  const double xmaxval = (1 + 0.5 / M_PI * atan((pars[0] * loge - Xmax) / 40.)) /
108  (1 + 0.5 / M_PI * atan((pars[0] * loge - pars[1]) / 40.));
109  return mval * xmaxval;
110  }
111 
112  // adapted from Maximo
113  double GetMeanMuonOffsetDataCalibrated(double r, double lgE, double theta)
114  {
115  // double OffsetM_Mu[3] = {0.06579588, 0.04701472, 0.11184198}; // uncs: 0.0467337, 0.03512474, 0.06394015
116  double OffsetM_Mu[3] = {0.04308893, 0.0284907, 0.08383378}; // uncs: 0.0467337, 0.03512474, 0.06394015
117 
118  double fOffsetM_Mu = OffsetM_Mu[0] + OffsetM_Mu[1] * (lgE - 19.) + OffsetM_Mu[2] * (1 / cos(theta) - 2.);
119  const double SysPar1 = 2.65;
120 
121  double C = fOffsetM_Mu / (1 - exp(-SysPar1));
122  double mshift = C * (1 - exp(-SysPar1 * r / 2e5));
123 
124  return mshift;
125  }
126 
127  // todo: add pars
128  double
129  GetMeanMuonOffsetMCCalibrated(double /*r*/, double /*lgE*/, double /*theta*/)
130  {
131  // update
132  /*const double OffsetM_Mu[3] = { 0.11, 0., 0. };
133 
134  const double fOffsetM_Mu = OffsetM_Mu[0] + OffsetM_Mu[1] * (lgE - 19) + OffsetM_Mu[2] * (1 / cos(theta) - 2);
135  const double SysPar1 = 2.65;
136 
137  const double C = fOffsetM_Mu / (1 - exp(-SysPar1));
138  double mshift = C * (1 - exp(-SysPar1 * r / 2e5));*/
139 
140  return 0;
141  }
142 
143 
144  double GetMeanMuonOffset(double r, double offset0)
145  {
146  const double SysPar1 = 2.65;
147 
148  double C = offset0 / (1 - exp(-SysPar1));
149  double mshift = C * (1 - exp(-SysPar1 * r / 2e5));
150 
151  return mshift;
152  }
153 
154  // see GAP 2013-105, sec. 5.5
155  double getX0(int version, double xmax, double loge)
156  {
157  // derivation of the X0-Xmax correlation function in x0_xmax_conversion.py
158  // it is done separately for fixed energies.
159  // The parameters are interpolated linearly in loge
160 
161  // The available configurations are:
162  // 0: qgsjet, p + Fe
163  // 1: epos, p + Fe
164  // 2: qgsjet + epos, p + Fe
165  // 3: qgsjet photons
166  // 4: qgsjet, p
167  // 5: epos, p
168 
169  const int nModels = 6;
170 
171  if (version < 0 || version > nModels - 1) {
172  cout << "################\nbad version for x0-xmax correlation\n################\n";
173  return 0;
174  }
175 
176  const int nBins = 4;
177  double loges[nBins] = { 1.860000e+01, 1.900000e+01, 1.950000e+01, 2.000000e+01 };
178 
179  const double pars0[nModels][nBins] = {
180  { 6.456017e+02, 6.469736e+02, 6.489524e+02, 6.476612e+02 },
181  { 6.453341e+02, 6.485834e+02, 6.501094e+02, 6.492983e+02 },
182  { 6.445297e+02, 6.474811e+02, 6.491586e+02, 6.502373e+02 },
183  { 6.432335e+02, 6.522376e+02, 6.632606e+02, 6.955606e+02 },
184  { 6.474369e+02, 6.502122e+02, 6.488559e+02, 6.493190e+02 },
185  { 6.542931e+02, 6.521569e+02, 6.479219e+02, 6.500125e+02 }
186  };
187 
188  const double pars1[nModels][nBins] = {
189  { 1.616533e-03, 1.444867e-03, 1.252005e-03, 1.582818e-03 },
190  { 8.559603e-04, 1.039581e-03, 7.401688e-04, 8.037290e-04 },
191  { 1.029642e-03, 1.117932e-03, 1.046979e-03, 9.735569e-04 },
192  { 1.036600e-03, 9.843582e-04, 2.213315e-04, 2.842102e-04 },
193  { 1.960041e-03, 1.456550e-03, 1.139915e-03, 1.162492e-03 },
194  { 1.178549e-03, 8.926028e-04, 1.382968e-03, 1.341381e-03 }
195  };
196 
197  const double pars2[nModels][nBins] = {
198  { 4.319217e+00, 2.778060e+00, 1.106250e+00, 5.520477e+00 },
199  { 3.101907e+00, 1.945493e+00, -3.072746e+00, -2.944935e+00 },
200  { 3.807706e+00, 2.476609e+00, 9.049038e-01, 1.516479e+00 },
201  { -1.954682e+01, 1.482052e+01, -4.562288e+01, 4.857960e+01 },
202  { 5.610586e+00, 9.524124e-01, -2.232481e+00, -1.119290e+00 },
203  { -5.986844e+00, -1.302564e+01, 9.704845e-01, 3.654311e+00 }
204  };
205 
206  const double pars3[nModels][nBins] = {
207  { 1.021706e-01, 5.903550e-02, 2.015838e-02, -1.283983e-01 },
208  { 1.533218e-01, 6.349976e-02, 7.258369e-02, 3.835097e-03 },
209  { 1.374037e-01, 7.072211e-02, 2.301778e-02, -2.622843e-02 },
210  { -7.461706e-02, -2.455179e-01, 1.211286e-01, -1.878918e-01 },
211  { 5.551634e-02, 7.942683e-02, 6.273052e-02, -1.132578e-02 },
212  { 2.103373e-01, 1.940762e-01, -8.057426e-02, -1.497254e-01 }
213  };
214 
215  xmax /= utl::gram / utl::cm2;
216  double x0;
217 
218  double p0 = UnivTimeKG::int1(loges, pars0[version], loge, nBins);
219  double p1 = UnivTimeKG::int1(loges, pars1[version], loge, nBins);
220  double p2 = UnivTimeKG::int1(loges, pars2[version], loge, nBins);
221  double p3 = UnivTimeKG::int1(loges, pars3[version], loge, nBins);
222 
223  double xmin = p0 - p3 / (2.*p1);
224  double ymin = p2 + p3 * (xmin - p0) + p1 * pow(xmin - p0, 2);
225 
226  if (xmax < xmin)
227  x0 = ymin;
228  else
229  x0 = p2 + p3 * (xmax - p0) + p1 * pow(xmax - p0, 2);
230 
231  if (std::isnan(x0) || x0 < 0) x0 = 0;
232  return x0 * (utl::gram / utl::cm2);
233  }
234 }
235 
double getDistToFirstInteraction(double hfi, double sHeight, double zenith, double dist, double psi)
Definition: FitterUtil.cc:12
double getMeanParametrizedXmaxData(double loge)
Definition: FitterUtil.cc:77
double pow(const double x, const unsigned int i)
double getX0(int version, double xmax, double loge)
Definition: FitterUtil.cc:155
double getMeanParametrizedXmax(double loge)
Definition: FitterUtil.cc:54
double int1(const vector< double > &xs, const vector< double > &ys, const double x)
Definition: UnivTimeKG.cc:70
double getFirstParticleArrivalTime(double r, double dx0)
Definition: FitterUtil.cc:25
double getMeanParametrizedNmuData(double loge, double theta)
Definition: FitterUtil.cc:92
double GetMeanMuonOffsetDataCalibrated(double r, double lgE, double theta)
Definition: FitterUtil.cc:113
double getMeanXmaxBias(double loge, double theta, bool saturated)
Definition: FitterUtil.cc:39
double GetMeanMuonOffset(double r, double offset0)
Definition: FitterUtil.cc:144
constexpr double kSpeedOfLight
double GetMeanMuonOffsetMCCalibrated(double, double, double)
Definition: FitterUtil.cc:129
constexpr double gram
Definition: AugerUnits.h:195
const double gpercm2
Definition: FitterUtil.h:9
static const int nModels
constexpr double cm2
Definition: AugerUnits.h:118

, generated on Tue Sep 26 2023.