ReFRACtor
spectral_window_range.cc
Go to the documentation of this file.
2 #include "dispersion.h"
3 #include "fp_exception.h"
4 #include <boost/foreach.hpp>
5 #include <boost/lexical_cast.hpp>
6 
7 using namespace FullPhysics;
8 using namespace blitz;
9 
10 #ifdef HAVE_LUA
11 #include "register_lua.h"
12 typedef void (SpectralWindowRange::*cfunc)(const std::vector<boost::shared_ptr<Dispersion> >&);
13 typedef const ArrayWithUnit<double, 3>& (SpectralWindowRange::*a1)(void) const;
15 .def(luabind::constructor<const ArrayWithUnit<double, 3>&>())
16 .def(luabind::constructor<const ArrayWithUnit<double, 3>&, const Array<bool, 2>&>())
17 .def(luabind::constructor<const ArrayWithUnit<double, 3>&, const Array<double, 2>&>())
18 .def("range_array", ((a1) &SpectralWindowRange::range_array))
19 .def("dispersion", ((cfunc) &SpectralWindowRange::dispersion))
21 #endif
22 
23 //-----------------------------------------------------------------------
35 //-----------------------------------------------------------------------
36 
38 (const ArrayWithUnit<double, 3>& Microwindow_ranges)
39  : range_(Microwindow_ranges)
40 {
41  if(range_.value.depth() != 2) {
42  Exception e;
43  e << "Microwindow_ranges needs to have a depth of 2\n"
44  << "(for lower and upper bound). Found depth of " << range_.value.depth();
45  throw e;
46  }
47 
48 }
49 
50 //-----------------------------------------------------------------------
56 //-----------------------------------------------------------------------
57 
58 template<class T>
60  const Array<T, 2>& Bad_sample_mask)
61  : range_(Microwindow_ranges)
62 {
63  if(range_.value.depth() != 2) {
64  Exception e;
65  e << "Microwindow_ranges needs to have a depth of 2\n"
66  << "(for lower and upper bound). Found depth of " << range_.value.depth();
67  throw e;
68  }
69 
70  // Initialize boolean object from any type that can be evaluated for truth
71  bad_sample_mask_.resize(Bad_sample_mask.shape());
72 
73  for(int i = 0; i < bad_sample_mask_.rows(); ++i) {
74  bad_sample_mask_(i, Range::all()) = where(Bad_sample_mask(i, Range::all()), true, false);
75  }
76 }
77 
78 // See base class for a description.
80 {
81  Range ra = Range::all();
82  std::vector<DoubleWithUnit> lbound, ubound;
83  for(int i = 0; i < number_spectrometer(); ++i) {
84  DoubleWithUnit lv(min(range_.value(i, ra, ra)), range_.units);
85  DoubleWithUnit uv(max(range_.value(i, ra, ra)), range_.units);
86  if(range_.units.is_commensurate(units::sample_index) && disp_.size() > 0) {
87  SpectralDomain pgrid = disp_[i]->pixel_grid();
88  // Special handling for SampleIndex, so it isn't out of range
90  if(lv.value < 1)
91  lv.value = 1;
92  if(lv.value > pgrid.data().rows())
93  lv.value = pgrid.data().rows();
94  if(uv.value < 1)
95  uv.value = 1;
96  if(uv.value > pgrid.data().rows())
97  uv.value = pgrid.data().rows();
98  }
99  lv = lv.convert_wave(pgrid.units(), pgrid);
100  uv = uv.convert_wave(pgrid.units(), pgrid);
101  // Might switch the direction of upper and lower
102  if(lv.value > uv.value)
103  std::swap(lv.value, uv.value);
104  }
105  lbound.push_back(lv);
106  ubound.push_back(uv);
107  }
108  return SpectralBound(lbound, ubound);
109 }
110 
111 // See base class for a description.
112 
113 std::vector<int>
114 SpectralWindowRange::grid_indexes(const SpectralDomain& Grid, int Spec_index) const
115 {
116  range_check(Spec_index, 0, number_spectrometer());
117  std::vector<int> res;
118  Array<double, 1> g;
119 
121  g.resize(Grid.sample_index().shape());
122  g = blitz::cast<double>(Grid.sample_index());
123  } else if(range_.units.is_commensurate(units::inv_cm))
124  g.reference(Grid.wavenumber(range_.units));
125  else
126  g.reference(Grid.wavelength(range_.units));
127 
128  for(int i = 0; i < g.rows(); ++i) {
129  bool ok = false;
130 
131  // Check if sample is bad first, if it is not then check if
132  // it falls within the spectral ranges
133  if(bad_sample_mask_.rows() == 0 || !bad_sample_mask_(Spec_index, i)) {
134  for(int j = 0; j < range_.value.cols(); ++j) {
135  if(g(i) >= range_.value(Spec_index, j, 0) &&
136  g(i) < range_.value(Spec_index, j, 1)) {
137  ok = true;
138  }
139  }
140  }
141 
142  if(ok) {
143  res.push_back(i);
144  }
145  }
146 
147  return res;
148 }
149 
150 //-----------------------------------------------------------------------
152 //-----------------------------------------------------------------------
153 
154 void SpectralWindowRange::print(std::ostream& Os) const
155 {
156  Os << "SpectralWindowRange:\n"
157  << " Units: " << range_.units;
158 
159  for(int i = 0; i < range_.value.rows(); ++i) {
160  Os << " Spec[" << i << "]:\n";
161 
162  for(int j = 0; j < range_.value.cols(); ++j)
163  Os << " Microwindow[" << j << "]: ("
164  << range_.value(i, j, 0) << ", " << range_.value(i, j, 1) << ")\n";
165  }
166 }
167 
168 
169 template SpectralWindowRange::SpectralWindowRange(const ArrayWithUnit<double, 3>&, const Array<double, 2>&);
#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.
void print(std::ostream &Os) const
Print to a stream.
SpectralWindowRange(const ArrayWithUnit< double, 3 > &Microwindow_ranges)
Construct a new window from the supplied information.
virtual SpectralBound spectral_bound() const
Bounds of spectral window.
const ArrayWithUnit< double, 3 > & range_array() const
For different instruments, it is more natural to either work with wavenumbers (e.g., GOSAT) or wavelength (e.g., OCO).
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
blitz::Array< double, 1 > wavelength(const Unit &Units=units::micron) const
Return data as wavelengths You can optionally supply the units to use.
blitz::Array< T, D > value
const Unit sample_index("sample_index", 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
Apply value function to a blitz array.
virtual std::vector< int > grid_indexes(const SpectralDomain &Grid, int Spec_index) const
Given a list of wavenumbers, this returns the indices that fall within the window.
const Unit inv_cm("cm^-1", pow(cm, -1))
This is an implementation of a SpectralWindow that covers a fixed window.
This gives the upper and lower bounds of the SpectralWindow.
We frequently have a double with units associated with it.
This class represents a the spectral window.
virtual int number_spectrometer() const
Number of spectrometers.
const blitz::Array< int, 1 > & sample_index() const
Return sample index.
const Unit g("g", 1e-3 *kg)
blitz::Array< double, 1 > wavenumber(const Unit &Units=units::inv_cm) const
Return data as wavenumbers.
const Unit units() const
Units that go with data()
bool is_commensurate(const Unit &Units) const
Test if this set of units is commensurate with another set.
Definition: unit.h:68
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.
const std::vector< boost::shared_ptr< Dispersion > > & dispersion() const
The Dispersion is optional.

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