ARTS 2.5.11 (git: 725533f0)
nc_io.cc
Go to the documentation of this file.
1
2// File description
4
13#include "arts.h"
14
15#ifdef ENABLE_NETCDF
16
17#include "exceptions.h"
18#include "file.h"
19#include "messages.h"
20#include "nc_io.h"
21#include "nc_io_types.h"
22
24// Default file name
26
28
36void nca_filename(String &filename, const String &varname) {
37 if ("" == filename) {
38 extern const String out_basename;
39 filename = out_basename + "." + varname + ".nc";
40 }
41}
42
44
53void nca_filename_with_index(String &filename, const Index &file_index,
54 const String &varname) {
55 if ("" == filename) {
56 extern const String out_basename;
57 ostringstream os;
58 os << out_basename << "." << varname << "." << file_index << ".nc";
59 filename = os.str();
60 } else {
61 ostringstream os;
62 os << filename << "." << file_index << ".nc";
63 filename = os.str();
64 }
65}
66
68
75template <typename T>
76void nca_read_from_file(const String &filename, T &type,
77 const Verbosity &verbosity) {
79
80 String efilename = expand_path(filename);
81
82 out2 << " Reading " << efilename << '\n';
83
84 bool fail = false;
85 String fail_msg;
86#pragma omp critical(netcdf__critical_region)
87 {
88 int ncid;
89 if (nc_open(efilename.c_str(), NC_NOWRITE, &ncid)) {
90 fail = true;
91 fail_msg = "Error opening file. Does it exists?";
92 } else {
93 try {
94 nca_read_from_file(ncid, type, verbosity);
95 } catch (const std::runtime_error &e) {
96 fail = true;
97 fail_msg = e.what();
98 }
99 nc_close(ncid);
100 }
101 }
102
103 if (fail)
104 ARTS_USER_ERROR("Error reading file: ", efilename, '\n', fail_msg);
105}
106
108
115template <typename T>
116void nca_write_to_file(const String &filename, const T &type,
117 const Verbosity &verbosity) {
119
120 String efilename = add_basedir(filename);
121
122 out2 << " Writing " << efilename << '\n';
123
124 bool fail = false;
125 String fail_msg;
126#pragma omp critical(netcdf__critical_region)
127 {
128 int ncid;
129 if (nc_create(efilename.c_str(), NC_CLOBBER | NC_NETCDF4, &ncid)) {
130 fail = true;
131 fail_msg = "Error opening file for writing.";
132 } else {
133 try {
134 nca_write_to_file(ncid, type, verbosity);
135 } catch (const std::runtime_error &e) {
136 fail = true;
137 fail_msg = e.what();
138 }
139 nc_close(ncid);
140 }
141 }
142
143 if (fail)
144 ARTS_USER_ERROR("Error writing file: ", efilename, '\n', fail_msg);
145}
146
148
156void nca_def_dim(const int ncid, const String &name, const Index nelem,
157 int *ncdim) {
158 int retval;
159 if ((retval = nc_def_dim(ncid, name.c_str(), nelem, ncdim)))
160 nca_error(retval, "nc_def_dim");
161}
162
164
174void nca_def_var(const int ncid, const String &name, const nc_type type,
175 const int ndims, const int *dims, int *varid) {
176 int retval;
177 if ((retval = nc_def_var(ncid, name.c_str(), type, ndims, dims, varid)))
178 nca_error(retval, "nc_def_var");
179}
180
182
190int nca_def_ArrayOfIndex(const int ncid, const String &name,
191 const ArrayOfIndex &a) {
192 std::array<int, 1> ncdims;
193 int varid;
194 if (a.nelem()) {
195 nca_def_dim(ncid, name + "_nelem", a.nelem(), &ncdims[0]);
196 nca_def_var(ncid, name, NC_INT, 1, &ncdims[0], &varid);
197 } else
198 varid = -1;
199
200 return varid;
201}
202
204
212int nca_def_Vector(const int ncid, const String &name, const Vector &v) {
213 std::array<int, 1> ncdims;
214 int varid;
215 if (v.nelem()) {
216 nca_def_dim(ncid, name + "_nelem", v.nelem(), &ncdims[0]);
217 nca_def_var(ncid, name, NC_DOUBLE, 1, &ncdims[0], &varid);
218 } else
219 varid = -1;
220
221 return varid;
222}
223
225
233int nca_def_Matrix(const int ncid, const String &name, const Matrix &m) {
234 std::array<int, 2> ncdims;
235 int varid;
236 if (m.nrows() && m.ncols()) {
237 nca_def_dim(ncid, name + "_nrows", m.nrows(), &ncdims[0]);
238 nca_def_dim(ncid, name + "_ncols", m.ncols(), &ncdims[1]);
239 nca_def_var(ncid, name, NC_DOUBLE, 2, &ncdims[0], &varid);
240 } else
241 varid = -1;
242
243 return varid;
244}
245
247
255int nca_def_Tensor4(const int ncid, const String &name, const Tensor4 &t) {
256 std::array<int, 4> ncdims;
257 int varid;
258 if (t.nbooks() && t.npages() && t.nrows() && t.ncols()) {
259 nca_def_dim(ncid, name + "_nbooks", t.nbooks(), &ncdims[0]);
260 nca_def_dim(ncid, name + "_npages", t.npages(), &ncdims[1]);
261 nca_def_dim(ncid, name + "_nrows", t.nrows(), &ncdims[2]);
262 nca_def_dim(ncid, name + "_ncols", t.ncols(), &ncdims[3]);
263 nca_def_var(ncid, name, NC_DOUBLE, 4, &ncdims[0], &varid);
264 } else
265 varid = -1;
266
267 return varid;
268}
269
271
279Index nca_get_dim(const int ncid, const String &name, const bool noerror) {
280 int retval, dimid;
281 size_t ndim;
282 if ((retval = nc_inq_dimid(ncid, name.c_str(), &dimid))) {
283 if (!noerror)
284 nca_error(retval, "nc_inq_ndims(" + name + ")");
285 else
286 return 0;
287 }
288 if ((retval = nc_inq_dimlen(ncid, dimid, &ndim))) {
289 if (!noerror)
290 nca_error(retval, "nc_inq_dimlen(" + name + ")");
291 else
292 return 0;
293 }
294
295 return (Index)ndim;
296}
297
299
306void nca_get_data(const int ncid, const String &name, int *data) {
307 int retval, varid;
308 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
309 nca_error(retval, "nc_inq_varid(" + name + ")");
310 if ((retval = nc_get_var_int(ncid, varid, data)))
311 nca_error(retval, "nc_get_var(" + name + ")");
312}
313
315
322void nca_get_data(const int ncid, const String &name, long *data) {
323 int retval, varid;
324 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
325 nca_error(retval, "nc_inq_varid(" + name + ")");
326 if ((retval = nc_get_var_long(ncid, varid, data)))
327 nca_error(retval, "nc_get_var(" + name + ")");
328}
329
331
338void nca_get_data(const int ncid, const String &name, long long *data) {
339 int retval, varid;
340 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
341 nca_error(retval, "nc_inq_varid(" + name + ")");
342 if ((retval = nc_get_var_longlong(ncid, varid, data)))
343 nca_error(retval, "nc_get_var(" + name + ")");
344}
345
347
354void nca_get_data(const int ncid, const String &name, Numeric *data) {
355 int retval, varid;
356 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
357 nca_error(retval, "nc_inq_varid(" + name + ")");
358 if ((retval = nc_get_var_double(ncid, varid, data)))
359 nca_error(retval, "nc_get_var(" + name + ")");
360}
361
363
370void nca_get_data(const int ncid, const String &name, size_t start,
371 size_t count, Numeric *data) {
372 int retval, varid;
373 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
374 nca_error(retval, "nc_inq_varid(" + name + ")");
375 if ((retval = nc_get_vara_double(ncid, varid, &start, &count, data)))
376 nca_error(retval, "nc_get_var(" + name + ")");
377}
378
380
387void nca_get_data(const int ncid, const String &name, char *data) {
388 int retval, varid;
389 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
390 nca_error(retval, "nc_inq_varid(" + name + ")");
391 if ((retval = nc_get_var_text(ncid, varid, data)))
392 nca_error(retval, "nc_get_var(" + name + ")");
393}
394
396
405void nca_get_data(const int ncid, const String &name, ArrayOfIndex &aoi,
406 const bool noerror) {
407 Index nelem = nca_get_dim(ncid, name + "_nelem", noerror);
408 aoi.resize(nelem);
409 if (nelem) {
410 nca_get_data(ncid, name, aoi.data());
411 }
412}
413
415
424void nca_get_data(const int ncid, const String &name,
425 ArrayOfArrayOfSpeciesTag &aast, const bool noerror) {
426 ArrayOfIndex species_count;
427 nca_get_data(ncid, name + "_count", species_count, noerror);
428 aast.resize(species_count.nelem());
429 if (species_count.nelem()) {
430 Index species_strings_nelem =
431 nca_get_dim(ncid, name + "_strings_nelem", noerror);
432 Index species_strings_length =
433 nca_get_dim(ncid, name + "_strings_length", noerror);
434 char *species_strings =
435 new char[species_strings_nelem * species_strings_length]; // FIXME: THIS SHOULD NOT USE "new"
436 if (species_count.nelem())
437 nca_get_data(ncid, name + "_strings", species_strings);
438
439 Index si = 0;
440 for (Index i = 0; i < species_count.nelem(); i++) {
441 aast[i].resize(0);
442 for (Index j = 0; j < species_count[i]; j++) {
443 aast[i].push_back(SpeciesTag(&species_strings[si]));
444 si += species_strings_length;
445 }
446 }
447
448 delete[] species_strings;
449 }
450}
451
453
462void nca_get_data(const int ncid, const String &name, Vector &v,
463 const bool noerror) {
464 Index nelem = nca_get_dim(ncid, name + "_nelem", noerror);
465 v.resize(nelem);
466 if (nelem)
467 nca_get_data(ncid, name, v.unsafe_data_handle());
468}
469
471
480void nca_get_data(const int ncid, const String &name, Matrix &m,
481 const bool noerror) {
482 Index nrows = nca_get_dim(ncid, name + "_nrows", noerror);
483 Index ncols = nca_get_dim(ncid, name + "_ncols", noerror);
484 m.resize(nrows, ncols);
485 if (nrows && ncols)
486 nca_get_data(ncid, name, m.unsafe_data_handle());
487}
488
490
499void nca_get_data(const int ncid, const String &name, Tensor4 &t,
500 const bool noerror) {
501 Index nbooks = nca_get_dim(ncid, name + "_nbooks", noerror);
502 Index npages = nca_get_dim(ncid, name + "_npages", noerror);
503 Index nrows = nca_get_dim(ncid, name + "_nrows", noerror);
504 Index ncols = nca_get_dim(ncid, name + "_ncols", noerror);
505 t.resize(nbooks, npages, nrows, ncols);
506 if (nbooks && npages && nrows && ncols)
507 nca_get_data(ncid, name, t.unsafe_data_handle());
508}
509
511
519void nca_put_var(const int ncid, const int varid, const long *ind_arr) {
520 int retval;
521 if ((retval = nc_put_var_long(ncid, varid, ind_arr)))
522 nca_error(retval, "nc_put_var");
523}
524
526
534void nca_put_var(const int ncid, const int varid, const long long *ind_arr) {
535 int retval;
536 if ((retval = nc_put_var_longlong(ncid, varid, ind_arr)))
537 nca_error(retval, "nc_put_var");
538}
539
541
549bool nca_put_var(const int ncid, const int varid, const ArrayOfIndex &a) {
550 bool fail = true;
551 if (a.nelem()) {
552 nca_put_var(ncid, varid, a.data());
553 fail = false;
554 }
555 return fail;
556}
557
559
567bool nca_put_var(const int ncid, const int varid, const Vector &v) {
568 bool fail = true;
569 if (v.nelem()) {
570 int retval;
571 if ((retval = nc_put_var_double(ncid, varid, v.unsafe_data_handle())))
572 nca_error(retval, "nc_put_var");
573 fail = false;
574 }
575 return fail;
576}
577
579
587bool nca_put_var(const int ncid, const int varid, const Matrix &m) {
588 bool fail = true;
589 if (m.nrows() && m.ncols()) {
590 int retval;
591 if ((retval = nc_put_var_double(ncid, varid, m.unsafe_data_handle())))
592 nca_error(retval, "nc_put_var");
593 fail = false;
594 }
595 return fail;
596}
597
599
607bool nca_put_var(const int ncid, const int varid, const Tensor4 &t) {
608 bool fail = true;
609 if (t.nbooks() && t.npages() && t.nrows() && t.ncols()) {
610 int retval;
611 if ((retval = nc_put_var_double(ncid, varid, t.unsafe_data_handle())))
612 nca_error(retval, "nc_put_var");
613 fail = false;
614 }
615 return fail;
616}
617
619
626void nca_error(const int e, const std::string_view s) {
627 ARTS_USER_ERROR("NetCDF error: ", s, ", ", e, "\nCheck your input file.");
628}
629
630// We can't do the instantiation at the beginning of this file, because the
631// implementation of nca_write_to_file and nca_read_from_file have to be known.
632
633#include "nc_io_instantiation.h"
634
635#endif /* ENABLE_NETCDF */
The global header file for ARTS.
Index nelem() const ARTS_NOEXCEPT
Definition array.h:75
#define ARTS_USER_ERROR(...)
Definition debug.h:153
The declarations of all the exception classes.
String add_basedir(const std::string_view path)
Definition file.cc:424
String expand_path(String path)
Definition file.cc:405
This file contains basic functions to handle ASCII files.
String out_basename
The basename for the report file and for all other output files.
Definition messages.cc:25
Declarations having to do with the four output streams.
#define CREATE_OUT2
Definition messages.h:188
void nca_filename_with_index(String &filename, const Index &file_index, const String &varname)
Gives the default filename, with file index, for the NetCDF formats.
Definition nc_io.cc:53
int nca_def_Tensor4(const int ncid, const String &name, const Tensor4 &t)
Define NetCDF dimensions and variable for a Tensor4.
Definition nc_io.cc:255
int nca_def_ArrayOfIndex(const int ncid, const String &name, const ArrayOfIndex &a)
Define NetCDF dimensions and variable for an ArrayOfIndex.
Definition nc_io.cc:190
void nca_filename(String &filename, const String &varname)
Gives the default filename for the NetCDF formats.
Definition nc_io.cc:36
int nca_def_Vector(const int ncid, const String &name, const Vector &v)
Define NetCDF dimensions and variable for a Vector.
Definition nc_io.cc:212
Index nca_get_dim(const int ncid, const String &name, const bool noerror)
Read a dimension from NetCDF file.
Definition nc_io.cc:279
void nca_def_var(const int ncid, const String &name, const nc_type type, const int ndims, const int *dims, int *varid)
Define NetCDF variable.
Definition nc_io.cc:174
int nca_def_Matrix(const int ncid, const String &name, const Matrix &m)
Define NetCDF dimensions and variable for a Matrix.
Definition nc_io.cc:233
void nca_error(const int e, const std::string_view s)
Throws a runtime error for the given NetCDF error code.
Definition nc_io.cc:626
void nca_def_dim(const int ncid, const String &name, const Index nelem, int *ncdim)
Define NetCDF dimension.
Definition nc_io.cc:156
void nca_put_var(const int ncid, const int varid, const long *ind_arr)
Write variable of type long* to NetCDF file.
Definition nc_io.cc:519
void nca_get_data(const int ncid, const String &name, int *data)
Read variable of type int from NetCDF file.
Definition nc_io.cc:306
void nca_write_to_file(const String &filename, const T &type, const Verbosity &verbosity)
Writes a variable to a NetCDF file.
Definition nc_io.cc:116
void nca_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads a variable from a NetCDF file.
Definition nc_io.cc:76
This file contains basic functions to handle NetCDF data files.
This file contains private function declarations and template instantiation to handle NetCDF data fil...
Species::Tag SpeciesTag
#define v
#define a