diff --git a/include/evalhyd/detail/masks.hpp b/include/evalhyd/detail/masks.hpp
index 60b94f229a8d2ca94045e90999371c7b3abc3486..8a2fa4da4df28d7947806866fdddec56076655d9 100644
--- a/include/evalhyd/detail/masks.hpp
+++ b/include/evalhyd/detail/masks.hpp
@@ -35,7 +35,7 @@ namespace evalhyd
             // observed or predicted (median or mean for probabilist) streamflow
             // e.g. q{>9.} q{<9} q{>=99.0} q{<=99} q{>9,<99} q{==9} q{!=9}
             std::regex exp_q (
-                    R"((q_obs|q_prd_median|q_prd_mean)\{((([><!=]?=?(mean|median|quantile[0-9]+\.?[0-9]*|[0-9]+\.?[0-9]*)),*)+)\})"
+                    R"((q_obs|q_prd_median|q_prd_mean)\{(((<|>|<=|>=|==|!=)(mean,?|median,?|qtl[0-1]\.[0-9]+,?|[0-9]+\.?[0-9]*,?))+)\})"
             );
 
             for (std::sregex_iterator i =
@@ -51,7 +51,7 @@ namespace evalhyd
                 std::vector<std::vector<std::string>> conditions;
 
                 // pattern supported to specify masking conditions based on streamflow
-                std::regex ex (R"(([><!=]?=?)(mean|median|quantile|[0-9]+\.?[0-9]*)([0-9]+\.?[0-9]*)?)");
+                std::regex ex (R"((<|>|<=|>=|==|!=)(mean|median|qtl[0-1]\.[0-9]+|[0-9]+\.?[0-9]*))");
 
                 for (std::sregex_iterator j =
                         std::sregex_iterator(str.begin(), str.end(), ex);
@@ -59,35 +59,22 @@ namespace evalhyd
                 {
                     const std::smatch & mt = *j;
 
-                    // check that operator is provided and is supported
-                    std::set<std::string> supported_op =
-                            {"<", ">", "<=", ">=", "!=", "=="};
-                    if (mt[1].str().empty())
+                    if ((mt[2].str() == "median")
+                        || (mt[2].str() == "mean"))
                     {
-                        throw std::runtime_error(
-                                "missing operator for streamflow masking condition"
-                        );
+                        conditions.push_back({mt[1].str(), mt[2].str(), ""});
                     }
-                    else if (supported_op.find(mt[1]) != supported_op.end())
+                    else if ((mt[2].str().length() >= 3)
+                             && (mt[2].str().substr(0, 3) == "qtl"))
                     {
-                        if ((mt[2].str() == "median")
-                            || (mt[2].str() == "mean")
-                            || (mt[2].str() == "quantile"))
-                        {
-                            conditions.push_back({mt[1].str(), mt[2].str(), mt[3].str()});
-                        }
-                        else
-                        {
-                            // it is a simple numerical value, swap last two
-                            conditions.push_back({mt[1].str(), mt[3].str(), mt[2].str()});
-                        }
+                        conditions.push_back(
+                            {mt[1].str(), "qtl", mt[2].str().substr(3)}
+                        );
                     }
                     else
                     {
-                        throw std::runtime_error(
-                                "invalid operator for streamflow masking "
-                                "condition: " + mt[1].str()
-                        );
+                        // it is a simple numerical value
+                        conditions.push_back({mt[1].str(), "", mt[2].str()});
                     }
                 }
 
@@ -105,7 +92,7 @@ namespace evalhyd
 
             // pattern supported to specify conditions to generate masks on time index
             // e.g. t{0:10} t{0:10,20:30} t{0,1,2,3} t{0:10,30,40,50} t{:}
-            std::regex exp_t (R"(([t])\{(((([0-9]+|[:]):?[0-9]*),*)+)\})");
+            std::regex exp_t (R"((t)\{(:|([0-9]+:[0-9]+,?|[0-9]+,?)+)\})");
 
             for (std::sregex_iterator i =
                     std::sregex_iterator(msk_str.begin(), msk_str.end(), exp_t);
@@ -119,40 +106,46 @@ namespace evalhyd
                 // process masking conditions on time index
                 std::vector<std::vector<std::string>> condition;
 
-                // pattern supported to specify masking conditions based on time index
-                std::regex e (R"(([0-9]+|[:]):?([0-9]*))");
-
-                for (std::sregex_iterator j =
-                        std::sregex_iterator(s.begin(), s.end(), e);
-                     j != std::sregex_iterator(); j++)
+                // check whether it is all indices (i.e. t{:})
+                if (s == ":")
+                {
+                    condition.emplace_back();
+                }
+                else
                 {
-                    const std::smatch & m = *j;
+                    // pattern supported to specify masking conditions based on time index
+                    std::regex e (R"([0-9]+:[0-9]+|[0-9]+)");
 
-                    // check whether it is all indices, a range of indices, or an index
-                    if (m[1] == ":")
+                    for (std::sregex_iterator j =
+                            std::sregex_iterator(s.begin(), s.end(), e);
+                         j != std::sregex_iterator(); j++)
                     {
-                        // it is all indices (i.e. t{:}) so keep everything
-                        condition.emplace_back();
-                    }
-                    else if (m[2].str().empty())
-                    {
-                        // it is an index (i.e. t{#})
-                        condition.push_back({m[1].str()});
-                    }
-                    else
-                    {
-                        // it is a range of indices (i.e. t{#:#})
-                        // generate sequence of integer indices from range
-                        std::vector<int> vi(std::stoi(m[2].str())
-                                            - std::stoi(m[1].str()));
-                        std::iota(vi.begin(), vi.end(), std::stoi(m[1].str()));
-                        // convert to sequence of integer indices to string indices
-                        std::vector<std::string> vs;
-                        std::transform(std::begin(vi), std::end(vi),
-                                       std::back_inserter(vs),
-                                       [](int d) { return std::to_string(d); });
-
-                        condition.push_back(vs);
+                        const std::smatch & m = *j;
+
+                        // check whether it is a range of indices, or an index
+                        if (m[0].str().find(":") != std::string::npos)
+                        {
+                            // it is a range of indices (i.e. t{#:#})
+                            std::string s_ = m[0].str();
+                            std::string beg = s_.substr(0, s_.find(":"));
+                            std::string end = s_.substr(s_.find(":") + 1);
+
+                            // generate sequence of integer indices from range
+                            std::vector<int> vi(std::stoi(end) - std::stoi(beg));
+                            std::iota(vi.begin(), vi.end(), std::stoi(beg));
+                            // convert to sequence of integer indices to string indices
+                            std::vector<std::string> vs;
+                            std::transform(std::begin(vi), std::end(vi),
+                                           std::back_inserter(vs),
+                                           [](int d) { return std::to_string(d); });
+
+                            condition.push_back(vs);
+                        }
+                        else
+                        {
+                            // it is an index (i.e. t{#})
+                            condition.push_back({m[0].str()});
+                        }
                     }
                 }
 
@@ -232,8 +225,6 @@ namespace evalhyd
                     auto q = get_q();
 
                     // define lambda function to precompute mean/median/quantile
-
-
                     auto get_val =
                             [&](const std::string& str, const std::string& num)
                     {
@@ -249,7 +240,7 @@ namespace evalhyd
                         {
                             return xt::mean(q)();
                         }
-                        else  // (str == "quantile")
+                        else  // (str == "qtl")
                         {
                             return xt::quantile(q, {std::stod(num)})();
                         }
@@ -266,7 +257,7 @@ namespace evalhyd
                     if (cond.size() == 2)
                     {
                         opr1 = cond[0][0];
-                        val1= get_val(cond[0][1], cond[0][2]);
+                        val1 = get_val(cond[0][1], cond[0][2]);
                         opr2 = cond[1][0];
                         val2 = get_val(cond[1][1], cond[1][2]);