MeteoIODoc  2.10.0
libsmet.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-or-later
2 /***********************************************************************************/
3 /* Copyright 2009 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 LIBSMET_H
20 #define LIBSMET_H
21 
22 #include <meteoio/FileUtils.h>
24 
25 #include <string>
26 #include <iostream>
27 #include <vector>
28 #include <set>
29 #include <map>
30 
31 #define SMET_STRINGIFY(x) #x
32 #define SMET_TOSTRING(x) SMET_STRINGIFY(x)
33 #define SMET_AT __FILE__ ":" SMET_TOSTRING(__LINE__)
34 
35 namespace smet {
36 
39 
45 class SMETException : public std::exception {
46  public:
47  SMETException(const std::string& message="SMETException occured", const std::string& position="");
48  const char* what() const noexcept;
49 
50  protected:
51  std::string msg;
52 };
53 
59 class SMETCommon {
60  public:
61  static bool validFileAndPath(const std::string& filename);
62  static void copy_file(const std::string& src, const std::string& dest);
63  static bool fileExists(const std::string& filename);
64  static std::string strToLower(std::string str);
65  static double convert_to_double(const std::string& in_string);
66  static int convert_to_int(const std::string& in_string);
67  static char convert_to_char(const std::string& in_string);
68  static void stripComments(std::string& str);
69  static char getEoln(std::istream& fin);
70  static void trim(std::string& str);
71  static void toUpper(std::string& str);
72  static bool readKeyValuePair(const std::string& in_line, const std::string& delimiter,
73  std::map<std::string,std::string>& out_map);
74  static size_t readLineToVec(const std::string& line_in, std::vector<std::string>& vecString);
75  static size_t readLineToVec(const std::string& line_in, std::vector<std::string>& vecString, const char& delim);
76  static bool is_decimal(const std::string& value);
77 
78  public:
79  static std::set<std::string> all_optional_header_keys;
80  static std::set<std::string> all_decimal_header_values;
81  static std::set<std::string> all_mandatory_header_keys;
82  static const char* smet_version;
83 
84  private:
85  static const bool __init;
86  static bool initStaticData();
87 };
88 
98 class SMETWriter {
99  public:
105  SMETWriter(const std::string& in_filename, const SMETType& in_type=ASCII);
106 
114  SMETWriter(const std::string& in_filename, const std::string& in_fields, const double& in_nodata);
115 
121  void set_header_value(const std::string& key, const std::string& value);
122 
128  void set_header_value(const std::string& key, const double& value);
129 
139  void write(const std::vector<std::string>& vec_timestamp, const std::vector<double>& data, const mio::ACDD& acdd);
140 
147  void write(const std::vector<double>& data, const mio::ACDD& acdd);
148 
155  void set_precision(const std::vector<int>& vec_precision);
156 
163  void set_width(const std::vector<int>& vec_width);
164 
172  void set_separator(const char& i_separator);
173 
179  void set_commented_headers(const bool& flag) {comment_headers=flag;}
180 
181  const std::string toString() const;
182 
183  private:
184  void setAppendMode(std::vector<std::string> vecFields);
185  void print_if_exists(const std::string& header_field, const std::string& prefix, std::ofstream& fout) const;
186  void printACDD(std::ofstream& fout, const std::string& prefix, const mio::ACDD& acdd) const;
187  void write_header(std::ofstream& fout, const mio::ACDD& acdd); //only writes when all necessary header values are set
188  void write_data_line_ascii(const std::string& timestamp, const std::vector<double>& data, std::ofstream& fout);
189  void write_data_line_binary(const std::vector<double>& data, std::ofstream& fout);
190  bool check_fields(const std::string& key, const std::string& value);
191  void check_formatting();
192  bool valid_header_pair(const std::string& key, const std::string& value);
193  bool valid_header();
194 
195  std::vector<std::string> other_header_keys; //this vector is used to preserve the sequence of header keys
196  std::vector<int> ascii_precision, ascii_width;
197  std::map< std::string, std::string > header;
198  std::set<std::string> mandatory_header_keys;
199 
200  std::string filename;
201  std::string nodata_string;
202  SMETType smet_type;
203  double nodata_value;
204  size_t nr_of_fields, julian_field, timestamp_field;
205  char location_wgs84, location_epsg;
206  char separator;
207  bool location_in_header, location_in_data_wgs84, location_in_data_epsg;
208  bool timestamp_present, julian_present;
209  bool file_is_binary, append_mode, append_possible, comment_headers;
210 };
211 
220 class SMETReader {
221  public:
222  friend class SMETWriter; //so the writer can call the reader for handling append mode
223 
228  SMETReader(const std::string& in_fname);
229 
238  void read(const std::string& timestamp_start, const std::string& timestamp_end,
239  std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data);
240 
248  void read(const double& julian_start, const double& julian_end, std::vector<double>& vec_data);
249 
255  void read(std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data);
256 
261  void read(std::vector<double>& vec_data);
262 
268  std::string get_header_value(const std::string& key) const;
269 
275  double get_header_doublevalue(const std::string& key) const;
276 
282  int get_header_intvalue(const std::string& key) const;
283 
288  bool contains_timestamp() const;
289 
295  std::string get_field_name(const size_t& nr_of_field);
296 
302  bool location_in_header(const LocationType& type) const;
303 
309  bool location_in_data(const LocationType& type) const;
310 
315  size_t get_nr_of_fields() const;
316 
325  void get_units_conversion(std::vector<double>& offset, std::vector<double>& multiplier) const;
326 
332  void convert_to_MKSA(const bool& in_mksa);
333 
338  std::string get_filename() const;
339 
340  private:
341  void truncate_file(const std::string& date_stop) const;
342  void copy_file_header(std::ifstream& fin, std::ofstream& fout) const;
343  void copy_file_data(const std::string& date_stop, std::ifstream& fin, std::ofstream& fout) const;
344  std::string getLastTimestamp() const;
345  void read_data_ascii(std::ifstream& fin, std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data);
346  void read_data_binary(std::ifstream& fin, std::vector<double>& vec_data);
347  void cleanup(std::ifstream& fin) noexcept;
348  void checkSignature(const std::vector<std::string>& vecSignature, bool& o_isAscii);
349  void read_header(std::ifstream& fin);
350  void process_header();
351 
352  std::streampos data_start_fpointer;
353 
354  std::vector<double> vec_offset; //an offset for every column, except timestamp
355  std::vector<double> vec_multiplier; //a multiplier for every column, except timestamp
356  std::vector<std::string> vec_fieldnames; //holds the column names, except for timestamp column
357  std::map< std::string, std::string > header; //holds the header
358  mio::FileUtils::FileIndexer indexer; //in order to save file pointers
359 
360  std::string filename;
361  std::string timestamp_start, timestamp_end; //the beginning and end date of the current timestamp_interval
362  double nodata_value; //The nodata value as seen in the header section of the SMET file
363  double julian_start, julian_end; //the beginning and end date of the current julian_interval
364  static const size_t streampos_every_n_lines; //save current stream pos every n lines of data
365  size_t nr_of_fields; //is always the number of fields minus the timestamp field, if present
366  size_t timestamp_field, julian_field; //index of the timestamp and julian column, if present
367  char location_wgs84, location_epsg, location_data_wgs84, location_data_epsg;
368  char eoln; //end of line character for this file
369  char separator; //column separator
370  bool timestamp_present, julian_present;
371  bool isAscii; //true if the file is in SMET ASCII format, false if it is in binary format
372  bool mksa; //true if MKSA converted values have to be returned
373  bool timestamp_interval, julian_interval; //true if data shall only be read for a time interval
374 };
375 
376 }
377 
378 #endif
This class contains and handles NetCDF Attribute Conventions Dataset Discovery attributes (see ACDD).
Definition: libacdd.h:98
Definition: FileUtils.h:133
A static class to provide basic operations and variables for the libsmet library.
Definition: libsmet.h:59
static std::string strToLower(std::string str)
Definition: libsmet.cc:154
static void toUpper(std::string &str)
Definition: libsmet.cc:237
static size_t readLineToVec(const std::string &line_in, std::vector< std::string > &vecString)
Definition: libsmet.cc:284
static char convert_to_char(const std::string &in_string)
Definition: libsmet.cc:180
static void copy_file(const std::string &src, const std::string &dest)
Definition: libsmet.cc:133
static int convert_to_int(const std::string &in_string)
Definition: libsmet.cc:171
static void stripComments(std::string &str)
Definition: libsmet.cc:229
static bool is_decimal(const std::string &value)
Definition: libsmet.cc:275
static bool readKeyValuePair(const std::string &in_line, const std::string &delimiter, std::map< std::string, std::string > &out_map)
Definition: libsmet.cc:204
static std::set< std::string > all_optional_header_keys
Definition: libsmet.h:79
static std::set< std::string > all_decimal_header_values
Definition: libsmet.h:80
static char getEoln(std::istream &fin)
Definition: libsmet.cc:242
static const char * smet_version
Definition: libsmet.h:82
static void trim(std::string &str)
Definition: libsmet.cc:189
static std::set< std::string > all_mandatory_header_keys
Definition: libsmet.h:81
static double convert_to_double(const std::string &in_string)
Definition: libsmet.cc:159
static bool fileExists(const std::string &filename)
Definition: libsmet.cc:102
static bool validFileAndPath(const std::string &filename)
Definition: libsmet.cc:117
A basic exception class adjusted for the needs of the SMET library.
Definition: libsmet.h:45
const char * what() const noexcept
Definition: libsmet.cc:50
std::string msg
Definition: libsmet.h:51
SMETException(const std::string &message="SMETException occured", const std::string &position="")
Definition: libsmet.cc:47
The SMETReader class enables to read a SMET formatted file. Data and header info can be extracted thr...
Definition: libsmet.h:220
void get_units_conversion(std::vector< double > &offset, std::vector< double > &multiplier) const
Get the unit conversion (offset and multiplier) that are used for this SMET object If the fields unit...
Definition: libsmet.cc:937
std::string get_filename() const
Retrieve the filename that this reader operates upon.
Definition: libsmet.cc:1594
bool location_in_data(const LocationType &type) const
Check whether location information is written in the data section.
Definition: libsmet.cc:954
size_t get_nr_of_fields() const
Get number of fields (=columns) in SMET file (timestamp excluded)
Definition: libsmet.cc:932
bool contains_timestamp() const
Check whether timestamp is a part of the fields.
Definition: libsmet.cc:1589
std::string get_field_name(const size_t &nr_of_field)
Get a name for a certain column in the SMET file.
Definition: libsmet.cc:920
int get_header_intvalue(const std::string &key) const
Get an int value for a header key in a SMET file.
Definition: libsmet.cc:1571
std::string get_header_value(const std::string &key) const
Get a string value for a header key in a SMET file.
Definition: libsmet.cc:1580
void convert_to_MKSA(const bool &in_mksa)
Set whether the values returned should be converted according to unit_offset and multiplier or whethe...
Definition: libsmet.cc:915
void read(const std::string &timestamp_start, const std::string &timestamp_end, std::vector< std::string > &vec_timestamp, std::vector< double > &vec_data)
Read the data in a SMET file for a given interval of time if no timestamp is present in the file,...
Definition: libsmet.cc:1222
bool location_in_header(const LocationType &type) const
Check whether location information is written in the header.
Definition: libsmet.cc:943
double get_header_doublevalue(const std::string &key) const
Get a double value for a header key in a SMET file.
Definition: libsmet.cc:1562
SMETReader(const std::string &in_fname)
A constructor that will immediately parse the header of the SMET file.
Definition: libsmet.cc:876
The SMETWriter class that enables to write a SMET formatted file. The user constructs a SMETWriter cl...
Definition: libsmet.h:98
void set_precision(const std::vector< int > &vec_precision)
Set precision for each field (except timestamp), otherwise a default precision of 3 is used for each ...
Definition: libsmet.cc:866
SMETWriter(const std::string &in_filename, const SMETType &in_type=ASCII)
The constructor allows to set the filename, the type and whether the file should be gzipped.
Definition: libsmet.cc:322
void set_width(const std::vector< int > &vec_width)
Set width for each field (except timestamp), otherwise a default width of 8 is used for each column.
Definition: libsmet.cc:851
void set_separator(const char &i_separator)
For some special cases (import into DB), the white space separator should be replaced by another one ...
Definition: libsmet.cc:856
const std::string toString() const
Definition: libsmet.cc:404
void set_header_value(const std::string &key, const std::string &value)
Set a key, value pair in the SMET header (both strings)
Definition: libsmet.cc:441
void set_commented_headers(const bool &flag)
For some special cases (import into DB), the headers should be commented out (please note that this b...
Definition: libsmet.h:179
void write(const std::vector< std::string > &vec_timestamp, const std::vector< double > &data, const mio::ACDD &acdd)
Write a SMET file, providing ASCII ISO formatted timestamps and data.
Definition: libsmet.cc:579
Definition: libsmet.cc:40
SMETType
Definition: libsmet.h:37
@ BINARY
Definition: libsmet.h:37
@ ASCII
Definition: libsmet.h:37
LocationType
Definition: libsmet.h:38
@ EPSG
Definition: libsmet.h:38
@ WGS84
Definition: libsmet.h:38