ARTS 2.5.0 (git: 9ee3ac6c)
nc_io.cc
Go to the documentation of this file.
1/* Copyright (C) 2012 Oliver Lemke <olemke@core-dump.info>
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2, or (at your option) any
6 later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 USA. */
17
19// File description
21
30#include "arts.h"
31
32#ifdef ENABLE_NETCDF
33
34#include "exceptions.h"
35#include "file.h"
36#include "messages.h"
37#include "nc_io.h"
38#include "nc_io_types.h"
39
41// Default file name
43
45
53void nca_filename(String& filename, const String& varname) {
54 if ("" == filename) {
55 extern const String out_basename;
56 filename = out_basename + "." + varname + ".nc";
57 }
58}
59
61
71 const Index& file_index,
72 const String& varname) {
73 if ("" == filename) {
74 extern const String out_basename;
75 ostringstream os;
76 os << out_basename << "." << varname << "." << file_index << ".nc";
77 filename = os.str();
78 } else {
79 ostringstream os;
80 os << filename << "." << file_index << ".nc";
81 filename = os.str();
82 }
83}
84
86
93template <typename T>
94void nca_read_from_file(const String& filename,
95 T& type,
96 const Verbosity& verbosity) {
98
99 String efilename = expand_path(filename);
100
101 out2 << " Reading " << efilename << '\n';
102
103#pragma omp critical(netcdf__critical_region)
104 {
105 int ncid;
106 if (nc_open(efilename.c_str(), NC_NOWRITE, &ncid)) {
107 ostringstream os;
108 os << "Error reading file: " << efilename << endl;
109 throw runtime_error(os.str());
110 }
111
112 try {
113 nca_read_from_file(ncid, type, verbosity);
114 } catch (const std::runtime_error& e) {
115 ostringstream os;
116 os << "Error reading file: " << efilename << endl;
117 os << e.what() << endl;
118 throw runtime_error(os.str());
119 }
120
121 nc_close(ncid);
122 }
123}
124
126
133template <typename T>
134void nca_write_to_file(const String& filename,
135 const T& type,
136 const Verbosity& verbosity) {
138
139 String efilename = add_basedir(filename);
140
141 out2 << " Writing " << efilename << '\n';
142
143#pragma omp critical(netcdf__critical_region)
144 {
145 int ncid;
146 if (nc_create(efilename.c_str(), NC_CLOBBER, &ncid)) {
147 ostringstream os;
148 os << "Error writing file: " << efilename << endl;
149 throw runtime_error(os.str());
150 }
151
152 try {
153 nca_write_to_file(ncid, type, verbosity);
154 } catch (const std::runtime_error& e) {
155 ostringstream os;
156 os << "Error writing file: " << efilename << endl;
157 os << e.what() << endl;
158 throw runtime_error(os.str());
159 }
160
161 nc_close(ncid);
162 }
163}
164
166
174void nca_def_dim(const int ncid,
175 const String& name,
176 const Index nelem,
177 int* ncdim) {
178 int retval;
179 if ((retval = nc_def_dim(ncid, name.c_str(), nelem, ncdim)))
180 nca_error(retval, "nc_def_dim");
181}
182
184
194void nca_def_var(const int ncid,
195 const String& name,
196 const nc_type type,
197 const int ndims,
198 const int* dims,
199 int* varid) {
200 int retval;
201 if ((retval = nc_def_var(ncid, name.c_str(), type, ndims, dims, varid)))
202 nca_error(retval, "nc_def_var");
203}
204
206
214int nca_def_ArrayOfIndex(const int ncid,
215 const String& name,
216 const ArrayOfIndex& a) {
217 int ncdims[1], varid;
218 if (a.nelem()) {
219 nca_def_dim(ncid, name + "_nelem", a.nelem(), &ncdims[0]);
220 nca_def_var(ncid, name, NC_INT, 1, &ncdims[0], &varid);
221 } else
222 varid = -1;
223
224 return varid;
225}
226
228
236int nca_def_Vector(const int ncid, const String& name, const Vector& v) {
237 int ncdims[1], varid;
238 if (v.nelem()) {
239 nca_def_dim(ncid, name + "_nelem", v.nelem(), &ncdims[0]);
240 nca_def_var(ncid, name, NC_DOUBLE, 1, &ncdims[0], &varid);
241 } else
242 varid = -1;
243
244 return varid;
245}
246
248
256int nca_def_Matrix(const int ncid, const String& name, const Matrix& m) {
257 int ncdims[2], varid;
258 if (m.nrows() && m.ncols()) {
259 nca_def_dim(ncid, name + "_nrows", m.nrows(), &ncdims[0]);
260 nca_def_dim(ncid, name + "_ncols", m.ncols(), &ncdims[1]);
261 nca_def_var(ncid, name, NC_DOUBLE, 2, &ncdims[0], &varid);
262 } else
263 varid = -1;
264
265 return varid;
266}
267
269
277int nca_def_Tensor4(const int ncid, const String& name, const Tensor4& t) {
278 int ncdims[4], varid;
279 if (t.nbooks() && t.npages() && t.nrows() && t.ncols()) {
280 nca_def_dim(ncid, name + "_nbooks", t.nbooks(), &ncdims[0]);
281 nca_def_dim(ncid, name + "_npages", t.npages(), &ncdims[1]);
282 nca_def_dim(ncid, name + "_nrows", t.nrows(), &ncdims[2]);
283 nca_def_dim(ncid, name + "_ncols", t.ncols(), &ncdims[3]);
284 nca_def_var(ncid, name, NC_DOUBLE, 4, &ncdims[0], &varid);
285 } else
286 varid = -1;
287
288 return varid;
289}
290
292
300Index nc_get_dim(const int ncid, const String& name, const bool noerror) {
301 int retval, dimid;
302 size_t ndim;
303 if ((retval = nc_inq_dimid(ncid, name.c_str(), &dimid))) {
304 if (!noerror)
305 nca_error(retval, "nc_inq_ndims(" + name + ")");
306 else
307 return 0;
308 }
309 if ((retval = nc_inq_dimlen(ncid, dimid, &ndim))) {
310 if (!noerror)
311 nca_error(retval, "nc_inq_dimlen(" + name + ")");
312 else
313 return 0;
314 }
315
316 return (Index)ndim;
317}
318
320
327void nca_get_data_int(const int ncid, const String& name, int* data) {
328 int retval, varid;
329 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
330 nca_error(retval, "nc_inq_varid(" + name + ")");
331 if ((retval = nc_get_var_int(ncid, varid, data)))
332 nca_error(retval, "nc_get_var(" + name + ")");
333}
334
336
343void nca_get_data_long(const int ncid, const String& name, long* data) {
344 int retval, varid;
345 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
346 nca_error(retval, "nc_inq_varid(" + name + ")");
347 if ((retval = nc_get_var_long(ncid, varid, data)))
348 nca_error(retval, "nc_get_var(" + name + ")");
349}
350
352
359void nca_get_data_double(const int ncid, const String& name, Numeric* data) {
360 int retval, varid;
361 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
362 nca_error(retval, "nc_inq_varid(" + name + ")");
363 if ((retval = nc_get_var_double(ncid, varid, data)))
364 nca_error(retval, "nc_get_var(" + name + ")");
365}
366
368
375void nca_get_dataa_double(const int ncid,
376 const String& name,
377 size_t start,
378 size_t count,
379 Numeric* data) {
380 int retval, varid;
381 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
382 nca_error(retval, "nc_inq_varid(" + name + ")");
383 if ((retval = nc_get_vara_double(ncid, varid, &start, &count, data)))
384 nca_error(retval, "nc_get_var(" + name + ")");
385}
386
388
395void nca_get_data_text(const int ncid, const String& name, char* data) {
396 int retval, varid;
397 if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
398 nca_error(retval, "nc_inq_varid(" + name + ")");
399 if ((retval = nc_get_var_text(ncid, varid, data)))
400 nca_error(retval, "nc_get_var(" + name + ")");
401}
402
404
413void nca_get_data_ArrayOfIndex(const int ncid,
414 const String& name,
415 ArrayOfIndex& aoi,
416 const bool noerror) {
417 Index nelem = nc_get_dim(ncid, name + "_nelem", noerror);
418 aoi.resize(nelem);
419 if (nelem) {
420 Index* ind_arr = new Index[nelem];
421 nca_get_data_long(ncid, name, ind_arr);
422 Index i = 0;
423 for (ArrayOfIndex::iterator it = aoi.begin(); it != aoi.end(); it++, i++)
424 *it = ind_arr[i];
425 }
426}
427
429
439 const String& name,
441 const bool noerror) {
442 ArrayOfIndex species_count;
443 nca_get_data_ArrayOfIndex(ncid, name + "_count", species_count, noerror);
444 aast.resize(species_count.nelem());
445 if (species_count.nelem()) {
446 Index species_strings_nelem =
447 nc_get_dim(ncid, name + "_strings_nelem", noerror);
448 Index species_strings_length =
449 nc_get_dim(ncid, name + "_strings_length", noerror);
450 char* species_strings =
451 new char[species_strings_nelem * species_strings_length];
452 if (species_count.nelem())
453 nca_get_data_text(ncid, name + "_strings", species_strings);
454
455 Index si = 0;
456 for (Index i = 0; i < species_count.nelem(); i++) {
457 aast[i].resize(0);
458 for (Index j = 0; j < species_count[i]; j++) {
459 aast[i].push_back(SpeciesTag(&species_strings[si]));
460 si += species_strings_length;
461 }
462 }
463
464 delete[] species_strings;
465 }
466}
467
469
478void nca_get_data_Vector(const int ncid,
479 const String& name,
480 Vector& v,
481 const bool noerror) {
482 Index nelem = nc_get_dim(ncid, name + "_nelem", noerror);
483 v.resize(nelem);
484 if (nelem) nca_get_data_double(ncid, name, v.get_c_array());
485}
486
488
497void nca_get_data_Matrix(const int ncid,
498 const String& name,
499 Matrix& m,
500 const bool noerror) {
501 Index nrows = nc_get_dim(ncid, name + "_nrows", noerror);
502 Index ncols = nc_get_dim(ncid, name + "_ncols", noerror);
503 m.resize(nrows, ncols);
504 if (nrows && ncols) nca_get_data_double(ncid, name, m.get_c_array());
505}
506
508
517void nca_get_data_Tensor4(const int ncid,
518 const String& name,
519 Tensor4& t,
520 const bool noerror) {
521 Index nbooks = nc_get_dim(ncid, name + "_nbooks", noerror);
522 Index npages = nc_get_dim(ncid, name + "_npages", noerror);
523 Index nrows = nc_get_dim(ncid, name + "_nrows", noerror);
524 Index ncols = nc_get_dim(ncid, name + "_ncols", noerror);
526 if (nbooks && npages && nrows && ncols)
527 nca_get_data_double(ncid, name, t.get_c_array());
528}
529
531
539bool nca_put_var_ArrayOfIndex(const int ncid,
540 const int varid,
541 const ArrayOfIndex& a) {
542 bool fail = true;
543 if (a.nelem()) {
544 Index* ind_arr = new Index[a.nelem()];
545 for (Index i = 0; i < a.nelem(); i++) ind_arr[i] = a[i];
546
547 int retval;
548 if ((retval = nc_put_var_long(ncid, varid, ind_arr)))
549 nca_error(retval, "nc_put_var");
550
551 delete[] ind_arr;
552 fail = false;
553 }
554 return fail;
555}
556
558
566bool nca_put_var_Vector(const int ncid, const int varid, const Vector& v) {
567 bool fail = true;
568 if (v.nelem()) {
569 int retval;
570 if ((retval = nc_put_var_double(ncid, varid, v.get_c_array())))
571 nca_error(retval, "nc_put_var");
572 }
573 return fail;
574}
575
577
585bool nca_put_var_Matrix(const int ncid, const int varid, const Matrix& m) {
586 bool fail = true;
587 if (m.nrows() && m.ncols()) {
588 int retval;
589 if ((retval = nc_put_var_double(ncid, varid, m.get_c_array())))
590 nca_error(retval, "nc_put_var");
591 }
592 return fail;
593}
594
596
604bool nca_put_var_Tensor4(const int ncid, const int varid, const Tensor4& t) {
605 bool fail = true;
606 if (t.nbooks() && t.npages() && t.nrows() && t.ncols()) {
607 int retval;
608 if ((retval = nc_put_var_double(ncid, varid, t.get_c_array())))
609 nca_error(retval, "nc_put_var");
610 }
611 return fail;
612}
613
615
622void nca_error(const int e, const String s) {
623 ostringstream os;
624 os << "NetCDF error: " << s << ", " << e;
625 throw runtime_error(os.str());
626}
627
628// We can't do the instantiation at the beginning of this file, because the
629// implementation of nca_write_to_file and nca_read_from_file have to be known.
630
631#include "nc_io_instantiation.h"
632
633#endif /* ENABLE_NETCDF */
The global header file for ARTS.
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
Index nrows
Index nbooks
Index npages
void * data
Index ncols
Index nelem() const ARTS_NOEXCEPT
Number of elements.
Definition: array.h:195
Index nrows() const ARTS_NOEXCEPT
Returns the number of rows.
Definition: matpackI.cc:433
Index ncols() const ARTS_NOEXCEPT
Returns the number of columns.
Definition: matpackI.cc:436
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:58
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:55
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:64
Index nrows() const
Returns the number of rows.
Definition: matpackIV.cc:61
const Numeric * get_c_array() const ARTS_NOEXCEPT
Conversion to plain C-array.
Definition: matpackI.cc:739
The Matrix class.
Definition: matpackI.h:1225
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1056
const Numeric * get_c_array() const ARTS_NOEXCEPT
Conversion to plain C-array.
Definition: matpackIV.cc:354
The Tensor4 class.
Definition: matpackIV.h:421
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1058
The Vector class.
Definition: matpackI.h:876
The declarations of all the exception classes.
String add_basedir(const String &path)
Definition: file.cc:499
String expand_path(const String &path)
Definition: file.cc:480
This file contains basic functions to handle ASCII files.
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Declarations having to do with the four output streams.
#define CREATE_OUT2
Definition: messages.h:206
Index nelem(const Lines &l)
Number of lines.
char Type type
constexpr Rational start(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the lowest M for a polarization type of this transition.
Definition: zeemandata.h:78
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:70
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:277
void nca_get_data_double(const int ncid, const String &name, Numeric *data)
Read variable of type double from NetCDF file.
Definition: nc_io.cc:359
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:214
void nca_filename(String &filename, const String &varname)
Gives the default filename for the NetCDF formats.
Definition: nc_io.cc:53
void nca_get_data_Tensor4(const int ncid, const String &name, Tensor4 &t, const bool noerror)
Read variable of type Tensor4 from NetCDF file.
Definition: nc_io.cc:517
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:236
void nca_get_dataa_double(const int ncid, const String &name, size_t start, size_t count, Numeric *data)
Read variable of type array of double from NetCDF file.
Definition: nc_io.cc:375
void nca_get_data_int(const int ncid, const String &name, int *data)
Read variable of type int from NetCDF file.
Definition: nc_io.cc:327
void nca_get_data_long(const int ncid, const String &name, long *data)
Read variable of type long from NetCDF file.
Definition: nc_io.cc:343
void nca_get_data_Matrix(const int ncid, const String &name, Matrix &m, const bool noerror)
Read variable of type Matrix from NetCDF file.
Definition: nc_io.cc:497
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:194
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:256
void nca_get_data_ArrayOfIndex(const int ncid, const String &name, ArrayOfIndex &aoi, const bool noerror)
Read variable of type ArrayOfIndex from NetCDF file.
Definition: nc_io.cc:413
void nca_get_data_Vector(const int ncid, const String &name, Vector &v, const bool noerror)
Read variable of type Vector from NetCDF file.
Definition: nc_io.cc:478
void nca_get_data_ArrayOfArrayOfSpeciesTag(const int ncid, const String &name, ArrayOfArrayOfSpeciesTag &aast, const bool noerror)
Read variable of type ArrayOfArrayOfSpeciesTag from NetCDF file.
Definition: nc_io.cc:438
bool nca_put_var_Tensor4(const int ncid, const int varid, const Tensor4 &t)
Write variable of type Tensor4 to NetCDF file.
Definition: nc_io.cc:604
void nca_get_data_text(const int ncid, const String &name, char *data)
Read variable of type array of char from NetCDF file.
Definition: nc_io.cc:395
Index nc_get_dim(const int ncid, const String &name, const bool noerror)
Read a dimension from NetCDF file.
Definition: nc_io.cc:300
void nca_def_dim(const int ncid, const String &name, const Index nelem, int *ncdim)
Define NetCDF dimension.
Definition: nc_io.cc:174
bool nca_put_var_ArrayOfIndex(const int ncid, const int varid, const ArrayOfIndex &a)
Write variable of type ArrayOfIndex to NetCDF file.
Definition: nc_io.cc:539
bool nca_put_var_Matrix(const int ncid, const int varid, const Matrix &m)
Write variable of type Matrix to NetCDF file.
Definition: nc_io.cc:585
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:134
bool nca_put_var_Vector(const int ncid, const int varid, const Vector &v)
Write variable of type Vector to NetCDF file.
Definition: nc_io.cc:566
void nca_error(const int e, const String s)
Throws a runtime error for the given NetCDF error code.
Definition: nc_io.cc:622
void nca_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads a variable from a NetCDF file.
Definition: nc_io.cc:94
This file contains basic functions to handle NetCDF data files.
This file contains private function declarations and template instantiation to handle NetCDF data fil...
#define v
#define a
Species::Tag SpeciesTag
Definition: species_tags.h:99