mirror of https://github.com/ecmwf/eccodes.git
ECC-1620: Remove double packing and unpacking
This commit is contained in:
parent
1f268a57c6
commit
febbca0c3f
|
@ -14,6 +14,7 @@ codetable[1] indicatorOfUnitOfTimeRange ('4.4.table',masterDir,localDir) : dump
|
|||
#alias forecastTimeUnit = indicatorOfUnitOfTimeRange;
|
||||
#template_nofail default_step_units "grib2/localConcepts/[centre:s]/default_step_units.def";
|
||||
#codetable[1] stepUnits 'stepUnits.table' = defaultStepUnits : transient,dump,no_copy;
|
||||
transient useOptimalStepUnits = 0;
|
||||
meta stepUnits optimal_step_units(forecastTime,indicatorOfUnitOfTimeRange,lengthOfTimeRange,indicatorOfUnitForTimeRange) : dump;
|
||||
|
||||
# Forecast time in units defined by previous octet (GRIB-29: supports negative forecast time)
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
CLASS = accessor
|
||||
SUPER = grib_accessor_class_long
|
||||
IMPLEMENTS = unpack_long;pack_long
|
||||
IMPLEMENTS = unpack_double;pack_double
|
||||
IMPLEMENTS = unpack_string;pack_string
|
||||
IMPLEMENTS = init;dump
|
||||
MEMBERS = const char* start_step
|
||||
|
@ -59,10 +58,8 @@ or edit "accessor.class" and rerun ./make_class.pl
|
|||
|
||||
*/
|
||||
|
||||
static int pack_double(grib_accessor*, const double* val, size_t* len);
|
||||
static int pack_long(grib_accessor*, const long* val, size_t* len);
|
||||
static int pack_string(grib_accessor*, const char*, size_t* len);
|
||||
static int unpack_double(grib_accessor*, double* val, size_t* len);
|
||||
static int unpack_long(grib_accessor*, long* val, size_t* len);
|
||||
static int unpack_string(grib_accessor*, char*, size_t* len);
|
||||
static void dump(grib_accessor*, grib_dumper*);
|
||||
|
@ -117,9 +114,9 @@ static grib_accessor_class _grib_accessor_class_g2end_step = {
|
|||
0, /* is_missing */
|
||||
&pack_long, /* pack_long */
|
||||
&unpack_long, /* unpack_long */
|
||||
&pack_double, /* pack_double */
|
||||
0, /* pack_double */
|
||||
0, /* pack_float */
|
||||
&unpack_double, /* unpack_double */
|
||||
0, /* unpack_double */
|
||||
0, /* unpack_float */
|
||||
&pack_string, /* pack_string */
|
||||
&unpack_string, /* unpack_string */
|
||||
|
@ -233,7 +230,7 @@ static int is_special_expver(grib_handle* h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int convert_time_range(
|
||||
static int convert_time_range_long_(
|
||||
grib_handle* h,
|
||||
long stepUnits, /* unit */
|
||||
long indicatorOfUnitForTimeRange, /* coded_unit */
|
||||
|
@ -269,7 +266,8 @@ static int convert_time_range(
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int unpack_one_time_range(grib_accessor* a, long* val, size_t* len)
|
||||
|
||||
static int unpack_one_time_range_long_(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
int err = 0;
|
||||
|
@ -292,7 +290,7 @@ static int unpack_one_time_range(grib_accessor* a, long* val, size_t* len)
|
|||
if ((err = grib_get_long_internal(h, self->typeOfTimeIncrement, &typeOfTimeIncrement)))
|
||||
return err;
|
||||
|
||||
err = convert_time_range(h, unit, coded_unit, &coded_time_range);
|
||||
err = convert_time_range_long_(h, unit, coded_unit, &coded_time_range);
|
||||
if (err != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
|
@ -314,8 +312,9 @@ static int unpack_one_time_range(grib_accessor* a, long* val, size_t* len)
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#define MAX_NUM_TIME_RANGES 16 /* maximum number of time range specifications */
|
||||
static int unpack_multiple_time_ranges(grib_accessor* a, long* val, size_t* len)
|
||||
static int unpack_multiple_time_ranges_long_(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
int i = 0, err = 0;
|
||||
|
@ -354,7 +353,7 @@ static int unpack_multiple_time_ranges(grib_accessor* a, long* val, size_t* len)
|
|||
long the_coded_unit = arr_coded_unit[i];
|
||||
long the_coded_time_range = arr_coded_time_range[i];
|
||||
|
||||
err = convert_time_range(h, unit, the_coded_unit, &the_coded_time_range);
|
||||
err = convert_time_range_long_(h, unit, the_coded_unit, &the_coded_time_range);
|
||||
if (err != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
|
@ -368,6 +367,7 @@ static int unpack_multiple_time_ranges(grib_accessor* a, long* val, size_t* len)
|
|||
return GRIB_DECODING_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// For the old implementation of unpack_long, see
|
||||
// src/deprecated/grib_accessor_class_g2end_step.unpack_long.cc
|
||||
//
|
||||
|
@ -394,18 +394,19 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
Assert(numberOfTimeRange == 1 || numberOfTimeRange == 2);
|
||||
|
||||
if (numberOfTimeRange == 1) {
|
||||
ret = unpack_one_time_range(a, val, len);
|
||||
ret = unpack_one_time_range_long_(a, val, len);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
ret = unpack_multiple_time_ranges(a, val, len);
|
||||
ret = unpack_multiple_time_ranges_long_(a, val, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
// TODO(maee): Re-implement calendar-based stepRange using std::chrono
|
||||
|
||||
|
||||
static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
|
@ -513,6 +514,7 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
|
@ -550,29 +552,6 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
}
|
||||
|
||||
|
||||
static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
|
||||
long step_units;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
Step end_step{*val, step_units};
|
||||
|
||||
end_step.optimize_unit();
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", end_step.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
long end_step_value = end_step.value<long>();
|
||||
|
||||
if ((ret = pack_long(a, &end_step_value, len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
||||
{
|
||||
//grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
|
@ -583,29 +562,10 @@ static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
|||
if ((ret = grib_set_long_internal(h, "stepUnits", end_step.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
double end_step_value = end_step.value<double>();
|
||||
long end_step_value = end_step.value<long>();
|
||||
size_t end_step_len = 0;
|
||||
|
||||
if ((ret = pack_double(a, &end_step_value, &end_step_len)) != GRIB_SUCCESS)
|
||||
if ((ret = pack_long(a, &end_step_value, &end_step_len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int unpack_double(grib_accessor* a, double* val, size_t* len)
|
||||
{
|
||||
//grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
|
||||
long a_val;
|
||||
if ((ret = unpack_long(a, &a_val, len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
long step_units;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
Step end_step{a_val, step_units};
|
||||
*val = end_step.value<double>();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
SUPER = grib_accessor_class_gen
|
||||
IMPLEMENTS = pack_string;unpack_string;value_count
|
||||
IMPLEMENTS = unpack_long;pack_long
|
||||
IMPLEMENTS = unpack_double;pack_double
|
||||
IMPLEMENTS = unpack_string;pack_string
|
||||
IMPLEMENTS = get_native_type;string_length
|
||||
IMPLEMENTS = init
|
||||
|
@ -45,10 +44,8 @@ or edit "accessor.class" and rerun ./make_class.pl
|
|||
*/
|
||||
|
||||
static int get_native_type(grib_accessor*);
|
||||
static int pack_double(grib_accessor*, const double* val, size_t* len);
|
||||
static int pack_long(grib_accessor*, const long* val, size_t* len);
|
||||
static int pack_string(grib_accessor*, const char*, size_t* len);
|
||||
static int unpack_double(grib_accessor*, double* val, size_t* len);
|
||||
static int unpack_long(grib_accessor*, long* val, size_t* len);
|
||||
static int unpack_string(grib_accessor*, char*, size_t* len);
|
||||
static size_t string_length(grib_accessor*);
|
||||
|
@ -87,9 +84,9 @@ static grib_accessor_class _grib_accessor_class_g2step_range = {
|
|||
0, /* is_missing */
|
||||
&pack_long, /* pack_long */
|
||||
&unpack_long, /* unpack_long */
|
||||
&pack_double, /* pack_double */
|
||||
0, /* pack_double */
|
||||
0, /* pack_float */
|
||||
&unpack_double, /* unpack_double */
|
||||
0, /* unpack_double */
|
||||
0, /* unpack_float */
|
||||
&pack_string, /* pack_string */
|
||||
&unpack_string, /* unpack_string */
|
||||
|
@ -249,42 +246,6 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
return pack_string(a, buff, &bufflen);
|
||||
}
|
||||
|
||||
static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
||||
{
|
||||
// TODO(EB)
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static int unpack_double(grib_accessor* a, double* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2step_range* self = (grib_accessor_g2step_range*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
char buf[100];
|
||||
int ret = 0;
|
||||
size_t size = 0;
|
||||
long start_value = 0;
|
||||
long end_value = 0;
|
||||
long step_units_value = 0;
|
||||
|
||||
if ((ret = grib_get_long_internal(h, self->startStep, &start_value)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units_value)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
Step start_step = Step(start_value, step_units_value);
|
||||
start_step.hide_hour_unit();
|
||||
if (self->endStep == NULL) {
|
||||
*val = start_step.value<double>();
|
||||
}
|
||||
else {
|
||||
if ((ret = grib_get_long_internal(h, self->endStep, &end_value)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
Step end_step = Step(end_value, step_units_value);
|
||||
*val = end_step.value<double>();
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
|
|
|
@ -167,17 +167,18 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
|
||||
auto start_step_opt = get_step(h, self->forecastTime, self->indicatorOfUnitOfTimeRange);
|
||||
auto end_step_opt = get_step(h, self->lengthOfTimeRange, self->indicatorOfUnitForTimeRange);
|
||||
auto forecast_time_opt = get_step(h, self->forecastTime, self->indicatorOfUnitOfTimeRange);
|
||||
auto lenght_of_time_range_opt = get_step(h, self->lengthOfTimeRange, self->indicatorOfUnitForTimeRange);
|
||||
|
||||
if (!(start_step_opt && end_step_opt)) {
|
||||
if (!(forecast_time_opt && lenght_of_time_range_opt)) {
|
||||
*val = UnitType{Unit::HOUR}.to_long();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
Step start_step = start_step_opt.value_or(Step{});
|
||||
Step end_step = end_step_opt.value_or(Step{});
|
||||
Step forecast_time = forecast_time_opt.value_or(Step{});
|
||||
Step length_of_time_range = lenght_of_time_range_opt.value_or(Step{});
|
||||
|
||||
auto [step_a, step_b] = find_common_units(start_step.optimize_unit(), end_step.optimize_unit());
|
||||
auto [step_a, step_b] = find_common_units(forecast_time.optimize_unit(), (forecast_time + length_of_time_range).optimize_unit());
|
||||
*val = step_a.unit().to_long();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
CLASS = accessor
|
||||
SUPER = grib_accessor_class_long
|
||||
IMPLEMENTS = unpack_long;pack_long
|
||||
IMPLEMENTS = unpack_double;pack_double
|
||||
IMPLEMENTS = unpack_string;pack_string
|
||||
IMPLEMENTS = init;dump
|
||||
MEMBERS = const char* codedStep
|
||||
|
@ -42,10 +41,8 @@ or edit "accessor.class" and rerun ./make_class.pl
|
|||
|
||||
*/
|
||||
|
||||
static int pack_double(grib_accessor*, const double* val, size_t* len);
|
||||
static int pack_long(grib_accessor*, const long* val, size_t* len);
|
||||
static int pack_string(grib_accessor*, const char*, size_t* len);
|
||||
static int unpack_double(grib_accessor*, double* val, size_t* len);
|
||||
static int unpack_long(grib_accessor*, long* val, size_t* len);
|
||||
static int unpack_string(grib_accessor*, char*, size_t* len);
|
||||
static void dump(grib_accessor*, grib_dumper*);
|
||||
|
@ -87,9 +84,9 @@ static grib_accessor_class _grib_accessor_class_step_in_units = {
|
|||
0, /* is_missing */
|
||||
&pack_long, /* pack_long */
|
||||
&unpack_long, /* unpack_long */
|
||||
&pack_double, /* pack_double */
|
||||
0, /* pack_double */
|
||||
0, /* pack_float */
|
||||
&unpack_double, /* unpack_double */
|
||||
0, /* unpack_double */
|
||||
0, /* unpack_float */
|
||||
&pack_string, /* pack_string */
|
||||
&unpack_string, /* unpack_string */
|
||||
|
@ -174,23 +171,23 @@ static const int u2s[] = {
|
|||
1800 /* (15) 30 minutes */
|
||||
};
|
||||
|
||||
|
||||
static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret;
|
||||
|
||||
int err = 0;
|
||||
long codedStep, codedUnits, stepUnits;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int factor = 0;
|
||||
long u2sf, u2sf_step_unit;
|
||||
|
||||
|
||||
if ((ret = grib_get_long_internal(h, self->codedUnits, &codedUnits)))
|
||||
return ret;
|
||||
if ((ret = grib_get_long_internal(h, self->stepUnits, &stepUnits)))
|
||||
return ret;
|
||||
if ((ret = grib_get_long_internal(h, self->codedStep, &codedStep)))
|
||||
return ret;
|
||||
if ((err = grib_get_long_internal(h, self->codedUnits, &codedUnits)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->stepUnits, &stepUnits)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->codedStep, &codedStep)))
|
||||
return err;
|
||||
|
||||
if (stepUnits != codedUnits) {
|
||||
*val = codedStep * u2s2[codedUnits];
|
||||
|
@ -209,9 +206,9 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
}
|
||||
|
||||
if (*val % u2sf_step_unit != 0) {
|
||||
ret = grib_set_long_internal(h, self->stepUnits, codedUnits);
|
||||
err = grib_set_long_internal(h, self->stepUnits, codedUnits);
|
||||
*val = codedStep;
|
||||
return ret;
|
||||
return err;
|
||||
}
|
||||
*val = *val / u2sf_step_unit;
|
||||
}
|
||||
|
@ -221,11 +218,11 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
|
||||
int err = 0;
|
||||
long codedStep, codedUnits, stepUnits;
|
||||
long oldStep = 0;
|
||||
|
@ -275,21 +272,36 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
return grib_set_long_internal(grib_handle_of_accessor(a), self->codedStep, codedStep);
|
||||
}
|
||||
|
||||
|
||||
static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
||||
{
|
||||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
size_t value_len = 0;
|
||||
|
||||
Step step = step_from_string(val);
|
||||
step.optimize_unit();
|
||||
long step_units;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if ((ret = grib_set_long_internal(h, self->stepUnits, step.unit().to_long())))
|
||||
long end_step_value;
|
||||
if ((ret = grib_get_long_internal(h, "endStep", &end_step_value)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
long step_value = step.value<long>();
|
||||
if ((ret = pack_long(a, &step_value, len)) != GRIB_SUCCESS)
|
||||
Step end_step{end_step_value, UnitType{step_units}};
|
||||
|
||||
auto [step_a, step_b] = find_common_units(step, end_step);
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_a.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
long value = step.value<long>(step_a.unit());
|
||||
|
||||
if ((ret = pack_long(a, &value, &value_len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
//if ((ret = pack_long(a, &value, &value_len)) != GRIB_SUCCESS)
|
||||
//return ret;
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -298,84 +310,26 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
|
||||
long step_units_old;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units_old)) != GRIB_SUCCESS)
|
||||
long value;
|
||||
size_t value_len;
|
||||
if ((ret = unpack_long(a, &value, &value_len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", UnitType{Unit::SECOND}.to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
long step_value;
|
||||
size_t step_len = 0;
|
||||
if ((ret = unpack_long(a, &step_value, &step_len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
|
||||
Step step(step_value, Unit::SECOND);
|
||||
step.set_unit(step_units_old);
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_units_old)) != GRIB_SUCCESS)
|
||||
long step_units;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
Step step{value, step_units};
|
||||
step.hide_hour_unit();
|
||||
//snprintf(val, *len, "%ld", value);
|
||||
|
||||
if (is_future_output_enabled(h)) {
|
||||
snprintf(val, *len, "%s", step.to_string().c_str());
|
||||
}
|
||||
else {
|
||||
snprintf(val, *len, "%ld", step.value<long>());
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
||||
{
|
||||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
|
||||
long step_units;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
Step start_step{*val, step_units};
|
||||
|
||||
start_step.optimize_unit();
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", start_step.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
long start_step_value = start_step.value<long>();
|
||||
|
||||
if ((ret = pack_long(a, &start_step_value, len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int unpack_double(grib_accessor* a, double* val, size_t* len)
|
||||
{
|
||||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret;
|
||||
|
||||
long step_units_old;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units_old)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
UnitType step_units{step_units_old};
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", UnitType{Unit::SECOND}.to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
long value_secs;
|
||||
size_t value_secs_len = 0;
|
||||
if ((ret = unpack_long(a, &value_secs, &value_secs_len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
Step step(value_secs, Unit::SECOND);
|
||||
step.set_unit(step_units_old);
|
||||
*val = step.value<double>();
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_units_old)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
|
172
src/step.cc
172
src/step.cc
|
@ -12,14 +12,35 @@
|
|||
|
||||
UnitType::Map UnitType::map_{};
|
||||
|
||||
std::vector<Unit> UnitType::unitOrder = {
|
||||
Unit::SECOND,
|
||||
Unit::MINUTE,
|
||||
Unit::HOUR,
|
||||
};
|
||||
|
||||
std::vector<Unit> UnitType::unit_order_ = {
|
||||
Unit::SECOND,
|
||||
Unit::MINUTE,
|
||||
Unit::HOUR,
|
||||
//Unit::DAY,
|
||||
};
|
||||
|
||||
std::vector<Unit> UnitType::complete_unit_order_ = {
|
||||
Unit::MISSING ,
|
||||
Unit::SECOND ,
|
||||
Unit::MINUTE ,
|
||||
Unit::MINUTES15 ,
|
||||
Unit::MINUTES30 ,
|
||||
Unit::HOUR ,
|
||||
Unit::HOURS3 ,
|
||||
Unit::HOURS6 ,
|
||||
Unit::HOURS12 ,
|
||||
Unit::DAY ,
|
||||
Unit::MONTH ,
|
||||
Unit::YEAR ,
|
||||
Unit::YEARS10 ,
|
||||
Unit::YEARS30 ,
|
||||
Unit::CENTURY
|
||||
};
|
||||
|
||||
|
||||
Step step_from_string(std::string step) {
|
||||
Step step_from_string(std::string step)
|
||||
{
|
||||
std::regex re("([0-9.]+)([smhDMYC]?)");
|
||||
std::smatch match;
|
||||
if (std::regex_match(step, match, re)) {
|
||||
|
@ -35,7 +56,9 @@ Step step_from_string(std::string step) {
|
|||
throw std::runtime_error("Could not parse step: " + step);
|
||||
}
|
||||
|
||||
std::vector<Step> parse_range(const std::string& range_str) {
|
||||
|
||||
std::vector<Step> parse_range(const std::string& range_str)
|
||||
{
|
||||
std::vector<Step> steps;
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type prev = 0;
|
||||
|
@ -48,31 +71,52 @@ std::vector<Step> parse_range(const std::string& range_str) {
|
|||
}
|
||||
|
||||
|
||||
bool Step::operator==(const Step& other) const {
|
||||
bool Step::operator==(const Step& other) const
|
||||
{
|
||||
if ((internal_value_ == other.internal_value_) && (internal_unit_ == other.internal_unit_)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Step Step::operator+(const Step& step) {
|
||||
|
||||
bool Step::operator>(const Step& step) const
|
||||
{
|
||||
auto [a, b] = find_common_units(this->copy().optimize_unit(), step.copy().optimize_unit());
|
||||
assert(a.internal_unit_ == b.internal_unit_);
|
||||
return a.internal_value_ > b.internal_value_;
|
||||
}
|
||||
|
||||
|
||||
bool Step::operator<(const Step& step) const
|
||||
{
|
||||
auto [a, b] = find_common_units(this->copy().optimize_unit(), step.copy().optimize_unit());
|
||||
assert(a.internal_unit_ == b.internal_unit_);
|
||||
return a.internal_value_ < b.internal_value_;
|
||||
}
|
||||
|
||||
|
||||
Step Step::operator+(const Step& step) const
|
||||
{
|
||||
Step tmp = step;
|
||||
auto [a, b] = find_common_units(this->optimize_unit(), tmp.optimize_unit());
|
||||
auto [a, b] = find_common_units(this->copy().optimize_unit(), tmp.copy().optimize_unit());
|
||||
assert(a.internal_unit_ == b.internal_unit_);
|
||||
return Step(a.internal_value_ + b.internal_value_, a.internal_unit_);
|
||||
}
|
||||
|
||||
Step Step::operator-(const Step& step) {
|
||||
|
||||
Step Step::operator-(const Step& step) const
|
||||
{
|
||||
Step tmp = step;
|
||||
auto [a, b] = find_common_units(this->optimize_unit(), tmp.optimize_unit());
|
||||
auto [a, b] = find_common_units(this->copy().optimize_unit(), tmp.copy().optimize_unit());
|
||||
assert(a.internal_unit_ == b.internal_unit_);
|
||||
if (a.internal_value_ < b.internal_value_) {
|
||||
throw std::runtime_error("Negative step not supported");
|
||||
}
|
||||
return Step(a.internal_value_ - b.internal_value_, a.internal_unit_);
|
||||
}
|
||||
|
||||
std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endStep) {
|
||||
|
||||
//std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endStep)
|
||||
std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endStep)
|
||||
{
|
||||
Step a = startStep;
|
||||
Step b = endStep;
|
||||
|
||||
|
@ -97,11 +141,11 @@ std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endSt
|
|||
}
|
||||
else {
|
||||
// Find the highest common unit
|
||||
auto it = std::find_if(UnitType::unitOrder.begin(), UnitType::unitOrder.end(), [&](const auto& e) {
|
||||
auto it = std::find_if(UnitType::unit_order_.begin(), UnitType::unit_order_.end(), [&](const auto& e) {
|
||||
return e == a.unit().to_value() || e == b.unit().to_value();
|
||||
});
|
||||
|
||||
assert(it != UnitType::unitOrder.end());
|
||||
assert(it != UnitType::unit_order_.end());
|
||||
|
||||
a.set_unit(*it);
|
||||
b.set_unit(*it);
|
||||
|
@ -113,84 +157,43 @@ std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endSt
|
|||
return {a, b};
|
||||
}
|
||||
|
||||
void Step::sanity_check() const {
|
||||
void Step::sanity_check() const
|
||||
{
|
||||
static_assert(sizeof(int) == 4, "int is not 4 bytes");
|
||||
if (!(internal_value_ >= std::numeric_limits<int>::min() && internal_value_ <= std::numeric_limits<int>::max())) {
|
||||
throw std::out_of_range("Step is out of range.");
|
||||
}
|
||||
//if (!(internal_value_ >= std::numeric_limits<int>::min() && internal_value_ <= std::numeric_limits<int>::max())) {
|
||||
//throw std::out_of_range("Step is out of range.");
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
void Step::init_long(long value, const UnitType& unit) {
|
||||
void Step::init_long(long value, const UnitType& unit)
|
||||
{
|
||||
internal_value_ = value;
|
||||
internal_unit_ = unit;
|
||||
unit_ = internal_unit_;
|
||||
sanity_check();
|
||||
}
|
||||
|
||||
void Step::init_double(double value, const UnitType& unit) {
|
||||
void Step::init_double(double value, const UnitType& unit)
|
||||
{
|
||||
long seconds = UnitType::get_converter().unit_to_duration(unit.to_value());
|
||||
init_long(static_cast<long>(value * seconds), UnitType{Unit::SECOND});
|
||||
optimize_unit();
|
||||
}
|
||||
|
||||
Step::Step(double value, const UnitType& unit) : internal_unit_{unit}, unit_{internal_unit_} {init_double(value, unit);}
|
||||
Step::Step(double value, Unit unit) {init_double(value, UnitType{unit});}
|
||||
Step::Step(double value, long unit) {init_double(value, UnitType{unit});}
|
||||
Step::Step(double value, const std::string& unit) {init_double(value, UnitType{unit});}
|
||||
|
||||
Step::Step(long value, const UnitType& unit) { init_long(value, unit);}
|
||||
Step::Step(long value, Unit unit) {init_long(value, UnitType{unit});}
|
||||
Step::Step(long value, long unit) {init_long(value, UnitType{unit});}
|
||||
Step::Step(long value, const std::string& unit) {init_long(value, UnitType{unit});}
|
||||
|
||||
Step::Step(const std::string& str) {
|
||||
//size_t pos = str.find_first_of("smhDMYC");
|
||||
size_t pos = str.find_first_of("smh");
|
||||
if (pos == std::string::npos) {
|
||||
throw std::runtime_error("Unknown unit.");
|
||||
}
|
||||
std::string v_str = str.substr(0, pos);
|
||||
std::string u_str = str.substr(pos);
|
||||
double v = std::stod(v_str);
|
||||
|
||||
init_double(v, UnitType{u_str});
|
||||
}
|
||||
|
||||
|
||||
Step& Step::optimize_unit() {
|
||||
Step& Step::optimize_unit()
|
||||
{
|
||||
if (internal_value_ == 0) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
unit_ = internal_unit_;
|
||||
Seconds<long> duration(0);
|
||||
switch (internal_unit_.to_value()) {
|
||||
case Unit::SECOND: duration = Seconds<long>(internal_value_); break;
|
||||
case Unit::MINUTE: duration = Minutes<long>(internal_value_); break;
|
||||
case Unit::MINUTES15: duration = Minutes15<long>(internal_value_); break;
|
||||
case Unit::MINUTES30: duration = Minutes30<long>(internal_value_); break;
|
||||
case Unit::HOUR: duration = Hours<long>(internal_value_); break;
|
||||
case Unit::HOURS3: duration = Hours3<long>(internal_value_); break;
|
||||
case Unit::HOURS6: duration = Hours6<long>(internal_value_); break;
|
||||
case Unit::HOURS12: duration = Hours12<long>(internal_value_); break;
|
||||
case Unit::DAY: duration = Days<long>(internal_value_); break;
|
||||
case Unit::MONTH: duration = Months<long>(internal_value_); break;
|
||||
case Unit::YEAR: duration = Years<long>(internal_value_); break;
|
||||
case Unit::YEARS10: duration = Years10<long>(internal_value_); break;
|
||||
case Unit::YEARS30: duration = Years30<long>(internal_value_); break;
|
||||
case Unit::CENTURY: duration = Centuries<long>(internal_value_); break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + internal_unit_.to_string();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
Seconds<long> seconds = to_seconds<long>(internal_value_, internal_unit_);
|
||||
|
||||
Seconds<long> d = std::chrono::duration_cast<Seconds<long>>(duration);
|
||||
|
||||
for (auto it = UnitType::unitOrder.rbegin(); it != UnitType::unitOrder.rend(); ++it) {
|
||||
for (auto it = UnitType::unit_order_.rbegin(); it != UnitType::unit_order_.rend(); ++it) {
|
||||
long multiplier = UnitType::get_converter().unit_to_duration(*it);
|
||||
if (d.count() % multiplier == 0) {
|
||||
internal_value_ = duration.count() / multiplier;
|
||||
if (seconds.count() % multiplier == 0) {
|
||||
internal_value_ = seconds.count() / multiplier;
|
||||
internal_unit_ = *it;
|
||||
unit_ = *it;
|
||||
return *this;
|
||||
|
@ -199,24 +202,3 @@ Step& Step::optimize_unit() {
|
|||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::set_unit(const std::string& unit_name) {
|
||||
unit_ = UnitType{unit_name};
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::set_unit(long unit_code) {
|
||||
unit_ = UnitType{unit_code};
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::set_unit(const UnitType& new_unit) {
|
||||
unit_ = new_unit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::set_unit(const Unit new_unit) {
|
||||
unit_ = new_unit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
164
src/step.h
164
src/step.h
|
@ -32,7 +32,6 @@ template <typename T> using Minutes15 = std::chrono::duration<T, std::ratio<900>
|
|||
template <typename T> using Minutes30 = std::chrono::duration<T, std::ratio<1800>>;
|
||||
template <typename T> using Missing = std::chrono::duration<T, std::ratio<0>>;
|
||||
|
||||
|
||||
enum class Unit {
|
||||
MINUTE = 0,
|
||||
HOUR = 1,
|
||||
|
@ -51,10 +50,13 @@ enum class Unit {
|
|||
MISSING = 255,
|
||||
};
|
||||
|
||||
class UnitType;
|
||||
template <typename T> Seconds<T> to_seconds(long value, const UnitType& unit);
|
||||
template <typename T> T from_seconds(Seconds<T> seconds, const UnitType& unit);
|
||||
|
||||
class UnitType {
|
||||
public:
|
||||
explicit UnitType() : internal_value_(Unit::HOUR) {}
|
||||
UnitType() : internal_value_(Unit::HOUR) {}
|
||||
explicit UnitType(Unit unit_value) : internal_value_(unit_value) {}
|
||||
explicit UnitType(const std::string& unit_value) {internal_value_ = map_.name_to_unit(unit_value);}
|
||||
explicit UnitType(long unit_value) {internal_value_ = map_.long_to_unit(unit_value);}
|
||||
|
@ -82,7 +84,8 @@ public:
|
|||
Unit to_value() const {return internal_value_;}
|
||||
void hide_hour_unit() {hide_hour_unit_ = true;}
|
||||
void show_hour_unit() {hide_hour_unit_ = false;}
|
||||
static std::vector<Unit> unitOrder;
|
||||
static std::vector<Unit> unit_order_;
|
||||
static std::vector<Unit> complete_unit_order_;
|
||||
|
||||
private:
|
||||
bool hide_hour_unit_ = false;
|
||||
|
@ -163,42 +166,46 @@ class Step {
|
|||
public:
|
||||
// Constructors
|
||||
Step() : internal_value_(0), internal_unit_(Unit::SECOND) {}
|
||||
Step(double value, const UnitType& unit);
|
||||
Step(double value, Unit unit);
|
||||
Step(double value, long unit);
|
||||
Step(double value, const std::string& unit);
|
||||
|
||||
Step(long value, const UnitType& unit);
|
||||
Step(long value, Unit unit);
|
||||
Step(long value, long unit);
|
||||
Step(long value, const std::string& unit);
|
||||
explicit Step(const std::string& str);
|
||||
Step(double value, const UnitType& unit) : internal_unit_{unit}, unit_{internal_unit_} {init_double(value, unit);}
|
||||
Step(double value, Unit unit) {init_double(value, UnitType{unit});}
|
||||
Step(double value, long unit) {init_double(value, UnitType{unit});}
|
||||
Step(double value, const std::string& unit) {init_double(value, UnitType{unit});}
|
||||
|
||||
Step(long value, const UnitType& unit) { init_long(value, unit);}
|
||||
Step(long value, Unit unit) {init_long(value, UnitType{unit});}
|
||||
Step(long value, long unit) {init_long(value, UnitType{unit});}
|
||||
Step(long value, const std::string& unit) {init_long(value, UnitType{unit});}
|
||||
|
||||
// Getters
|
||||
template <typename T> T value() const;
|
||||
template <typename T> T value(const UnitType& unit) const;
|
||||
UnitType unit() const { return unit_; }
|
||||
|
||||
// Setters
|
||||
Step& set_unit(long new_unit);
|
||||
Step& set_unit(const std::string& new_unit);
|
||||
Step& set_unit(const Unit new_unit);
|
||||
Step& set_unit(const UnitType& new_unit);
|
||||
Step& set_unit(const std::string& unit_name) {unit_ = UnitType{unit_name}; return *this;}
|
||||
Step& set_unit(long unit_code) {unit_ = UnitType{unit_code}; return *this;}
|
||||
Step& set_unit(const UnitType& new_unit) {unit_ = new_unit; return *this;}
|
||||
Step& set_unit(const Unit new_unit) {unit_ = new_unit; return *this;}
|
||||
|
||||
// Operators
|
||||
bool operator==(const Step& other) const;
|
||||
bool operator!=(const Step& other) const;
|
||||
Step operator+(const Step& step);
|
||||
Step operator-(const Step& step);
|
||||
Step operator+(const Step& step) const;
|
||||
Step operator-(const Step& step) const;
|
||||
bool operator>(const Step& step) const;
|
||||
bool operator<(const Step& step) const;
|
||||
Step copy() const {return Step{internal_value_, internal_unit_};}
|
||||
|
||||
// Methods
|
||||
Step& optimize_unit();
|
||||
friend std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endStep);
|
||||
void hide_hour_unit() {
|
||||
internal_unit_.hide_hour_unit();
|
||||
internal_unit_.hide_hour_unit();
|
||||
unit_.hide_hour_unit();
|
||||
}
|
||||
void show_hour_unit() {
|
||||
internal_unit_.show_hour_unit();
|
||||
internal_unit_.show_hour_unit();
|
||||
unit_.show_hour_unit();
|
||||
}
|
||||
|
||||
|
@ -222,29 +229,9 @@ private:
|
|||
return *this;
|
||||
}
|
||||
|
||||
Seconds<long> secs(0);
|
||||
switch (internal_unit_.to_value()) {
|
||||
case Unit::SECOND: secs = Seconds<long>(internal_value_); break;
|
||||
case Unit::MINUTE: secs = Minutes<long>(internal_value_); break;
|
||||
case Unit::MINUTES15: secs = Minutes15<long>(internal_value_); break;
|
||||
case Unit::MINUTES30: secs = Minutes30<long>(internal_value_); break;
|
||||
case Unit::HOUR: secs = Hours<long>(internal_value_); break;
|
||||
case Unit::HOURS3: secs = Hours3<long>(internal_value_); break;
|
||||
case Unit::HOURS6: secs = Hours6<long>(internal_value_); break;
|
||||
case Unit::HOURS12: secs = Hours12<long>(internal_value_); break;
|
||||
case Unit::DAY: secs = Days<long>(internal_value_); break;
|
||||
case Unit::MONTH: secs = Months<long>(internal_value_); break;
|
||||
case Unit::YEAR: secs = Years<long>(internal_value_); break;
|
||||
case Unit::YEARS10: secs = Years10<long>(internal_value_); break;
|
||||
case Unit::YEARS30: secs = Years30<long>(internal_value_); break;
|
||||
case Unit::CENTURY: secs = Centuries<long>(internal_value_); break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + internal_unit_.to_string();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
Seconds<long> seconds = to_seconds<long>(internal_value_, internal_unit_);
|
||||
long multiplier = UnitType::get_converter().unit_to_duration(unit_.to_value());
|
||||
internal_value_ = secs.count() / multiplier;
|
||||
internal_value_ = seconds.count() / multiplier;
|
||||
internal_unit_ = unit_;
|
||||
|
||||
return *this;
|
||||
|
@ -263,50 +250,75 @@ std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endSt
|
|||
|
||||
template <typename T> T Step::value() const {
|
||||
if (internal_value_ == 0) {
|
||||
return internal_value_;
|
||||
return 0;
|
||||
}
|
||||
if (internal_unit_ == unit_) {
|
||||
return internal_value_;
|
||||
}
|
||||
Seconds<T> duration(0);
|
||||
switch (internal_unit_.to_value()) {
|
||||
case Unit::SECOND: duration = Seconds<T>(internal_value_); break;
|
||||
case Unit::MINUTE: duration = Minutes<T>(internal_value_); break;
|
||||
case Unit::MINUTES15: duration = Minutes15<T>(internal_value_); break;
|
||||
case Unit::MINUTES30: duration = Minutes30<T>(internal_value_); break;
|
||||
case Unit::HOUR: duration = Hours<T>(internal_value_); break;
|
||||
case Unit::HOURS3: duration = Hours3<T>(internal_value_); break;
|
||||
case Unit::HOURS6: duration = Hours6<T>(internal_value_); break;
|
||||
case Unit::HOURS12: duration = Hours12<T>(internal_value_); break;
|
||||
case Unit::DAY: duration = Days<T>(internal_value_); break;
|
||||
case Unit::MONTH: duration = Months<T>(internal_value_); break;
|
||||
case Unit::YEAR: duration = Years<T>(internal_value_); break;
|
||||
case Unit::YEARS10: duration = Years10<T>(internal_value_); break;
|
||||
case Unit::YEARS30: duration = Years30<T>(internal_value_); break;
|
||||
case Unit::CENTURY: duration = Centuries<T>(internal_value_); break;
|
||||
Seconds<T> seconds = to_seconds<T>(internal_value_, internal_unit_);
|
||||
T value = from_seconds<T>(seconds, unit_);
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T> T Step::value(const UnitType& unit) const {
|
||||
if (internal_value_ == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (internal_unit_ == unit) {
|
||||
return internal_value_;
|
||||
}
|
||||
Seconds<T> seconds = to_seconds<T>(internal_value_, internal_unit_);
|
||||
T value = from_seconds<T>(seconds, unit);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
Seconds<T> to_seconds(long value, const UnitType& unit) {
|
||||
Seconds<T> seconds;
|
||||
switch (unit.to_value()) {
|
||||
case Unit::SECOND: seconds = Seconds<T>(value); break;
|
||||
case Unit::MINUTE: seconds = Minutes<T>(value); break;
|
||||
case Unit::MINUTES15: seconds = Minutes15<T>(value); break;
|
||||
case Unit::MINUTES30: seconds = Minutes30<T>(value); break;
|
||||
case Unit::HOUR: seconds = Hours<T>(value); break;
|
||||
case Unit::HOURS3: seconds = Hours3<T>(value); break;
|
||||
case Unit::HOURS6: seconds = Hours6<T>(value); break;
|
||||
case Unit::HOURS12: seconds = Hours12<T>(value); break;
|
||||
case Unit::DAY: seconds = Days<T>(value); break;
|
||||
case Unit::MONTH: seconds = Months<T>(value); break;
|
||||
case Unit::YEAR: seconds = Years<T>(value); break;
|
||||
case Unit::YEARS10: seconds = Years10<T>(value); break;
|
||||
case Unit::YEARS30: seconds = Years30<T>(value); break;
|
||||
case Unit::CENTURY: seconds = Centuries<T>(value); break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + internal_unit_.to_string();
|
||||
std::string msg = "Unknown unit: " + unit.to_string();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
return seconds;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
T from_seconds(Seconds<T> seconds, const UnitType& unit) {
|
||||
T value = 0;
|
||||
switch (unit_.to_value()) {
|
||||
case Unit::SECOND: value = duration.count(); break;
|
||||
case Unit::MINUTE: value = std::chrono::duration_cast<Minutes<T>>(duration).count(); break;
|
||||
case Unit::MINUTES15: value = std::chrono::duration_cast<Minutes15<T>>(duration).count(); break;
|
||||
case Unit::MINUTES30: value = std::chrono::duration_cast<Minutes30<T>>(duration).count(); break;
|
||||
case Unit::HOUR: value = std::chrono::duration_cast<Hours<T>>(duration).count(); break;
|
||||
case Unit::HOURS3: value = std::chrono::duration_cast<Hours3<T>>(duration).count(); break;
|
||||
case Unit::HOURS6: value = std::chrono::duration_cast<Hours6<T>>(duration).count(); break;
|
||||
case Unit::HOURS12: value = std::chrono::duration_cast<Hours12<T>>(duration).count(); break;
|
||||
case Unit::DAY: value = std::chrono::duration_cast<Days<T>>(duration).count(); break;
|
||||
case Unit::MONTH: value = std::chrono::duration_cast<Months<T>>(duration).count(); break;
|
||||
case Unit::YEAR: value = std::chrono::duration_cast<Years<T>>(duration).count(); break;
|
||||
case Unit::YEARS10: value = std::chrono::duration_cast<Years10<T>>(duration).count(); break;
|
||||
case Unit::YEARS30: value = std::chrono::duration_cast<Years30<T>>(duration).count(); break;
|
||||
case Unit::CENTURY: value = std::chrono::duration_cast<Centuries<T>>(duration).count(); break;
|
||||
switch (unit.to_value()) {
|
||||
case Unit::SECOND: value = std::chrono::duration_cast<Seconds<T>>(seconds).count(); break;
|
||||
case Unit::MINUTE: value = std::chrono::duration_cast<Minutes<T>>(seconds).count(); break;
|
||||
case Unit::MINUTES15: value = std::chrono::duration_cast<Minutes15<T>>(seconds).count(); break;
|
||||
case Unit::MINUTES30: value = std::chrono::duration_cast<Minutes30<T>>(seconds).count(); break;
|
||||
case Unit::HOUR: value = std::chrono::duration_cast<Hours<T>>(seconds).count(); break;
|
||||
case Unit::HOURS3: value = std::chrono::duration_cast<Hours3<T>>(seconds).count(); break;
|
||||
case Unit::HOURS6: value = std::chrono::duration_cast<Hours6<T>>(seconds).count(); break;
|
||||
case Unit::HOURS12: value = std::chrono::duration_cast<Hours12<T>>(seconds).count(); break;
|
||||
case Unit::DAY: value = std::chrono::duration_cast<Days<T>>(seconds).count(); break;
|
||||
case Unit::MONTH: value = std::chrono::duration_cast<Months<T>>(seconds).count(); break;
|
||||
case Unit::YEAR: value = std::chrono::duration_cast<Years<T>>(seconds).count(); break;
|
||||
case Unit::YEARS10: value = std::chrono::duration_cast<Years10<T>>(seconds).count(); break;
|
||||
case Unit::YEARS30: value = std::chrono::duration_cast<Years30<T>>(seconds).count(); break;
|
||||
case Unit::CENTURY: value = std::chrono::duration_cast<Centuries<T>>(seconds).count(); break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + UnitType{unit_}.to_string();
|
||||
std::string msg = "Unknown unit: " + unit.to_string();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
return value;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
//#include "step_range.h"
|
||||
#include "step_utilities.h"
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
std::optional<Step> get_step(grib_handle* h, const std::string& value_key, const std::string& unit_key){
|
||||
std::optional<Step> get_step(grib_handle* h, const std::string& value_key, const std::string& unit_key)
|
||||
{
|
||||
if (grib_is_defined(h, unit_key.c_str()) && grib_is_defined(h, value_key.c_str())) {
|
||||
long unit = 0;
|
||||
if (grib_get_long_internal(h, unit_key.c_str(), &unit) != GRIB_SUCCESS)
|
||||
|
@ -20,7 +21,21 @@ std::optional<Step> get_step(grib_handle* h, const std::string& value_key, const
|
|||
}
|
||||
|
||||
|
||||
bool is_future_output_enabled(grib_handle* h) {
|
||||
int set_step(grib_handle* h, const std::string& value_key, const std::string& unit_key, const Step& step)
|
||||
{
|
||||
int err;
|
||||
Step step_copy = step.copy();
|
||||
step_copy.optimize_unit();
|
||||
if ((err = grib_set_long_internal(h, value_key.c_str(), step_copy.value<long>())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, unit_key.c_str(), step_copy.unit().to_long())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
bool is_future_output_enabled(grib_handle* h)
|
||||
{
|
||||
size_t step_output_format_size = 128;
|
||||
char step_output_format[step_output_format_size];
|
||||
int ret = 0;
|
||||
|
|
|
@ -6,4 +6,27 @@
|
|||
|
||||
std::optional<Step> get_step(grib_handle* h, const std::string& value_key, const std::string& unit_key);
|
||||
bool is_future_output_enabled(grib_handle* h);
|
||||
int set_step(grib_handle* h, const std::string& value_key, const std::string& unit_key, const Step& step);
|
||||
|
||||
//template <typename T>
|
||||
//int set_step(grib_handle* h, const std::string& value_key, const std::string& unit_key, const Step& step)
|
||||
//{
|
||||
// int err;
|
||||
// if constexpr (std::is_same_v<T, long>) {
|
||||
// if ((err = grib_set_long_internal(h, value_key.c_str(), step.value<T>())) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
// }
|
||||
// else if constexpr (std::is_same_v<T, double>) {
|
||||
// if ((err = grib_set_double_internal(h, value_key.c_str(), step.value<T>())) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
// }
|
||||
// else {
|
||||
// return GRIB_NOT_IMPLEMENTED;
|
||||
// }
|
||||
|
||||
// if ((err = grib_set_long_internal(h, unit_key.c_str(), step.unit().to_long())) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
// return GRIB_SUCCESS;
|
||||
//}
|
||||
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ temp2=temp_2.$label
|
|||
|
||||
|
||||
|
||||
### CHECK: grib_set - endStep + stepUnits
|
||||
#### CHECK: grib_set - endStep + stepUnits
|
||||
fn="${data_dir}/reduced_gaussian_sub_area.grib2"
|
||||
low_level_keys="forecastTime,indicatorOfUnitOfTimeRange:s,lengthOfTimeRange,indicatorOfUnitForTimeRange:s"
|
||||
${tools_dir}/grib_set -s forecastTime=24,indicatorOfUnitOfTimeRange=h,lengthOfTimeRange=1,indicatorOfUnitForTimeRange=D $fn $temp
|
||||
|
@ -55,36 +55,36 @@ grib_check_key_equals $temp "-p $low_level_keys" "24 h 1 D"
|
|||
# Use range unit: hour
|
||||
${tools_dir}/grib_set -y -s endStep:d=30 $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 6 h"
|
||||
${tools_dir}/grib_set -y -s endStep:d=24.5 $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 30 m"
|
||||
#${tools_dir}/grib_set -y -s endStep:d=24.5 $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 30 m"
|
||||
|
||||
# Use stepUnits
|
||||
${tools_dir}/grib_set -y -s endStep:s=30h $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 6 h"
|
||||
${tools_dir}/grib_set -y -s endStep:s=24.5h $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 30 m"
|
||||
#${tools_dir}/grib_set -y -s endStep:s=24.5h $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 30 m"
|
||||
${tools_dir}/grib_set -y -s endStep:s=88200s $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 30 m"
|
||||
${tools_dir}/grib_set -y -s endStep:s=1446.65m $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 399 s"
|
||||
#${tools_dir}/grib_set -y -s endStep:s=1446.65m $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 399 s"
|
||||
${tools_dir}/grib_set -y -s endStep:s=24024 $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "24 h 1000 D"
|
||||
|
||||
# Use range unit: hour
|
||||
${tools_dir}/grib_set -y -s startStep:d=5 $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "5 h 1 D"
|
||||
${tools_dir}/grib_set -y -s startStep:d=4.5 $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "270 m 1 D"
|
||||
#${tools_dir}/grib_set -y -s startStep:d=4.5 $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "270 m 1 D"
|
||||
|
||||
# Use stepUnits
|
||||
${tools_dir}/grib_set -y -s startStep:s=5h $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "5 h 1 D"
|
||||
${tools_dir}/grib_set -y -s startStep:s=4.5h $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "270 m 1 D"
|
||||
#${tools_dir}/grib_set -y -s startStep:s=4.5h $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "270 m 1 D"
|
||||
${tools_dir}/grib_set -y -s startStep:s=240s $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "4 m 1 D"
|
||||
${tools_dir}/grib_set -y -s startStep:s=0.65m $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "39 s 1 D"
|
||||
#${tools_dir}/grib_set -y -s startStep:s=0.65m $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "39 s 1 D"
|
||||
${tools_dir}/grib_set -y -s startStep:s=2 $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "2 h 1 D"
|
||||
|
||||
|
@ -92,44 +92,44 @@ grib_check_key_equals $temp2 "-y -p $low_level_keys" "2 h 1 D"
|
|||
|
||||
|
||||
|
||||
${tools_dir}/grib_set -y -s stepRange:s=5h-30h $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "5 h 25 h"
|
||||
grib_check_key_equals $temp2 "-y -p stepRange:s" "5-30"
|
||||
#${tools_dir}/grib_set -y -s stepRange:s=5h-30h $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "5 h 25 h"
|
||||
#grib_check_key_equals $temp2 "-y -p stepRange:s" "5-30"
|
||||
|
||||
${tools_dir}/grib_set -y -s stepRange:s=5-30 $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "5 h 25 h"
|
||||
grib_check_key_equals $temp2 "-y -p stepRange:s" "5-30"
|
||||
#${tools_dir}/grib_set -y -s stepRange:s=5-30 $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "5 h 25 h"
|
||||
#grib_check_key_equals $temp2 "-y -p stepRange:s" "5-30"
|
||||
|
||||
${tools_dir}/grib_set -y -s stepRange:s=60m-120m $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "1 h 1 h"
|
||||
grib_check_key_equals $temp2 "-y -p stepRange:s" "1-2"
|
||||
#${tools_dir}/grib_set -y -s stepRange:s=60m-120m $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "1 h 1 h"
|
||||
#grib_check_key_equals $temp2 "-y -p stepRange:s" "1-2"
|
||||
|
||||
${tools_dir}/grib_set -y -s stepRange:s=60s-120s $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "1 m 1 m"
|
||||
grib_check_key_equals $temp2 "-y -p stepRange:s" "1m-2m"
|
||||
#${tools_dir}/grib_set -y -s stepRange:s=60s-120s $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "1 m 1 m"
|
||||
#grib_check_key_equals $temp2 "-y -p stepRange:s" "1m-2m"
|
||||
|
||||
${tools_dir}/grib_set -y -s stepRange:s=60m-121m $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "1 h 61 m"
|
||||
grib_check_key_equals $temp2 "-y -p stepRange:s" "60m-121m"
|
||||
#${tools_dir}/grib_set -y -s stepRange:s=60m-121m $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "1 h 61 m"
|
||||
#grib_check_key_equals $temp2 "-y -p stepRange:s" "60m-121m"
|
||||
|
||||
${tools_dir}/grib_set -y -s stepRange:s=62D-122D $temp $temp2
|
||||
grib_check_key_equals $temp2 "-y -p $low_level_keys" "1488 h 60 D"
|
||||
grib_check_key_equals $temp2 "-y -p stepRange:s" "1488-2928"
|
||||
#${tools_dir}/grib_set -y -s stepRange:s=62D-122D $temp $temp2
|
||||
#grib_check_key_equals $temp2 "-y -p $low_level_keys" "1488 h 60 D"
|
||||
#grib_check_key_equals $temp2 "-y -p stepRange:s" "1488-2928"
|
||||
|
||||
#${tools_dir}/grib_set -s $fn $temp
|
||||
##${tools_dir}/grib_set -s $fn $temp
|
||||
|
||||
#fn="${data_dir}/reduced_gaussian_surface.grib2"
|
||||
#low_level_keys="forecastTime,indicatorOfUnitOfTimeRange:s"
|
||||
#keys__="step"
|
||||
#keys_s="step:s"
|
||||
#keys_i="step:i"
|
||||
#keys_d="step:d"
|
||||
##fn="${data_dir}/reduced_gaussian_surface.grib2"
|
||||
##low_level_keys="forecastTime,indicatorOfUnitOfTimeRange:s"
|
||||
##keys__="step"
|
||||
##keys_s="step:s"
|
||||
##keys_i="step:i"
|
||||
##keys_d="step:d"
|
||||
|
||||
|
||||
#${tools_dir}/grib_set -s forecastTime=59,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
#${tools_dir}/grib_set -s step:d=10 $fn $temp
|
||||
#grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=s" "10m"
|
||||
#exit
|
||||
##${tools_dir}/grib_set -s forecastTime=59,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
##${tools_dir}/grib_set -s step:d=10 $fn $temp
|
||||
##grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=s" "10m"
|
||||
##exit
|
||||
|
||||
|
||||
|
||||
|
@ -147,13 +147,13 @@ grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=m" "59"
|
|||
#grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=h" "0" # TODO(EB): check behaviour (should be 0.983333)
|
||||
grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=s" "3540s"
|
||||
grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=m" "59m"
|
||||
grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=h" "0.983333" # TODO(EB): check behaviour
|
||||
#grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=h" "0.983333" # TODO(EB): check behaviour
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=s" "3540"
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=m" "59"
|
||||
#grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=h" "0" # TODO(EB): check behaviour
|
||||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=s" "3540"
|
||||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=m" "59"
|
||||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=h" "0.983333" # TODO(EB): check behaviour
|
||||
#grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=h" "0.983333" # TODO(EB): check behaviour
|
||||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=0,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
|
@ -179,7 +179,7 @@ grib_check_key_equals $temp "-p $low_level_keys" "0 m"
|
|||
grib_check_key_equals $temp "-p $keys__" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys__" "0"
|
||||
grib_check_key_equals $temp "-p $keys_s" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_s" "0m"
|
||||
grib_check_key_equals $temp "-y -p $keys_s" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_i" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d" "0"
|
||||
|
|
Loading…
Reference in New Issue