LateralLightCalculator.cc
Go to the documentation of this file.
2 #include "TelescopeData.h"
3 //#warning MU move OpticalHalo to FDetector
4 #include "../FdProfileReconstructorKG/OpticalHalo.h"
5 
6 #include <fwk/CentralConfig.h>
7 #include <utl/Reader.h>
8 #include <utl/ErrorLogger.h>
9 #include <utl/PhysicalFunctions.h>
10 #include <utl/Point.h>
11 #include <utl/Integrator.h>
12 #include <utl/TabulatedFunction.h>
13 #include <det/Detector.h>
14 #include <fdet/Telescope.h>
15 #include <atm/Atmosphere.h>
16 #include <atm/ProfileResult.h>
17 #include <atm/AttenuationResult.h>
18 #include <atm/ScatteringResult.h>
19 #include <atm/InclinedAtmosphericProfile.h>
20 
21 #include <string>
22 #include <sstream>
23 using namespace std;
24 using namespace utl;
25 using namespace fdet;
26 using namespace fevt;
27 using namespace atm;
28 using namespace FdEnergyDepositFinderKG;
29 
30 
32 
33 public:
34  ScattCherFunctor(const double distanceToTelescope,
35  const double distanceAlongShower,
36  const double showerAge,
37  const double verticalDepth,
38  const TabulatedFunction& arcLengthFunction) :
39  fDistanceToTelescope(distanceToTelescope),
40  fDistanceAlongShower(distanceAlongShower),
41  fShowerAge(showerAge),
42  fVerticalDepth(verticalDepth),
43  fArcLengthFunction(arcLengthFunction),
44  fSmallAngleApprox(false)
45  { }
46 
47  double
48  operator()(const double zeta)
49  const
50  {
51  const double distanceRatio = fDistanceToTelescope / fDistanceAlongShower;
52  const auto& atmo = det::Detector::GetInstance().GetAtmosphere();
53 
54  double pdf;
55  double jacobian;
56 
57  if (fSmallAngleApprox) {
58 
59  const double theta = zeta * distanceRatio;
60  jacobian = distanceRatio;
61  pdf = atmo.AngularCherenkovPDF(theta, fVerticalDepth, fShowerAge);
62 
63  } else {
64 
65  const double cosZeta = cos(zeta);
66  const double sinZeta = sin(zeta);
67  const double tanZeta = sinZeta / cosZeta;
68 
69  const double cosZeta2 = cosZeta * cosZeta;
70  const double sinZeta2 = sinZeta * sinZeta;
71  const double theta = atan(tanZeta * distanceRatio);
72  jacobian = 1 / (cosZeta2/distanceRatio + distanceRatio*sinZeta2);
73  pdf = atmo.AngularCherenkovPDF(theta, fVerticalDepth, fShowerAge);
74 
75  }
76 
77  const double arcLength = fArcLengthFunction.Y(zeta);
78 
79  return pdf * jacobian * arcLength;
80  }
81 
82 private:
83  double fDistanceToTelescope = 0;
84  double fDistanceAlongShower = 0;
85  double fShowerAge = 0;
86  double fVerticalDepth = 0;
88  bool fSmallAngleApprox = false;
89 
90 };
91 
92 
94 
95 public:
96  FluorescenceFunctor(const double showerAge,
97  const double distance,
98  const double moliereRadius,
99  const TabulatedFunction& arcLengthFunction):
100  fShowerAge(showerAge),
101  fDistance(distance),
102  fMoliereRadius(moliereRadius),
103  fArcLengthFunction(arcLengthFunction),
104  fSmallAngleApprox(false)
105  { }
106 
107  double
108  operator()(const double zeta)
109  const
110  {
111  const double age = fShowerAge;
112  const double d = fDistance;
113  const double rM = fMoliereRadius;
114  const double distanceRatio = d / rM;
115 
116  double pdf;
117  double jacobian;
118  if (fSmallAngleApprox) {
119  jacobian = distanceRatio;
120  pdf = GoraPDF(zeta * distanceRatio, age);
121  } else {
122  const double tanZeta = tan(zeta);
123  const double rStar = distanceRatio * tanZeta;
124  jacobian = distanceRatio*(1 + Sqr(tanZeta));
125  pdf = GoraPDF(rStar, age);
126  }
127 
128  const double arcLength = fArcLengthFunction.Y(zeta);
129 
130  return pdf * jacobian * arcLength;
131  }
132 
133 private:
134  double fShowerAge = 0;
135  double fDistance = 0;
136  double fMoliereRadius = 0;
138  bool fSmallAngleApprox = false;
139 
140 };
141 
142 
143 LateralLightCalculator::LateralLightCalculator() :
144  fPrecision(1e-4),
145  fOpticalHalo(nullptr)
146 {
147  Init();
148 }
149 
150 
152 {
153  delete fOpticalHalo;
154 }
155 
156 
157 void
159 {
160  auto topBranch =
161  fwk::CentralConfig::GetInstance()->GetTopBranch("FdEnergyDepositFinder");
162  auto lldBranch = topBranch.GetChild("lateralLight");
163 
164  ostringstream info;
165 
166  string lldOption;
167  lldBranch.GetChild("method").GetData(lldOption);
168  fMethod = (lldOption == "eCircle") ?
169  eCircle :
170  (lldOption == "eBinByBin") ?
172  info << "\n\t method: " << lldOption;
173 
174  bool lldIsOn;
175  lldBranch.GetChild("fluorescence").GetData(lldIsOn);
177  info << "\n\t lateral fluorescence is "
178  << (lldIsOn ? "on" : "off");
179 
180  lldBranch.GetChild("directCherenkov").GetData(lldIsOn);
182  info << "\n\t lateral direct Cherenkov is "
183  << (lldIsOn ? "on" : "off");
184 
185  lldBranch.GetChild("directCherenkovCorrectedGora").GetData(fDirCherCorrGora);
186  info << "\n\t lateral direct Cherenkov correction for Gora is "
187  << (fDirCherCorrGora ? "on" : "off");
188 
189  lldBranch.GetChild("scatteredCherenkov").GetData(lldIsOn);
192  info << "\n\t lateral scattered Cherenkov is "
193  << (lldIsOn ? "on" : "off");
194 
195  if (lldBranch.GetChild("lateralWidthCorrection").Get<bool>()) {
196  if (fMethod == ePixelIntegrated) {
197  info << "\n\t lateralWidthCorrection in PixelIntegrated mode is "
198  "calculated in the same way as for eCircle option";
199  } else if (fMethod != eCircle) {
200  throw NonExistentComponentException("lateralWidthCorrection can currently"
201  "only be used with eCircle option...");
202  }
203 
204  using namespace FdProfileReconstructorKG;
205  fOpticalHalo = new OpticalHalo(OpticalHalo::eSpotGroup2);
206  }
207  info << "\n\t lateral width correction is "
208  << (fOpticalHalo ? "on" : "off");
209 
210  INFO(info);
211 }
212 
213 
214 double
216  const TelescopeDataBin& emissionBin,
217  const TelescopeDataBin& detectionBin,
218  const fdet::Telescope& telescope,
219  const double xMax,
220  const double cosTheta,
221  const double zeta)
222  const
223 {
224  const auto sourceIter = fLLDIsOn.find(source);
225 
226  if (sourceIter != fLLDIsOn.end()) {
227 
228  if (sourceIter->second) {
229  if (source == FdConstants::eFluorDirect)
230  return FluoLightFraction(detectionBin, telescope, xMax, cosTheta, zeta);
231  else if (source == FdConstants::eCherDirect)
232  return DirCherLightFraction(detectionBin, telescope, xMax, cosTheta, zeta);
233  else if (source == FdConstants::eCherMieScattered ||
235  return ScattCherLightFraction(emissionBin, detectionBin, telescope, xMax, zeta);
236  } else {
237  for (unsigned int i = 0; i < emissionBin.GetZetaPixels().size(); ++i)
238  emissionBin.GetZetaPixels()[i].fLightFraction = emissionBin.GetZetaPixels()[i].IsInside(0, 0);
239  return 1; // option for no ldd
240  }
241  }
242 
243  ostringstream errMsg;
244  errMsg << " source " << source << " not implemented";
245  ERROR(errMsg);
246  throw NonExistentComponentException(errMsg.str());
247 }
248 
249 
250 double
252  const fdet::Telescope& detTel,
253  const double xMax,
254  const double cosTheta,
255  const double zeta)
256  const
257 {
258  if (fMethod == eBinByBin) {
261  else {
262  const string errMsg = "no bin-by-bin efficiency for fluorescence light";
263  ERROR(errMsg);
264  throw NonExistentComponentException(errMsg);
265  }
266  } else {
267  const auto& atmo = det::Detector::GetInstance().GetAtmosphere();
268 
269  const auto& tempProfile = atmo.EvaluateTemperatureVsHeight();
270  const auto& pressureProfile = atmo.EvaluatePressureVsHeight();
271 
272  const double height = telData.fHeight;
273  const double xSlant = telData.GetMeanDepth();
274  const double pressure = pressureProfile.Y(height);
275  const double temperature = tempProfile.Y(height);
276  const double age = ShowerAge(xSlant, xMax);
277  const double rMoliere = MoliereRadius(temperature, pressure, cosTheta);
278 
279  const auto& meanPos = telData.fMeanDepthPoint;
280  const auto& telescopePos = detTel.GetPosition();
281  const double showerTelDist = (meanPos - telescopePos).GetMag();
282  const double distanceToShowerAxis = tan(zeta) * showerTelDist;
283 
284  const double rStar = distanceToShowerAxis / rMoliere;
285 
286  if (fMethod == eCircle || telData.GetZetaPixels().empty()) {
287  const double spotFraction = fOpticalHalo ?
288  fOpticalHalo->GetHaloFraction(zeta, age, showerTelDist) : 1;
289  return GoraCDF(rStar, age) * spotFraction;
290  } else if (fMethod == ePixelIntegrated) {
291  FluorescenceFunctor fluoFunc(age, showerTelDist, rMoliere,
292  telData.GetArcLengthFunction());
293  const Integrator<FluorescenceFunctor> integrator(fluoFunc, fPrecision);
294  const double fraction = integrator.GetIntegral(0., telData.GetMaxZeta());
295 
296  for (unsigned int i = 0; i < telData.GetZetaPixels().size(); ++i) {
297  if (telData.GetZetaPixels()[i].fLightFraction == -1) {
298  FluorescenceFunctor fluoFuncPixel(age, showerTelDist, rMoliere,
299  telData.GetZetaPixels()[i].GetArcLengthFunction());
300  const Integrator<FluorescenceFunctor> integratorPixel(fluoFuncPixel, fPrecision);
301  telData.GetZetaPixels()[i].fLightFraction = integratorPixel.GetIntegral(0., telData.GetMaxZeta())/fraction;
302  }
303  }
304  const double spotFraction = fOpticalHalo ?
305  fOpticalHalo->GetHaloFraction(zeta, age, showerTelDist) : 1;
306  return fraction * spotFraction;
307  }
308  }
309 
310  return 1;
311 }
312 
313 
314 double
316  const TelescopeDataBin& detectionBin,
317  const fdet::Telescope& detTel,
318  const double xMax,
319  const double zeta)
320  const
321 {
322  if (fMethod == eBinByBin) {
323 
324  int nEff = 0;
325  double eff = 0;
326  if (detectionBin.HasEfficiency(FdConstants::eCherMieScattered)) {
327  eff += detectionBin.GetEfficiency(FdConstants::eCherMieScattered);
328  ++nEff;
329  }
332  ++nEff;
333  }
334  if (nEff == 0) {
335  const string errMsg = "no bin-by-bin efficiency for fluorescence light";
336  ERROR(errMsg);
337  throw NonExistentComponentException(errMsg);
338  } else
339  return eff / nEff;
340 
341  } else {
342 
343  const double pathLength =
344  (detectionBin.fMeanDepthPoint - emissionBin.fMeanDepthPoint).GetMag();
345 
346  if (pathLength < 1*m)
347  return 1;
348 
349  const auto& meanPos = detectionBin.fMeanDepthPoint;
350  const auto& telescopePos = detTel.GetPosition();
351  const double showerTelDist = (meanPos - telescopePos).GetMag();
352  const double distanceToShowerAxis = tan(zeta) * showerTelDist;
353 
354  const auto& atmo = det::Detector::GetInstance().GetAtmosphere();
355  const auto& depthProfile = atmo.EvaluateDepthVsHeight();
356  const double height = emissionBin.fHeight;
357  const double xSlant = emissionBin.GetMeanDepth();
358  const double xVert = depthProfile.Y(height);
359  const double showerAge = utl::ShowerAge(xSlant, xMax);
360 
361  if (fMethod == eCircle || detectionBin.GetZetaPixels().empty()) {
362  const double maxEmissionAngle = atan2(distanceToShowerAxis, pathLength);
363  const double fraction =
364  atmo.AngularCherenkovCDF(maxEmissionAngle, xVert, showerAge);
365  const double spotFraction = fOpticalHalo ?
366  fOpticalHalo->GetHaloFraction(zeta, showerAge, showerTelDist) : 1;
367  return fraction * spotFraction;
368  } else if (fMethod == ePixelIntegrated) {
369  ScattCherFunctor cherFunc(showerTelDist, pathLength,
370  showerAge, xVert,
371  detectionBin.GetArcLengthFunction());
372  const Integrator<ScattCherFunctor> integrator(cherFunc, fPrecision);
373  const double fraction =
374  integrator.GetIntegral(0., detectionBin.GetMaxZeta());
375  return fraction;
376  }
377  }
378 
379  return 1;
380 }
381 
382 
383 double
385  const fdet::Telescope& detTel,
386  const double xMax,
387  const double cosTheta,
388  const double zeta)
389  const
390 {
391  if (fMethod == eBinByBin) {
393  return telData.GetEfficiency(FdConstants::eCherDirect);
394  else {
395  const string errMsg = "no bin-by-bin efficiency for direct Cherenkov light";
396  ERROR(errMsg);
397  throw NonExistentComponentException(errMsg);
398  }
399  } else {
400 
401  if (!fDirCherCorrGora) {
402 
403  // currently same lateral light distribution as fluorescence
404  return FluoLightFraction(telData, detTel, xMax, cosTheta, zeta);
405 
406  } else {
407 
408  // corrections to Gora LDF distributions based on 3D simulations in CORSIKA
409  // at low energies (10^15 - 10^17 eV) - parametrized by pol5 in viewing angle
410  static const double p_VA[30][6] = {
411  { 0.501418, 2.94216, -7.30234, 9.31207, -5.99745, 1.54418 },
412  { -0.00333121, 4.5624, -9.71922, 11.7979, -7.69457, 2.05705 },
413  { -0.00994375, 1.81732, 0.719025, -4.27035, 4.22282, -1.48334 },
414  { -0.00107321, 0.503863, 5.99427, -13.9105, 12.9082, -4.49541 },
415  { 0.000745283, 0.148745, 6.33147, -13.439, 12.1988, -4.23893 },
416  { 0.000709519, 0.0885937, 5.10991, -8.54954, 6.0705, -1.71655 },
417  { 0.000880354, 0.0530137, 4.34411, -5.90561, 3.24284, -0.732068 },
418  { 0.000579476, 0.0499766, 3.56326, -3.08367, -0.234635, 0.708838 },
419  { 0.000467793, 0.0390384, 3.02424, -1.45418, -1.85989, 1.25452 },
420  { 0.000499658, 0.0371965, 2.43002, 0.258876, -3.57741, 1.85539 },
421  { 0.00040399, 0.0208659, 2.08504, 1.23074, -4.54824, 2.21649 },
422  { 8.86504e-05, 0.0440711, 1.35947, 3.24868, -6.701, 3.05502 },
423  { -0.000288326, 0.055371, 0.907594, 4.31152, -7.62045, 3.35124 },
424  { -0.000158639, 0.0429035, 0.800877, 4.33574, -7.43096, 3.2566 },
425  { -0.000312911, 0.0631904, 0.162198, 6.2208, -9.62415, 4.1835 },
426  { -0.000578045, 0.0752885, 0.0811873, 5.96277, -8.99537, 3.87796 },
427  { -0.000428683, 0.0672003, -0.0811488, 6.14087, -9.08156, 3.9582 },
428  { -0.000585311, 0.083422, -0.437892, 6.90878, -9.8617, 4.30713 },
429  { -0.000603162, 0.0796437, -0.646415, 7.40142, -10.4691, 4.63569 },
430  { -0.000975556, 0.116029, -0.977511, 7.81595, -10.8033, 4.84644 },
431  { -0.00104516, 0.121701, -1.13216, 8.16602, -11.4698, 5.30535 },
432  { -0.000692655, 0.0743631, -0.839957, 7.01192, -10.029, 4.76265 },
433  { -0.000873929, 0.0974708, -1.08584, 7.59646, -11.055, 5.43051 },
434  { -0.000278001, 0.0384464, -0.475365, 5.31638, -8.13554, 4.22311 },
435  { -0.000373472, 0.0491568, -0.658973, 5.52961, -8.70434, 4.73939 },
436  { -0.000784299, 0.0923149, -1.20043, 7.06114, -10.5462, 5.52973 },
437  { -0.000272599, 0.0343134, -0.602254, 5.44353, -9.1348, 5.18153 },
438  { -0.000153735, 0.0203647, -0.445935, 4.48833, -7.8483, 4.69983 },
439  { -0.00365289, 0.175263, -2.03252, 9.50892, -14.4687, 7.745 },
440  { -0.00219899, 0.110025, -1.4529, 7.59706, -12.3696, 6.98898 }
441  };
442 
443  const auto& meanPos = telData.fMeanDepthPoint;
444  const auto& telPos = detTel.GetPosition();
445  const auto showerDir = Normalized(telData.fLastPoint - telData.fFirstPoint);
446  const double va = Angle(telPos - meanPos, showerDir) / degree;
447  const double* p = p_VA[int(round(max(0., min(29., floor(va)))))];
448  const double x = FluoLightFraction(telData, detTel, xMax, cosTheta, zeta);
449  return p[0] + x*(p[1] + x*(p[2] + x*(p[3] + x*(p[4] + x*p[5]))));
450  }
451  }
452 }
TMatrixD jacobian(TVectorD(*f)(TVectorD, const modeltype), TVectorD x, TVectorD dx, const modeltype mtype)
Definition: Statistics.icc:10
const TabulatedFunction & fArcLengthFunction
const double degree
constexpr T Sqr(const T &x)
double GoraCDF(const double rStar, const double age)
double Angle(const double theta1, const double phi1, const double theta2, const double phi2)
double DirCherLightFraction(const TelescopeDataBin &telData, const fdet::Telescope &detTel, const double xMax, const double cosTheta, const double zeta) const
double FluoLightFraction(const TelescopeDataBin &telData, const fdet::Telescope &detTel, const double xMax, const double cosTheta, const double zeta) const
const TabulatedFunction & fArcLengthFunction
Class for integration of functions with one independent parameter.
Definition: Integrator.h:72
Class to hold collection (x,y) points and provide interpolation between them.
FdProfileReconstructorKG::OpticalHalo * fOpticalHalo
#define INFO(message)
Macro for logging informational messages.
Definition: ErrorLogger.h:161
Base class for exceptions trying to access non-existing components.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
#define max(a, b)
double operator()(const double zeta) const
LightSource
Possible light sources.
Definition: FdConstants.h:9
double GetHaloFraction(const double zeta, const double age, const double dist) const
Definition: OpticalHalo.cc:19
double MoliereRadius(double temperature, double pressure, const double cosTheta)
The Moliere Radius (2 radiation length above obs-level, GAP-1998-002)
constexpr double fraction
Definition: AugerUnits.h:281
ScattCherFunctor(const double distanceToTelescope, const double distanceAlongShower, const double showerAge, const double verticalDepth, const TabulatedFunction &arcLengthFunction)
const std::vector< ZetaPixel > & GetZetaPixels() const
double operator()(const double zeta) const
double GetLightFraction(fevt::FdConstants::LightSource source, const TelescopeDataBin &emissionBin, const TelescopeDataBin &detectionBin, const fdet::Telescope &telescope, const double xMax, const double cosTheta, const double zeta) const
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
AxialVector Normalized(const AxialVector &v)
Definition: AxialVector.h:81
Detector description interface for Telescope-related data.
double GoraPDF(const double rStar, const double age)
FluorescenceFunctor(const double showerAge, const double distance, const double moliereRadius, const TabulatedFunction &arcLengthFunction)
double ShowerAge(const double slantDepth, const double showerMax)
General definition of shower age.
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
bool HasEfficiency(fevt::FdConstants::LightSource source) const
utl::Point GetPosition() const
double ScattCherLightFraction(const TelescopeDataBin &emissionBin, const TelescopeDataBin &detectionBin, const fdet::Telescope &detTel, const double xMax, const double zeta) const
double GetEfficiency(fevt::FdConstants::LightSource source) const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
constexpr double m
Definition: AugerUnits.h:121
calculation of FD optical halo light fraction
Definition: OpticalHalo.h:16
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)
const utl::TabulatedFunction & GetArcLengthFunction() const
std::map< fevt::FdConstants::LightSource, bool > fLLDIsOn

, generated on Tue Sep 26 2023.