ReFRACtor
fluorescence_effect.cc
Go to the documentation of this file.
1 #include "fluorescence_effect.h"
3 #include "ostream_pad.h"
4 
5 #include <boost/progress.hpp>
6 using namespace FullPhysics;
7 using namespace blitz;
8 
9 #ifdef HAVE_LUA
10 #include "register_lua.h"
12 .def(luabind::constructor<const blitz::Array<double, 1>&,
13  const blitz::Array<bool, 1>&,
16  const DoubleWithUnit&,
17  const int,
18  const DoubleWithUnit&,
19  const Unit&>())
21 #endif
22 
24 (const blitz::Array<double, 1>& Coeff,
25  const blitz::Array<bool, 1>& Used_flag,
27  const boost::shared_ptr<StokesCoefficient>& Stokes_coef,
28  const DoubleWithUnit& Lza,
29  const int Spec_index,
30  const DoubleWithUnit& Reference,
31  const Unit& Retrieval_unit)
32 : SpectrumEffectImpBase(Coeff, Used_flag),
33  lza(Lza), reference(Reference), retrieval_unit(Retrieval_unit),
34  spec_index(Spec_index), stokes_coef(Stokes_coef)
35 {
36  // We need to use the AtmosphereOco specific interfaces
37  atm_oco = boost::dynamic_pointer_cast<AtmosphereOco>(Atm);
38 
39  // Use a map cache, because due to LSI and non-uniform sampling we can
40  // not count on all values being cached that we need in the right order
42 }
43 
45  const ForwardModelSpectralGrid& Forward_model_grid) const
46 {
47  AccumulatedTimer tm("FluorescenceEffect");
48  {
49  FunctionTimer ft = tm.function_timer();
50 
51  double lza_sec = 1.0 / cos(lza.convert(units::rad).value);
52  double reference_wn = reference.convert_wave(units::inv_cm).value;
53 
54  Logger::info() << "Adding fluorescence to band: " + boost::lexical_cast<std::string>(spec_index + 1) + "\n";
55 
56  // Radiance array of spectrum to add fluoresence to
57  ArrayAd<double, 1>& rt_solar_rad = Spec.spectral_range().data_ad();
58 
59  // Access fluoresence retireved values in the correct units
60  double conv_factor = FullPhysics::conversion(retrieval_unit, Spec.spectral_range().units());
61  AutoDerivative<double> fs_ref = coefficient()(0) * conv_factor;
62  AutoDerivative<double> slope = coefficient()(1);
63 
64  // Grid to calculate on and Spectrum class to save into for use in interpolation
65  // Must use same grid as used in RT and interpolated later (if needed) so that points
66  // match up correctly when doing final addition
67  Array<double, 1> spec_samp_wn =
68  Forward_model_grid.high_resolution_grid(spec_index).wavenumber();
69  ArrayAd<double, 1> fluor_effect_rt;
70 
71  // Calculate fluorescence contribution that matches what would have been calculated if done inside RT
72  for(int wn_idx = 0; wn_idx < spec_samp_wn.rows(); wn_idx++) {
73  AutoDerivative<double> o2_col_abs = atm_oco->column_optical_depth(spec_samp_wn(wn_idx), spec_index, "O2");
74 
75  AutoDerivative<double> f_surf = fs_ref * (1.0 + slope * (spec_samp_wn(wn_idx) - reference_wn));
76  if(wn_idx ==0) {
77  fluor_effect_rt.resize(spec_samp_wn.rows(),
78  std::max(f_surf.number_variable(), o2_col_abs.number_variable()));
79  }
80  fluor_effect_rt(wn_idx) = f_surf * exp(-1 * o2_col_abs * lza_sec);
81  }
82 
83  Spectrum f_contrib_spectrum(Forward_model_grid.high_resolution_grid(spec_index), SpectralRange(fluor_effect_rt, Spec.spectral_range().units()));
84 
85  // Interpolate to obtain contribution we should add to rt radiances which have been interpolated and solar
86  // doppler shifted
87  Spectrum fluor_effect_interpolated = Forward_model_grid.interpolate_spectrum(f_contrib_spectrum, spec_index);
88 
89  // Save interpolated fluoresence contribution for use in output products
90  f_contrib_ad.reference(fluor_effect_interpolated.spectral_range().data_ad());
91 
92  // Check that interpolated fluorescence and radiances agree in size
93  if (rt_solar_rad.rows() != f_contrib_ad.rows()) {
94  std::stringstream err_msg;
95  err_msg << "Interpolated fluorescence size: " << f_contrib_ad.rows()
96  << " does not match radiance size: " << rt_solar_rad.rows();
97  throw Exception(err_msg.str());
98  }
99 
100  // Add fluorescence contribution to radiances
101  if(rt_solar_rad.number_variable() == 0 && f_contrib_ad.number_variable() > 0) {
102  rt_solar_rad.resize_number_variable(f_contrib_ad.number_variable());
103  }
104 
105  for(int wn_idx = 0; wn_idx < rt_solar_rad.rows(); wn_idx++) {
106  rt_solar_rad(wn_idx) = rt_solar_rad(wn_idx) +
107  stokes_coef->stokes_coefficient()(spec_index, 0) * f_contrib_ad(wn_idx);
108  }
109  }
110  Logger::info() << tm << "\n";
111 }
112 
114 {
115  return boost::shared_ptr<SpectrumEffect>(new FluorescenceEffect(coeff.value(), used_flag,
116  atm_oco, stokes_coef, lza, spec_index,
117  reference, retrieval_unit));
118 }
119 
120 void FluorescenceEffect::print(std::ostream& Os) const
121 {
122  OstreamPad opad(Os, " ");
123  Os << "FluorescenceEffect" << std::endl
124  << " Coefficient: " << coefficient().value() << "\n"
125  << " Retrieval flag: " << used_flag_value() << "\n"
126  << " Zenith angle: " << lza << "\n"
127  << " Reference point: " << reference << "\n";
128  opad << *stokes_coef;
129  opad.strict_sync();
130 }
static LogHelper info()
Definition: logger.h:109
const SpectralDomain high_resolution_grid(int Spec_index) const
The high resolution grid, possibly nonuniform.
This is a filtering stream that adds a pad to the front of every line written out.
Definition: ostream_pad.h:32
virtual void apply_effect(Spectrum &Spec, const ForwardModelSpectralGrid &Forward_model_grid) const
Apply correction to spectrum in place.
As a design principle, we have each base class with the absolutely minimum interface needed for use f...
This is the Forward Model spectral grid.
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
double conversion(const Unit &Dunit_from, const Unit &Dunit_to)
Return conversion factor to go from one unit to another.
Definition: unit.cc:180
Spectrum interpolate_spectrum(const Spectrum &Spec_in, int Spec_index) const
Interpolate a spectrum to the high_resolution_interpolated_grid() sampling.
const SpectralRange & spectral_range() const
Spectral range (e.g, radiance values)
Definition: spectrum.h:39
#define REGISTER_LUA_DERIVED_CLASS(X, Y)
Definition: register_lua.h:136
Implements adding the effect of fluorescence to A-Band spectrum by using a retrievable across the ban...
Apply value function to a blitz array.
virtual void print(std::ostream &Os) const
This class models models any effects that need to be applied to high resolution spectra after the rad...
FluorescenceEffect(const blitz::Array< double, 1 > &Coeff, const blitz::Array< bool, 1 > &Used_flag, const boost::shared_ptr< RtAtmosphere > &Atm, const boost::shared_ptr< StokesCoefficient > &Stokes_coef, const DoubleWithUnit &Lza, const int Spec_index, const DoubleWithUnit &Reference, const Unit &Retrieval_unit)
const Unit inv_cm("cm^-1", pow(cm, -1))
void resize(const blitz::TinyVector< int, D > &Shape, int nvar)
Definition: array_ad.h:177
const Unit & units() const
Units of data.
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
virtual boost::shared_ptr< SpectrumEffect > clone() const
Clone a SpectrumEffect object.
int number_variable() const
Number of variables in gradient.
We frequently have a double with units associated with it.
We have a number of different spectrums that appear in different parts of the code.
const ArrayAd< double, 1 > & data_ad() const
Underlying data, possibly with a Jacobian.
This is a simple timer class that can be used to accumulate the time spent in multiple calls to a fun...
Libraries such as boost::units allow unit handling where we know the units at compile time...
Definition: unit.h:25
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
virtual boost::shared_ptr< ArrayAdCache< double, double, 1 > > & column_optical_depth_cache()
const T & value() const
Convert to type T.
#define REGISTER_LUA_END()
Definition: register_lua.h:134
Caches ArrayAd objects using a std::map.
This class maintains the atmosphere portion of the state, and uses this to set up the atmosphere and ...
Helper class for AccumulatedTimer.
const Unit rad("rad", 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)

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