Isis 3 Programmer Reference
TopoAtm.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <cmath>
8#include "TopoAtm.h"
9#include "NumericalApproximation.h"
10#include "IException.h"
11
12namespace Isis {
13 /*
14 * @history 2008-11-05 Jeannie Walldren - Modified references to
15 * NumericalMethods class and replaced Isis::PI with PI
16 * since this is in Isis namespace.
17 */
18 TopoAtm::TopoAtm(Pvl &pvl, PhotoModel &pmodel, AtmosModel &amodel) : NormModel(pvl, pmodel, amodel) {
19 double psurf0;
20 double psurfref;
21 double pprimeref;
22 double ahref;
23 double munotref;
24 double pstdref;
25 double transref;
26 double trans0ref;
27 double transs;
28 double sbar;
29
30 PvlGroup &algorithm = pvl.findObject("NormalizationModel").findGroup("Algorithm", Pvl::Traverse);
31
32 SetNormPharef(0.0);
33 SetNormIncref(0.0);
34 SetNormEmaref(0.0);
35 SetNormAlbedo(1.0);
36
37 if(algorithm.hasKeyword("Incref")) {
38 SetNormIncref(algorithm["Incref"]);
39 }
40
41 if(algorithm.hasKeyword("Pharef")) {
42 SetNormPharef(algorithm["Pharef"]);
43 }
44 else {
45 p_normPharef = p_normIncref;
46 }
47
48 if(algorithm.hasKeyword("Emaref")) {
49 SetNormEmaref(algorithm["Emaref"]);
50 }
51
52 if(algorithm.hasKeyword("Albedo")) {
53 SetNormAlbedo(algorithm["Albedo"]);
54 }
55
56 // First-time setup:
57 // Calculate normalization at standard conditions
58 GetPhotoModel()->SetStandardConditions(true);
59 psurf0 = GetPhotoModel()->CalcSurfAlbedo(0.0, 0.0, 0.0);
60
61 if(psurf0 == 0.0) {
62 std::string msg = "Divide by zero encountered";
63 throw IException(IException::Unknown, msg, _FILEINFO_);
64 }
65 else {
66 p_normRhobar = p_normAlbedo / psurf0;
67 }
68
69 psurfref = GetPhotoModel()->CalcSurfAlbedo(p_normPharef, p_normIncref, p_normEmaref);
70 pprimeref = GetPhotoModel()->PhtTopder(p_normPharef, p_normIncref, p_normEmaref);
71 GetPhotoModel()->SetStandardConditions(false);
72
73 // Get reference hemispheric albedo (p_photoB0 doesn't influence it much)
74 GetAtmosModel()->GenerateAhTable();
75
76 ahref = (GetAtmosModel()->AtmosAhSpline()).Evaluate(p_normIncref, NumericalApproximation::Extrapolate);
77
78 munotref = cos((PI / 180.0) * p_normIncref);
79
80 // Now calculate atmosphere at standard conditions
81 GetAtmosModel()->SetStandardConditions(true);
82 GetAtmosModel()->CalcAtmEffect(p_normPharef, p_normIncref, p_normEmaref, &pstdref, &transref,
83 &trans0ref, &sbar, &transs);
84 GetAtmosModel()->SetStandardConditions(false);
85
86 // Finally, calculate the additive and multiplicative parts of the
87 // output-normalized signal, from the point of view of fixed albedo
88 // and varying topography
89 p_normAout = p_normRhobar * pprimeref * trans0ref;
90 p_normBout = pstdref + p_normRhobar * (transref * ahref * munotref /
91 (1.0 - p_normRhobar * GetAtmosModel()->AtmosAb() * sbar) + trans0ref *
92 (psurfref - ahref * munotref));
93 }
94
95 /*
96 *@history 2008-11-05 Jeannie Walldren - Modified references to
97 * NumericalMethods class and replaced Isis::PI with PI
98 * since this is in Isis namespace.
99 */
100 void TopoAtm::NormModelAlgorithm(double phase, double incidence, double emission,
101 double demincidence, double dememission, double dn,
102 double &albedo, double &mult, double &base) {
103 double eps = 0.1;
104 static double psurf;
105 static double pprime;
106 static double ahInterp;
107 static double munot;
108 double pstd;
109 double trans;
110 double trans0;
111 double transs;
112 double sbar;
113 double rhotlt;
114 double dpo;
115 double q;
116 double slope;
117 double pprimeeff;
118 double ptilt;
119 double dpm;
120 double pflat;
121 double rhoflat;
122
123 static double old_phase = -9999;
124 static double old_incidence = -9999;
125 static double old_emission = -9999;
126 static double old_demincidence = -9999;
127 static double old_dememission = -9999;
128
129 if (old_phase != phase || old_incidence != incidence || old_emission != emission ||
130 old_demincidence != demincidence || old_dememission != dememission) {
131
132 psurf = GetPhotoModel()->CalcSurfAlbedo(phase, demincidence, dememission);
133 pprime = GetPhotoModel()->PhtTopder(phase, demincidence, dememission);
134 ahInterp = (GetAtmosModel()->AtmosAhSpline()).Evaluate(incidence, NumericalApproximation::Extrapolate);
135
136 munot = cos(incidence * (PI / 180.0));
137
138 old_phase = phase;
139 old_incidence = incidence;
140 old_emission = emission;
141 old_demincidence = demincidence;
142 old_dememission = dememission;
143 }
144
145 GetAtmosModel()->CalcAtmEffect(phase, incidence, emission, &pstd, &trans, &trans0, &sbar,
146 &transs);
147 pflat = pstd + p_normRhobar * (trans * ahInterp * munot /
148 (1.0 - p_normRhobar * GetAtmosModel()->AtmosAb() * sbar) + trans0 * (psurf -
149 ahInterp * munot));
150 ptilt = pflat + p_normRhobar * pprime * trans0 * eps;
151 dpo = ptilt - pstd;
152 dpm = (psurf - ahInterp * munot) * trans0;
153 q = ahInterp * munot * trans + GetAtmosModel()->AtmosAb() * sbar * dpo + dpm;
154 rhotlt = 2.0 * dpo / (q + sqrt(pow(q, 2.0) - 4.0 * GetAtmosModel()->AtmosAb() * sbar * dpo * dpm));
155 dpo = pflat - pstd;
156 q = ahInterp * munot * trans + GetAtmosModel()->AtmosAb() * sbar * dpo + dpm;
157 rhoflat = 2.0 * dpo / (q + sqrt(pow(q, 2.0) - 4.0 * GetAtmosModel()->AtmosAb() * sbar * dpo * dpm));
158 pprimeeff = (rhotlt - rhoflat) / (rhoflat * eps);
159 slope = (dn - 1.0) / pprimeeff;
160 albedo = p_normAout * slope + p_normBout;
161 }
162
172 void TopoAtm::SetNormPharef(const double pharef) {
173 if(pharef < 0.0 || pharef >= 180.0) {
174 std::string msg = "Invalid value of normalization pharef [" + IString(pharef) + "]";
175 throw IException(IException::User, msg, _FILEINFO_);
176 }
177
178 p_normPharef = pharef;
179 }
180
190 void TopoAtm::SetNormIncref(const double incref) {
191 if(incref < 0.0 || incref >= 90.0) {
192 std::string msg = "Invalid value of normalization incref [" + IString(incref) + "]";
193 throw IException(IException::User, msg, _FILEINFO_);
194 }
195
196 p_normIncref = incref;
197 }
198
208 void TopoAtm::SetNormEmaref(const double emaref) {
209 if(emaref < 0.0 || emaref >= 90.0) {
210 std::string msg = "Invalid value of normalization emaref [" + IString(emaref) + "]";
211 throw IException(IException::User, msg, _FILEINFO_);
212 }
213
214 p_normEmaref = emaref;
215 }
216
225 void TopoAtm::SetNormAlbedo(const double albedo) {
226 p_normAlbedo = albedo;
227 }
228}
229
230extern "C" Isis::NormModel *TopoAtmPlugin(Isis::Pvl &pvl, Isis::PhotoModel &pmodel, Isis::AtmosModel &amodel) {
231 return new Isis::TopoAtm(pvl, pmodel, amodel);
232}
Isotropic atmos scattering model.
Definition AtmosModel.h:60
Isis exception class.
Definition IException.h:91
Adds specific functionality to C++ strings.
Definition IString.h:165
Container for cube-like labels.
Definition Pvl.h:119
As in the case without an atmosphere, processing proceeds in three steps, a pass 1 PHOTOM followed by...
Definition TopoAtm.h:74
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16