MeasuredDBMieModel.cc
Go to the documentation of this file.
1 
9 #include <string>
10 #include <sstream>
11 #include <vector>
12 #include <cmath>
13 #include <limits>
14 
15 #include <det/Detector.h>
16 #include <fdet/FDetector.h>
17 #include <fdet/Eye.h>
18 #include <atm/ParametricXMLMieModel.h>
19 #include <atm/ScatteringResult.h>
20 #include <atm/AttenuationResult.h>
21 #include <atm/MeasuredDBMieModel.h>
22 
23 #include <fwk/CentralConfig.h>
24 
25 #include <utl/Point.h>
26 #include <utl/UTMPoint.h>
27 #include <utl/Vector.h>
28 #include <utl/AugerUnits.h>
29 #include <utl/Reader.h>
30 #include <utl/ErrorLogger.h>
31 #include <utl/TabulatedFunctionErrors.h>
32 #include <utl/ReferenceEllipsoid.h>
33 #include <utl/MathConstants.h>
34 #include <utl/StringCompare.h>
35 
36 #include <atm/AerosolDB.h>
37 #include <atm/AerosolZone.h>
38 
39 using namespace atm;
40 using namespace fdet;
41 using namespace utl;
42 using namespace std;
43 using namespace fwk;
44 
45 
47  fVAODVsHeightMap(NULL),
48  fDbIsEmptyNow(false),
49  fNSigma(0.),
50  fSystematicShift(0),
51  fZoneParam(eAll)
52 {
53 }
54 
55 
56 void
58 {
59  Branch topB = CentralConfig::GetInstance()->GetTopBranch("MeasuredDBMieModel");
60 
61  Branch zoneB;
62  if (bool(zoneB = topB.GetChild("systematicShiftVAOD")))
64 
65  if (bool(zoneB = topB.GetChild("zoneForce"))) {
66  string zoneName;
67  zoneB.GetData(zoneName);
68  fZoneParam = StringToZoneParam(zoneName);
69  }
70  else if (bool(zoneB = topB.GetChild("zoneSwap"))) {
71  vector<string> zoneNames;
72  zoneB.GetData(zoneNames);
73  if (zoneNames.size() == 2) {
74  fSwapZones.clear();
75  fSwapZones.push_back(StringToZoneParam(zoneNames[0]));
76  fSwapZones.push_back(StringToZoneParam(zoneNames[1]));
77  }
78  else
79  throw InvalidConfigurationException("Zone swap requires two zone names");
80  }
81 }
82 
83 
84 bool
86 {
87  if (!CheckForUpdates())
88  return false;
89  else if (fZoneParam == eAll)
90  return true;
91  else {// zone force
92  ZonePosition::iterator zPosIt =
93  find_if(fZonePositions.begin(), fZonePositions.end(),
94  [&](const auto& zone) { return ZoneMatch(zone, ZoneParamToString(fZoneParam)); });
95  return zPosIt != fZonePositions.end();
96  }
97 }
98 
99 
100 bool
101 MeasuredDBMieModel::HasZone(const string& zoneName) const
102 {
103  return find_if(fZonePositions.begin(), fZonePositions.end(),
104  [&](const auto& zone) { return ZoneMatch(zone, zoneName); }) != fZonePositions.end();
105 }
106 
107 
110  const utl::Point& xFinal,
111  const double angle,
112  const double distance,
113  const vector<double>& wLength) const
114 {
115  const AttenuationResult mieAttenuation = EvaluateMieAttenuation(xInit, xFinal, wLength);
116  return EvaluateMieScattering(xInit, xFinal, angle, distance, mieAttenuation);
117 }
118 
119 
122  const utl::Point& xFinal,
123  const double angle,
124  const double distance,
125  const AttenuationResult& mieAttenuation) const
126 {
127  const utl::TabulatedFunctionErrors& attenuation = mieAttenuation.GetTransmissionFactor();
129  const double fractionError = 0;
130  const double wError = 0;
131  // The model implemented here is wavelength independent
132  for (TabulatedFunctionErrors::ArrayConstIterator it = attenuation.XBegin();
133  it != attenuation.XEnd(); ++it) {
134  const double scat = EvaluateMieScattering(xInit, xFinal, angle, distance, *it, attenuation.Y(*it));
135  frac.PushBack(*it, wError, scat, fractionError);
136  }
137  return ScatteringResult(frac, angle);
138 }
139 
140 
142  const utl::Point& xFinal,
143  const double angle,
144  const double distance,
145  double wLength) const
146 {
147  const double mAtt = EvaluateMieAttenuation(xInit, xFinal, wLength);
148  return EvaluateMieScattering(xInit, xFinal, angle, distance, wLength, mAtt);
149 }
150 
151 
153  const utl::Point& /*xFinal*/,
154  const double angle,
155  const double distance,
156  double wLength,
157  const double mieAttenuation) const
158 {
159  if (!CheckForUpdates())
160  throw NoDataForModelException("Mie model could not find data to compute scattering.");
161 
162  // TO BE DONE - CASE OF ZONE CROSSING
163  // -- REFACTOR
164 
165  const double pf = EvaluateScatteringAngle(xInit, angle, wLength);
166  return (1.0 - mieAttenuation) * pf / pow(distance, 2);
167 }
168 
169 
172  const utl::Point& xFinal,
173  const vector<double>& wLength) const
174 {
175  // Not yet implemented errors !!
176  //
178 
179  for (std::vector<double>::const_iterator wIt = wLength.begin();
180  wIt != wLength.end(); ++wIt) {
181 
182  const double value = EvaluateMieAttenuation(xInit, xFinal, *wIt);
183 
184  // wavelength dependence computed as
185  // alpha(wav)=alpha(355nm) * (wav/355nm)^gamma (gamma positive)
186  //
187  // This assumes gamma is the same for all heights. Need to either
188  // verify that this is true when reading DB, or else provide a
189  // more general method
190  //
191  atten.PushBack(*wIt, 0., value, 0.);
192  }
193 
194  return AttenuationResult(atten);
195 }
196 
197 double
199  const utl::Point& xFinal,
200  double wLength) const
201 {
202  if (!CheckForUpdates())
203  throw NoDataForModelException("Mie model could not find data to compute attenuation");
204 
205  const string zoneName = GetZoneName(xInit);
206 
207  // TO BE DONE - CASE OF ZONE CROSSING
208  // -- REFACTOR
209 
210  // Get height above reference ellipsoid for the specified points
211  //
212  ReferenceEllipsoid wgs84(ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
213  double hInit = (wgs84.PointToLatitudeLongitudeHeight(xInit)).get<2>();
214  double hFinal = (wgs84.PointToLatitudeLongitudeHeight(xFinal)).get<2>();
215 
216  // THIS CONDITION WILL BE REMOVED WHEN PROPER BOUNDS CHECKING EXISTS
217  // IN TABULATEDFUNCTION
218  const TabulatedFunction& zoneVAODVsHeight = (*fVAODVsHeightMap)[zoneName];
219  const double hMin = zoneVAODVsHeight.XFront();
220  const double hMax = zoneVAODVsHeight.XBack();
221 
222  const double distance = (xFinal - xInit).GetMag();
223  const double deltaHeight = abs(hFinal - hInit);
224  const double cosTheta = deltaHeight / distance;
225  double averageHeight = min(hInit, hFinal) + 0.5 * deltaHeight;
226 
227  //BRD 24/2/06 --> use closest measured VAOD point
228  if (hInit < hMin)
229  hInit = hMin;
230  if (hInit > hMax)
231  hInit = hMax;
232  if (hFinal < hMin)
233  hFinal = hMin;
234  if (hFinal > hMax)
235  hFinal = hMax;
236  if (averageHeight < hMin)
237  averageHeight = hMin;
238  if (averageHeight > hMax)
239  averageHeight = hMax;
240 
241  double vaodSlant;
242 
243  if (deltaHeight > 1 * m) {
244  // Accuracy could probably be improved by using attenuation length
245  // for track segments in the top and bottom slices. Here we are
246  // relying on interpolation in VAOD table, for ease of implementation.
247  // ALSO, IS 3rd ORDER INTERPOLATION TOO MUCH?
248  const double vaodInit = zoneVAODVsHeight.InterpolateY(hInit,3);
249  const double vaodFinal = zoneVAODVsHeight.InterpolateY(hFinal,3);
250  vaodSlant = abs(vaodFinal - vaodInit) / cosTheta;
251  } else {
252  const double alpha = (*fAttVsHeightMap)[zoneName].Y(hInit);
253  vaodSlant = distance*alpha;
254  }
255 
256  // Not yet implemented errors !!
257  //
258  const double gamma = (*fAttLambdaVsHeightMap)[zoneName].Y(averageHeight);
259 
260  // This assumes gamma is the same for all heights. Need to either
261  // verify that this is true when reading DB, or else provide a
262  // more general method.
263  const double arg = -vaodSlant * pow(wLength/355./nanometer, -gamma);
264 
265  // Numerical sanity check, though argument should always be <= 0...
266  if (arg < std::numeric_limits<double>::max_exponent10 * kLn10)
267  return exp(arg);
268 
270 }
271 
272 
273 double
274 MeasuredDBMieModel::GetVerticalAerosolOpticalDepth(const unsigned int eyeId, const double altitude)
275  const
276 {
277  if (!CheckForUpdates())
278  throw NoDataForModelException("Mie model could not find data to compute VAOD");
279 
280  string zoneName = GetZoneName(eyeId);
281  const TabulatedFunction& zoneVAODVsHeight = (*fVAODVsHeightMap)[zoneName];
282 
283  const double hMax = zoneVAODVsHeight.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 = zoneVAODVsHeight.YBack();
294  }
295  else {
296  // IS 3rd ORDER INTERPOLATION TOO MUCH?
297  VAOD = zoneVAODVsHeight.InterpolateY(altitude, 3);
298  }
299 
300  return VAOD;
301 }
302 
303 double
305  const double wLength) const
306 {
307  const string zoneName = GetZoneName(p);
308  const TabulatedFunction& zoneAlphaVsHeight = (*fAttVsHeightMap)[zoneName];
309 
310  // TO BE DONE - CASE OF ZONE CROSSING
311  // -- REFACTOR
312 
313  // THIS CONDITION WILL BE REMOVED WHEN PROPER BOUNDS CHECKING EXISTS
314  // IN TABULATEDFUNCTION
315  const double hMin = zoneAlphaVsHeight.XFront();
316  const double hMax = zoneAlphaVsHeight.XBack();
317 
318  // Get height above reference ellipsoid for the specified points.
319  ReferenceEllipsoid wgs84(ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
320  double height = (wgs84.PointToLatitudeLongitudeHeight(p)).get<2>();
321 
322  // VMH 2018-11-09: when h > hMax we give higher VAODs by repeating the VAOD at hMax,
323  // so we must give 0 for alpha (inf for att length) in that case because no change
324  // in integrated aerosols means no aerosols at all
325  if (height < hMin)
326  height = hMin;
327  if (height > hMax)
329 
330  const double alpha = zoneAlphaVsHeight.Y(height);
331 
332  // Not yet implemented errors !!
333  const double gamma = (*fAttLambdaVsHeightMap)[zoneName].Y(height);
334 
335  // wavelength dependence computed as
336  // alpha(wav)=alpha(355nm) * (wav/355nm)^gamma (gamma positive)
337  //
338  // This assumes gamma is the same for all heights. Need to either
339  // verify that this is true when reading DB, or else provide a
340  // more general method.
341  return alpha>0 ? 1. / (alpha * pow(wLength / 355. / nanometer, -gamma)) : numeric_limits<double>::max();
342 }
343 
344 
345 double
347  const double angle,
348  const double /*wLength*/)
349  const
350 {
351  const string zoneName = GetZoneName(p);
352  const PFParameters& pfParams = (*fPhaseFuncMap)[zoneName];
353 
354  const double g2 = pfParams.g * pfParams.g;
355  const double mu = cos(angle);
356  const double a = 0.25 * (1 - g2) / kPi;
357  const double b = pow(1 + g2 - 2 * pfParams.g * mu, -1.5);
358  const double c = pfParams.f * 0.5 * (3*mu*mu - 1) * pow(1 + g2, -1.5);
359 
360  return a * (b + c);
361 }
362 
363 
364 // Returns true if data are found and cached or if data already exist
365 // for the current detector time.
366 bool
368 {
369  if (fCurrentTime == det::Detector::GetInstance().GetTime() && fCurrentTime)
370  return !fDbIsEmptyNow;
371 
372  fCurrentTime = det::Detector::GetInstance().GetTime();
373  fDbIsEmptyNow = false;
374 
375  // Note: these tables are shadow pointers. No need to call delete.
382 
383  fZonePositions.clear();
384 
385  const AerosolDB& aerosol1 =
386  det::Detector::GetInstance().GetAtmosphere().GetAerosolDB();
387 
388  unsigned int zoneCount = 0;
389  for (AerosolDB::ZoneIterator zIt = aerosol1.ZonesBegin();
390  zIt != aerosol1.ZonesEnd(); ++zIt, ++zoneCount)
391  {
392  // fill zone name and position
393  // height should not be relevant for these calculations
394  fZonePositions[zIt->GetName()] =
395  UTMPoint(
396  zIt->GetNorthing(),
397  zIt->GetEasting(),
398  0., 19, 'H',
399  ReferenceEllipsoid::GetEllipsoidIDFromString("WGS84")).GetPoint();
400 
401  TabulatedFunction attVsH;
402  TabulatedFunction centralVaodVsH;
403  TabulatedFunction minVaodVsH;
404  TabulatedFunction maxVaodVsH;
405  TabulatedFunction attLambdaVsH;
406 
407  // Fill VAOD slices; extrapolate lower end of VAOD table down to VAOD = 0
408  // (for more accurate interpolations).
409  centralVaodVsH.PushBack(zIt->AttSlicesBegin()->GetMinHeight(), 0.);
410  minVaodVsH.PushBack(zIt->AttSlicesBegin()->GetMinHeight(), 0.);
411  maxVaodVsH.PushBack(zIt->AttSlicesBegin()->GetMinHeight(), 0.);
412 
413  double sliceRoof = 0.;
414  double att = 0.;
415  double attLambda = 0.;
416  for (AerosolZone::AttSliceIterator attIt = zIt->AttSlicesBegin();
417  attIt != zIt->AttSlicesEnd(); ++attIt)
418  {
419  const double hMin = attIt->GetMinHeight();
420  const double hMax = attIt->GetMaxHeight(); // DB stores VAOD @ top of each slice
421 
422  att = attIt->GetAttAlpha();
423  attLambda = attIt->GetAttLambda();
424 
425  try {
426  if (fSystematicShift == 0) {
427  minVaodVsH.PushBack(hMax, attIt->GetMinVAODUncor());
428  maxVaodVsH.PushBack(hMax, attIt->GetMaxVAODUncor());
429  centralVaodVsH.PushBack(hMax, attIt->GetVAOD());
430  }
431  else if (fSystematicShift > 0) {
432  const double dVAOD = fSystematicShift*(attIt->GetMaxVAODCor()-attIt->GetVAOD());
433  minVaodVsH.PushBack(hMax, attIt->GetMinVAODUncor() + dVAOD);
434  maxVaodVsH.PushBack(hMax, attIt->GetMaxVAODUncor() + dVAOD);
435  centralVaodVsH.PushBack(hMax, attIt->GetVAOD() + dVAOD);
436  }
437  else if (fSystematicShift < 0) {
438  const double minVaod = attIt->GetMinVAODUncor();
439  const double maxVaod = attIt->GetMaxVAODUncor();
440  const double vaod = attIt->GetVAOD();
441  const double dVAOD =
442  fabs(fSystematicShift) * (attIt->GetVAOD()-attIt->GetMinVAODCor());
443 
444  if(vaod > dVAOD)
445  centralVaodVsH.PushBack(hMax, vaod - dVAOD);
446  else
447  centralVaodVsH.PushBack(hMax, 0.);
448 
449  if(minVaod > dVAOD)
450  minVaodVsH.PushBack(hMax, minVaod - dVAOD);
451  else
452  minVaodVsH.PushBack(hMax, 0.);
453 
454  if(maxVaod > dVAOD)
455  maxVaodVsH.PushBack(hMax, maxVaod - dVAOD);
456  else
457  maxVaodVsH.PushBack(hMax, 0.);
458  }
459  }
460  catch (utl::DataNotFoundInDBException& err) {
461  ostringstream warn;
462  warn << "New Aerosol DB structure (Atm_Aerosol_1_A) not found, trying old DB structure (Atm_Aerosol_0_A)";
463  WARNING(warn);
464 
465  minVaodVsH.PushBack(hMax, attIt->GetMinVAOD());
466  maxVaodVsH.PushBack(hMax, attIt->GetMaxVAOD());
467  centralVaodVsH.PushBack(hMax, attIt->GetVAOD());
468  }
469 
470  attVsH.PushBack(hMin, att);
471  attLambdaVsH.PushBack(hMin, attLambda);
472 
473  sliceRoof = attIt->GetMaxHeight();
474  }
475 
476  // Set value at top of highest slice to be the same as at
477  // the bottom of same slice (not sure if this is the best thing to do).
478  attVsH.PushBack(sliceRoof, att);
479  attLambdaVsH.PushBack(sliceRoof, attLambda);
480 
481  (*fAttVsHeightMap)[zIt->GetName()] = attVsH;
482  (*fCentralVAODVsHeightMap)[zIt->GetName()] = centralVaodVsH;
483  (*fMaxVAODVsHeightMap)[zIt->GetName()] = maxVaodVsH;
484  (*fMinVAODVsHeightMap)[zIt->GetName()] = minVaodVsH;
485 
486  // set VAOD pointer according to user request
487  ToggleVAODPtr();
488 
489  (*fAttLambdaVsHeightMap)[zIt->GetName()] = attLambdaVsH;
490 
491  // Fill PF slices
492  for (AerosolZone::PFSliceIterator pfIt = zIt->PFSlicesBegin();
493  pfIt != zIt->PFSlicesEnd() ; ++pfIt) {
494 
495  PFParameters pfParams;
496  pfParams.f = pfIt->GetF();
497  pfParams.fErr = pfIt->GetFError();
498  pfParams.g = pfIt->GetG();
499  pfParams.gErr = pfIt->GetGError();
500  pfParams.fLambda = pfIt->GetFLambda();
501  pfParams.fLambdaErr = pfIt->GetFLambdaError();
502  pfParams.gLambda = pfIt->GetGLambda();
503  pfParams.gLambdaErr = pfIt->GetGLambdaError();
504 
505  (*fPhaseFuncMap)[zIt->GetName()] = pfParams;
506  }
507  }
508  if (zoneCount == 0) {
509  fDbIsEmptyNow = true;
510 
511  ostringstream msg;
512  msg << "Mie model requested data from database, but no data found for time ";
513  msg << det::Detector::GetInstance().GetTime();
514  DEBUGLOG(msg);
515 
516  return false;
517  }
518  return true;
519 }
520 
521 
522 // First attempt at zone selection. Pick the zone with coordinates closest to
523 // the given point.
524 string
526 {
527  string zoneName("");
528 
529  if (fZoneParam == eAll) {
530  double smallestDist = numeric_limits<float>::max(); // was HUGE
531  for (map<string, Point>::iterator zIt = fZonePositions.begin();
532  zIt != fZonePositions.end(); ++zIt) {
533 
534  const double dist = (pt - zIt->second).GetMag();
535 
536  if (dist <= smallestDist) {
537  smallestDist = dist;
538  zoneName = zIt->first;
539  }
540  }
541 
542  // Zone swapping: see if zone is in the swap list, and swap the zone name
543  if (fSwapZones.size()) {
544  string zone1 = ZoneParamToString(fSwapZones[0]);
545  string zone2 = ZoneParamToString(fSwapZones[1]);
546  bool isZone1 = false;
547  bool isZone2 = false;
548 
549  if ((isZone1 = ContainsSubstringEquivalent(zoneName, zone1)) ||
550  (isZone2 = ContainsSubstringEquivalent(zoneName, zone2)))
551  {
552  ZonePosition::iterator zPosIt;
553  if (isZone1 && HasZone(zone2))
554  zPosIt = find_if(fZonePositions.begin(), fZonePositions.end(),
555  [&](const auto& zone) { return ZoneMatch(zone, zone2); });
556  else if (isZone2 && HasZone(zone1))
557  zPosIt = find_if(fZonePositions.begin(), fZonePositions.end(),
558  [&](const auto& zone) { return ZoneMatch(zone, zone1); });
559  else {
560  ostringstream error;
561  error << "Zone swap: missing zone for \""
562  << (isZone1 ? zone2 : (isZone2 ? zone1 : "UNKNOWN")) << "\"";
563  throw DataNotFoundInDBException(error.str());
564  }
565  zoneName = zPosIt->first;
566  }
567  }
568  return zoneName;
569  }
570  // Zone forcing enabled
571  else {
572  ZonePosition::iterator zPosIt =
573  find_if(fZonePositions.begin(), fZonePositions.end(),
574  [&](const auto& zone) { return ZoneMatch(zone, ZoneParamToString(fZoneParam)); });
575 
576  if (zPosIt != fZonePositions.end())
577  return zPosIt->first;
578  else {
579  ostringstream error;
580  error << "Zone force: missing zone for \""
581  << ZoneParamToString(fZoneParam) << "\"";
582  throw DataNotFoundInDBException(error.str());
583  }
584  }
585 }
586 
587 // Pick the aerosol zone nearest to the given eye.
588 string
589 MeasuredDBMieModel::GetZoneName(const unsigned int eyeId) const
590 {
591  const utl::Point& eyePos =
592  det::Detector::GetInstance().GetFDetector().GetEye(eyeId).GetPosition();
593 
594  return GetZoneName(eyePos);
595 }
596 
597 
598 bool
599 MeasuredDBMieModel::CrossesZone(const utl::Point& /*pt1*/, const utl::Point& /*p2*/) const
600 {
601  // To be implemented. Return true if the two points are not in the same zone.
602  return false;
603 }
604 
605 
606 void
608 {
609  fNSigma = nSigma;
610  ToggleVAODPtr();
611 }
612 
613 
614 void
616 {
617  if (fNSigma == 0.)
619  else if (fNSigma == 1.)
621  else if (fNSigma == -1.)
623  else {
624  ostringstream err;
625  err << " Mie model could not find data for " << fNSigma
626  << " sigma uncertainty bound";
627  throw NoDataForModelException(err.str());
628  }
629 }
630 
631 
633 MeasuredDBMieModel::StringToZoneParam(const std::string& zoneString) const
634 {
635  if (ContainsSubstringEquivalent(zoneString, "Leones"))
636  return eLosLeones;
637  else if (ContainsSubstringEquivalent(zoneString, "Morados"))
638  return eLosMorados;
639  else if (ContainsSubstringEquivalent(zoneString, "Amarilla"))
640  return eLomaAmarilla;
641  else if (ContainsSubstringEquivalent(zoneString, "Coihueco"))
642  return eCoihueco;
643  else
644  return eAll;
645 }
646 
647 
648 std::string
650 {
651  string zoneName("");
652 
653  switch (zone) {
654  case eLosLeones:
655  zoneName = "Leones";
656  break;
657  case eLosMorados:
658  zoneName = "Morados";
659  break;
660  case eLomaAmarilla:
661  zoneName = "Amarilla";
662  break;
663  case eCoihueco:
664  zoneName = "Coihueco";
665  break;
666  default:
667  break;
668  }
669 
670  return zoneName;
671 }
672 
673 
674 bool
675 MeasuredDBMieModel::ZoneMatch(const ZonePoint& zonePt, const string& zoneName) const
676 {
677  return ContainsSubstringEquivalent(zonePt.first, zoneName);
678 }
679 
Branch GetTopBranch() const
Definition: Branch.cc:63
ZoneIterator ZonesBegin() const
Beginning of the collection of valid Zones.
Definition: AerosolDB.h:36
bool ZoneMatch(const ZonePoint &pt, const std::string &name) const
bool HasZone(const std::string &zoneName) const
Check for a zone in the DB (partial name match, case-insensitive)
Point object.
Definition: Point.h:32
ArrayConstReference XBack() const
read-only reference to back of array of X
double GetAttenuationLength(const utl::Point &p, const double wLength) const
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
Class to hold and convert a point in geodetic coordinates.
Definition: UTMPoint.h:40
ArrayIterator XEnd()
end of array of X
Base class for exceptions arising because configuration data are not valid.
Class to hold collection (x,y) points and provide interpolation between them.
bool CrossesZone(const utl::Point &pt1, const utl::Point &p2) const
std::map< std::string, PFParameters > ZonePhaseFunction
atm::ScatteringResult EvaluateMieScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &wLength) const
Compute scattering intensity at point at a particular angle and distance from track defined by two po...
utl::ShadowPtr< ZoneFunction > fMaxVAODVsHeightMap
std::vector< ZoneParam > fSwapZones
void PushBack(const double x, const double y)
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)
Exception to use in a atmosphere model cannot find data it needs.
constexpr double nanometer
Definition: AugerUnits.h:102
Class holding the output of the ScatteringResult function.
boost::transform_iterator< InternalZoneFunctor, InternalZoneIterator, const AerosolZone & > ZoneIterator
ZoneIterator returns a pointer to an AerosolZone.
Definition: AerosolDB.h:33
#define max(a, b)
Class representing a document branch.
Definition: Branch.h:107
Exception to use in case requested data not found in the database with detailed printout.
Class for loading and storing a collection of aerosol data.
Definition: AerosolDB.h:14
Reference ellipsoids for UTM transformations.
ArrayConstReference XFront() const
read-only reference to front of array of X
constexpr double kPi
Definition: MathConstants.h:24
#define DEBUGLOG(message)
Macro for logging debugging messages.
Definition: ErrorLogger.h:157
double abs(const SVector< n, T > &v)
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
bool HasData() const
Determine if the DB tables are full or if an update is needed.
const double km
bool ContainsSubstringEquivalent(const std::string &a, const std::string &b)
Syntactic sugar for searching within a string for a substring. Search is case-insensitive.
Definition: StringCompare.h:84
double GetVerticalAerosolOpticalDepth(const unsigned int eyeId, const double altitude) const
utl::ShadowPtr< ZonePhaseFunction > fPhaseFuncMap
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
void SetUncertaintyBound(double nSigma) const
alter Model by nSigma standard deviations
boost::indirect_iterator< InternalAttSliceIterator, const AttSlice & > AttSliceIterator
AttSlice iterator returns a pointer to the attenuation data slice for this zone.
Definition: AerosolZone.h:43
void Init()
Initialize model using an XML card.
ArrayConstReference YBack() const
read-only reference to back of array of Y
double InterpolateY(const double x, const unsigned int polyDegree) const
Interpolate the Y value with a polyDegree polynomial.
std::string ZoneParamToString(const ZoneParam &zone) const
ArrayIterator XBegin()
begin of array of X
ZoneIterator ZonesEnd() const
End of the collection of valid Zones.
Definition: AerosolDB.h:40
std::map< std::string, utl::TabulatedFunction > ZoneFunction
atm::AttenuationResult EvaluateMieAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
std::string GetZoneName(const utl::Point &pt) const
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
ZoneParam StringToZoneParam(const std::string &str) const
utl::ShadowPtr< ZoneFunction > fCentralVAODVsHeightMap
double EvaluateScatteringAngle(const utl::Point &p, const double angle, const double wLength) const
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
boost::indirect_iterator< InternalPFSliceIterator, const PFSlice & > PFSliceIterator
PFSlice Iterator returns a pointer to the phase function data slice for this zone.
Definition: AerosolZone.h:53
constexpr double m
Definition: AugerUnits.h:121
utl::ShadowPtr< ZoneFunction > fAttLambdaVsHeightMap
utl::ShadowPtr< ZoneFunction > fAttVsHeightMap
Class describing the Atmospheric attenuation.
std::pair< std::string, utl::Point > ZonePoint
utl::ShadowPtr< ZoneFunction > fMinVAODVsHeightMap

, generated on Tue Sep 26 2023.