12 #include "IException.h" 
   19   Hapke::Hapke(Pvl &pvl) : PhotoModel(pvl) {
 
   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;
 
  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 -
 
  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;