WSL/SLF GitLab Repository

Commit c526bff1 authored by Mathias Bavay's avatar Mathias Bavay
Browse files

The Buffer class has been expanded with a new push() call and the...

The Buffer class has been expanded with a new push() call and the documentation moved around in IOUtils
parent c25a88bd
......@@ -569,15 +569,6 @@ void getTimeZoneParameters(const Config& cfg, double& tz_in, double& tz_out) {
cfg.getValue("TIME_ZONE", "Output", tz_out, IOUtils::nothrow);
}
/**
* @brief Search for an element at a given date in a vector of MeteoData.
* The position of the matching date is returned or IOUtils::npos if not found. If \em exactmatch=false,
* the position of the first element \em after \em soughtdate is returned (or IOUtils::npos if this is
* not possible / relevant).
* @param[in] soughtdate date that should be found
* @param[in] vecM vector that should contain the data
* @param[in] exactmatch if the exact requested date is not found, return npos
*/
size_t seek(const Date& soughtdate, const std::vector<MeteoData>& vecM, const bool& exactmatch)
{
if (vecM.empty() || soughtdate < vecM.front().date || soughtdate > vecM.back().date) {
......
......@@ -80,6 +80,15 @@ namespace IOUtils {
*/
inline bool checkEpsilonEquality(const double& val1, const double& val2, const double& epsilon) {return (fabs(val1-val2) < epsilon);}
/**
* @brief Search for an element at a given date in a vector of MeteoData.
* The position of the matching date is returned or IOUtils::npos if not found. If \em exactmatch=false,
* the position of the first element \em after \em soughtdate is returned (or IOUtils::npos if this is
* not possible / relevant).
* @param[in] soughtdate date that should be found
* @param[in] vecM vector that should contain the data
* @param[in] exactmatch if the exact requested date is not found, return npos
*/
size_t seek(const Date& soughtdate, const std::vector<MeteoData>& vecM, const bool& exactmatch=true);
/**
......
......@@ -84,6 +84,81 @@ void MeteoBuffer::clear()
ts_end.setUndef(true);
}
void MeteoBuffer::push(const std::vector<MeteoData>& vecMeteo)
{
const size_t nrStationsPush = vecMeteo.size();
if (nrStationsPush==0) return;
if (empty()) {
ts_start = vecMeteo.front().date;
ts_end = vecMeteo.front().date;
ts_buffer.resize(nrStationsPush); //allocate the memory
for (size_t ii=0; ii<nrStationsPush; ii++)
ts_buffer[ii].push_back( vecMeteo[ii] );
return;
} else {
const size_t nrStationsBuffer = ts_buffer.size();
//check that we are dealing with the same stations
if (nrStationsBuffer!=nrStationsPush) {
ostringstream ss;
ss << "The number of stations changed over time from " << nrStationsBuffer << " to " << nrStationsPush << ", ";
ss << "this is not handled yet!";
std::cerr << "trying to push: ";
for (size_t ii=0; ii<nrStationsPush; ii++) //for all stations
std::cerr << vecMeteo[ii].meta.stationID << " ";
std::cerr << "\nWas before: ";
for (size_t ii=0; ii<nrStationsBuffer; ii++) //for all stations
std::cerr << ts_buffer[ii].front().meta.stationID << " ";
throw IOException(ss.str(), AT);
}
for (size_t ii=0; ii<nrStationsPush; ii++) { //for all stations
if (ts_buffer[ii].empty()) continue;
if (ts_buffer[ii].front().meta.getHash()!=vecMeteo[ii].meta.getHash()) {
ostringstream ss;
ss << "The stations changed over time from " << ts_buffer[ii].front().meta.getHash() << " to " << vecMeteo[ii].meta.getHash() << ", ";
ss << "this is not handled yet!";
throw IOException(ss.str(), AT);
}
}
}
//now, do the inserts
for (size_t ii=0; ii<nrStationsPush; ii++) { //for all stations
const Date buffer_start = ts_buffer[ii].front().date;
const Date buffer_end = ts_buffer[ii].back().date;
const Date data_ts = vecMeteo[ii].date;
if (data_ts<buffer_start) { //the data simply fits at the start
ts_buffer[ii].insert(ts_buffer[ii].begin(), vecMeteo[ii]);
continue;
}
if (data_ts>buffer_end) { //the data simply fits to the end
ts_buffer[ii].push_back( vecMeteo[ii] );
continue;
}
const size_t insert_pos = IOUtils::seek(data_ts, ts_buffer[ii], false); //returns the first date >=
if (vecMeteo[ii].date!=ts_buffer[ii][insert_pos].date)
ts_buffer[ii].insert(ts_buffer[ii].begin()+insert_pos, vecMeteo[ii]); //insert takes place at element *before* insert_pos
else
ts_buffer[ii][insert_pos] = vecMeteo[ii]; //if the element already existed, replace it
ts_start = min(ts_start, data_ts);
ts_end = max(ts_end, data_ts);
}
}
void MeteoBuffer::push(const Date& date_start, const Date& date_end, const std::vector<MeteoData>& vecMeteo)
{
//HACK: check that the provided data is between date_start and date_end?
push(vecMeteo);
//take the data validity range into account for buffer validity
ts_start = min(ts_start, date_start);
ts_end = max(ts_end, date_end);
}
void MeteoBuffer::push(const Date& date_start, const Date& date_end, const std::vector< METEO_SET >& vecMeteo)
{
if (empty()) {
......@@ -104,7 +179,7 @@ void MeteoBuffer::push(const Date& date_start, const Date& date_end, const std::
throw IOException(ss.str(), AT);
}
for (size_t ii=0; ii<nrStationsBuffer; ii++) { //for all stations
for (size_t ii=0; ii<nrStationsPush; ii++) { //for all stations
if (ts_buffer[ii].empty() || vecMeteo[ii].empty())
continue;
if (ts_buffer[ii].front().meta.getHash()!=vecMeteo[ii].front().meta.getHash()) {
......@@ -116,7 +191,7 @@ void MeteoBuffer::push(const Date& date_start, const Date& date_end, const std::
}
//now, do the append/merge
for (size_t ii=0; ii<nrStationsBuffer; ii++) { //for all stations
for (size_t ii=0; ii<nrStationsPush; ii++) { //for all stations
if (vecMeteo[ii].empty()) continue;
if (ts_buffer[ii].empty()) {
......
......@@ -101,7 +101,21 @@ class MeteoBuffer {
* @param vecMeteo A vector of vector<MeteoData> objects providing the data
*/
void push(const Date& date_start, const Date& date_end, const std::vector< METEO_SET >& vecMeteo);
//void push(const Date& date, const METEO_SET& vecMeteo);
/**
* @brief Add a data point for several stations. The data is considered valid within the provided two dates
* @param date_start A Date object representing the beginning of an interval (inclusive)
* @param date_end A Date object representing the end of an interval (inclusive)
* @param vecMeteo A vector of <MeteoData> objects providing the data
*/
void push(const Date& date_start, const Date& date_end, const std::vector<MeteoData>& vecMeteo);
/**
* @brief Add a data point for several stations. The date is taken from the data itself
* @param vecMeteo A vector of <MeteoData> objects providing the data
*/
void push(const std::vector<MeteoData>& vecMeteo);
const std::string toString() const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment