An error occurred while loading the file. Please try again.
-
Fize Jacques authoredc4667d6f
#ifndef EVALHYD_PROBABILIST_HPP
#define EVALHYD_PROBABILIST_HPP
#include <utility>
#include <unordered_map>
#include <vector>
#include <xtensor/xtensor.hpp>
#include <xtensor/xview.hpp>
#include "utils.hpp"
#include "probabilist/evaluator.h"
namespace eh = evalhyd;
namespace evalhyd
{
namespace probabilist
{
/// Function allowing the evaluation of streamflow forecasts using a
/// range of relevant metrics.
///
/// \param [in] metrics:
/// Vector of strings for the metric(s) to be computed.
/// \param [in] q_obs:
/// 2D array of streamflow observations.
/// shape: (1, time)
/// \param [in] q_frc:
/// 2D array of streamflow forecasts.
/// shape: (members, time)
/// \param [in] q_thr:
/// 1D array of streamflow exceedance threshold(s).
/// shape: (thresholds,)
/// \return
/// Vector of 2D array of metrics for each threshold.
std::vector<xt::xtensor<double, 2>> evaluate(
const std::vector<std::string>& metrics,
const xt::xtensor<double, 2>& q_obs,
const xt::xtensor<double, 2>& q_frc,
const xt::xtensor<double, 1>& q_thr
)
{
// check that the metrics to be computed are valid
utils::check_metrics(
metrics,
{"BS", "BSS", "BS_CRD", "BS_LBD", "QS", "CRPS"}
);
// instantiate probabilist evaluator
eh::probabilist::Evaluator evaluator(q_obs, q_frc, q_thr);
// declare maps for memoisation purposes
std::unordered_map<std::string, std::vector<std::string>> elt;
std::unordered_map<std::string, std::vector<std::string>> dep;
// register potentially recurring computation elements across metrics
elt["BS"] = {"o_k", "y_k"};
elt["BSS"] = {"o_k", "bar_o"};
elt["BS_CRD"] = {"o_k", "bar_o", "y_k"};
elt["BS_LBD"] = {"o_k", "y_k"};
elt["QS"] = {"q_qnt"};
// register nested metrics (i.e. metric dependent on another metric)
dep["BSS"] = {"BS"};
dep["QS"] = {"qs"};
dep["CRPS"] = {"qs", "crps"};
// determine required elt/dep to be pre-computed
std::vector<std::string> req_elt;
std::vector<std::string> req_dep;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
eh::utils::find_requirements(metrics, elt, dep, req_elt, req_dep);
// pre-compute required elt
for (const auto& element : req_elt)
{
if ( element == "o_k" )
evaluator.calc_o_k();
else if ( element == "bar_o" )
evaluator.calc_bar_o();
else if ( element == "y_k" )
evaluator.calc_y_k();
else if ( element == "q_qnt" )
evaluator.calc_q_qnt();
}
// pre-compute required dep
for (const auto& dependency : req_dep)
{
if ( dependency == "BS" )
evaluator.calc_BS();
else if ( dependency == "qs" )
evaluator.calc_qs();
else if ( dependency == "crps" )
evaluator.calc_crps();
}
// retrieve or compute requested metrics
std::vector<xt::xtensor<double, 2>> r;
for (const auto& metric : metrics)
{
if ( metric == "BS" )
{
if (std::find(req_dep.begin(), req_dep.end(), metric)
== req_dep.end())
evaluator.calc_BS();
r.emplace_back(evaluator.BS);
}
else if ( metric == "BSS" )
{
if (std::find(req_dep.begin(), req_dep.end(), metric)
== req_dep.end())
evaluator.calc_BSS();
r.emplace_back(evaluator.BSS);
}
else if ( metric == "BS_CRD" )
{
if (std::find(req_dep.begin(), req_dep.end(), metric)
== req_dep.end())
evaluator.calc_BS_CRD();
r.emplace_back(evaluator.BS_CRD);
}
else if ( metric == "BS_LBD" )
{
if (std::find(req_dep.begin(), req_dep.end(), metric)
== req_dep.end())
evaluator.calc_BS_LBD();
r.emplace_back(evaluator.BS_LBD);
}
else if ( metric == "QS" )
{
if (std::find(req_dep.begin(), req_dep.end(), metric)
== req_dep.end())
evaluator.calc_QS();
r.emplace_back(evaluator.QS);
}
else if ( metric == "CRPS" )
{
if (std::find(req_dep.begin(), req_dep.end(), metric)
== req_dep.end())
141142143144145146147148149150151152
evaluator.calc_CRPS();
r.emplace_back(evaluator.CRPS);
}
}
return r;
}
}
}
#endif //EVALHYD_PROBABILIST_HPP