diff --git a/include/evalhyd/evald.hpp b/include/evalhyd/evald.hpp index a9f250b7f2f113bfb752ccf2049e599257b7d854..5fb72f96445c3124c646639ff5dae2f754cfb899 100644 --- a/include/evalhyd/evald.hpp +++ b/include/evalhyd/evald.hpp @@ -84,15 +84,14 @@ namespace evalhyd /// /// .. seealso:: :doc:`../../functionalities/temporal-masking` /// - /// m_cdt: ``xt::xtensor<std::array<char, 32>, 1>``, optional + /// m_cdt: ``xt::xtensor<std::array<char, 32>, 2>``, optional /// Masking conditions to use to generate temporal subsets. Each /// condition consists in a string and can be specified on observed /// streamflow values/statistics (mean, median, quantile), or on time /// indices. If provided in combination with *t_msk*, the latter takes /// precedence. If not provided and neither is *t_msk*, no subset is - /// performed. If provided, there must be as many conditions as there - /// are time series of observations. - /// shape: (subsets,) + /// performed. + /// shape: (series, subsets) /// /// .. seealso:: :doc:`../../functionalities/conditional-masking` /// @@ -171,7 +170,7 @@ namespace evalhyd xtl::xoptional<double, bool> epsilon = xtl::missing<double>(), const xt::xexpression<XB3>& t_msk = XB3({}), - const xt::xtensor<std::array<char, 32>, 1>& m_cdt = {}, + const xt::xtensor<std::array<char, 32>, 2>& m_cdt = {}, xtl::xoptional<const std::unordered_map<std::string, int>, bool> bootstrap = xtl::missing<const std::unordered_map<std::string, int>>(), const std::vector<std::string>& dts = {}, @@ -251,6 +250,7 @@ namespace evalhyd "observations contain more than one time series" ); } + if (t_msk_.size() > 0) { if (q_prd_.shape(0) != t_msk_.shape(0)) @@ -262,6 +262,17 @@ namespace evalhyd } } + if (m_cdt.size() > 0) + { + if (q_prd_.shape(0) != m_cdt.shape(0)) + { + throw std::runtime_error( + "predictions and masking conditions feature different " + "numbers of series" + ); + } + } + // retrieve dimensions std::size_t n_tim = q_prd_.shape(1); @@ -271,7 +282,7 @@ namespace evalhyd if ((t_msk_.size() < 1) && (m_cdt.size() > 0)) { std::size_t n_srs = q_prd_.shape(0); - std::size_t n_msk = m_cdt.shape(0); + std::size_t n_msk = m_cdt.shape(1); XB3 c_msk = xt::zeros<bool>({n_srs, n_msk, n_tim}); @@ -281,7 +292,7 @@ namespace evalhyd { xt::view(c_msk, s, m) = masks::generate_mask_from_conditions( - xt::view(m_cdt, m), + xt::view(m_cdt, s, m), xt::view(q_obs_, 0), xt::view(q_prd_, s, xt::newaxis()) ); diff --git a/include/evalhyd/evalp.hpp b/include/evalhyd/evalp.hpp index 658de7ff0132b7370e36d45bd03a55a9e0d363b8..4c49e426fe3a111ec804ca07efc0683ab4ae2276 100644 --- a/include/evalhyd/evalp.hpp +++ b/include/evalhyd/evalp.hpp @@ -95,8 +95,7 @@ namespace evalhyd /// quantile), or on time indices. If provided in combination with /// *t_msk*, the latter takes precedence. If not provided and neither /// is *t_msk*, no subset is performed and only one set of metrics is - /// returned corresponding to the whole time series. If provided, as - /// many sets of metrics are returned as they are conditions provided. + /// returned corresponding to the whole time series. /// shape: (sites, subsets) /// /// .. seealso:: :doc:`../../functionalities/conditional-masking` diff --git a/tests/test_determinist.cpp b/tests/test_determinist.cpp index be2820410e29b35935a511d5b37f305337ffa6d8..560c713fa7577de14df108c439bc33c1fa33d84c 100644 --- a/tests/test_determinist.cpp +++ b/tests/test_determinist.cpp @@ -191,9 +191,13 @@ TEST(DeterministTests, TestMaskingConditions) // conditions on streamflow values _________________________________________ // compute scores using masking conditions on streamflow to subset whole record - xt::xtensor<std::array<char, 32>, 1> q_conditions = { - std::array<char, 32> {"q_obs{<2000,>3000}"} - }; + xt::xtensor<std::array<char, 32>, 2> q_conditions = {{ + {{std::array<char, 32>{"q_obs{<2000,>3000}"}}}, + {{std::array<char, 32>{"q_obs{<2000,>3000}"}}}, + {{std::array<char, 32>{"q_obs{<2000,>3000}"}}}, + {{std::array<char, 32>{"q_obs{<2000,>3000}"}}}, + {{std::array<char, 32>{"q_obs{<2000,>3000}"}}} + }}; std::vector<xt::xarray<double>> metrics_q_conditioned = evalhyd::evald( @@ -222,9 +226,13 @@ TEST(DeterministTests, TestMaskingConditions) // conditions on streamflow statistics _____________________________________ // compute scores using masking conditions on streamflow to subset whole record - xt::xtensor<std::array<char, 32>, 1> q_conditions_ ={ - std::array<char, 32> {"q_obs{>=mean}"} - }; + xt::xtensor<std::array<char, 32>, 2> q_conditions_ = {{ + {{std::array<char, 32>{"q_obs{>=mean}"}}}, + {{std::array<char, 32>{"q_obs{>=mean}"}}}, + {{std::array<char, 32>{"q_obs{>=mean}"}}}, + {{std::array<char, 32>{"q_obs{>=mean}"}}}, + {{std::array<char, 32>{"q_obs{>=mean}"}}} + }}; double mean = xt::mean(observed, {1})(); @@ -255,9 +263,13 @@ TEST(DeterministTests, TestMaskingConditions) // conditions on temporal indices __________________________________________ // compute scores using masking conditions on time indices to subset whole record - xt::xtensor<std::array<char, 32>, 1> t_conditions = { - std::array<char, 32> {"t{0,1,2,3,4,5:97,97,98,99}"} - }; + xt::xtensor<std::array<char, 32>, 2> t_conditions = {{ + {{std::array<char, 32>{"t{0,1,2,3,4,5:97,97,98,99}"}}}, + {{std::array<char, 32>{"t{0,1,2,3,4,5:97,97,98,99}"}}}, + {{std::array<char, 32>{"t{0,1,2,3,4,5:97,97,98,99}"}}}, + {{std::array<char, 32>{"t{0,1,2,3,4,5:97,97,98,99}"}}}, + {{std::array<char, 32>{"t{0,1,2,3,4,5:97,97,98,99}"}}} + }}; std::vector<xt::xarray<double>> metrics_t_conditioned = evalhyd::evald(