Isis 3 Programmer Reference
MinnaertEmpirical.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include <cmath>
8 #include "MinnaertEmpirical.h"
9 #include "IException.h"
10 
11 namespace Isis {
12  MinnaertEmpirical::MinnaertEmpirical(Pvl &pvl) : PhotoModel(pvl) {
13  PvlGroup &algo = pvl.findObject("PhotometricModel")
14  .findGroup("Algorithm", Pvl::Traverse);
15  // There are no default values for the Minnaert 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  std::string msg = "The empirical Minnaert phase list was not provided by user";
21  throw IException(IException::User, msg, _FILEINFO_);
22  }
23  if (algo.hasKeyword("KList")) {
24  SetPhotoKList(algo["KList"]);
25  } else {
26  std::string msg = "The empirical Minnaert k 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  std::string msg = "The empirical Minnaert 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_photoKList.size()) {
40  std::string msg = "Number of empirical Minnaert k 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  std::string msg = "Number of empirical Minnaert 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_photoKSpline.Reset();
54  p_photoKSpline.AddData(p_photoPhaseList,p_photoKList);
55  p_photoKSpline.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  MinnaertEmpirical::~MinnaertEmpirical() {
63  p_photoKSpline.Reset();
64  p_photoBSpline.Reset();
65  p_photoPhaseList.clear();
66  p_photoKList.clear();
67  p_photoPhaseCurveList.clear();
68  }
69 
79  void MinnaertEmpirical::SetPhotoPhaseList(QString phasestrlist) {
80  double phaseangle;
81  IString strlist(phasestrlist);
82  p_photoPhaseList.clear();
83 
84  while (strlist.length()) {
85  phaseangle = strlist.Token(",");
86  if (phaseangle < 0.0 || phaseangle > 180.0) {
87  std::string msg = "Invalid value of empirical Minnaert phase angle list value [" +
88  IString(phaseangle) + "]";
89  throw IException(IException::User, msg, _FILEINFO_);
90  }
91  p_photoPhaseList.push_back(phaseangle);
92  }
93  }
94 
104  void MinnaertEmpirical::SetPhotoKList(QString kstrlist) {
105  double kvalue;
106  IString strlist(kstrlist);
107  p_photoKList.clear();
108 
109  while (strlist.length()) {
110  kvalue = strlist.Token(",");
111  if (kvalue < 0.0) {
112  std::string msg = "Invalid value of Minnaert k list value [" +
113  IString(kvalue) + "]";
114  throw IException(IException::User, msg, _FILEINFO_);
115  }
116  p_photoKList.push_back(kvalue);
117  }
118  }
119 
127  void MinnaertEmpirical::SetPhotoPhaseCurveList(QString phasecurvestrlist) {
128  double phasecurve;
129  IString strlist(phasecurvestrlist);
130  p_photoPhaseCurveList.clear();
131 
132  while (strlist.length()) {
133  phasecurve = strlist.Token(",");
134  p_photoPhaseCurveList.push_back(phasecurve);
135  }
136  }
137 
138  double MinnaertEmpirical::PhotoModelAlgorithm(double phase, double incidence,
139  double emission) {
140  static double pht_minnaert_empirical;
141  double incrad;
142  double emarad;
143  double munot;
144  double mu;
145  double kInterpolated = 0;
146  double bInterpolated = 0;
147 
148  static double old_phase = -9999;
149  static double old_incidence = -9999;
150  static double old_emission= -9999;
151 
152  // Don't need to do anything if the photometric angles are the same as before
153  if (old_phase == phase && old_incidence == incidence && old_emission == emission) {
154  return pht_minnaert_empirical;
155  }
156 
157  old_incidence = incidence;
158  old_emission = emission;
159 
160  incrad = incidence * Isis::PI / 180.0;
161  emarad = emission * Isis::PI / 180.0;
162  munot = cos(incrad);
163  mu = cos(emarad);
164 
165  if (phase != old_phase) {
166  kInterpolated = p_photoKSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
167  bInterpolated = p_photoBSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
168  old_phase = phase;
169  }
170 
171  if(munot <= 0.0 || mu <= 0.0 || incidence == 90.0 ||
172  emission == 90.0) {
173  pht_minnaert_empirical = 0.0;
174  }
175  else if(kInterpolated == 1.0) {
176  pht_minnaert_empirical = munot * bInterpolated;
177  }
178  else {
179  pht_minnaert_empirical = bInterpolated * munot * pow((munot * mu), (kInterpolated - 1.0));
180  }
181 
182  return pht_minnaert_empirical;
183  }
184 }
185 
186 extern "C" Isis::PhotoModel *MinnaertEmpiricalPlugin(Isis::Pvl &pvl) {
187  return new Isis::MinnaertEmpirical(pvl);
188 }
Isis::NumericalApproximation::SetInterpType
void SetInterpType(NumericalApproximation::InterpType itype)
Sets interpolation type.
Definition: NumericalApproximation.cpp:2319
Isis::MinnaertEmpirical::SetPhotoPhaseCurveList
void SetPhotoPhaseCurveList(QString phasecurvestrlist)
Set the empirical Minnaert function phase curve list.
Definition: MinnaertEmpirical.cpp:127
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::PhotoModel
Definition: PhotoModel.h:41
Isis::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::MinnaertEmpirical::PhotoModelAlgorithm
virtual double PhotoModelAlgorithm(double phase, double incidence, double emission)
Return photometric phase angle list.
Definition: MinnaertEmpirical.cpp:138
Isis::MinnaertEmpirical
Empirical Minnaert photometric model Derive model albedo using phase dependent Minnaert equation and ...
Definition: MinnaertEmpirical.h:43
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::MinnaertEmpirical::SetPhotoKList
void SetPhotoKList(QString kstrlist)
Set the empirical Minnaert function K exponent list.
Definition: MinnaertEmpirical.cpp:104
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::MinnaertEmpirical::SetPhotoPhaseList
void SetPhotoPhaseList(QString phasestrlist)
Set the empirical Minnaert function phase angle list.
Definition: MinnaertEmpirical.cpp:79
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::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
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::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