Skip to content

Commit

Permalink
ECC-1813: GRIB2: Sub-hourly: Set step units without step
Browse files Browse the repository at this point in the history
  • Loading branch information
shahramn committed May 3, 2024
1 parent 7588a02 commit daba8ee
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 65 deletions.
2 changes: 1 addition & 1 deletion examples/C/large_grib1.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "eccodes.h"

/* See JIRA issue GRIB-361 */
int main()
int main(void)
{
const int ni = 2880;
const int nj = 2880;
Expand Down
21 changes: 20 additions & 1 deletion src/grib_accessor_class_g2end_step.cc
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,13 @@ static int unpack_one_time_range_long_(grib_accessor* a, long* val, size_t* len)
}
if (add_time_range) {
*val = start_step_value + time_range_value;
if ((err = grib_set_long_internal(h, "endStepUnit", step_units)) != GRIB_SUCCESS)
return err;
}
else {
*val = start_step_value;
if ((err = grib_set_long_internal(h, "endStepUnit", step_units)) != GRIB_SUCCESS)
return err;
}

return GRIB_SUCCESS;
Expand Down Expand Up @@ -310,9 +314,13 @@ static int unpack_one_time_range_double_(grib_accessor* a, double *val , size_t*
}
if (add_time_range) {
*val = (start_step + time_range).value<double>(eccodes::Unit(step_units));
if ((err = grib_set_long_internal(h, "endStepUnit", step_units)) != GRIB_SUCCESS)
return err;
}
else {
*val = start_step.value<double>(eccodes::Unit(start_step_unit));
if ((err = grib_set_long_internal(h, "endStepUnit", start_step_unit)) != GRIB_SUCCESS)
return err;
}

return GRIB_SUCCESS;
Expand Down Expand Up @@ -441,14 +449,19 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
grib_handle* h = grib_handle_of_accessor(a);
int ret = 0;
long start_step_value;
long start_step_unit;
long numberOfTimeRange;

if ((ret = grib_get_long_internal(h, self->start_step_value, &start_step_value)))
return ret;
if ((ret = grib_get_long_internal(h, "startStepUnit", &start_step_unit)))
return ret;

/* point in time */
if (self->year == NULL) {
*val = start_step_value;
if ((ret = grib_set_long_internal(h, "endStepUnit", start_step_unit)))
return ret;
return 0;
}

Expand Down Expand Up @@ -479,14 +492,19 @@ static int unpack_double(grib_accessor* a, double* val, size_t* len)
grib_handle* h = grib_handle_of_accessor(a);
int ret = 0;
long start_step_value;
long start_step_unit;
long numberOfTimeRange;

if ((ret = grib_get_long_internal(h, self->start_step_value, &start_step_value)))
return ret;
if ((ret = grib_get_long_internal(h, "startStepUnit", &start_step_unit)))
return ret;

/* point in time */
if (self->year == NULL) {
*val = start_step_value;
if ((ret = grib_set_long_internal(h, "endStepUnit", start_step_unit)))
return ret;
return 0;
}

Expand Down Expand Up @@ -542,7 +560,8 @@ static int pack_long_(grib_accessor* a, const long end_step_value, const long en

/*point in time */
if (self->year == NULL) {
err = grib_set_long_internal(h, "startStepUnit", end_step.unit().value<long>());
if ((err = grib_set_long_internal(h, "startStepUnit", end_step.unit().value<long>())) != GRIB_SUCCESS)
return err;
err = grib_set_long_internal(h, self->start_step_value, end_step.value<long>());
return err;
}
Expand Down
42 changes: 40 additions & 2 deletions src/grib_accessor_class_optimal_step_units.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
grib_handle* h = grib_handle_of_accessor(a);
grib_accessor_optimal_step_units* self = (grib_accessor_optimal_step_units*)a;

long start_step = 0;
long start_step_unit = 0;
long end_step = 0;
long end_step_unit = 0;
int ret;

auto supported_units = eccodes::Unit::list_supported_units();
try {
eccodes::Unit unit{*val}; // throws if not supported
Expand All @@ -198,10 +204,42 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
return GRIB_INVALID_ARGUMENT;
}

int ret;
// ECC-1813: When the stepUnits key is used without specifying a value, as in the command
// "grib-set -s stepUnits=m in.grib out.grib", the following code initiates an indirect update
// of the low-level keys: forecastTime,indicatorOfUnitOfTimeRange,indicatorOfUnitForTimeRange,lengthOfTimeRange

self->overwriteStepUnits = *val;
if ((ret = grib_set_long_internal(h, "forceStepUnits", *val)) != GRIB_SUCCESS) {
if ((ret = grib_set_long_internal(h, "forceStepUnits", *val)) != GRIB_SUCCESS)
return ret;

if ((ret = grib_get_long_internal(h, "startStep", &start_step)) != GRIB_SUCCESS)
return ret;
if ((ret = grib_get_long_internal(h, "startStepUnit", &start_step_unit)) != GRIB_SUCCESS)
return ret;
if ((ret = grib_get_long_internal(h, "endStep", &end_step)) != GRIB_SUCCESS)
return ret;
if ((ret = grib_get_long_internal(h, "endStepUnit", &end_step_unit)) != GRIB_SUCCESS)
return ret;

try {
eccodes::Step start{start_step, start_step_unit};
start.set_unit(*val);
eccodes::Step end{end_step, end_step_unit};
end.set_unit(*val);

if ((ret = grib_set_long_internal(h, "startStepUnit", start.unit().value<long>())) != GRIB_SUCCESS)
return ret;
if ((ret = grib_set_long_internal(h, "startStep", start.value<long>())) != GRIB_SUCCESS)
return ret;
if ((ret = grib_set_long_internal(h, "endStepUnit", end.unit().value<long>())) != GRIB_SUCCESS)
return ret;
if ((ret = grib_set_long_internal(h, "endStep", end.value<long>())) != GRIB_SUCCESS)
return ret;
}
catch (std::exception& e) {
std::string msg = std::string{"Failed to convert steps to: "} + std::to_string(*val) + " (" + e.what() + ")";
grib_context_log(a->context, GRIB_LOG_ERROR, "%s", msg.c_str());
return GRIB_INTERNAL_ERROR;
}

return GRIB_SUCCESS;
Expand Down
Loading

0 comments on commit daba8ee

Please sign in to comment.