ParametricXMLMieModel.cc
Go to the documentation of this file.
1 
10 #include <det/Detector.h>
11 
12 #include <fdet/FDetector.h>
13 #include <fdet/Eye.h>
14 
15 #include <atm/ParametricXMLMieModel.h>
16 #include <atm/ScatteringResult.h>
17 #include <atm/AttenuationResult.h>
18 
19 #include <fwk/CentralConfig.h>
20 #include <fwk/CoordinateSystemRegistry.h>
21 
22 #include <utl/Point.h>
23 #include <utl/AugerUnits.h>
24 #include <utl/MathConstants.h>
25 #include <utl/Reader.h>
26 #include <utl/ErrorLogger.h>
27 #include <utl/Vector.h>
28 #include <utl/ReferenceEllipsoid.h>
29 #include <utl/TabulatedFunctionErrors.h>
30 #include <utl/TabulatedFunction.h>
31 #include <utl/RandomSamplerFromPDF.h>
32 
33 #include <algorithm>
34 #include <iostream>
35 #include <string>
36 #include <sstream>
37 #include <vector>
38 #include <limits>
39 
40 using namespace utl;
41 using namespace atm;
42 using namespace fwk;
43 using namespace std;
44 
45 
46 void
48 {
49  Branch topB =
50  CentralConfig::GetInstance()->GetTopBranch("ParametricXMLMieModel");
51 
52  // Get model parameters for vertical distribution of aerosols.
53  Branch profileB = topB.GetChild("aerosolProfile");
54 
55  profileB.GetChild("attLength").GetData(fLMix);
56  profileB.GetChild("attLengthError").GetData(fLMixError);
57 
58  profileB.GetChild("mixHeight").GetData(fHMix);
59  profileB.GetChild("mixHeightError").GetData(fHMixError);
60 
61  profileB.GetChild("scaleHeight").GetData(fHScl);
62  profileB.GetChild("scaleHeightError").GetData(fHSclError);
63 
64  // Get phase function.
65  Branch pfB = topB.GetChild("phaseFunction");
66  pfB.GetChild("f").GetData(fPhaseFunction.f);
67  pfB.GetChild("fError").GetData(fPhaseFunction.fError);
68  pfB.GetChild("g").GetData(fPhaseFunction.g);
69  pfB.GetChild("gError").GetData(fPhaseFunction.gError);
70 
71  // Get wavelength dependence.
72  Branch waveB = topB.GetChild("wavelengthDependence");
73  waveB.GetChild("gamma").GetData(fGamma);
74  waveB.GetChild("gammaError").GetData(fGammaError);
75 
76  // Set prevailing ground height (use PampaAmarilla as reference coordinate system).
77  // obtaining the reference coordinate system from the detector does not work,
78  // because in this Init() funciton there should not be any GetInstance() of the detector.
79  const utl::CoordinateSystemPtr referenceCS = fwk::CoordinateSystemRegistry::Get("PampaAmarilla");
80 
81  const utl::Point origin(0,0,0, referenceCS);
82  const ReferenceEllipsoid& wgs84 =
84 
85  fHGnd = wgs84.PointToLatitudeLongitudeHeight(origin).get<2>();
86 }
87 
88 
93 ParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
94  const utl::Point& xB,
95  const double angle,
96  const double distance,
97  const vector<double>& wLength)
98  const
99 {
100  const AttenuationResult& mieAttenuation = EvaluateMieAttenuation(xA, xB, wLength);
101  return EvaluateMieScattering(xA, xB, angle, distance, mieAttenuation);
102 }
103 
104 
109 ParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
110  const utl::Point& xB,
111  const double angle,
112  const double distance,
113  const AttenuationResult& mieAttenuation)
114  const
115 {
116  const utl::TabulatedFunctionErrors& attenuation = mieAttenuation.GetTransmissionFactor();
118  const double fractionError = 0;
119  const double wError = 0;
120 
121  const unsigned int nWl = attenuation.GetNPoints();
122  for (unsigned int iWl = 0; iWl < nWl; ++iWl) {
123  const double wl = attenuation.GetX(iWl);
124  const double value = EvaluateMieScattering(xA, xB, angle, distance, wl, attenuation.GetY(iWl));
125  frac.PushBack(wl, wError, value, fractionError);
126  }
127 
128  return ScatteringResult(frac, angle);
129 }
130 
131 
135 double
136 ParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
137  const utl::Point& xB,
138  const double angle,
139  const double distance,
140  const double wLength)
141  const
142 {
143  // Attenuation is needed in the scattering calculations.
144  const double mAtt = EvaluateMieAttenuation(xA, xB, wLength);
145  return EvaluateMieScattering(xA, xB, angle, distance, wLength, mAtt);
146 }
147 
148 
152 double
153 ParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
154  const utl::Point& /*xB*/,
155  const double angle,
156  const double distance,
157  const double wLength,
158  const double mieAttenuation)
159  const
160 {
161  const double xphs = EvaluateScatteringAngle(xA, angle, wLength);
162  return (1 - mieAttenuation) * xphs / pow(distance, 2);
163 }
164 
165 
171 ParametricXMLMieModel::EvaluateMieAttenuation(const utl::Point& xInit,
172  const utl::Point& xFinal,
173  const std::vector<double>& wLength)
174  const
175 {
176  utl::TabulatedFunctionErrors attenuation;
177  const double wError = 0;
178  const double mieAttError = 0;
179 
180  for (std::vector<double>::const_iterator wlIter = wLength.begin();
181  wlIter != wLength.end(); ++wlIter) {
182  const double mieAtt = EvaluateMieAttenuation(xInit, xFinal, *wlIter);
183  attenuation.PushBack(*wlIter, wError, mieAtt, mieAttError);
184  }
185 
186  return AttenuationResult(attenuation);
187 }
188 
189 
194 double
195 ParametricXMLMieModel::EvaluateMieAttenuation(const utl::Point& xInit,
196  const utl::Point& xFinal,
197  const double wLength)
198  const
199 {
200  const ReferenceEllipsoid& wgs84 =
202  double hInit = wgs84.PointToLatitudeLongitudeHeight(xInit).get<2>() - fHGnd;
203  double hFinal = wgs84.PointToLatitudeLongitudeHeight(xFinal).get<2>() - fHGnd;
204 
205  const double alphaM = 1. / fLMix;
206  const double distance = (xInit-xFinal).GetMag();
207  const double deltaHeight = abs(hFinal - hInit);
208  const double cosTheta = deltaHeight / distance;
209 
210  double vaodSlant;
211 
212  if (deltaHeight > 1*m) {
213  // Integration limits expect hInit < hFinal.
214  if (hInit > hFinal)
215  swap(hInit, hFinal);
216 
217  // Integrate extinction coefficient; be careful of integration limits.
218  if (hInit < fHMix && hFinal < fHMix)
219  vaodSlant = alphaM * (hFinal - hInit);
220  else if (hInit < fHMix && hFinal > fHMix)
221  vaodSlant = alphaM * (fHMix - hInit +
222  fHScl * (1. - exp(-(hFinal - fHMix) / fHScl)));
223  else
224  vaodSlant = alphaM * fHScl *
225  (exp(-(hInit - fHMix)/fHScl) - exp(-(hFinal - fHMix)/fHScl));
226 
227  // Convert vertical depth to slant depth.
228  vaodSlant /= cosTheta;
229  } else {
230  // Assume attenuation at a fixed altitude.
231  if (hInit < fHMix)
232  vaodSlant = alphaM * distance;
233  else
234  vaodSlant = alphaM * exp(-(hInit - fHMix) / fHScl) * distance;
235  }
236 
237  // Add the wavelength dependence.
238  const double arg = -vaodSlant * pow(wLength/355./nanometer, -fGamma);
239 
240  if (arg < std::numeric_limits<double>::max_exponent10 * kLn10)
241  return exp(arg);
242 
244 }
245 
246 
250 double
251 ParametricXMLMieModel::GetVerticalAerosolOpticalDepth(const unsigned int eyeId,
252  const double altitude)
253  const
254 {
255  const ReferenceEllipsoid& wgs84 =
257  const utl::Point& eyePos =
258  det::Detector::GetInstance().GetFDetector().GetEye(eyeId).GetPosition();
259  const double hEye =
260  wgs84.PointToLatitudeLongitudeHeight(eyePos).get<2>() - fHGnd;
261  const double hFinal = altitude - fHGnd;
262 
263  const double alphaM = 1. / fLMix;
264 
265  // Ignore ground level differences across the array and fix the mixing
266  // layer height with respect to the prevailing ground height.
267  if ((hFinal - hEye) > 1*m) {
268  // Integrate extinction coefficient; be careful of integration limits.
269  if (hEye < fHMix && hFinal < fHMix)
270  return alphaM * (hFinal - hEye);
271  else if (hEye < fHMix && hFinal > fHMix)
272  return alphaM * (fHMix - hEye +
273  fHScl * (1. - exp(-(hFinal - fHMix) / fHScl)));
274  else
275  return alphaM * fHScl *
276  (exp(-(hEye - fHMix)/fHScl) - exp(-(hFinal - fHMix)/fHScl));
277  } else
278  return 0;
279 }
280 
281 
286 double
287 ParametricXMLMieModel::GetAttenuationLength(const utl::Point& p,
288  const double wLength)
289  const
290 {
291  const ReferenceEllipsoid& wgs84 =
293  const double height =
294  wgs84.PointToLatitudeLongitudeHeight(p).get<2>() - fHGnd;
295 
296  double alpha;
297 
298  if (height < fHMix)
299  alpha = 1. / fLMix;
300  else
301  alpha = 1. / (fLMix * exp((height - fHMix) / fHScl));
302 
303  return 1. / (alpha * pow(wLength / 355. / nanometer, -fGamma));
304 }
305 
306 
310 double
311 ParametricXMLMieModel::EvaluateScatteringAngle(const Point& /*p*/,
312  const double angle,
313  const double /*wLength*/)
314  const
315 {
316  const double g2 = fPhaseFunction.g * fPhaseFunction.g;
317  const double mu = cos(angle);
318  const double a = 0.25 * (1 - g2) / kPi;
319  const double b = pow(1 + g2 - 2 * fPhaseFunction.g * mu, -1.5);
320  const double c = fPhaseFunction.f * 0.5 * (3*mu*mu - 1) * pow(1 + g2, -1.5);
321 
322  return a * (b + c);
323 }
324 
Branch GetTopBranch() const
Definition: Branch.cc:63
unsigned int GetNPoints() const
Point object.
Definition: Point.h:32
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
void swap(utl::TabulatedFunction &t1, utl::TabulatedFunction &t2)
void Init()
Initialise the registry.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
Definition: Branch.cc:211
static const ReferenceEllipsoid & Get(const EllipsoidID theID)
Get known ellipsoid by registered ID.
double pow(const double x, const unsigned int i)
constexpr double nanometer
Definition: AugerUnits.h:102
Class holding the output of the ScatteringResult function.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
Reference ellipsoids for UTM transformations.
constexpr double kPi
Definition: MathConstants.h:24
double abs(const SVector< n, T > &v)
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
void PushBack(const double x, const double xErr, const double y, const double yErr)
void GetData(bool &b) const
Overloads of the GetData member template function.
Definition: Branch.cc:644
constexpr double kLn10
Definition: MathConstants.h:29
const double & GetY(const unsigned int idx) const
const double & GetX(const unsigned int idx) const
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
constexpr double m
Definition: AugerUnits.h:121
Class describing the Atmospheric attenuation.

, generated on Tue Sep 26 2023.