MeteoIODoc  2.10.0
libncpp.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-or-later
2 /***********************************************************************************/
3 /* Copyright 2018 WSL Institute for Snow and Avalanche Research SLF-DAVOS */
4 /***********************************************************************************/
5 /* This file is part of MeteoIO.
6  MeteoIO is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  MeteoIO is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with MeteoIO. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef LIBNCPP_H
20 #define LIBNCPP_H
21 
24 #include <meteoio/IOUtils.h>
25 #include <meteoio/Config.h>
27 
28 #include <string>
29 #include <vector>
30 
31 namespace ncpp {
34 
35  //These methods are needed by the structures defined below
36  std::string getParameterName(const size_t& param);
37  std::string getParameterDescription(const size_t& param);
38  std::string getParameterUnits(const size_t& param);
39  size_t getParameterIndex(const std::string& param);
40 
42  typedef struct VAR_ATTR {
43  VAR_ATTR() : name(), standard_name(), long_name(), units(), height(mio::IOUtils::nodata), param(mio::IOUtils::npos), type(-1) {} //please do NOT use this constructor!
44  VAR_ATTR(const int& i_type) : name(), standard_name(), long_name(), units(), height(mio::IOUtils::nodata), param(mio::IOUtils::npos), type(i_type) {}
45  VAR_ATTR(const std::string& i_name, const int& i_type) : name(i_name), standard_name(), long_name(), units(), height(mio::IOUtils::nodata), param(mio::IOUtils::npos), type(i_type) {}
46  VAR_ATTR(const size_t& prm, const std::string& i_name, const double& hgt, const int& i_type)
47  : name(i_name), standard_name(), long_name(), units(), height(hgt), param(prm), type(i_type) {}
48  VAR_ATTR(const size_t& prm, const std::string& i_name, const std::string& std_name, const std::string& lg_name, const std::string& i_units, const double& hgt, const int& i_type)
49  : name(i_name), standard_name(std_name), long_name(lg_name), units(i_units), height(hgt), param(prm), type(i_type) {}
50 
51  bool isUndef() const {return (type==-1);}
52  std::string toString() const {std::ostringstream os; os << "[" << ((param<=ncpp::lastdimension)? getParameterName(param) : "Unknown") << " - " << name << " / " << standard_name << " / " << long_name << " , in " << units << " @ " << height << ", type=" << type << "]"; return os.str();}
53 
54  std::string name;
55  std::string standard_name;
56  std::string long_name;
57  std::string units;
58  double height;
59  size_t param;
60  int type;
61  } var_attr;
62 
64  typedef struct NC_VARIABLE {
65  NC_VARIABLE() : attributes(), dimids(), dimid_time(0.), dimid_X(0.), dimid_Y(0.), scale(1.), offset(0.), nodata(mio::IOUtils::nodata), varid(-1) {} //please do NOT use this constructor!
66  NC_VARIABLE(const int& i_type) : attributes(i_type), dimids(), dimid_time(0.), dimid_X(0.), dimid_Y(0.), scale(1.), offset(0.), nodata(mio::IOUtils::nodata), varid(-1) {}
67  NC_VARIABLE(const var_attr& attr, const double& i_nodata)
68  : attributes(attr), dimids(), dimid_time(0.), dimid_X(0.), dimid_Y(0.), scale(1.), offset(0.), nodata(i_nodata), varid(-1) {}
69  NC_VARIABLE(const var_attr& attr, const size_t& i_dimid_time, const size_t& i_dimid_X, const size_t& i_dimid_Y, const double& i_scale, const double& i_offset, const double& i_nodata, const int& i_varid)
70  : attributes(attr), dimids(), dimid_time(i_dimid_time), dimid_X(i_dimid_X), dimid_Y(i_dimid_Y), scale(i_scale), offset(i_offset), nodata(i_nodata), varid(i_varid) {}
71 
72  bool isUndef() const {return (attributes.isUndef());}
73  std::string toString() const {std::ostringstream os; os << "[" << varid << " - " << "\"" << attributes.name << "\" - packing( *" << scale << ", +" << offset << "), nodata=" << nodata << " - depends on ("; for(size_t ii=0; ii<dimids.size(); ii++) os << " " << dimids[ii]; os << ") ]"; return os.str();}
74 
76  std::vector<int> dimids;
77  // Store the sequence in which dimensions vary:
78  size_t dimid_time;
79  size_t dimid_X;
80  size_t dimid_Y;
81  double scale, offset, nodata;
82  int varid;
83  } nc_variable;
84 
86  typedef struct NC_DIMENSION {
87  NC_DIMENSION() : name(), length(0), dimid(-1), param(mio::IOUtils::npos), isUnlimited(false) {}
88  NC_DIMENSION(const size_t& i_param, const std::string& i_name)
89  : name(i_name), length(0), dimid(-1), param(i_param), isUnlimited(false) {}
90  NC_DIMENSION(const size_t& i_param, const std::string& i_name, const size_t& len, const int& i_dimid, const bool& unlimited)
91  : name(i_name), length(len), dimid(i_dimid), param(i_param), isUnlimited(unlimited) {}
92  std::string toString() const {std::ostringstream os; os << getParameterName(param) << " -> [ " << dimid << " - " << name << ", length " << length; if (isUnlimited) os << ", unlimited"; os << "]"; return os.str();}
93 
94  std::string name;
95  size_t length;
96  int dimid;
97  size_t param;
98  bool isUnlimited;
99  } nc_dimension;
100 
101  void open_file(const std::string& filename, const int& omode, int& ncid);
102  void create_file(const std::string& filename, const int& cmode, int& ncid);
103  void file_redef(const std::string& filename, const int& ncid);
104  void create_variable(const int& ncid, ncpp::nc_variable& var);
105  void end_definitions(const std::string& filename, const int& ncid);
106  void close_file(const std::string& filename, const int& ncid);
107 
108  void add_attribute(const int& ncid, const int& varid, const std::string& attr_name, const double& attr_value);
109  void add_attribute(const int& ncid, const int& varid, const std::string& attr_name, const float& attr_value);
110  void add_attribute(const int& ncid, const int& varid, const std::string& attr_name, const int& attr_value);
111  void add_attribute(const int& ncid, const int& varid, const std::string& attr_name, const double& attr_value, const int& data_type);
112  void add_attribute(const int& ncid, const int& varid, const std::string& attr_name, const std::string& attr_value);
113  void writeACDDAttributes(const int& ncid, const mio::ACDD& acdd);
114  bool check_attribute(const int& ncid, const int& varid, const std::string& attr_name);
115  void getGlobalAttribute(const int& ncid, const std::string& attr_name, std::string& attr_value);
116  void getGlobalAttribute(const int& ncid, const std::string& attr_name, int& attr_value);
117  void getAttribute(const int& ncid, const nc_variable& var, const std::string& attr_name, std::string& attr_value);
118  void getAttribute(const int& ncid, const nc_variable& var, const std::string& attr_name, double& attr_value);
119 
120  void read_data(const int& ncid, const nc_variable& var, const size_t& pos, const size_t& nrows, const size_t& ncols, const size_t& pos_i, const size_t& row_i, const size_t& col_i, double* data);
121  void read_data_point(const int& ncid, const nc_variable& var, const size_t& row, const size_t& col, const size_t& row_i, const size_t& col_i, double* data);
122  void read_data_point(const int& ncid, const nc_variable& var, const size_t& pos, const size_t& row, const size_t& col, const size_t& pos_i, const size_t& row_i, const size_t& col_i, double* data);
123  void read_data(const int& ncid, const nc_variable& var, double* data);
124  void read_data(const int& ncid, const nc_variable& var, int* data);
125  void readVariableMetadata(const int& ncid, ncpp::nc_variable& var, const bool& readTimeTransform=false, const double& TZ=0.);
126  void write_data(const int& ncid, const nc_variable& var, const size_t& pos, const size_t& nrows, const size_t& ncols, const double * const data);
127  void write_1Ddata(const int& ncid, const nc_variable& var, const std::vector<double>& data, const bool& isUnlimited=false);
128  void write_1Ddata(const int& ncid, const nc_variable& var, const std::vector<std::string>& data, const int& strMaxLen);
129 
130  void fill2DGrid(mio::Grid2DObject& grid, const double data[], const double& nodata, const bool& normal_Xorder=true, const bool& normal_Yorder=true);
131  void getTimeTransform(const std::string& time_units, const double& i_TZ, double &o_time_offset, double &o_time_multiplier);
132  void createDimension(const int& ncid, nc_dimension& dimension, const size_t& length);
133  std::string generateHistoryAttribute();
134 } // end namespace
135 
143 //TODO: redo the whole user_schema thing: we should fill vars / dimensions with the schema, then add/overwrite with the user schema
144 class NC_SCHEMA {
145  public:
146  NC_SCHEMA(const mio::Config& cfg, const std::string& schema);
147 
148  void initFromSchema(std::map<size_t, ncpp::nc_variable> &vars, std::map<size_t, ncpp::nc_dimension> &dimensions_map);
149  const ncpp::var_attr getSchemaAttributes(const std::string& var) const;
150  const ncpp::var_attr getSchemaAttributes(const size_t& param) const;
151  const ncpp::nc_dimension getSchemaDimension(const std::string& dimname) const;
152 
153  private:
154  static std::map< std::string, std::vector<ncpp::var_attr> > initSchemasVars();
155  static std::map< std::string, std::vector<ncpp::nc_dimension> > initSchemasDims();
156  static std::vector<ncpp::var_attr> initUserSchemas(const mio::Config& i_cfg);
157  static std::vector<ncpp::nc_dimension> initUserDimensions(const mio::Config& i_cfg);
158  void initSchemaCst(const std::string& schema);
159 
160  static std::map< std::string, std::vector<ncpp::var_attr> > schemas_vars;
161  static std::map< std::string, std::vector<ncpp::nc_dimension> > schemas_dims;
162 
163  std::vector<ncpp::var_attr> user_schemas;
164  std::vector<ncpp::nc_dimension> user_dimensions;
165 
166  public:
167  std::string name;
168  double nodata;
169  int dflt_type;
171 };
172 
173 #endif
This class contains and handles NetCDF schemas.
Definition: libncpp.h:144
bool force_station_dimension
force writing a station dimension even if only one station is present
Definition: libncpp.h:170
NC_SCHEMA(const mio::Config &cfg, const std::string &schema)
Definition: libncpp.cc:693
std::string name
name of the current schema
Definition: libncpp.h:167
const ncpp::nc_dimension getSchemaDimension(const std::string &dimname) const
Definition: libncpp.cc:1068
double nodata
nodata value as defined in the schema
Definition: libncpp.h:168
const ncpp::var_attr getSchemaAttributes(const std::string &var) const
Definition: libncpp.cc:1032
void initFromSchema(std::map< size_t, ncpp::nc_variable > &vars, std::map< size_t, ncpp::nc_dimension > &dimensions_map)
Definition: libncpp.cc:1019
int dflt_type
default data type as defined in the schema
Definition: libncpp.h:169
This class contains and handles NetCDF Attribute Conventions Dataset Discovery attributes (see ACDD).
Definition: libacdd.h:98
A class that reads a key/value file. These files (typically named *.ini) follow the INI file format s...
Definition: Config.h:79
A class to represent 2D Grids. Typical application as DEM or Landuse Model.
Definition: Grid2DObject.h:42
@ lastparam
Definition: MeteoData.h:83
const size_t npos
npos is the out-of-range value
Definition: IOUtils.h:80
const double nodata
This is the internal nodata value.
Definition: IOUtils.h:75
Definition: Config.cc:30
Definition: libncpp.cc:38
void getGlobalAttribute(const int &ncid, const std::string &attr_name, std::string &attr_value)
Read a given global attribute (if not found, an empty string is returned)
Definition: libncpp.cc:504
void create_variable(const int &ncid, ncpp::nc_variable &var)
Write a pre-defined set of attributes for the given variable.
Definition: libncpp.cc:190
void fill2DGrid(mio::Grid2DObject &grid, const double data[], const double &nodata, const bool &normal_Xorder, const bool &normal_Yorder)
Fill a Grid2DObject with 2D gridded data as read from a NetCDF file.
Definition: libncpp.cc:599
void getTimeTransform(const std::string &time_units, const double &i_TZ, double &o_time_offset, double &o_time_divisor)
Parse a time unit specification.
Definition: libncpp.cc:538
Dimensions
This enum expands the parameters given in mio::MeteoGrids::Parameters and adds parameters used as dim...
Definition: libncpp.h:33
@ STATION
Definition: libncpp.h:33
@ firstdimension
Definition: libncpp.h:33
@ NORTHING
Definition: libncpp.h:33
@ ZREF
Definition: libncpp.h:33
@ LONGITUDE
Definition: libncpp.h:33
@ LATITUDE
Definition: libncpp.h:33
@ lastdimension
Definition: libncpp.h:33
@ TIME
Definition: libncpp.h:33
@ DATESTRLEN
Definition: libncpp.h:33
@ NONE
Definition: libncpp.h:33
@ UREF
Definition: libncpp.h:33
@ EASTING
Definition: libncpp.h:33
@ STATSTRLEN
Definition: libncpp.h:33
void add_attribute(const int &ncid, const int &varid, const std::string &attr_name, const double &attr_value, const int &data_type)
Add an attribute to the file pointed to by ncid.
Definition: libncpp.cc:82
void read_data(const int &ncid, const nc_variable &var, const size_t &pos, const size_t &nrows, const size_t &ncols, const size_t &pos_i, const size_t &row_i, const size_t &col_i, double *data)
Read 2D gridded data at the provided time position for a specific variable.
Definition: libncpp.cc:257
void close_file(const std::string &filename, const int &ncid)
Definition: libncpp.cc:237
void open_file(const std::string &filename, const int &omode, int &ncid)
Definition: libncpp.cc:59
void read_data_point(const int &ncid, const nc_variable &var, const size_t &row, const size_t &col, const size_t &row_i, const size_t &col_i, double *data)
Read grid point in 2D gridded data for non time dependent data.
Definition: libncpp.cc:288
void create_file(const std::string &filename, const int &cmode, int &ncid)
Definition: libncpp.cc:66
void writeACDDAttributes(const int &ncid, const mio::ACDD &acdd)
Add all the ACDD attributes contained in the acdd object to the file pointed to by ncid.
Definition: libncpp.cc:130
void write_data(const int &ncid, const nc_variable &var, const size_t &pos, const size_t &nrows, const size_t &ncols, const double *const data)
Write 2D gridded data at the provided time position for a specific variable.
Definition: libncpp.cc:399
std::string getParameterDescription(const size_t &param)
Definition: libncpp.cc:648
void readVariableMetadata(const int &ncid, ncpp::nc_variable &var, const bool &readTimeTransform, const double &TZ)
Read a pre-defined set of attributes for the given variable, from the provided file.
Definition: libncpp.cc:363
void file_redef(const std::string &filename, const int &ncid)
Re-open the file in "definition" mode.
Definition: libncpp.cc:222
std::string getParameterUnits(const size_t &param)
Definition: libncpp.cc:654
std::string generateHistoryAttribute()
Build a CF-1 history string (date of creation, creator, software version)
Definition: libncpp.cc:679
bool check_attribute(const int &ncid, const int &varid, const std::string &attr_name)
Check if a variable has a given attribute.
Definition: libncpp.cc:148
void write_1Ddata(const int &ncid, const nc_variable &var, const std::vector< double > &data, const bool &isUnlimited)
Write a vector of data for a given 1D variable.
Definition: libncpp.cc:426
void getAttribute(const int &ncid, const nc_variable &var, const std::string &attr_name, std::string &attr_value)
Read a given attribute from a variable (if not found, an empty string is returned)
Definition: libncpp.cc:466
size_t getParameterIndex(const std::string &param)
Given a parameter name, return its associated index.
Definition: libncpp.cc:666
std::string getParameterName(const size_t &param)
Given a parameter index, return its associated name.
Definition: libncpp.cc:635
void createDimension(const int &ncid, ncpp::nc_dimension &dimension, const size_t &length)
Create a new dimension.
Definition: libncpp.cc:576
void end_definitions(const std::string &filename, const int &ncid)
Definition: libncpp.cc:229
Definition: libncpp.h:86
NC_DIMENSION(const size_t &i_param, const std::string &i_name, const size_t &len, const int &i_dimid, const bool &unlimited)
Definition: libncpp.h:90
size_t param
parameter index (from Dimensions or MeteoGrids::Parameters)
Definition: libncpp.h:97
NC_DIMENSION()
Definition: libncpp.h:87
bool isUnlimited
at most, one dimension can be "unlimited"
Definition: libncpp.h:98
std::string toString() const
Definition: libncpp.h:92
std::string name
dimension name
Definition: libncpp.h:94
int dimid
dimension ID, set to -1 and then to a positive value after reading/writing to/from a file
Definition: libncpp.h:96
NC_DIMENSION(const size_t &i_param, const std::string &i_name)
Definition: libncpp.h:88
size_t length
dimension length (irrelevant when the dimension is "unlimited")
Definition: libncpp.h:95
Definition: libncpp.h:64
NC_VARIABLE(const var_attr &attr, const size_t &i_dimid_time, const size_t &i_dimid_X, const size_t &i_dimid_Y, const double &i_scale, const double &i_offset, const double &i_nodata, const int &i_varid)
Definition: libncpp.h:69
double nodata
scale and offset for data packing, nodata value
Definition: libncpp.h:81
NC_VARIABLE(const var_attr &attr, const double &i_nodata)
Definition: libncpp.h:67
var_attr attributes
metadata about the variable
Definition: libncpp.h:75
bool isUndef() const
Definition: libncpp.h:72
int varid
variable ID, set to -1 and then to a positive value after reading/writing to/from a file
Definition: libncpp.h:82
std::string toString() const
Definition: libncpp.h:73
NC_VARIABLE(const int &i_type)
Definition: libncpp.h:66
std::vector< int > dimids
dimensions this variable depends on
Definition: libncpp.h:76
size_t dimid_X
dimension sequence for longitude/easting
Definition: libncpp.h:79
size_t dimid_Y
dimension sequence for latitude/northing
Definition: libncpp.h:80
size_t dimid_time
dimension sequence for time variable
Definition: libncpp.h:78
NC_VARIABLE()
Definition: libncpp.h:65
Definition: libncpp.h:42
std::string name
variable name (it is possible to retrieve a variable by name)
Definition: libncpp.h:54
std::string toString() const
Definition: libncpp.h:52
VAR_ATTR(const std::string &i_name, const int &i_type)
Definition: libncpp.h:45
int type
contain NetCDF External Data Types, -1 for "none"
Definition: libncpp.h:60
bool isUndef() const
Definition: libncpp.h:51
VAR_ATTR()
Definition: libncpp.h:43
std::string units
unit string representation
Definition: libncpp.h:57
size_t param
parameter index (from Dimensions or MeteoGrids::Parameters)
Definition: libncpp.h:59
std::string long_name
non-standard but often present, longer description of the variable
Definition: libncpp.h:56
VAR_ATTR(const size_t &prm, const std::string &i_name, const std::string &std_name, const std::string &lg_name, const std::string &i_units, const double &hgt, const int &i_type)
Definition: libncpp.h:48
VAR_ATTR(const size_t &prm, const std::string &i_name, const double &hgt, const int &i_type)
Definition: libncpp.h:46
double height
sensor height (currently unused)
Definition: libncpp.h:58
VAR_ATTR(const int &i_type)
Definition: libncpp.h:44
std::string standard_name
somehow human-friendly, standardized description of the name
Definition: libncpp.h:55