Beispiel #1
0
  void Mixed::NormModelAlgorithm (double phase, double incidence, 
      double emission, double dn, double &albedo, double &mult,
      double &base)
  {
    double psurf;
    double pprime;
    double aden;

    // code for scaling each pixel
    psurf = GetPhotoModel()->CalcSurfAlbedo(phase, incidence, emission);
    pprime = GetPhotoModel()->PhtTopder(phase, incidence, emission);
    double arg = pow(psurf,2.0) + pow(p_psurfmatch*pprime / std::max(1.0e-30, p_pprimematch), 2.0);
    aden = sqrt(std::max(1.0e-30,arg));

    // thresh is a parameter limiting how much we amplify the dns
    // shouldn't actually get a large amplification in this mode because 
    // of the growing pprime term in the denominator.

    if (aden > p_anum*p_normThresh) {
      albedo = NULL8;
    }
    else {
      albedo = dn * p_anum / aden + p_rhobar * (p_psurfref - p_anum / aden * psurf);
    }
  }
Beispiel #2
0
  /*
   * @param phase Phase angle
   * @param incidence Incidence angle
   * @param emission Emission angle
   * @param dn
   * @param albedo
   * @param mult
   * @param base
   *
   * @history 2008-11-05 Jeannie Walldren - Modified references
   *           to NumericalMethods class and replaced Isis::PI
   *           with PI since this is in Isis namespace.
   *
   */
  void ShadeAtm::NormModelAlgorithm(double phase, double incidence, double emission,
                                    double demincidence, double dememission, double dn,
                                    double &albedo, double &mult, double &base) {
    double rho;
    double psurfref;
    static double psurf;
    static double ahInterp;
    static double munot;
    double pstd;
    double trans;
    double trans0;
    double transs;
    double sbar;

    static double old_phase = -9999;
    static double old_incidence = -9999;
    static double old_emission = -9999;
    static double old_demincidence = -9999;
    static double old_dememission = -9999;

    // Calculate normalization at standard conditions
    GetPhotoModel()->SetStandardConditions(true);
    psurfref = GetPhotoModel()->CalcSurfAlbedo(p_normPharef, p_normIncref, p_normEmaref);
    GetPhotoModel()->SetStandardConditions(false);

    // Get reference hemispheric albedo (Hapke opposition effect doesn't influence it much)
    GetAtmosModel()->GenerateAhTable();

    if(psurfref == 0.0) {
      std::string msg = "Divide by zero error";
      throw IException(IException::Unknown, msg, _FILEINFO_);
    }

    rho = p_normAlbedo / psurfref;

    if (old_phase != phase || old_incidence != incidence || old_emission != emission ||
        old_demincidence != demincidence || old_dememission != dememission) {

      psurf = GetPhotoModel()->CalcSurfAlbedo(phase, demincidence, dememission);

      ahInterp = (GetAtmosModel()->AtmosAhSpline()).Evaluate(incidence, NumericalApproximation::Extrapolate);

      munot = cos(incidence * (PI / 180.0));

      old_phase = phase;
      old_incidence = incidence;
      old_emission = emission;
      old_demincidence = demincidence;
      old_dememission = dememission;
    }

    GetAtmosModel()->CalcAtmEffect(phase, incidence, emission, &pstd, &trans, &trans0, &sbar,
                                   &transs);

    albedo = pstd + rho * (ahInterp * munot * trans /
                           (1.0 - rho * GetAtmosModel()->AtmosAb() * sbar) + (psurf - ahInterp * munot) * trans0);
  }
Beispiel #3
0
  void Albedo::NormModelAlgorithm(double phase, double incidence,
                                  double emission, double demincidence, double dememission,
                                  double dn, double &albedo, double &mult, double &base) {
    double psurf;
    double result;

    // code for scaling each pixel
    psurf = GetPhotoModel()->CalcSurfAlbedo(phase, demincidence, dememission);

    // thresh is a parameter limiting how much we amplify the dns
    if(p_normPsurfref > psurf * p_normThresh) {
      result = NULL8;
      albedo = NULL8;
      mult = 0.0;
      base = 0.0;
    }
    else {
      if(psurf == 0.0) {
        QString msg = "Albedo math divide by zero error";
        throw IException(IException::Unknown, msg, _FILEINFO_);
      }
      else {
        result = dn * p_normPsurfref / psurf;
        albedo = result;
        mult = p_normPsurfref / psurf;
        base = 0.0;
      }
    }
  }
Beispiel #4
0
  /**
   * Constructs AlbedoAtm object using a Pvl, PhotoModel, and
   * AtmosModel
   * @param pvl
   * @param pmodel
   * @param amodel
   *
   * @internal
   *   @history 2008-11-05 Jeannie Walldren - Modified references
   *          to NumericalMethods class and replaced Isis::PI with
   *          PI since this is in Isis namespace.
   */
  AlbedoAtm::AlbedoAtm(Pvl &pvl, PhotoModel &pmodel, AtmosModel &amodel) :
    NormModel(pvl, pmodel, amodel) {
    PvlGroup &algo = pvl.findObject("NormalizationModel")
                     .findGroup("Algorithm", Pvl::Traverse);
    // Set default value
    SetNormPharef(0.0);
    SetNormIncref(0.0);
    SetNormEmaref(0.0);

    // Get value from user
    if(algo.hasKeyword("Incref")) {
      SetNormIncref(algo["Incref"]);
    }

    if(algo.hasKeyword("Pharef")) {
      SetNormPharef(algo["Pharef"]);
    } else {
      p_normPharef = p_normIncref;
    }

    if(algo.hasKeyword("Emaref")) {
      SetNormEmaref(algo["Emaref"]);
    }

    // First-time setup:
    // Calculate normalization at standard conditions
    GetPhotoModel()->SetStandardConditions(true);
    p_normPsurfref = GetPhotoModel()->CalcSurfAlbedo(p_normPharef, p_normIncref, p_normEmaref);
    GetPhotoModel()->SetStandardConditions(false);

    // Get reference hemispheric albedo
    GetAtmosModel()->GenerateAhTable();

    p_normAhref = (GetAtmosModel()->AtmosAhSpline()).Evaluate(p_normIncref, NumericalApproximation::Extrapolate);

    p_normMunotref = cos((PI / 180.0) * p_normIncref);

    // Now calculate atmosphere at standard conditions
    GetAtmosModel()->SetStandardConditions(true);
    GetAtmosModel()->CalcAtmEffect(p_normPharef, p_normIncref, p_normEmaref,
                                   &p_normPstdref, &p_normTransref,
                                   &p_normTrans0ref, &p_normSbar,
                                   &p_normTranss);
    GetAtmosModel()->SetStandardConditions(false);
  }
Beispiel #5
0
  Albedo::Albedo(Pvl &pvl, PhotoModel &pmodel) : NormModel(pvl, pmodel) {
    PvlGroup &algorithm = pvl.findObject("NormalizationModel").findGroup("Algorithm", Pvl::Traverse);

    SetNormPharef(0.0);
    SetNormIncref(0.0);
    SetNormEmaref(0.0);
    SetNormIncmat(0.0);
    SetNormThresh(30.0);
    SetNormAlbedo(1.0);

    // Get value from user
    if(algorithm.hasKeyword("Incref")) {
      SetNormIncref(algorithm["Incref"]);
    }

    if(algorithm.hasKeyword("Pharef")) {
      SetNormPharef(algorithm["Pharef"]);
    } else {
      p_normPharef = p_normIncref;
    }

    if(algorithm.hasKeyword("Emaref")) {
      SetNormEmaref(algorithm["Emaref"]);
    }

    if(algorithm.hasKeyword("Incmat")) {
      SetNormIncmat(algorithm["Incmat"]);
    }

    if(algorithm.hasKeyword("Thresh")) {
      SetNormThresh(algorithm["Thresh"]);
    }

    if(algorithm.hasKeyword("Albedo")) {
      SetNormAlbedo(algorithm["Albedo"]);
    }

    // Calculate normalization at standard conditions.
    GetPhotoModel()->SetStandardConditions(true);
    p_normPsurfref = GetPhotoModel()->CalcSurfAlbedo(p_normPharef, p_normIncref, p_normEmaref);
    GetPhotoModel()->SetStandardConditions(false);
  }
Beispiel #6
0
  void NoNormalization::NormModelAlgorithm (double phase, double incidence, 
      double emission, double dn, double &albedo, double &mult,
      double &base)
  {
    double a;

    a = GetPhotoModel()->CalcSurfAlbedo(phase,incidence,emission);

    if (a != 0.0) {
      albedo = a * dn + phase;
    } else {
      albedo = NULL8;
      return;
    }
  }
Beispiel #7
0
  Mixed::Mixed (Pvl &pvl, PhotoModel &pmodel) : NormModel(pvl,pmodel) {
    PvlGroup &algorithm = pvl.FindObject("NormalizationModel").FindGroup("Algorithm",Pvl::Traverse);

    // Set default value
    SetNormIncref(0.0);
    SetNormIncmat(0.0);
    SetNormThresh(30.0);
    SetNormAlbedo(1.0);

    // Get value from user
    if (algorithm.HasKeyword("Incref")) {
      SetNormIncref(algorithm["Incref"]);
    }
    if (algorithm.HasKeyword("Incmat")) {
      SetNormIncmat(algorithm["Incmat"]);
    }

    if (algorithm.HasKeyword("Thresh")) {
      SetNormThresh(algorithm["Thresh"]);
    }

    if (algorithm.HasKeyword("Albedo")) {
      SetNormAlbedo(algorithm["Albedo"]);
    }

    // First-time setup
    // Calculate normalization at standard conditions
    // Turn off Hapke opposition effect
    GetPhotoModel()->SetStandardConditions(true);
    p_psurfref = GetPhotoModel()->CalcSurfAlbedo(0.0, p_normIncref, 0.0);
    double pprimeref = GetPhotoModel()->PhtTopder(0.0, p_normIncref, 0.0);

    if (p_psurfref == 0.0) {
      std::string err = "Divide by zero error";
      throw iException::Message(iException::Math, err, _FILEINFO_);
    }
    else {
      p_rhobar = p_normAlbedo / p_psurfref;
    }

    // Calculate brightness and topo derivative at matchpoint incidence
    p_psurfmatch = GetPhotoModel()->CalcSurfAlbedo(p_normIncmat, p_normIncmat, 0.0);
    p_pprimematch = GetPhotoModel()->PhtTopder(p_normIncmat, p_normIncmat, 0.0);

    // Calculate numerator of the stretch coeff. a; if it is very
    // large or small we haven't chosen a good reference state
    double arg = pow(p_psurfref,2.0) + pow(p_psurfmatch*pprimeref / std::max(1.0e-30,p_pprimematch),2.0);
    if ((arg < 1.0e-10) || (arg > 1.0e10)) {
      std::string err = "Bad reference state encountered";
      throw iException::Message(iException::Math, err, _FILEINFO_);
    }

    p_anum = sqrt(arg);
    GetPhotoModel()->SetStandardConditions(false);
  }
Beispiel #8
0
  /**
   * @param phase Value of phase angle.
   * @param incidence  Value of incidence angle.
   * @param emission Value of emission angle.
   * @param dn
   * @param albedo
   * @param mult
   * @param base
   * @internal
   *   @history 2008-11-05 Jeannie Walldren - Modified references
   *          to NumericalMethods class and replaced Isis::PI with
   *          PI since this is in Isis namespace.
   */
  void AlbedoAtm::NormModelAlgorithm(double phase, double incidence, double emission,
                                     double demincidence, double dememission, double dn,
                                     double &albedo, double &mult, double &base) {
    static double psurf;
    static double ahInterp;
    static double munot;
    double pstd;
    double trans;
    double trans0;
    double transs;
    double rho;
    double dpo;
    double q;
    double dpm;
    double firsterm;
    double secondterm;
    double thirdterm;
    double fourthterm;
    double fifthterm;

    static double old_phase = -9999;
    static double old_incidence = -9999;
    static double old_emission = -9999;
    static double old_demincidence = -9999;
    static double old_dememission = -9999;

    if (old_phase != phase || old_incidence != incidence || old_emission != emission ||
        old_demincidence != demincidence || old_dememission != dememission) {

      psurf = GetPhotoModel()->CalcSurfAlbedo(phase, demincidence,
                                              dememission);

      ahInterp = (GetAtmosModel()->AtmosAhSpline()).Evaluate(incidence, NumericalApproximation::Extrapolate);

      munot = cos(incidence * (PI / 180.0));

      old_phase = phase;
      old_incidence = incidence;
      old_emission = emission;
      old_demincidence = demincidence;
      old_dememission = dememission;
    }

    GetAtmosModel()->CalcAtmEffect(phase, incidence, emission, &pstd, &trans, &trans0, &p_normSbar,
                                   &transs);

    // With model at actual geometry, calculate rho from dn
    dpo = dn - pstd;
    dpm = (psurf - ahInterp * munot) * trans0;
    q = ahInterp * munot * trans + GetAtmosModel()->AtmosAb() * p_normSbar * dpo + dpm;

    if(dpo <= 0.0 && GetAtmosModel()->AtmosNulneg()) {
      rho = 0.0;
    }
    else {
      firsterm = GetAtmosModel()->AtmosAb() * p_normSbar;
      secondterm = dpo * dpm;
      thirdterm = firsterm * secondterm;
      fourthterm = pow(q, 2.0) - 4.0 * thirdterm;

      if(fourthterm < 0.0) {
        QString msg = "Square root of negative (math) encountered";
        throw IException(IException::Unknown, msg, _FILEINFO_);
      }
      else {
        fifthterm = q + sqrt(fourthterm);
      }

      rho = 2 * dpo / fifthterm;
    }

    // Now use rho and reference geometry to calculate output dnout
    if((1.0 - rho * GetAtmosModel()->AtmosAb()*p_normSbar) <= 0.0) {
      QString msg = "Divide by zero (math) encountered";
      throw IException(IException::Unknown, msg, _FILEINFO_);
    }
    else {
      albedo = p_normPstdref + rho * (p_normAhref * p_normMunotref *
                                      p_normTransref / (1.0 - rho * GetAtmosModel()->AtmosAb() *
                                          p_normSbar) + (p_normPsurfref - p_normAhref *
                                              p_normMunotref) * p_normTrans0ref);
    }
  }
Beispiel #9
0
 void NoNormalization::NormModelAlgorithm(double phase, double incidence, double emission,
     double demincidence, double dememission, double dn, double &albedo, double &mult,
     double &base) {
   // apply the photometric correction
   albedo = GetPhotoModel()->CalcSurfAlbedo(phase, demincidence, dememission);
 }
Beispiel #10
0
  void MoonAlbedo::NormModelAlgorithm(double phase, double incidence, double emission,
                                      double demincidence, double dememission, double dn,
                                      double &albedo, double &mult, double &base) {
    double a;
    double cosa;
    double pg2;
    double bshad;
    double r;
    double g1;
    double g1sq;
    double pg1;
    double pg;
    double fbc;
    double pg31;
    double pg3;

    a = GetPhotoModel()->CalcSurfAlbedo(phase, demincidence, dememission);

    if(a != 0.0) {
      cosa = cos(phase * Isis::PI / 180.0);
      if(1.0 + p_normG2sq + 2.0 * p_normG2 *cosa <= 0.0) {
        albedo = NULL8;
        return;
      }
      pg2 = p_normF * (1.0 - p_normG2sq) / (pow((1.0 + p_normG2sq + 2.0 * p_normG2 * cosa), 1.5));
      if(1.0 + tan(phase * .5 * Isis::PI / 180.0) / p_normH == 0.0) {
        albedo = NULL8;
        return;
      }
      bshad = 1.0 + p_normBsh1 / (1.0 + tan(phase * .5 * Isis::PI / 180.0) / p_normH);
      r = dn * p_normXmul;
      // Estimate the albedo at 0.1, then iterate
      albedo = 0.1;
      for(int i = 0; i < 6; i++) {
        g1 = p_normD * albedo + p_normE;
        g1sq = g1 * g1;
        if(1.0 + g1sq + 2.0 * g1 *cosa <= 0.0) {
          albedo = NULL8;
          return;
        }
        pg1 = p_normF1 * (1.0 - g1sq) / (pow((1.0 + g1sq + 2.0 * g1 * cosa), 1.5));
        pg = (pg1 + pg2) * bshad;
        if(phase <= 2.0) {
          fbc = 1.0 + p_normBc1 * phase;
          if(1.0 + g1sq + 2.0 * g1 *p_normC3 <= 0.0) {
            albedo = NULL8;
            return;
          }
          pg31 = p_normF1 * (1.0 - g1sq) / (pow((1.0 + g1sq + 2.0 * g1 * p_normC3), 1.5));
          pg3 = (pg31 + p_normPg32) * p_normBshad3;
          pg = fbc * (pg3 / p_normFbc3);
        }
        if(pg == 0.0) {
          albedo = NULL8;
          return;
        }
        albedo = r * a * p_normPg30 / pg;
      }
    }
    else {
      albedo = NULL8;
      return;
    }
  }