ReFRACtor
gas_vmr_apriori.cc
Go to the documentation of this file.
1 #include "gas_vmr_apriori.h"
2 #include "linear_interpolate.h"
4 
5 using namespace FullPhysics;
6 using namespace blitz;
7 
8 #ifdef HAVE_LUA
9 #include "register_lua.h"
10 
12 .def(luabind::constructor<const boost::shared_ptr<Meteorology>&,
15  const HdfFile&,
16  const std::string&,
17  const std::string&>())
18 .def(luabind::constructor<const boost::shared_ptr<Meteorology>&,
21  const HdfFile&,
22  const std::string&,
23  const std::string&,
24  const int>())
25 .def(luabind::constructor<const boost::shared_ptr<Meteorology>&,
28  const HdfFile&,
29  const std::string&,
30  const std::string&>())
31 .def(luabind::constructor<const boost::shared_ptr<Meteorology>&,
34  const HdfFile&,
35  const std::string&,
36  const std::string&,
37  const int>())
38 // Expose version which requires a Pressure argument
39 .def("apriori_vmr", (const blitz::Array<double, 1>(GasVmrApriori::*)(const Pressure&) const) &GasVmrApriori::apriori_vmr)
40 .def("tropopause_pressure", &GasVmrApriori::tropopause_pressure)
42 #endif
43 
44 // temp_avg_window is the number of points before and after the current temperature value
45 // to average among
46 
48  const boost::shared_ptr<Level1b>& L1b_file,
49  const boost::shared_ptr<Altitude>& altitude,
50  const HdfFile& reference_file,
51  const std::string& hdf_group,
52  const std::string& gas_name,
53  const int temp_avg_window)
54 {
55  const blitz::Array<double, 1> met_press = Met_file->pressure_levels();
56  const blitz::Array<double, 1> met_temp = Met_file->temperature();
57 
58  // Get observation values from L1B file
59  const double obs_latitude = L1b_file->latitude(0).value;
60  const Time obs_time = L1b_file->time(0);
61 
62  initialize(met_press, met_temp, obs_latitude, obs_time, altitude, reference_file, hdf_group, gas_name, temp_avg_window);
63 }
64 
65 GasVmrApriori::GasVmrApriori(const blitz::Array<double, 1>& pressure_levels,
66  const blitz::Array<double, 1>& temperature_levels,
67  const double& obs_latitude,
68  const Time& obs_time,
69  const boost::shared_ptr<Altitude>& altitude,
70  const HdfFile& reference_file,
71  const std::string& hdf_group,
72  const std::string& gas_name,
73  const int temp_avg_window)
74 {
75  initialize(pressure_levels, temperature_levels, obs_latitude, obs_time, altitude, reference_file, hdf_group, gas_name, temp_avg_window);
76 }
77 
78 void GasVmrApriori::initialize(const blitz::Array<double, 1>& pressure_levels,
79  const blitz::Array<double, 1>& temperature_levels,
80  const double& obs_latitude,
81  const Time& obs_time,
82  const boost::shared_ptr<Altitude>& altitude,
83  const HdfFile& reference_file,
84  const std::string& hdf_group,
85  const std::string& gas_name_in,
86  const int temp_avg_window)
87 {
88  // Save gas name as instance attribute
89  gas_name = gas_name_in;
90 
91  // Read pressure and temperature grids
92  model_press.resize(pressure_levels.rows());
93  model_press = pressure_levels;
94 
95  // Smooth the model temperature out with a simple moving average to reduce problems finding
96  // tropopause altitude due to kinks in the data
97  blitz::Array<double, 1> smoothed_model_temp(temperature_levels.rows());
98  for (int out_idx = 0; out_idx < temperature_levels.rows(); out_idx++) {
99  double sum = 0;
100  int count = 0;
101  int avg_beg = std::max(out_idx - temp_avg_window, 0);
102  int avg_end = std::min(out_idx + temp_avg_window, temperature_levels.rows() - 1);
103  for(int avg_idx = avg_beg; avg_idx <= avg_end; avg_idx++) {
104  sum += temperature_levels(avg_idx);
105  count++;
106  }
107  smoothed_model_temp(out_idx) = sum/count;
108  }
109 
110  model_alt.resize(model_press.rows());
111  for(int lev_idx = 0; lev_idx < model_press.rows(); lev_idx++) {
112  model_alt(lev_idx) = altitude->altitude(AutoDerivativeWithUnit<double>(model_press(lev_idx), units::Pa)).convert(units::km).value.value();
113  }
114 
115  // Get reference data from HDF file
116  Array<double, 1> ref_altitude = reference_file.read_field<double, 1>(hdf_group + "/altitude_grid");
117  double ref_latitude = reference_file.read_field<double>(hdf_group + "/latitude");
118  Time ref_time = Time::parse_time(reference_file.read_field<std::string>(hdf_group + "/time_string"));
119  double ref_tropo_alt = reference_file.read_field<double>(hdf_group + "/tropopause_altitude");
120  ref_vmr.reference( reference_file.read_field<double, 1>(hdf_group + "/Gas/" + gas_name_in + "/vmr") );
121 
122  // Allow values to be in either increasing altitude or increasing pressure order
123  bool in_increasing_alt = reference_file.read_field<int>(hdf_group + "/increasing_altitude_order");
124  if (!in_increasing_alt) {
125  // Reverse on a copy to make sure order is correct behind the scenes
126  // to satisfy LinearInterpolate
127  ref_altitude = ref_altitude.copy().reverse(firstDim);
128  ref_vmr = ref_vmr.copy().reverse(firstDim);
129  }
130 
131  ref_apriori.reset(new ReferenceVmrApriori(model_press.reverse(firstDim), model_alt.reverse(firstDim), smoothed_model_temp.reverse(firstDim), ref_altitude, ref_latitude, ref_time, ref_tropo_alt, obs_latitude, obs_time));
132 }
133 
134 const blitz::Array<double, 1> GasVmrApriori::apriori_vmr() const
135 {
136  Array<double, 1> ap_vmr = ref_apriori->apriori_vmr(ref_vmr, gas_name);
137  ap_vmr.reverseSelf(firstDim);
138  return ap_vmr;
139 }
140 
141 const blitz::Array<double, 1> GasVmrApriori::apriori_vmr(const Pressure& pressure) const
142 {
143  // Make a copy to avoid issues with memory access into the reversed view
144  Array<double, 1> model_ap_vmr(model_press.shape());
145  model_ap_vmr = apriori_vmr();
146 
147  Array<double, 1> press_levels(pressure.pressure_grid().convert(units::Pa).value.value());
148 
149  LinearInterpolate<double, double> mod_vmr_interp(model_press.begin(), model_press.end(), model_ap_vmr.begin());
150 
151  Array<double, 1> interp_vmr(press_levels.shape());
152  for(int lev_idx = 0; lev_idx < interp_vmr.rows(); lev_idx++) {
153  interp_vmr(lev_idx) = mod_vmr_interp(press_levels(lev_idx));
154  }
155 
156  return interp_vmr;
157 }
158 
160 {
161  // Make a copy and reverse to satisfy array increasing ordering and memory contiguous requirements of linear interpolator
162  blitz::Array<double, 1> rev_alt(model_alt.shape());
163  rev_alt = model_alt.copy().reverse(firstDim);
164  blitz::Array<double, 1> rev_press(rev_alt.shape());
165  rev_press = model_press.copy().reverse(firstDim);
166 
167  LinearInterpolate<double, double> alt_press_interp(rev_alt.begin(), rev_alt.end(), rev_press.begin());
168  return alt_press_interp(tropopause_altitude().convert(units::km).value);
169 }
ArrayAdWithUnit< T, D > convert(const Unit &R) const
Convert to the given units.
static Time parse_time(const std::string &Time_string)
Parse CCSDS format time (e.g., "1996-07-03T04:13:57.987654Z")
Definition: fp_time.cc:64
This is a AutoDerivative that also has units associated with it.
blitz::Array< T, D > read_field(const std::string &Dataname) const
Read a given field.
Definition: hdf_file.h:564
Creates a VMR profile for a gas using a set of dated reference VMRs with a known latitude.
const Unit Pa("Pa", N/(m *m))
const double tropopause_pressure() const
This class reads and writes a HDF5 file.
Definition: hdf_file.h:39
#define REGISTER_LUA_CLASS(X)
Definition: register_lua.h:116
Apply value function to a blitz array.
Adapts the ReferenceVmrApriori class into a form that is easier to work with in the context of how th...
This class maintains the pressure portion of the state.
Definition: pressure.h:32
This is a simple time class.
Definition: fp_time.h:29
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
virtual ArrayAdWithUnit< double, 1 > pressure_grid() const =0
This returns the pressure grid to use for layer retrieval, along with the gradient of each of the pre...
const Unit km("km", 1e3 *m)
GasVmrApriori(const boost::shared_ptr< Meteorology > &met_file, const boost::shared_ptr< Level1b > &l1b_file, const boost::shared_ptr< Altitude > &alt, const HdfFile &hdf_static_input, const std::string &hdf_group, const std::string &gas_name, const int temp_avg_window=11)
double value(const FullPhysics::AutoDerivative< double > &Ad)
double tropopause_altitude(const boost::shared_ptr< GasVmrApriori > &ga)
const blitz::Array< double, 1 > apriori_vmr() const

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