ARTS  2.4.0(git:4fb77825)
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 
53 void 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 
93 template <typename T>
94 void 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 
133 template <typename T>
134 void nca_write_to_file(const String& filename,
135  const T& type,
136  const Verbosity& verbosity) {
137  CREATE_OUT2;
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 
174 void 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 
194 void 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 
214 int 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 
236 int 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 
256 int 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 
277 int 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 
300 Index 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 
327 void 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 
343 void 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 
359 void 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 
375 void 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 
395 void 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 
413 void 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 
478 void 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 
497 void 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 
517 void 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 
539 bool 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 
566 bool 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 
585 bool 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 
604 bool 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 
622 void 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 */
Matrix
The Matrix class.
Definition: matpackI.h:1193
nca_get_data_Matrix
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
Tensor4::resize
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1064
exceptions.h
The declarations of all the exception classes.
out_basename
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
nca_get_data_double
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
nca_get_data_int
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
nca_get_data_ArrayOfIndex
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
nc_get_dim
Index nc_get_dim(const int ncid, const String &name, const bool noerror)
Read a dimension from NetCDF file.
Definition: nc_io.cc:300
nc_io.h
This file contains basic functions to handle NetCDF data files.
ARTS::Var::verbosity
Verbosity verbosity(Workspace &ws) noexcept
Definition: autoarts.h:7112
nca_get_data_text
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
nca_write_to_file
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
nca_put_var_Matrix
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
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:404
data
G0 G2 FVC Y DV Numeric Numeric Numeric Zeeman LowerQuantumNumbers void * data
Definition: arts_api_classes.cc:232
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:429
CREATE_OUT2
#define CREATE_OUT2
Definition: messages.h:206
nca_get_data_Tensor4
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
nca_filename
void nca_filename(String &filename, const String &varname)
Gives the default filename for the NetCDF formats.
Definition: nc_io.cc:53
Tensor4
The Tensor4 class.
Definition: matpackIV.h:421
nc_io_types.h
This file contains private function declarations and template instantiation to handle NetCDF data fil...
nca_filename_with_index
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
nca_get_dataa_double
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
Array
This can be used to make arrays out of anything.
Definition: array.h:108
SpeciesTag
A tag group can consist of the sum of several of these.
Definition: abs_species_tags.h:44
nca_put_var_ArrayOfIndex
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
Absorption::nelem
Index nelem(const Lines &l)
Number of lines.
Definition: absorptionlines.h:1820
nca_def_Vector
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
messages.h
Declarations having to do with the four output streams.
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:432
my_basic_string< char >
nca_def_Tensor4
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
nca_put_var_Tensor4
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
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:51
ConstTensor4View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:66
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Verbosity
Definition: messages.h:49
ConstTensor4View::npages
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:60
nca_get_data_long
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
nca_read_from_file
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
nca_def_Matrix
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
ConstTensor4View::nbooks
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:57
nca_def_ArrayOfIndex
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
ARTS::Var::npages
Index npages(Workspace &ws) noexcept
Definition: autoarts.h:4675
Matrix::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1056
nca_def_var
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
ARTS::Var::nrows
Index nrows(Workspace &ws) noexcept
Definition: autoarts.h:4682
ConstTensor4View::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackIV.cc:63
expand_path
String expand_path(const String &path)
Definition: file.cc:480
Zeeman::start
constexpr Rational start(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the lowest M for a polarization type of this transition.
Definition: zeemandata.h:77
nc_io_instantiation.h
add_basedir
String add_basedir(const String &path)
Definition: file.cc:499
nca_def_dim
void nca_def_dim(const int ncid, const String &name, const Index nelem, int *ncdim)
Define NetCDF dimension.
Definition: nc_io.cc:174
file.h
This file contains basic functions to handle ASCII files.
ARTS::Var::file_index
Index file_index(Workspace &ws) noexcept
Definition: autoarts.h:3475
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
nca_get_data_Vector
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
MatrixView::get_c_array
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackI.cc:735
ARTS::Var::ncols
Index ncols(Workspace &ws) noexcept
Definition: autoarts.h:4546
Vector
The Vector class.
Definition: matpackI.h:860
nca_error
void nca_error(const int e, const String s)
Throws a runtime error for the given NetCDF error code.
Definition: nc_io.cc:622
Tensor4View::get_c_array
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackIV.cc:358
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:195
ARTS::Var::nbooks
Index nbooks(Workspace &ws) noexcept
Definition: autoarts.h:4539
VectorView::get_c_array
const Numeric * get_c_array() const
Conversion to plain C-array, const-version.
Definition: matpackI.cc:272
arts.h
The global header file for ARTS.
nca_get_data_ArrayOfArrayOfSpeciesTag
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
nca_put_var_Vector
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