3 #include <utl/Reader.h>
4 #include <utl/ReferenceEllipsoid.h>
5 #include <utl/AugerUnits.h>
6 #include <utl/RandomEngine.h>
7 #include <utl/AugerUnits.h>
8 #include <utl/MathConstants.h>
10 #include <fwk/CentralConfig.h>
11 #include <fwk/RandomEngineRegistry.h>
13 #include <fevt/FdConstants.h>
15 #include <atm/Atmosphere.h>
16 #include <det/Detector.h>
20 #include <CLHEP/Random/Randomize.h>
21 using CLHEP::RandFlat;
31 const string modelString = topB.
GetChild(
"fAerosolModel").
Get<
string>();
32 if (modelString ==
"eLongtin")
33 fAerosolModel = eLongtin;
34 else if (modelString ==
"eHG01")
35 fAerosolModel = eHG01;
36 else if (modelString ==
"eHG05")
37 fAerosolModel = eHG05;
38 else if (modelString ==
"eHG09")
39 fAerosolModel = eHG09;
42 err <<
" Unknown aerosol model: " << modelString
43 <<
", switching to default eHG05";
45 fAerosolModel = eHG05;
55 std::vector<utl::Photon>& photonVector)
58 const atm::Atmosphere& atmo = det::Detector::GetInstance().GetAtmosphere();
63 const double Transmission = rayAtt*mieAtt;
65 AddPhotons(PointOfOrigin, PhotonDirect, Transmission, photonVector);
73 const double Transmission,
74 std::vector<utl::Photon>& photonVector)
78 INFO(
" Photon source eFluorTotal ");
87 double OptDistance = - log (Transmission);
89 if ((height > 0.) && (height < 15.) && (OptDistance < 5.)) {
97 for (
double Time = (0 *
nanosecond); Time < MaxTime; Time+=TimeBin) {
98 if (GetRandomZeta(zeta, weightfactor, Time, OptDistance, height, MaxZeta)) {
101 Photon newPhoton = PhotonDirect;
105 if (weightfactor > 1.) {
106 double weight = PhotonDirect.
GetWeight();
107 newPhoton.
SetWeight(weight * weightfactor);
113 double theta = photonDir.
GetTheta(PhotonDirCS);
114 double phi = photonDir.
GetPhi(PhotonDirCS);
121 double thetaRandom = zeta;
122 double phiRandom = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 2*
kPi);
124 Vector newphotonDir(cos(phiRandom)*sin(thetaRandom),
125 sin(phiRandom)*sin(thetaRandom),cos(thetaRandom),newCS);
130 double timeRandom = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 100.);
131 timeScatt += (Time + timeRandom *
nanosecond);
137 photonVector.push_back(newPhoton);
146 double Time,
double OptDistance,
147 double height,
double MaxZeta)
149 double A(0), B(0), C(0), D(0), E(0), F(0), G(0), H(0);
153 switch(fAerosolModel) {
155 A = (0.00152 + 0.0000165 * Time) *
pow (OptDistance, (0.0826+0.00525*Time))
156 * exp(-0.644*height) + 0.0000569 + 0.0000011 * Time;
157 B = -0.0504 * height * OptDistance + (-0.17+0.000766*Time)*OptDistance
158 - 0.0323 * height - 1.78 + 0.00814 * Time;
159 C = 3.59e-6 * OptDistance + (2.03e-7 + 1.65e-9*Time)*height + 2.44e-6 - 6.2e-8 * Time;
162 A = (0.000272 + 7.88e-6 * Time) *
pow (OptDistance, (-0.248+0.0061*Time))
163 * exp(-0.456*height) + 4.04e-5 + 1.29e-6 * Time;
164 B = -0.0372 * height * OptDistance + (-0.272+0.000413*Time)*OptDistance
165 - 0.00927 * height - 2.04 + 0.009 * Time;
166 C = 1.61e-6 * OptDistance + (-1.56e-8 + 2.82e-9*Time)*height + 1.64e-6 - 5.09e-8 * Time;
169 A = (0.00123 + 1.6e-5 * Time) *
pow (OptDistance, (0.0346+0.00544*Time))
170 * exp(-0.637*height) + 5.49e-5 + 1.15e-6 * Time;
171 B = -0.0495 * height * OptDistance + (-0.186+0.000749*Time)*OptDistance
172 - 0.0292 * height - 1.82 + 0.00831 * Time;
173 C = 2.98e-6 * OptDistance + (1.41e-7 + 2.03e-9*Time)*height + 2.3e-6 - 5.62e-8 * Time;
176 A = (0.0128 - 4.4e-5 * Time) *
pow (OptDistance, (0.607+0.0026*Time))
177 * exp(-0.43*height) + 0.000474 - 5.66e-6 * Time;
178 B = (0.0343 - 0.000747 * Time) * height * OptDistance + (-0.178+0.0023*Time)*OptDistance
179 + (-0.0132 - 0.000584 * Time) * height - 1.33 + 0.00665 * Time;
180 C = (-4.34e-6 - 1.35e-6 * Time) * OptDistance + (4.73e-6 + 2.61e-7 * Time) * height
181 - 1.18-5 - 8.11e-7 * Time;
184 ERROR(
"No valid multiple satter model specified");
188 double ScattLight = IntegralA(A,B,C,MaxZeta);
189 double ScattAngle = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
192 weightfactor = ScattLight;
193 ScattAngle *= weightfactor;
199 if (ScattAngle > ScattLight)
204 double Accuracy = 0.1*
degree;
211 double val = IntegralA(A,B,C,m);
212 if (val == ScattAngle || (l-k) < Accuracy) {
216 if (val > ScattAngle)
222 WARNING(
" maxIter reached!!! ");
228 switch(fAerosolModel) {
230 D = 128 * OptDistance * exp(-0.329 * height) *
pow (Time, -1.76);
231 E = (-81.3 * OptDistance + 21.8) * height *
pow (Time, -0.857);
232 F = 2004 * OptDistance * exp (-0.103*height) *
pow (Time, -2.22);
233 G = (-132 * height * OptDistance + 78.4 * height - 600) * pow (Time, -0.833);
234 H = 0.0207 * exp(-0.367*OptDistance) * exp(-0.371*height) *
pow(Time, (0.0812*height-1.54));
237 D = 43 * OptDistance * exp(-0.098 * height) *
pow (Time, -1.72);
238 E = (-55.4 * OptDistance + 18) * height * pow (Time, -0.829);
239 F = 2275 * OptDistance * exp (-0.0586*height) *
pow (Time, -2.26);
240 G = (-151 * height * OptDistance + 78.6 * height - 457) * pow (Time, -0.814);
241 H = 22.1 * exp(-9.99*OptDistance) * exp(-2.99*height) *
pow(Time, (0.0258*height-0.881));
244 D = 90.7 * OptDistance * exp(-0.215 * height) *
pow (Time, -1.77);
245 E = (-74.6 * OptDistance + 19.8) * height *
pow (Time, -0.863);
246 F = 4260 * OptDistance * exp (-0.297*height) *
pow (Time, -2.24);
247 G = (-130 * height * OptDistance + 77.2 * height - 613) * pow (Time, -0.829);
248 H = 0.0141 * exp(-0.286*OptDistance) * exp(-0.415*height) *
pow(Time, (0.0748*height-1.44));
251 D = 161 * OptDistance * exp(-0.068 * height) *
pow (Time, -1.45);
252 E = (-60.2 * OptDistance + 38.5) * height *
pow (Time, -0.244);
253 F = 934 * OptDistance * exp (-0.0437*height) *
pow (Time, -2.16);
254 G = (-49.5 * height * OptDistance + 7164 * height - 1340) * pow (Time, -0.824);
255 H = -0.0854 * exp(0.263*OptDistance) * exp(-0.767*height) *
pow(Time, (-1.11));
260 double ScattLight = IntegralB(D,E,F,G,H,MaxZeta);
261 double ScattAngle = RandFlat::shoot(&fRandomEngine->GetEngine(), 0.0, 1.0);
264 weightfactor = ScattLight;
265 ScattAngle *= weightfactor;
271 if (ScattAngle > ScattLight)
276 double Accuracy = 0.1*
degree;
283 double val = IntegralB(D,E,F,G,H,m);
284 if (val == ScattAngle || (l-k) < Accuracy) {
288 if (val > ScattAngle)
294 WARNING(
" maxIter reached!!! ");
303 double integr, integr0, integr1;
306 A *=
pow(57.295779513, B);
311 integr1 = log(x) - x*x/12 +
pow(x, 4)/480;
312 integr0 = log(x0) - x0*x0/12 +
pow(x0, 4)/480;
313 }
else if (B == -4) {
314 integr1 = -1/(2*x*x) - log(x)/6 + x*x/240;
315 integr0 = -1/(2*x0*x0) - log(x0)/6 + x0*x0/240;
316 }
else if (B == -6) {
317 integr1 = -1/(4*
pow(x, 4)) + 1/(12*x*x) + log(x)/120;
318 integr0 = -1/(4*
pow(x0, 4)) + 1/(12*x0*x0) + log(x0)/120;
320 integr1 =
pow(x, B)*(x*x/(2+B) -
pow(x, 4)/(6*(4+B)) +
pow(x, 6)/(120*(6+B)));
321 integr0 =
pow(x0, B)*(x0*x0/(2+B) -
pow(x0, 4)/(6*(4+B)) +
pow(x0, 6)/(120*(6+B)));
323 integr = (A * integr1 - C * cos(zeta)) - (A * integr0 - C * cos(x0*
radian));
324 integr += (A *
pow(x0, B) + C) * 1.5230867e-6;
325 integr *= 20626.48062;
327 integr = (A *
pow(x0, B) + C) * (1. - cos(zeta));
328 integr *= 20626.48062;
336 double G,
double H,
double zeta)
341 integr = -H*cos(zeta) + (D*exp(E * zeta/
radian)*(-cos(zeta)+E*sin(zeta)))/(1+E*E)
342 + (F*exp(G * zeta/
radian)*(-cos(zeta)+G*sin(zeta)))/(1+G*G)
343 - (-H - D/(1+E*E) - F/(1+G*G));
344 integr *= 20626.48062;
Top of the interface to Atmosphere information.
double IntegralA(double A, double B, double C, double zeta)
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
void AddPhotons(const utl::Point &PointOfOrigin, const utl::Photon &PhotonDirect, const utl::Point &PointOfDetection, std::vector< utl::Photon > &photonVector)
atm::AttenuationResult EvaluateMieAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
CoordinateSystemPtr GetCoordinateSystem() const
Get the coordinate system of the current internal representation.
#define INFO(message)
Macro for logging informational messages.
double GetWeight() const
weight assigned to the photon
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
double pow(const double x, const unsigned int i)
int GetSource() const
source of the photons. Should use Eye::LightSource enum types
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Class representing a document branch.
Reference ellipsoids for UTM transformations.
constexpr double nanosecond
atm::AttenuationResult EvaluateRayleighAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
Compute Rayleigh attenuation between points.
void SetSource(const int source)
Triple PointToLatitudeLongitudeHeight(const Point &thePoint) const
Convert Point to Lat/Long/Height.
static const ReferenceEllipsoid & GetWGS84()
Get the auger standard ellipsoid: wgs84.
void SetWeight(const double w)
source of the photons. Should use Eye::LightSource enum types
#define WARNING(message)
Macro for logging warning messages.
void GetData(bool &b) const
Overloads of the GetData member template function.
double GetInterval() const
Get the time interval as a double (in Auger base units)
const utl::Vector & GetDirection() const
A TimeInterval is used to represent time elapsed between two events.
bool GetRandomZeta(double &zeta, double &weightfactor, double Time, double OptDistance, double height, double MaxZeta)
static CentralConfig * GetInstance()
Use this the first time you get an instance of central configuration.
constexpr double kilometer
double IntegralB(double D, double E, double F, double G, double H, double zeta)
Main configuration utility.
double GetWavelength() const
void SetTime(const utl::TimeInterval &t)
#define ERROR(message)
Macro for logging error messages.
utl::TimeInterval GetTime() const
void SetDirection(const utl::Vector &v)
utl::Branch GetTopBranch(const std::string &id)
Get top branch for moduleConfigLink with given id (XML files)