Isis 3 Programmer Reference
AtmosModel.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <cmath>
8#include <string>
9#include "Pvl.h"
10#include "IString.h"
11#include "AtmosModel.h"
12#include "NumericalApproximation.h"
13#include "NumericalAtmosApprox.h"
14#include "PhotoModel.h"
15#include "Minnaert.h"
16#include "LunarLambert.h"
17#include "Plugin.h"
18#include "IException.h"
19#include "FileName.h"
20
21using namespace std;
22
23#define MAX(x,y) (((x) > (y)) ? (x) : (y))
24namespace Isis {
42 p_atmosAlgorithmName = "Unknown";
43 p_atmosPM = &pmodel;
44
45 p_atmosIncTable.resize(91);
46 p_atmosAhTable.resize(91);
47 p_atmosHahgtTable.resize(91);
48 p_atmosHahgt0Table.resize(91);
49 p_atmosAb = 0.0;
50 p_atmosCosphi = 0.0;
51 p_atmosAtmSwitch = 0;
52 p_atmosEulgam = 0.5772156;
53 p_atmosHahgsb = 0.0;
54 p_atmosHga = 0.68;
55 p_atmosInc = 0.0;
56 p_atmosMunot = 0.0;
57 p_atmosNinc = 91;
58 p_atmosPhi = 0.0;
59 p_atmosSini = 0.0;
60 p_atmosTau = 0.28;
61 p_atmosTauref = 0.0;
62 p_atmosTauold = -1.0;
63 p_atmosWha = 0.95;
64 p_atmosWhaold = 1.0e30;
65 p_atmosBha = 0.85;
66 p_atmosHnorm = 0.003;
67 p_pstd = 0.0;
68 p_sbar = 0.0;
69 p_trans = 0.0;
70 p_trans0 = 0.0;
71 p_transs = 0.0;
72 p_standardConditions = false;
73
74 PvlGroup &algorithm = pvl.findObject("AtmosphericModel").findGroup("Algorithm", Pvl::Traverse);
75
76 if(algorithm.hasKeyword("Nulneg")) {
77 SetAtmosNulneg(algorithm["Nulneg"][0] == "YES");
78 }
79 else {
80 p_atmosNulneg = false;
81 }
82
83 if(algorithm.hasKeyword("Tau")) {
84 SetAtmosTau(algorithm["Tau"]);
85 }
86 p_atmosTausave = p_atmosTau;
87
88 if(algorithm.hasKeyword("Tauref")) {
89 SetAtmosTauref(algorithm["Tauref"]);
90 }
91
92 if(algorithm.hasKeyword("Wha")) {
93 SetAtmosWha(algorithm["Wha"]);
94 }
95 p_atmosWhasave = p_atmosWha;
96
97 if(algorithm.hasKeyword("Hga")) {
98 SetAtmosHga(algorithm["Hga"]);
99 }
100 p_atmosHgasave = p_atmosHga;
101
102 if(algorithm.hasKeyword("Bha")) {
103 SetAtmosBha(algorithm["Bha"]);
104 }
105 p_atmosBhasave = p_atmosBha;
106
107 if(algorithm.hasKeyword("Inc")) {
108 SetAtmosInc(algorithm["Inc"]);
109 }
110
111 if(algorithm.hasKeyword("Phi")) {
112 SetAtmosPhi(algorithm["Phi"]);
113 }
114
115 if(algorithm.hasKeyword("Hnorm")) {
116 SetAtmosHnorm(algorithm["Hnorm"]);
117 }
118
119 if(algorithm.hasKeyword("Iord")) {
120 SetAtmosIord(algorithm["Iord"][0] == "YES");
121 }
122 else {
123 p_atmosAddOffset = false;
124 }
125
126 if(algorithm.hasKeyword("EstTau")) {
127 SetAtmosEstTau(algorithm["EstTau"][0] == "YES");
128 }
129 else {
130 p_atmosEstTau = false;
131 }
132 }
133
153 double AtmosModel::G11Prime(double tau) {
154 double sum;
155 int icnt;
156 double fac;
157 double term;
158 double tol;
159 double fi;
160 double elog;
161 double eulgam;
162 double e1_2;
163 double result;
164
165 tol = 1.0e-6;
166 eulgam = 0.5772156;
167
168 sum = 0.0;
169 icnt = 1;
170 fac = -tau;
171 term = fac;
172 while(fabs(term) > fabs(sum)*tol) {
173 sum = sum + term;
174 icnt = icnt + 1;
175 fi = (double) icnt;
176 fac = fac * (-tau) / fi;
177 term = fac / (fi * fi);
178 }
179 elog = log(MAX(1.0e-30, tau)) + eulgam;
180 e1_2 = sum + PI * PI / 12.0 + 0.5 *
181 pow(elog, 2.0);
182 result = 2.0 * (AtmosModel::En(1, tau)
183 + elog * AtmosModel::En(2, tau)
184 - tau * e1_2);
185 return(result);
186 }
187
229 double AtmosModel::Ei(double x) {
230 //static double r8ei(double x) in original NumericalMethods class
231 // This method was derived from an algorithm in the text
232 // Numerical Recipes in C: The Art of Scientific Computing
233 // Section 6.3 by Flannery, Press, Teukolsky, and Vetterling
234 double result;
235 double fpmin; // close to smallest representable floating-point number
236 double euler; // Euler's constant, lower-case gamma
237 double epsilon; // desired relative error (tolerance)
238 int maxit; // maximum number of iterations allowed
239 double sum, fact, term, prev;
240
241 fpmin = 1.0e-30;
242 maxit = 100;
243 epsilon = 6.0e-8;
244 euler = 0.57721566;
245
246 if(x <= 0.0) {
248 "AtmosModel::Ei() - Invalid argument. Definition requires x > 0.0. Entered x = "
249 + IString(x),
250 _FILEINFO_);
251 }
252 if(x < fpmin) { //special case: avoid failure of convergence test because underflow
253 result = log(x) + euler;
254 }
255 else if(x <= -log(epsilon)) { //Use power series
256 sum = 0.0;
257 fact = 1.0;
258 for(int k = 1; k <= maxit; k++) {
259 fact = fact * x / k;
260 term = fact / k;
261 sum = sum + term;
262 if(term < epsilon * sum) {
263 result = sum + log(x) + euler;
264 return(result);
265 }
266 }
268 "AtmosModel::Ei() - Power series failed to converge in "
269 + IString(maxit) + " iterations. Unable to calculate exponential integral.",
270 _FILEINFO_);
271 }
272 else { // Use asymptotic series
273 sum = 0.0;
274 term = 1.0;
275 for(int k = 1; k <= maxit; k++) {
276 prev = term;
277 term = term * k / x;
278 if(term < epsilon) {
279 result = exp(x) * (1.0 + sum) / x;
280 return(result);
281 }
282 else {
283 if(term < prev) { // still converging: add new term
284 sum = sum + term;
285 }
286 else { // diverging: subtract previous term and exit
287 sum = sum - prev;
288 result = exp(x) * (1.0 + sum) / x;
289 return(result);
290 }
291 }
292 }
293 result = exp(x) * (1.0 + sum) / x;
294 }
295 return(result);
296 }
297
370 double AtmosModel::En(unsigned int n, double x) {
371 //static double r8expint(int n, double x) in original NumericalMethods class
372 // This method was derived from an algorithm in the text
373 // Numerical Recipes in C: The Art of Scientific Computing
374 // Section 6.3 by Flannery, Press, Teukolsky, and Vetterling
375 int nm1;
376 double result;
377 double a, b, c, d, h;
378 double delta;
379 double fact;
380 double psi;
381 double fpmin; // close to smallest representable floating-point number
382 double maxit; // maximum number of iterations allowed
383 double epsilon; // desired relative error (tolerance)
384 double euler; // Euler's constant, gamma
385
386 fpmin = 1.0e-30;
387 maxit = 100;
388 epsilon = 1.0e-7;
389 euler = 0.5772156649;
390
391 nm1 = n - 1;
392 if((x < 0.0) || (x == 0.0 && (n == 0 || n == 1))) {
393 IString msg = "AtmosModel::En() - Invalid arguments. ";
394 msg += "Definition requires (x > 0.0 and n >=0 ) or (x >= 0.0 and n > 1). ";
395 msg += "Entered x = " + IString(x) + " and n = " + IString((int) n);
396 throw IException(IException::Programmer, msg, _FILEINFO_);
397 }
398 else if(n == 0) { // special case, this implies x > 0 by logic above
399 result = exp(-x) / x;
400 }
401 else if(x == 0.0) { // special case, this implies n > 1
402 result = 1.0 / nm1;
403 }
404 else if(x > 1.0) { // Lentz's algorithm, this implies n > 0
405 b = x + n;
406 c = 1.0 / fpmin;
407 d = 1.0 / b;
408 h = d;
409 for(int i = 1; i <= maxit; i++) {
410 a = -i * (nm1 + i);
411 b = b + 2.0;
412 d = 1.0 / (a * d + b);
413 c = b + a / c;
414 delta = c * d;
415 h = h * delta;
416 if(fabs(delta - 1.0) < epsilon) {
417 result = h * exp(-x);
418 return(result);
419 }
420 }
422 "AtmosModel::En() - Continued fraction failed to converge in "
423 + IString(maxit) + " iterations. Unable to calculate exponential integral.",
424 _FILEINFO_);
425 }
426 else { // evaluate series
427 if(nm1 != 0) {
428 result = 1.0 / nm1;
429 }
430 else {
431 result = -log(x) - euler;
432 }
433 fact = 1.0;
434 for(int i = 1; i <= maxit; i++) {
435 fact = -fact * x / i;
436 if(i != nm1) {
437 delta = -fact / (i - nm1);
438 }
439 else {
440 psi = -euler;
441 for(int ii = 1; ii <= nm1; ii++) {
442 psi = psi + 1.0 / ii;
443 }
444 delta = fact * (-log(x) + psi);
445 }
446 result = result + delta;
447 if(fabs(delta) < fabs(result)*epsilon) {
448 return(result);
449 }
450 }
452 "AtmosModel::En() - Series representation failed to converge in "
453 + IString(maxit) + " iterations. Unable to calculate exponential integral.",
454 _FILEINFO_);
455 }
456 return(result);
457 }
458
475 void AtmosModel::CalcAtmEffect(double pha, double inc, double ema,
476 double *pstd, double *trans, double *trans0, double *sbar,
477 double *transs) {
478
479 // Check validity of photometric angles
480 //if (pha > 180.0 || inc > 90.0 || ema > 90.0 || pha < 0.0 ||
481 // inc < 0.0 || ema < 0.0) {
482 // string msg = "Invalid photometric angles";
483 // throw IException::Message(IException::Programmer,msg,_FILEINFO_);
484 //}
485
486 // Apply atmospheric function
487 AtmosModelAlgorithm(pha, inc, ema);
488 *pstd = p_pstd;
489 *trans = p_trans;
490 *trans0 = p_trans0;
491 *sbar = p_sbar;
492 *transs = p_transs;
493 }
494
499 p_standardConditions = standard;
500 if(p_standardConditions) {
501 p_atmosTausave = p_atmosTau;
502 p_atmosTau = p_atmosTauref;
503 }
504 else {
505 p_atmosTau = p_atmosTausave;
506 }
507 }
508
538 int inccnt; //for loop incidence angle count, 1:ninc
539 double fun_temp;//temporary variable for integral
540 double factor; //factor for integration: 1 except at ends of interval where it's 1/2
541 double yp1, yp2; //first derivatives of first and last x values of @a p_atmosIncTable
542
545
546 p_atmosAb = 0.0;
547
548 //Create NumericalAtmosApprox object here for RombergsMethod used in for loop
550
551 for(inccnt = 0; inccnt < p_atmosNinc; inccnt++) {
552 p_atmosInc = (double) inccnt;
553 p_atmosIncTable[inccnt] = p_atmosInc;
554 p_atmosMunot = cos((PI / 180.0) * p_atmosInc);
555 p_atmosSini = sin((PI / 180.0) * p_atmosInc);
556
557 IString phtName = p_atmosPM->AlgorithmName();
558 phtName.UpCase();
559 if(p_atmosInc == 90.0) {
560 p_atmosAhTable[inccnt] = 0.0;
561 }
562 else if(phtName == "LAMBERT") {
563 p_atmosAhTable[inccnt] = 1.0;
564 }
565 else if(phtName == "LOMMELSEELIGER") {
566 p_atmosAhTable[inccnt] = 2.0 * log((1.0 / p_atmosMunot) / p_atmosMunot);
567 }
568 else if(phtName == "MINNAERT") {
569 p_atmosAhTable[inccnt] = (pow(p_atmosMunot, ((Minnaert *)p_atmosPM)->PhotoK())) / ((Minnaert *)p_atmosPM)->PhotoK();
570 }
571 else if(phtName == "LUNARLAMBERT") {
572 p_atmosAhTable[inccnt] = 2.0 * ((LunarLambert *)p_atmosPM)->PhotoL() *
573 log((1.0 + p_atmosMunot) / p_atmosMunot) + 1.0 -
574 ((LunarLambert *)p_atmosPM)->PhotoL();
575 }
576 else {
577 // numerically integrate the other photometric models
578 // outer integral is over phi from 0 to pi rad = 180 deg
579 p_atmosAtmSwitch = 0;
580 // integrate AtmosModel function from 0 to 180
581 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
582 // the correct normalization with phi in degrees is:
583 p_atmosAhTable[inccnt] = fun_temp / (90.0 * p_atmosMunot);
584 }
585 // Let's get our estimate of Ab by integrating (summing)
586 // A (i)sinicosi over our A table
587 if((inccnt == 0) || (inccnt == p_atmosNinc - 1)) {
588 factor = 0.5;
589 }
590 else {
591 factor = 1.0;
592 }
593
594 p_atmosAb = p_atmosAb + p_atmosAhTable[inccnt] * p_atmosMunot * p_atmosSini * factor;
595 }
596
597 factor = 2.0 * PI / 180.0;
598 p_atmosAb = p_atmosAb * factor;
599
600 // set up clamped cubic spline
601 yp1 = 1.0e30;
602 yp2 = 1.0e30;
605 p_atmosAhSpline.AddData(p_atmosIncTable, p_atmosAhTable);
607 }
608
638 int inccnt; // for loop incidence angle count,1:ninc
639 double fun_temp; // temporary variable for integral
640 double hahgsb_temp; // save increment to hahgsb
641 double factor; // factor for integration: 1 except at ends of interval where it's 1/2
642 double yp1, yp2; // derivatives of endpoints of data set
643
646
647 p_atmosHahgsb = 0.0;
649
650 for(inccnt = 0; inccnt < p_atmosNinc; inccnt++) {
651 p_atmosInc = (double) inccnt;
652 p_atmosIncTable[inccnt] = p_atmosInc;
653 p_atmosMunot = cos((PI / 180.0) * p_atmosInc);
654 p_atmosSini = sin((PI / 180.0) * p_atmosInc);
655
656 p_atmosAtmSwitch = 1;
657
658 qromb.Reset();
659 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
660
661 p_atmosHahgtTable[inccnt] = fun_temp * AtmosWha() / 360.0;
662 p_atmosAtmSwitch = 2;
663
664 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
665
666 hahgsb_temp = fun_temp * AtmosWha() / 360.0;
667
668 if((inccnt == 0) || (inccnt == p_atmosNinc - 1)) {
669 factor = 0.5;
670 }
671 else {
672 factor = 1.0;
673 }
674
675 p_atmosHahgsb = p_atmosHahgsb + p_atmosSini * factor * hahgsb_temp;
676 if(p_atmosInc == 0.0) {
677 p_atmosHahgt0Table[inccnt] = 0.0;
678 }
679 else {
680 p_atmosAtmSwitch = 3;
681 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
682 p_atmosHahgt0Table[inccnt] = fun_temp * AtmosWha() * p_atmosMunot / (360.0 * p_atmosSini);
683 }
684 }
685
686 factor = 2.0 * PI / 180.0;
687 p_atmosHahgsb = p_atmosHahgsb * factor;
688
689 // set up clamped cubic splines
690 yp1 = 1.0e30;
691 yp2 = 1.0e30;
694 p_atmosHahgtSpline.AddData(p_atmosIncTable, p_atmosHahgtTable);
696
699 p_atmosHahgt0Spline.AddData(p_atmosIncTable, p_atmosHahgt0Table);
701 }
702
727 int inccnt; // for loop incidence angle count,1:ninc
728 double fun_temp; // temporary variable for integral
729 double factor; // factor for integration: 1 except at ends of interval where it's 1/2
730 int nincl = 19; // used instead of p_atmosNinc
731 double deltaInc; // limits table size and increment used
732
735
736 p_atmosHahgsb = 0.0;
738 deltaInc = 90.0/(double)(nincl-1.0);
739
740 for(inccnt = 0; inccnt < nincl; inccnt++) {
741 p_atmosInc = deltaInc * (double) inccnt;
742 p_atmosMunot = cos((PI / 180.0) * p_atmosInc);
743 p_atmosSini = sin((PI / 180.0) * p_atmosInc);
744
745 p_atmosAtmSwitch = 2;
746
747 qromb.Reset();
748 if (p_atmosInc >= 90.0) {
749 fun_temp = 0.0;
750 } else {
751 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
752 }
753
754 if((inccnt == 0) || (inccnt == nincl - 1)) {
755 factor = 0.5;
756 }
757 else {
758 factor = 1.0;
759 }
760 p_atmosHahgsb = p_atmosHahgsb + p_atmosSini * factor * fun_temp *
761 AtmosWha() / 360.0;
762 }
763
764 factor = 2.0 * deltaInc * PI / 180.0;
765 p_atmosHahgsb = p_atmosHahgsb * factor;
766 }
767
779 void AtmosModel::SetAtmosAtmSwitch(const int atmswitch) {
780 if(atmswitch < 0 || atmswitch > 3) {
781 string msg = "Invalid value of atmospheric atmswitch [" + IString(atmswitch) + "]";
782 throw IException(IException::User, msg, _FILEINFO_);
783 }
784
785 p_atmosAtmSwitch = atmswitch;
786 }
787
799 void AtmosModel::SetAtmosBha(const double bha) {
800 if(bha < -1.0 || bha > 1.0) {
801 string msg = "Invalid value of Anisotropic atmospheric bha [" +
802 IString(bha) + "]";
803 throw IException(IException::User, msg, _FILEINFO_);
804 }
805
806 p_atmosBha = bha;
807 }
808
820 void AtmosModel::SetAtmosHga(const double hga) {
821 if(hga <= -1.0 || hga >= 1.0) {
822 string msg = "Invalid value of Hapke atmospheric hga [" + IString(hga) + "]";
823 throw IException(IException::User, msg, _FILEINFO_);
824 }
825
826 p_atmosHga = hga;
827 }
828
839 void AtmosModel::SetAtmosInc(const double inc) {
840 if(inc < 0.0 || inc > 90.0) {
841 string msg = "Invalid value of atmospheric inc [" + IString(inc) + "]";
842 throw IException(IException::User, msg, _FILEINFO_);
843 }
844
845 p_atmosInc = inc;
846 p_atmosMunot = cos(inc * PI / 180.0);
847 p_atmosSini = sin(inc * PI / 180.0);
848 }
849
861 void AtmosModel::SetAtmosNulneg(const string nulneg) {
862 IString temp(nulneg);
863 temp = temp.UpCase();
864
865 if(temp != "NO" && temp != "YES") {
866 string msg = "Invalid value of Atmospheric nulneg [" + temp + "]";
867 throw IException(IException::User, msg, _FILEINFO_);
868 }
869
870 SetAtmosNulneg(temp.compare("YES") == 0);
871 }
872
884 void AtmosModel::SetAtmosPhi(const double phi) {
885 if(phi < 0.0 || phi > 360.0) {
886 string msg = "Invalid value of atmospheric phi [" + IString(phi) + "]";
887 throw IException(IException::User, msg, _FILEINFO_);
888 }
889
890 p_atmosPhi = phi;
891 p_atmosCosphi = cos(phi * PI / 180.0);
892 }
893
903 void AtmosModel::SetAtmosTau(const double tau) {
904 if(tau < 0.0) {
905 string msg = "Invalid value of Atmospheric tau [" + IString(tau) + "]";
906 throw IException(IException::User, msg, _FILEINFO_);
907 }
908
909 p_atmosTau = tau;
910 }
911
922 void AtmosModel::SetAtmosTauref(const double tauref) {
923 if(tauref < 0.0) {
924 string msg = "Invalid value of Atmospheric tauref [" + IString(tauref) + "]";
925 throw IException(IException::User, msg, _FILEINFO_);
926 }
927
928 p_atmosTauref = tauref;
929 }
930
941 void AtmosModel::SetAtmosWha(const double wha) {
942 if(wha <= 0.0 || wha > 1.0) {
943 string msg = "Invalid value of Atmospheric wha [" + IString(wha) + "]";
944 throw IException(IException::User, msg, _FILEINFO_);
945 }
946
947 p_atmosWha = wha;
948 }
949
955 return (AtmosTau() != p_atmosTauold) || (AtmosWha() != p_atmosWhaold);
956 }
957
968 void AtmosModel::SetAtmosHnorm(const double hnorm) {
969 if(hnorm < 0.0) {
970 QString msg = "Invalid value of Atmospheric hnorm [" + toString(hnorm) + "]";
971 throw IException(IException::User, msg, _FILEINFO_);
972 }
973 p_atmosHnorm = hnorm;
974 }
975
983 void AtmosModel::SetAtmosIord(const string offset) {
984 IString temp(offset);
985 temp = temp.UpCase();
986
987 if(temp != "NO" && temp != "YES") {
988 string msg = "Invalid value of Atmospheric additive offset[" + temp + "]";
989 throw IException(IException::User, msg, _FILEINFO_);
990 }
991
992 SetAtmosIord(temp.compare("YES") == 0);
993 }
994
1002 void AtmosModel::SetAtmosEstTau(const string esttau) {
1003 IString temp(esttau);
1004 temp = temp.UpCase();
1005
1006 if(temp != "NO" && temp != "YES") {
1007 string msg = "Invalid value of Atmospheric optical depth estimation[" + temp + "]";
1008 throw IException(IException::User, msg, _FILEINFO_);
1009 }
1010
1011 SetAtmosEstTau(temp.compare("YES") == 0);
1012 }
1013}
double p_trans
Transmission of surface reflected light through the atmosphere overall.
Definition AtmosModel.h:259
static double En(unsigned int n, double x)
This routine evaluates the generalized exponential integral, En(x).
void SetAtmosHga(const double hga)
Set the Hapke atmospheric function parameter.
double p_atmosHnorm
Atmospheric shell thickness normalized to planet radius.
Definition AtmosModel.h:267
double p_sbar
Illumination of the ground by the sky.
Definition AtmosModel.h:262
bool p_atmosEstTau
Estimate optical depth tau using shadows.
Definition AtmosModel.h:269
void SetAtmosInc(const double inc)
Set the incidence angle.
void SetAtmosEstTau(const string esttau)
Estimate the optical depth tau using shadows.
NumericalApproximation p_atmosAhSpline
Spline object for the atmospheric Ah Table. Properties are set in GenerateAhTable().
Definition AtmosModel.h:283
double AtmosTau() const
Return atmospheric Tau value.
Definition AtmosModel.h:119
static double G11Prime(double tau)
Perform Chandra and Van de Hulst's series approximation for the g'11 function needed in second order ...
void SetAtmosWha(const double wha)
Set the Atmospheric function parameter.
bool p_atmosAddOffset
Allow additive offset in fit.
Definition AtmosModel.h:268
void SetAtmosTau(const double tau)
Set the Atmospheric function parameter.
void SetAtmosBha(const double bha)
Set the Anisotropic Atmospheric function parameter.
double p_transs
Transmission of light that must be subtracted from the flat surface model to get the shadow model.
Definition AtmosModel.h:261
NumericalApproximation p_atmosHahgt0Spline
Spline object for the atmospheric Hahg0 Table. Properties are set in GenerateHahgTables().
Definition AtmosModel.h:287
static double Ei(double x)
This routine computes the exponential integral, Ei(x).
void SetAtmosIord(const string offset)
Set additive offset in fit.
void GenerateAhTable()
This method computes the values of the atmospheric Ah table and sets the properties of the atmospheri...
void SetAtmosHnorm(const double hnorm)
Set the Atmospheric function parameter.
void SetAtmosAtmSwitch(const int atmswitch)
Set the switch that controls the function that will be integrated.
virtual void SetStandardConditions(bool standard)
Used to calculate atmosphere at standard conditions.
void GenerateHahgTablesShadow()
This method is a modified version of the GenerateHahgTables method and is used solely for shadow mode...
AtmosModel(Pvl &pvl, PhotoModel &pmodel)
Create an AtmosModel object.
double p_pstd
Pure atmospheric-scattering term.
Definition AtmosModel.h:258
void SetAtmosPhi(const double phi)
Set the azimuth angle.
void SetAtmosNulneg(const string nulneg)
Set the Atmospheric function parameter.
double p_trans0
Transmission of surface reflected light through the atmosphere with no scatterings in the atmosphere.
Definition AtmosModel.h:260
void CalcAtmEffect(double pha, double inc, double ema, double *pstd, double *trans, double *trans0, double *sbar, double *transs)
Calculate the atmospheric scattering effect using photometric angle information.
NumericalApproximation p_atmosHahgtSpline
Spline object for the atmospheric Hahg Table. Properties are set in GenerateHahgTables().
Definition AtmosModel.h:285
double AtmosWha() const
Return atmospheric Wha value.
Definition AtmosModel.h:123
void GenerateHahgTables()
This method computes the values of the atmospheric Hahg and Hahg0 tables and sets the properties of t...
void SetAtmosTauref(const double tauref)
Set the Atmospheric function parameter.
bool TauOrWhaChanged() const
Checks whether tau or wha have changed.
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Adds specific functionality to C++ strings.
Definition IString.h:165
Lunar (Lommel-Seeliger)-Lambert law photometric model Derive model albedo for Lunar (Lommel-Seeliger)...
Minnaert photometric model Derive model albedo using Minnaert equation.
Definition Minnaert.h:42
@ CubicClamped
Cubic Spline interpolation with clamped boundary conditions.
void SetInterpType(NumericalApproximation::InterpType itype)
Sets interpolation type.
void Reset()
Resets the state of the object.
void SetCubicClampedEndptDeriv(const double yp1, const double ypn)
Sets the values for the first derivatives of the endpoints of the data set.
void AddData(const double x, const double y)
Add a datapoint to the set.
This class extends Isis::NumericalApproximation.
IntegFunc
This enum defines function to be integrated by Romberg's method.
@ OuterFunction
Indicates that Romberg's method will integrate the function OutrFunc2Bint()
QString AlgorithmName() const
Return algorithm name found in Pvl file from constructor.
Definition PhotoModel.h:47
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
@ Traverse
Search child objects.
Definition PvlObject.h:158
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
const double PI
The mathematical constant PI.
Definition Constants.h:40
Namespace for the standard library.