ReFRACtor
spectrum_sampling_fixed_spacing.cc
Go to the documentation of this file.
2 #include <fstream>
3 using namespace FullPhysics;
4 using namespace blitz;
5 
6 #ifdef HAVE_LUA
7 #include "register_lua.h"
9 .def(luabind::constructor<const ArrayWithUnit<double, 1>&>())
11 #endif
12 
13 // See base class for description.
15 (int spec_index,
16  const SpectralDomain& Lowres_grid,
17  const DoubleWithUnit& Ils_half_width) const
18 {
19  range_check(spec_index, 0, spec_spacing.rows());
20 
21  // Units we input and want to output and the units we
22  // use for computing the grid
23  Unit u_orig = Lowres_grid.units();
24  Unit u_comp = spec_spacing.units;
25 
26  // Determines how we compute the gridding, use a shorter name
27  DoubleWithUnit sp = spec_spacing(spec_index);
28 
29  // Make sure low res grid and ils half width have commensurate units
30  if (!u_orig.is_commensurate(Ils_half_width.units)) {
31  std::stringstream err_msg;
32  err_msg << "Low res grid units:" << std::endl
33  << u_orig << std::endl
34  << "are not commensurate with ils half width units:" << std::endl
35  << Ils_half_width.units;
36  throw Exception(err_msg.str());
37  }
38 
39  // Convert to same units as spacing for the purpose of gridding
40  // Make sure data is sorted in ascending order.
41  std::vector<DoubleWithUnit> lres_conv;
42  BOOST_FOREACH(double v, Lowres_grid.data())
43  lres_conv.push_back(DoubleWithUnit(v, u_orig).convert_wave(u_comp));
44  std::sort(lres_conv.begin(), lres_conv.end());
45 
46  // Fill in points so that we cover +=Ils_half_width for each value listed in
47  // low resolution spectral domain. By convention, we have the points
48  // be an exact multiple of sp. This isn't strictly necessary, but it
49  // could be used to reduce interpolation between spectral points
50  // in forward model calculations.
51  //
52  // Because ILS half width and spectral spacing could be specified
53  // using different units, we need to do this conversion back and
54  // forth to make sure things are applied appropriately
55 
56  std::vector<double> hres;
57  if(lres_conv.size() > 0) {
58  // Pick the smaller point of +/- since due to conversion
59  // to the original units and units not being commensurate
60  // one or the other could be the larger value
61  DoubleWithUnit begval =
62  min( (lres_conv[0].convert_wave(u_orig) - Ils_half_width).
63  convert_wave(u_comp),
64  (lres_conv[0].convert_wave(u_orig) + Ils_half_width).
65  convert_wave(u_comp) );
66 
67  DoubleWithUnit fpoint = floor(begval / sp) * sp;
68  hres.push_back(fpoint.convert_wave(u_orig).value);
69 
70  // Value for for first iteration of loop
71  int smax = (int) round(fpoint.value / sp).value;
72 
73  BOOST_FOREACH(DoubleWithUnit v, lres_conv) {
74  DoubleWithUnit minusval = (v.convert_wave(u_orig) - Ils_half_width).
75  convert_wave(u_comp);
76  DoubleWithUnit plusval = (v.convert_wave(u_orig) + Ils_half_width).
77  convert_wave(u_comp);
78 
79  // Pick values appropriately accounting for ordering change
80  // due to conversion of units back and forth
81  DoubleWithUnit preval = min(minusval, plusval);
82  DoubleWithUnit postval = max(minusval, plusval);
83 
84  int fmin = (int) floor(preval / sp).value;
85  int fmax = (int) ceil(postval / sp).value;
86  for(int f = std::max(fmin, smax + 1); f < fmax; ++f) {
87  // Convert back to original units
88  DoubleWithUnit fval(f * sp.value, u_comp);
89  hres.push_back(fval.convert_wave(u_orig).value);
90 
91  // For next iteration
92  smax = (int) round(fval / sp).value;
93  }
94  }
95  }
96  // Make sure the computed grid points are
97  // in sorted order
98  std::sort(hres.begin(), hres.end());
99 
100  // Create result object
101  Array<double, 1> dv((int) hres.size());
102  std::copy(hres.begin(), hres.end(), dv.begin());
103  SpectralDomain fixed_grid = SpectralDomain(dv, u_orig);
104 
105  return fixed_grid;
106 }
#define range_check(V, Min, Max)
Range check.
Definition: fp_exception.h:140
DoubleWithUnit convert_wave(const Unit &R) const
We often need to handle conversion from wavenumber to/from wavelength.
This generates a spectrum sampling that covers all the high resolution points needed to create the sp...
For different instruments, it is more natural to either work with wavenumbers (e.g., GOSAT) or wavelength (e.g., OCO).
virtual SpectralDomain spectral_domain(int spec_index, const SpectralDomain &Lowres_grid, const DoubleWithUnit &Ils_half_width) const
Wavenumbers/Wavelengths to use for the given spectrometer.
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
#define REGISTER_LUA_DERIVED_CLASS(X, Y)
Definition: register_lua.h:136
Apply value function to a blitz array.
This determines the sampling of the spectrum that should be used for each of the spectrum indexes...
We frequently have a double with units associated with it.
Libraries such as boost::units allow unit handling where we know the units at compile time...
Definition: unit.h:25
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 blitz::Array< double, 1 > & data() const
Return data.

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