15 #include <det/Detector.h>
16 #include <fdet/FDetector.h>
18 #include <atm/ParametricXMLMieModel.h>
19 #include <atm/ScatteringResult.h>
20 #include <atm/AttenuationResult.h>
21 #include <atm/MeasuredDBMieModel.h>
23 #include <fwk/CentralConfig.h>
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>
36 #include <atm/AerosolDB.h>
37 #include <atm/AerosolZone.h>
47 fVAODVsHeightMap(NULL),
62 if (
bool(zoneB = topB.
GetChild(
"systematicShiftVAOD")))
65 if (
bool(zoneB = topB.
GetChild(
"zoneForce"))) {
70 else if (
bool(zoneB = topB.
GetChild(
"zoneSwap"))) {
71 vector<string> zoneNames;
73 if (zoneNames.size() == 2) {
92 ZonePosition::iterator zPosIt =
112 const double distance,
113 const vector<double>& wLength)
const
124 const double distance,
129 const double fractionError = 0;
130 const double wError = 0;
132 for (TabulatedFunctionErrors::ArrayConstIterator it = attenuation.
XBegin();
133 it != attenuation.
XEnd(); ++it) {
135 frac.
PushBack(*it, wError, scat, fractionError);
144 const double distance,
145 double wLength)
const
155 const double distance,
157 const double mieAttenuation)
const
166 return (1.0 - mieAttenuation) * pf /
pow(distance, 2);
173 const vector<double>& wLength)
const
179 for (std::vector<double>::const_iterator wIt = wLength.begin();
180 wIt != wLength.end(); ++wIt) {
191 atten.
PushBack(*wIt, 0., value, 0.);
200 double wLength)
const
219 const double hMin = zoneVAODVsHeight.
XFront();
220 const double hMax = zoneVAODVsHeight.
XBack();
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;
236 if (averageHeight < hMin)
237 averageHeight = hMin;
238 if (averageHeight > hMax)
239 averageHeight = hMax;
243 if (deltaHeight > 1 *
m) {
248 const double vaodInit = zoneVAODVsHeight.
InterpolateY(hInit,3);
249 const double vaodFinal = zoneVAODVsHeight.
InterpolateY(hFinal,3);
250 vaodSlant =
abs(vaodFinal - vaodInit) / cosTheta;
252 const double alpha = (*fAttVsHeightMap)[zoneName].Y(hInit);
253 vaodSlant = distance*alpha;
258 const double gamma = (*fAttLambdaVsHeightMap)[zoneName].Y(averageHeight);
263 const double arg = -vaodSlant *
pow(wLength/355./
nanometer, -gamma);
266 if (arg < std::numeric_limits<double>::max_exponent10 *
kLn10)
283 const double hMax = zoneVAODVsHeight.
XBack();
286 if (altitude >= hMax) {
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.";
293 VAOD = zoneVAODVsHeight.
YBack();
305 const double wLength)
const
315 const double hMin = zoneAlphaVsHeight.
XFront();
316 const double hMax = zoneAlphaVsHeight.
XBack();
330 const double alpha = zoneAlphaVsHeight.
Y(height);
333 const double gamma = (*fAttLambdaVsHeightMap)[zoneName].Y(height);
352 const PFParameters& pfParams = (*fPhaseFuncMap)[zoneName];
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);
386 det::Detector::GetInstance().GetAtmosphere().GetAerosolDB();
388 unsigned int zoneCount = 0;
390 zIt != aerosol1.
ZonesEnd(); ++zIt, ++zoneCount)
399 ReferenceEllipsoid::GetEllipsoidIDFromString(
"WGS84")).GetPoint();
409 centralVaodVsH.
PushBack(zIt->AttSlicesBegin()->GetMinHeight(), 0.);
410 minVaodVsH.
PushBack(zIt->AttSlicesBegin()->GetMinHeight(), 0.);
411 maxVaodVsH.
PushBack(zIt->AttSlicesBegin()->GetMinHeight(), 0.);
413 double sliceRoof = 0.;
415 double attLambda = 0.;
417 attIt != zIt->AttSlicesEnd(); ++attIt)
419 const double hMin = attIt->GetMinHeight();
420 const double hMax = attIt->GetMaxHeight();
422 att = attIt->GetAttAlpha();
423 attLambda = attIt->GetAttLambda();
427 minVaodVsH.
PushBack(hMax, attIt->GetMinVAODUncor());
428 maxVaodVsH.
PushBack(hMax, attIt->GetMaxVAODUncor());
429 centralVaodVsH.
PushBack(hMax, attIt->GetVAOD());
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);
438 const double minVaod = attIt->GetMinVAODUncor();
439 const double maxVaod = attIt->GetMaxVAODUncor();
440 const double vaod = attIt->GetVAOD();
445 centralVaodVsH.
PushBack(hMax, vaod - dVAOD);
450 minVaodVsH.
PushBack(hMax, minVaod - dVAOD);
455 maxVaodVsH.
PushBack(hMax, maxVaod - dVAOD);
462 warn <<
"New Aerosol DB structure (Atm_Aerosol_1_A) not found, trying old DB structure (Atm_Aerosol_0_A)";
465 minVaodVsH.
PushBack(hMax, attIt->GetMinVAOD());
466 maxVaodVsH.
PushBack(hMax, attIt->GetMaxVAOD());
467 centralVaodVsH.
PushBack(hMax, attIt->GetVAOD());
471 attLambdaVsH.
PushBack(hMin, attLambda);
473 sliceRoof = attIt->GetMaxHeight();
479 attLambdaVsH.
PushBack(sliceRoof, attLambda);
481 (*fAttVsHeightMap)[zIt->GetName()] = attVsH;
482 (*fCentralVAODVsHeightMap)[zIt->GetName()] = centralVaodVsH;
483 (*fMaxVAODVsHeightMap)[zIt->GetName()] = maxVaodVsH;
484 (*fMinVAODVsHeightMap)[zIt->GetName()] = minVaodVsH;
489 (*fAttLambdaVsHeightMap)[zIt->GetName()] = attLambdaVsH;
493 pfIt != zIt->PFSlicesEnd() ; ++pfIt) {
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();
505 (*fPhaseFuncMap)[zIt->GetName()] = pfParams;
508 if (zoneCount == 0) {
512 msg <<
"Mie model requested data from database, but no data found for time ";
513 msg << det::Detector::GetInstance().GetTime();
534 const double dist = (pt - zIt->second).GetMag();
536 if (dist <= smallestDist) {
538 zoneName = zIt->first;
546 bool isZone1 =
false;
547 bool isZone2 =
false;
552 ZonePosition::iterator zPosIt;
555 [&](
const auto& zone) {
return ZoneMatch(zone, zone2); });
556 else if (isZone2 &&
HasZone(zone1))
558 [&](
const auto& zone) {
return ZoneMatch(zone, zone1); });
561 error <<
"Zone swap: missing zone for \""
562 << (isZone1 ? zone2 : (isZone2 ? zone1 :
"UNKNOWN")) <<
"\"";
565 zoneName = zPosIt->first;
572 ZonePosition::iterator zPosIt =
577 return zPosIt->first;
580 error <<
"Zone force: missing zone for \""
589 MeasuredDBMieModel::GetZoneName(
const unsigned int eyeId)
const
592 det::Detector::GetInstance().GetFDetector().GetEye(eyeId).GetPosition();
625 err <<
" Mie model could not find data for " <<
fNSigma
626 <<
" sigma uncertainty bound";
658 zoneName =
"Morados";
661 zoneName =
"Amarilla";
664 zoneName =
"Coihueco";
Branch GetTopBranch() const
ZoneIterator ZonesBegin() const
Beginning of the collection of valid Zones.
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)
ArrayConstReference XBack() const
read-only reference to back of array of X
void ToggleVAODPtr() const
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.
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.
double pow(const double x, const unsigned int i)
bool CheckForUpdates() const
constexpr double nanometer
Class holding the output of the ScatteringResult function.
boost::transform_iterator< InternalZoneFunctor, InternalZoneIterator, const AerosolZone & > ZoneIterator
ZoneIterator returns a pointer to an AerosolZone.
Class representing a document branch.
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.
Reference ellipsoids for UTM transformations.
ArrayConstReference XFront() const
read-only reference to front of array of X
#define DEBUGLOG(message)
Macro for logging debugging messages.
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.
bool ContainsSubstringEquivalent(const std::string &a, const std::string &b)
Syntactic sugar for searching within a string for a substring. Search is case-insensitive.
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.
void GetData(bool &b) const
Overloads of the GetData member template function.
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.
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.
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
ZonePosition fZonePositions
utl::ShadowPtr< ZoneFunction > fCentralVAODVsHeightMap
double EvaluateScatteringAngle(const utl::Point &p, const double angle, const double wLength) const
ZoneFunction * fVAODVsHeightMap
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.
utl::TimeStamp fCurrentTime
utl::ShadowPtr< ZoneFunction > fAttLambdaVsHeightMap
utl::ShadowPtr< ZoneFunction > fAttVsHeightMap
Class describing the Atmospheric attenuation.
std::pair< std::string, utl::Point > ZonePoint
utl::ShadowPtr< ZoneFunction > fMinVAODVsHeightMap