9 void register_lua_AbscoHdf(lua_State *ls) { \
11 luabind::class_<AbscoHdf,Absco,boost::shared_ptr<GasAbsorption> >
13 .
def(luabind::constructor<const std::string&>())
14 .
def(luabind::constructor<const std::string&,double>())
16 const std::vector<double>&>())
30 load_file(Fname, Table_scale, Cache_nline);
41 const std::vector<double>& Table_scale,
44 load_file(Fname, Spectral_bound, Table_scale, Cache_nline);
57 load_file(Fname, sb, table_scale_, cache_nline);
71 std::vector<double> tscale;
72 tscale.push_back(Table_scale);
73 load_file(Fname, empty, tscale, Cache_nline);
85 const std::vector<double>& Table_scale,
89 std::vector<double> tcopy(Table_scale);
90 table_scale_.swap(tcopy);
91 if(sb.number_spectrometer() > 0 &&
92 (int) table_scale_.size() != sb.number_spectrometer()) {
94 e <<
"Table_scale size needs to match the number of spectrometers\n" 95 <<
" Table_scale size: " << table_scale_.size() <<
"\n" 96 <<
" Number spectrometer: " << sb.number_spectrometer();
99 if(sb.number_spectrometer() ==0 && (int) table_scale_.size() != 1) {
101 e <<
"Table_scale size needs to be exactly 1\n" 102 <<
" Table_scale size: " << table_scale_.size() <<
"\n";
105 cache_nline = Cache_nline;
106 cache_double_lbound = 0;
107 cache_double_ubound = 0;
108 cache_float_lbound = 0;
109 cache_float_ubound = 0;
112 read_cache_float.resize(0,0,0,0);
113 read_cache_double.resize(0,0,0,0);
115 hfile.reset(
new HdfFile(Fname));
118 if (hfile->has_object(
"Extent_Range")) {
119 extent_range.reference(hfile->read_field<
double, 2>(
"Extent_Range"));
120 extent_index.reference(hfile->read_field<
int, 2>(
"Extent_Index"));
124 pgrid.reference(hfile->read_field<
double, 1>(
"Pressure"));
125 tgrid.reference(hfile->read_field<
double, 2>(
"Temperature"));
126 wngrid.reference(hfile->read_field<
double, 1>(
"Wavenumber"));
127 wnfront = &wngrid(0);
131 std::string t = hfile->read_field<std::string>(
"Gas_Index");
132 field_name = std::string(
"Gas_") + t.c_str() +
"_Absorption";
135 H5::DataSet d = hfile->h5_file().openDataSet(field_name);
136 if(d.getDataType().getSize() == 4)
140 std::string bindex =
"";
142 bindex = hfile->read_field<std::string>(
"Broadener_Index");
143 bindex = std::string(bindex.c_str());
150 else if(bindex ==
"01")
158 e <<
"Right now we only support H2O as a broadener (HITRAN index \"01\"). " 159 <<
"File " << Fname <<
" has index of \"" << bindex <<
"\"";
164 bvmr.reference(hfile->read_field<
double, 1>(
"Broadener_" + bindex +
"_VMR"));
171 if (extent_range.rows() > 0) {
173 for (
int range_idx = 0; range_idx < extent_range.rows(); range_idx++) {
174 if (extent_range(range_idx, 0) <= Wn_in && Wn_in <= extent_range(range_idx, 1)) {
175 int beg_idx = extent_index(range_idx, 0);
176 int end_idx = extent_index(range_idx, 1);
178 double* beg_loc =
const_cast<double*
>(&wngrid(beg_idx));
179 double* end_loc =
const_cast<double*
>(&wngrid(end_idx));
180 return std::pair<double*, double*>(beg_loc, end_loc);
187 err <<
"The ABSCO file " << hfile->file_name()
188 <<
" does not have an extent that contains the wavenumber: " 189 << std::setprecision(8) << Wn_in;
192 double* wnback =
const_cast<double *
>(&wngrid(wngrid.rows() - 1));
194 if (Wn_in >= *wnfront && Wn_in <= *wnback) {
195 return std::pair<double*, double*>(wnfront, wnback);
198 err <<
"The ASBCO file " << hfile->file_name() <<
"\n" 199 <<
" does not have data for wavenumber: " << Wn_in;
207 if(sb.number_spectrometer() > 0) {
211 return table_scale_[index];
213 return table_scale_[0];
223 auto extents = wn_extent(wn);
224 return table_scale(wn) > 0.0;
233 int AbscoHdf::wn_index(
double Wn_in)
const 236 auto extent = wn_extent(Wn_in);
238 double *wnptr = std::lower_bound(extent.first, extent.second, Wn_in);
239 double f = (Wn_in - *(wnptr - 1)) / (*wnptr - *(wnptr - 1));
240 if(f > 0.1 && f < 0.9) {
242 e << std::setprecision(8)
243 <<
"AbscoHDF does not interpolate in wavenumber direction.\n" 244 <<
"The interpolation doesn't work well near peaks, so we\n" 245 <<
"just don't do it. The requested Wn needs to be within 10%\n" 246 <<
"of the absco wn grid, return the value for the closest number.\n" 247 <<
"Wn: " << Wn_in <<
"\n" 248 <<
"Wnptr - 1: " << *(wnptr - 1) <<
"\n" 249 <<
"Wnptr: " << *wnptr <<
"\n" 250 <<
"Frac: " << f <<
" (should be < 0.1 or > 0.9)\n" 257 return (
int) (wnptr - wnfront);
263 int wi = wn_index(Wn_in);
264 if(wi < cache_double_lbound ||
265 wi >= cache_double_ubound)
267 return read_cache<double>()(Range::all(), Range::all(), Range::all(),
268 wi - cache_double_lbound);
274 int wi = wn_index(Wn_in);
275 if(wi < cache_float_lbound ||
276 wi >= cache_float_ubound)
278 return read_cache<float>()(Range::all(), Range::all(), Range::all(),
279 wi - cache_float_lbound);
287 template<
class T>
void AbscoHdf::swap(
int i)
const 290 if(read_cache<T>().extent(fourthDim) == 0)
291 read_cache<T>().resize(tgrid.rows(), tgrid.cols(),
292 std::max(1, number_broadener_vmr()),
294 int nl = read_cache<T>().extent(fourthDim);
297 TinyVector<int, 4> start, size;
298 start = 0, 0, 0, (i / nl) * nl;
299 size = tgrid.rows(), tgrid.cols(), std::max(number_broadener_vmr(), 1),
300 std::min(nl, wngrid.rows() - start(3));
301 bound_set<T>((i / nl) * nl, size(3));
302 if(number_broadener_vmr() > 0) {
304 read_cache<T>()(Range::all(), Range::all(), Range::all(), Range(0, size(3) - 1)) =
305 hfile->read_field<T, 4>(field_name, start, size);
308 TinyVector<int, 3> start2, size2;
309 start2 = 0, 0, (i / nl) * nl;
310 size2 = tgrid.rows(), tgrid.cols(),
311 std::min(nl, wngrid.rows() - start(3));
312 read_cache<T>()(Range::all(), Range::all(), 0, Range(0, size(3) - 1)) =
313 hfile->read_field<T, 3>(field_name, start2, size2);
319 Os <<
"AbscoHdf" <<
"\n" 320 <<
" File name: " << hfile->file_name() <<
"\n";
321 if(sb.number_spectrometer() ==0)
322 Os <<
" Scale factor: " << table_scale_[0] <<
"\n";
324 Os <<
" Scale factor: [";
325 for(
int i = 0; i < (int) table_scale_.size(); ++i) {
326 Os << table_scale_[i];
327 if(i < (
int) table_scale_.size() - 1)
This is the base of the exception hierarchy for Full Physics code.
AbscoHdf(const std::string &Fname, double Table_scale=1.0, int Cache_nline=5000)
Read the given Absco file.
virtual blitz::Array< float, 3 > read_float(double wn) const
This class reads and writes a HDF5 file.
Apply value function to a blitz array.
This gives the upper and lower bounds of the SpectralWindow.
virtual const std::pair< double *, double * > wn_extent(double Wn_in) const
virtual blitz::Array< double, 3 > read_double(double wn) const
Return either a blitz::Array<double, 3> or blitz::Array<float, 3>, depending on the type of the under...
We frequently have a double with units associated with it.
Contains classes to abstract away details in various Spurr Radiative Transfer software.
def(luabind::constructor< int >()) .def("rows"
virtual void print(std::ostream &Os) const
virtual double table_scale(double wn) const
Scale to apply to underlying ABSCO data to get the absorption_cross_section.
void load_file(const std::string &Fname)
Load file, using the same table scaling as we already have.
virtual bool have_data(double wn) const
Return true if we have data for the given wave number.