ReFRACtor
chapman_boa_rt.cc
Go to the documentation of this file.
1 #include "chapman_boa_rt.h"
2 #include "wgs84_constant.h"
3 #include "ostream_pad.h"
4 
5 using namespace FullPhysics;
6 using namespace blitz;
7 
10  const blitz::Array<double, 1>& Sza,
11  const SpectralBound& Spec_bound)
12 {
13  const boost::shared_ptr<AtmosphereOco> atm_oco(boost::dynamic_pointer_cast<AtmosphereOco>(Atm));
14  return boost::shared_ptr<RadiativeTransfer>(new ChapmanBoaRT(atm_oco, Sza, Spec_bound));
15 }
16 
17 #ifdef HAVE_LUA
18 #include "register_lua.h"
20 .scope
21 [
23 ]
25 #endif
26 
28  const blitz::Array<double, 1>& Sza)
29  : atm(Atm), sza(Sza)
30 {
31  // Watch atmosphere for changes, so we clear cache if needed.
32  atm->add_observer(*this);
33 
34  // Cache is state since we have just been initialized
35  chapman_cache_stale.resize(Sza.rows());
36  chapman_cache_stale = true;
37 
38  chapman_boa.resize(Sza.rows());
39 }
40 
42  const blitz::Array<double, 1>& Sza,
43  const SpectralBound& Spec_bound)
44  : spec_bound(Spec_bound), atm(Atm), sza(Sza)
45 {
46  // Watch atmosphere for changes, so we clear cache if needed.
47  atm->add_observer(*this);
48 
49  // Cache is state since we have just been initialized
50  chapman_cache_stale.resize(spec_bound.number_spectrometer());
51  chapman_cache_stale = true;
52 
53  chapman_boa.resize(spec_bound.number_spectrometer());
54 }
55 
56 void ChapmanBoaRT::compute_chapman_factors(const int spec_idx) const {
57 
58  if(chapman_cache_stale(spec_idx)) {
59  // Constants needed by ChapmanBoa
61  double rfindex_param = 0.000288;
62 
63  // Can not use OCO refracrive index if CO2 and H2O are not
64  // present in the state structure
65  bool can_use_oco_refr = atm->absorber_ptr()->gas_index("CO2") != -1 and
66  atm->absorber_ptr()->gas_index("H2O") != -1;
67 
68  // Atmospheric values
69  Array<AutoDerivative<double>, 1> height_grid( atm->altitude(spec_idx).convert(units::km).value.to_array() );
70  Array<AutoDerivative<double>, 1> press_grid( atm->pressure_ptr()->pressure_grid().convert(units::Pa).value.to_array() );
71  Array<AutoDerivative<double>, 1> temp_grid(press_grid.rows());
72  Array<AutoDerivative<double>, 1> co2_vmr(press_grid.rows());
73  Array<AutoDerivative<double>, 1> h2o_vmr(press_grid.rows());
74  for(int i = 0; i < temp_grid.rows(); ++i) {
75  temp_grid(i) =
76  atm->temperature_ptr()->temperature(AutoDerivativeWithUnit<double>(press_grid(i), units::Pa)).convert(units::K).value;
77 
78  if(can_use_oco_refr) {
79  co2_vmr(i) = atm->absorber_ptr()->absorber_vmr("CO2")->
80  volume_mixing_ratio(press_grid(i));
81  h2o_vmr(i) = atm->absorber_ptr()->absorber_vmr("H2O")->
82  volume_mixing_ratio(press_grid(i));
83  }
84  }
85 
86  // Calculate reference wavelengths, if we can..
87  double ref_wavelength;
88  if(spec_bound.number_spectrometer() > 0)
89  ref_wavelength = spec_bound.center(spec_idx, units::micron).value;
90 
91  Logger::debug() << "Generating Chapman Factors\n";
93  Logger::debug() << "Band " << (spec_idx+1) << " using ";
94  if(can_use_oco_refr && spec_bound.number_spectrometer() > 0 &&
96  Logger::debug() << "OCO";
97  refr_index.reset(new OcoRefractiveIndex(ref_wavelength, press_grid, temp_grid, co2_vmr, h2o_vmr));
98  } else {
99  Logger::debug() << "simple";
100  refr_index.reset(new SimpleRefractiveIndex(rfindex_param, press_grid, temp_grid));
101  }
102  Logger::debug() << " refractive index class.\n";
103 
104  chapman_boa[spec_idx].reset( new ChapmanBOA(rearth, sza(spec_idx), height_grid, refr_index) );
105 
106  // Do not need recomputing until updates from Atmosphere class
107  chapman_cache_stale(spec_idx) = false;
108  }
109 
110 }
111 
113  int Spec_index, bool Skip_jacobian) const
114 {
115  ArrayAd<double, 1> res;
116  if(Skip_jacobian)
117  res.reference(ArrayAd<double, 1>(stokes(Spec_domain, Spec_index)
118  (Range::all(), 0)));
119  else
120  res.reference(stokes_and_jacobian(Spec_domain, Spec_index)
121  (Range::all(), 0));
122  return Spectrum(Spec_domain, SpectralRange(res, units::inv_sr));
123 }
124 
125 blitz::Array<double, 2> ChapmanBoaRT::stokes(const SpectralDomain& Spec_domain, int Spec_index) const
126 {
130 
131  // Compute chapman factors if needed
132  compute_chapman_factors(Spec_index);
133 
134  Array<double, 1> wn(Spec_domain.wavenumber());
135  Array<double, 2> trans(wn.extent(firstDim), number_stokes());
137 
138  for(int i = 0; i < wn.rows(); ++i) {
139  trans(i, 0) = value( chapman_boa[Spec_index]->transmittance(atm->optical_depth_wrt_state_vector(wn(i), Spec_index).to_array(), 0) );
140  if(disp) *disp += 1;
141  }
142 
143  return trans;
144 }
145 
146 ArrayAd<double, 2> ChapmanBoaRT::stokes_and_jacobian(const SpectralDomain& Spec_domain, int Spec_index) const
147 {
149 
150  // Compute chapman factors if needed
151  compute_chapman_factors(Spec_index);
152 
153  Array<double, 1> wn(Spec_domain.wavenumber());
154  ArrayAd<double, 2> trans_jac(wn.extent(firstDim), number_stokes(), 1);
156 
157  for(int i = 0; i < wn.extent(firstDim); ++i) {
158  AutoDerivative<double> trans_wn = chapman_boa[Spec_index]->transmittance(atm->optical_depth_wrt_state_vector(wn(i), Spec_index).to_array(), 0);
159  trans_jac.resize_number_variable(trans_wn.number_variable());
160  trans_jac(i, 0) = trans_wn;
161  if(disp) *disp += 1;
162  }
163 
164  return trans_jac;
165 }
166 
167 void ChapmanBoaRT::print(std::ostream& Os, bool Short_form) const
168 {
169  Os << "ChapmanBoaRT";
170  OstreamPad opad(Os, " ");
171  if(!Short_form) {
172  Os << "\nAtmosphere:\n";
173  opad << *atm << "\n";
174  opad.strict_sync();
175  }
176 }
static AccumulatedTimer timer
This is a AutoDerivative that also has units associated with it.
This is a filtering stream that adds a pad to the front of every line written out.
Definition: ostream_pad.h:32
boost::shared_ptr< RadiativeTransfer > chapman_boa_rt_create(const boost::shared_ptr< RtAtmosphere > &Atm, const blitz::Array< double, 1 > &Sza, const SpectralBound &Spec_bound)
const DoubleWithUnit wgs84_a(6378137.0000, units::m)
Equatorial radius.
For different instruments, it is more natural to either work with wavenumbers (e.g., GOSAT) or wavelength (e.g., OCO).
static LogHelper debug()
Definition: logger.h:108
const Unit Pa("Pa", N/(m *m))
Computes refractive index per level/layer using a simple approximation using pressure and temperature...
#define REGISTER_LUA_DERIVED_CLASS(X, Y)
Definition: register_lua.h:136
ChapmanBoaRT(const boost::shared_ptr< AtmosphereOco > &Atm, const blitz::Array< double, 1 > &Sza)
virtual blitz::Array< double, 2 > stokes(const SpectralDomain &Spec_domain, int Spec_index) const
Calculate stokes vector for the given set of wavenumbers/wavelengths.
virtual int number_stokes() const
Number of stokes parameters we will return in stokes and stokes_and_jacobian.
const Unit micron("micron", 1e-6 *m)
Apply value function to a blitz array.
This runs a Radiative Transfer code to determine the reflectance for a given set of wavelengths...
FunctionTimer function_timer(bool Auto_log=false) const
Function timer.
This is a full spectrum, which contains a SpectralRange and SpectralDomain.
Definition: spectrum.h:18
This gives the upper and lower bounds of the SpectralWindow.
const Unit K("K", 1.0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)
virtual ArrayAd< double, 2 > stokes_and_jacobian(const SpectralDomain &Spec_domain, int Spec_index) const
Calculate stokes vector for the given set of wavenumbers/wavelengths.
virtual Spectrum reflectance(const SpectralDomain &Spec_domain, int Spec_index, bool Skip_jacobian=false) const
Calculate reflectance for the given set of wavenumbers/wavelengths.
boost::shared_ptr< boost::progress_display > progress_display(const blitz::Array< double, 1 > &wn) const
Helper routine, creates a progress meter.
int number_variable() const
Number of variables in gradient.
const Unit inv_sr("sr^-1", pow(sr, -1))
DoubleWithUnit convert(const Unit &R) const
Convert to the given units.
We have a number of different spectrums that appear in different parts of the code.
virtual void print(std::ostream &Os, bool Short_form=false) const
Print to stream.
void reference(const ArrayAd< T, D > &V)
Definition: array_ad.h:372
Computes refractive index per level/layer using a method that takes into account knowledge of OCO spe...
blitz::Array< double, 1 > wavenumber(const Unit &Units=units::inv_cm) const
Return data as wavenumbers.
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
#define REGISTER_LUA_END()
Definition: register_lua.h:134
def(luabind::constructor< int >()) .def("rows"
int number_spectrometer() const
Number of spectrometers.
Helper class for AccumulatedTimer.
static bool wavelength_in_bounds(double wavelength)
Determines if the passed wavelength value in microns is within the bounds of those accepted by the cl...
const Unit km("km", 1e3 *m)
double value(const FullPhysics::AutoDerivative< double > &Ad)
This class computes Bottom of the Atmosphere radiance.
Definition: chapman_boa.h:76
DoubleWithUnit center(int Spec_index, const Unit &U) const
Center between lower_bound and upper_bound.

Copyright © 2017, California Institute of Technology.
ALL RIGHTS RESERVED.
U.S. Government Sponsorship acknowledged.
Generated Fri Aug 24 2018 15:44:08