Isis 3 Programmer Reference
LunarLambertEmpirical.cpp
1 #include <cmath>
3 #include "IException.h"
4 
5 namespace Isis {
6  LunarLambertEmpirical::LunarLambertEmpirical(Pvl &pvl) : PhotoModel(pvl) {
7  PvlGroup &algo = pvl.findObject("PhotometricModel")
8  .findGroup("Algorithm", Pvl::Traverse);
9  // There are no default values for the Lunar Lambert Empirical function; if user
10  // does not provide information, then an exception is thrown
11  if (algo.hasKeyword("PhaseList")) {
12  SetPhotoPhaseList(algo["PhaseList"]);
13  } else {
14  QString msg = "The empirical Lunar Lambert phase list was not provided by user";
15  throw IException(IException::User, msg, _FILEINFO_);
16  }
17  if (algo.hasKeyword("LList")) {
18  SetPhotoLList(algo["LList"]);
19  } else {
20  QString msg = "The empirical Lunar Lambert l exponent list was not provided by user";
21  throw IException(IException::User, msg, _FILEINFO_);
22  }
23  if (algo.hasKeyword("PhaseCurveList")) {
24  SetPhotoPhaseCurveList(algo["PhaseCurveList"]);
25  } else {
26  QString msg = "The empirical Lunar Lambert phase brightness list was not provided by user";
27  throw IException(IException::User, msg, _FILEINFO_);
28  }
29 
30  // Make sure all the vectors are the same size
31  p_photoPhaseAngleCount = (int)p_photoPhaseList.size();
32 
33  if (p_photoPhaseAngleCount != (int)p_photoLList.size()) {
34  QString msg = "Number of empirical Lunar Lambert l list values must be equal";
35  msg += "to number of phase angles provided";
36  throw IException(IException::User, msg, _FILEINFO_);
37  }
38 
39  if (p_photoPhaseAngleCount != (int)p_photoPhaseCurveList.size()) {
40  QString msg = "Number of empirical Lunar Lambert phase curve list values must be equal";
41  msg += "to number of phase angles provided";
42  throw IException(IException::User, msg, _FILEINFO_);
43  }
44 
45  // Create Cubic piecewise linear splines
46  p_photoLSpline.Reset();
48  p_photoLSpline.AddData(p_photoPhaseList,p_photoLList);
49  p_photoLSpline.SetCubicClampedEndptDeriv(1.0e30,1.0e30);
50  p_photoBSpline.Reset();
52  p_photoBSpline.AddData(p_photoPhaseList,p_photoPhaseCurveList);
53  p_photoBSpline.SetCubicClampedEndptDeriv(1.0e30,1.0e30);
54  }
55 
56  LunarLambertEmpirical::~LunarLambertEmpirical() {
57  p_photoLSpline.Reset();
58  p_photoBSpline.Reset();
59  p_photoPhaseList.clear();
60  p_photoLList.clear();
61  p_photoPhaseCurveList.clear();
62  }
63 
73  void LunarLambertEmpirical::SetPhotoPhaseList(QString phasestrlist) {
74  double phaseangle;
75  IString strlist(phasestrlist);
76  p_photoPhaseList.clear();
77 
78  while (strlist.length()) {
79  phaseangle = strlist.Token(",");
80  if (phaseangle < 0.0 || phaseangle > 180.0) {
81  QString msg = "Invalid value of empirical Lunar Lambert phase angle list value [" +
82  toString(phaseangle) + "]";
84  }
85  p_photoPhaseList.push_back(phaseangle);
86  }
87  }
88 
99  void LunarLambertEmpirical::SetPhotoLList(QString lstrlist) {
100  double lvalue;
101  IString strlist(lstrlist);
102  p_photoLList.clear();
103 
104  while (strlist.length()) {
105  lvalue = strlist.Token(",");
106  p_photoLList.push_back(lvalue);
107  }
108  }
109 
117  void LunarLambertEmpirical::SetPhotoPhaseCurveList(QString phasecurvestrlist) {
118  double phasecurve;
119  IString strlist(phasecurvestrlist);
120  p_photoPhaseCurveList.clear();
121 
122  while (strlist.length()) {
123  phasecurve = strlist.Token(",");
124  p_photoPhaseCurveList.push_back(phasecurve);
125  }
126  }
127 
128  double LunarLambertEmpirical::PhotoModelAlgorithm(double phase, double incidence,
129  double emission) {
130  static double pht_lunarlambert_empirical;
131  double incrad;
132  double emarad;
133  double munot;
134  double mu;
135  double lInterpolated = 0;
136  double bInterpolated = 0;
137 
138  static double old_phase = -9999;
139  static double old_incidence = -9999;
140  static double old_emission= -9999;
141 
142  // Don't need to do anything if the photometric angles are the same as before
143  if (old_phase == phase && old_incidence == incidence && old_emission == emission) {
144  return pht_lunarlambert_empirical;
145  }
146 
147  old_incidence = incidence;
148  old_emission = emission;
149 
150  incrad = incidence * Isis::PI / 180.0;
151  emarad = emission * Isis::PI / 180.0;
152  munot = cos(incrad);
153  mu = cos(emarad);
154 
155  if (phase != old_phase) {
156  lInterpolated = p_photoLSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
157  bInterpolated = p_photoBSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
158  old_phase = phase;
159  }
160 
161  if(munot <= 0.0 || mu <= 0.0) {
162  pht_lunarlambert_empirical = 0.0;
163  }
164  else if(lInterpolated == 0.0) {
165  pht_lunarlambert_empirical = munot * bInterpolated;
166  }
167  else if(lInterpolated == 1.0) {
168  pht_lunarlambert_empirical = bInterpolated * 2.0 * munot / (munot + mu);
169  }
170  else {
171  pht_lunarlambert_empirical = bInterpolated * munot * ((1.0 - lInterpolated) + 2.0 * lInterpolated / (munot + mu));
172  }
173 
174  return pht_lunarlambert_empirical;
175  }
176 }
177 
178 extern "C" Isis::PhotoModel *LunarLambertEmpiricalPlugin(Isis::Pvl &pvl) {
179  return new Isis::LunarLambertEmpirical(pvl);
180 }
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.
Empirical Lunar Lambert photometric model Derive model albedo using phase dependent Minnaert equation...
const double PI
The mathematical constant PI.
Definition: Constants.h:56
Search child objects.
Definition: PvlObject.h:170
void SetPhotoLList(QString kstrlist)
Set the empirical Lunar Lambert function L exponent list.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
void SetPhotoPhaseCurveList(QString phasecurvestrlist)
Set the empirical Lunar Lambert function phase curve list.
double Evaluate(const double a, const ExtrapType &etype=ThrowError)
Calculates interpolated or extrapolated value of tabulated data set for given domain value...
IString Token(const IString &separator)
Returns the first token in the IString.
Definition: IString.cpp:912
void Reset()
Resets the state of the object.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
void SetCubicClampedEndptDeriv(const double yp1, const double ypn)
Sets the values for the first derivatives of the endpoints of the data set.
Cubic Spline interpolation with clamped boundary conditions.
Container for cube-like labels.
Definition: Pvl.h:135
void SetInterpType(NumericalApproximation::InterpType itype)
Sets interpolation type.
void AddData(const double x, const double y)
Add a datapoint to the set.
Isis exception class.
Definition: IException.h:107
Adds specific functionality to C++ strings.
Definition: IString.h:181
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
Evaluate() attempts to extrapolate if a is outside of the domain. This is only valid for NumericalApp...