OGS
SensorData.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "SensorData.h"
5
6#include <algorithm>
7#include <cstdlib>
8#include <fstream>
9
10#include "BaseLib/DateTools.h"
11#include "BaseLib/Logging.h"
12#include "BaseLib/StringTools.h"
13
14SensorData::SensorData(const std::string& file_name)
16{
17 readDataFromFile(file_name);
18}
19
20SensorData::SensorData(std::vector<std::size_t> time_steps)
21 : _start(time_steps.front()),
22 _end(time_steps.back()),
23 _step_size(0),
25 _time_steps(time_steps)
26{
27 if (!std::is_sorted(
28 time_steps.begin(), time_steps.end(), std::less_equal{}))
29 {
30 ERR("Error in SensorData() - Time series has no order!");
31 }
32}
33
35{
36 for (std::vector<float>* vec : _data_vecs)
37 {
38 delete vec;
39 }
40}
41
42void SensorData::addTimeSeries(const std::string& data_name,
43 std::vector<float>* data,
44 const std::string& data_unit_string)
45{
47 data,
48 data_unit_string);
49}
50
52 std::vector<float>* data,
53 const std::string& data_unit_string)
54{
55 if (_step_size > 0)
56 {
57 if (((_end - _start) / _step_size) != data->size())
58 {
59 WARN(
60 "Warning in SensorData::addTimeSeries() - Lengths of time "
61 "series does not match number of time steps.");
62 return;
63 }
64 }
65 else
66 {
67 if (data->size() != _time_steps.size())
68 {
69 WARN(
70 "Warning in SensorData::addTimeSeries() - Lengths of time "
71 "series does not match number of time steps.");
72 return;
73 }
74 }
75
76 _vec_names.push_back(data_name);
77 _data_vecs.push_back(data);
78 _data_unit_string.push_back(data_unit_string);
79}
80
81const std::vector<float>* SensorData::getTimeSeries(
82 SensorDataType time_series_name) const
83{
84 for (std::size_t i = 0; i < _vec_names.size(); i++)
85 {
86 if (time_series_name == _vec_names[i])
87 {
88 return _data_vecs[i];
89 }
90 }
91 ERR("Error in SensorData::getTimeSeries() - Time series '{:s}' not found.",
92 convertSensorDataType2String(time_series_name));
93 return nullptr;
94}
95
96int SensorData::readDataFromFile(const std::string& file_name)
97{
98 std::ifstream in(file_name.c_str());
99
100 if (!in.is_open())
101 {
102 INFO("SensorData::readDataFromFile() - Could not open file {:s}.",
103 file_name);
104 return 0;
105 }
106
107 std::string line;
108
109 /* first line contains field names */
110 std::getline(in, line);
111 std::list<std::string> fields = BaseLib::splitString(line, '\t');
112 std::list<std::string>::const_iterator it(fields.begin());
113 std::size_t const nFields = fields.size();
114
115 if (nFields < 2)
116 {
117 return 0;
118 }
119
120 std::size_t const nDataArrays(nFields - 1);
121
122 // create vectors necessary to hold the data
123 for (std::size_t i = 0; i < nDataArrays; i++)
124 {
126 _data_unit_string.emplace_back("");
127 _data_vecs.push_back(new std::vector<float>);
128 }
129
130 while (std::getline(in, line))
131 {
132 fields = BaseLib::splitString(line, '\t');
133
134 if (nFields != fields.size())
135 {
136 return 0;
137 }
138
139 it = fields.begin();
140 std::size_t const pos(it->rfind("."));
141 std::size_t const current_time_step = (pos == std::string::npos)
142 ? atoi((it++)->c_str())
143 : BaseLib::strDate2int(*it++);
144 _time_steps.push_back(current_time_step);
145
146 for (std::size_t i = 0; i < nDataArrays; i++)
147 {
148 _data_vecs[i]->push_back(
149 static_cast<float>(strtod((it++)->c_str(), nullptr)));
150 }
151 }
152
153 in.close();
154
155 _start = _time_steps[0];
156 _end = _time_steps[_time_steps.size() - 1];
157
158 return 1;
159}
160
162{
164 {
165 return "Evaporation";
166 }
168 {
169 return "Precipitation";
170 }
172 {
173 return "Temperature";
174 }
175 // pls leave this as last choice
176 return "Unknown";
177}
178
180{
181 if (s == "Evaporation" || s == "EVAPORATION")
182 {
184 }
185 if (s == "Precipitation" || s == "PRECIPITATION")
186 {
188 }
189 if (s == "Temperature" || s == "TEMPERATURE")
190 {
192 }
194}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
TimeStepType
Definition SensorData.h:32
SensorDataType
Definition SensorData.h:17
const std::vector< float > * getTimeSeries(SensorDataType time_series_name) const
Returns the time series with the given name.
std::size_t _end
Definition SensorData.h:116
std::vector< SensorDataType > _vec_names
Definition SensorData.h:121
std::vector< std::vector< float > * > _data_vecs
Definition SensorData.h:122
TimeStepType _time_unit
Definition SensorData.h:118
SensorData(const std::string &file_name)
std::size_t _start
Definition SensorData.h:115
std::vector< std::string > _data_unit_string
Definition SensorData.h:119
std::vector< std::size_t > _time_steps
Definition SensorData.h:120
void addTimeSeries(const std::string &data_name, std::vector< float > *data, const std::string &data_unit_string="")
std::size_t _step_size
Definition SensorData.h:117
int readDataFromFile(const std::string &file_name)
Reads a CSV-file with time series data and fills the container.
static SensorDataType convertString2SensorDataType(const std::string &s)
Converts Strings to Sensor Data Types.
static std::string convertSensorDataType2String(SensorDataType t)
Converts Sensor Data Types to Strings.
int strDate2int(const std::string &s)
Definition DateTools.cpp:91
std::vector< std::string > splitString(std::string const &str)