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 
14 using namespace std;
15 
16 namespace Isis {
26  PhotoModel::PhotoModel(Pvl &pvl) {
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 
43  p_standardConditions = false;
44  }
45 
50  void PhotoModel::SetStandardConditions(bool standard) {
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::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::PvlObject::findObject
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:274
Isis::IException
Isis exception class.
Definition: IException.h:91
std
Namespace for the standard library.
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16