testParametricXMLMieModel.cc
Go to the documentation of this file.
1 
10 #include <cppunit/extensions/HelperMacros.h>
11 #include <det/Detector.h>
12 #include <fdet/FDetector.h>
13 #include <fdet/Eye.h>
14 #include <fwk/CoordinateSystemRegistry.h>
15 
16 #include <atm/AerosolDB.h>
17 #include <atm/AttenuationResult.h>
18 #include <atm/ScatteringResult.h>
19 
20 #include <atm/ParametricXMLMieModel.h>
21 
22 #include <fwk/CentralConfig.h>
23 
24 #include <utl/TimeStamp.h>
25 #include <utl/UTCDateTime.h>
26 #include <utl/ErrorLogger.h>
27 #include <utl/Point.h>
28 #include <utl/TabulatedFunctionErrors.h>
29 #include <utl/ReferenceEllipsoid.h>
30 
31 #include <tst/Verify.h>
32 
33 #include <iostream>
34 
35 using namespace std;
36 using namespace det;
37 using namespace atm;
38 using namespace fwk;
39 using namespace utl;
40 using namespace tst;
41 
42 
43 class testParametricXMLMieModel : public CppUnit::TestFixture {
44 
45  CPPUNIT_TEST_SUITE(testParametricXMLMieModel);
46  CPPUNIT_TEST(testAttenuation);
47  CPPUNIT_TEST(testScattering);
48  CPPUNIT_TEST(testExpertMode);
49  CPPUNIT_TEST_SUITE_END();
50 
51 public:
52  void
54  {
55  CentralConfig::GetInstance(BOOTSTRAPFILE);
56  ErrorLogger::GetInstance().SetVerbosity(Verbosity::eVerbose);
57  }
58 
59  void tearDown() { }
60 
61  void
63  {
64  Detector::GetInstance().Update(UTCDateTime(2005,1,1,0,0,0).GetTimeStamp());
65 
66  CoordinateSystemPtr CSll =
67  Detector::GetInstance().GetFDetector().GetEye("Los Leones").GetLocalCoordinateSystem();
68 
69  ReferenceEllipsoid wgs84(ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84));
70 
71  //
72  // To test scattering and attenuation we define several
73  // points in the sky and compute scattering/attenuation between
74  // different pairs. Points are also defined in >1 coordinate system
75  // to ensure that the calculations are not CS dependent.
76  //
77  // 5 points are defined, arranged as indicated (schematically) below.
78  //
79  // C
80  //
81  //
82  //
83  //
84  // B D E
85  //
86  // A -------- z=0 in local CS ----------
87  //
88 
89  Point All(0., 0., 0., CSll);
90  Point Bll(0., 0., 2600.*m, CSll);
91  Point Cll(0., 0., 9000.*m, CSll);
92  Point Dll(0., 2000.*m, 2600.*m, CSll);
93  Point Ell(0., 9000.*m, 2600.*m, CSll);
94 
95  CoordinateSystemPtr CSst( Detector::GetInstance().GetSiteCoordinateSystem() );
96  Point Cst(0., 0., 10000.*m, CSst);
97 
98  vector<double> wlength;
99  wlength.push_back(300.*nanometer);
100  wlength.push_back(350.*nanometer);
101  wlength.push_back(400.*nanometer);
102 
103 
104  const Atmosphere& theAtm = Detector::GetInstance().GetAtmosphere();
105 
106  AttenuationResult attABll = theAtm.EvaluateMieAttenuation(All,
107  Bll,
108  wlength);
109  CPPUNIT_ASSERT(Verify<CloseTo>(attABll.GetTransmissionFactor().Y(300.*nanometer), 0.915745));
110 
111  AttenuationResult attACll = theAtm.EvaluateMieAttenuation(All,
112  Cll,
113  wlength);
114  CPPUNIT_ASSERT(Verify<CloseTo>(attACll.GetTransmissionFactor().Y(300.*nanometer), 0.906834));
115 
116  AttenuationResult attADll = theAtm.EvaluateMieAttenuation(All,
117  Dll,
118  wlength);
119  CPPUNIT_ASSERT(Verify<CloseTo>(attADll.GetTransmissionFactor().Y(300.*nanometer), 0.894906));
120 
121  AttenuationResult attBDll = theAtm.EvaluateMieAttenuation(Bll,
122  Dll,
123  wlength);
124  CPPUNIT_ASSERT(Verify<CloseTo>(attBDll.GetTransmissionFactor().Y(300.*nanometer), 0.980601));
125 
126  AttenuationResult attBEll = theAtm.EvaluateMieAttenuation(Bll,
127  Ell,
128  wlength);
129  CPPUNIT_ASSERT(Verify<CloseTo>(attBEll.GetTransmissionFactor().Y(300.*nanometer), 0.915878));
130 
131  //
132  // Calculate distance between sea level and a fixed height above sea level using two different
133  // coordinate systems. The results should be identical (modulo difference in
134  // the vertical due to earth curvature). This test turns up error if, for eg.,
135  // you use GetZ(some CS) rather than the height above reference ellipsoid
136  // in ParametricXMLRayleighModel::GDistance
137  //
138  double heightSLll = ( (ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84)).
139  PointToLatitudeLongitudeHeight( Point(0., 0., 0., CSll)) ).get<2>();
140  double heightSLst = ( (ReferenceEllipsoid::Get(ReferenceEllipsoid::eWGS84)).
141  PointToLatitudeLongitudeHeight( Point(0., 0., 0., CSst)) ).get<2>();
142 
143  AttenuationResult attCGroundLl
144  = theAtm.EvaluateRayleighAttenuation(Point(0., 0., 0., CSll),
145  Point(0., 0., 10000*m, CSll),
146  wlength);
147  AttenuationResult attCGroundSt
148  = theAtm.EvaluateRayleighAttenuation(Point(0., 0., heightSLll - heightSLst, CSst),
149  Point(0., 0., heightSLll - heightSLst + 10000.*m, CSst),
150  wlength);
151 
152  CPPUNIT_ASSERT(Verify<CloseTo>( attCGroundLl.GetTransmissionFactor().Y(300.*nanometer),
153  attCGroundSt.GetTransmissionFactor().Y(300.*nanometer)));
154 
155  }
156 
157  void
159  {
160  Detector::GetInstance().Update(UTCDateTime(2005,1,1,0,0,0).GetTimeStamp());
161  const Atmosphere& theAtm = Detector::GetInstance().GetAtmosphere();
162 
163  vector<double> wlength;
164  wlength.push_back(300*nanometer);
165  wlength.push_back(350*nanometer);
166  wlength.push_back(400*nanometer);
167 
169  CSll(Detector::GetInstance().GetFDetector().GetEye("Los Leones").GetLocalCoordinateSystem() );
170 
171  Point pointA(0., 0. , 0., CSll);
172  Point pointB(0., 0. , 1400.*m, CSll);
173  Point pointC(0., 600.*m, 1600.*m, CSll);
174 
175  // vary angle
176  //
177  AttenuationResult attAB1=
178  theAtm.EvaluateMieAttenuation(pointA, pointB, wlength);
179 
180  ScatteringResult scatAB1 =
181  theAtm.EvaluateMieScattering(pointA, pointB,
182  20.*degree, 1.*km, wlength);
183  CPPUNIT_ASSERT(Verify<CloseTo>(1.e8*scatAB1.GetScatteringFactor().Y(400.*nanometer), 2.70631, 1.e-5));
184 
185  ScatteringResult scatAB2 =
186  theAtm.EvaluateMieScattering(pointA, pointB,
187  30.*degree, 1.*km, wlength);
188  CPPUNIT_ASSERT(Verify<CloseTo>(1.e8*scatAB2.GetScatteringFactor().Y(400.*nanometer), 1.35966, 1.e-5));
189 
190  ScatteringResult scatAB3 =
191  theAtm.EvaluateMieScattering(pointA, pointB,
192  40.*degree, 1.*km, wlength);
193  CPPUNIT_ASSERT(Verify<CloseTo>(1.e9*scatAB3.GetScatteringFactor().Y(400.*nanometer), 7.3915, 1.e-5));
194 
195  ScatteringResult scatAB4 =
196  theAtm.EvaluateMieScattering(pointA, pointB,
197  60.*degree, 1.*km, wlength);
198  CPPUNIT_ASSERT(Verify<CloseTo>(1.e9*scatAB4.GetScatteringFactor().Y(400.*nanometer), 2.69556, 1.e-5));
199 
200  // vary distance
201  //
202  ScatteringResult scatAB5 =
203  theAtm.EvaluateMieScattering(pointA, pointB,
204  30.*degree, 10.*km, wlength);
205  CPPUNIT_ASSERT(Verify<CloseTo>(1.e11*scatAB5.GetScatteringFactor().Y(400*nanometer),
206  13.5966, 1.e-5));
207 
208  ScatteringResult scatAB6 =
209  theAtm.EvaluateMieScattering(pointA, pointB,
210  60.*degree, 10.*km, wlength);
211  CPPUNIT_ASSERT(Verify<CloseTo>(1e11*scatAB6.GetScatteringFactor().Y(400*nanometer),
212  2.69556, 1.e-5));
213 
214 
215  // new pair of points (at same altitude)
216  //
217  ScatteringResult scatBC1 =
218  theAtm.EvaluateMieScattering(pointB, pointC,
219  40.*degree, 1.*km, wlength);
220  CPPUNIT_ASSERT(Verify<CloseTo>(1.e8*scatBC1.GetScatteringFactor().Y(400*nanometer),
221  0.214726, 1.e-5));
222 
223  ScatteringResult scatBC2 =
224  theAtm.EvaluateMieScattering(pointB, pointC,
225  50.*degree, 1.*km, wlength);
226  CPPUNIT_ASSERT(Verify<CloseTo>(1.e8*scatBC2.GetScatteringFactor().Y(400*nanometer),
227  0.126153, 1.e-5));
228 
229  ScatteringResult scatBC3 =
230  theAtm.EvaluateMieScattering(pointB, pointC,
231  60.*degree, 1.*km, wlength);
232  CPPUNIT_ASSERT(Verify<CloseTo>(1.e10*scatBC3.GetScatteringFactor().Y(400*nanometer),
233  7.83072, 1.e-5));
234 
235  ScatteringResult scatBC4 =
236  theAtm.EvaluateMieScattering(pointB, pointC,
237  90.*degree, 1.*km, wlength);
238  CPPUNIT_ASSERT(Verify<CloseTo>(1.e10*scatBC4.GetScatteringFactor().Y(400*nanometer),
239  2.32344, 1.e-5));
240 
241  // vary wavelengths
242  //
243  CPPUNIT_ASSERT(Verify<CloseTo>(1.e8*scatAB1.GetScatteringFactor().Y(300.*nanometer), 3.57936, 1.e-5));
244  CPPUNIT_ASSERT(Verify<CloseTo>(1.e8*scatAB1.GetScatteringFactor().Y(350.*nanometer), 3.08222, 1.e-5));
245 
246  // check angle returned
247  //
248  CPPUNIT_ASSERT(Verify<CloseTo>(scatAB1.GetScatteringAngle(), 20.*degree));
249  CPPUNIT_ASSERT(Verify<CloseTo>(scatAB2.GetScatteringAngle(), 30.*degree));
250  }
251 
252  void
254  {
255  ParametricXMLMieModel myModel;
256  myModel.Init();
257 
258  CPPUNIT_ASSERT(Verify<Equal>(myModel.GetHorizAttLength(),24000.*meter));
259  CPPUNIT_ASSERT(Verify<Equal>(myModel.GetMixHeight(),1000.*meter));
260  CPPUNIT_ASSERT(Verify<Equal>(myModel.GetScaleHeight(),1000.*meter));
261  CPPUNIT_ASSERT(Verify<Equal>(myModel.GetAngstromCoeff(),1.));
262 
263  vector<double> wlength;
264  wlength.push_back(300*nanometer);
265  wlength.push_back(350*nanometer);
266  wlength.push_back(400*nanometer);
267 
269  CSll(Detector::GetInstance().GetFDetector().GetEye("Los Leones").GetLocalCoordinateSystem() );
270 
271  Point pointA(0., 0. , 0., CSll);
272  Point pointB(0., 0. , 1400.*m, CSll);
273 
274  ScatteringResult scatAB1 =
275  myModel.EvaluateMieScattering(pointA, pointB,
276  20.*degree, 1.*km, wlength);
277  CPPUNIT_ASSERT(Verify<CloseTo>(1.e8*scatAB1.GetScatteringFactor().Y(400.*nanometer), 2.70631, 1.e-5));
278 
279  myModel.SetHorizAttLength(100.*meter);
280  myModel.SetScaleHeight(1000.*meter);
281 
282  CPPUNIT_ASSERT(Verify<Equal>(myModel.GetHorizAttLength(),100.*meter));
283  CPPUNIT_ASSERT(Verify<Equal>(myModel.GetScaleHeight(),1000.*meter));
284  }
285 
286 };
287 
288 
290 
291 
292 // Configure (x)emacs for this file ...
293 // Local Variables:
294 // mode:c++
295 // compile-command: "make -C .. -k"
296 // End:
double GetScatteringAngle() const
Get calculated scattering angle.
Top of the interface to Atmosphere information.
const double degree
Point object.
Definition: Point.h:32
atm::AttenuationResult EvaluateMieAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
const utl::TabulatedFunctionErrors & GetTransmissionFactor() const
Transmission factor.
const double meter
Definition: GalacticUnits.h:29
Traditional name.
Definition: Verbosity.h:17
CPPUNIT_TEST_SUITE_REGISTRATION(testAiresShowerFile)
constexpr double nanometer
Definition: AugerUnits.h:102
Class holding the output of the ScatteringResult function.
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
Reference ellipsoids for UTM transformations.
atm::AttenuationResult EvaluateRayleighAttenuation(const utl::Point &xInit, const utl::Point &xFinal, const std::vector< double > &wLength) const
Compute Rayleigh attenuation between points.
const double km
const utl::TabulatedFunctionErrors & GetScatteringFactor() const
Scattering factor.
void SetHorizAttLength(const double lMix)
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
Class for computing aerosol scattering and attenuation using simple parameterizations.
double Y(const double x) const
Get or interpolate the Y value that corresponds to parameter x.
constexpr double m
Definition: AugerUnits.h:121
atm::ScatteringResult EvaluateMieScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &wLength) const
Aerosol scattering fraction in a wavelength band.
Class describing the Atmospheric attenuation.
void SetScaleHeight(const double hScl)
atm::ScatteringResult EvaluateMieScattering(const utl::Point &xA, const utl::Point &xB, const double angle, const double distance, const std::vector< double > &xLength) const

, generated on Tue Sep 26 2023.