ReFRACtor
output_hdf.cc
Go to the documentation of this file.
1 #include "output_hdf.h"
2 #include "fp_exception.h"
3 #include <boost/regex.hpp>
4 #include <cstdio>
5 
6 using namespace FullPhysics;
7 using namespace blitz;
8 
9 //-----------------------------------------------------------------------
11 //-----------------------------------------------------------------------
12 
13 OutputHdf::OutputHdf(const std::string& Fname, int Num_level,
14  int Statevector_size, int Num_aerosol,
15  int Num_band)
16 : num_level(Num_level), statevector_size(Statevector_size),
17  num_aerosol(Num_aerosol), num_band(Num_band)
18 {
19  h.reset(new HdfFileGenerating(Fname));
20  initialize();
21 }
22 
23 //-----------------------------------------------------------------------
25 //-----------------------------------------------------------------------
26 
28  int Num_level,
29  int Statevector_size, int Num_aerosol,
30  int Num_band)
31 : num_level(Num_level), statevector_size(Statevector_size),
32  num_aerosol(Num_aerosol), num_band(Num_band), h(H)
33 {
34  initialize();
35 }
36 
37 void OutputHdf::initialize()
38 {
39  range_min_check(num_level, 1);
40  range_min_check(num_aerosol, 1);
41 
42  // See discussion in output_hdf.h for explanation of this check.
43 
44  if(num_level == statevector_size ||
45  num_aerosol == statevector_size ||
46  num_aerosol == num_level) {
47  Exception e;
48  e << "The current implementation assumes Num_level, Statevector_size\n"
49  << "and Num_aerosol are all different. This is entirely to simplify\n"
50  << "the implementation, see the discussion in output_hdf.h. If\n"
51  << "needed, we could relax this constraint by changing the code.\n"
52  << "The values of Num_level = " << num_level << ", Statevector_size = "
53  << statevector_size << ",\n"
54  << "and Num_aerosol = " << num_aerosol << " violates this assumption.";
55  throw e;
56  }
57 }
58 
59 // See base class for descriptions of all these functions.
60 
62 {
63  write_dimension_metadata();
64  write_shape_metadata();
65 }
66 
68 {
69  h->abandon();
70 }
71 
72 //-----------------------------------------------------------------------
79 //-----------------------------------------------------------------------
80 
81 void OutputHdf::write_dimension_metadata()
82 {
83  h->hdf_file().dimension_metadata("Retrieval",
84  "Number retrievals reported.", 1);
85  h->hdf_file().dimension_metadata("StateVectorElement",
86  "Retrieved state vector elements.", statevector_size);
87  h->hdf_file().dimension_metadata("Level",
88  "Atmospheric retrieval levels.", num_level);
89  h->hdf_file().dimension_metadata("Aerosol",
90  "Retrieved aerosol type.", num_aerosol);
91  h->hdf_file().dimension_metadata("Band",
92  "Spectral band.", num_band);
93 }
94 
95 //-----------------------------------------------------------------------
102 //-----------------------------------------------------------------------
103 
104 void OutputHdf::write_shape_metadata()
105 {
106  h->hdf_file().shape_metadata("Retrieval_Array", "Retrieval");
107  h->hdf_file().shape_metadata(
108  "Retrieval_StateVectorElement_StateVectorElement_Array",
109  "Retrieval", "StateVectorElement", "StateVectorElement");
110  h->hdf_file().shape_metadata("Retrieval_Level_Array", "Retrieval", "Level");
111  h->hdf_file().shape_metadata("Retrieval_StateVectorElement_Array",
112  "Retrieval", "StateVectorElement");
113  h->hdf_file().shape_metadata("Retrieval_Aerosol_Array", "Retrieval", "Aerosol");
114  h->hdf_file().shape_metadata("Retrieval_Band_Array", "Retrieval", "Band");
115 }
116 
117 template<class T> void OutputHdf::write_data_t(
118  const std::string& Dataset_name, T Val)
119 {
120  h->hdf_file().write_field(Dataset_name, Val);
121  // Metadata fields are scalars, all others are indexed by Retrieval.
122  if(Dataset_name.find("/Metadata/") == std::string::npos)
123  h->hdf_file().write_attribute(Dataset_name + "/Shape", "Retrieval_Array");
124  else
125  h->hdf_file().write_attribute(Dataset_name + "/Shape", "Scalar");
126 }
127 
128 template<class T> void OutputHdf::write_data_t(
129  const std::string& Dataset_name, const blitz::Array<T, 1>& Val)
130 {
131  using namespace blitz;
132  // We add an extra retrieval dimension, even though it has only 1
133  // value. This makes this look like the aggregated product SDOS
134  // produces.
135  Array<T, 2> val2(1, Val.rows());
136  val2(0, Range::all()) = Val;
137  h->hdf_file().write_field(Dataset_name, val2);
138 
139  // Check size, and use this to fill in Shape metadata. We silently
140  // leave off Shape metadata if don't recognize the size. See discussion
141  // of this design decision in output_hdf.h
142 
143  if(Val.rows() == statevector_size)
144  h->hdf_file().write_attribute(Dataset_name + "/Shape",
145  "Retrieval_StateVectorElement_Array");
146  else if(Val.rows() == num_level)
147  h->hdf_file().write_attribute(Dataset_name + "/Shape",
148  "Retrieval_Level_Array");
149  // We can't depend on num_aerosol and num_band being different, so
150  // we hardcode the few fields we have that depend on band.
151  else if(boost::regex_match(Dataset_name,
152  boost::regex(".*/num_colors_per_band")) ||
153  boost::regex_match(Dataset_name, boost::regex(".*/Absco.*Scale")))
154  h->hdf_file().write_attribute(Dataset_name + "/Shape",
155  "Retrieval_Band_Array");
156  else if(Val.rows() == num_aerosol)
157  h->hdf_file().write_attribute(Dataset_name + "/Shape",
158  "Retrieval_Aerosol_Array");
159 }
160 
161 template<class T> void OutputHdf::write_data_t(
162  const std::string& Dataset_name, const blitz::Array<T, 2>& Val)
163 {
164  using namespace blitz;
165  // We add an extra retrieval dimension, even though it has only 1
166  // value. This makes this look like the aggregated product SDOS
167  // produces.
168  Array<T, 3> val2(1, Val.rows(), Val.cols());
169  val2(0, Range::all(), Range::all()) = Val;
170  h->hdf_file().write_field(Dataset_name, val2);
171 
172  // Check size, and use this to fill in Shape metadata. We silently
173  // leave off Shape metadata if don't recognize the size. See discussion
174  // of this design decision in output_hdf.h
175 
176  if(Val.rows() == statevector_size &&
177  Val.cols() == statevector_size)
178  h->hdf_file().write_attribute(Dataset_name + "/Shape",
179  "Retrieval_StateVectorElement_StateVectorElement_Array");
180 }
181 
182 template<class T> void OutputHdf::write_data_t(
183  const std::string& Dataset_name, const blitz::Array<T, 3>& Val)
184 {
185  using namespace blitz;
186  // We add an extra retrieval dimension, even though it has only 1
187  // value. This makes this look like the aggregated product SDOS
188  // produces.
189  Array<T, 4>
190  val2(1, Val.rows(), Val.cols(),
191  Val.extent(thirdDim));
192  val2(0, Range::all(), Range::all(), Range::all()) = Val;
193  h->hdf_file().write_field(Dataset_name, val2);
194 
195  // Don't have any hardcoded shapes of rank 3, so silently leave
196  // metadata off. See discussion in output_hdf.h for this design
197  // decision.
198 }
199 
200 // Instantiation of the templates for the various types.
201 
202 template void OutputHdf::write_data_t(const std::string& Dataset_name,
203  int Val);
204 template void OutputHdf::write_data_t(const std::string& Dataset_name,
205  int64_t Val);
206 template void OutputHdf::write_data_t(const std::string& Dataset_name,
207  double Val);
208 template void OutputHdf::write_data_t(const std::string& Dataset_name,
209  const std::string& Val);
210 template void OutputHdf::write_data_t(const std::string& Dataset_name,
211  const char* Val);
212 
213 template void OutputHdf::write_data_t(const std::string& Dataset_name,
214  const blitz::Array<int, 1>& Val);
215 template void OutputHdf::write_data_t(const std::string& Dataset_name,
216  const blitz::Array<std::string, 1>& Val);
217 template void OutputHdf::write_data_t(const std::string& Dataset_name,
218  const blitz::Array<const char*, 1>& Val);
219 template void OutputHdf::write_data_t(const std::string& Dataset_name,
220  const blitz::Array<double, 1>& Val);
221 
222 template void OutputHdf::write_data_t(const std::string& Dataset_name,
223  const blitz::Array<int, 2>& Val);
224 template void OutputHdf::write_data_t(const std::string& Dataset_name,
225  const blitz::Array<std::string, 2>& Val);
226 template void OutputHdf::write_data_t(const std::string& Dataset_name,
227  const blitz::Array<const char*, 2>& Val);
228 template void OutputHdf::write_data_t(const std::string& Dataset_name,
229  const blitz::Array<double, 2>& Val);
230 
231 template void OutputHdf::write_data_t(const std::string& Dataset_name,
232  const blitz::Array<int, 3>& Val);
233 template void OutputHdf::write_data_t(const std::string& Dataset_name,
234  const blitz::Array<std::string, 3>& Val);
235 template void OutputHdf::write_data_t(const std::string& Dataset_name,
236  const blitz::Array<const char*, 3>& Val);
237 template void OutputHdf::write_data_t(const std::string& Dataset_name,
238  const blitz::Array<double, 3>& Val);
virtual void end_because_of_error()
Notify when an error occurred.
Definition: output_hdf.cc:67
To avoid creating files when an error occurs, we create the file with the name ".generating" appended...
This is the base of the exception hierarchy for Full Physics code.
Definition: fp_exception.h:16
Apply value function to a blitz array.
void write_data_t(const std::string &Dataset_name, T Val)
Definition: output_hdf.cc:117
virtual void start_write()
Notify derived class that we are starting to write data.
Definition: output_hdf.cc:61
Contains classes to abstract away details in various Spurr Radiative Transfer software.
Definition: doxygen_python.h:1
#define range_min_check(V, Min)
Range check.
Definition: fp_exception.h:167
OutputHdf(const std::string &Fname, int Num_level, int Statevector_size, int Num_aerosol, int Number_band)
Constructor. This takes the file name to write.
Definition: output_hdf.cc:13

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