Isis 3 Programmer Reference
LunarLambertEmpirical.cpp
1
5
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
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
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
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
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
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
Adds specific functionality to C++ strings.
Definition IString.h:165
IString Token(const IString &separator)
Returns the first token in the IString.
Definition IString.cpp:897
Empirical Lunar Lambert photometric model Derive model albedo using phase dependent Minnaert equation...
void SetPhotoPhaseCurveList(QString phasecurvestrlist)
Set the empirical Lunar Lambert function phase curve list.
void SetPhotoLList(QString kstrlist)
Set the empirical Lunar Lambert function L exponent list.
virtual double PhotoModelAlgorithm(double phase, double incidence, double emission)
Return photometric phase angle list.
void SetPhotoPhaseList(QString phasestrlist)
Set the empirical Lunar Lambert function phase angle list.
@ Extrapolate
Evaluate() attempts to extrapolate if a is outside of the domain. This is only valid for NumericalApp...
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
int size() const
Returns the number of values stored in this keyword.
Definition PvlKeyword.h:133
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