1.3.64
 
Loading...
Searching...
No Matches
PragueSkyModel.h
1
18// Copyright 2022 Charles University
19// SPDX-License-Identifier: Apache-2.0
20
21#include <exception>
22#include <string>
23#include <vector>
24#include <cmath>
25
26double lerp(const double from, const double to, const double factor);
27
59
60
62 // Public types
64public:
66 class DatasetNotFoundException : public std::exception {
67 private:
68 const std::string message;
69
70 public:
71 DatasetNotFoundException(const std::string &filename) : message(std::string("Dataset file ") + filename + std::string(" not found")) {
72 }
73
74 virtual const char *what() const throw() {
75 return message.c_str();
76 }
77 };
78
80 class DatasetReadException : public std::exception {
81 private:
82 const std::string message;
83
84 public:
85 DatasetReadException(const std::string &parameterName) : message(std::string("Dataset reading failed at ") + parameterName) {
86 }
87
88 virtual const char *what() const throw() {
89 return message.c_str();
90 }
91 };
92
95 class NoPolarisationException : public std::exception {
96 private:
97 const std::string message;
98
99 public:
100 NoPolarisationException() : message(std::string("The supplied dataset does not contain polarisation data")) {
101 }
102
103 virtual const char *what() const throw() {
104 return message.c_str();
105 }
106 };
107
109 class NotInitializedException : public std::exception {
110 private:
111 const std::string message;
112
113 public:
114 NotInitializedException() : message(std::string("The model is not initialized")) {
115 }
116
117 virtual const char *what() const throw() {
118 return message.c_str();
119 }
120 };
121
123 class Vector3 {
124 public:
125 double x, y, z;
126
127 Vector3() {
128 this->x = 0.0;
129 this->y = 0.0;
130 this->z = 0.0;
131 }
132
133 Vector3(double x, double y, double z) {
134 this->x = x;
135 this->y = y;
136 this->z = z;
137 }
138
139 Vector3 operator+(const Vector3 &other) const {
140 return Vector3(x + other.x, y + other.y, z + other.z);
141 }
142 Vector3 operator-(const Vector3 &other) const {
143 return Vector3(x - other.x, y - other.y, z - other.z);
144 }
145
146 Vector3 operator*(const double factor) const {
147 return Vector3(x * factor, y * factor, z * factor);
148 }
149
150 Vector3 operator/(const double factor) const {
151 return Vector3(x / factor, y / factor, z / factor);
152 }
153
154 bool isZero() const {
155 return x == 0.0 && y == 0.0 && z == 0.0;
156 }
157 };
158
160 struct Parameters {
163 double theta;
164
166 double gamma;
167
171 double shadow;
172
174 double zero;
175
179 double elevation;
180
182 double altitude;
183
187
189 double albedo;
190 };
191
194 double albedoMin;
195 double albedoMax;
196 double altitudeMin;
197 double altitudeMax;
198 double elevationMin;
199 double elevationMax;
200 double visibilityMin;
201 double visibilityMax;
202 bool polarisation;
203 int channels;
204 double channelStart;
205 double channelWidth;
206 };
207
208
210 // Private types
212private:
215 struct InterpolationParameter {
216 double factor;
217 int index;
218 };
219
221 struct AngleParameters {
222 InterpolationParameter gamma, alpha, zero;
223 };
224
226 struct ControlParameters {
228 std::array<std::vector<float>::const_iterator, 16> coefficients;
229 std::array<double, 4> interpolationFactor;
230 };
231
233 struct Metadata {
234 int rank;
235
236 int sunOffset;
237 int sunStride;
238 std::vector<double> sunBreaks;
239
240 int zenithOffset;
241 int zenithStride;
242 std::vector<double> zenithBreaks;
243
244 int emphOffset; // not used for polarisation
245 std::vector<double> emphBreaks; // not used for polarisation
246
247 int totalCoefsSingleConfig;
248 int totalCoefsAllConfigs;
249 };
250
252 struct TransmittanceParameters {
253 InterpolationParameter altitude;
254 InterpolationParameter distance;
255 };
256
257
259 // Private data
261 int channels;
262 double channelStart;
263 double channelWidth;
264
265 bool initialized;
266
267 // Total number of configurations
268 int totalConfigs;
269
270 // Number of configurations skipped from the beginning of the radiance/polarisation coefficients part
271 // of the dataset file (if loading of just one visibility was requested)
272 int skippedConfigsBegin;
273
274 // Number of configurations skipped till the end of the radiance/polarisation coefficients part
275 // of the dataset file (if loading of just one visibility was requested)
276 int skippedConfigsEnd;
277
278 // Metadata common for radiance and polarisation
279
280 std::vector<double> visibilitiesRad;
281 std::vector<double> albedosRad;
282 std::vector<double> altitudesRad;
283 std::vector<double> elevationsRad;
284
285 // Radiance metadata
286
287 Metadata metadataRad;
288
289 // Radiance data
290 //
291 // Structure:
292 // [[[[[[ sunCoefsRad (sunBreaksCountRad * float),
293 // zenithCoefsRad (zenithBreaksCountRad * float) ] * rankRad,
294 // emphCoefsRad (emphBreaksCountRad * float) ]
295 // * channels ] * elevationCount ] * altitudeCount ] * albedoCount ] * visibilityCount
296
297 std::vector<float> dataRad;
298
299 // Polarisation metadata
300
301 Metadata metadataPol;
302
303 // Polarisation data
304 //
305 // Struture:
306 // [[[[[[ sunCoefsPol (sunBreaksCountPol * float),
307 // zenithCoefsPol (zenithBreaksCountPol * float) ] * rankPol]
308 // * channels ] * elevationCount ] * altitudeCount ] * albedoCount ] * visibilityCount
309
310 std::vector<float> dataPol;
311
312 // Transmittance metadata
313
314 int aDim;
315 int dDim;
316 int rankTrans;
317 std::vector<double> altitudesTrans;
318 std::vector<double> visibilitiesTrans;
319
320 // Transmittance data
321
322 std::vector<float> dataTransU;
323 std::vector<float> dataTransV;
324
325
327 // Public methods
329public:
330 PragueSkyModel() : initialized(false) {};
331
341 void initialize(const std::string &filename, const double singleVisibility = 0.0);
342
343 bool isInitialized() const {
344 return initialized;
345 }
346
350 AvailableData getAvailableData() const;
351
360 Parameters computeParameters(const Vector3 &viewPoint, const Vector3 &viewDirection, const double groundLevelSolarElevationAtOrigin, const double groundLevelSolarAzimuthAtOrigin, const double visibility, const double albedo) const;
361
366 double skyRadiance(const Parameters &params, const double wavelength) const;
367
374 double sunRadiance(const Parameters &params, const double wavelength) const;
375
383 double polarisation(const Parameters &params, const double wavelength) const;
384
393 double transmittance(const Parameters &params, const double wavelength, const double distance) const;
394
395
397 // Private methods
399private:
407 void readRadiance(FILE *handle, const double singleVisibility);
408
411 void readTransmittance(FILE *handle);
412
415 void readPolarisation(FILE *handle);
416
417 // Sky radiance and polarisation
418
421 std::vector<float>::const_iterator getCoefficients(const std::vector<float> &dataset, const int totalCoefsSingleConfig, const int elevation, const int altitude, const int visibility, const int albedo, const int wavelength) const;
422
425 template<int TOffset, int TLevel>
426 double interpolate(const AngleParameters &angleParameters, const ControlParameters &controlParameters, const Metadata &metadata) const {
430 if constexpr (TLevel == 4) {
431 return reconstruct(angleParameters, controlParameters.coefficients[TOffset], metadata);
432 } else {
433 // Compute the first value
434 const double resultLow = interpolate<TOffset, TLevel + 1>(angleParameters, controlParameters, metadata);
435
436 // Skip the second value if not useful or not available.
437 if (controlParameters.interpolationFactor[TLevel] < 1e-6) {
438 return resultLow;
439 }
440
441 // Compute the second value
442 const double resultHigh = interpolate<TOffset + (1 << (3 - TLevel)), TLevel + 1>(angleParameters, controlParameters, metadata);
443
445 return lerp(resultLow, resultHigh, controlParameters.interpolationFactor[TLevel]);
446 }
447 }
448
451 double reconstruct(const AngleParameters &angleParameters, const std::vector<float>::const_iterator controlParameters, const Metadata &metadata) const;
452
457 InterpolationParameter getInterpolationParameter(const double queryVal, const std::vector<double> &breaks) const;
458
460 double evaluateModel(const Parameters &params, const double wavelength, const std::vector<float> &data, const Metadata &metadata) const;
461
462 // Transmittance
463
466 std::vector<float>::const_iterator getCoefficientsTransBase(const int altitude, const int a, const int d) const;
467
470 std::vector<float>::const_iterator getCoefficientsTrans(const int visibility, const int altitude, const int wavelength) const;
471
473 double interpolateTrans(const int visibilityIndex, const InterpolationParameter altitudeParam, const TransmittanceParameters transParams, const int channelIndex) const;
474
477 double reconstructTrans(const int visibilityIndex, const int altitudeIndex, const TransmittanceParameters transParams, const int channelIndex) const;
478
480 InterpolationParameter getInterpolationParameterTrans(const double value, const int paramCount, const int power) const;
481
484 TransmittanceParameters toTransmittanceParams(const double theta, const double distance, const double altitude) const;
485};