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
11namespace 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();
53 p_photoKSpline.SetInterpType(NumericalApproximation::CubicClamped);
54 p_photoKSpline.AddData(p_photoPhaseList,p_photoKList);
55 p_photoKSpline.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 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::SetPhotoPhaseList(PvlKeyword phaseList) {
105
106 // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5)
107 if (phaseList.size() == 1) {
108 SetPhotoPhaseList(QString(phaseList));
109 return;
110 }
111
112 double phaseAngle;
113 p_photoPhaseList.clear();
114
115 for (int i=0; i< phaseList.size(); i++) {
116 phaseAngle = phaseList[i].toDouble();
117
118 if (phaseAngle < 0.0 || phaseAngle > 180.0) {
119 QString msg = "Invalid value of empirical Minnaert phase angle list value [" +
120 toString(phaseAngle) + "]";
121 throw IException(IException::User, msg, _FILEINFO_);
122 }
123 p_photoPhaseList.push_back(phaseAngle);
124 }
125 }
126
136 void MinnaertEmpirical::SetPhotoKList(QString kstrlist) {
137 double kvalue;
138 IString strlist(kstrlist);
139 p_photoKList.clear();
140
141 while (strlist.length()) {
142 kvalue = strlist.Token(",");
143 if (kvalue < 0.0) {
144 std::string msg = "Invalid value of Minnaert k list value [" +
145 IString(kvalue) + "]";
146 throw IException(IException::User, msg, _FILEINFO_);
147 }
148 p_photoKList.push_back(kvalue);
149 }
150 }
151
161 void MinnaertEmpirical::SetPhotoKList(PvlKeyword kstrList) {
162
163 // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5)
164 if (kstrList.size() == 1) {
165 SetPhotoKList(QString(kstrList));
166 return;
167 }
168
169 p_photoKList.clear();
170 for (int i=0; i<kstrList.size(); i++) {
171 p_photoKList.push_back(kstrList[i].toDouble());
172 }
173 }
174
182 void MinnaertEmpirical::SetPhotoPhaseCurveList(QString phasecurvestrlist) {
183 double phasecurve;
184 IString strlist(phasecurvestrlist);
185 p_photoPhaseCurveList.clear();
186
187 while (strlist.length()) {
188 phasecurve = strlist.Token(",");
189 p_photoPhaseCurveList.push_back(phasecurve);
190 }
191 }
192
201 void MinnaertEmpirical::SetPhotoPhaseCurveList(PvlKeyword photocurvestrList) {
202
203 // If the format is Keyword="1,2,3,4,5" rather than Keyword = (1,2,3,4,5)
204 if (photocurvestrList.size() == 1) {
205 SetPhotoPhaseCurveList(QString(photocurvestrList));
206 return;
207 }
208
209 p_photoPhaseCurveList.clear();
210 for (int i=0; i<photocurvestrList.size(); i++) {
211 p_photoPhaseCurveList.push_back(photocurvestrList[i].toDouble());
212 }
213 }
214
215 double MinnaertEmpirical::PhotoModelAlgorithm(double phase, double incidence,
216 double emission) {
217 static double pht_minnaert_empirical;
218 double incrad;
219 double emarad;
220 double munot;
221 double mu;
222 double kInterpolated = 0;
223 double bInterpolated = 0;
224
225 static double old_phase = -9999;
226 static double old_incidence = -9999;
227 static double old_emission= -9999;
228
229 // Don't need to do anything if the photometric angles are the same as before
230 if (old_phase == phase && old_incidence == incidence && old_emission == emission) {
231 return pht_minnaert_empirical;
232 }
233
234 old_incidence = incidence;
235 old_emission = emission;
236
237 incrad = incidence * Isis::PI / 180.0;
238 emarad = emission * Isis::PI / 180.0;
239 munot = cos(incrad);
240 mu = cos(emarad);
241
242 if (phase != old_phase) {
243 kInterpolated = p_photoKSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
244 bInterpolated = p_photoBSpline.Evaluate(phase, NumericalApproximation::Extrapolate);
245 old_phase = phase;
246 }
247
248 if(munot <= 0.0 || mu <= 0.0 || incidence == 90.0 ||
249 emission == 90.0) {
250 pht_minnaert_empirical = 0.0;
251 }
252 else if(kInterpolated == 1.0) {
253 pht_minnaert_empirical = munot * bInterpolated;
254 }
255 else {
256 pht_minnaert_empirical = bInterpolated * munot * pow((munot * mu), (kInterpolated - 1.0));
257 }
258
259 return pht_minnaert_empirical;
260 }
261}
262
263extern "C" Isis::PhotoModel *MinnaertEmpiricalPlugin(Isis::Pvl &pvl) {
264 return new Isis::MinnaertEmpirical(pvl);
265}
Isis exception class.
Definition IException.h:91
Adds specific functionality to C++ strings.
Definition IString.h:165
Empirical Minnaert photometric model Derive model albedo using phase dependent Minnaert equation and ...
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
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