ReFRACtor
level_1b.cc
Go to the documentation of this file.
1 #include "level_1b.h"
2 #include "fe_disable_exception.h"
3 
4 using namespace FullPhysics;
5 using namespace blitz;
6 
7 #ifdef HAVE_LUA
8 
9 // Convenience function to give us solar zenith, relative azimuth,
10 // stokes_coefficents, and sounding azimuth in different forms for Lua
11 
12 blitz::Array<double, 1> level_1b_sza(const Level1b& Lev1)
13 {
14  blitz::Array<double, 1> res(Lev1.number_spectrometer());
15  for(int i = 0; i < res.rows(); ++i)
16  res(i) = Lev1.solar_zenith(i).convert(units::deg).value;
17  return res;
18 }
19 
20 double level_1b_sza_i(const Level1b& Lev1, int Spec_index)
21 {
22  return Lev1.solar_zenith(Spec_index).convert(units::deg).value;
23 }
24 
25 blitz::Array<double, 1> level_1b_zen(const Level1b& Lev1)
26 {
27  blitz::Array<double, 1> res(Lev1.number_spectrometer());
28  for(int i = 0; i < res.rows(); ++i)
29  res(i) = Lev1.sounding_zenith(i).convert(units::deg).value;
30  return res;
31 }
32 
33 double level_1b_zen_i(const Level1b& Lev1, int Spec_index)
34 {
35  return Lev1.sounding_zenith(Spec_index).convert(units::deg).value;
36 }
37 
38 blitz::Array<double, 1> level_1b_azm(const Level1b& Lev1)
39 {
40  blitz::Array<double, 1> res(Lev1.number_spectrometer());
41  for(int i = 0; i < res.rows(); ++i) {
42  res(i) = Lev1.relative_azimuth(i).convert(units::deg).value;
43  }
44  return res;
45 }
46 
47 double level_1b_azm_i(const Level1b& Lev1, int Spec_index)
48 {
49  return Lev1.relative_azimuth(Spec_index).convert(units::deg).value;
50 }
51 
52 blitz::Array<double, 2> level_1b_stokes(const Level1b& Lev1)
53 {
54  blitz::Array<double, 2> res(Lev1.number_spectrometer(), 4);
55  for(int i = 0; i < res.rows(); ++i)
56  res(i, blitz::Range::all()) = Lev1.stokes_coefficient(i);
57  return res;
58 }
59 
60 blitz::Array<double, 1> level_1b_radiance(const Level1b& Lev1, int Spec_index)
61 {
62  return Lev1.radiance(Spec_index).data();
63 }
64 
65 blitz::Array<double, 1> level_1b_uncertainty(const Level1b& Lev1, int Spec_index)
66 {
67  return Lev1.radiance(Spec_index).uncertainty();
68 }
69 
70 ArrayWithUnit<double, 1> level_1b_uncertainty_with_unit(const Level1b& Lev1, int Spec_index)
71 {
72  return ArrayWithUnit<double, 1>(Lev1.radiance(Spec_index).uncertainty(), Lev1.radiance(Spec_index).units());
73 }
74 
75 ArrayWithUnit<double, 1> level_1b_radiance_with_unit(const Level1b& Lev1, int Spec_index)
76 {
77  return ArrayWithUnit<double, 1>(Lev1.radiance(Spec_index).data(), Lev1.radiance(Spec_index).units());
78 }
79 
80 SpectralRange level_1b_radiance_spectral_range(const Level1b& Lev1, int Spec_index)
81 {
82  return Lev1.radiance(Spec_index);
83 }
84 
85 double level_1b_relative_velocity(const Level1b& Lev1, int i)
86 {
87  return Lev1.relative_velocity(i).value;
88 }
89 
90 int level_1b_year(const Level1b& Lev1, int i)
91 {
92  boost::posix_time::ptime t = Lev1.time(i);
93  // +1900 since value is years since 1900
94  return 1900 + to_tm(t).tm_year;
95 }
96 
97 int level_1b_month(const Level1b& Lev1, int i)
98 {
99  boost::posix_time::ptime t = Lev1.time(i);
100  // +1 because tm_mon goes from 0 to 11. We want 1 to 12.
101  return to_tm(t).tm_mon + 1;
102 }
103 
104 int level_1b_day(const Level1b& Lev1, int i)
105 {
106  boost::posix_time::ptime t = Lev1.time(i);
107  return to_tm(t).tm_mday;
108 }
109 
110 int level_1b_hour(const Level1b& Lev1, int i)
111 {
112  boost::posix_time::ptime t = Lev1.time(i);
113  return to_tm(t).tm_hour;
114 }
115 
116 int level_1b_minute(const Level1b& Lev1, int i)
117 {
118  boost::posix_time::ptime t = Lev1.time(i);
119  return to_tm(t).tm_min;
120 }
121 
122 int level_1b_second(const Level1b& Lev1, int i)
123 {
124  boost::posix_time::ptime t = Lev1.time(i);
125  return to_tm(t).tm_sec;
126 }
127 
128 int level_1b_dayofyear(const Level1b& Lev1, int i)
129 {
130  boost::posix_time::ptime t = Lev1.time(i);
131  return to_tm(t).tm_yday;
132 }
133 
134 DoubleWithUnit l1b_signal_no_indexes(const boost::shared_ptr<Level1b>& l1b, int Spec_index)
135 {
136  return l1b->signal(Spec_index, std::vector<int>());
137 }
138 
139 #include "register_lua.h"
141 .def("number_spectrometer", &Level1b::number_spectrometer)
142 .def("latitude", &Level1b::latitude)
143 .def("longitude", &Level1b::longitude)
144 .def("altitude", &Level1b::altitude)
145 .def("sza", &level_1b_sza)
146 .def("sza", &level_1b_sza_i)
147 .def("sza_with_unit", &Level1b::solar_zenith)
148 .def("azm", &level_1b_azm)
149 .def("azm", &level_1b_azm_i)
150 .def("azm_with_unit", &Level1b::relative_azimuth)
151 .def("zen", &level_1b_zen)
152 .def("zen", &level_1b_zen_i)
153 .def("zen_with_unit", &Level1b::sounding_zenith)
154 .def("stokes_coef", &level_1b_stokes)
155 .def("year", &level_1b_year)
156 .def("month", &level_1b_month)
157 .def("day", &level_1b_day)
158 .def("hour", &level_1b_hour)
159 .def("minute", &level_1b_minute)
160 .def("second", &level_1b_second)
161 .def("dayofyear", &level_1b_dayofyear)
162 .def("radiance", &level_1b_radiance)
163 .def("uncertainty", &level_1b_uncertainty)
164 .def("uncertainty_with_unit", &level_1b_uncertainty_with_unit)
165 .def("radiance_with_unit", &level_1b_radiance_with_unit)
166 .def("radiance_spectral_range", &level_1b_radiance_spectral_range)
167 .def("signal", &Level1b::signal)
168 .def("signal", &l1b_signal_no_indexes)
169 .def("relative_velocity", &level_1b_relative_velocity)
170 .def("time", &Level1b::time)
172 
173 // typedef to distinguish between copying value or moving value (C++11) push_back prototoypes
174 typedef void(std::vector<boost::shared_ptr<Level1b> >::*pbt1)(
175  const std::vector<boost::shared_ptr<Level1b> >::value_type&);
176 
177 REGISTER_LUA_CLASS_NAME(std::vector<boost::shared_ptr<Level1b> >,
178  VectorLevel1b)
179 .def(luabind::constructor<>())
180 .def("push_back", ((pbt1) &std::vector<boost::shared_ptr<Level1b> >::push_back))
182 
183 // Azimuth is modified because the convention used by the OCO L1B file is to
184 // take both solar and observation angles as viewed from an observer
185 // standing in the FOV. In this convention, the convention for glint
186 // would be a relative azimuth difference of 180 degrees, as the
187 // spacecraft and sun would be on opposite sides of the sky. However, the
188 // radiative transfer convention is that the azimuth angles must be the
189 // same for glint (it is "follow the photons" convention). However, we'd
190 // like the solar azimuth to not be changed, so as to continue to agree
191 // with zenith, so this change of the observation azimuth has the effect
192 // of putting everything in a "reverse follow-the-photons" convention,
193 // where we look from the satellite to the FOV, then from the FOV to the
194 // sun. Note that because of an old historical reason, however, both
195 // zenith angles remain > 0 and < 90, even in the RT convention.
196 
197 DoubleWithUnit Level1b::relative_azimuth(int Spec_index) const
198 {
199  Unit orig_unit = sounding_azimuth(Spec_index).units;
200  double res = (180 + sounding_azimuth(Spec_index).convert(units::deg).value) -
201  solar_azimuth(Spec_index).convert(units::deg).value;
202 
203  if (res > 360)
204  res -= 360;
205  else if(res < 0)
206  res += 360;
207 
208  return DoubleWithUnit(res, units::deg).convert(orig_unit);
209 }
210 
211 DoubleWithUnit Level1b::signal(int Spec_index, const std::vector<int>& Sample_indexes) const
212 {
213  // Basically a copy of what is in ErrorAnalysis::signal
214  FeDisableException disable_fp;
215  const int nrad = 10;
216  SpectralRange rad(radiance(Spec_index));
217 
218  if(rad.data().rows() ==0) {
219  return DoubleWithUnit(0, rad.units());
220  }
221 
222  // Copy either the whole data if no sample index list is used
223  // or only selected samples indexes listed in Sample_indexes
224  Array<double, 1> used_rad;
225  if (Sample_indexes.size() == 0) {
226  used_rad.resize(rad.data().rows());
227  used_rad = rad.data();
228  } else {
229  used_rad.resize(Sample_indexes.size());
230  for(int samp_idx = 0; samp_idx < (int) Sample_indexes.size(); samp_idx++) {
231  used_rad(samp_idx) = rad.data()(Sample_indexes[samp_idx]);
232  }
233  }
234  std::sort(used_rad.data(), used_rad.data() + used_rad.rows()); // Min to max value
235  used_rad.reverseSelf(firstDim); // Now max to min value
236  Range avg_range(0, std::min(nrad - 1, used_rad.rows() - 1));
237  return DoubleWithUnit(sum(used_rad(avg_range) / avg_range.length()), rad.units());
238 }
239 
240 #endif
virtual Time time(int Spec_index) const =0
Time of sounding.
Definition: doxygen.h:52
virtual DoubleWithUnit altitude(int i) const =0
Altitude.
virtual blitz::Array< double, 1 > stokes_coefficient(int i) const =0
Return stokes coefficients.
virtual SpectralRange radiance(int Spec_index) const =0
Radiance, for given spectral band.
STL namespace.
To detect things like divide by zero, we may turn on floating point exceptions.
This is used to read a Level 1B file.
Definition: level_1b.h:15
#define REGISTER_LUA_CLASS(X)
Definition: register_lua.h:116
Apply value function to a blitz array.
virtual DoubleWithUnit latitude(int i) const =0
Latitude.
#define REGISTER_LUA_CLASS_NAME(X, Y)
Definition: register_lua.h:129
const Unit & units() const
Units of data.
const blitz::Array< double, 1 > & uncertainty() const
Uncertainty.
virtual DoubleWithUnit relative_azimuth(int i) const
Realtive azimuth.
We frequently have a double with units associated with it.
virtual DoubleWithUnit longitude(int i) const =0
Longitude.
DoubleWithUnit convert(const Unit &R) const
Convert to the given units.
void(std::vector< std::string >::* pbt1)(const std::vector< std::string >::value_type &)
Definition: register_lua.cc:52
We have a number of different spectrums that appear in different parts of the code.
Libraries such as boost::units allow unit handling where we know the units at compile time...
Definition: unit.h:25
virtual DoubleWithUnit sounding_zenith(int i) const =0
Sounding zenith.
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"
virtual DoubleWithUnit signal(int Spec_index, const std::vector< int > &Sample_indexes=std::vector< int >()) const
Calculate an approximation to the size of the continuum signal where there is no significant atmosphe...
virtual DoubleWithUnit solar_zenith(int i) const =0
Solar zenith.
virtual DoubleWithUnit relative_velocity(int Spec_index) const =0
Relative velocity.
const Unit rad("rad", 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
const blitz::Array< double, 1 > & data() const
Underlying data.
const Unit deg("deg", pi/180.0 *rad)
virtual int number_spectrometer() const =0
Number of spectrometers.

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