From df97a0599cead5b87a94fa6f88ce6158807d1086 Mon Sep 17 00:00:00 2001
From: Thibault Hallouin <thibault.hallouin@inrae.fr>
Date: Tue, 3 Jan 2023 16:50:27 +0100
Subject: [PATCH] document template parameters

---
 .../evalhyd/detail/determinist/elements.hpp   | 40 ++++++-------
 .../evalhyd/detail/determinist/evaluator.hpp  | 28 +++++-----
 include/evalhyd/detail/probabilist/brier.hpp  | 28 +++++-----
 .../evalhyd/detail/probabilist/evaluator.hpp  |  8 +--
 .../evalhyd/detail/probabilist/quantiles.hpp  |  8 +--
 include/evalhyd/evald.hpp                     | 56 +++++++++++--------
 include/evalhyd/evalp.hpp                     | 52 ++++++++++-------
 7 files changed, 122 insertions(+), 98 deletions(-)

diff --git a/include/evalhyd/detail/determinist/elements.hpp b/include/evalhyd/detail/determinist/elements.hpp
index 8c8fe1b..6218e6d 100644
--- a/include/evalhyd/detail/determinist/elements.hpp
+++ b/include/evalhyd/detail/determinist/elements.hpp
@@ -33,9 +33,9 @@ namespace evalhyd
             // \return
             //     Mean observed streamflow.
             //     shape: (subsets, samples, series, 1)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 4> calc_mean_obs(
-                    const D2& q_obs,
+                    const XD2& q_obs,
                     const xt::xtensor<bool, 3>& t_msk,
                     const std::vector<xt::xkeep_slice<int>>& b_exp,
                     std::size_t n_srs,
@@ -85,9 +85,9 @@ namespace evalhyd
             // \return
             //     Mean predicted streamflow.
             //     shape: (subsets, samples, series, 1)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 4> calc_mean_prd(
-                    const D2& q_prd,
+                    const XD2& q_prd,
                     const xt::xtensor<bool, 3>& t_msk,
                     const std::vector<xt::xkeep_slice<int>>& b_exp,
                     std::size_t n_srs,
@@ -128,10 +128,10 @@ namespace evalhyd
             // \return
             //     Quadratic errors between observations and predictions.
             //     shape: (series, time)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 2> calc_quad_err(
-                    const D2& q_obs,
-                    const D2& q_prd
+                    const XD2& q_obs,
+                    const XD2& q_prd
             )
             {
                 return xt::square(q_obs - q_prd);
@@ -159,9 +159,9 @@ namespace evalhyd
             // \return
             //     Quadratic errors between observations and mean observation.
             //     shape: (subsets, samples, series, time)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 4> calc_quad_obs(
-                    const D2& q_obs,
+                    const XD2& q_obs,
                     const xt::xtensor<double, 4>& mean_obs,
                     const xt::xtensor<bool, 3>& t_msk,
                     std::size_t n_srs,
@@ -212,9 +212,9 @@ namespace evalhyd
             // \return
             //     Quadratic errors between predictions and mean prediction.
             //     shape: (subsets, samples, series, time)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 4> calc_quad_prd(
-                    const D2& q_prd,
+                    const XD2& q_prd,
                     const xt::xtensor<double, 4>& mean_prd,
                     const xt::xtensor<bool, 3>& t_msk,
                     std::size_t n_srs,
@@ -278,10 +278,10 @@ namespace evalhyd
             // \return
             //     Pearson correlation coefficients.
             //     shape: (subsets, samples, series)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 3> calc_r_pearson(
-                    const D2& q_obs,
-                    const D2& q_prd,
+                    const XD2& q_obs,
+                    const XD2& q_prd,
                     const xt::xtensor<double, 4>& mean_obs,
                     const xt::xtensor<double, 4>& mean_prd,
                     const xt::xtensor<double, 4>& quad_obs,
@@ -358,10 +358,10 @@ namespace evalhyd
             // \return
             //     Alphas, ratios of standard deviations.
             //     shape: (subsets, samples, series)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 3> calc_alpha(
-                    const D2& q_obs,
-                    const D2& q_prd,
+                    const XD2& q_obs,
+                    const XD2& q_prd,
                     const xt::xtensor<double, 4>& mean_obs,
                     const xt::xtensor<double, 4>& mean_prd,
                     const xt::xtensor<bool, 3>& t_msk,
@@ -419,10 +419,10 @@ namespace evalhyd
             // \return
             //     Biases.
             //     shape: (subsets, samples, series)
-            template <class D2>
+            template <class XD2>
             inline xt::xtensor<double, 3> calc_bias(
-                    const D2& q_obs,
-                    const D2& q_prd,
+                    const XD2& q_obs,
+                    const XD2& q_prd,
                     const xt::xtensor<bool, 3>& t_msk,
                     const std::vector<xt::xkeep_slice<int>>& b_exp,
                     std::size_t n_srs,
diff --git a/include/evalhyd/detail/determinist/evaluator.hpp b/include/evalhyd/detail/determinist/evaluator.hpp
index 8e494af..03ed47a 100644
--- a/include/evalhyd/detail/determinist/evaluator.hpp
+++ b/include/evalhyd/detail/determinist/evaluator.hpp
@@ -15,13 +15,13 @@ namespace evalhyd
 {
     namespace determinist
     {
-        template <class D2, class B2>
+        template <class XD2, class XB2>
         class Evaluator
         {
         private:
             // members for input data
-            const D2& q_obs;
-            const D2& q_prd;
+            const XD2& q_obs;
+            const XD2& q_prd;
             xt::xtensor<bool, 3> t_msk;
             const std::vector<xt::xkeep_slice<int>>& b_exp;
 
@@ -52,7 +52,7 @@ namespace evalhyd
             {
                 if (!mean_obs.has_value())
                 {
-                    mean_obs = elements::calc_mean_obs<D2>(
+                    mean_obs = elements::calc_mean_obs<XD2>(
                             q_obs, t_msk, b_exp, n_srs, n_msk, n_exp
                     );
                 }
@@ -63,7 +63,7 @@ namespace evalhyd
             {
                 if (!mean_prd.has_value())
                 {
-                    mean_prd = elements::calc_mean_prd<D2>(
+                    mean_prd = elements::calc_mean_prd<XD2>(
                             q_prd, t_msk, b_exp, n_srs, n_msk, n_exp
                     );
                 }
@@ -74,7 +74,7 @@ namespace evalhyd
             {
                 if (!quad_err.has_value())
                 {
-                    quad_err = elements::calc_quad_err<D2>(
+                    quad_err = elements::calc_quad_err<XD2>(
                             q_obs, q_prd
                     );
                 }
@@ -85,7 +85,7 @@ namespace evalhyd
             {
                 if (!quad_obs.has_value())
                 {
-                    quad_obs = elements::calc_quad_obs<D2>(
+                    quad_obs = elements::calc_quad_obs<XD2>(
                             q_obs, get_mean_obs(), t_msk,
                             n_srs, n_tim, n_msk, n_exp
                     );
@@ -97,7 +97,7 @@ namespace evalhyd
             {
                 if (!quad_prd.has_value())
                 {
-                    quad_prd = elements::calc_quad_prd<D2>(
+                    quad_prd = elements::calc_quad_prd<XD2>(
                             q_prd, get_mean_prd(), t_msk,
                             n_srs, n_tim, n_msk, n_exp
                     );
@@ -109,7 +109,7 @@ namespace evalhyd
             {
                 if (!r_pearson.has_value())
                 {
-                    r_pearson = elements::calc_r_pearson<D2>(
+                    r_pearson = elements::calc_r_pearson<XD2>(
                             q_obs, q_prd, get_mean_obs(), get_mean_prd(),
                             get_quad_obs(), get_quad_prd(), t_msk, b_exp,
                             n_srs, n_msk, n_exp
@@ -122,7 +122,7 @@ namespace evalhyd
             {
                 if (!alpha.has_value())
                 {
-                    alpha = elements::calc_alpha<D2>(
+                    alpha = elements::calc_alpha<XD2>(
                             q_obs, q_prd, get_mean_obs(), get_mean_prd(),
                             t_msk, b_exp, n_srs, n_msk, n_exp
                     );
@@ -134,7 +134,7 @@ namespace evalhyd
             {
                 if (!bias.has_value())
                 {
-                    bias = elements::calc_bias<D2>(
+                    bias = elements::calc_bias<XD2>(
                             q_obs, q_prd, t_msk, b_exp, n_srs, n_msk, n_exp
                     );
                 }
@@ -143,9 +143,9 @@ namespace evalhyd
 
         public:
             // constructor method
-            Evaluator(const D2& obs,
-                      const D2& prd,
-                      const B2& msk,
+            Evaluator(const XD2& obs,
+                      const XD2& prd,
+                      const XB2& msk,
                       const std::vector<xt::xkeep_slice<int>>& exp) :
                     q_obs{obs}, q_prd{prd}, b_exp{exp}
             {
diff --git a/include/evalhyd/detail/probabilist/brier.hpp b/include/evalhyd/detail/probabilist/brier.hpp
index 70293fc..fec0f09 100644
--- a/include/evalhyd/detail/probabilist/brier.hpp
+++ b/include/evalhyd/detail/probabilist/brier.hpp
@@ -23,10 +23,10 @@ namespace evalhyd
             // \return
             //     Event observed outcome.
             //     shape: (thresholds, time)
-            template<class V1D2>
+            template<class XV1D2>
             inline xt::xtensor<double, 2> calc_o_k(
-                    const V1D2& q_obs,
-                    const V1D2& q_thr
+                    const XV1D2& q_obs,
+                    const XV1D2& q_thr
             )
             {
                 // determine observed realisation of threshold(s) exceedance
@@ -100,10 +100,10 @@ namespace evalhyd
             // \return
             //     Event probability forecast.
             //     shape: (thresholds, time)
-            template<class V2D4, class V1D2>
+            template<class XV2D4, class XV1D2>
             inline xt::xtensor<double, 2> calc_y_k(
-                    const V2D4& q_prd,
-                    const V1D2& q_thr,
+                    const XV2D4& q_prd,
+                    const XV1D2& q_thr,
                     std::size_t n_mbr
             )
             {
@@ -171,10 +171,10 @@ namespace evalhyd
             // \return
             //     Brier score for each subset and for each threshold.
             //     shape: (subsets, samples, thresholds)
-            template <class V1D2>
+            template <class XV1D2>
             inline xt::xtensor<double, 3> calc_BS(
                     const xt::xtensor<double, 2>& bs,
-                    const V1D2& q_thr,
+                    const XV1D2& q_thr,
                     const xt::xtensor<bool, 2>& t_msk,
                     const std::vector<xt::xkeep_slice<int>>& b_exp,
                     std::size_t n_thr,
@@ -253,9 +253,9 @@ namespace evalhyd
             //     Brier score components (reliability, resolution, uncertainty)
             //     for each subset and for each threshold.
             //     shape: (subsets, samples, thresholds, components)
-            template <class V1D2>
+            template <class XV1D2>
             inline xt::xtensor<double, 4> calc_BS_CRD(
-                    const V1D2& q_thr,
+                    const XV1D2& q_thr,
                     const xt::xtensor<double, 2>& o_k,
                     const xt::xtensor<double, 2>& y_k,
                     const xt::xtensor<double, 3>& bar_o,
@@ -402,9 +402,9 @@ namespace evalhyd
             //     Brier score components (type 2 bias, discrimination, sharpness)
             //     for each subset and for each threshold.
             //     shape: (subsets, samples, thresholds, components)
-            template <class V1D2>
+            template <class XV1D2>
             inline xt::xtensor<double, 4> calc_BS_LBD(
-                    const V1D2& q_thr,
+                    const XV1D2& q_thr,
                     const xt::xtensor<double, 2>& o_k,
                     const xt::xtensor<double, 2>& y_k,
                     const xt::xtensor<bool, 2>& t_msk,
@@ -560,10 +560,10 @@ namespace evalhyd
             // \return
             //     Brier skill score for each subset and for each threshold.
             //     shape: (subsets, samples, thresholds)
-            template <class V1D2>
+            template <class XV1D2>
             inline xt::xtensor<double, 3> calc_BSS(
                     const xt::xtensor<double, 2>& bs,
-                    const V1D2& q_thr,
+                    const XV1D2& q_thr,
                     const xt::xtensor<double, 2>& o_k,
                     const xt::xtensor<double, 3>& bar_o,
                     const xt::xtensor<bool, 2>& t_msk,
diff --git a/include/evalhyd/detail/probabilist/evaluator.hpp b/include/evalhyd/detail/probabilist/evaluator.hpp
index 7f0e2eb..e58fb3e 100644
--- a/include/evalhyd/detail/probabilist/evaluator.hpp
+++ b/include/evalhyd/detail/probabilist/evaluator.hpp
@@ -16,13 +16,13 @@ namespace evalhyd
 {
     namespace probabilist
     {
-        template <class D2, class D4, class B4>
+        template <class XD2, class XD4, class XB4>
         class Evaluator
         {
         private:
             using view1d_xtensor2d_double_type = decltype(
                 xt::view(
-                        std::declval<const D2&>(),
+                        std::declval<const XD2&>(),
                         std::declval<std::size_t>(),
                         xt::all()
                 )
@@ -30,7 +30,7 @@ namespace evalhyd
 
             using view2d_xtensor4d_double_type = decltype(
                 xt::view(
-                        std::declval<const D4&>(),
+                        std::declval<const XD4&>(),
                         std::declval<std::size_t>(),
                         std::declval<std::size_t>(),
                         xt::all(),
@@ -40,7 +40,7 @@ namespace evalhyd
 
             using view2d_xtensor4d_bool_type = decltype(
                 xt::view(
-                        std::declval<const B4&>(),
+                        std::declval<const XB4&>(),
                         std::declval<std::size_t>(),
                         std::declval<std::size_t>(),
                         xt::all(),
diff --git a/include/evalhyd/detail/probabilist/quantiles.hpp b/include/evalhyd/detail/probabilist/quantiles.hpp
index c05273d..b4963c5 100644
--- a/include/evalhyd/detail/probabilist/quantiles.hpp
+++ b/include/evalhyd/detail/probabilist/quantiles.hpp
@@ -20,9 +20,9 @@ namespace evalhyd
             // \return
             //     Streamflow forecast quantiles.
             //     shape: (quantiles, time)
-            template <class V2D4>
+            template <class XV2D4>
             inline xt::xtensor<double, 2> calc_q_qnt(
-                    const V2D4& q_prd
+                    const XV2D4& q_prd
             )
             {
                 return xt::sort(q_prd, 0);
@@ -42,9 +42,9 @@ namespace evalhyd
             // \return
             //     Quantile scores for each time step.
             //     shape: (quantiles, time)
-            template <class V1D2>
+            template <class XV1D2>
             inline xt::xtensor<double, 2> calc_qs(
-                    const V1D2 &q_obs,
+                    const XV1D2 &q_obs,
                     const xt::xtensor<double, 2>& q_qnt,
                     std::size_t n_mbr
             )
diff --git a/include/evalhyd/evald.hpp b/include/evalhyd/evald.hpp
index c10ed21..2efb647 100644
--- a/include/evalhyd/evald.hpp
+++ b/include/evalhyd/evald.hpp
@@ -21,16 +21,26 @@ namespace evalhyd
     ///
     /// \rst
     ///
+    /// :Template Parameters:
+    ///
+    ///    XD2: Any 2-dimensional container class storing numeric elements
+    ///         (e.g. ``xt::xtensor<double, 2>``, ``xt::pytensor<double, 2>``,
+    ///         ``xt::rtensor<double, 2>``, etc.).
+    ///
+    ///    XB2: Any 2-dimensional container class storing boolean elements
+    ///         (e.g. ``xt::xtensor<bool, 4>``, ``xt::pytensor<bool, 4>``,
+    ///         ``xt::rtensor<bool, 4>``, etc.).
+    ///
     /// :Parameters:
     ///
-    ///    q_obs: ``xt::xtensor<double, 2>``
+    ///    q_obs: ``XD2``
     ///       Streamflow observations. Time steps with missing observations
     ///       must be assigned `NAN` values. Those time steps will be ignored
     ///       both in the observations and the predictions before the
     ///       *metrics* are computed.
     ///       shape: (1, time)
     ///
-    ///    q_prd: ``xt::xtensor<double, 2>``
+    ///    q_prd: ``XD2``
     ///       Streamflow predictions. Time steps with missing predictions
     ///       must be assigned `NAN` values. Those time steps will be ignored
     ///       both in the observations and the predictions before the
@@ -62,7 +72,7 @@ namespace evalhyd
     ///       `Pushpalatha et al. (2012)
     ///       <https://doi.org/10.1016/j.jhydrol.2011.11.055>`_.
     ///
-    ///    t_msk: ``xt::xtensor<bool, 2>``, optional
+    ///    t_msk: ``XB2``, optional
     ///       Mask used to temporally subset of the whole streamflow time series
     ///       (where True/False is used for the time steps to include/discard in
     ///       the subset). If provided, masks must feature the same number of
@@ -144,15 +154,15 @@ namespace evalhyd
     ///       evalhyd::evald(obs, prd, {"NSE"}, "none", 1, -9, msk);
     ///
     /// \endrst
-    template <class D2, class B2>
+    template <class XD2, class XB2>
     std::vector<xt::xarray<double>> evald(
-            const xt::xexpression<D2>& q_obs,
-            const xt::xexpression<D2>& q_prd,
+            const xt::xexpression<XD2>& q_obs,
+            const xt::xexpression<XD2>& q_prd,
             const std::vector<std::string>& metrics,
             const std::string& transform = "none",
             double exponent = 1,
             double epsilon = -9,
-            const xt::xexpression<B2>& t_msk = B2({}),
+            const xt::xexpression<XB2>& t_msk = XB2({}),
             const xt::xtensor<std::array<char, 32>, 1>& m_cdt = {},
             const std::unordered_map<std::string, int>& bootstrap =
                     {{"n_samples", -9}, {"len_sample", -9}, {"summary", 0}},
@@ -160,13 +170,13 @@ namespace evalhyd
     )
     {
         // check ranks of tensors
-        if (xt::get_rank<D2>::value != 2)
+        if (xt::get_rank<XD2>::value != 2)
         {
             throw std::runtime_error(
                     "observations and/or predictions are not two-dimensional"
             );
         }
-        if (xt::get_rank<B2>::value != 2)
+        if (xt::get_rank<XB2>::value != 2)
         {
             throw std::runtime_error(
                     "temporal masks are not two-dimensional"
@@ -174,10 +184,10 @@ namespace evalhyd
         }
 
         // retrieve real types of the expressions
-        const D2& q_obs_ = q_obs.derived_cast();
-        const D2& q_prd_ = q_prd.derived_cast();
+        const XD2& q_obs_ = q_obs.derived_cast();
+        const XD2& q_prd_ = q_prd.derived_cast();
 
-        const B2& t_msk_ = t_msk.derived_cast();
+        const XB2& t_msk_ = t_msk.derived_cast();
 
         // check that the metrics to be computed are valid
         utils::check_metrics(
@@ -243,7 +253,7 @@ namespace evalhyd
             // else if m_cdt provided, use them to generate t_msk
             else if (m_cdt.size() > 0)
             {
-                B2 c_msk = xt::zeros<bool>({n_msk, n_tim});
+                XB2 c_msk = xt::zeros<bool>({n_msk, n_tim});
 
                 for (std::size_t m = 0; m < n_msk; m++)
                 {
@@ -258,14 +268,14 @@ namespace evalhyd
             // if neither t_msk nor m_cdt provided, generate dummy mask
             else
             {
-                return B2({xt::ones<bool>({std::size_t{1}, n_tim})});
+                return XB2({xt::ones<bool>({std::size_t{1}, n_tim})});
             }
         };
 
         auto msk = gen_msk();
 
         // apply streamflow transformation if requested
-        auto q_transform = [&](const D2& q)
+        auto q_transform = [&](const XD2& q)
         {
             if ( transform == "none" || (transform == "pow" && exponent == 1))
             {
@@ -273,7 +283,7 @@ namespace evalhyd
             }
             else if ( transform == "sqrt" )
             {
-                return D2(xt::sqrt(q));
+                return XD2(xt::sqrt(q));
             }
             else if ( transform == "inv" )
             {
@@ -283,7 +293,7 @@ namespace evalhyd
                     epsilon = xt::mean(q_obs_)() * 0.01;
                 }
 
-                return D2(1. / (q + epsilon));
+                return XD2(1. / (q + epsilon));
             }
             else if ( transform == "log" )
             {
@@ -293,7 +303,7 @@ namespace evalhyd
                     epsilon = xt::mean(q_obs_)() * 0.01;
                 }
 
-                return D2(xt::log(q + epsilon));
+                return XD2(xt::log(q + epsilon));
             }
             else if ( transform == "pow" )
             {
@@ -305,11 +315,11 @@ namespace evalhyd
                         epsilon = xt::mean(q_obs_)() * 0.01;
                     }
 
-                    return D2(xt::pow(q + epsilon, exponent));
+                    return XD2(xt::pow(q + epsilon, exponent));
                 }
                 else
                 {
-                    return D2(xt::pow(q, exponent));
+                    return XD2(xt::pow(q, exponent));
                 }
             }
             else
@@ -320,8 +330,8 @@ namespace evalhyd
             }
         };
 
-        const D2 obs = q_transform(q_obs_);
-        const D2 prd = q_transform(q_prd_);
+        const XD2 obs = q_transform(q_obs_);
+        const XD2 prd = q_transform(q_prd_);
 
         // generate bootstrap experiment if requested
         std::vector<xt::xkeep_slice<int>> exp;
@@ -349,7 +359,7 @@ namespace evalhyd
         }
 
         // instantiate determinist evaluator
-        determinist::Evaluator<D2, B2> evaluator(obs, prd, msk, exp);
+        determinist::Evaluator<XD2, XB2> evaluator(obs, prd, msk, exp);
 
         // retrieve or compute requested metrics
         std::vector<xt::xarray<double>> r;
diff --git a/include/evalhyd/evalp.hpp b/include/evalhyd/evalp.hpp
index 0a48ae3..89088ad 100644
--- a/include/evalhyd/evalp.hpp
+++ b/include/evalhyd/evalp.hpp
@@ -21,16 +21,30 @@ namespace evalhyd
     ///
     /// \rst
     ///
+    /// :Template Parameters:
+    ///
+    ///    XD2: Any 2-dimensional container class storing numeric elements
+    ///         (e.g. ``xt::xtensor<double, 2>``, ``xt::pytensor<double, 2>``,
+    ///         ``xt::rtensor<double, 2>``, etc.).
+    ///
+    ///    XD4: Any 4-dimensional container class storing numeric elements
+    ///         (e.g. ``xt::xtensor<double, 4>``, ``xt::pytensor<double, 4>``,
+    ///         ``xt::rtensor<double, 4>``, etc.).
+    ///
+    ///    XB4: Any 4-dimensional container class storing boolean elements
+    ///         (e.g. ``xt::xtensor<bool, 4>``, ``xt::pytensor<bool, 4>``,
+    ///         ``xt::rtensor<bool, 4>``, etc.).
+    ///
     /// :Parameters:
     ///
-    ///    q_obs: ``xt::xtensor<double, 2>``
+    ///    q_obs: ``XD2``
     ///       Streamflow observations. Time steps with missing observations
     ///       must be assigned `NAN` values. Those time steps will be ignored
     ///       both in the observations and the predictions before the
     ///       *metrics* are computed.
     ///       shape: (sites, time)
     ///
-    ///    q_prd: ``xt::xtensor<double, 4>``
+    ///    q_prd: ``XD4``
     ///       Streamflow predictions. Time steps with missing predictions
     ///       must be assigned `NAN` values. Those time steps will be ignored
     ///       both in the observations and the predictions before the
@@ -40,11 +54,11 @@ namespace evalhyd
     ///    metrics: ``std::vector<std::string>``
     ///       The sequence of evaluation metrics to be computed.
     ///
-    ///    q_thr: ``xt::xtensor<double, 2>``, optional
+    ///    q_thr: ``XD2``, optional
     ///       Streamflow exceedance threshold(s).
     ///       shape: (sites, thresholds)
     ///
-    ///    t_msk: ``xt::xtensor<bool, 4>``, optional
+    ///    t_msk: ``XB4``, optional
     ///       Mask(s) used to generate temporal subsets of the whole streamflow
     ///       time series (where True/False is used for the time steps to
     ///       include/discard in a given subset). If not provided and neither
@@ -122,13 +136,13 @@ namespace evalhyd
     ///       evalhyd::evalp(obs, prd, {"CRPS"});
     ///
     /// \endrst
-    template <class D2, class D4, class B4>
+    template <class XD2, class XD4, class XB4>
     std::vector<xt::xarray<double>> evalp(
-            const xt::xexpression<D2>& q_obs,
-            const xt::xexpression<D4>& q_prd,
+            const xt::xexpression<XD2>& q_obs,
+            const xt::xexpression<XD4>& q_prd,
             const std::vector<std::string>& metrics,
-            const xt::xexpression<D2>& q_thr = D2({}),
-            const xt::xexpression<B4>& t_msk = B4({}),
+            const xt::xexpression<XD2>& q_thr = XD2({}),
+            const xt::xexpression<XB4>& t_msk = XB4({}),
             const xt::xtensor<std::array<char, 32>, 2>& m_cdt = {},
             const std::unordered_map<std::string, int>& bootstrap =
                     {{"n_samples", -9}, {"len_sample", -9}, {"summary", 0}},
@@ -136,19 +150,19 @@ namespace evalhyd
     )
     {
         // check ranks of tensors
-        if (xt::get_rank<D2>::value != 2)
+        if (xt::get_rank<XD2>::value != 2)
         {
             throw std::runtime_error(
                     "observations and/or thresholds are not two-dimensional"
             );
         }
-        if (xt::get_rank<D4>::value != 4)
+        if (xt::get_rank<XD4>::value != 4)
         {
             throw std::runtime_error(
                     "predictions are not four-dimensional"
             );
         }
-        if (xt::get_rank<B4>::value != 4)
+        if (xt::get_rank<XB4>::value != 4)
         {
             throw std::runtime_error(
                     "temporal masks are not four-dimensional"
@@ -156,11 +170,11 @@ namespace evalhyd
         }
 
         // retrieve real types of the expressions
-        const D2& q_obs_ = q_obs.derived_cast();
-        const D4& q_prd_ = q_prd.derived_cast();
-        const D2& q_thr_ = q_thr.derived_cast();
+        const XD2& q_obs_ = q_obs.derived_cast();
+        const XD4& q_prd_ = q_prd.derived_cast();
+        const XD2& q_thr_ = q_thr.derived_cast();
 
-        const B4& t_msk_ = t_msk.derived_cast();
+        const XB4& t_msk_ = t_msk.derived_cast();
 
         // check that the metrics to be computed are valid
         utils::check_metrics(
@@ -268,7 +282,7 @@ namespace evalhyd
         // generate masks from conditions if provided
         auto gen_msk = [&]()
         {
-            B4 c_msk = xt::zeros<bool>({n_sit, n_ltm, n_msk, n_tim});
+            XB4 c_msk = xt::zeros<bool>({n_sit, n_ltm, n_msk, n_tim});
             if (m_cdt.size() > 0)
             {
                 for (std::size_t s = 0; s < n_sit; s++)
@@ -290,7 +304,7 @@ namespace evalhyd
 
             return c_msk;
         };
-        const B4 c_msk = gen_msk();
+        const XB4 c_msk = gen_msk();
 
         // generate bootstrap experiment if requested
         std::vector<xt::xkeep_slice<int>> b_exp;
@@ -341,7 +355,7 @@ namespace evalhyd
                          xt::view(c_msk, s, l, xt::all(), xt::all()) :
                          xt::view(t_msk_, s, l, xt::all(), xt::all()));
 
-                probabilist::Evaluator<D2, D4, B4> evaluator(
+                probabilist::Evaluator<XD2, XD4, XB4> evaluator(
                         q_obs_v, q_prd_v, q_thr_v, t_msk_v, b_exp
                 );
 
-- 
GitLab