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