|
Isis 3.0 Object Programmers' Reference |
Home |
00001 #include <cmath> 00002 #include "AlbedoAtm.h" 00003 #include "NumericalApproximation.h" 00004 #include "iException.h" 00005 00006 #define MIN(x,y) (((x) < (y)) ? (x) : (y)) 00007 #define MAX(x,y) (((x) > (y)) ? (x) : (y)) 00008 00009 namespace Isis { 00022 AlbedoAtm::AlbedoAtm (Pvl &pvl, PhotoModel &pmodel, AtmosModel &amodel) : 00023 NormModel(pvl,pmodel,amodel) { 00024 PvlGroup &algo = pvl.FindObject("NormalizationModel") 00025 .FindGroup("Algorithm",Pvl::Traverse); 00026 // Set default value 00027 SetNormIncref(0.0); 00028 // Get value from user 00029 if (algo.HasKeyword("Incref")) { 00030 SetNormIncref(algo["Incref"]); 00031 } 00032 00033 // First-time setup: 00034 // Calculate normalization at standard conditions 00035 GetPhotoModel()->SetStandardConditions(true); 00036 p_normPsurfref = GetPhotoModel()->CalcSurfAlbedo(p_normIncref, p_normIncref,0.0); 00037 GetPhotoModel()->SetStandardConditions(false); 00038 00039 // Get reference hemispheric albedo 00040 GetAtmosModel()->GenerateAhTable(); 00041 00042 p_normAhref = (GetAtmosModel()->AtmosAhSpline()).Evaluate(p_normIncref, NumericalApproximation::Extrapolate); 00043 00044 p_normMunotref = cos((PI/180.0)*p_normIncref); 00045 00046 // Now calculate atmosphere at standard conditions 00047 GetAtmosModel()->SetStandardConditions(true); 00048 GetAtmosModel()->CalcAtmEffect(p_normIncref,p_normIncref,0.0, 00049 &p_normPstdref,&p_normTransref, 00050 &p_normTrans0ref,&p_normSbar); 00051 GetAtmosModel()->SetStandardConditions(false); 00052 } 00053 00067 void AlbedoAtm::NormModelAlgorithm (double phase, double incidence, 00068 double emission, double dn, double &albedo, double &mult, double &base) 00069 { 00070 double psurf; 00071 double ahInterp; 00072 double munot; 00073 double pstd; 00074 double trans; 00075 double trans0; 00076 double rho; 00077 double dpo; 00078 double q; 00079 double dpm; 00080 double firsterm; 00081 double secondterm; 00082 double thirdterm; 00083 double fourthterm; 00084 double fifthterm; 00085 00086 psurf = GetPhotoModel()->CalcSurfAlbedo(phase,incidence, 00087 emission); 00088 00089 ahInterp = (GetAtmosModel()->AtmosAhSpline()).Evaluate(incidence, NumericalApproximation::Extrapolate); 00090 00091 munot = cos(incidence*(PI/180.0)); 00092 GetAtmosModel()->CalcAtmEffect(phase,incidence,emission,&pstd,&trans,&trans0,&p_normSbar); 00093 00094 // With model at actual geometry, calculate rho from dn 00095 dpo = dn - pstd; 00096 dpm = (psurf - ahInterp * munot) * trans0; 00097 q = ahInterp * munot * trans + GetAtmosModel()->AtmosAb() * p_normSbar * dpo + dpm; 00098 00099 if (dpo <= 0.0 && GetAtmosModel()->AtmosNulneg()) { 00100 rho = 0.0; 00101 } 00102 else { 00103 firsterm = GetAtmosModel()->AtmosAb() * p_normSbar; 00104 secondterm = dpo * dpm; 00105 thirdterm = firsterm * secondterm; 00106 fourthterm = pow(q,2.0) - 4.0 * thirdterm; 00107 00108 if (fourthterm < 0.0) { 00109 std::string msg = "Square root of negative encountered"; 00110 throw iException::Message(iException::Math,msg,_FILEINFO_); 00111 } 00112 else { 00113 fifthterm = q + sqrt(fourthterm); 00114 } 00115 00116 rho = 2 * dpo / fifthterm; 00117 } 00118 00119 // Now use rho and reference geometry to calculate output dnout 00120 if ((1.0-rho*GetAtmosModel()->AtmosAb()*p_normSbar) <= 0.0) { 00121 std::string msg = "Divide by zero encountered"; 00122 throw iException::Message(iException::Math,msg,_FILEINFO_); 00123 } 00124 else { 00125 albedo = p_normPstdref + rho * (p_normAhref * p_normMunotref * 00126 p_normTransref / (1.0 - rho * GetAtmosModel()->AtmosAb() * 00127 p_normSbar) + (p_normPsurfref - p_normAhref * 00128 p_normMunotref) * p_normTrans0ref); 00129 } 00130 } 00131 00141 void AlbedoAtm::SetNormIncref (const double incref) { 00142 if (incref < 0.0 || incref >= 90.0) { 00143 std::string msg = "Invalid value of normalization incref [" + 00144 iString(incref) + "]"; 00145 throw iException::Message(iException::User,msg,_FILEINFO_); 00146 } 00147 00148 p_normIncref = incref; 00149 } 00150 } 00151 00152 extern "C" Isis::NormModel *AlbedoAtmPlugin (Isis::Pvl &pvl, Isis::PhotoModel &pmodel, Isis::AtmosModel &amodel) { 00153 return new Isis::AlbedoAtm(pvl,pmodel,amodel); 00154 }