ARTS  2.2.66
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 
18 
20 // File description
22 
31 #include "arts.h"
32 
33 #ifdef ENABLE_NETCDF
34 
35 #include "nc_io.h"
36 #include "nc_io_types.h"
37 #include "file.h"
38 #include "messages.h"
39 #include "exceptions.h"
40 
41 
43 // Default file name
45 
47 
55 void nca_filename(String& filename, const String& varname)
56 {
57  if ("" == filename)
58  {
59  extern const String out_basename;
60  filename = out_basename + "." + varname + ".nc";
61  }
62 }
63 
64 
65 
67 
77  const Index& file_index,
78  const String& varname)
79 {
80  if ("" == filename)
81  {
82  extern const String out_basename;
83  ostringstream os;
84  os << out_basename << "." << varname << "." << file_index << ".nc";
85  filename = os.str();
86  }
87  else
88  {
89  ostringstream os;
90  os << filename << "." << file_index << ".nc";
91  filename = os.str();
92  }
93 }
94 
95 
97 
104 template<typename T>
105 void nca_read_from_file(const String& filename,
106  T& type,
107  const Verbosity& verbosity)
108 {
109  CREATE_OUT2;
110 
111  String efilename = expand_path(filename);
112 
113  out2 << " Reading " << efilename << '\n';
114 
115 #pragma omp critical(netcdf__critical_region)
116  {
117  int ncid;
118  if (nc_open(efilename.c_str(), NC_NOWRITE, &ncid))
119  {
120  ostringstream os;
121  os << "Error reading file: " << efilename << endl;
122  throw runtime_error(os.str());
123  }
124 
125  try
126  {
127  nca_read_from_file(ncid, type, verbosity);
128  }
129  catch (runtime_error e)
130  {
131  ostringstream os;
132  os << "Error reading file: " << efilename << endl;
133  os << e.what() << endl;
134  throw runtime_error(os.str());
135  }
136 
137  nc_close(ncid);
138  }
139 }
140 
141 
143 
150 template<typename T>
151 void nca_write_to_file(const String& filename,
152  const T& type,
153  const Verbosity& verbosity)
154 {
155  CREATE_OUT2;
156 
157  String efilename = add_basedir(filename);
158 
159  out2 << " Writing " << efilename << '\n';
160 
161 #pragma omp critical(netcdf__critical_region)
162  {
163  int ncid;
164  if (nc_create(efilename.c_str(), NC_CLOBBER, &ncid))
165  {
166  ostringstream os;
167  os << "Error writing file: " << efilename << endl;
168  throw runtime_error(os.str());
169  }
170 
171  try
172  {
173  nca_write_to_file(ncid, type, verbosity);
174  }
175  catch (runtime_error e)
176  {
177  ostringstream os;
178  os << "Error writing file: " << efilename << endl;
179  os << e.what() << endl;
180  throw runtime_error(os.str());
181  }
182 
183  nc_close(ncid);
184  }
185 }
186 
187 
189 
197 void nca_def_dim(const int ncid, const String& name, const Index nelem, int* ncdim)
198 {
199  int retval;
200  if ((retval = nc_def_dim(ncid, name.c_str(), nelem, ncdim)))
201  nca_error(retval, "nc_def_dim");
202 }
203 
204 
206 
216 void nca_def_var(const int ncid, const String& name, const nc_type type, const int ndims,
217  const int* dims, int* varid)
218 {
219  int retval;
220  if ((retval = nc_def_var(ncid, name.c_str(), type, ndims, dims, varid)))
221  nca_error(retval, "nc_def_var");
222 }
223 
224 
226 
234 int nca_def_ArrayOfIndex(const int ncid, const String& name, const ArrayOfIndex& a)
235 {
236  int ncdims[1], varid;
237  if (a.nelem())
238  {
239  nca_def_dim(ncid, name+"_nelem", a.nelem(), &ncdims[0]);
240  nca_def_var(ncid, name, NC_INT, 1, &ncdims[0], &varid);
241  }
242  else
243  varid = -1;
244 
245  return varid;
246 }
247 
248 
250 
258 int nca_def_Vector(const int ncid, const String& name, const Vector& v)
259 {
260  int ncdims[1], varid;
261  if (v.nelem())
262  {
263  nca_def_dim(ncid, name+"_nelem", v.nelem(), &ncdims[0]);
264  nca_def_var(ncid, name, NC_DOUBLE, 1, &ncdims[0], &varid);
265  }
266  else
267  varid = -1;
268 
269  return varid;
270 }
271 
272 
274 
282 int nca_def_Matrix(const int ncid, const String& name, const Matrix& m)
283 {
284  int ncdims[2], varid;
285  if (m.nrows() && m.ncols())
286  {
287  nca_def_dim(ncid, name+"_nrows", m.nrows(), &ncdims[0]);
288  nca_def_dim(ncid, name+"_ncols", m.ncols(), &ncdims[1]);
289  nca_def_var(ncid, name, NC_DOUBLE, 2, &ncdims[0], &varid);
290  }
291  else
292  varid = -1;
293 
294  return varid;
295 }
296 
297 
299 
307 int nca_def_Tensor4(const int ncid, const String& name, const Tensor4& t)
308 {
309  int ncdims[4], varid;
310  if (t.nbooks() && t.npages() && t.nrows() && t.ncols())
311  {
312  nca_def_dim(ncid, name+"_nbooks", t.nbooks(), &ncdims[0]);
313  nca_def_dim(ncid, name+"_npages", t.npages(), &ncdims[1]);
314  nca_def_dim(ncid, name+"_nrows", t.nrows(), &ncdims[2]);
315  nca_def_dim(ncid, name+"_ncols", t.ncols(), &ncdims[3]);
316  nca_def_var(ncid, name, NC_DOUBLE, 4, &ncdims[0], &varid);
317  }
318  else
319  varid = -1;
320 
321  return varid;
322 }
323 
324 
326 
334 Index nc_get_dim(const int ncid, const String& name, const bool noerror)
335 {
336  int retval, dimid;
337  size_t ndim;
338  if ((retval = nc_inq_dimid(ncid, name.c_str(), &dimid)))
339  {
340  if (!noerror) nca_error(retval, "nc_inq_ndims("+name+")");
341  else return 0;
342  }
343  if ((retval = nc_inq_dimlen(ncid, dimid, &ndim)))
344  {
345  if (!noerror) nca_error(retval, "nc_inq_dimlen("+name+")");
346  else return 0;
347  }
348 
349  return (Index)ndim;
350 }
351 
352 
354 
361 void nca_get_data_int(const int ncid, const String& name, int* data)
362 {
363  int retval, varid;
364  if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
365  nca_error(retval, "nc_inq_varid("+name+")");
366  if ((retval = nc_get_var_int(ncid, varid, data)))
367  nca_error(retval, "nc_get_var("+name+")");
368 }
369 
370 
372 
379 void nca_get_data_long(const int ncid, const String& name, long* data)
380 {
381  int retval, varid;
382  if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
383  nca_error(retval, "nc_inq_varid("+name+")");
384  if ((retval = nc_get_var_long(ncid, varid, data)))
385  nca_error(retval, "nc_get_var("+name+")");
386 }
387 
388 
390 
397 void nca_get_data_double(const int ncid, const String& name, Numeric* data)
398 {
399  int retval, varid;
400  if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
401  nca_error(retval, "nc_inq_varid("+name+")");
402  if ((retval = nc_get_var_double(ncid, varid, data)))
403  nca_error(retval, "nc_get_var("+name+")");
404 }
405 
406 
408 
415 void nca_get_dataa_double(const int ncid, const String& name,
416  size_t start, size_t count, Numeric* data)
417 {
418  int retval, varid;
419  if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
420  nca_error(retval, "nc_inq_varid("+name+")");
421  if ((retval = nc_get_vara_double(ncid, varid, &start, &count, data)))
422  nca_error(retval, "nc_get_var("+name+")");
423 }
424 
425 
427 
434 void nca_get_data_text(const int ncid, const String& name, char* data)
435 {
436  int retval, varid;
437  if ((retval = nc_inq_varid(ncid, name.c_str(), &varid)))
438  nca_error(retval, "nc_inq_varid("+name+")");
439  if ((retval = nc_get_var_text(ncid, varid, data)))
440  nca_error(retval, "nc_get_var("+name+")");
441 }
442 
443 
445 
454 void nca_get_data_ArrayOfIndex(const int ncid, const String& name, ArrayOfIndex& aoi,
455  const bool noerror)
456 {
457  Index nelem = nc_get_dim(ncid, name+"_nelem", noerror);
458  aoi.resize(nelem);
459  if (nelem)
460  {
461  Index* ind_arr = new Index[nelem];
462  nca_get_data_long(ncid, name, ind_arr);
463  Index i = 0;
464  for (ArrayOfIndex::iterator it = aoi.begin(); it != aoi.end(); it++, i++)
465  *it = ind_arr[i];
466  }
467 }
468 
469 
471 
481  const String& name,
483  const bool noerror)
484 {
485  ArrayOfIndex species_count;
486  nca_get_data_ArrayOfIndex(ncid, name+"_count", species_count, noerror);
487  aast.resize(species_count.nelem());
488  if (species_count.nelem())
489  {
490  Index species_strings_nelem = nc_get_dim(ncid, name+"_strings_nelem", noerror);
491  Index species_strings_length = nc_get_dim(ncid, name+"_strings_length", noerror);
492  char* species_strings = new char[species_strings_nelem*species_strings_length];
493  if (species_count.nelem()) nca_get_data_text(ncid, name+"_strings", species_strings);
494 
495  Index si = 0;
496  for (Index i = 0; i < species_count.nelem(); i++)
497  {
498  aast[i].resize(0);
499  for (Index j = 0; j < species_count[i]; j++)
500  {
501  aast[i].push_back(SpeciesTag(&species_strings[si]));
502  si += species_strings_length;
503  }
504  }
505 
506  delete[] species_strings;
507  }
508 }
509 
510 
512 
521 void nca_get_data_Vector(const int ncid, const String& name, Vector& v, const bool noerror)
522 {
523  Index nelem = nc_get_dim(ncid, name+"_nelem", noerror);
524  v.resize(nelem);
525  if (nelem) nca_get_data_double(ncid, name, v.get_c_array());
526 }
527 
528 
530 
539 void nca_get_data_Matrix(const int ncid, const String& name, Matrix& m, const bool noerror)
540 {
541  Index nrows = nc_get_dim(ncid, name+"_nrows", noerror);
542  Index ncols = nc_get_dim(ncid, name+"_ncols", noerror);
543  m.resize(nrows, ncols);
544  if (nrows && ncols) nca_get_data_double(ncid, name, m.get_c_array());
545 }
546 
547 
549 
558 void nca_get_data_Tensor4(const int ncid, const String& name, Tensor4& t, const bool noerror)
559 {
560  Index nbooks = nc_get_dim(ncid, name+"_nbooks", noerror);
561  Index npages = nc_get_dim(ncid, name+"_npages", noerror);
562  Index nrows = nc_get_dim(ncid, name+"_nrows", noerror);
563  Index ncols = nc_get_dim(ncid, name+"_ncols", noerror);
564  t.resize(nbooks, npages, nrows, ncols);
565  if (nbooks && npages && nrows && ncols) nca_get_data_double(ncid, name, t.get_c_array());
566 }
567 
568 
570 
578 bool nca_put_var_ArrayOfIndex(const int ncid, const int varid, const ArrayOfIndex& a)
579 {
580  bool fail = true;
581  if (a.nelem())
582  {
583  Index* ind_arr = new Index[a.nelem()];
584  for (Index i = 0; i < a.nelem(); i++)
585  ind_arr[i] = a[i];
586 
587  int retval;
588  if ((retval = nc_put_var_long(ncid, varid, ind_arr)))
589  nca_error(retval, "nc_put_var");
590 
591  delete[] ind_arr;
592  fail = false;
593  }
594  return fail;
595 }
596 
597 
599 
607 bool nca_put_var_Vector(const int ncid, const int varid, const Vector& v)
608 {
609  bool fail = true;
610  if (v.nelem())
611  {
612  int retval;
613  if ((retval = nc_put_var_double(ncid, varid, v.get_c_array())))
614  nca_error(retval, "nc_put_var");
615  }
616  return fail;
617 }
618 
619 
621 
629 bool nca_put_var_Matrix(const int ncid, const int varid, const Matrix& m)
630 {
631  bool fail = true;
632  if (m.nrows() && m.ncols())
633  {
634  int retval;
635  if ((retval = nc_put_var_double(ncid, varid, m.get_c_array())))
636  nca_error(retval, "nc_put_var");
637  }
638  return fail;
639 }
640 
641 
643 
651 bool nca_put_var_Tensor4(const int ncid, const int varid, const Tensor4& t)
652 {
653  bool fail = true;
654  if (t.nbooks() && t.npages() && t.nrows() && t.ncols())
655  {
656  int retval;
657  if ((retval = nc_put_var_double(ncid, varid, t.get_c_array())))
658  nca_error(retval, "nc_put_var");
659  }
660  return fail;
661 }
662 
664 
671 void nca_error(const int e, const String s)
672 {
673  ostringstream os;
674  os << "NetCDF error: " << s << ", " << e;
675  throw runtime_error(os.str());
676 }
677 
678 
679 // We can't do the instantiation at the beginning of this file, because the
680 // implementation of nca_write_to_file and nca_read_from_file have to be known.
681 
682 #include "nc_io_instantiation.h"
683 
684 #endif /* ENABLE_NETCDF */
685 
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:35
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:521
void nca_filename(String &filename, const String &varname)
Gives the default filename for the NetCDF formats.
Definition: nc_io.cc:55
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:307
This file contains basic functions to handle NetCDF data files.
Index nelem() const
Number of elements.
Definition: array.h:176
Declarations having to do with the four output streams.
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:607
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:578
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackI.cc:1214
The Vector class.
Definition: matpackI.h:556
void nca_error(const int e, const String s)
Throws a runtime error for the given NetCDF error code.
Definition: nc_io.cc:671
String expand_path(const String &path)
Definition: file.cc:506
The Tensor4 class.
Definition: matpackIV.h:383
Index npages() const
Returns the number of pages.
Definition: matpackIV.cc:69
This file contains basic functions to handle ASCII files.
Index nrows() const
Returns the number of rows.
Definition: matpackIV.cc:75
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
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:361
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:180
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:434
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:651
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:454
The implementation for String, the ARTS string class.
Definition: mystring.h:63
void nca_read_from_file(const String &filename, T &type, const Verbosity &verbosity)
Reads a variable from a NetCDF file.
Definition: nc_io.cc:105
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:838
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackI.cc:542
The global header file for ARTS.
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:415
This file contains private function declarations and template instantiation to handle NetCDF data fil...
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:216
The declarations of all the exception classes.
A tag group can consist of the sum of several of these.
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:558
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:629
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:29
The Matrix class.
Definition: matpackI.h:788
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:151
void nca_def_dim(const int ncid, const String &name, const Index nelem, int *ncdim)
Define NetCDF dimension.
Definition: nc_io.cc:197
This can be used to make arrays out of anything.
Definition: array.h:40
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:379
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:234
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:480
void resize(Index n)
Assignment operator from VectorView.
Definition: matpackI.cc:798
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:76
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:258
String add_basedir(const String &path)
Definition: file.cc:530
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:282
Index nbooks() const
Returns the number of books.
Definition: matpackIV.cc:63
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:397
Index nc_get_dim(const int ncid, const String &name, const bool noerror)
Read a dimension from NetCDF file.
Definition: nc_io.cc:334
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:539
Index ncols() const
Returns the number of columns.
Definition: matpackIV.cc:81
#define CREATE_OUT2
Definition: messages.h:213
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:832
void resize(Index b, Index p, Index r, Index c)
Resize function.
Definition: matpackIV.cc:1403
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1580
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackIV.cc:402