CherenkovModel.cc
Go to the documentation of this file.
1 /*
2  \file
3  Implementation of CherenkovModel
4 
5  \autor Diego Melo.
6  \date 18 Dic 2003
7 */
8 
9 
10 #include <iostream>
11 #include <string>
12 #include <vector>
13 
14 #include <fwk/CentralConfig.h>
15 
16 #include <utl/Vector.h>
17 #include <utl/AugerUnits.h>
18 #include <utl/MathConstants.h>
19 #include <utl/PhysicalConstants.h>
20 
21 #include <det/Detector.h>
22 
23 #include <atm/Atmosphere.h>
24 #include <atm/CherenkovModel.h>
25 #include <atm/AttenuationResult.h>
26 
27 using namespace std;
28 using namespace fwk;
29 using namespace utl;
30 using namespace det;
31 using namespace atm;
32 
33 
34 CherenkovModel::CherenkovModel()
35 { }
36 
37 
38 // Gaisser-Hillas
39 double
40 CherenkovModel::GaisserHillas(const double chi, const double chi0, const double chimax, const double Nmax, const double lambda)
41  const
42 {
43  if (chi < chi0)
44  return 0;
45 
46  const double x = (chi - chi0) / (chimax - chi0);
47  const double p = (chimax - chi0) / lambda;
48  const double q = (chimax - chi) / lambda;
49  return Nmax * std::pow(x, p) * std::exp(q);
50 }
51 
52 
53 // Energy(beta)
54 double
55 CherenkovModel::Energy(const double beta)
56  const
57 {
58  return utl::ElectronMass/std::sqrt(1 - beta*beta);
59 }
60 
61 
62 // Beta(energy)
63 double
64 CherenkovModel::Beta(const double energy)
65  const
66 {
67  const double gammaInv = utl::ElectronMass / energy;
68  return std::sqrt(1 - gammaInv*gammaInv);
69 }
70 
71 
72 // Threshold de Energia Cherenkov.
73 double
74 CherenkovModel::CKVThreshold(const double nIndex)
75  const
76 {
77  return utl::ElectronMass / std::sqrt(1 - 1 / (nIndex * nIndex));
78 }
79 
80 
81 // Distance between two points (m)
82 double
83 CherenkovModel::Distance(const double x1[], const double x2[])
84  const
85 {
86  double d2 = 0;
87 
88  for (int k = 0; k < 3; ++k) {
89  const double dx = x1[k] - x2[k];
90  d2 += dx * dx;
91  }
92 
93  return std::sqrt(d2);
94 }
95 
96 
97 // Distance between two points (g/cm2).
98 double
99 CherenkovModel::GDistance(const double x1[], const double x2[])
100  const
101 {
102  double gdistance = 0;
103  const double chi1 = det::Detector::GetInstance().GetAtmosphere().EvaluateDepth(x1[2]);
104  const double chi2 = det::Detector::GetInstance().GetAtmosphere().EvaluateDepth(x2[2]);
105 
106  if (x1[2] != x2[2])
107  return Distance(x1, x2) * std::abs((chi1 - chi2) / (x1[2] - x2[2]));
108  if (x1[2] <= 12*utl::km)
109  return Distance(x1, x2) * std::abs(chi1 / (0.19*(44340 - x1[2])));
110  if (x1[2] <= 45.470*utl::km)
111  return Distance(x1, x2) * std::abs(chi1 / (6.340*utl::km));
112  return 0;
113 }
114 
115 
116 // Hillas -J.Phys G: Nucl. Phys. 8, p1461, 1982-
117 double
118 CherenkovModel::TrackLengthH(const double energy, const double chi, const double chimax)
119  const
120 {
121  const double s = 3 / (1 + 2*chimax/chi);
122  const double e0 = (s < 0.4) ? 26 : 44 - 17*std::pow(s - 1.46, 2);
123 
124  return std::pow((0.89*e0 - 1.20) / (e0 + energy), s) / std::pow(1 + 1e-4 * s * energy, 2);
125 }
126 
127 
128 // Nerling -Malargue Nov. 2003-
129 double
130 CherenkovModel::TrackLengthN(const double energy, const double chi, const double chimax)
131  const
132 {
133  const double s = 3 / (1 + 2*chimax/chi);
134 
135  const double a0 = 102.24; //Estimacion por el momento !!!!
136  const double a1 = 6.425 - 1.532 * s;
137  const double a2 = 168.13 - 42.14 * s;
138 
139  return a0 / ((energy + a1)*std::pow(energy + a2, s));
140 }
141 
142 
143 // Fotones Cherenkov Producidos por una unica Particula de Energia E
144 double
145 CherenkovModel::CKVPhot(const double trl, const double nIndex, const double beta, const double dl, const double l1, const double l2)
146  const
147 {
148  const double cte = 2*utl::kPi * utl::Alpha;
149 
150  return cte * trl * std::abs(1/l1 - 1/l2) * (1 - 1/std::pow(beta*nIndex, 2)) * dl;
151 }
152 
153 
154 // Funcion Auxiliar Empleada para Integrar la Luz Cherenkov
155 double
156 CherenkovModel::Fu(const double x, const double a)
157  const
158 {
159  return std::exp(-x/a) * std::sin(x);
160 }
161 
162 
163 // Integral Angular Light Cherenkov
164 void
165 CherenkovModel::CKVIntegral(const double xlo, const double xhi, const double xb, double& integral)
166  const
167 {
168  double s2 = 0;
169 
170  double suma = Fu(xlo, xb);
171  const double step = (xhi - xlo) / 10;
172 
173  for (int i = 1; i <= 5; ++i) {
174  const double a1 = xlo + (2*i - 1)*step;
175  const double a2 = a1 + step;
176 
177  const double s1 = 4 * Fu(a1, xb);
178  s2 = 2 * Fu(a2, xb);
179 
180  suma += s1 + s2;
181  }
182 
183  integral = (suma - s2/2) * step / 3;
184 }
185 
186 
187 // Cherenkov Directo
188 void
189 CherenkovModel::CKVDirect(const double bin, const double theta, const double height, const double rp, const double chimax, std::vector<double>& dirCh)
190  const
191 {
192  std::vector<double> nphot(kN_WAVE_BIN);
193  std::vector<double> ophot(kN_WAVE_BIN);
194  double h1;
195  double h2;
196 
197  for (int w = 0; w < kN_WAVE_BIN; ++w) {
198  //nphot[w] = 0;
199  //ophot[w] = 0;
200  dirCh[w] = 0;
201  }
202 
203  double th1 = theta - bin/2;
204  if (th1 <= 0)
205  th1 = theta/2;
206 
207  const double th2 = theta + bin/2;
208 
209  const double dl = rp * std::abs(1 / std::tan(th1) - 1 / std::tan(th2));
210 
211  const double a = 0.83;
212  const double b = -0.67;
213 
214  const double chi = det::Detector::GetInstance().GetAtmosphere().EvaluateDepth(height);
215  const double nIndex = det::Detector::GetInstance().GetAtmosphere().EvaluateRefractionIndex(height);
216 
217  const double em = min(CKVThreshold(nIndex), 2e3);
218 
219  const double th0 = a * std::pow(em, b);
220 
221  // Integrate in Theta
222  double integral = 0;
223  CKVIntegral(th1, th2, th0, integral);
224 
225  // Normalizes Integral
226  const double norm = integral / th0;
227 
228  // Integrate in Energy
229  const double dE = 10;
230 
231  // From Threshold to Ultrarelativistic "E = 361.33 <---> beta = 1 - 1e-6"
232  double jmax = 361.33;
233 
234  double lambda = 0;
235  for (double j = em; j <= jmax; j += dE) {
236  const double tl1 = TrackLengthN(j, chi, chimax);
237  const double tl2 = TrackLengthN(j+dE, chi, chimax);
238 
239  const double aux1 = tl1 - tl2;
240  const double aux2 = j + dE/2;
241  const double aux3 = Beta(aux2);
242  lambda = kWAVE_MIN - kWAVE_STEP/2;
243 
244  for (int w = 0; w < kN_WAVE_BIN; ++w) {
245  lambda += kWAVE_STEP;
246  const double aux4 = lambda - kWAVE_STEP/2;
247  const double aux5 = lambda + kWAVE_STEP/2;
248 
249  nphot[w] = CKVPhot(aux1, nIndex, aux3, dl, aux4, aux5) + ophot[w];
250  ophot[w] = nphot[w];
251  }
252 
253  jmax = j;
254  }
255 
256  // Add Ultrarelativistic Energy Contribution "beta = 1.0"
257  lambda = kWAVE_MIN - kWAVE_STEP/2;
258  const double aux1 = TrackLengthN(jmax, chi, chimax);
259  const double aux3 = 1;
260 
261  for (int w = 0; w < kN_WAVE_BIN; ++w) {
262  lambda += kWAVE_STEP;
263  const double aux4 = lambda - kWAVE_STEP/2;
264  const double aux5 = lambda + kWAVE_STEP/2;
265 
266  nphot[w] = CKVPhot(aux1, nIndex, aux3, dl, aux4, aux5) + ophot[w];
267  }
268 
269  // Area of Annulus on Ground
270  const double dA = 2*utl::kPi * rp*rp * bin;
271 
272  for (int w = 0; w < kN_WAVE_BIN; ++w)
273  dirCh[w] = nphot[w] * norm / dA;
274 }
275 
276 
277 // Cherenkov Beam
278 void
279 CherenkovModel::CKVBeam(const double h1, const double h2, const double theta, const double chimax, std::vector<double>& beamCh)
280  const
281 {
282  std::vector<double> nphot(kN_WAVE_BIN);
283  std::vector<double> ophot(kN_WAVE_BIN);
284  double chimed;
285  double em;
286  double lambda;
287 
288  for (int w = 0; w < kN_WAVE_BIN; ++w) {
289  //nphot[w] = 0;
290  //ophot[w] = 0;
291  beamCh[w] = 0;
292  }
293 
294  const double chi1 = det::Detector::GetInstance().GetAtmosphere().EvaluateDepth(h1);
295  const double chi2 = det::Detector::GetInstance().GetAtmosphere().EvaluateDepth(h2);
296 
297  const double dl = std::abs(h2 - h1) / std::cos(theta);
298 
299  const double nIndex = det::Detector::GetInstance().GetAtmosphere().EvaluateRefractionIndex((h1 + h2) / 2);
300 
301  const double em = min(CKVThreshold(n_index), 2e3);
302 
303  // Integrate in Energy
304  const double dE = 10;
305 
306  // From Threshold to Ultrarelativistic "E = 361.33 <---> beta = 1 - 1e-6"
307  double jmax = 361.33;
308 
309  const double aux1 = (chi1 + chi2) / 2;
310 
311  for (double j = em; j <= jmax; j += dE) {
312  const double tl1 = TrackLengthN(j, aux1, chimax);
313  const double tl2 = TrackLengthN(j+dE, aux1, chimax);
314 
315  const double aux2 = tl1 - tl2;
316  const double aux3 = j + dE/2;
317  const double aux4 = Beta(aux3);
318  lambda = kWAVE_MIN - kWAVE_STEP/2;
319 
320  for (int w = 0; w < kN_WAVE_BIN; ++w) {
321  lambda += kWAVE_STEP;
322  const double aux5 = lambda - kWAVE_STEP/2;
323  const double aux6 = lambda + kWAVE_STEP/2;
324 
325  nphot[w] = CKVPhot(aux2, nIndex, aux4, dl, aux5, aux6) + ophot[w];
326  ophot[w] = nphot[w];
327  }
328 
329  jmax = j;
330  }
331 
332  // Add Ultrarelativistic Energy Contribution "beta = 1.0"
333  lambda = kWAVE_MIN - kWAVE_STEP/2;
334  const double aux2 = TrackLengthN(jmax, aux1, chimax);
335  const double aux4 = 1;
336 
337  for (int w = 0; w < kN_WAVE_BIN; ++w) {
338  lambda += kWAVE_STEP;
339  const double aux4 = lambda - kWAVE_STEP/2;
340  const double aux5 = lambda + kWAVE_STEP/2;
341 
342  nphot[w] = CKVPhot(aux2, nIndex, aux4, dl, aux5, aux6) + ophot[w];
343  }
344 
345  for (int w = 0; w < kN_WAVE_BIN; ++w)
346  beamCh[w] = nphot[w];
347 }
348 
349 
350 // Cherenkov Rayleigh
351 void
352 CherenkovModel::CKVRayleigh(const double h1, const double h2, const double theta, const double rr, std::vector<double>& rayCh)
353  const
354 {
355  std::vector<double> lambda(kN_WAVE_BIN);
356 
357  const double aux = kWAVE_MIN - kWAVE_STEP/2;
358 
359  for (int w = 0; w < kN_WAVE_BIN; ++w)
360  lambda[w] += aux + kWAVE_STEP;
361 
362  const CoordinateSystemPtr cs = det::Detector::GetInstance().GetSiteCoordinateSystem();
363 
364  const Point p1(0, 0, h1, cs);
365  const Point p2(0, 0, h2, cs);
366 
367  AttenuationResult AttRes =
368  det::Detector::GetInstance().GetAtmosphere().EvaluateRayleighAttenuation(p1, p2, lambda);
369 
370  const vector<double> attenuationVector = AttRes.GetTransmissionFactor();
371 
372  const double anfc = 1 + std::pow(std::cos(theta), 2);
373  const double factor = 3 / (16*utl::kPi) * anfc / (rr*rr);
374  for (int wl = 0; wl < kN_WAVE_BIN; ++wl) {
375  const double probScat = 1 - attenuationVector[wl];
376  rayCh[wl] = factor * probScat;
377  }
378 }
379 
380 
381 // Cherenkov Aerosol
382 void
383 CherenkovModel::CKVAerosol(const double h1, const double h2, const double theta, const double rr, std::vector<double>& aerCh)
384  const
385 {
386  const double a = 0.8;
387  const double thM = 26.7*utl::degree;
388 
389  std::vector<double> lambda(kN_WAVE_BIN);
390 
391  const double aux = kWAVE_MIN - kWAVE_STEP/2;
392 
393  for (int w = 0; w < kN_WAVE_BIN; ++w)
394  lambda[w] += aux + kWAVE_STEP;
395 
396  const CoordinateSystemPtr cs = det::Detector::GetInstance().GetSiteCoordinateSystem();
397 
398  const Point p1(0, 0, h1, cs);
399  const Point p2(0, 0, h2, cs);
400 
401  AttenuationResult AttRes =
402  det::Detector::GetInstance().GetAtmosphere().EvaluateMieAttenuation(p1, p2, lambda);
403 
404  const vector<double> attenuationVector = AttRes.GetTransmissionFactor();
405 
406  const double factor = a * std::exp(-theta/thM) / (rr*rr);
407  for (int wl = 0; wl < kN_WAVE_BIN; ++wl) {
408  const double prob_scat = 1 - attenuationVector[wl];
409  aerCh[wl] = factor * prob_scat;
410  }
411 }
Point object.
Definition: Point.h:32
double Energy(const double beta)
Calculate the electron energy for a relativistic beta.
constexpr double km
Definition: AugerUnits.h:125
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
double pow(const double x, const unsigned int i)
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
constexpr double s
Definition: AugerUnits.h:163
constexpr double kPi
Definition: MathConstants.h:24
double abs(const SVector< n, T > &v)
constexpr double degree
double Beta(const double energy)
Calculate the electron energy versus the relativistic beta.
double GaisserHillas(const double x, const double x0, const double xMax, const double nMax, const double lambda)
Calculate the Gaisser-Hillas function.
double Distance(const Point &p, const sdet::Station &s)
double norm(utl::Vector x)
Class describing the Atmospheric attenuation.

, generated on Tue Sep 26 2023.