diff --git a/include/evalhyd/evald.hpp b/include/evalhyd/evald.hpp
index a3af81b522bd7fd5247b88febbc67dfac56613e9..248071dcdffbc5f58044813a1ef54848a57be116 100644
--- a/include/evalhyd/evald.hpp
+++ b/include/evalhyd/evald.hpp
@@ -35,14 +35,17 @@ namespace evalhyd
     /// :Parameters:
     ///
     ///    q_obs: ``xt::xexpression<A>``
-    ///       Streamflow observations. Time steps with missing observation
+    ///       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::xexpression<A>``
-    ///       Streamflow predictions.
+    ///       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
+    ///       *metrics* are computed.
     ///       shape: ({1+, ...}, time)
     ///
     ///    metrics: ``std::vector<std::string>``
diff --git a/src/determinist/evaluator.hpp b/src/determinist/evaluator.hpp
index 95f034643a401d6e9adf9d239fe2e8fea613320c..124b9f06d3bc566a8bf7b761277b2426d0d77e9e 100644
--- a/src/determinist/evaluator.hpp
+++ b/src/determinist/evaluator.hpp
@@ -26,10 +26,20 @@ namespace evalhyd
         template <class A>
         class Evaluator
         {
+        // define type for function to be used to "mask" (i.e. yield NaNs) the
+        // time steps for which the observations/predictions are missing data
+        typedef xt::xfunction<xt::detail::conditional_ternary,
+                              xt::xfunction<xt::math::isnan_fun, const A&>,
+                              xt::xscalar<float>,
+                              const A&> nan_function;
+
         private:
             // members for input data
-            const A& q_obs;
-            const A& q_prd;
+            const A& _q_obs;
+            const A& _q_prd;
+            nan_function q_obs;
+            nan_function q_prd;
+
             // members for computational elements
             A mean_obs;
             A mean_prd;
@@ -43,17 +53,33 @@ namespace evalhyd
             // constructor method
             Evaluator(const xt::xexpression<A>& obs,
                       const xt::xexpression<A>& prd) :
-                    q_obs{obs.derived_cast()},
-                    q_prd{prd.derived_cast()}
+                    _q_obs{obs.derived_cast()},
+                    _q_prd{prd.derived_cast()},
+                    // "mask" (i.e. use NaN) observations where predictions are
+                    // missing (i.e. NaN)
+                    q_obs{xt::where(xt::isnan(prd.derived_cast()),
+                                    NAN, obs.derived_cast())},
+                    // "mask" (i.e. use NaN) predictions where observations are
+                    // missing (i.e. NaN)
+                    q_prd{xt::where(xt::isnan(obs.derived_cast()),
+                                    NAN, prd.derived_cast())}
             {
                 // check that data dimensions are compatible
-                if (q_prd.dimension() != q_obs.dimension())
+                if (_q_prd.dimension() != _q_obs.dimension())
                 {
                     throw std::runtime_error(
                             "number of dimensions of 'sim' and 'obs' "
                             "must be identical"
                     );
                 }
+                else if (_q_prd.shape(_q_prd.dimension() - 1)
+                         != _q_obs.shape( _q_obs.dimension() - 1))
+                {
+                    throw std::runtime_error(
+                            "length of time series of 'sim' and 'obs' "
+                            "must be identical"
+                    );
+                }
             };
 
             // members for evaluation metrics
@@ -103,10 +129,7 @@ namespace evalhyd
         template <class A>
         void Evaluator<A>::calc_mean_prd()
         {
-            mean_prd = xt::nanmean(
-                    xt::where(xt::isnan(q_obs), NAN, q_prd),
-                    -1, xt::keep_dims
-            );
+            mean_prd = xt::nanmean(q_prd, -1, xt::keep_dims);
         }
 
         // Compute the quadratic error between observations and predictions.
@@ -157,9 +180,7 @@ namespace evalhyd
         template <class A>
         void Evaluator<A>::calc_quad_prd()
         {
-            quad_prd = xt::square(
-                    xt::where(xt::isnan(q_obs), NAN, q_prd) - mean_prd
-            );
+            quad_prd = xt::square(q_prd - mean_prd);
         }
 
         // Compute the Pearson correlation coefficient.
@@ -191,8 +212,7 @@ namespace evalhyd
             // calculate error in timing and dynamics $r_{pearson}$
             // (Pearson's correlation coefficient)
             auto r_num = xt::nansum(
-                    (xt::where(xt::isnan(q_obs), NAN, q_prd) - mean_prd)
-                    * (q_obs - mean_obs),
+                    (q_prd - mean_prd) * (q_obs - mean_obs),
                     -1, xt::keep_dims
             );
             auto r_den = xt::sqrt(
@@ -218,8 +238,7 @@ namespace evalhyd
         void Evaluator<A>::calc_bias()
         {
             // calculate $bias$
-            bias = xt::nansum(xt::where(xt::isnan(q_obs), NAN, q_prd),
-                              -1, xt::keep_dims)
+            bias = xt::nansum(q_prd, -1, xt::keep_dims)
                    / xt::nansum(q_obs, -1, xt::keep_dims);
         }
 
@@ -287,8 +306,7 @@ namespace evalhyd
         void Evaluator<A>::calc_KGE()
         {
             // calculate error in spread of flow $alpha$
-            auto q_prd_ = xt::where(xt::isnan(q_obs), NAN, q_prd);
-            auto alpha = detail::std_dev(q_prd_, mean_prd)
+            auto alpha = detail::std_dev(q_prd, mean_prd)
                          / detail::std_dev(q_obs, mean_obs);
 
             // compute KGE
@@ -326,8 +344,7 @@ namespace evalhyd
         void Evaluator<A>::calc_KGEPRIME()
         {
             // calculate error in spread of flow $gamma$
-            auto q_prd_ = xt::where(xt::isnan(q_obs), NAN, q_prd);
-            auto gamma = (detail::std_dev(q_prd_, mean_prd) / mean_prd)
+            auto gamma = (detail::std_dev(q_prd, mean_prd) / mean_prd)
                          / (detail::std_dev(q_obs, mean_obs) / mean_obs);
 
             // compute KGE
diff --git a/tests/test_determinist.cpp b/tests/test_determinist.cpp
index 8ef2fec6e58d2d7ff1d40d82da2cfbb688966265..89c213e56172fa0483de3a2af82a20efbbaa7405 100644
--- a/tests/test_determinist.cpp
+++ b/tests/test_determinist.cpp
@@ -189,6 +189,12 @@ TEST(DeterministTests, TestMissingData)
 
     // add some missing observations artificially by assigning NaN values
     xt::view(observed, xt::all(), xt::range(0, 20)) = NAN;
+    // add some missing predictions artificially by assigning NaN values
+    xt::view(observed, 0, xt::range(20, 23)) = NAN;
+    xt::view(observed, 1, xt::range(20, 26)) = NAN;
+    xt::view(observed, 2, xt::range(20, 29)) = NAN;
+    xt::view(observed, 3, xt::range(20, 32)) = NAN;
+    xt::view(observed, 4, xt::range(20, 35)) = NAN;
 
     // compute metrics with observations containing NaN values
     std::vector<xt::xarray<double>> metrics_nan =
@@ -196,19 +202,27 @@ TEST(DeterministTests, TestMissingData)
                     observed, predicted, metrics
             );
 
-    // compute metrics on subset of observations and predictions
-    // (i.e. eliminating region with NaN in observations manually)
-    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_sbs =
-            evalhyd::evald<xt::xtensor<double, 2>>(
-                    obs, prd, metrics
-            );
-
     for (int m = 0; m < metrics.size(); m++) {
-        EXPECT_TRUE(
-                xt::allclose(metrics_nan[m], metrics_sbs[m])
-        ) << "Failure for (" << metrics[m] << ")";
+        for (int p = 0; p < predicted.shape(0); p++) {
+            // compute metrics on subset of observations and predictions
+            // (i.e. eliminating region with NaN in observations manually)
+            xt::xtensor<double, 1> obs =
+                    xt::view(observed, 0, xt::range(3*(p+1), _));
+            xt::xtensor<double, 1> prd =
+                    xt::view(predicted, p, xt::range(3*(p+1), _));
+
+            std::vector<xt::xarray<double>> metrics_sbs =
+                    evalhyd::evald<xt::xtensor<double, 1>>(
+                            obs, prd, {metrics[m]}
+                    );
+
+            // compare to check results are the same
+            EXPECT_TRUE(
+                    xt::allclose(
+                            xt::view(metrics_nan[m], p),
+                            metrics_sbs[0]
+                    )
+            ) << "Failure for (" << metrics[m] << ")";
+        }
     }
 }
\ No newline at end of file