diff --git a/include/evalhyd/evald.hpp b/include/evalhyd/evald.hpp index 2efb64745614fe03fe6c7e0e68cd108b8e842955..8b0041b6a9667f8d89532dc1ff4eb38d3006ae8a 100644 --- a/include/evalhyd/evald.hpp +++ b/include/evalhyd/evald.hpp @@ -154,7 +154,7 @@ namespace evalhyd /// evalhyd::evald(obs, prd, {"NSE"}, "none", 1, -9, msk); /// /// \endrst - template <class XD2, class XB2> + template <class XD2, class XB2 = xt::xtensor<bool, 2>> std::vector<xt::xarray<double>> evald( const xt::xexpression<XD2>& q_obs, const xt::xexpression<XD2>& q_prd, diff --git a/include/evalhyd/evalp.hpp b/include/evalhyd/evalp.hpp index 89088ade3fbc78e57f9a43976785efeebcbbb21e..a425a6692e23cfc9f1790511a7d51cd9a2730aee 100644 --- a/include/evalhyd/evalp.hpp +++ b/include/evalhyd/evalp.hpp @@ -136,7 +136,7 @@ namespace evalhyd /// evalhyd::evalp(obs, prd, {"CRPS"}); /// /// \endrst - template <class XD2, class XD4, class XB4> + template <class XD2, class XD4, class XB4 = xt::xtensor<bool, 4>> std::vector<xt::xarray<double>> evalp( const xt::xexpression<XD2>& q_obs, const xt::xexpression<XD4>& q_prd, diff --git a/tests/test_determinist.cpp b/tests/test_determinist.cpp index d5f725e328445df06a1619fa3b5db6247a00b926..a64f56c570a28a0d92f667434b53a696b80f4aa9 100644 --- a/tests/test_determinist.cpp +++ b/tests/test_determinist.cpp @@ -43,7 +43,7 @@ TEST(DeterministTests, TestMetrics) // compute scores (with 2D tensors) std::vector<xt::xarray<double>> metrics = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>( + evalhyd::evald( observed, predicted, {"RMSE", "NSE", "KGE", "KGEPRIME"} ); @@ -90,7 +90,7 @@ TEST(DeterministTests, TestTransform) // compute and check results on square-rooted streamflow series std::vector<xt::xarray<double>> metrics = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>(observed, predicted, {"NSE"}, "sqrt"); + evalhyd::evald(observed, predicted, {"NSE"}, "sqrt"); xt::xtensor<double, 3> nse_sqrt = {{{0.882817}}, @@ -101,7 +101,7 @@ TEST(DeterministTests, TestTransform) EXPECT_TRUE(xt::allclose(metrics[0], nse_sqrt)); // compute and check results on inverted streamflow series - metrics = evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>(observed, predicted, {"NSE"}, "inv"); + metrics = evalhyd::evald(observed, predicted, {"NSE"}, "inv"); xt::xtensor<double, 3> nse_inv = {{{0.737323}}, @@ -112,7 +112,7 @@ TEST(DeterministTests, TestTransform) EXPECT_TRUE(xt::allclose(metrics[0], nse_inv)); // compute and check results on square-rooted streamflow series - metrics = evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>(observed, predicted, {"NSE"}, "log"); + metrics = evalhyd::evald(observed, predicted, {"NSE"}, "log"); xt::xtensor<double, 3> nse_log = {{{0.893344}}, @@ -123,7 +123,7 @@ TEST(DeterministTests, TestTransform) EXPECT_TRUE(xt::allclose(metrics[0], nse_log)); // compute and check results on power-transformed streamflow series - metrics = evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>(observed, predicted, {"NSE"}, "pow", 0.2); + metrics = evalhyd::evald(observed, predicted, {"NSE"}, "pow", 0.2); xt::xtensor<double, 3> nse_pow = {{{0.899207}}, @@ -152,14 +152,14 @@ TEST(DeterministTests, TestMasks) {"RMSE", "NSE", "KGE", "KGEPRIME"}; std::vector<xt::xarray<double>> metrics_masked = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>(observed, predicted, metrics, "none", 1, -9, masks); + evalhyd::evald(observed, predicted, metrics, {}, {}, {}, masks); // compute scores on pre-computed subset of whole record xt::xtensor<double, 2> obs = xt::view(observed, xt::all(), xt::range(20, _)); xt::xtensor<double, 2> prd = xt::view(predicted, xt::all(), xt::range(20, _)); std::vector<xt::xarray<double>> metrics_subset = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>(obs, prd, metrics); + evalhyd::evald(obs, prd, metrics); // check results are identical for (std::size_t m = 0; m < metrics.size(); m++) @@ -192,12 +192,12 @@ TEST(DeterministTests, TestMaskingConditions) std::vector<xt::xarray<double>> metrics_q_conditioned = evalhyd::evald( observed, predicted, metrics, - "none", 1, -9, masks, q_conditions + {}, {}, {}, masks, q_conditions ); // compute scores using "NaN-ed" time indices where conditions on streamflow met std::vector<xt::xarray<double>> metrics_q_preconditioned = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>( + evalhyd::evald( xt::eval(xt::where((observed < 2000) | (observed > 3000), observed, NAN)), predicted, metrics @@ -225,12 +225,12 @@ TEST(DeterministTests, TestMaskingConditions) std::vector<xt::xarray<double>> metrics_q_conditioned_ = evalhyd::evald( observed, predicted, metrics, - "none", 1, -9, masks, q_conditions_ + {}, {}, {}, masks, q_conditions_ ); // compute scores using "NaN-ed" time indices where conditions on streamflow met std::vector<xt::xarray<double>> metrics_q_preconditioned_ = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>( + evalhyd::evald( xt::eval(xt::where(observed >= mean, observed, NAN)), predicted, metrics @@ -241,7 +241,7 @@ TEST(DeterministTests, TestMaskingConditions) { EXPECT_TRUE( xt::allclose( - metrics_q_conditioned[m], metrics_q_preconditioned[m] + metrics_q_conditioned_[m], metrics_q_preconditioned_[m] ) ) << "Failure for (" << metrics[m] << ")"; } @@ -256,12 +256,12 @@ TEST(DeterministTests, TestMaskingConditions) std::vector<xt::xarray<double>> metrics_t_conditioned = evalhyd::evald( observed, predicted, metrics, - "none", 1, -9, masks, t_conditions + {}, {}, {}, masks, t_conditions ); // compute scores on already subset time series std::vector<xt::xarray<double>> metrics_t_subset = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>( + evalhyd::evald( xt::eval(xt::view(observed, xt::all(), xt::range(0, 100))), xt::eval(xt::view(predicted, xt::all(), xt::range(0, 100))), metrics @@ -299,7 +299,7 @@ TEST(DeterministTests, TestMissingData) // compute metrics with observations containing NaN values std::vector<xt::xarray<double>> metrics_nan = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>(observed, predicted, metrics); + evalhyd::evald(observed, predicted, metrics); for (std::size_t m = 0; m < metrics.size(); m++) { @@ -313,7 +313,7 @@ TEST(DeterministTests, TestMissingData) xt::view(predicted, p, xt::range(20+(3*(p+1)), _)); std::vector<xt::xarray<double>> metrics_sbs = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>( + evalhyd::evald( xt::eval(xt::view(obs, xt::newaxis(), xt::all())), xt::eval(xt::view(prd, xt::newaxis(), xt::all())), {metrics[m]} @@ -356,13 +356,13 @@ TEST(DeterministTests, TestBootstrap) {{"n_samples", 10}, {"len_sample", 3}, {"summary", 0}}; std::vector<xt::xarray<double>> metrics_bts = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>( + evalhyd::evald( xt::eval(xt::view(observed, xt::newaxis(), xt::all())), predicted, metrics, - "none", // transform - 1, // exponent - -9, // epsilon + {}, // transform + {}, // exponent + {}, // epsilon xt::xtensor<bool, 2>({}), // t_msk {}, // m_cdt bootstrap, @@ -381,7 +381,7 @@ TEST(DeterministTests, TestBootstrap) xt::concatenate(xt::xtuple(predicted, predicted, predicted), 1); std::vector<xt::xarray<double>> metrics_rep = - evalhyd::evald<xt::xtensor<double, 2>, xt::xtensor<bool, 2>>( + evalhyd::evald( xt::eval(xt::view(observed_x3, xt::newaxis(), xt::all())), predicted_x3, metrics diff --git a/tests/test_probabilist.cpp b/tests/test_probabilist.cpp index 342cbf04ddc608692c50adc5da23dcb61f721521..2c657dff86df2d29a69780a5aa3c08969d60f722 100644 --- a/tests/test_probabilist.cpp +++ b/tests/test_probabilist.cpp @@ -43,7 +43,7 @@ TEST(ProbabilistTests, TestBrier) xt::xtensor<double, 2> thresholds = {{690, 534, 445, NAN}}; std::vector<xt::xarray<double>> metrics = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( // shape: (sites [1], time [t]) xt::eval(xt::view(observed, xt::newaxis(), xt::all())), // shape: (sites [1], lead times [1], members [m], time [t]) @@ -101,7 +101,7 @@ TEST(ProbabilistTests, TestQuantiles) // compute scores std::vector<xt::xarray<double>> metrics = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( // shape: (sites [1], time [t]) xt::eval(xt::view(observed, xt::newaxis(), xt::all())), // shape: (sites [1], lead times [1], members [m], time [t]) @@ -150,7 +150,7 @@ TEST(ProbabilistTests, TestMasks) {"BS", "BSS", "BS_CRD", "BS_LBD", "QS", "CRPS"}; std::vector<xt::xarray<double>> metrics_masked = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( // shape: (sites [1], time [t]) xt::eval(xt::view(observed, xt::newaxis(), xt::all())), // shape: (sites [1], lead times [1], members [m], time [t]) @@ -163,7 +163,7 @@ TEST(ProbabilistTests, TestMasks) // compute scores on pre-computed subset of whole record std::vector<xt::xarray<double>> metrics_subset = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( // shape: (sites [1], time [t-20]) xt::eval(xt::view(observed, xt::newaxis(), xt::range(20, _))), // shape: (sites [1], lead times [1], members [m], time [t-20]) @@ -205,7 +205,7 @@ TEST(ProbabilistTests, TestMaskingConditions) }; std::vector<xt::xarray<double>> metrics_q_conditioned = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(observed), xt::eval(xt::view(predicted, xt::newaxis(), xt::newaxis(), xt::all(), xt::all())), metrics, @@ -216,7 +216,7 @@ TEST(ProbabilistTests, TestMaskingConditions) // compute scores using "NaN-ed" time indices where conditions on streamflow met std::vector<xt::xarray<double>> metrics_q_preconditioned = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(xt::where((observed < 2000) | (observed > 3000), observed, NAN)), xt::eval(xt::view(predicted, xt::newaxis(), xt::newaxis(), xt::all(), xt::all())), metrics, @@ -244,7 +244,7 @@ TEST(ProbabilistTests, TestMaskingConditions) double median = xt::median(q_prd_mean); std::vector<xt::xarray<double>> metrics_q_conditioned_ = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(observed), xt::eval(xt::view(predicted, xt::newaxis(), xt::newaxis(), xt::all(), xt::all())), metrics, @@ -255,7 +255,7 @@ TEST(ProbabilistTests, TestMaskingConditions) // compute scores using "NaN-ed" time indices where conditions on streamflow met std::vector<xt::xarray<double>> metrics_q_preconditioned_ = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(xt::where(q_prd_mean >= median, observed, NAN)), xt::eval(xt::view(predicted, xt::newaxis(), xt::newaxis(), xt::all(), xt::all())), metrics, @@ -280,7 +280,7 @@ TEST(ProbabilistTests, TestMaskingConditions) }; std::vector<xt::xarray<double>> metrics_t_conditioned = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(observed), xt::eval(xt::view(predicted, xt::newaxis(), xt::newaxis(), xt::all(), xt::all())), metrics, @@ -291,7 +291,7 @@ TEST(ProbabilistTests, TestMaskingConditions) // compute scores on already subset time series std::vector<xt::xarray<double>> metrics_t_subset = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(xt::view(observed_, xt::newaxis(), xt::range(0, 100))), xt::eval(xt::view(predicted, xt::newaxis(), xt::newaxis(), xt::all(), xt::range(0, 100))), metrics, @@ -332,7 +332,7 @@ TEST(ProbabilistTests, TestMissingData) {{ 4.7, 4.3, NAN, 2.7, 4.1 }}; std::vector<xt::xarray<double>> metrics_nan = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( observed_nan, forecast_nan, metrics, @@ -351,7 +351,7 @@ TEST(ProbabilistTests, TestMissingData) {{ 4.7, 4.3, 2.7 }}; std::vector<xt::xarray<double>> metrics_pp1 = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( observed_pp1, forecast_pp1, metrics, @@ -369,7 +369,7 @@ TEST(ProbabilistTests, TestMissingData) {{ 4.3, 2.7, 4.1 }}; std::vector<xt::xarray<double>> metrics_pp2 = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( observed_pp2, forecast_pp2, metrics, @@ -425,7 +425,7 @@ TEST(ProbabilistTests, TestBootstrap) {{"n_samples", 10}, {"len_sample", 3}, {"summary", 0}}; std::vector<xt::xarray<double>> metrics_bts = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(xt::view(observed, xt::newaxis(), xt::all())), xt::eval(xt::view(predicted, xt::newaxis(), xt::newaxis(), xt::all(), xt::all())), metrics, @@ -448,7 +448,7 @@ TEST(ProbabilistTests, TestBootstrap) xt::concatenate(xt::xtuple(predicted, predicted, predicted), 1); std::vector<xt::xarray<double>> metrics_rep = - evalhyd::evalp<xt::xtensor<double, 2>, xt::xtensor<double, 4>, xt::xtensor<bool, 4>>( + evalhyd::evalp( xt::eval(xt::view(observed_x3, xt::newaxis(), xt::all())), xt::eval(xt::view(predicted_x3, xt::newaxis(), xt::newaxis(), xt::all(), xt::all())), metrics,