diff --git a/ChangeLog b/ChangeLog
index ddcb7a346dd9a4a77731ddaa75f8c695b7dbc7a4..32dc281bfbb87a0ec5eb963424b2bfd3ec4fbf9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2024-09-30  Uwe Schulzweida
+
+	* Ydrunstat: added parameter rm=c (readMethod=circular)
+
+2024-09-19  Uwe Schulzweida
+
+	* Version 2.4.4 release
+	* cmor operator update
+
 2024-09-16  Uwe Schulzweida
 
 	* Timselstat: added support for parameter nskip=-1
diff --git a/doc/tex/mod/Ydrunstat b/doc/tex/mod/Ydrunstat
index 26ff47455215d129a25984b56d713cdbf1392598..b73210457d5fa6be47d9ca39dcfb6718a7ce06da 100644
--- a/doc/tex/mod/Ydrunstat
+++ b/doc/tex/mod/Ydrunstat
@@ -24,7 +24,7 @@ only if the input time series does include the (nts-1)/2 days before and after e
 
 @BeginOperator_ydrunmin
 @Title     = Multi-year daily running minimum
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 @IfMan
@@ -47,7 +47,7 @@ o(\mbox{366},x) = \mbox{\textbf{min}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mbo
 
 @BeginOperator_ydrunmax
 @Title     = Multi-year daily running maximum
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 @IfMan
@@ -70,7 +70,7 @@ o(\mbox{366},x) = \mbox{\textbf{max}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mbo
 
 @BeginOperator_ydrunsum
 @Title     = Multi-year daily running sum
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 @IfMan
@@ -93,7 +93,7 @@ o(\mbox{366},x) = \mbox{\textbf{sum}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mbo
 
 @BeginOperator_ydrunmean
 @Title     = Multi-year daily running mean
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 @IfMan
@@ -116,7 +116,7 @@ o(\mbox{366},x) = \mbox{\textbf{mean}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mb
 
 @BeginOperator_ydrunavg
 @Title     = Multi-year daily running average
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 @IfMan
@@ -139,7 +139,7 @@ o(\mbox{366},x) = \mbox{\textbf{avg}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mbo
 
 @BeginOperator_ydrunvar
 @Title     = Multi-year daily running variance
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 Normalize by n.
@@ -164,7 +164,7 @@ o(\mbox{366},x) = \mbox{\textbf{var}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mbo
 
 @BeginOperator_ydrunvar1
 @Title     = Multi-year daily running variance (n-1)
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 Normalize by (n-1).
@@ -189,7 +189,7 @@ o(\mbox{366},x) = \mbox{\textbf{var1}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mb
 
 @BeginOperator_ydrunstd
 @Title     = Multi-year daily running standard deviation
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 Normalize by n.
@@ -214,7 +214,7 @@ o(\mbox{366},x) = \mbox{\textbf{std}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mbo
 
 @BeginOperator_ydrunstd1
 @Title     = Multi-year daily running standard deviation (n-1)
-@Parameter = nts
+@Parameter = nts [rm=c]
 
 @BeginDescription
 Normalize by (n-1).
@@ -240,6 +240,8 @@ o(\mbox{366},x) = \mbox{\textbf{std1}}\{i(t,x), i(t+1,x), ..., i(t+nts-1,x); \mb
 @BeginParameter
 @Item = nts
 INTEGER  Number of timesteps
+@Item = rm=c
+STRING   Read method circular
 @EndParameter
 
 
diff --git a/src/Ydrunstat.cc b/src/Ydrunstat.cc
index 34aedbc28dc9769f17c46c214586b3418db752a9..9e80e2cf0f049bc51d0b52f9335cac0eb42d4745 100644
--- a/src/Ydrunstat.cc
+++ b/src/Ydrunstat.cc
@@ -25,6 +25,7 @@
 #include "cdi.h"
 #include "calendar.h"
 
+#include "cdo_options.h"
 #include "process_int.h"
 #include "param_conversion.h"
 #include "datetime.h"
@@ -124,6 +125,57 @@ ydstat_finalize(YdayStats &stats, int operfunc)
       }
 }
 
+namespace
+{
+struct Parameter
+{
+  int nts{ -1 };
+  std::string rm;
+};
+}  // namespace
+
+static Parameter
+get_parameter()
+{
+  Parameter parameter;
+
+  auto numParams = cdo_operator_argc();
+  if (numParams < 1) cdo_abort("Too few arguments!");
+
+  auto param1 = cdo_operator_argv(0);
+  int start = 0;
+  if (std::isdigit(param1[0]) && !string_contains(param1, '='))
+    {
+      parameter.nts = parameter_to_int(param1);
+      start = 1;
+    }
+
+  for (int i = start; i < numParams; ++i)
+    {
+      const auto &param = cdo_operator_argv(i);
+      if (!string_contains(param, '=')) cdo_abort("Missing '=' for parameter >%s<!", param);
+      auto keyValue = split_with_seperator(param, '=');
+      if (keyValue.size() != 2) cdo_abort("Invalid parameter>%s<!", param);
+      const auto &key = keyValue[0];
+      const auto &value = keyValue[1];
+      // clang-format off
+      if      (key == "nts") parameter.nts = parameter_to_int(value);
+      else if (key == "rm")  parameter.rm += value[0];
+      else cdo_abort("Invalid parameter key >%s<!", key);
+      // clang-format on
+    }
+
+  return parameter;
+}
+
+static void
+check_parameter(const Parameter &parameter)
+{
+  if (parameter.nts == -1) cdo_abort("Too few parameter!");
+  if (parameter.nts <= 0) cdo_abort("Parameter nts must be greater than 0!");
+  if (parameter.rm.size() && parameter.rm[0] != 'c') cdo_abort("Parameter rm must only contain 'c'!");
+}
+
 class Ydrunstat : public Process
 {
 public:
@@ -156,9 +208,9 @@ private:
   int taxisID2;
   int vlistID1;
 
-  char readMethod;
+  char readMethod{ 0 };
   bool lvarstd;
-  int numDates;
+  int numDates{ -1 };
   int dpy;
 
   FieldVector3D varsData1;
@@ -173,11 +225,13 @@ public:
     auto operatorID = cdo_operator_id();
     operfunc = cdo_operator_f1(operatorID);
 
-    operator_input_arg("number of timesteps");
-    auto numParams = cdo_operator_argc();
-    numDates = parameter_to_int(cdo_operator_argv(0));
-    readMethod = (numParams == 2) ? cdo_operator_argv(1)[0] : '0';
-    operator_check_argc((numParams == 2 && readMethod == 'c') ? 2 : 1);
+    operator_input_arg("number of timesteps, read method");
+
+    auto parameter = get_parameter();
+    check_parameter(parameter);
+    numDates = parameter.nts;
+    if (parameter.rm.size()) readMethod = 'c';
+    if (Options::cdoVerbose) cdo_print("numDates=%d readMethod=%c", numDates, readMethod);
 
     auto lminmax = (operfunc == FieldFunc_Min || operfunc == FieldFunc_Max);
     lvarstd = (operfunc == FieldFunc_Std || operfunc == FieldFunc_Var || operfunc == FieldFunc_Std1 || operfunc == FieldFunc_Var1);
@@ -298,8 +352,12 @@ public:
         tsID++;
       }
 
-    if (readMethod == 'c' && cdo_assert_files_only())
+    cdo_stream_close(streamID1);
+
+    if (readMethod == 'c')
       {
+        if (cdo_assert_files_only() == false) cdo_warning("Operators cannot be piped in circular mode");
+
         auto endYear = cdiDateTimes[numDates - 1].date.year;
         auto cdiStream = streamOpenRead(cdo_get_stream_name(0));
         auto cdiVlistID = streamInqVlist(cdiStream);
@@ -356,8 +414,6 @@ public:
 
         streamClose(cdiStream);
       }
-    else if (readMethod == 'c')
-      cdo_warning("Operators cannot be piped in circular mode");
 
     ydstat_finalize(stats, operfunc);
 
@@ -388,6 +444,5 @@ public:
   close() override
   {
     cdo_stream_close(streamID2);
-    cdo_stream_close(streamID1);
   }
 };
diff --git a/src/operator_help.cc b/src/operator_help.cc
index 56b24157dd83ed3ebc1baaccbef034e3b0680be6..9a1a9c8faf3b4b388e0e45ff1e10060b80d2ff9c 100644
--- a/src/operator_help.cc
+++ b/src/operator_help.cc
@@ -4098,7 +4098,7 @@ const CdoHelp YdrunstatHelp = {
     "    ydrunvar, ydrunvar1 - Multi-year daily running statistics",
     "",
     "SYNOPSIS",
-    "    <operator>,nts  infile outfile",
+    "    <operator>,nts[,rm=c]  infile outfile",
     "",
     "DESCRIPTION",
     "    This module writes running statistical values for each day of year in infile to outfile.",
@@ -4160,7 +4160,8 @@ const CdoHelp YdrunstatHelp = {
     "               o(366,x) = var1{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[(i(t+(nts-1)/2)] = 366}",
     "",
     "PARAMETER",
-    "    nts  INTEGER  Number of timesteps",
+    "    nts   INTEGER  Number of timesteps",
+    "    rm=c  STRING   Read method circular",
 };
 
 const CdoHelp YdrunpctlHelp = {