NonParametricXMLMieModel.cc
Go to the documentation of this file.
1 
9 #include <det/Detector.h>
10 
11 #include <fdet/FDetector.h>
12 #include <fdet/Eye.h>
13 
14 #include <atm/NonParametricXMLMieModel.h>
15 #include <atm/ScatteringResult.h>
16 #include <atm/AttenuationResult.h>
17 
18 #include <fwk/CentralConfig.h>
19 #include <fwk/CoordinateSystemRegistry.h>
20 
21 #include <utl/Point.h>
22 #include <utl/AugerUnits.h>
23 #include <utl/MathConstants.h>
24 #include <utl/Reader.h>
25 #include <utl/ErrorLogger.h>
26 #include <utl/Vector.h>
27 #include <utl/ReferenceEllipsoid.h>
28 #include <utl/TabulatedFunctionErrors.h>
29 #include <utl/RandomSamplerFromPDF.h>
30 
31 #include <limits>
32 
33 using namespace utl;
34 using namespace atm;
35 using namespace fwk;
36 using namespace std;
37 
38 
39 void
41 {
42  Branch topB =
43  CentralConfig::GetInstance()->GetTopBranch("NonParametricXMLMieModel");
44 
45  // Get model parameters for vertical distribution of aerosols.
46  Branch profileB = topB.GetChild("aerosolProfile");
47 
48  vector<double> height;
49  vector<double> vaod;
50 
51  profileB.GetChild("height").GetData(height);
52  profileB.GetChild("opticalDepth").GetData(vaod);
53 
54  // Get phase function and wavelength dependence.
55  topB.GetChild("phaseFunction").GetData(fPF);
56 
57  // Get wavelength dependence (assume Angstrom parameterization)
58  Branch waveB = topB.GetChild("wavelengthDependence");
59  waveB.GetChild("gamma").GetData(fGamma);
60  waveB.GetChild("gammaError").GetData(fGammaError);
61 
62  // Fill the VAOD and extinction coefficient tables
63  vector<double> alpha;
64  const double dh = height[1] - height[0];
65  const int N = height.size();
66 
67  // Define extinction @ top of altitude bin (CLF convention)
68  if (vaod[0] > 0) {
69  alpha.push_back(vaod[0] / dh);
70  for (int i = 1; i < N; ++i)
71  alpha.push_back((vaod[i] - vaod[i-1]) / dh);
72  }
73  // Ignore lowest bin where VAOD=0 (force the CLF convention)
74  else {
75  for (int i = 1; i < N; ++i)
76  alpha.push_back((vaod[i] - vaod[i-1]) / dh);
77  vaod.erase(vaod.begin());
78  height.erase(height.begin());
79  }
80 
81  fVAODVsHeight = new TabulatedFunction(height, vaod);
82  fAlphaVsHeight = new TabulatedFunction(height, alpha);
83 }
84 
85 
86 void
87 NonParametricXMLMieModel::SetOpticalDepth(const utl::TabulatedFunction& vaod,
88  const utl::TabulatedFunction& alpha)
89 {
90  // Old pointers are automatically deleted when we do this
91  fVAODVsHeight = new TabulatedFunction(vaod);
92  fAlphaVsHeight = new TabulatedFunction(alpha);
93 }
94 
95 
96 void
97 NonParametricXMLMieModel::SetPhaseFunction(const PhaseFunction& phaseFunc)
98 {
99  fPF = phaseFunc;
100 }
101 
102 
107 NonParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
108  const utl::Point& xB,
109  const double angle,
110  const double distance,
111  const vector<double>& wLength)
112  const
113 {
115  const double fractionError = 0;
116  const double wError = 0;
117 
118  for (std::vector<double>::const_iterator it = wLength.begin();
119  it != wLength.end(); ++it) {
120  const double value = EvaluateMieScattering(xA, xB, angle, distance, *it);
121  frac.PushBack(*it, wError, value, fractionError);
122  }
123 
124  return ScatteringResult(frac, angle);
125 }
126 
127 
132 NonParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
133  const utl::Point& xB,
134  const double angle,
135  const double distance,
136  const AttenuationResult& mieAttenuation)
137  const
138 {
139  const utl::TabulatedFunctionErrors& attenuation = mieAttenuation.GetTransmissionFactor();
141  const double fractionError = 0;
142  const double wError = 0;
143 
144  const unsigned int nWl = attenuation.GetNPoints();
145  for (unsigned int iWl = 0; iWl < nWl; ++iWl) {
146  const double wl = attenuation.GetX(iWl);
147  const double value = EvaluateMieScattering(xA, xB, angle, distance, wl, attenuation.GetY(iWl));
148  frac.PushBack(wl, wError, value, fractionError);
149  }
150 
151  return ScatteringResult(frac, angle);
152 }
153 
154 
158 double
159 NonParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
160  const utl::Point& xB,
161  const double angle,
162  const double distance,
163  const double wLength)
164  const
165 {
166  // Attenuation is needed in the scattering calculations.
167  const double mAtt = EvaluateMieAttenuation(xA, xB, wLength);
168  return EvaluateMieScattering(xA, xB, angle, distance, wLength, mAtt);
169 }
170 
171 
175 double
176 NonParametricXMLMieModel::EvaluateMieScattering(const utl::Point& xA,
177  const utl::Point& /*xB*/,
178  const double angle,
179  const double distance,
180  const double wLength,
181  const double mieAttenuation)
182  const
183 {
184  const double xphs = EvaluateScatteringAngle(xA, angle, wLength);
185  return (1 - mieAttenuation) * xphs / pow(distance, 2);
186 }
187 
188 
194 NonParametricXMLMieModel::EvaluateMieAttenuation(const utl::Point& xInit,
195  const utl::Point& xFinal,
196  const std::vector<double>& wLength)
197  const
198 {
199  utl::TabulatedFunctionErrors attenuation;
200  const double wError = 0;
201  const double mieAttError = 0;
202 
203  for (std::vector<double>::const_iterator wlIter = wLength.begin();
204  wlIter != wLength.end(); ++wlIter) {
205  const double mieAtt = EvaluateMieAttenuation(xInit, xFinal, *wlIter);
206  attenuation.PushBack(*wlIter, wError, mieAtt, mieAttError);
207  }
208 
209  return AttenuationResult(attenuation);
210 }
211 
212 
217 double
218 NonParametricXMLMieModel::EvaluateMieAttenuation(const utl::Point& xInit,
219  const utl::Point& xFinal,
220  const double wLength)
221  const
222 {
223  const ReferenceEllipsoid& wgs84 =
225  double hInit = wgs84.PointToLatitudeLongitudeHeight(xInit).get<2>();
226  double hFinal = wgs84.PointToLatitudeLongitudeHeight(xFinal).get<2>();
227 
228  const double hMin = fVAODVsHeight->XFront();
229  const double hMax = fVAODVsHeight->XBack();
230 
231  const double distance = (xFinal - xInit).GetMag();
232  const double deltaHeight = abs(hFinal - hInit);
233  const double cosTheta = deltaHeight / distance;
234  double averageHeight = min(hInit, hFinal) + 0.5 * deltaHeight;
235 
236  // Use closest measured VAOD point
237  if (hInit > hFinal)
238  swap(hInit, hFinal);
239 
240  if (hInit < hMin)
241  hInit = hMin;
242  if (hInit > hMax)
243  hInit = hMax;
244  if (hFinal < hMin)
245  hFinal = hMin;
246  if (hFinal > hMax)
247  hFinal = hMax;
248  if (averageHeight < hMin)
249  averageHeight = hMin;
250  if (averageHeight > hMax)
251  averageHeight = hMax;
252 
253  double vaodSlant;
254 
255  // Estimate optical depth of slant path
256  if (deltaHeight > 1 * m) {
257  const double vaodInit = fVAODVsHeight->InterpolateY(hInit,3);
258  const double vaodFinal = fVAODVsHeight->InterpolateY(hFinal,3);
259  vaodSlant = abs(vaodFinal - vaodInit) / cosTheta;
260  } else {
261  const double alpha = fAlphaVsHeight->Y(hInit);
262  vaodSlant = distance*alpha;
263  }
264 
265  // Add the wavelength dependence.
266  const double arg = -vaodSlant * pow(wLength/355./nanometer, -fGamma);
267 
268  if (arg < std::numeric_limits<double>::max_exponent10 * kLn10)
269  return exp(arg);
270 
272 }
273 
274 
278 double
279 NonParametricXMLMieModel::GetVerticalAerosolOpticalDepth(const unsigned int eyeId,
280  const double altitude)
281  const
282 {
283  const double hMax = fVAODVsHeight->XBack();
284  double VAOD;
285 
286  if (altitude >= hMax) {
287  ostringstream warn;
288  warn << "Requested VAOD at " << altitude / km << " km at eye " << eyeId
289  << ", but VAOD profile only goes to " << hMax / km << "km."
290  << " Returning heighest measured VAOD.";
291  WARNING(warn);
292 
293  VAOD = fVAODVsHeight->YBack();
294  }
295  else
296  VAOD = fVAODVsHeight->InterpolateY(altitude, 3);
297 
298  return VAOD;
299 }
300 
301 
306 double
307 NonParametricXMLMieModel::GetAttenuationLength(const utl::Point& p,
308  const double wLength)
309  const
310 {
311  const ReferenceEllipsoid& wgs84 =
313  double height = wgs84.PointToLatitudeLongitudeHeight(p).get<2>();
314 
315  const double hMin = fAlphaVsHeight->XFront();
316  const double hMax = fAlphaVsHeight->XBack();
317 
318  // Use closest measured VAOD point
319  if (height < hMin)
320  height = hMin;
321  if (height > hMax)
322  height = hMax;
323 
324  const double alpha = fAlphaVsHeight->Y(height);
325  return 1. / (alpha * pow(wLength / 355. / nanometer, -fGamma));
326 }
327 
328 
332 double
333 NonParametricXMLMieModel::EvaluateScatteringAngle(const Point& /*p*/,
334  const double angle,
335  const double /*wLength*/)
336  const
337 {
338  const int nbin = fPF.size();
339  const double binSize = kPi / (nbin - 1);
340  int ibin = int(angle / binSize);
341 
342  if (ibin < 0)
343  ibin = 0;
344  else if (ibin > nbin)
345  ibin = nbin - 1;
346 
347  return exp(log(fPF[ibin]) +
348  (angle - binSize * ibin) * log(fPF[ibin+1] / fPF[ibin]) / binSize);
349 }
350 
std::vector< double > PhaseFunction
Phase function table (arbitrary angular binning between 0, 180 degrees)
Branch GetTopBranch() const
Definition: Branch.cc:63
unsigned int GetNPoints() const
Point object.
Definition: Point.h:32
constexpr double km
Definition: AugerUnits.h:125
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
void swap(utl::TabulatedFunction &t1, utl::TabulatedFunction &t2)
Class to hold collection (x,y) points and provide interpolation between them.
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.
#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)
#define WARNING(message)
Macro for logging warning messages.
Definition: ErrorLogger.h:163
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
constexpr double m
Definition: AugerUnits.h:121
Class describing the Atmospheric attenuation.

, generated on Tue Sep 26 2023.