WSL/SLF GitLab Repository

Commit e5d8343f authored by Thomas Egger's avatar Thomas Egger
Browse files

Completed the resampling algorithm Accumulate.

parent 4693284f
......@@ -566,6 +566,13 @@ const string Date::toString(FORMATS type, const bool& gmt) const
<< setw(2) << setfill('0') << hour_out << ":"
<< setw(2) << setfill('0') << minute_out << " ("
<< setprecision(10) << julian_out << ")" ;
} else if(type==DIN) {
tmpstr
<< setw(2) << setfill('0') << day_out << "."
<< setw(2) << setfill('0') << month_out << "."
<< setw(4) << setfill('0') << year_out << " "
<< setw(2) << setfill('0') << hour_out << ":"
<< setw(2) << setfill('0') << minute_out;
} else {
throw InvalidArgumentException("Wrong date conversion format requested", AT);
}
......
......@@ -74,7 +74,8 @@ class Date {
typedef enum {
ISO, ///< ISO 8601 extended format combined date: YYYY-MM-DDTHH:mm:SS (fields might be dropped, in the least to the most significant order)
FULL, ///< ISO 8601 followed by the julian date (in parenthesis)
NUM ///< ISO 8601 basic format date: YYYYMMDDHHmmSS (fields might be dropped, in the least to the most significant order)
NUM, ///< ISO 8601 basic format date: YYYYMMDDHHmmSS (fields might be dropped, in the least to the most significant order)
DIN ///<DIN5008 format: DD.MM.YYYY HH:MM
} FORMATS;
static const int daysLeapYear[];
static const int daysNonLeapYear[];
......
......@@ -65,6 +65,7 @@ unsigned int Meteo1DInterpolator::resampleData(const Date& date, std::vector<Met
MeteoData tmpmd(vecM.at(0)); //create a clone of one of the elements
tmpmd.reset(); //set all values to IOUtils::nodata
tmpmd.setDate(date);
tmpmd.setResampled(true);
if (position == IOUtils::npos){ //nothing found append new element at the left or right
if (vecM.at(0).date > date){
......
......@@ -236,10 +236,6 @@ void ResamplingAlgorithms::Accumulate(const unsigned int& pos, const MeteoData::
const std::vector<std::string>& taskargs,
std::vector<MeteoData>& vecM, std::vector<StationData>& vecS)
{
//Not ready for usage yet...
throw IOException("Not finished...", AT);
unsigned int npos = pos;
if (pos >= vecM.size())
throw IOException("The position of the resampled element is out of bounds", AT);
......@@ -255,53 +251,79 @@ void ResamplingAlgorithms::Accumulate(const unsigned int& pos, const MeteoData::
}
} else {
std::stringstream tmp;
tmp << "Please provide accumulation period (in seconds) for parameter " << MeteoData::getParameterName(paramindex);
tmp << "Please provide accumulation period (in seconds) for param" << MeteoData::getParameterName(paramindex);
throw InvalidArgumentException(tmp.str(), AT);
}
//find start of accumulation period
bool found_start=false;
int start_idx=pos;
const Date Start(vecM[pos].date.getJulianDate() - accumulate_period/(24.*3600.));
int start_idx = (int)pos;
Date dateStart(vecM[pos].date.getJulianDate() - accumulate_period/(24.*3600.));
for (; start_idx>=0; start_idx--) {
if(vecM[(unsigned int)start_idx].date<=Start) {
if(vecM[(unsigned int)start_idx].date <= dateStart) {
found_start=true;
break;
}
}
if(found_start==false) {
std::cerr << "[W] Could not accumulate " << MeteoData::getParameterName(paramindex);
std::cerr << ", not enough data for accumulation period\n";
cerr << "[W] Could not accumulate " << MeteoData::getParameterName(paramindex)
<< ", not enough data for accumulation period at date " << vecM[pos].date.toString(Date::ISO)
<< endl;
vecM[pos].param(paramindex) = IOUtils::nodata;
return;
}
//resample the starting point
//HACK: we consider nodata to be 0. In fact, we should try to interpolate from valid points
//if they are not too far away
/*Interpol1D::linearInterpolation(vecM[(unsigned int)start_idx].date.getJulianDate(), ,
vecM[(unsigned int)start_idx+1].date.getJulianDate(), val2,
vecM[pos].date.getJulianDate());*/
int interval_start = start_idx;
int interval_end = start_idx + 1;
if ((interval_end == pos) && (vecM[pos].isResampled())){
interval_end++;
dateStart = vecM[pos].date;
}
if (interval_end >= vecM.size()) //Nothing to do, point at the very right of our window
return;
//start accumulating
double sum = 0.0;
bool exist=false;
int end_idx=start_idx;
while(vecM[end_idx].date<=vecM[npos].date) {
//we will at least enter once into this loop since accumulate_period>0
const double& val = vecM[npos].param(paramindex);
double val2 = vecM[(unsigned int)interval_end].param(paramindex);
if (val2 == IOUtils::nodata) val2 = 0.0;
double part1 = val2 - Interpol1D::linearInterpolation(vecM[interval_start].date.getJulianDate(), 0.0,
vecM[interval_end].date.getJulianDate(), val2,
dateStart.getJulianDate());
double sum = part1;
int end_idx = interval_end + 1;
while((end_idx < vecM.size()) && (vecM[end_idx].date < vecM[pos].date)) {
const double& val = vecM[end_idx].param(paramindex);
if (val != IOUtils::nodata) {
sum += val;
exist=true;
}
end_idx++;
}
//add last remaining point after interpolating it
//HACK: TODO
if ((vecM[end_idx].date == vecM[pos].date) || (end_idx >= pos+1)){
vecM[pos].param(paramindex) = sum;
return;
}
double part2 = 0;
if ((pos + 1) < vecM.size()){
double nextval = vecM[(unsigned int)pos+1].param(paramindex);
part2 = Interpol1D::linearInterpolation(vecM[pos-1].date.getJulianDate(), 0.0,
vecM[pos+1].date.getJulianDate(), nextval,
vecM[pos].date.getJulianDate());
}
sum += part2;
//check if at least one point has been summed. If not -> nodata
vecM[pos].param(paramindex) = sum;
//TODO:check if at least one point has been summed. If not -> nodata
}
......
......@@ -390,6 +390,18 @@ void SNIO::parseMeteoLine(const std::vector<std::string>& vecLine, const std::st
md.setData(MeteoData::TSG, tmpdata[12]);
md.setData(MeteoData::HNW, tmpdata[13]);
md.setData(MeteoData::HS, tmpdata[14]);
//cout << "Adding parameters:" << endl;
//All the rest of the values ought to be ts[ii] values
stringstream ss;
for (unsigned int ii=15; ii<tmpdata.size(); ii++){
ss.str("");
ss << "TS" << (ii-15);
md.addParameter(ss.str());
md.param(ss.str()) = tmpdata[ii];
//cout << "Added " << ss.str() << ": " << tmpdata[ii] << endl;
}
//cout << "Adding parameters done" << endl;
}
void SNIO::writeMeteoData(const std::vector< std::vector<MeteoData> >& vecMeteo,
......@@ -591,6 +603,20 @@ void SNIO::convertUnits(MeteoData& meteo)
if (meteo.rh>1.2)
meteo.rh /= 100;
}
//cout << "Converting" << endl;
stringstream ss;
for (unsigned int ii=0; ii<100; ii++){
ss.str("");
ss << "TS" << ii;
if (meteo.param_exists(ss.str())){
double& value = meteo.param(ss.str());
value = C_TO_K(value);
} else {
break;
}
}
//cout << "Converting done" << endl;
}
#ifndef _METEOIO_JNI
......
Supports Markdown
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