From 22a938c31eca97955417a42e9e9d000ebaae14d4 Mon Sep 17 00:00:00 2001 From: Mikko Partio Date: Wed, 31 Jan 2024 17:01:10 +0200 Subject: [PATCH] Add option to set step length when specifying list of time with keys 'hours' or 'times' "hours" : "0-12-3" -> 0,3,6,9,12 "times" : "0:00:00-1:00:00-0:15:00" -> 0:00:00,0:15:00,0:30:00,0:45:00,1:00:00 --- doc/configuration.md | 22 ++++++++++++- himan-lib/include/util.h | 1 + himan-lib/source/json_parser.cpp | 6 ++-- himan-lib/source/util.cpp | 54 ++++++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/doc/configuration.md b/doc/configuration.md index 39804c37..743ad2f7 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -254,7 +254,7 @@ Multiple origin times can also be specified with key `origintimes`. -## Lead time method 1: Listing hours +## Lead time method 1: Listing times With key `hours` the hours (lead times) that should be calculated are listed. Values are separated with a comma, if a hyphen ('-') is used, Himan will interpolate values to fill the gap. @@ -266,6 +266,19 @@ Example: This example will result to hours 1,2,3,4,5,6,7 and 8. +By default when expanding a list the step value is 1, but it can be changed: + + "hours" : "1,2-8-2" + +Result: 1,2,4,6,8 + +For sub-hour values key `times` can be used: + + "times" : "0:00:00-9:00:00-0:15:00" + +Result: 0:00:00,0:15:00,0:30:00,...,9:00:00 + + ## Lead time method 2: Setting start and stop values @@ -297,6 +310,13 @@ Example: "stop_minute" : "1470", "step" : "15", +start_time and stop_time can be used to specify time duration value + + "start_time" : "0:00:00", + "stop_time" : "1:00:00", + "step" : "0:15:00" + + # Levels diff --git a/himan-lib/include/util.h b/himan-lib/include/util.h index bb5d2421..806b827c 100644 --- a/himan-lib/include/util.h +++ b/himan-lib/include/util.h @@ -55,6 +55,7 @@ std::vector Split(const std::string& s, const std::string& delims); */ std::vector ExpandString(const std::string& identifier); +std::vector ExpandTimeDuration(const std::string& identifier); /** * @brief Join a string-vector with given delimiter diff --git a/himan-lib/source/json_parser.cpp b/himan-lib/source/json_parser.cpp index 27e5b759..2d3e1ff6 100644 --- a/himan-lib/source/json_parser.cpp +++ b/himan-lib/source/json_parser.cpp @@ -765,14 +765,14 @@ void Steps(const boost::property_tree::ptree& pt, shared_ptr& con try { - vector timesStr = himan::util::Split(pt.get("times"), ","); + vector timeValues = himan::util::ExpandTimeDuration(pt.get("times")); vector times; for (const auto& originDateTime : originDateTimes) { - for (const auto& str : timesStr) + for (const auto& tv : timeValues) { - times.push_back(forecast_time(originDateTime, time_duration(str))); + times.push_back(forecast_time(originDateTime, tv)); } } conf->Times(times); diff --git a/himan-lib/source/util.cpp b/himan-lib/source/util.cpp index f7eddf4a..7f0ebea0 100644 --- a/himan-lib/source/util.cpp +++ b/himan-lib/source/util.cpp @@ -180,16 +180,27 @@ vector util::ExpandString(const std::string& identifier) // 1,5,10-12 // --> return a vector of: // 1,5,10,11,12 + // 1,5,10-16-2 + // --> return a vector of: + // 1,5,10,12,14,16 vector ret; const auto split1 = Split(identifier, ","); for (const auto& tok : split1) { - const auto split2 = Split(tok, "-"); + auto split2 = Split(tok, "-"); + + int step = 1; + + if (split2.size() == 3) + { + step = split2[2]; + split2.pop_back(); + } if (split2.size() == 2) { - int a = split2[0], b = split2[1], step = 1; + int a = split2[0], b = split2[1]; if (a > b) { step *= -1; @@ -207,6 +218,45 @@ vector util::ExpandString(const std::string& identifier) return ret; } +vector util::ExpandTimeDuration(const std::string& identifier) +{ + vector ret; + const auto split1 = Split(identifier, ","); + for (const auto& tok : split1) + { + auto split2 = Split(tok, "-"); + + time_duration step = ONE_HOUR; + + if (split2.size() == 3) + { + step = time_duration(split2[2]); + split2.pop_back(); + } + + if (split2.size() == 2) + { + time_duration a = split2[0], b = split2[1]; + if (a > b) + { + step *= -1; + } + + while (a != b) + { + ret.push_back(time_duration(a)); + a += step; + } + ret.push_back(time_duration(a)); // include end range value + } + else if (split2.size() == 1) + { + ret.push_back(split2[0]); + } + } + return ret; +} + vector util::Split(const string& s, const string& delims) { return Split(s, delims);