ParametricMuonProfile.cc
Go to the documentation of this file.
2 #include "IndexProcessor.h"
3 
4 #include <utl/MathConstants.h>
5 #include <utl/AugerUnits.h>
6 #include <utl/Branch.h>
7 
8 #include <cmath>
9 #include <string>
10 #include <iostream>
11 
12 using namespace ParametricMuonProfileNS;
13 using namespace utl;
14 using namespace std;
15 using namespace tls;
16 
18  ModelDataType& tensor,
19  LocalDataType& tensorLocal) const
20 {
21  std::vector<size_t> extent;
22  modelBranch.GetChild("matrixExtension").GetData(extent);
23 
24  tensor.resize(extent);
25  tensorLocal.resize(extent);
26 
27  std::vector<double> data;
28  modelBranch.GetChild("data").GetData(data);
29 
30  IndexProcessor<6> ip(extent);
31  size_t kjvmlu[6];
32  for (size_t i=0,ii=0; i < tensor.num_elements(); ++i)
33  {
34  tensor.data()[i] = 0;
35  ip.Delinearize(i, kjvmlu);
36  // skip coefficients which are multiplied with zero in expansion
37  if ( (kjvmlu[1]==0 && kjvmlu[2]==1) || (kjvmlu[4]==0 && kjvmlu[5]==1) )
38  continue;
39  tensor.data()[i] = data[ii];
40  ++ii;
41  }
42 }
43 
44 
46  fTheta(0.), fPhi(0.), fEnergy(10.*EeV), fBPsi(0.)
47 {
48  topBranch.GetChild("thetaRange").GetData(fThetaRange);
49  topBranch.GetChild("radiusMax").GetData(fSqrtRadiusMax);
51 
52  topBranch.GetChild("dModel").GetData(fDMaxData);
53 
54  topBranch.GetChild("nMuModel").GetData(fNMuData);
55 
56  Branch b;
57  std::vector<double> data;
58 
59  b = topBranch.GetChild("nMuTankModel");
60  b.GetChild("biasCorrectionFactor").GetData(fBiasCorrection[eNMuTank]);
61  ReadModelData(b, fModelData[eNMuTank], fLocalData[eNMuTank]);
62 
63  b = topBranch.GetChild("cosThetaModel");
64  b.GetChild("biasCorrectionFactor").GetData(fBiasCorrection[eCosTheta]);
65  ReadModelData(b, fModelData[eCosTheta], fLocalData[eCosTheta]);
66 
67  b = topBranch.GetChild("logEnergyModel");
68  b.GetChild("biasCorrectionFactor").GetData(fBiasCorrection[eLogEnergy]);
69  ReadModelData(b, fModelData[eLogEnergy], fLocalData[eLogEnergy]);
70 }
71 
72 
73 double ParametricMuonProfile::D(double theta) const
74 {
75  /* Original analytical function was expanded (approximated) in a series of
76  Chebyshev polynomials. Evaluation uses Clenshaw's recurrence formula
77  with following recursion for Chebyshev polynomials T[n](z):
78  T[n+1](z) = 2 z T[n](z) - T[n-1](z) */
79 
80  const unsigned int n = fDMaxData.size();
81  const double z = 2*theta/(0.5*kPi)-1.0;
82  double d = 0.0;
83  double dd = 0.0;
84  for (unsigned int i=n-1;i!=0;--i)
85  {
86  const double sv = d;
87  d = 2*z*d - dd + fDMaxData[i];
88  dd = sv;
89  }
90  return z*d + 0.5*fDMaxData[0] - dd;
91 }
92 
93 
94 double ParametricMuonProfile::TotalMuonNumber(double theta, double energy) const
95 {
96  const double lgE = log10(energy/EeV);
97  const double lgD = log10(D(theta));
98  return pow(10.,fNMuData[0]+fNMuData[1]*lgE+fNMuData[2]*lgD);
99 }
100 
101 
102 double ParametricMuonProfile::EvaluateProfile(ProfileType type, double x, double y,
103  double theta, double phi, double energy)
104 {
105  CachedSetProfile(theta,phi,energy);
106 
107  // translate ground to shower plane coordinates
108  double sqr = sqrt( rPerpendicular( x, y, theta, phi)/meter );
109  const double zeta = PsiPerpendicular( x, y, theta, phi ) - fBPsi + 0.5*kPi;
110 
111  double result = 0.0;
112 
113  switch(type)
114  {
115  case eNMuTank:
116  if (sqr > fSqrtRadiusMax)
117  { // extrapolation with formula ln N_\mu = a + b sqrt{r}
118  const double a = EvaluateLocalProfile(eNMuTank, fSqrtRadiusMax, zeta);
119  const double b = ( a - EvaluateLocalProfile(eNMuTank, fSqrtRadiusMax*0.95, zeta) )
120  /(0.05*fSqrtRadiusMax);
121  result = fNMuonNumber
123  *pow(10., a + b*(sqr-fSqrtRadiusMax));
124  }
125  else
126  result = fNMuonNumber
128  *pow(10., EvaluateLocalProfile(eNMuTank, sqr, zeta));
129  break;
130 
131  case eCosTheta:
132  if (sqr > fSqrtRadiusMax) sqr = fSqrtRadiusMax;
133  result = fBiasCorrection[eCosTheta]
134  *EvaluateLocalProfile(eCosTheta, sqr, zeta);
135  if (result < 0) result = 0.0;
136  if (result > 1) result = 1.0;
137  result = acos(result);
138 
139  break;
140 
141  case eLogEnergy:
142  if (sqr > fSqrtRadiusMax) sqr = fSqrtRadiusMax;
143  result = fBiasCorrection[eLogEnergy]
144  *pow(10.,EvaluateLocalProfile(eLogEnergy, sqr, zeta))*GeV;
145  break;
146  }
147 
148  return result;
149 }
150 
151 
152 double ParametricMuonProfile::EvaluateLocalProfile(ProfileType type, double sqr, double zeta) const
153 {
154  double result = 0.0;
155 
156  for (size_t k=0; k < fLocalData[type].shape()[0]; ++k)
157  for (size_t j=0; j < fLocalData[type].shape()[1]; ++j)
158  for (size_t v=0; v < 2; ++v)
159  {
160  // skip coefficients which are multiplied with zero in expansion
161  if (j==0 && v==1) continue;
162 
163  if (v==0)
164  result += fLocalData[type][k][j][v]*pow(sqr, int(k))*cos(j*zeta);
165  else
166  result += fLocalData[type][k][j][v]*pow(sqr, int(k))*sin(j*zeta);
167  }
168 
169  return result;
170 }
171 
172 
174 {
175  const double dmax = D(90*degree);
176  const double dmin = D(0);
177  const double zA = 2*(D(fTheta)-dmin)/(dmax-dmin)-1;
178  const double zB = 2*(fTheta/degree-60)/28-1;
179 
180  for (int iType=0;iType<3;++iType)
181  for (size_t k=0; k<fModelData[iType].shape()[0]; ++k)
182  for (size_t j=0; j<fModelData[iType].shape()[1]; ++j)
183  for (size_t v=0; v<2; ++v)
184  {
185  fLocalData[iType][k][j][v] = 0;
186  for (size_t m=0; m<fModelData[iType].shape()[3]; ++m)
187  for (size_t l=0; l<fModelData[iType].shape()[4]; ++l)
188  for (size_t u=0; u<2; ++u)
189  {
190  // skip coefficients which are multiplied with zero in expansion
191  if ( (j==0 && v==1) || (l==0 && u==1) ) continue;
192  const double z = iType == 0? zA : zB;
193  if (u == 0)
194  fLocalData[iType][k][j][v] += fModelData[iType][k][j][v][m][l][u]*pow(z, (double)m )*cos(l*fPhi);
195  else
196  fLocalData[iType][k][j][v] += fModelData[iType][k][j][v][m][l][u]*pow(z, (double)m )*sin(l*fPhi);
197  }
198  }
199 }
200 
201 
203 
204 
const double degree
void ReadModelData(const utl::Branch &modelBranch, ModelDataType &tensor, LocalDataType &tensorLocal) const
const double meter
Definition: GalacticUnits.h:29
double rPerpendicular(const double xpos, const double ypos, const double theta, const double phi)
radial distance in shower front plane coordinate system
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)
const double EeV
Definition: GalacticUnits.h:34
double TotalMuonNumber(double theta, double energy) const
Class representing a document branch.
Definition: Branch.h:107
double EvaluateProfile(ProfileType type, double x, double y, double theta, double phi, double energy)
constexpr double kPi
Definition: MathConstants.h:24
const Data result[]
double GetThetaMax()
Maximum zenith angle, at which the tank response function is defined.
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
double PsiPerpendicular(const double xpos, const double ypos, const double theta, const double phi)
polar angle in shower front plane coordinate system
constexpr double GeV
Definition: AugerUnits.h:187
uint16_t * data
Definition: dump1090.h:228
double GetThetaMin()
Minimum zenith angle, at which the tank response function is defined.
void CachedSetProfile(double theta, double phi, double energy)
double EvaluateLocalProfile(ProfileType type, double sqr, double zeta) const
constexpr double m
Definition: AugerUnits.h:121

, generated on Tue Sep 26 2023.