Isis 3 Programmer Reference
PhotoModel.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <cmath>
8#include "FileName.h"
9#include "PhotoModel.h"
10#include "Plugin.h"
11#include "Pvl.h"
12#include "IException.h"
13
14using namespace std;
15
16namespace Isis {
27 PvlGroup &algorithm = pvl.findObject("PhotometricModel").findGroup("Algorithm", Pvl::Traverse);
28
29 // Use 'PhtName' instead of 'Name' if using the Gui combo box
30 // for unique Pvl keyword in DefFile
31 if(algorithm.hasKeyword("PhtName")) {
32 p_photoAlgorithmName = algorithm["PhtName"][0];
33 }
34 else if(algorithm.hasKeyword("Name")) {
35 p_photoAlgorithmName = algorithm["Name"][0];
36 }
37 else {
38 IString msg = "Keyword [Name] or keyword [PhtName] must ";
39 msg += "exist in [Group = Algorithm]";
40 throw IException(IException::User, msg, _FILEINFO_);
41 }
42
44 }
45
51 p_standardConditions = standard;
52 }
53
64 double PhotoModel::PhtTopder(double phase, double incidence,
65 double emission) {
66 double xi, zi;
67 double cphi;
68 double phi;
69 double xe, ye, ze;
70 double epsh;
71 double xy, z;
72 double cinc;
73 double inc1, inc2, inc3, inc4;
74 double cema;
75 double ema1, ema2, ema3, ema4;
76 double d1, d2;
77 double result;
78 double eps;
79
80 eps = 0.04;
81
82 // set up incidence vector
83 xi = sin((Isis::PI / 180.0) * incidence);
84 zi = cos((Isis::PI / 180.0) * incidence);
85
86 // phi is the azimuth from xz plane to emission direction; if
87 // either incidence or emission is zero, it's arbitrary and gets
88 // set to zero. Thus cos(phi), cphi, is set to one.
89 if((incidence == 0.0) || (emission == 0.0)) {
90 cphi = 1.0;
91 }
92 else {
93 cphi = (cos((Isis::PI / 180.0) * phase) -
94 cos((Isis::PI / 180.0) * incidence) *
95 cos((Isis::PI / 180.0) * emission)) /
96 (sin((Isis::PI / 180.0) * incidence) *
97 sin((Isis::PI / 180.0) * emission));
98 }
99
100 // now calculate the emission vector
101 phi = PhtAcos(cphi) * (180.0 / Isis::PI);
102 xe = cphi * sin((Isis::PI / 180.0) * emission);
103 ye = sin((Isis::PI / 180.0) * phi) * sin((Isis::PI / 180.0) * emission);
104 ze = cos((Isis::PI / 180.0) * emission);
105
106 // now evaluate two orthogonal derivatives
107 epsh = eps * 0.5;
108 xy = sin((Isis::PI / 180.0) * epsh);
109 z = cos((Isis::PI / 180.0) * epsh);
110
111 cinc = max(-1.0, min(xy * xi + z * zi, 1.0));
112 inc1 = PhtAcos(cinc) * (180.0 / Isis::PI);
113 cema = max(-1.0, min(xy * xe + z * ze, 1.0));
114 ema1 = PhtAcos(cema) * (180.0 / Isis::PI);
115
116 cinc = max(-1.0, min(-xy * xi + z * zi, 1.0));
117 inc2 = PhtAcos(cinc) * (180.0 / Isis::PI);
118 cema = max(-1.0, min(-xy * xe + z * ze, 1.0));
119 ema2 = PhtAcos(cema) * (180.0 / Isis::PI);
120
121 cinc = max(-1.0, min(z * zi, 1.0));
122 inc3 = PhtAcos(cinc) * (180.0 / Isis::PI);
123 cema = max(-1.0, min(xy * ye + z * ze, 1.0));
124 ema3 = PhtAcos(cema) * (180.0 / Isis::PI);
125
126 cinc = max(-1.0, min(z * zi, 1.0));
127 inc4 = PhtAcos(cinc) * (180.0 / Isis::PI);
128 cema = max(-1.0, min(-xy * ye + z * ze, 1.0));
129 ema4 = PhtAcos(cema) * (180.0 / Isis::PI);
130
131 d1 = (CalcSurfAlbedo(phase, inc1, ema1) - CalcSurfAlbedo(phase, inc2, ema2)) / eps;
132 d2 = (CalcSurfAlbedo(phase, inc3, ema3) - CalcSurfAlbedo(phase, inc4, ema4)) / eps;
133
134 // Combine these two derivatives and return the gradient
135 result = sqrt(max(1.0e-30, d1 * d1 + d2 * d2));
136 return result;
137 }
138
150 double PhotoModel::PhtAcos(double cosang) {
151 double result;
152
153 if(fabs(cosang) <= 1.0) {
154 result = acos(cosang);
155 }
156 else {
157 if(cosang < -1.0) {
158 result = acos(-1.0);
159 }
160 else {
161 result = acos(1.0);
162 }
163 }
164
165 return result;
166 }
167
177 double PhotoModel::CalcSurfAlbedo(double pha, double inc, double ema) {
178
179 // Check validity of photometric angles
180 //if (pha > 180.0 || inc > 90.0 || ema > 90.0 || pha < 0.0 ||
181 // inc < 0.0 || ema < 0.0) {
182 // std::string msg = "Invalid photometric angles";
183 // throw iException::Message(iException::Programmer,msg,_FILEINFO_);
184 //}
185
186 // Apply photometric function
187 double albedo = PhotoModelAlgorithm(pha, inc, ema);
188 return albedo;
189 }
190
201// void PhotoModel::SetPhotoL(const double l) {
202// p_photoL = l;
203// }
204
214// void PhotoModel::SetPhotoK(const double k) {
215// if(k < 0.0) {
216// std::string msg = "Invalid value of Minnaert k [" +
217// IString(k) + "]";
218// throw iException::Message(iException::User, msg, _FILEINFO_);
219// }
220// p_photoK = k;
221// }
222}
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
Adds specific functionality to C++ strings.
Definition IString.h:165
double CalcSurfAlbedo(double pha, double inc, double ema)
Calculate the surface brightness using photometric angle information.
QString p_photoAlgorithmName
Unique name of the photometric model.
Definition PhotoModel.h:232
bool p_standardConditions
Indicates whether standard conditions are used.
Definition PhotoModel.h:234
double PhtTopder(double phase, double incidence, double emission)
Obtain topographic derivative of an arbitrary photometric function.
virtual void SetStandardConditions(bool standard)
Sets whether standard conditions will be used.
PhotoModel(Pvl &pvl)
Create a PhotoModel object.
static double PhtAcos(double cosang)
Obtain arccosine of input value.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
@ Traverse
Search child objects.
Definition PvlObject.h:158
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
const double PI
The mathematical constant PI.
Definition Constants.h:40
Namespace for the standard library.