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 
11 namespace 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();
54  p_photoLSpline.AddData(p_photoPhaseList,p_photoLList);
55  p_photoLSpline.SetCubicClampedEndptDeriv(1.0e30,1.0e30);
56  p_photoBSpline.Reset();
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 
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 
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 
269 extern "C" Isis::PhotoModel *LunarLambertEmpiricalPlugin(Isis::Pvl &pvl) {
270  return new Isis::LunarLambertEmpirical(pvl);
271 }
Isis::NumericalApproximation::SetInterpType
void SetInterpType(NumericalApproximation::InterpType itype)
Sets interpolation type.
Definition: NumericalApproximation.cpp:2319
Isis::NumericalApproximation::Extrapolate
@ Extrapolate
Evaluate() attempts to extrapolate if a is outside of the domain. This is only valid for NumericalApp...
Definition: NumericalApproximation.h:814
Isis::LunarLambertEmpirical::SetPhotoLList
void SetPhotoLList(QString kstrlist)
Set the empirical Lunar Lambert function L exponent list.
Definition: LunarLambertEmpirical.cpp:140
Isis::PhotoModel
Definition: PhotoModel.h:41
Isis::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::LunarLambertEmpirical::SetPhotoPhaseCurveList
void SetPhotoPhaseCurveList(QString phasecurvestrlist)
Set the empirical Lunar Lambert function phase curve list.
Definition: LunarLambertEmpirical.cpp:184
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::NumericalApproximation::CubicClamped
@ CubicClamped
Cubic Spline interpolation with clamped boundary conditions.
Definition: NumericalApproximation.h:735
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
Isis::NumericalApproximation::SetCubicClampedEndptDeriv
void SetCubicClampedEndptDeriv(const double yp1, const double ypn)
Sets the values for the first derivatives of the endpoints of the data set.
Definition: NumericalApproximation.cpp:565
Isis::NumericalApproximation::AddData
void AddData(const double x, const double y)
Add a datapoint to the set.
Definition: NumericalApproximation.cpp:440
Isis::NumericalApproximation::Evaluate
double Evaluate(const double a, const ExtrapType &etype=ThrowError)
Calculates interpolated or extrapolated value of tabulated data set for given domain value.
Definition: NumericalApproximation.cpp:836
Isis::IString::Token
IString Token(const IString &separator)
Returns the first token in the IString.
Definition: IString.cpp:897
Isis::PvlKeyword::size
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:125
Isis::LunarLambertEmpirical::PhotoModelAlgorithm
virtual double PhotoModelAlgorithm(double phase, double incidence, double emission)
Return photometric phase angle list.
Definition: LunarLambertEmpirical.cpp:219
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::LunarLambertEmpirical::SetPhotoPhaseList
void SetPhotoPhaseList(QString phasestrlist)
Set the empirical Lunar Lambert function phase angle list.
Definition: LunarLambertEmpirical.cpp:80
Isis::NumericalApproximation::Reset
void Reset()
Resets the state of the object.
Definition: NumericalApproximation.cpp:2251
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::LunarLambertEmpirical
Empirical Lunar Lambert photometric model Derive model albedo using phase dependent Minnaert equation...
Definition: LunarLambertEmpirical.h:47
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126