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;
 
  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;
 
  307  void Hapke::SetPhotoHg1(
const double hg1) {
 
  308    if(hg1 <= -1.0 || hg1 >= 1.0) {
 
  309      string msg = 
"Invalid value of Hapke Henyey Greenstein hg1 [" +
 
  311      throw IException(IException::User, msg, _FILEINFO_);
 
 
  324  void Hapke::SetPhotoHg2(
const double hg2) {
 
  325    if(hg2 < 0.0 || hg2 > 1.0) {
 
  326      string msg = 
"Invalid value of Hapke Henyey Greenstein hg2 [" +
 
  328      throw IException(IException::User, msg, _FILEINFO_);
 
 
  341  void Hapke::SetPhotoBh(
const double bh) {
 
  342    if(bh < -1.0 || bh > 1.0) {
 
  343      string msg = 
"Invalid value of Hapke Legendre bh [" +
 
  345      throw IException(IException::User, msg, _FILEINFO_);
 
 
  358  void Hapke::SetPhotoCh(
const double ch) {
 
  359    if(ch < -1.0 || ch > 1.0) {
 
  360      string msg = 
"Invalid value of Hapke Legendre ch [" +
 
  362      throw IException(IException::User, msg, _FILEINFO_);
 
 
  374  void Hapke::SetPhotoWh(
const double wh) {
 
  375    if(wh <= 0.0 || wh > 1.0) {
 
  376      string msg = 
"Invalid value of Hapke wh [" +
 
  378      throw IException(IException::User, msg, _FILEINFO_);
 
 
  390  void Hapke::SetPhotoHh(
const double hh) {
 
  392      string msg = 
"Invalid value of Hapke hh [" +
 
  394      throw IException(IException::User, msg, _FILEINFO_);
 
 
  406  void Hapke::SetPhotoB0(
const double b0) {
 
  408      string msg = 
"Invalid value of Hapke b0 [" +
 
  410      throw IException(IException::User, msg, _FILEINFO_);
 
 
  423  void Hapke::SetPhoto0B0Standard(
const QString &b0standard) {
 
  425    temp = temp.UpCase();
 
  427    if(temp != 
"NO" && temp != 
"YES" && temp != 
"FALSE" && temp != 
"TRUE") {
 
  428      string msg = 
"Invalid value of Hapke ZeroB0Standard [" +
 
  430      throw IException(IException::User, msg, _FILEINFO_);
 
  433    if (temp == 
"NO" || temp == 
"FALSE") p_photo0B0Standard = 
"FALSE";
 
  434    if (temp == 
"YES" || temp == 
"TRUE") p_photo0B0Standard = 
"TRUE";
 
 
  444  void Hapke::SetPhotoTheta(
const double theta) {
 
  445    if(theta < 0.0 || theta > 90.0) {
 
  446      string msg = 
"Invalid value of Hapke theta [" +
 
  448      throw IException(IException::User, msg, _FILEINFO_);
 
  450    p_photoTheta = theta;
 
 
  454  void Hapke::SetStandardConditions(
bool standard) {
 
  455    PhotoModel::SetStandardConditions(standard);
 
  458      p_photoB0save = p_photoB0;
 
  459      if (p_photo0B0Standard == 
"TRUE") p_photoB0 = 0.0;
 
  462      p_photoB0 = p_photoB0save;
 
 
Hapke-Henyey-Greenstein photometric model.
 
Adds specific functionality to C++ strings.
 
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.