12#include "IException.h"
24 p_photoThetaold = -999.0;
29 PvlGroup &algorithm = pvl.findObject(
"PhotometricModel").findGroup(
"Algorithm", Pvl::Traverse);
31 p_algName = AlgorithmName().toUpper();
33 if(algorithm.hasKeyword(
"Hg1")) {
34 SetPhotoHg1(algorithm[
"Hg1"]);
37 if(algorithm.hasKeyword(
"Hg2")) {
38 SetPhotoHg2(algorithm[
"Hg2"]);
41 if(algorithm.hasKeyword(
"Bh")) {
42 SetPhotoBh(algorithm[
"Bh"]);
45 if(algorithm.hasKeyword(
"Ch")) {
46 SetPhotoCh(algorithm[
"Ch"]);
49 if(algorithm.hasKeyword(
"ZeroB0Standard")) {
50 SetPhoto0B0Standard(algorithm[
"ZeroB0Standard"][0]);
51 }
else if (algorithm.hasKeyword(
"ZeroB0St")) {
52 SetPhoto0B0Standard(algorithm[
"ZeroB0St"][0]);
54 SetPhoto0B0Standard(
"TRUE");
57 if(algorithm.hasKeyword(
"Wh")) {
58 SetPhotoWh(algorithm[
"Wh"]);
61 if(algorithm.hasKeyword(
"Hh")) {
62 SetPhotoHh(algorithm[
"Hh"]);
65 if(algorithm.hasKeyword(
"B0")) {
66 SetPhotoB0(algorithm[
"B0"]);
69 p_photoB0save = p_photoB0;
71 if(algorithm.hasKeyword(
"Theta")) {
72 SetPhotoTheta(algorithm[
"Theta"]);
109 double Hapke::PhotoModelAlgorithm(
double phase,
double incidence,
111 static double pht_hapke;
159 static double old_phase = -9999;
160 static double old_incidence = -9999;
161 static double old_emission= -9999;
163 if (old_phase == phase && old_incidence == incidence && old_emission == emission) {
168 old_incidence = incidence;
169 old_emission = emission;
171 pharad = phase *
PI / 180.0;
172 incrad = incidence *
PI / 180.0;
173 emarad = emission *
PI / 180.0;
177 if(p_photoTheta != p_photoThetaold) {
178 cost = cos(p_photoTheta * PI / 180.0);
179 sint = sin(p_photoTheta * PI / 180.0);
180 p_photoCott = cost / max(1.0e-10, sint);
181 p_photoCot2t = p_photoCott * p_photoCott;
182 p_photoTant = sint / cost;
183 tan2t = p_photoTant * p_photoTant;
184 p_photoSr = sqrt(1.0 + PI * tan2t);
185 p_photoOsr = 1.0 / p_photoSr;
186 SetOldTheta(p_photoTheta);
189 if(incidence >= 90.0) {
194 gamma = sqrt(1.0 - p_photoWh);
195 hgs = p_photoHg1 * p_photoHg1;
198 tang2 = tan(pharad/2.0);
200 if(p_photoHh == 0.0) {
204 bg = p_photoB0 / (1.0 + tang2 / p_photoHh);
207 if (p_algName ==
"HAPKEHEN") {
208 pg1 = (1.0 - p_photoHg2) * (1.0 - hgs) / pow((1.0 + hgs + 2.0 *
209 p_photoHg1 * cosg), 1.5);
210 pg2 = p_photoHg2 * (1.0 - hgs) / pow((1.0 + hgs - 2.0 *
211 p_photoHg1 * cosg), 1.5);
214 pg = 1.0 + p_photoBh * cosg + p_photoCh * (1.5 * pow(cosg, 2.0) - .5);
218 if(p_photoTheta <= 0.0) {
219 pht_hapke = p_photoWh / 4.0 * munot / (munot + mu) * ((1.0 + bg) *
220 pg - 1.0 + Hfunc(munot, gamma) * Hfunc(mu, gamma));
225 coti = munot / max(1.0e-10, sini);
227 ecoti = exp(min(-p_photoCot2t * cot2i / PI , 23.0));
228 ecot2i = exp(min(-2.0 * p_photoCott * coti / PI, 23.0));
229 u0p0 = p_photoOsr * (munot + sini * p_photoTant * ecoti / (2.0 - ecot2i));
232 cote = mu / max(1.0e-10, sine);
243 caz = (cosg - cosei) / sinei;
251 az = acos(caz) * 180.0 /
PI;
260 tanaz2 = tan(az2 * PI / 180.0);
261 faz = exp(min(-2.0 * tanaz2, 23.0));
264 sin2a2 = pow(sin(az2 * PI / 180.0), 2.0);
267 ecote = exp(min(-p_photoCot2t * cot2e / PI, 23.0));
268 ecot2e = exp(min(-2.0 * p_photoCott * cote / PI, 23.0));
269 up0 = p_photoOsr * (mu + sine * p_photoTant * ecote / (2.0 - ecot2e));
271 if(incidence <= emission) {
272 q = p_photoOsr * munot / u0p0;
275 q = p_photoOsr * mu / up0;
278 if(incidence <= emission) {
279 ecei = (2.0 - ecot2e - api * ecot2i);
280 s2ei = sin2a2 * ecoti;
281 u0p = p_photoOsr * (munot + sini * p_photoTant * (caz * ecote + s2ei) / ecei);
282 up = p_photoOsr * (mu + sine * p_photoTant * (ecote - s2ei) / ecei);
285 ecee = (2.0 - ecot2i - api * ecot2e);
286 s2ee = sin2a2 * ecote;
287 u0p = p_photoOsr * (munot + sini * p_photoTant * (ecoti - s2ee) / ecee);
288 up = p_photoOsr * (mu + sine * p_photoTant * (caz * ecoti + s2ee) / ecee);
291 rr1 = p_photoWh / 4.0 * u0p / (u0p + up) * ((1.0 + bg) * pg -
292 1.0 + Hfunc(u0p, gamma) * Hfunc(up, gamma));
293 rr2 = up * munot / (up0 * u0p0 * p_photoSr * (1.0 - faz + faz * q));
294 pht_hapke = rr1 * rr2;
308 if(hg1 <= -1.0 || hg1 >= 1.0) {
309 string msg =
"Invalid value of Hapke Henyey Greenstein hg1 [" +
325 if(hg2 < 0.0 || hg2 > 1.0) {
326 string msg =
"Invalid value of Hapke Henyey Greenstein hg2 [" +
342 if(bh < -1.0 || bh > 1.0) {
343 string msg =
"Invalid value of Hapke Legendre bh [" +
359 if(ch < -1.0 || ch > 1.0) {
360 string msg =
"Invalid value of Hapke Legendre ch [" +
375 if(wh <= 0.0 || wh > 1.0) {
376 string msg =
"Invalid value of Hapke wh [" +
392 string msg =
"Invalid value of Hapke hh [" +
408 string msg =
"Invalid value of Hapke b0 [" +
427 if(temp !=
"NO" && temp !=
"YES" && temp !=
"FALSE" && temp !=
"TRUE") {
428 string msg =
"Invalid value of Hapke ZeroB0Standard [" +
433 if (temp ==
"NO" || temp ==
"FALSE") p_photo0B0Standard =
"FALSE";
434 if (temp ==
"YES" || temp ==
"TRUE") p_photo0B0Standard =
"TRUE";
445 if(theta < 0.0 || theta > 90.0) {
446 string msg =
"Invalid value of Hapke theta [" +
450 p_photoTheta = theta;
458 p_photoB0save = p_photoB0;
459 if (p_photo0B0Standard ==
"TRUE") p_photoB0 = 0.0;
462 p_photoB0 = p_photoB0save;
Hapke-Henyey-Greenstein photometric model.
void SetPhotoHg1(const double hg1)
Set the Hapke Henyey Greenstein coefficient for the single particle phase function.
void SetPhotoB0(const double b0)
Return photometric Hh value.
void SetPhotoWh(const double wh)
Return photometric Ch value.
void SetPhotoBh(const double bh)
Return photometric Hg2 value.
void SetPhotoHh(const double hh)
Return photometric Wh value.
void SetPhotoTheta(const double theta)
Return photometric B0 value.
void SetPhotoCh(const double ch)
Return photometric Bh value.
void SetPhotoHg2(const double hg2)
Return photometric Hg1 value.
void SetStandardConditions(bool standard)
Sets whether standard conditions will be used.
void SetPhoto0B0Standard(const QString &b0standard)
Determine if the Hapke opposition surge component is initialized to zero during the SetStandardCondit...
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Adds specific functionality to C++ strings.
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
virtual void SetStandardConditions(bool standard)
Sets whether standard conditions will be used.
Container for cube-like labels.
This is free and unencumbered software released into the public domain.
const double PI
The mathematical constant PI.
Namespace for the standard library.