USGS

Isis 3.0 Object Programmers' Reference

Home

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 }