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 
21 using namespace std;
22 
23 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
24 namespace Isis {
41  AtmosModel::AtmosModel(Pvl &pvl, PhotoModel &pmodel) {
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) {
247  throw IException(IException::Programmer,
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  }
267  throw IException(IException::Unknown,
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  }
421  throw IException(IException::Unknown,
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  }
451  throw IException(IException::Unknown,
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 
498  void AtmosModel::SetStandardConditions(bool standard) {
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 
537  void AtmosModel::GenerateAhTable() {
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 
544  sub = NumericalAtmosApprox::OuterFunction;
545 
546  p_atmosAb = 0.0;
547 
548  //Create NumericalAtmosApprox object here for RombergsMethod used in for loop
549  NumericalAtmosApprox qromb;
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;
603  p_atmosAhSpline.Reset();
604  p_atmosAhSpline.SetInterpType(NumericalApproximation::CubicClamped);
605  p_atmosAhSpline.AddData(p_atmosIncTable, p_atmosAhTable);
606  p_atmosAhSpline.SetCubicClampedEndptDeriv(yp1, yp2);
607  }
608 
637  void AtmosModel::GenerateHahgTables() {
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 
645  sub = NumericalAtmosApprox::OuterFunction;
646 
647  p_atmosHahgsb = 0.0;
648  NumericalAtmosApprox qromb;
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;
692  p_atmosHahgtSpline.Reset();
693  p_atmosHahgtSpline.SetInterpType(NumericalApproximation::CubicClamped);
694  p_atmosHahgtSpline.AddData(p_atmosIncTable, p_atmosHahgtTable);
695  p_atmosHahgtSpline.SetCubicClampedEndptDeriv(yp1, yp2);
696 
697  p_atmosHahgt0Spline.Reset();
698  p_atmosHahgt0Spline.SetInterpType(NumericalApproximation::CubicClamped);
699  p_atmosHahgt0Spline.AddData(p_atmosIncTable, p_atmosHahgt0Table);
700  p_atmosHahgt0Spline.SetCubicClampedEndptDeriv(yp1, yp2);
701  }
702 
726  void AtmosModel::GenerateHahgTablesShadow() {
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 
734  sub = NumericalAtmosApprox::OuterFunction;
735 
736  p_atmosHahgsb = 0.0;
737  NumericalAtmosApprox qromb;
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 
954  bool AtmosModel::TauOrWhaChanged() const {
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 }
Isis::NumericalAtmosApprox::IntegFunc
IntegFunc
This enum defines function to be integrated by Romberg's method.
Definition: NumericalAtmosApprox.h:43
Isis::PhotoModel
Definition: PhotoModel.h:41
Isis::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::LunarLambert
Lunar (Lommel-Seeliger)-Lambert law photometric model Derive model albedo for Lunar (Lommel-Seeliger)...
Definition: LunarLambert.h:32
Isis::NumericalAtmosApprox
This class extends Isis::NumericalApproximation.
Definition: NumericalAtmosApprox.h:32
Isis::Minnaert
Minnaert photometric model Derive model albedo using Minnaert equation.
Definition: Minnaert.h:42
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::IString::UpCase
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
Definition: IString.cpp:617
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::PvlObject::findObject
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition: PvlObject.h:274
Isis::IException
Isis exception class.
Definition: IException.h:91
std
Namespace for the standard library.
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::NumericalAtmosApprox::RombergsMethod
double RombergsMethod(AtmosModel *am, IntegFunc sub, double a, double b)
This variation on the NumericalApproximation method integrates a specified AtmosModel function rather...
Definition: NumericalAtmosApprox.cpp:52
Isis::NumericalApproximation::Reset
void Reset()
Resets the state of the object.
Definition: NumericalApproximation.cpp:2251
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16