Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
AtmosModel.cpp
1
5
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
23namespace Isis {
41 p_atmosAlgorithmName = "Unknown";
42 p_atmosPM = &pmodel;
43
44 p_atmosIncTable.resize(91);
45 p_atmosAhTable.resize(91);
46 p_atmosHahgtTable.resize(91);
47 p_atmosHahgt0Table.resize(91);
48 p_atmosAb = 0.0;
49 p_atmosCosphi = 0.0;
50 p_atmosAtmSwitch = 0;
51 p_atmosEulgam = 0.5772156;
52 p_atmosHahgsb = 0.0;
53 p_atmosHga = 0.68;
54 p_atmosInc = 0.0;
55 p_atmosMunot = 0.0;
56 p_atmosNinc = 91;
57 p_atmosPhi = 0.0;
58 p_atmosSini = 0.0;
59 p_atmosTau = 0.28;
60 p_atmosTauref = 0.0;
61 p_atmosTauold = -1.0;
62 p_atmosWha = 0.95;
63 p_atmosWhaold = 1.0e30;
64 p_atmosBha = 0.85;
65 p_atmosHnorm = 0.003;
66 p_pstd = 0.0;
67 p_sbar = 0.0;
68 p_trans = 0.0;
69 p_trans0 = 0.0;
70 p_transs = 0.0;
71 p_standardConditions = false;
72
73 PvlGroup &algorithm = pvl.findObject("AtmosphericModel").findGroup("Algorithm", Pvl::Traverse);
74
75 if(algorithm.hasKeyword("Nulneg")) {
76 SetAtmosNulneg(algorithm["Nulneg"][0] == "YES");
77 }
78 else {
79 p_atmosNulneg = false;
80 }
81
82 if(algorithm.hasKeyword("Tau")) {
83 SetAtmosTau(algorithm["Tau"]);
84 }
85 p_atmosTausave = p_atmosTau;
86
87 if(algorithm.hasKeyword("Tauref")) {
88 SetAtmosTauref(algorithm["Tauref"]);
89 }
90
91 if(algorithm.hasKeyword("Wha")) {
92 SetAtmosWha(algorithm["Wha"]);
93 }
94 p_atmosWhasave = p_atmosWha;
95
96 if(algorithm.hasKeyword("Hga")) {
97 SetAtmosHga(algorithm["Hga"]);
98 }
99 p_atmosHgasave = p_atmosHga;
100
101 if(algorithm.hasKeyword("Bha")) {
102 SetAtmosBha(algorithm["Bha"]);
103 }
104 p_atmosBhasave = p_atmosBha;
105
106 if(algorithm.hasKeyword("Inc")) {
107 SetAtmosInc(algorithm["Inc"]);
108 }
109
110 if(algorithm.hasKeyword("Phi")) {
111 SetAtmosPhi(algorithm["Phi"]);
112 }
113
114 if(algorithm.hasKeyword("Hnorm")) {
115 SetAtmosHnorm(algorithm["Hnorm"]);
116 }
117
118 if(algorithm.hasKeyword("Iord")) {
119 SetAtmosIord(algorithm["Iord"][0] == "YES");
120 }
121 else {
122 p_atmosAddOffset = false;
123 }
124
125 if(algorithm.hasKeyword("EstTau")) {
126 SetAtmosEstTau(algorithm["EstTau"][0] == "YES");
127 }
128 else {
129 p_atmosEstTau = false;
130 }
131 }
132
152 double AtmosModel::G11Prime(double tau) {
153 double sum;
154 int icnt;
155 double fac;
156 double term;
157 double tol;
158 double fi;
159 double elog;
160 double eulgam;
161 double e1_2;
162 double result;
163
164 tol = 1.0e-6;
165 eulgam = 0.5772156;
166
167 sum = 0.0;
168 icnt = 1;
169 fac = -tau;
170 term = fac;
171 while(fabs(term) > fabs(sum)*tol) {
172 sum = sum + term;
173 icnt = icnt + 1;
174 fi = (double) icnt;
175 fac = fac * (-tau) / fi;
176 term = fac / (fi * fi);
177 }
178 elog = log(std::max(1.0e-30, tau)) + eulgam;
179 e1_2 = sum + PI * PI / 12.0 + 0.5 *
180 pow(elog, 2.0);
181 result = 2.0 * (AtmosModel::En(1, tau)
182 + elog * AtmosModel::En(2, tau)
183 - tau * e1_2);
184 return(result);
185 }
186
228 double AtmosModel::Ei(double x) {
229 //static double r8ei(double x) in original NumericalMethods class
230 // This method was derived from an algorithm in the text
231 // Numerical Recipes in C: The Art of Scientific Computing
232 // Section 6.3 by Flannery, Press, Teukolsky, and Vetterling
233 double result;
234 double fpmin; // close to smallest representable floating-point number
235 double euler; // Euler's constant, lower-case gamma
236 double epsilon; // desired relative error (tolerance)
237 int maxit; // maximum number of iterations allowed
238 double sum, fact, term, prev;
239
240 fpmin = 1.0e-30;
241 maxit = 100;
242 epsilon = 6.0e-8;
243 euler = 0.57721566;
244
245 if(x <= 0.0) {
246 throw IException(IException::Programmer,
247 "AtmosModel::Ei() - Invalid argument. Definition requires x > 0.0. Entered x = "
248 + IString(x),
249 _FILEINFO_);
250 }
251 if(x < fpmin) { //special case: avoid failure of convergence test because underflow
252 result = log(x) + euler;
253 }
254 else if(x <= -log(epsilon)) { //Use power series
255 sum = 0.0;
256 fact = 1.0;
257 for(int k = 1; k <= maxit; k++) {
258 fact = fact * x / k;
259 term = fact / k;
260 sum = sum + term;
261 if(term < epsilon * sum) {
262 result = sum + log(x) + euler;
263 return(result);
264 }
265 }
266 throw IException(IException::Unknown,
267 "AtmosModel::Ei() - Power series failed to converge in "
268 + IString(maxit) + " iterations. Unable to calculate exponential integral.",
269 _FILEINFO_);
270 }
271 else { // Use asymptotic series
272 sum = 0.0;
273 term = 1.0;
274 for(int k = 1; k <= maxit; k++) {
275 prev = term;
276 term = term * k / x;
277 if(term < epsilon) {
278 result = exp(x) * (1.0 + sum) / x;
279 return(result);
280 }
281 else {
282 if(term < prev) { // still converging: add new term
283 sum = sum + term;
284 }
285 else { // diverging: subtract previous term and exit
286 sum = sum - prev;
287 result = exp(x) * (1.0 + sum) / x;
288 return(result);
289 }
290 }
291 }
292 result = exp(x) * (1.0 + sum) / x;
293 }
294 return(result);
295 }
296
369 double AtmosModel::En(unsigned int n, double x) {
370 //static double r8expint(int n, double x) in original NumericalMethods class
371 // This method was derived from an algorithm in the text
372 // Numerical Recipes in C: The Art of Scientific Computing
373 // Section 6.3 by Flannery, Press, Teukolsky, and Vetterling
374 int nm1;
375 double result;
376 double a, b, c, d, h;
377 double delta;
378 double fact;
379 double psi;
380 double fpmin; // close to smallest representable floating-point number
381 double maxit; // maximum number of iterations allowed
382 double epsilon; // desired relative error (tolerance)
383 double euler; // Euler's constant, gamma
384
385 fpmin = 1.0e-30;
386 maxit = 100;
387 epsilon = 1.0e-7;
388 euler = 0.5772156649;
389
390 nm1 = n - 1;
391 if((x < 0.0) || (x == 0.0 && (n == 0 || n == 1))) {
392 IString msg = "AtmosModel::En() - Invalid arguments. ";
393 msg += "Definition requires (x > 0.0 and n >=0 ) or (x >= 0.0 and n > 1). ";
394 msg += "Entered x = " + IString(x) + " and n = " + IString((int) n);
395 throw IException(IException::Programmer, msg, _FILEINFO_);
396 }
397 else if(n == 0) { // special case, this implies x > 0 by logic above
398 result = exp(-x) / x;
399 }
400 else if(x == 0.0) { // special case, this implies n > 1
401 result = 1.0 / nm1;
402 }
403 else if(x > 1.0) { // Lentz's algorithm, this implies n > 0
404 b = x + n;
405 c = 1.0 / fpmin;
406 d = 1.0 / b;
407 h = d;
408 for(int i = 1; i <= maxit; i++) {
409 a = -i * (nm1 + i);
410 b = b + 2.0;
411 d = 1.0 / (a * d + b);
412 c = b + a / c;
413 delta = c * d;
414 h = h * delta;
415 if(fabs(delta - 1.0) < epsilon) {
416 result = h * exp(-x);
417 return(result);
418 }
419 }
420 throw IException(IException::Unknown,
421 "AtmosModel::En() - Continued fraction failed to converge in "
422 + IString(maxit) + " iterations. Unable to calculate exponential integral.",
423 _FILEINFO_);
424 }
425 else { // evaluate series
426 if(nm1 != 0) {
427 result = 1.0 / nm1;
428 }
429 else {
430 result = -log(x) - euler;
431 }
432 fact = 1.0;
433 for(int i = 1; i <= maxit; i++) {
434 fact = -fact * x / i;
435 if(i != nm1) {
436 delta = -fact / (i - nm1);
437 }
438 else {
439 psi = -euler;
440 for(int ii = 1; ii <= nm1; ii++) {
441 psi = psi + 1.0 / ii;
442 }
443 delta = fact * (-log(x) + psi);
444 }
445 result = result + delta;
446 if(fabs(delta) < fabs(result)*epsilon) {
447 return(result);
448 }
449 }
450 throw IException(IException::Unknown,
451 "AtmosModel::En() - Series representation failed to converge in "
452 + IString(maxit) + " iterations. Unable to calculate exponential integral.",
453 _FILEINFO_);
454 }
455 return(result);
456 }
457
474 void AtmosModel::CalcAtmEffect(double pha, double inc, double ema,
475 double *pstd, double *trans, double *trans0, double *sbar,
476 double *transs) {
477
478 // Check validity of photometric angles
479 //if (pha > 180.0 || inc > 90.0 || ema > 90.0 || pha < 0.0 ||
480 // inc < 0.0 || ema < 0.0) {
481 // string msg = "Invalid photometric angles";
482 // throw IException::Message(IException::Programmer,msg,_FILEINFO_);
483 //}
484
485 // Apply atmospheric function
486 AtmosModelAlgorithm(pha, inc, ema);
487 *pstd = p_pstd;
488 *trans = p_trans;
489 *trans0 = p_trans0;
490 *sbar = p_sbar;
491 *transs = p_transs;
492 }
493
498 p_standardConditions = standard;
499 if(p_standardConditions) {
500 p_atmosTausave = p_atmosTau;
501 p_atmosTau = p_atmosTauref;
502 }
503 else {
504 p_atmosTau = p_atmosTausave;
505 }
506 }
507
537 int inccnt; //for loop incidence angle count, 1:ninc
538 double fun_temp;//temporary variable for integral
539 double factor; //factor for integration: 1 except at ends of interval where it's 1/2
540 double yp1, yp2; //first derivatives of first and last x values of @a p_atmosIncTable
541
544
545 p_atmosAb = 0.0;
546
547 //Create NumericalAtmosApprox object here for RombergsMethod used in for loop
548 NumericalAtmosApprox qromb;
549
550 for(inccnt = 0; inccnt < p_atmosNinc; inccnt++) {
551 p_atmosInc = (double) inccnt;
552 p_atmosIncTable[inccnt] = p_atmosInc;
553 p_atmosMunot = cos((PI / 180.0) * p_atmosInc);
554 p_atmosSini = sin((PI / 180.0) * p_atmosInc);
555
556 IString phtName = p_atmosPM->AlgorithmName();
557 phtName.UpCase();
558 if(p_atmosInc == 90.0) {
559 p_atmosAhTable[inccnt] = 0.0;
560 }
561 else if(phtName == "LAMBERT") {
562 p_atmosAhTable[inccnt] = 1.0;
563 }
564 else if(phtName == "LOMMELSEELIGER") {
565 p_atmosAhTable[inccnt] = 2.0 * log((1.0 / p_atmosMunot) / p_atmosMunot);
566 }
567 else if(phtName == "MINNAERT") {
568 p_atmosAhTable[inccnt] = (pow(p_atmosMunot, ((Minnaert *)p_atmosPM)->PhotoK())) / ((Minnaert *)p_atmosPM)->PhotoK();
569 }
570 else if(phtName == "LUNARLAMBERT") {
571 p_atmosAhTable[inccnt] = 2.0 * ((LunarLambert *)p_atmosPM)->PhotoL() *
572 log((1.0 + p_atmosMunot) / p_atmosMunot) + 1.0 -
573 ((LunarLambert *)p_atmosPM)->PhotoL();
574 }
575 else {
576 // numerically integrate the other photometric models
577 // outer integral is over phi from 0 to pi rad = 180 deg
578 p_atmosAtmSwitch = 0;
579 // integrate AtmosModel function from 0 to 180
580 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
581 // the correct normalization with phi in degrees is:
582 p_atmosAhTable[inccnt] = fun_temp / (90.0 * p_atmosMunot);
583 }
584 // Let's get our estimate of Ab by integrating (summing)
585 // A (i)sinicosi over our A table
586 if((inccnt == 0) || (inccnt == p_atmosNinc - 1)) {
587 factor = 0.5;
588 }
589 else {
590 factor = 1.0;
591 }
592
593 p_atmosAb = p_atmosAb + p_atmosAhTable[inccnt] * p_atmosMunot * p_atmosSini * factor;
594 }
595
596 factor = 2.0 * PI / 180.0;
597 p_atmosAb = p_atmosAb * factor;
598
599 // set up clamped cubic spline
600 yp1 = 1.0e30;
601 yp2 = 1.0e30;
602 p_atmosAhSpline.Reset();
604 p_atmosAhSpline.AddData(p_atmosIncTable, p_atmosAhTable);
605 p_atmosAhSpline.SetCubicClampedEndptDeriv(yp1, yp2);
606 }
607
637 int inccnt; // for loop incidence angle count,1:ninc
638 double fun_temp; // temporary variable for integral
639 double hahgsb_temp; // save increment to hahgsb
640 double factor; // factor for integration: 1 except at ends of interval where it's 1/2
641 double yp1, yp2; // derivatives of endpoints of data set
642
645
646 p_atmosHahgsb = 0.0;
647 NumericalAtmosApprox qromb;
648
649 for(inccnt = 0; inccnt < p_atmosNinc; inccnt++) {
650 p_atmosInc = (double) inccnt;
651 p_atmosIncTable[inccnt] = p_atmosInc;
652 p_atmosMunot = cos((PI / 180.0) * p_atmosInc);
653 p_atmosSini = sin((PI / 180.0) * p_atmosInc);
654
655 p_atmosAtmSwitch = 1;
656
657 qromb.Reset();
658 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
659
660 p_atmosHahgtTable[inccnt] = fun_temp * AtmosWha() / 360.0;
661 p_atmosAtmSwitch = 2;
662
663 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
664
665 hahgsb_temp = fun_temp * AtmosWha() / 360.0;
666
667 if((inccnt == 0) || (inccnt == p_atmosNinc - 1)) {
668 factor = 0.5;
669 }
670 else {
671 factor = 1.0;
672 }
673
674 p_atmosHahgsb = p_atmosHahgsb + p_atmosSini * factor * hahgsb_temp;
675 if(p_atmosInc == 0.0) {
676 p_atmosHahgt0Table[inccnt] = 0.0;
677 }
678 else {
679 p_atmosAtmSwitch = 3;
680 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
681 p_atmosHahgt0Table[inccnt] = fun_temp * AtmosWha() * p_atmosMunot / (360.0 * p_atmosSini);
682 }
683 }
684
685 factor = 2.0 * PI / 180.0;
686 p_atmosHahgsb = p_atmosHahgsb * factor;
687
688 // set up clamped cubic splines
689 yp1 = 1.0e30;
690 yp2 = 1.0e30;
691 p_atmosHahgtSpline.Reset();
693 p_atmosHahgtSpline.AddData(p_atmosIncTable, p_atmosHahgtTable);
694 p_atmosHahgtSpline.SetCubicClampedEndptDeriv(yp1, yp2);
695
696 p_atmosHahgt0Spline.Reset();
698 p_atmosHahgt0Spline.AddData(p_atmosIncTable, p_atmosHahgt0Table);
699 p_atmosHahgt0Spline.SetCubicClampedEndptDeriv(yp1, yp2);
700 }
701
726 int inccnt; // for loop incidence angle count,1:ninc
727 double fun_temp; // temporary variable for integral
728 double factor; // factor for integration: 1 except at ends of interval where it's 1/2
729 int nincl = 19; // used instead of p_atmosNinc
730 double deltaInc; // limits table size and increment used
731
734
735 p_atmosHahgsb = 0.0;
736 NumericalAtmosApprox qromb;
737 deltaInc = 90.0/(double)(nincl-1.0);
738
739 for(inccnt = 0; inccnt < nincl; inccnt++) {
740 p_atmosInc = deltaInc * (double) inccnt;
741 p_atmosMunot = cos((PI / 180.0) * p_atmosInc);
742 p_atmosSini = sin((PI / 180.0) * p_atmosInc);
743
744 p_atmosAtmSwitch = 2;
745
746 qromb.Reset();
747 if (p_atmosInc >= 90.0) {
748 fun_temp = 0.0;
749 } else {
750 fun_temp = qromb.RombergsMethod(this, sub, 0, 180);
751 }
752
753 if((inccnt == 0) || (inccnt == nincl - 1)) {
754 factor = 0.5;
755 }
756 else {
757 factor = 1.0;
758 }
759 p_atmosHahgsb = p_atmosHahgsb + p_atmosSini * factor * fun_temp *
760 AtmosWha() / 360.0;
761 }
762
763 factor = 2.0 * deltaInc * PI / 180.0;
764 p_atmosHahgsb = p_atmosHahgsb * factor;
765 }
766
778 void AtmosModel::SetAtmosAtmSwitch(const int atmswitch) {
779 if(atmswitch < 0 || atmswitch > 3) {
780 string msg = "Invalid value of atmospheric atmswitch [" + IString(atmswitch) + "]";
781 throw IException(IException::User, msg, _FILEINFO_);
782 }
783
784 p_atmosAtmSwitch = atmswitch;
785 }
786
798 void AtmosModel::SetAtmosBha(const double bha) {
799 if(bha < -1.0 || bha > 1.0) {
800 string msg = "Invalid value of Anisotropic atmospheric bha [" +
801 IString(bha) + "]";
802 throw IException(IException::User, msg, _FILEINFO_);
803 }
804
805 p_atmosBha = bha;
806 }
807
819 void AtmosModel::SetAtmosHga(const double hga) {
820 if(hga <= -1.0 || hga >= 1.0) {
821 string msg = "Invalid value of Hapke atmospheric hga [" + IString(hga) + "]";
822 throw IException(IException::User, msg, _FILEINFO_);
823 }
824
825 p_atmosHga = hga;
826 }
827
838 void AtmosModel::SetAtmosInc(const double inc) {
839 if(inc < 0.0 || inc > 90.0) {
840 string msg = "Invalid value of atmospheric inc [" + IString(inc) + "]";
841 throw IException(IException::User, msg, _FILEINFO_);
842 }
843
844 p_atmosInc = inc;
845 p_atmosMunot = cos(inc * PI / 180.0);
846 p_atmosSini = sin(inc * PI / 180.0);
847 }
848
860 void AtmosModel::SetAtmosNulneg(const string nulneg) {
861 IString temp(nulneg);
862 temp = temp.UpCase();
863
864 if(temp != "NO" && temp != "YES") {
865 string msg = "Invalid value of Atmospheric nulneg [" + temp + "]";
866 throw IException(IException::User, msg, _FILEINFO_);
867 }
868
869 SetAtmosNulneg(temp.compare("YES") == 0);
870 }
871
883 void AtmosModel::SetAtmosPhi(const double phi) {
884 if(phi < 0.0 || phi > 360.0) {
885 string msg = "Invalid value of atmospheric phi [" + IString(phi) + "]";
886 throw IException(IException::User, msg, _FILEINFO_);
887 }
888
889 p_atmosPhi = phi;
890 p_atmosCosphi = cos(phi * PI / 180.0);
891 }
892
902 void AtmosModel::SetAtmosTau(const double tau) {
903 if(tau < 0.0) {
904 string msg = "Invalid value of Atmospheric tau [" + IString(tau) + "]";
905 throw IException(IException::User, msg, _FILEINFO_);
906 }
907
908 p_atmosTau = tau;
909 }
910
921 void AtmosModel::SetAtmosTauref(const double tauref) {
922 if(tauref < 0.0) {
923 string msg = "Invalid value of Atmospheric tauref [" + IString(tauref) + "]";
924 throw IException(IException::User, msg, _FILEINFO_);
925 }
926
927 p_atmosTauref = tauref;
928 }
929
940 void AtmosModel::SetAtmosWha(const double wha) {
941 if(wha <= 0.0 || wha > 1.0) {
942 string msg = "Invalid value of Atmospheric wha [" + IString(wha) + "]";
943 throw IException(IException::User, msg, _FILEINFO_);
944 }
945
946 p_atmosWha = wha;
947 }
948
954 return (AtmosTau() != p_atmosTauold) || (AtmosWha() != p_atmosWhaold);
955 }
956
967 void AtmosModel::SetAtmosHnorm(const double hnorm) {
968 if(hnorm < 0.0) {
969 QString msg = "Invalid value of Atmospheric hnorm [" + toString(hnorm) + "]";
970 throw IException(IException::User, msg, _FILEINFO_);
971 }
972 p_atmosHnorm = hnorm;
973 }
974
982 void AtmosModel::SetAtmosIord(const string offset) {
983 IString temp(offset);
984 temp = temp.UpCase();
985
986 if(temp != "NO" && temp != "YES") {
987 string msg = "Invalid value of Atmospheric additive offset[" + temp + "]";
988 throw IException(IException::User, msg, _FILEINFO_);
989 }
990
991 SetAtmosIord(temp.compare("YES") == 0);
992 }
993
1001 void AtmosModel::SetAtmosEstTau(const string esttau) {
1002 IString temp(esttau);
1003 temp = temp.UpCase();
1004
1005 if(temp != "NO" && temp != "YES") {
1006 string msg = "Invalid value of Atmospheric optical depth estimation[" + temp + "]";
1007 throw IException(IException::User, msg, _FILEINFO_);
1008 }
1009
1010 SetAtmosEstTau(temp.compare("YES") == 0);
1011 }
1012}
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.
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 Reset()
Resets the state of the object.
double RombergsMethod(AtmosModel *am, IntegFunc sub, double a, double b)
This variation on the NumericalApproximation method integrates a specified AtmosModel function rather...
IntegFunc
This enum defines function to be integrated by Romberg's method.
@ OuterFunction
Indicates that Romberg's method will integrate the function OutrFunc2Bint()
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.
Namespace for the standard library.