MeteoIODoc 20240502.aefd3c94
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>
23#include <meteoio/FStream.h>
25
26#include <string>
27#include <iostream>
28#include <vector>
29#include <set>
30#include <map>
31
32#define SMET_STRINGIFY(x) #x
33#define SMET_TOSTRING(x) SMET_STRINGIFY(x)
34#define SMET_AT __FILE__ ":" SMET_TOSTRING(__LINE__)
35
36namespace smet {
37
40
46class SMETException : public std::exception {
47 public:
48 SMETException(const std::string& message="SMETException occured", const std::string& position="");
49 const char* what() const noexcept;
50
51 protected:
52 std::string msg;
53};
54
61 public:
62 static bool validFileAndPath(const std::string& filename);
63 static void copy_file(const std::string& src, const std::string& dest);
64 static bool fileExists(const std::string& filename);
65 static std::string strToLower(std::string str);
66 static double convert_to_double(const std::string& in_string);
67 static int convert_to_int(const std::string& in_string);
68 static char convert_to_char(const std::string& in_string);
69 static void stripComments(std::string& str);
70 static char getEoln(std::istream& fin);
71 static void trim(std::string& str);
72 static void toUpper(std::string& str);
73 static bool readKeyValuePair(const std::string& in_line, const std::string& delimiter,
74 std::map<std::string,std::string>& out_map);
75 static size_t readLineToVec(const std::string& line_in, std::vector<std::string>& vecString);
76 static size_t readLineToVec(const std::string& line_in, std::vector<std::string>& vecString, const char& delim);
77 static bool is_decimal(const std::string& value);
78
79 public:
80 static std::set<std::string> all_optional_header_keys;
81 static std::set<std::string> all_decimal_header_values;
82 static std::set<std::string> all_mandatory_header_keys;
83 static const char* smet_version;
84
85 private:
86 static const bool __init;
87 static bool initStaticData();
88};
89
100 public:
106 SMETWriter(const std::string& in_filename, const SMETType& in_type=ASCII);
107
115 SMETWriter(const std::string& in_filename, const std::string& in_fields, const double& in_nodata);
116
122 void set_header_value(const std::string& key, const std::string& value);
123
129 void set_header_value(const std::string& key, const double& value);
130
140 void write(const std::vector<std::string>& vec_timestamp, const std::vector<double>& data, const mio::ACDD& acdd);
141
148 void write(const std::vector<double>& data, const mio::ACDD& acdd);
149
156 void set_precision(const std::vector<int>& vec_precision);
157
164 void set_width(const std::vector<int>& vec_width);
165
173 void set_separator(const char& i_separator);
174
180 void set_commented_headers(const bool& flag) {comment_headers=flag;}
181
182 const std::string toString() const;
183
184 private:
185 void setAppendMode(std::vector<std::string> vecFields);
186 void print_if_exists(const std::string& header_field, const std::string& prefix, mio::ofilestream& fout) const;
187 void printACDD(mio::ofilestream& fout, const std::string& prefix, const mio::ACDD& acdd) const;
188 void write_header(mio::ofilestream& fout, const mio::ACDD& acdd); //only writes when all necessary header values are set
189 void write_data_line_ascii(const std::string& timestamp, const std::vector<double>& data, mio::ofilestream& fout);
190 void write_data_line_binary(const std::vector<double>& data, mio::ofilestream& fout);
191 bool check_fields(const std::string& key, const std::string& value);
192 void check_formatting();
193 bool valid_header_pair(const std::string& key, const std::string& value);
194 bool valid_header();
195
196 std::vector<std::string> other_header_keys; //this vector is used to preserve the sequence of header keys
197 std::vector<int> ascii_precision, ascii_width;
198 std::map< std::string, std::string > header;
199 std::set<std::string> mandatory_header_keys;
200
201 std::string filename;
202 std::string nodata_string;
203 SMETType smet_type;
204 double nodata_value;
205 size_t nr_of_fields, julian_field, timestamp_field;
206 char location_wgs84, location_epsg;
207 char separator;
208 bool location_in_header, location_in_data_wgs84, location_in_data_epsg;
209 bool timestamp_present, julian_present;
210 bool file_is_binary, append_mode, append_possible, comment_headers;
211};
212
222 public:
223 friend class SMETWriter; //so the writer can call the reader for handling append mode
224
229 SMETReader(const std::string& in_fname);
230
239 void read(const std::string& timestamp_start, const std::string& timestamp_end,
240 std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data);
241
249 void read(const double& julian_start, const double& julian_end, std::vector<double>& vec_data);
250
256 void read(std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data);
257
262 void read(std::vector<double>& vec_data);
263
269 std::string get_header_value(const std::string& key) const;
270
276 double get_header_doublevalue(const std::string& key) const;
277
283 int get_header_intvalue(const std::string& key) const;
284
289 bool contains_timestamp() const;
290
296 std::string get_field_name(const size_t& nr_of_field);
297
303 bool location_in_header(const LocationType& type) const;
304
310 bool location_in_data(const LocationType& type) const;
311
316 size_t get_nr_of_fields() const;
317
326 void get_units_conversion(std::vector<double>& offset, std::vector<double>& multiplier) const;
327
333 void convert_to_MKSA(const bool& in_mksa);
334
339 std::string get_filename() const;
340
341 private:
342 void truncate_file(const std::string& date_stop) const;
343 void copy_file_header(std::ifstream& fin, mio::ofilestream& fout) const;
344 void copy_file_data(const std::string& date_stop, std::ifstream& fin, mio::ofilestream& fout) const;
345 std::string getLastTimestamp() const;
346 void read_data_ascii(std::ifstream& fin, std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data);
347 void read_data_binary(std::ifstream& fin, std::vector<double>& vec_data);
348 void cleanup(std::ifstream& fin) noexcept;
349 void checkSignature(const std::vector<std::string>& vecSignature, bool& o_isAscii);
350 void read_header(std::ifstream& fin);
351 void process_header();
352
353 std::streampos data_start_fpointer;
354
355 std::vector<double> vec_offset; //an offset for every column, except timestamp
356 std::vector<double> vec_multiplier; //a multiplier for every column, except timestamp
357 std::vector<std::string> vec_fieldnames; //holds the column names, except for timestamp column
358 std::map< std::string, std::string > header; //holds the header
359 mio::FileUtils::FileIndexer indexer; //in order to save file pointers
360
361 std::string filename;
362 std::string timestamp_start, timestamp_end; //the beginning and end date of the current timestamp_interval
363 double nodata_value; //The nodata value as seen in the header section of the SMET file
364 double julian_start, julian_end; //the beginning and end date of the current julian_interval
365 static const size_t streampos_every_n_lines; //save current stream pos every n lines of data
366 size_t nr_of_fields; //is always the number of fields minus the timestamp field, if present
367 size_t timestamp_field, julian_field; //index of the timestamp and julian column, if present
368 char location_wgs84, location_epsg, location_data_wgs84, location_data_epsg;
369 char eoln; //end of line character for this file
370 char separator; //column separator
371 bool timestamp_present, julian_present;
372 bool isAscii; //true if the file is in SMET ASCII format, false if it is in binary format
373 bool mksa; //true if MKSA converted values have to be returned
374 bool timestamp_interval, julian_interval; //true if data shall only be read for a time interval
375};
376
377}
378
379#endif
This class contains and handles NetCDF Attribute Conventions Dataset Discovery attributes (see ACDD).
Definition: libacdd.h:113
Definition: FileUtils.h:150
A class that extends std::ofstream, adding some output functionality. Limiting the write access of th...
Definition: FStream.h:37
A static class to provide basic operations and variables for the libsmet library.
Definition: libsmet.h:60
static std::string strToLower(std::string str)
Definition: libsmet.cc:154
static void toUpper(std::string &str)
Definition: libsmet.cc:249
static size_t readLineToVec(const std::string &line_in, std::vector< std::string > &vecString)
Definition: libsmet.cc:296
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:287
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:80
static std::set< std::string > all_decimal_header_values
Definition: libsmet.h:81
static char getEoln(std::istream &fin)
Definition: libsmet.cc:254
static const char * smet_version
Definition: libsmet.h:83
static void trim(std::string &str)
Definition: libsmet.cc:189
static std::set< std::string > all_mandatory_header_keys
Definition: libsmet.h:82
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:46
const char * what() const noexcept
Definition: libsmet.cc:50
std::string msg
Definition: libsmet.h:52
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:221
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:948
std::string get_filename() const
Retrieve the filename that this reader operates upon.
Definition: libsmet.cc:1605
bool location_in_data(const LocationType &type) const
Check whether location information is written in the data section.
Definition: libsmet.cc:965
size_t get_nr_of_fields() const
Get number of fields (=columns) in SMET file (timestamp excluded)
Definition: libsmet.cc:943
bool contains_timestamp() const
Check whether timestamp is a part of the fields.
Definition: libsmet.cc:1600
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:931
int get_header_intvalue(const std::string &key) const
Get an int value for a header key in a SMET file.
Definition: libsmet.cc:1582
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:1591
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:926
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:1233
bool location_in_header(const LocationType &type) const
Check whether location information is written in the header.
Definition: libsmet.cc:954
double get_header_doublevalue(const std::string &key) const
Get a double value for a header key in a SMET file.
Definition: libsmet.cc:1573
SMETReader(const std::string &in_fname)
A constructor that will immediately parse the header of the SMET file.
Definition: libsmet.cc:887
The SMETWriter class that enables to write a SMET formatted file. The user constructs a SMETWriter cl...
Definition: libsmet.h:99
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:877
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:334
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:862
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:867
const std::string toString() const
Definition: libsmet.cc:416
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:453
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:180
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:591
Definition: libsmet.cc:40
SMETType
Definition: libsmet.h:38
@ BINARY
Definition: libsmet.h:38
@ ASCII
Definition: libsmet.h:38
LocationType
Definition: libsmet.h:39
@ EPSG
Definition: libsmet.h:39
@ WGS84
Definition: libsmet.h:39