WSL/SLF GitLab Repository

Commit 0d4e537f authored by Mathias Bavay's avatar Mathias Bavay
Browse files

The PSUMDistribute "filter" was not working properly on some data, this has...

The PSUMDistribute "filter" was not working properly on some data, this has been fixed. Some missing documentation for the TAU_CLD generator has been added.
parent 375feb4a
......@@ -80,6 +80,7 @@ namespace mio {
* - CLEARSKY_LW: use a clear sky model to generate ILWR from TA, RH (see ClearSkyLWGenerator)
* - ALLSKY_LW: use an all sky model to generate ILWR from TA, RH and cloudiness (see AllSkyLWGenerator)
* - ALLSKY_SW: generate the incoming short wave radiation from the potential radiation, corrected for cloudiness if possible (see AllSkySWGenerator)
* - TAU_CLD: generate the atmospheric transmissivity based on cloud cover fraction (see TauCLDGenerator)
* - ESOLIP: generate precipitation from snow height changes (see ESOLIPGenerator)
* - PPHASE: generate precipitation phase with a user-selected method (see PPhaseGenerator)
*
......
......@@ -36,6 +36,7 @@ void ProcPSUMDistribute::process(const unsigned int& param, const std::vector<Me
{
ovec = ivec;
const size_t nr_elems = ivec.size();
bool first_true_point = true; //to identify the first true data point found in the input data
size_t ii=0;
while (ii<nr_elems) {
......@@ -43,30 +44,32 @@ void ProcPSUMDistribute::process(const unsigned int& param, const std::vector<Me
const Date endDate = startDate + measured_period;
const size_t endIdx = findNextAccumulation(param, ovec, endDate, ii+1);
if (endIdx==IOUtils::npos) { //no accumulation found
if (ovec.back().date<endDate) { //the proper end dat is not in our vector
fillInterval(param, ovec, ii, nr_elems-1, 0.); //fill the rest with 0
ii = nr_elems;
} else { //the next accumulation is really missing
if (is_soft) {
fillInterval(param, ovec, ii, endIdx, 0.); //fill the interval with 0
ii = endIdx+1;
} else {
std::ostringstream ss;
ss << "Redistribution of precipitation before reaccumulation failed: precipitation value required ";
ss << "in the " << startDate.toString(Date::ISO) << " - " << endDate.toString(Date::ISO) << " interval!\n";
throw NoDataException(ss.str(), AT);
}
//the proper end date is not in our vector
if (endIdx==IOUtils::npos || (endIdx==ii && is_soft)) {
fillInterval(param, ovec, ii, nr_elems-1, 0.); //fill the rest with 0
ii = nr_elems;
continue;
}
//at the end of the accumulation period, there is nodata
if (ovec[endIdx](param)==IOUtils::nodata) {
if (!is_soft) {
std::ostringstream ss;
ss << "Redistribution of precipitation before reaccumulation failed: precipitation value required ";
ss << "in the " << startDate.toString(Date::ISO) << " - " << endDate.toString(Date::ISO) << " interval!\n";
throw NoDataException(ss.str(), AT);
}
fillInterval(param, ovec, ii, endIdx, 0.); //fill the interval with 0
ii = endIdx;
continue;
}
//we might have found an accumulation that comes too early -> ok for first point, otherwise multiple accumulations
if (ovec[endIdx].date<endDate && ii!=0) {
if (ovec[endIdx].date<endDate && !first_true_point) {
const double interval = endDate.getJulian(true) - startDate.getJulian(true);
std::ostringstream ss;
const string param_name = ovec[0].getNameForParameter(param);
std::ostringstream ss;
if (interval==measured_period) {
ss << "The precipitation must be provided at the end of the accumulation period ";
ss << "for the " << getName() << " filter, and this is not the case for " << endDate.toString(Date::ISO);
......@@ -84,16 +87,19 @@ void ProcPSUMDistribute::process(const unsigned int& param, const std::vector<Me
SmartDistributePSUM(precip, ii+1, endIdx, param, ovec);
ii = endIdx;
first_true_point = false;
}
}
//find first value before or at endDate
//find the index of the first value > endDate. Please check if the matching value is not nodata!
//return IOUtils::npos if endDate is not in the provided vector.
size_t ProcPSUMDistribute::findNextAccumulation(const unsigned int& param, const std::vector<MeteoData>& ivec, const Date& endDate, size_t ii)
{
const size_t nr_elems = ivec.size();
while (ii<nr_elems && ivec[ii].date<=endDate && ivec[ii](param)==IOUtils::nodata) ii++;
if (ii==nr_elems || ivec[ii].date>endDate) return IOUtils::npos;
if (ii==nr_elems) return IOUtils::npos;
if (ivec[ii].date>endDate) return ii-1; //we never found data!=nodata, so revert to last point in the period
return ii;
}
......
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