11 #include <utl/Reader.h>
12 #include <utl/ErrorLogger.h>
13 #include <utl/AugerException.h>
14 #include <utl/AugerUnits.h>
15 #include <utl/MathConstants.h>
16 #include <utl/TabulatedFunction.h>
17 #include <utl/PhysicalConstants.h>
18 #include <utl/PhysicalFunctions.h>
19 #include <utl/Vector.h>
20 #include <utl/Point.h>
21 #include <utl/ReferenceEllipsoid.h>
22 #include <utl/UTMPoint.h>
24 #include <fwk/CentralConfig.h>
25 #include <fwk/RunController.h>
26 #include <fwk/LocalCoordinateSystem.h>
28 #include <atm/ProfileResult.h>
30 #include <evt/Event.h>
31 #include <evt/Header.h>
32 #include <evt/ShowerSimData.h>
33 #include <evt/RadioSimulation.h>
34 #include <evt/AtmosphereParameters.h>
53 INFO(
"Using SimShowerProfileModel");
61 const Event&
event = RunController::GetInstance().GetCurrentEvent();
63 if (fInitialized && fCurrentEvent == event.GetHeader().GetId())
66 if (!(event.HasSimShower() &&
event.GetSimShower().HasAtmosphereParameters()))
68 "with AtmosphereParameters. One of the two was not found.");
75 fCurrentEvent =
event.GetHeader().GetId();
83 const Point pCORSIKA(0, 0, 0, coordSys);
84 const Vector zCORSIKA(0, 0, 1, coordSys);
86 const Vector zLocal(0, 0, 1, localSys);
87 const double cosZenith = zCORSIKA.
GetCosTheta(localSys);
89 const double hObservationLevel =
UTMPoint(pCORSIKA, ReferenceEllipsoid::eWGS84).
GetHeight();
93 fAatm = params.
GetA();
94 fBatm = params.
GetB();
95 fCatm = params.
GetC();
97 double refractiveIndexAtSeaLevel = 0;
102 info <<
"Event has RadioSimulation, use refractive index at sea level from .reas file: n = "
103 << std::setprecision(10) << refractiveIndexAtSeaLevel;
118 const double minLog =
kLn10 * numeric_limits<double>::min_exponent10;
119 const double densityAtSeaLevel = GetDensityAtHeight(0);
121 vector<double> heights;
122 vector<double> depths;
126 const double heightStep = 10 *
meter;
127 double height = -heightStep;
128 while (height < fHlay.back()) {
129 height += heightStep;
131 if (height > fHlay.back())
132 height = fHlay.back();
134 const double heightCORSIKA = height;
135 const double heightOffline = cosZenith * (heightCORSIKA - hObservationLevel) + hObservationLevel;
137 const double depth = GetDepthAtHeight(heightCORSIKA);
139 const double density = GetDensityAtHeight(heightCORSIKA);
142 const double avgrelhumidity = 27 *
percent;
151 const double pVapor = avgrelhumidity * pSat;
153 double refracIndex = 1;
162 tabLogDepthVsHeight.
PushBack(heightOffline, 0, log(depth), minLog);
164 tabLogPressureVsHeight.
PushBack(heightOffline, 0, log(pressure), minLog);
166 tabLogDensityVsHeight.
PushBack(heightOffline, 0, log(density), minLog);
168 tabRIVsHeight.
PushBack(heightOffline, 0., log(refracIndex), minLog);
170 tabLogVaporPressureVsHeight.
PushBack(heightOffline, 0, log(pVapor), minLog);
172 tabTemperatureVsHeight.
PushBack(heightOffline, 0, temperature, 0);
174 heights.push_back(heightOffline);
175 depths.push_back(depth);
179 for (
int i = heights.size() - 1; i >= 0; --i)
180 tabHeightVsLogDepth.
PushBack(log(depths[i]), minLog, heights[i], 0);
183 *fTabLogPressureVsHeight =
186 *fTabLogVaporPressureVsHeight =
189 *fTabTemperatureVsHeight =
192 *fTabLogDensityVsHeight =
195 *fTabLogDepthVsHeight =
198 *fTabHeightVsLogDepth =
211 return *fTabLogPressureVsHeight;
220 return *fTabLogVaporPressureVsHeight;
229 return *fTabTemperatureVsHeight;
238 return *fTabLogDensityVsHeight;
247 return *fTabLogDepthVsHeight;
256 return *fTabHeightVsLogDepth;
265 return *fTabRIVsHeight;
273 const int n = fHlay.size();
274 for (
int l = 0; l < n-1; ++l)
275 if (fHlay[l] <= height && height < fHlay[l+1])
276 return fBatm[l] * exp(-height/fCatm[l]) / fCatm[l];
277 if (height >= fHlay[n-1])
278 return fBatm[n-1] / fCatm[n-1];
288 const int n = fHlay.size();
289 for (
int l = 0; l < n-1; ++l) {
290 if (fHlay[l] <= height && height < fHlay[l+1]) {
295 if (height >= fHlay[n-1])
298 const double hc = height / fCatm[section];
300 return fAatm[section] + fBatm[section] * exp(-hc);
301 return fAatm[section] - fBatm[section] * hc;
const ProfileResult & EvaluateVaporPressureVsHeight() const override
Table of H2O vapor pressure as a function of height.
const evt::AtmosphereParameters & GetAtmosphereParameters() const
Get the Atmosphere profile used to simulate the shower.
double GetDepthAtHeight(const double height) const
constexpr double atmosphere
double GladstoneDale(const double density, const double densityAtSeaLevel, const double refractiveIndexAtSeaLevel)
Calculate the refraction index for a given density.
constexpr double kDryAirMolarMass
double GetDensityAtHeight(const double height) const
Class to hold and convert a point in geodetic coordinates.
double GetCosTheta(const CoordinateSystemPtr &coordinateSystem) const
cos of zenith (theta) angle
const std::vector< double > & GetA() const
constexpr double kRefractiveIndexSeaLevel
Data structure for a radio simulation (including several SimRadioPulses)
constexpr double kOverburdenSeaLevel
#define INFO(message)
Macro for logging informational messages.
bool HasRadioSimulation() const
Check initialization of the RadioSimulation.
const std::vector< double > & GetB() const
double GetRefractiveIndexAtSeaLevel() const
const atm::ProfileResult & EvaluateDepthVsHeight() const override
Table of depth as a function of height.
Interface class to access Shower Simulated parameters.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
const atm::ProfileResult & EvaluateTemperatureVsHeight() const override
Table of temperature as a function of height.
double GetHeight() const
Get the height.
Class describing the Atmospheric profile.
utl::CoordinateSystemPtr GetGroundParticleCoordinateSystem() const
RadioSimulation & GetRadioSimulation()
Get the radio simulation data.
double SaturationVaporPressure(const double temperature)
Evaluate the saturation vapor pressure over ice or water.
void PushBack(const double x, const double xErr, const double y, const double yErr)
const atm::ProfileResult & EvaluateHeightVsDepth() const override
Table of height as a function of depth.
double LorentzLorentz(const double verticalDepth)
Calculate the refraction index for a given depth.
Base class for exceptions arising because required info not present in the Event. ...
const atm::ProfileResult & EvaluateRefractionIndexVsHeight() const override
Table of refraction index as a function of height.
constexpr double kMolarGasConstant
bool HasGeometry() const
check initialization of shower geometry
const std::vector< double > & GetLayerAltitudes() const
const atm::ProfileResult & EvaluatePressureVsHeight() const override
Table of air pressure as a function of height.
const atm::ProfileResult & EvaluateDensityVsHeight() const override
Table of density as a function of height.
const std::vector< double > & GetC() const
Class to hold the standard parameters used to specify an atmospheric profile.