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); } }
/* * @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); }
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; } } }
/** * 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); }
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); }
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; } }
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); }
/** * @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); } }
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); }
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; } }