ReFRACtor
radiance_scaling_linear_fit.cc
Go to the documentation of this file.
2 #include "ostream_pad.h"
3 #include "linear_algebra.h"
4 
5 #include <fstream>
6 
7 using namespace FullPhysics;
8 using namespace blitz;
9 
10 #ifdef HAVE_LUA
11 #include "register_lua.h"
13 .def(luabind::constructor<const SpectralRange&,
14  const DoubleWithUnit&,
15  const std::string&>())
16 .def(luabind::constructor<const SpectralRange&,
17  const DoubleWithUnit&,
18  const std::string&,
19  const bool>())
21 #endif
22 
24 (const SpectralDomain& Pixel_grid,
25  const std::vector<int>& Pixel_list,
26  SpectralRange& Radiance) const
27 {
28  ArrayAd<double, 1> grid_ad(Pixel_list.size(), Pixel_grid.data_ad().number_variable());
29  for (int i = 0; i < (int) Pixel_list.size(); i++) {
30  grid_ad(i) = Pixel_grid.data_ad()(Pixel_list[i]);
31  }
32  SpectralDomain grid_sd(grid_ad, Pixel_grid.units());
33 
34  // Convert measured radiances into same units as radiance to scale
35  // and only use those pixels being used for the retrieval
36  double conv_factor = FullPhysics::conversion(measured_radiance.units(), Radiance.units());
37  Array<double, 1> meas_conv_data(Pixel_list.size());
38  for(int i = 0; i < (int) Pixel_list.size(); i++)
39  meas_conv_data(i) = measured_radiance.data()(Pixel_list[i]) * conv_factor;
40  SpectralRange meas_conv(meas_conv_data, Radiance.units());
41 
42  // Formulate radiance scaling as a linear equation and solve
43  Array<double, 2> problem_mat;
44  if (do_offset)
45  problem_mat.resize(Pixel_list.size(), 3);
46  else
47  problem_mat.resize(Pixel_list.size(), 2);
48 
49  double band_ref_conv = band_ref.convert_wave(grid_sd.units()).value;
50  Array<double, 1> wrefd( grid_sd.data() - band_ref_conv );
51 
52  Range all = Range::all();
53 
54  // Create problem matrix
55  // r0*x0 + r0*x1*wrefd + x2
56  // To solve for scaling coefficients (x0, x1)
57  // and possibly an offset x2
58  problem_mat(all, 0) = Radiance.data();
59  problem_mat(all, 1) = Radiance.data() * wrefd;
60  if (do_offset)
61  problem_mat(all,2) = 1.0;
62 
63  // Use a QR factorization based least square solver since
64  // our problem is overdetermined
65  Array<double, 1> scale_offset = solve_least_squares_qr(problem_mat, meas_conv.data());
66 
67  scaling_coeff(all) = scale_offset(Range(0,1));
68  if (do_offset)
69  offset = scale_offset(2);
70 
71  // Debugging output
72  if(false) {
73  std::ofstream debug_out(("radiance_scaling_linear_fit_debug_" + band_name + ".txt").c_str());
74  debug_out << "# scale_offset: " << std::endl << scale_offset << std::endl;
75  double conv_factor = FullPhysics::conversion(measured_radiance.units(), Radiance.units());
76  debug_out << "# inst_corr conv_factor = " << conv_factor << std::endl
77  << "# measured_radiance: " << measured_radiance.units().name() << std::endl
78  << measured_radiance.data() << std::endl
79  << "# ---" << std::endl
80  << "# measured_radiance converted = " << meas_conv.units().name() << std::endl
81  << meas_conv.data() << std::endl
82  << "# ---" << std::endl
83  << "# Radiance: " << Radiance.units().name() << std::endl
84  << Radiance.data() << std::endl
85  << "# ---" << std::endl
86  << "# wrefd: " << std::endl
87  << wrefd << std::endl;
88  debug_out.close();
89  }
90 
91  apply_scaling(grid_sd, Radiance);
92 }
93 
95 {
97  (new RadianceScalingLinearFit(measured_radiance, band_ref, band_name, do_offset));
98 }
99 
100 void RadianceScalingLinearFit::print(std::ostream& Os) const
101 {
102  Os << "RadianceScalingLinearFit:" << std::endl;
103  OstreamPad opad(Os, " ");
105  opad << "Use offset: " << (do_offset ? "True" : "False") << std::endl;
106  opad.strict_sync();
107 }
virtual void print(std::ostream &Os) const
virtual void print(std::ostream &Os) const
virtual void apply_correction(const SpectralDomain &Pixel_grid, const std::vector< int > &Pixel_list, SpectralRange &Radiance) const
Apply correction to radiance values, in place.
This is a filtering stream that adds a pad to the front of every line written out.
Definition: ostream_pad.h:32
For different instruments, it is more natural to either work with wavenumbers (e.g., GOSAT) or wavelength (e.g., OCO).
const ArrayAd< double, 1 > & data_ad() const
Underlying data, possibly with a Jacobian.
virtual boost::shared_ptr< InstrumentCorrection > clone() const
Clone an InstrumentCorrection object.
double conversion(const Unit &Dunit_from, const Unit &Dunit_to)
Return conversion factor to go from one unit to another.
Definition: unit.cc:180
#define REGISTER_LUA_DERIVED_CLASS(X, Y)
Definition: register_lua.h:136
Apply value function to a blitz array.
blitz::Array< double, 1 > solve_least_squares_qr(const blitz::Array< double, 2 > &A, const blitz::Array< double, 1 > &B)
This finds the least squares solution to the overdetermined system A x = b where the matrix A has mor...
const Unit & units() const
Units of data.
Implements a fitted radiance scaling correction where the correction is determined by a linear fit of...
We frequently have a double with units associated with it.
int number_variable() const
Definition: array_ad.h:376
We have a number of different spectrums that appear in different parts of the code.
const Unit units() const
Units that go with data()
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
const std::string & name() const
Name of unit. May be an empty string if a name wasn&#39;t assigned.
Definition: unit.h:77
double value(const FullPhysics::AutoDerivative< double > &Ad)
const blitz::Array< double, 1 > & data() const
Underlying data.
This class models an Instrument correction.

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