USGS

Isis 3.0 Object Programmers' Reference

Home

PhotoModel.cpp
1 #include <cmath>
2 #include "FileName.h"
3 #include "PhotoModel.h"
4 #include "Plugin.h"
5 #include "Pvl.h"
6 #include "IException.h"
7 
8 using namespace std;
9 
10 namespace Isis {
20  PhotoModel::PhotoModel(Pvl &pvl) {
21  PvlGroup &algorithm = pvl.findObject("PhotometricModel").findGroup("Algorithm", Pvl::Traverse);
22 
23  // Use 'PhtName' instead of 'Name' if using the Gui combo box
24  // for unique Pvl keyword in DefFile
25  if(algorithm.hasKeyword("PhtName")) {
26  p_photoAlgorithmName = algorithm["PhtName"][0];
27  }
28  else if(algorithm.hasKeyword("Name")) {
29  p_photoAlgorithmName = algorithm["Name"][0];
30  }
31  else {
32  IString msg = "Keyword [Name] or keyword [PhtName] must ";
33  msg += "exist in [Group = Algorithm]";
34  throw IException(IException::User, msg, _FILEINFO_);
35  }
36 
37  p_standardConditions = false;
38  }
39 
44  void PhotoModel::SetStandardConditions(bool standard) {
45  p_standardConditions = standard;
46  }
47 
58  double PhotoModel::PhtTopder(double phase, double incidence,
59  double emission) {
60  double xi, zi;
61  double cphi;
62  double phi;
63  double xe, ye, ze;
64  double epsh;
65  double xy, z;
66  double cinc;
67  double inc1, inc2, inc3, inc4;
68  double cema;
69  double ema1, ema2, ema3, ema4;
70  double d1, d2;
71  double result;
72  double eps;
73 
74  eps = 0.04;
75 
76  // set up incidence vector
77  xi = sin((Isis::PI / 180.0) * incidence);
78  zi = cos((Isis::PI / 180.0) * incidence);
79 
80  // phi is the azimuth from xz plane to emission direction; if
81  // either incidence or emission is zero, it's arbitrary and gets
82  // set to zero. Thus cos(phi), cphi, is set to one.
83  if((incidence == 0.0) || (emission == 0.0)) {
84  cphi = 1.0;
85  }
86  else {
87  cphi = (cos((Isis::PI / 180.0) * phase) -
88  cos((Isis::PI / 180.0) * incidence) *
89  cos((Isis::PI / 180.0) * emission)) /
90  (sin((Isis::PI / 180.0) * incidence) *
91  sin((Isis::PI / 180.0) * emission));
92  }
93 
94  // now calculate the emission vector
95  phi = PhtAcos(cphi) * (180.0 / Isis::PI);
96  xe = cphi * sin((Isis::PI / 180.0) * emission);
97  ye = sin((Isis::PI / 180.0) * phi) * sin((Isis::PI / 180.0) * emission);
98  ze = cos((Isis::PI / 180.0) * emission);
99 
100  // now evaluate two orthogonal derivatives
101  epsh = eps * 0.5;
102  xy = sin((Isis::PI / 180.0) * epsh);
103  z = cos((Isis::PI / 180.0) * epsh);
104 
105  cinc = max(-1.0, min(xy * xi + z * zi, 1.0));
106  inc1 = PhtAcos(cinc) * (180.0 / Isis::PI);
107  cema = max(-1.0, min(xy * xe + z * ze, 1.0));
108  ema1 = PhtAcos(cema) * (180.0 / Isis::PI);
109 
110  cinc = max(-1.0, min(-xy * xi + z * zi, 1.0));
111  inc2 = PhtAcos(cinc) * (180.0 / Isis::PI);
112  cema = max(-1.0, min(-xy * xe + z * ze, 1.0));
113  ema2 = PhtAcos(cema) * (180.0 / Isis::PI);
114 
115  cinc = max(-1.0, min(z * zi, 1.0));
116  inc3 = PhtAcos(cinc) * (180.0 / Isis::PI);
117  cema = max(-1.0, min(xy * ye + z * ze, 1.0));
118  ema3 = PhtAcos(cema) * (180.0 / Isis::PI);
119 
120  cinc = max(-1.0, min(z * zi, 1.0));
121  inc4 = PhtAcos(cinc) * (180.0 / Isis::PI);
122  cema = max(-1.0, min(-xy * ye + z * ze, 1.0));
123  ema4 = PhtAcos(cema) * (180.0 / Isis::PI);
124 
125  d1 = (CalcSurfAlbedo(phase, inc1, ema1) - CalcSurfAlbedo(phase, inc2, ema2)) / eps;
126  d2 = (CalcSurfAlbedo(phase, inc3, ema3) - CalcSurfAlbedo(phase, inc4, ema4)) / eps;
127 
128  // Combine these two derivatives and return the gradient
129  result = sqrt(max(1.0e-30, d1 * d1 + d2 * d2));
130  return result;
131  }
132 
144  double PhotoModel::PhtAcos(double cosang) {
145  double result;
146 
147  if(fabs(cosang) <= 1.0) {
148  result = acos(cosang);
149  }
150  else {
151  if(cosang < -1.0) {
152  result = acos(-1.0);
153  }
154  else {
155  result = acos(1.0);
156  }
157  }
158 
159  return result;
160  }
161 
171  double PhotoModel::CalcSurfAlbedo(double pha, double inc, double ema) {
172 
173  // Check validity of photometric angles
174  //if (pha > 180.0 || inc > 90.0 || ema > 90.0 || pha < 0.0 ||
175  // inc < 0.0 || ema < 0.0) {
176  // std::string msg = "Invalid photometric angles";
177  // throw iException::Message(iException::Programmer,msg,_FILEINFO_);
178  //}
179 
180  // Apply photometric function
181  double albedo = PhotoModelAlgorithm(pha, inc, ema);
182  return albedo;
183  }
184 
195 // void PhotoModel::SetPhotoL(const double l) {
196 // p_photoL = l;
197 // }
198 
208 // void PhotoModel::SetPhotoK(const double k) {
209 // if(k < 0.0) {
210 // std::string msg = "Invalid value of Minnaert k [" +
211 // IString(k) + "]";
212 // throw iException::Message(iException::User, msg, _FILEINFO_);
213 // }
214 // p_photoK = k;
215 // }
216 }