ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_NCInterface.H
Go to the documentation of this file.
1 /** \file nc_interface.H
2  *
3  * Interface to NetCDF library
4  *
5  * Defines convenience wrappers to interact with a NetCDF file in a more
6  * OOP-like manner.
7  */
8 
9 #ifndef ERF_NC_INTERFACE_H
10 #define ERF_NC_INTERFACE_H
11 
12 #ifdef ERF_USE_NETCDF
13 #include <string>
14 #include <unordered_map>
15 #include <vector>
16 
17 #include <netcdf.h>
18 #include <netcdf_par.h>
19 
20 namespace ncutils {
21 
22 //! Wrapper around NetCDF data types
23 struct NCDType
24 {
25  static constexpr nc_type Int = NC_INT;
26 #ifdef AMREX_USE_FLOAT
27  static constexpr nc_type Real = NC_FLOAT;
28  using RType = float;
29 #else
30  static constexpr nc_type Real = NC_DOUBLE;
31  using RType = double;
32 #endif
33 };
34 
35 //! Representation of NetCDF dimension
36 struct NCDim
37 {
38  //! File/Group Identifier
39  const int ncid;
40 
41  //! Dimension ID used with NetCDF API
42  const int dimid;
43 
44  //! Name of this dimension
45  [[nodiscard]] std::string name() const;
46 
47  //! Length of this dimension
48  [[nodiscard]] size_t len() const;
49 };
50 
51 //! Representation of a NetCDF variable
52 struct NCVar
53 {
54  //! File/Group identifier
55  const int ncid;
56 
57  //! Variable ID used with NetCDF API
58  const int varid;
59 
60  //! Name of this variable
61  [[nodiscard]] std::string name () const;
62 
63  //! Number of array dimensions for this variable
64  [[nodiscard]] int ndim () const;
65 
66  //! Shape of the array (size in each array dimension)
67  [[nodiscard]] std::vector<size_t> shape () const;
68 
69  //! Dimension names of the array (str in each array dimension)
70  [[nodiscard]] std::vector<std::string> dimnames () const;
71 
72  //! Write out the entire variable
73  void put (const double*) const;
74  void put (const float*) const;
75  void put (const int*) const;
76 
77  //! Write out a slice of data
78  void
79  put (const double*,
80  const std::vector<size_t>&,
81  const std::vector<size_t>&) const;
82 
83  //! Write out a slice of data with with strides (see hyperslab definition in
84  //! NetCDF)
85  void
86  put (const double*,
87  const std::vector<size_t>&,
88  const std::vector<size_t>&,
89  const std::vector<ptrdiff_t>&) const;
90  //! Write out a slice of data
91  void
92  put (const float*,
93  const std::vector<size_t>&,
94  const std::vector<size_t>&) const;
95 
96  //! Write out a slice of data with with strides (see hyperslab definition in
97  //! NetCDF)
98  void
99  put (const float*,
100  const std::vector<size_t>&,
101  const std::vector<size_t>&,
102  const std::vector<ptrdiff_t>&) const;
103 
104  void put (const int*, const std::vector<size_t>&, const std::vector<size_t>&) const;
105 
106  void
107  put (const int*,
108  const std::vector<size_t>&,
109  const std::vector<size_t>&,
110  const std::vector<ptrdiff_t>&) const;
111 
112  void put (const char**, const std::vector<size_t>&, const std::vector<size_t>&) const;
113 
114  void
115  put (const char** dptr,
116  const std::vector<size_t>& start,
117  const std::vector<size_t>& count,
118  const std::vector<ptrdiff_t>& stride) const;
119 
120  //! Read the entire variable from file
121  void get (double*) const;
122  void get (float*) const;
123  void get (int*) const;
124 
125  //! Read a chunk of data from the file
126  void
127  get (double*, const std::vector<size_t>&, const std::vector<size_t>&) const;
128 
129  //! Read a chunk of data with strides
130  void
131  get (double*,
132  const std::vector<size_t>&,
133  const std::vector<size_t>&,
134  const std::vector<ptrdiff_t>&) const;
135 
136  //! Read a chunk of data from the file
137  void
138  get (float*, const std::vector<size_t>&, const std::vector<size_t>&) const;
139 
140  //! Read a chunk of data with strides
141  void
142  get (float*,
143  const std::vector<size_t>&,
144  const std::vector<size_t>&,
145  const std::vector<ptrdiff_t>&) const;
146 
147  void
148  get (int*, const std::vector<size_t>&, const std::vector<size_t>&) const;
149 
150  void
151  get (int*,
152  const std::vector<size_t>&,
153  const std::vector<size_t>&,
154  const std::vector<ptrdiff_t>&) const;
155 
156  //! Read a chunk of data from the file
157  void
158  get (char*, const std::vector<size_t>&, const std::vector<size_t>&) const;
159 
160  //! Read a chunk of data with strides
161  void
162  get (char*,
163  const std::vector<size_t>&,
164  const std::vector<size_t>&,
165  const std::vector<ptrdiff_t>&) const;
166 
167  [[nodiscard]] bool has_attr (const std::string& name) const;
168 
169  void put_attr (const std::string& name, const std::string& value) const;
170 
171  void
172  put_attr (const std::string& name, const std::vector<double>& value) const;
173 
174  void
175  put_attr (const std::string& name, const std::vector<float>& value) const;
176 
177  void put_attr (const std::string& name, const std::vector<int>& value) const;
178 
179  [[nodiscard]] std::string get_attr (const std::string& name) const;
180 
181  void get_attr (const std::string& name, std::vector<double>& value) const;
182  void get_attr (const std::string& name, std::vector<float>& value) const;
183  void get_attr (const std::string& name, std::vector<int>& value) const;
184 
185  void par_access (int cmode) const; //Uncomment for parallel NetCDF
186 };
187 
188 //! Representation of a NetCDF group
189 class NCGroup
190 {
191 public:
192  //! Identifier used with NetCDF API calls
193  const int ncid;
194 
195  //! Name of this group
196  [[nodiscard]] std::string name () const;
197 
198  //! Full name for this group
199  [[nodiscard]] std::string full_name () const;
200 
201  //! Number of sub-groups within this group
202  [[nodiscard]] int num_groups () const;
203 
204  //! Number of dimensions in this group
205  [[nodiscard]] int num_dimensions () const;
206 
207  //! Number of variables within this group
208  [[nodiscard]] int num_variables () const;
209 
210  //! Number of attributes within this group
211  [[nodiscard]] int num_attributes () const;
212 
213  //! Check if a group exists
214  [[nodiscard]] bool has_group (const std::string&) const;
215 
216  //! Check if a dimension exists by name
217  [[nodiscard]] bool has_dim (const std::string&) const;
218 
219  /** Return id of variable by name
220  *
221  * Throws error if variable does not exist, use 'has_var' to check
222  */
223  [[nodiscard]] int get_id (const std::string&) const;
224 
225  //! Check if a variable exists by name
226  [[nodiscard]] bool has_var (const std::string&) const;
227 
228  //! Check if an attribute exists
229  [[nodiscard]] bool has_attr (const std::string&) const;
230 
231  /** Get the group by name
232  *
233  * Throws error if the group doesn't exist, use `has_group` to check
234  */
235  [[nodiscard]] NCGroup group (const std::string&) const;
236 
237  //! Get the dimension instance by name
238  [[nodiscard]] NCDim dim (const std::string&) const;
239 
240  //! Get the variable instance by name
241  [[nodiscard]] NCVar var (const std::string&) const;
242 
243  //! Define new dimension
244  void def_dim (const std::string&, size_t len) const;
245 
246  //! Define an array
247  void def_array (const std::string& name,
248  nc_type dtype,
249  const std::vector<std::string>&) const;
250 
251  //! Define a variable (wrapper for def_array)
252  void def_var (const std::string& name,
253  const nc_type dtype,
254  const std::vector<std::string>& dnames) const
255  {
256  def_array(name, dtype, dnames);
257  }
258 
259  void put_attr (const std::string& name, const std::string& value) const;
260  void put_attr (const std::string& name, const std::vector<double>& value) const;
261  void put_attr (const std::string& name, const std::vector<float>& value) const;
262  void put_attr (const std::string& name, const std::vector<int>& value) const;
263 
264  [[nodiscard]] std::string get_attr (const std::string& name) const;
265  void get_attr (const std::string& name, std::vector<double>& value) const;
266  void get_attr (const std::string& name, std::vector<float>& value) const;
267  void get_attr (const std::string& name, std::vector<int>& value) const;
268 
269  //! Return a list of all groups defined in this group
270  [[nodiscard]] std::vector<NCGroup> all_groups () const;
271 
272  //! Return a list of all dimensions defined in this group
273  [[nodiscard]] std::vector<NCDim> all_dims () const;
274 
275  //! Return a list of all variables defined in this group
276  [[nodiscard]] std::vector<NCVar> all_vars () const;
277 
278  //! Enter definition mode (not needed for NetCDF4 format)
279  void enter_def_mode () const;
280 
281  //! Exit definition mode
282  void exit_def_mode () const;
283 
284 protected:
285  NCGroup (const int id) : ncid(id) {}
286  NCGroup (const int id, const NCGroup* /*par*/) : ncid(id) {}
287 };
288 
289 /** Representation of a NetCDF file
290  *
291  * Provide wrappes to create and open file
292  */
293 class NCFile : public NCGroup
294 {
295 public:
296  static NCFile create (const std::string& name, const int cmode = NC_CLOBBER | NC_NETCDF4);
297  static NCFile open (const std::string& name, const int cmode = NC_NOWRITE);
298 
299  static NCFile create_par (const std::string& name,
300  const int cmode = NC_CLOBBER | NC_NETCDF4 | NC_MPIIO,
301  MPI_Comm comm = MPI_COMM_WORLD,
302  MPI_Info info = MPI_INFO_NULL);
303 
304  static NCFile open_par (const std::string& name,
305  const int cmode = NC_NOWRITE,
306  MPI_Comm comm = MPI_COMM_WORLD,
307  MPI_Info info = MPI_INFO_NULL);
308 
309  ~NCFile ();
310 
311  void close ();
312 
313 protected:
314  NCFile (const int id) : NCGroup(id), is_open{true} {}
315 
316  bool is_open{false};
317 };
318 
319 } // namespace ncutils
320 
321 #else
322 
323 namespace ncutils {
324 
325 struct NCDim
326 {
327  const int ncid{-1};
328  const int dimid{-1};
329 };
330 
331 struct NCVar
332 {
333  const int ncid{-1};
334  const int varid{-1};
335 };
336 
337 class NCGroup
338 {
339 public:
340  const int ncid{-1};
341 };
342 
343 class NCFile : public NCGroup
344 {};
345 
346 } // namespace ncutils
347 
348 #endif
349 
350 #endif /* NC_INTERFACE_H */
Real value
Definition: ERF_HurricaneDiagnostics.cpp:30
pp get("wavelength", wavelength)
std::string name
Definition: ERF_Plotfile2DCatalog.cpp:97
DiagnosticID id
Definition: ERF_Plotfile2DWaterPath.cpp:23
int Int
Definition: ERF_ShocInterface.H:20
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_NCInterface.H:344
Definition: ERF_NCInterface.H:338
const int ncid
Definition: ERF_NCInterface.H:340
@ open
Definition: ERF_IndexDefines.H:255
Definition: ERF_NCInterface.cpp:9
Definition: ERF_NCInterface.H:326
const int dimid
Definition: ERF_NCInterface.H:328
const int ncid
Definition: ERF_NCInterface.H:327
Definition: ERF_NCInterface.H:332
const int ncid
Definition: ERF_NCInterface.H:333
const int varid
Definition: ERF_NCInterface.H:334