WSL/SLF GitLab Repository

NetCDFIO.h 11.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/***********************************************************************************/
/*  Copyright 2009 WSL Institute for Snow and Avalanche Research    SLF-DAVOS      */
/***********************************************************************************/
/* This file is part of MeteoIO.
    MeteoIO is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MeteoIO is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with MeteoIO.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __NetCDFIO_H__
#define __NetCDFIO_H__

#include <meteoio/IOInterface.h>
#include <meteoio/Config.h>
23
#include <meteoio/ResamplingAlgorithms2D.h>
24
#include <meteoio/meteostats/libinterpol1D.h>
25

26
#include <netcdf.h>
27
#include <string>
28
29
#include <cmath>
#include <cstdio>
30
#include <algorithm>
31
32
33
34
35

namespace mio {

/**
 * @class NetCDFIO
36
 * @brief This plug-in allows reading and writing of NetCDF files formatted according to CNRM standard.
37
38
39
40
41
42
43
 *
 * @ingroup plugins
 * @author Thomas Egger
 * @date   2014-03-13
 */
class NetCDFIO : public IOInterface {
	public:
44
45
		enum TimeUnit { seconds, hours, days };

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
		NetCDFIO(const std::string& configfile);
		NetCDFIO(const NetCDFIO&);
		NetCDFIO(const Config& cfgreader);
		~NetCDFIO() throw();

		virtual void read2DGrid(Grid2DObject& grid_out, const std::string& parameter="");
		virtual void read2DGrid(Grid2DObject& grid_out, const MeteoGrids::Parameters& parameter, const Date& date);
		virtual void readDEM(DEMObject& dem_out);
		virtual void readLanduse(Grid2DObject& landuse_out);

		virtual void readStationData(const Date& date, std::vector<StationData>& vecStation);
		virtual void readMeteoData(const Date& dateStart, const Date& dateEnd,
		                           std::vector< std::vector<MeteoData> >& vecMeteo,
		                           const size_t& stationindex=IOUtils::npos);

		virtual void writeMeteoData(const std::vector< std::vector<MeteoData> >& vecMeteo,
		                            const std::string& name="");

		virtual void readAssimilationData(const Date&, Grid2DObject& da_out);
		virtual void readPOI(std::vector<Coords>& pts);
		virtual void write2DGrid(const Grid2DObject& grid_in, const std::string& filename);
		virtual void write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameters& parameter, const Date& date);

	private:
70
		void parseInputOutputSection();
71
72
73
74
		void create_parameters(const int& ncid, const int& did_time, const int& did_points, const size_t& number_of_records,
		                       const size_t& number_of_stations, std::map<size_t, std::string>& map_param_name,
		                       std::map<std::string, double*>& map_data_2D, std::map<std::string, int>& varid);
		void create_meta_data(const int& ncid, const int& did, std::map<std::string, double*>& map_data_1D, std::map<std::string, int>& varid);
Thomas Egger's avatar
Thomas Egger committed
75
76
		void get_parameters(const std::vector< std::vector<MeteoData> >& vecMeteo, std::map<size_t, std::string>& map_param_name,
		                    std::map<std::string, double*>& map_data_1D, double*& dates);
77
		void get_parameters(const int& ncid, std::map<std::string, size_t>& map_parameters, MeteoData& meteo_data);
78
79
80
		size_t get_dates(const std::vector< std::vector<MeteoData> >& vecMeteo, double*& dates);
		void copy_data(const size_t& number_of_stations, const size_t& number_of_records, const std::vector< std::vector<MeteoData> >& vecMeteo,
                         const std::map<size_t, std::string>& map_param_name, std::map<std::string, double*>& map_data_2D);
81
		void copy_data(const int& ncid, const std::map<std::string, size_t>& map_parameters, const std::map<std::string, double*> map_data,
82
		               const size_t& number_of_stations, const size_t& number_of_records, std::vector< std::vector<MeteoData> >& vecMeteo);
83
84
		void readData(const int& ncid, const size_t& index_start, const std::vector<Date>& vec_date, const std::map<std::string, size_t>& map_parameters,
		              const MeteoData& meteo_data, std::vector< std::vector<MeteoData> >& vecMeteo);
85
		void readMetaData(const int& ncid, std::vector<StationData>& vecStation);
86
		void get_meta_data_ids(const int& ncid, std::map<std::string, int>& map_vid);
87
		std::string get_varname(const MeteoGrids::Parameters& parameter);
88
89
		void get_indices(const int& ncid, const Date& dateStart, const Date& dateEnd, size_t& indexStart, size_t& indexEnd, std::vector<Date>& vecDate);
		void calculate_offset(const std::string& units, NetCDFIO::TimeUnit& time_unit, Date& offset);
90
91
		void check_consistency(const int& ncid, const Grid2DObject& grid, double*& lat_array, double*& lon_array,
		                       int& did_lat, int& did_lon, int& vid_lat, int& vid_lon);
92
		void read2DGrid_internal(Grid2DObject& grid_out, const std::string& full_name, const std::string& varname, const Date& date=Date());
93
		void write2DGrid_internal(const Grid2DObject& grid_in, const std::string& filename, const std::string& varname, const Date& date=Date());
94
		void fill_data(const Grid2DObject& grid, double*& data);
95
96
97
98
		void copy_grid(const size_t& latlen, const size_t& lonlen, const double * const lat, const double * const lon,
		               const double * const grid, Grid2DObject& grid_out);
		double calculate_cellsize(const size_t& latlen, const size_t& lonlen, const double * const lat, const double * const lon,
		                          double& factor_x, double& factor_y);
99
100
101
102
103
		void calculate_dimensions(const Grid2DObject& grid, double*& lat_array, double*& lon_array);
		void add_attributes_for_variable(const int& ncid, const int& varid, const std::string& varname);
		void create_latlon_dimensions(const int& ncid, const Grid2DObject& grid, int& did_lat, int& did_lon, int& vid_lat, int& vid_lon);
		void create_time_dimension(const int& ncid, int& did_time, int& vid_time);

Thomas Egger's avatar
Thomas Egger committed
104

105
		/* libnetcdf wrappers */
Thomas Egger's avatar
Thomas Egger committed
106
107

		//Opening, creating, closing dataset
108
109
110
111
112
		static void open_file(const std::string& filename, const int& omode, int& ncid);
		static void create_file(const std::string& filename, const int& cmode, int& ncid);
		static void start_definitions(const std::string& filename, const int& ncid);
		static void end_definitions(const std::string& filename, const int& ncid);
		static void close_file(const std::string& filename, const int& ncid);
Thomas Egger's avatar
Thomas Egger committed
113
114

		//Adding variables
115
116
117
118
		static void add_0D_variable(const int& ncid, const std::string& varname, const nc_type& xtype, int& varid);
		static void add_1D_variable(const int& ncid, const std::string& varname, const nc_type& xtype, const int& dimid, int& varid);
		static void add_2D_variable(const int& ncid, const std::string& varname, const nc_type& xtype, const int& dimid1, const int& dimid2, int& varid);
		static void add_3D_variable(const int& ncid, const std::string& varname, const nc_type& xtype, const int& dimid_record,
Thomas Egger's avatar
Thomas Egger committed
119
120
121
		                     const int& dimid1, const int& dimid2, int& varid);

		//Adding attributes
122
123
124
		static void add_attribute(const int& ncid, const int& varid, const std::string& attr_name, const std::string& attr_value);
		static void add_attribute(const int& ncid, const int& varid, const std::string& attr_name, const double& attr_value);
		static void get_attribute(const int& ncid, const std::string& varname, const int& varid, const std::string& attr_name, std::string& attr_value);
125
126

		//Adding dimensions
127
		static void add_dimension(const int& ncid, const std::string& dimname, const size_t& length, int& dimid);
128
129
130


		//Reading data from NetCDF file
131
		static void read_data(const int& ncid, const std::string& varname, const int& varid,
132
		               const size_t& pos, const size_t& latlen, const size_t& lonlen, double*& data);
133
		static void read_data_2D(const int& ncid, const std::string& varname, const int& varid,
134
		                  const size_t& record, const size_t& count, const size_t& length, double*& data);
135
136
137
		static void read_value(const int& ncid, const std::string& varname, const int& varid, double& data);
		static void read_value(const int& ncid, const std::string& varname, const int& varid, const size_t& pos, double& data);
		static void read_data(const int& ncid, const std::string& varname, const int& varid, double*& data);
138
139

		//Writing data to NetCDF file
140
141
		static void write_data(const int& ncid, const std::string& varname, const int& varid, const double * const data);
		static void write_data(const int& ncid, const std::string& varname, const int& varid, const Grid2DObject& grid,
142
		                const size_t& pos_start, const double * const data);
143
144

		//Dealing with variables that have dimension NC_UNLIMITED
145
146
147
		static size_t find_record(const int& ncid, const std::string& varname, const int& varid, const double& data);
		static size_t add_record(const int& ncid, const std::string& varname, const int& varid, const double& data);
		static void write_record(const int& ncid, const std::string& varname, const int& varid, const size_t& pos,
148
		                  const size_t& length, const double * const data);
Thomas Egger's avatar
Thomas Egger committed
149

150
		//Dealing with variables and dimensions
151
152
153
154
155
156
157
		static bool check_dim_var(const int& ncid, const std::string& dimname);
		static bool check_variable(const int& ncid, const std::string& varname);
		static void get_variable(const int& ncid, const std::string& varname, int& varid);
		static void check_dimensions(const int& ncid, const std::string& varname, const int& varid, const std::vector<std::string>& names);
		static void get_dimension(const int& ncid, const std::string& dimname, int& dimid);
		static void get_dimension(const int& ncid, const std::string& dimname, int& dimid, size_t& dimlen);
		static void get_dimension(const int& ncid, const std::string& varname, const int& varid,
158
		                   std::vector<int>& dimid, std::vector<int>& dim_varid, std::vector<std::string>& dimname, std::vector<size_t>& dimlen);
Thomas Egger's avatar
Thomas Egger committed
159

160

Thomas Egger's avatar
Thomas Egger committed
161
		// Private variables
162
		static const double plugin_nodata; //plugin specific nodata value, e.g. -999
163
		static const std::string cf_time, cf_units, cf_days, cf_seconds, cf_latitude, cf_longitude, cf_altitude, cf_ta, cf_rh, cf_p;
164
		static const std::string cnrm_points, cnrm_latitude, cnrm_longitude, cnrm_altitude, cnrm_aspect, cnrm_slope, cnrm_ta, cnrm_rh, cnrm_vw, cnrm_dw, cnrm_qair;
Thomas Egger's avatar
Thomas Egger committed
165
		static const std::string cnrm_co2air, cnrm_theorsw, cnrm_neb, cnrm_hnw, cnrm_snowf, cnrm_swr_direct, cnrm_swr_diffuse, cnrm_p, cnrm_ilwr, cnrm_timestep;
166

167
		static std::map<std::string, size_t> paramname; ///<Associate a name with meteo parameters in Parameters
168
		static std::map<std::string, std::string> map_name; ///Associate MeteoIO parameter names with CNRM parameter names
169
170
171
		static const bool __init;    ///<helper variable to enable the init of static collection data
		static bool initStaticData();///<initialize the static map

Thomas Egger's avatar
Thomas Egger committed
172
		const Config cfg;
173
		std::string coordin, coordinparam, coordout, coordoutparam; //projection parameters
174
		double in_dflt_TZ, out_dflt_TZ;     //default time zones
175
		bool in_strict, out_strict;
176
		std::vector<StationData> vecMetaData;
177
178
179
180
};

} //namespace
#endif