Isis 3 Programmer Reference
LunarLambertEmpirical.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <cmath>
8#include "LunarLambertEmpirical.h"
9#include "IException.h"
10
11namespace Isis {
12 LunarLambertEmpirical::LunarLambertEmpirical(Pvl &pvl) : PhotoModel(pvl) {
13 PvlGroup &algo = pvl.findObject("PhotometricModel")
14 .findGroup("Algorithm", Pvl::Traverse);
15 // There are no default values for the Lunar Lambert Empirical function; if user
16 // does not provide information, then an exception is thrown
17 if (algo.hasKeyword("PhaseList")) {
18 SetPhotoPhaseList(algo["PhaseList"]);
19 } else {
20 QString msg = "The empirical Lunar Lambert phase list was not provided by user";
21 throw IException(IException::User, msg, _FILEINFO_);
22 }
23 if (algo.hasKeyword("LList")) {
24 SetPhotoLList(algo["LList"]);
25 } else {
26 QString msg = "The empirical Lunar Lambert l exponent list was not provided by user";
27 throw IException(IException::User, msg, _FILEINFO_);
28 }
29 if (algo.hasKeyword("PhaseCurveList")) {
30 SetPhotoPhaseCurveList(algo["PhaseCurveList"]);
31 } else {
32 QString msg = "The empirical Lunar Lambert phase brightness list was not provided by user";
33 throw IException(IException::User, msg, _FILEINFO_);
34 }
35
36 // Make sure all the vectors are the same size
37 p_photoPhaseAngleCount = (int)p_photoPhaseList.size();
38
39 if (p_photoPhaseAngleCount != (int)p_photoLList.size()) {
40 QString msg = "Number of empirical Lunar Lambert l list values must be equal";
41 msg += "to number of phase angles provided";
42 throw IException(IException::User, msg, _FILEINFO_);
43 }
44
45 if (p_photoPhaseAngleCount != (int)p_photoPhaseCurveList.size()) {
46 QString msg = "Number of empirical Lunar Lambert phase curve list values must be equal";
47 msg += "to number of phase angles provided";
48 throw IException(IException::User, msg, _FILEINFO_);
49 }
50
51 // Create Cubic piecewise linear splines
52 p_photoLSpline.Reset();
53 p_photoLSpline.SetInterpType(NumericalApproximation::CubicClamped);
54 p_photoLSpline.AddData(p_photoPhaseList,p_photoLList);
55 p_photoLSpline.SetCubicClampedEndptDeriv(1.0e30,1.0e30);
56 p_photoBSpline.Reset();
57 p_photoBSpline.SetInterpType(NumericalApproximation::CubicClamped);
58 p_photoBSpline.AddData(p_photoPhaseList,p_photoPhaseCurveList);
59 p_photoBSpline.SetCubicClampedEndptDeriv(1.0e30,1.0e30);
60 }
61
62 LunarLambertEmpirical::~LunarLambertEmpirical() {
63 p_photoLSpline.Reset();
64 p_photoBSpline.Reset();
65 p_photoPhaseList.clear();
66 p_photoLList.clear();
67 p_photoPhaseCurveList.clear();
68 }
69
70
80 void LunarLambertEmpirical::SetPhotoPhaseList(QString phasestrlist) {
81 double phaseangle;
82 IString strlist(phasestrlist);
83 p_photoPhaseList.clear();
84
85 while (strlist.length()) {
86 phaseangle = strlist.Token(",");
87 if (phaseangle < 0.0 || phaseangle > 180.0) {
88 QString msg = "Invalid value of empirical Lunar Lambert phase angle list value [" +
89 toString(phaseangle) + "]";
90 throw IException(IException::User, msg, _FILEINFO_);
91 }
92 p_photoPhaseList.push_back(phaseangle);
93 }
94 }
95
96
106 void LunarLambertEmpirical::SetPhotoPhaseList(PvlKeyword phaseList) {
107
108 // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5)
109 if (phaseList.size() == 1) {
110 SetPhotoPhaseList(QString(phaseList));
111 return;
112 }
113
114 double phaseAngle;
115 p_photoPhaseList.clear();
116
117 for (int i=0; i< phaseList.size(); i++) {
118 phaseAngle = phaseList[i].toDouble();
119
120 if (phaseAngle < 0.0 || phaseAngle > 180.0) {
121 QString msg = "Invalid value of empirical Lunar Lambert phase angle list value [" +
122 toString(phaseAngle) + "]";
123 throw IException(IException::User, msg, _FILEINFO_);
124 }
125 p_photoPhaseList.push_back(phaseAngle);
126 }
127 }
128
129
140 void LunarLambertEmpirical::SetPhotoLList(QString lstrlist) {
141 double lvalue;
142 IString strlist(lstrlist);
143 p_photoLList.clear();
144
145 while (strlist.length()) {
146 lvalue = strlist.Token(",");
147 p_photoLList.push_back(lvalue);
148 }
149 }
150
151
162 void LunarLambertEmpirical::SetPhotoLList(PvlKeyword lstrList) {
163
164 // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5)
165 if (lstrList.size() == 1) {
166 SetPhotoLList(QString(lstrList));
167 return;
168 }
169
170 p_photoLList.clear();
171 for (int i=0; i<lstrList.size(); i++) {
172 p_photoLList.push_back(lstrList[i].toDouble());
173 }
174 }
175
176
184 void LunarLambertEmpirical::SetPhotoPhaseCurveList(QString phasecurvestrlist) {
185 double phasecurve;
186 IString strlist(phasecurvestrlist);
187 p_photoPhaseCurveList.clear();
188
189 while (strlist.length()) {
190 phasecurve = strlist.Token(",");
191 p_photoPhaseCurveList.push_back(phasecurve);
192 }
193 }
194
195
204 void LunarLambertEmpirical::SetPhotoPhaseCurveList(PvlKeyword photocurvestrList) {
205
206 // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5)
207 if (photocurvestrList.size() == 1) {
208 SetPhotoPhaseCurveList(QString(photocurvestrList));
209 return;
210 }
211
212 p_photoPhaseCurveList.clear();
213 for (int i=0; i<photocurvestrList.size(); i++) {
214 p_photoPhaseCurveList.push_back(photocurvestrList[i].toDouble());
215 }
216 }
217
218
219 double LunarLambertEmpirical::PhotoModelAlgorithm(double phase, double incidence,
220 double emission) {
221 static double pht_lunarlambert_empirical;
222 double incrad;
223 double emarad;
224 double munot;
225 double mu;
226 double lInterpolated = 0;
227 double bInterpolated = 0;
228
229 static double old_phase = -9999;
230 static double old_incidence = -9999;
231 static double old_emission= -9999;
232
233 // Don't need to do anything if the photometric angles are the same as before
234 if (old_phase == phase && old_incidence == incidence && old_emission == emission) {
235 return pht_lunarlambert_empirical;
236 }
237
238 old_incidence = incidence;
239 old_emission = emission;
240
241 incrad = incidence * Isis::PI / 180.0;
242 emarad = emission * Isis::PI / 180.0;
243 munot = cos(incrad);
244 mu = cos(emarad);
245
246 if (phase != old_phase) {
247 lInterpolated = p_photoLSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
248 bInterpolated = p_photoBSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
249 old_phase = phase;
250 }
251
252 if(munot <= 0.0 || mu <= 0.0) {
253 pht_lunarlambert_empirical = 0.0;
254 }
255 else if(lInterpolated == 0.0) {
256 pht_lunarlambert_empirical = munot * bInterpolated;
257 }
258 else if(lInterpolated == 1.0) {
259 pht_lunarlambert_empirical = bInterpolated * 2.0 * munot / (munot + mu);
260 }
261 else {
262 pht_lunarlambert_empirical = bInterpolated * munot * ((1.0 - lInterpolated) + 2.0 * lInterpolated / (munot + mu));
263 }
264
265 return pht_lunarlambert_empirical;
266 }
267}
268
269extern "C" Isis::PhotoModel *LunarLambertEmpiricalPlugin(Isis::Pvl &pvl) {
270 return new Isis::LunarLambertEmpirical(pvl);
271}
Isis exception class.
Definition IException.h:91
Adds specific functionality to C++ strings.
Definition IString.h:165
Empirical Lunar Lambert photometric model Derive model albedo using phase dependent Minnaert equation...
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149
const double PI
The mathematical constant PI.
Definition Constants.h:40