WSL/SLF GitLab Repository

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

More refinements to the Winstral spatial interpolation: it is now possible to...

More refinements to the Winstral spatial interpolation: it is now possible to provide a reference station to take the wind direction from, or to provide a fixed wind direction. 
parent ca13350c
......@@ -42,7 +42,7 @@ namespace mio {
*
* Another usage scenario is to create new parameters fully based on parametrizations. In such a case, the "generator" is called
* a "creator" and behaves the same way as a generator, except that it creates an additional parameter. It is declared as
* {new_parameter}::create = {data generators}.
* {new_parameter}::%create = {data generators}.
*
* @note it is generally not advised to use data generators in combination with spatial interpolations as this would
* potentially mix measured and generated values in the resulting grid. It is therefore advised to turn the data generators
......
......@@ -593,36 +593,51 @@ double WinstralAlgorithm::getQualityRating(const Date& i_date, const MeteoData::
param = in_param;
nrOfMeasurments = getData(date, param, vecData, vecMeta);
//option 1: fixed DW
//option 2: specify the station to take DW from
//option 3: compute DW from multiple stations
if (vecArgs.size() == 2) { //fixed wind direction
IOUtils::convertString(synoptic_bearing, vecArgs[1]);
} else { //incorrect arguments, throw an exception
throw InvalidArgumentException("Please provide the wind direction to use for the "+algo+" algorithm", AT);
}
if (nrOfMeasurments==0)
return 0.0;
return 0.9;
return 0.99;
}
void WinstralAlgorithm::initGrid(const DEMObject& dem, Grid2DObject& grid)
void WinstralAlgorithm::getParameters(std::string &base_algo, double &synoptic_bearing) const
{
//retrieve optional arguments
std::string base_algo;
if (vecArgs.empty()){
base_algo=std::string("IDW_LAPSE");
} else if (vecArgs.size() <= 2){
IOUtils::convertString(base_algo, vecArgs[0]);
} else { //incorrect arguments, throw an exception
//option 0: compute DW from multiple stations
//option 1: fixed DW
//option 2: specify the station_id to take DW from
base_algo = "IDW_LAPSE";
const size_t nr_args = vecArgs.size();
if (nr_args==0) {
synoptic_bearing = getSynopticBearing(vecMeteo);
if (synoptic_bearing==IOUtils::nodata)
throw IOException("Synoptic wind could not be computed by the "+algo+" algorithm", AT);
return;
} else if (nr_args==1) {
if (IOUtils::isNumeric(vecArgs[0]))
IOUtils::convertString(synoptic_bearing, vecArgs[0]);
else
throw InvalidArgumentException("Please provide both the base interpolation method and the station_id to use for wind direction for the "+algo+" algorithm", AT);
return;
} else if (nr_args==2) {
if (IOUtils::isNumeric(vecArgs[0])) {
IOUtils::convertString(synoptic_bearing, vecArgs[0]);
base_algo = IOUtils::strToUpper( vecArgs[1] );
} else if (IOUtils::isNumeric(vecArgs[1])) {
IOUtils::convertString(synoptic_bearing, vecArgs[1]);
base_algo = IOUtils::strToUpper( vecArgs[0] );
} else {
base_algo = IOUtils::strToUpper( vecArgs[0] );
const string ref_station( vecArgs[1] );
synoptic_bearing = getSynopticBearing(vecMeteo, ref_station, algo);
}
return;
} else
throw InvalidArgumentException("Wrong number of arguments supplied for the "+algo+" algorithm", AT);
}
}
void WinstralAlgorithm::initGrid(const std::string& base_algo, const DEMObject& dem, Grid2DObject& grid)
{
//initialize precipitation grid with user supplied algorithm (IDW_LAPSE by default)
IOUtils::toUpper(base_algo);
vector<string> vecArgs2;
mi.getArgumentsForAlgorithm(MeteoData::getParameterName(param), base_algo, vecArgs2);
auto_ptr<InterpolationAlgorithm> algorithm(AlgorithmFactory::getAlgorithm(base_algo, mi, vecArgs2, iomanager));
......@@ -631,6 +646,16 @@ void WinstralAlgorithm::initGrid(const DEMObject& dem, Grid2DObject& grid)
info << algorithm->getInfo();
}
double WinstralAlgorithm::getSynopticBearing(const std::vector<MeteoData>& vecMeteo, const std::string& ref_station, const std::string& algo)
{
for(size_t ii=0; ii<vecMeteo.size(); ++ii) {
if (vecMeteo[ii].meta.stationID==ref_station)
return vecMeteo[ii](MeteoData::DW);
}
throw InvalidArgumentException("Station \""+ref_station+"\" should be used as reference station for the "+algo+" algorithm but has not been found", AT);
}
double WinstralAlgorithm::getSynopticBearing(const std::vector<MeteoData>& vecMeteo)
{
// 1) locate the stations in DEM and check if they are higher than their surroundings within a given radius
......@@ -664,12 +689,11 @@ double WinstralAlgorithm::getSynopticBearing(const std::vector<MeteoData>& vecMe
void WinstralAlgorithm::calculate(const DEMObject& dem, Grid2DObject& grid)
{
info.clear(); info.str("");
initGrid(dem, grid);
//get synoptic wind direction. Three options:
// a) use a fixed wind direction b) use a user provided list of directions c) get it from the data
//synoptic_bearing = (vecMeteo);
string base_algo, ref_station;
double synoptic_bearing;
getParameters(base_algo, synoptic_bearing);
initGrid(base_algo, dem, grid);
//alter the field with Winstral and the chosen wind direction
Interpol2D::Winstral(dem, 300., synoptic_bearing, grid); //HACK
......
......@@ -386,9 +386,12 @@ class SimpleWindInterpolationAlgorithm : public InterpolationAlgorithm {
* Journal of Hydrometeorology, <b>3(5)</b>, 524-538.
* The DEM is used to compute wind exposure factors that are used to alter the precipitation fields.
* It is usually a good idea to provide a DEM that also contain the accumulated snow height in order
* to get a progrfessive softening of the terrain features.
* It takes two arguments: the base algorithm to generate the initial wind field and the
* synoptic wind direction.
* to get a progressive softening of the terrain features.
* It takes the following arguments: the base algorithm to generate the initial wind field, the
* synoptic wind direction or the station_id of the station to get the wind direction from. All these arguments
* are optional but in order to make it possible to distinguish the arguments, it is not possible to only
* provide one argument of type "string" (in such a case, the second one must be provided and the order
* defines which is which).
* @code
* HNW::algorithms = WINSTRAL
* HNW::winstral = idw_lapse 180
......@@ -399,14 +402,14 @@ class WinstralAlgorithm : public InterpolationAlgorithm {
WinstralAlgorithm(Meteo2DInterpolator& i_mi,
const std::vector<std::string>& i_vecArgs,
const std::string& i_algo, IOManager& iom)
: InterpolationAlgorithm(i_mi, i_vecArgs, i_algo, iom), synoptic_bearing(0.) {}
: InterpolationAlgorithm(i_mi, i_vecArgs, i_algo, iom) {}
virtual double getQualityRating(const Date& i_date, const MeteoData::Parameters& in_param);
virtual void calculate(const DEMObject& dem, Grid2DObject& grid);
private:
void initGrid(const DEMObject& dem, Grid2DObject& grid);
void getParameters(std::string &base_algo, double &synoptic_bearing) const;
void initGrid(const std::string& base_algo, const DEMObject& dem, Grid2DObject& grid);
static double getSynopticBearing(const std::vector<MeteoData>& vecMeteo, const std::string& ref_station, const std::string& algo);
static double getSynopticBearing(const std::vector<MeteoData>& vecMeteo);
double synoptic_bearing;
};
/**
......
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