mirror of https://github.com/ecmwf/eccodes.git
ECC-1620: Prototype
This commit is contained in:
parent
bf4e481cd6
commit
9cd5041d53
|
@ -10,9 +10,11 @@ alias minutesAfterReferenceTimeOfDataCutoff=minutesAfterDataCutoff;
|
|||
|
||||
# Indicator of unit of time range
|
||||
codetable[1] indicatorOfUnitOfTimeRange ('4.4.table',masterDir,localDir) : dump;
|
||||
alias defaultStepUnits = one; # 1 means Hour. See code table 4.4
|
||||
template_nofail default_step_units "grib2/localConcepts/[centre:s]/default_step_units.def";
|
||||
codetable[1] stepUnits 'stepUnits.table' = defaultStepUnits : transient,dump,no_copy;
|
||||
#alias defaultStepUnits = one; # 1 means Hour. See code table 4.4
|
||||
#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;
|
||||
meta stepUnits optimal_step_units(forecastTime,indicatorOfUnitOfTimeRange,lengthOfTimeRange,indicatorOfUnitForTimeRange) : dump;
|
||||
|
||||
# Forecast time in units defined by previous octet (GRIB-29: supports negative forecast time)
|
||||
signed[4] forecastTime : dump;
|
||||
|
|
|
@ -167,6 +167,7 @@ list( APPEND eccodes_src_files
|
|||
grib_accessor_class_signed_bits.cc
|
||||
grib_accessor_class_section.cc
|
||||
grib_accessor_class_step_in_units.cc
|
||||
grib_accessor_class_optimal_step_units.cc
|
||||
grib_accessor_class_section_length.cc
|
||||
grib_accessor_class_g1_message_length.cc
|
||||
grib_accessor_class_g1_section4_length.cc
|
||||
|
|
|
@ -156,6 +156,7 @@ extern grib_accessor_class* grib_accessor_class_octahedral_gaussian;
|
|||
extern grib_accessor_class* grib_accessor_class_octet_number;
|
||||
extern grib_accessor_class* grib_accessor_class_offset_file;
|
||||
extern grib_accessor_class* grib_accessor_class_offset_values;
|
||||
extern grib_accessor_class* grib_accessor_class_optimal_step_units;
|
||||
extern grib_accessor_class* grib_accessor_class_pack_bufr_values;
|
||||
extern grib_accessor_class* grib_accessor_class_pad;
|
||||
extern grib_accessor_class* grib_accessor_class_padding;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
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
|
||||
MEMBERS = const char* unit
|
||||
|
@ -57,12 +59,12 @@ or edit "accessor.class" and rerun ./make_class.pl
|
|||
|
||||
*/
|
||||
|
||||
static int pack_long(grib_accessor*, const long* val, size_t* len);
|
||||
static int unpack_long(grib_accessor*, long* val, size_t* len);
|
||||
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 pack_string(grib_accessor*, const char* val, size_t* len);
|
||||
static int unpack_string(grib_accessor*, char* 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*);
|
||||
static void init(grib_accessor*, const long, grib_arguments*);
|
||||
|
||||
|
@ -115,9 +117,9 @@ static grib_accessor_class _grib_accessor_class_g2end_step = {
|
|||
0, /* is_missing */
|
||||
&pack_long, /* pack_long */
|
||||
&unpack_long, /* unpack_long */
|
||||
0, //&pack_double, /* pack_double */
|
||||
&pack_double, /* pack_double */
|
||||
0, /* pack_float */
|
||||
0, //&unpack_double, /* unpack_double */
|
||||
&unpack_double, /* unpack_double */
|
||||
0, /* unpack_float */
|
||||
&pack_string, /* pack_string */
|
||||
&unpack_string, /* unpack_string */
|
||||
|
@ -241,36 +243,27 @@ static int convert_time_range(
|
|||
Assert(lengthOfTimeRange != NULL);
|
||||
|
||||
if (indicatorOfUnitForTimeRange != stepUnits) {
|
||||
Step step{(int) *lengthOfTimeRange, indicatorOfUnitForTimeRange};
|
||||
if (stepUnits != 255) {
|
||||
step.setUnit(stepUnits);
|
||||
long u2sf_step_unit;
|
||||
long coded_time_range_sec = (*lengthOfTimeRange) * u2s2[indicatorOfUnitForTimeRange];
|
||||
if (coded_time_range_sec < 0) {
|
||||
long u2sf;
|
||||
int factor = 60;
|
||||
if (u2s2[indicatorOfUnitForTimeRange] % factor)
|
||||
return GRIB_DECODING_ERROR;
|
||||
if (u2s[stepUnits] % factor)
|
||||
return GRIB_DECODING_ERROR;
|
||||
u2sf = u2s2[indicatorOfUnitForTimeRange] / factor;
|
||||
coded_time_range_sec = (*lengthOfTimeRange) * u2sf;
|
||||
u2sf_step_unit = u2s[stepUnits] / factor;
|
||||
}
|
||||
else {
|
||||
step.setUnit(indicatorOfUnitForTimeRange);
|
||||
u2sf_step_unit = u2s[stepUnits];
|
||||
}
|
||||
*lengthOfTimeRange = step.value();
|
||||
|
||||
//long u2sf_step_unit;
|
||||
//long coded_time_range_sec = (*lengthOfTimeRange) * u2s2[indicatorOfUnitForTimeRange];
|
||||
//if (coded_time_range_sec < 0) {
|
||||
// long u2sf;
|
||||
// int factor = 60;
|
||||
// if (u2s2[indicatorOfUnitForTimeRange] % factor)
|
||||
// return GRIB_DECODING_ERROR;
|
||||
// if (u2s[stepUnits] % factor)
|
||||
// return GRIB_DECODING_ERROR;
|
||||
// u2sf = u2s2[indicatorOfUnitForTimeRange] / factor;
|
||||
// coded_time_range_sec = (*lengthOfTimeRange) * u2sf;
|
||||
// u2sf_step_unit = u2s[stepUnits] / factor;
|
||||
//}
|
||||
//else {
|
||||
// u2sf_step_unit = u2s[stepUnits];
|
||||
//}
|
||||
//if (coded_time_range_sec % u2sf_step_unit != 0) {
|
||||
// grib_context_log(h->context, GRIB_LOG_ERROR, "unable to convert endStep in stepUnits");
|
||||
// return GRIB_WRONG_STEP_UNIT;
|
||||
//}
|
||||
//*lengthOfTimeRange = coded_time_range_sec / u2sf_step_unit;
|
||||
if (coded_time_range_sec % u2sf_step_unit != 0) {
|
||||
grib_context_log(h->context, GRIB_LOG_ERROR, "unable to convert endStep in stepUnits");
|
||||
return GRIB_WRONG_STEP_UNIT;
|
||||
}
|
||||
*lengthOfTimeRange = coded_time_range_sec / u2sf_step_unit;
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
|
@ -381,10 +374,20 @@ static int unpack_multiple_time_ranges(grib_accessor* a, long* val, size_t* len)
|
|||
static int unpack_long(grib_accessor* a, long* 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;
|
||||
|
||||
//if (futureOutputEnabled(h)) {
|
||||
// StepRange range;
|
||||
// if ((ret = getOptTimeRange(h, range)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
// *val = range.endStep().value<long>();
|
||||
//}
|
||||
//else {
|
||||
int err = 0;
|
||||
long start_step;
|
||||
long numberOfTimeRange;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
|
||||
if ((err = grib_get_long_internal(h, self->start_step, &start_step)))
|
||||
return err;
|
||||
|
@ -401,208 +404,275 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
Assert(numberOfTimeRange == 1 || numberOfTimeRange == 2);
|
||||
|
||||
if (numberOfTimeRange == 1) {
|
||||
return unpack_one_time_range(a, val, len);
|
||||
ret = unpack_one_time_range(a, val, len);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
return unpack_multiple_time_ranges(a, val, len);
|
||||
ret = unpack_multiple_time_ranges(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;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int err = 0;
|
||||
|
||||
size_t stepOutputFormatSize = 128;
|
||||
char stepOutputFormat[stepOutputFormatSize];
|
||||
if ((ret = grib_get_string_internal(h, "stepOutputFormat", stepOutputFormat, &stepOutputFormatSize)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
long year;
|
||||
long month;
|
||||
long day;
|
||||
long hour;
|
||||
long minute;
|
||||
long second;
|
||||
|
||||
if (strcmp(stepOutputFormat, "future") == 0) {
|
||||
Step<long> step{*val, "h"};
|
||||
ret = grib_set_long_internal(h, "indicatorOfUnitForTimeRange", step.unit().to_long());
|
||||
if (ret)
|
||||
return ret;
|
||||
long start_step;
|
||||
long unit, coded_unit;
|
||||
long year_of_end_of_interval;
|
||||
long month_of_end_of_interval;
|
||||
long day_of_end_of_interval;
|
||||
long hour_of_end_of_interval;
|
||||
long minute_of_end_of_interval = 0;
|
||||
long second_of_end_of_interval = 0;
|
||||
|
||||
ret = grib_set_long_internal(h, "lengthOfTimeRange", step.value());
|
||||
if (ret)
|
||||
return ret;
|
||||
return GRIB_SUCCESS;
|
||||
long coded_time_range, time_range, typeOfTimeIncrement;
|
||||
|
||||
double dend, dstep;
|
||||
|
||||
/*point in time */
|
||||
if (self->year == NULL) {
|
||||
err = grib_set_long_internal(h, self->start_step, *val);
|
||||
return err;
|
||||
}
|
||||
else {
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
|
||||
int err = 0;
|
||||
if ((err = grib_get_long_internal(h, self->coded_unit, &coded_unit)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->unit, &unit)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->year, &year)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->month, &month)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->day, &day)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->hour, &hour)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->minute, &minute)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->second, &second)))
|
||||
return err;
|
||||
|
||||
long year;
|
||||
long month;
|
||||
long day;
|
||||
long hour;
|
||||
long minute;
|
||||
long second;
|
||||
if ((err = grib_get_long_internal(h, self->start_step, &start_step)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->typeOfTimeIncrement, &typeOfTimeIncrement)))
|
||||
return err;
|
||||
|
||||
long start_step;
|
||||
long unit, coded_unit;
|
||||
long year_of_end_of_interval;
|
||||
long month_of_end_of_interval;
|
||||
long day_of_end_of_interval;
|
||||
long hour_of_end_of_interval;
|
||||
long minute_of_end_of_interval = 0;
|
||||
long second_of_end_of_interval = 0;
|
||||
time_range = *val - start_step;
|
||||
|
||||
long coded_time_range, time_range, typeOfTimeIncrement;
|
||||
|
||||
double dend, dstep;
|
||||
|
||||
/*point in time */
|
||||
if (self->year == NULL) {
|
||||
err = grib_set_long_internal(h, self->start_step, *val);
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = grib_get_long_internal(h, self->coded_unit, &coded_unit)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->unit, &unit)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->year, &year)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->month, &month)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->day, &day)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->hour, &hour)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->minute, &minute)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->second, &second)))
|
||||
return err;
|
||||
|
||||
if ((err = grib_get_long_internal(h, self->start_step, &start_step)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->typeOfTimeIncrement, &typeOfTimeIncrement)))
|
||||
return err;
|
||||
|
||||
time_range = *val - start_step;
|
||||
|
||||
if (time_range < 0) {
|
||||
grib_context_log(h->context, GRIB_LOG_ERROR,
|
||||
"endStep < startStep (%ld < %ld)", *val, start_step);
|
||||
return GRIB_WRONG_STEP;
|
||||
}
|
||||
|
||||
err = grib_datetime_to_julian(year, month, day, hour, minute, second, &dend);
|
||||
if (err != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
dstep = (((double)(*val)) * u2s[unit]) / u2s[2]; /* in days */
|
||||
dend += dstep;
|
||||
|
||||
err = grib_julian_to_datetime(dend, &year_of_end_of_interval, &month_of_end_of_interval,
|
||||
&day_of_end_of_interval, &hour_of_end_of_interval,
|
||||
&minute_of_end_of_interval, &second_of_end_of_interval);
|
||||
if (err != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
if ((err = grib_set_long_internal(h, self->year_of_end_of_interval, year_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->month_of_end_of_interval, month_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->day_of_end_of_interval, day_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->hour_of_end_of_interval, hour_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->minute_of_end_of_interval, minute_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->second_of_end_of_interval, second_of_end_of_interval)))
|
||||
return err;
|
||||
|
||||
if (time_range * u2s[unit] % u2s2[coded_unit]) {
|
||||
coded_unit = unit;
|
||||
if ((err = grib_set_long_internal(h, self->coded_unit, coded_unit)))
|
||||
return err;
|
||||
coded_time_range = time_range;
|
||||
}
|
||||
else
|
||||
coded_time_range = (time_range * u2s[unit]) / u2s2[coded_unit];
|
||||
|
||||
if (typeOfTimeIncrement != 1) {
|
||||
/* 1 means "Successive times processed have same forecast time, start time of forecast is incremented" */
|
||||
/* Note: For this case, length of timeRange is not related to step and so should NOT be used to calculate step */
|
||||
if ((err = grib_set_long_internal(h, self->coded_time_range, coded_time_range)))
|
||||
return err;
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
if (time_range < 0) {
|
||||
grib_context_log(h->context, GRIB_LOG_ERROR,
|
||||
"endStep < startStep (%ld < %ld)", *val, start_step);
|
||||
return GRIB_WRONG_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
static int pack_string(grib_accessor* a, const char* 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;
|
||||
err = grib_datetime_to_julian(year, month, day, hour, minute, second, &dend);
|
||||
if (err != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
Step<long> step = Step<long>(parse_step(std::string(val)));
|
||||
dstep = (((double)(*val)) * u2s[unit]) / u2s[2]; /* in days */
|
||||
dend += dstep;
|
||||
|
||||
ret = grib_set_long_internal(h, "indicatorOfUnitForTimeRange", step.unit().to_long());
|
||||
if (ret)
|
||||
return ret;
|
||||
err = grib_julian_to_datetime(dend, &year_of_end_of_interval, &month_of_end_of_interval,
|
||||
&day_of_end_of_interval, &hour_of_end_of_interval,
|
||||
&minute_of_end_of_interval, &second_of_end_of_interval);
|
||||
if (err != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
ret = grib_set_long_internal(h, "lengthOfTimeRange", step.value());
|
||||
if (ret)
|
||||
return ret;
|
||||
if ((err = grib_set_long_internal(h, self->year_of_end_of_interval, year_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->month_of_end_of_interval, month_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->day_of_end_of_interval, day_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->hour_of_end_of_interval, hour_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->minute_of_end_of_interval, minute_of_end_of_interval)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->second_of_end_of_interval, second_of_end_of_interval)))
|
||||
return err;
|
||||
|
||||
if (time_range * u2s[unit] % u2s2[coded_unit]) {
|
||||
coded_unit = unit;
|
||||
if ((err = grib_set_long_internal(h, self->coded_unit, coded_unit)))
|
||||
return err;
|
||||
coded_time_range = time_range;
|
||||
}
|
||||
else
|
||||
coded_time_range = (time_range * u2s[unit]) / u2s2[coded_unit];
|
||||
|
||||
if (typeOfTimeIncrement != 1) {
|
||||
/* 1 means "Successive times processed have same forecast time, start time of forecast is incremented" */
|
||||
/* Note: For this case, length of timeRange is not related to step and so should NOT be used to calculate step */
|
||||
if ((err = grib_set_long_internal(h, self->coded_time_range, coded_time_range)))
|
||||
return err;
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int unpack_string(grib_accessor* a, char* val, size_t* len) {
|
||||
static int unpack_string(grib_accessor* a, char* 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;
|
||||
|
||||
auto [start, stop] = getTimeRange(h);
|
||||
auto [step_a, step_b] = findCommonUnits(start.optimizeUnit(), stop.optimizeUnit());
|
||||
step_a.hide_hour_unit();
|
||||
step_b.hide_hour_unit();
|
||||
long step_units_old;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units_old)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", UnitType{Unit::SECOND}.toLong())) != 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.setUnit(step_units_old);
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_units_old)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
step.hideHourUnit();
|
||||
if (futureOutputEnabled(h)) {
|
||||
snprintf(val, *len, "%ld%s", step_b.value(), step_b.unit().to_string().c_str());
|
||||
snprintf(val, *len, "%s", step.toString().c_str());
|
||||
}
|
||||
else {
|
||||
snprintf(val, *len, "%ld", step_b.value());
|
||||
snprintf(val, *len, "%ld", step.value<long>());
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
|
||||
|
||||
//grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
//grib_handle* h = grib_handle_of_accessor(a);
|
||||
//int ret = 0;
|
||||
|
||||
//long start_step_long;
|
||||
//size_t start_step_len = 0;
|
||||
//if ((ret = unpack_long(a, &start_step_long, &start_step_len)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
//long step_units;
|
||||
//if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
//Step start_step(start_step_long, step_units);
|
||||
//start_step.hideHourUnit();
|
||||
//if (futureOutputEnabled(h)) {
|
||||
// snprintf(val, *len, "%s", start_step.toString().c_str());
|
||||
//}
|
||||
//else {
|
||||
// snprintf(val, *len, "%ld", start_step.value<long>());
|
||||
//}
|
||||
|
||||
//return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
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.optimizeUnit();
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", end_step.unit().toLong())) != 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_double(grib_accessor* a, const double* val, size_t* len) {
|
||||
// not implemented
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
|
||||
static int pack_string(grib_accessor* a, const char* 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;
|
||||
Step end_step = step_from_string(val);
|
||||
end_step.optimizeUnit();
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", end_step.unit().toLong())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
double end_step_value = end_step.value<double>();
|
||||
size_t end_step_len = 0;
|
||||
|
||||
if ((ret = pack_double(a, &end_step_value, &end_step_len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
return GRIB_SUCCESS;
|
||||
|
||||
////grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
//grib_handle* h = grib_handle_of_accessor(a);
|
||||
//int ret = 0;
|
||||
|
||||
//if (futureOutputEnabled(h)) {
|
||||
// // TODO(EB): Export code to a function
|
||||
// long stepUnitsLong;
|
||||
// if ((ret = grib_get_long_internal(h, "stepUnits", &stepUnitsLong)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
// UnitType stepUnits{stepUnitsLong};
|
||||
|
||||
// StepRange range;
|
||||
// getOptTimeRange(h, range);
|
||||
// UnitType endStepUnit = range.endStep().unit();
|
||||
// Step endStep{parseStep(val)};
|
||||
// Step length = endStep - range.startStep();
|
||||
// if (stepUnits != Unit::MISSING) {
|
||||
// length.setUnit(stepUnits);
|
||||
// }
|
||||
|
||||
// length.optimizeUnit();
|
||||
// if ((ret = grib_set_double_internal(h, "lengthOfTimeRange", length.value<double>()) != GRIB_SUCCESS))
|
||||
// return ret;
|
||||
// if ((ret = grib_set_long_internal(h, "indicatorOfUnitForTimeRange", length.unit().toLong())) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
// return GRIB_SUCCESS;
|
||||
//}
|
||||
//else {
|
||||
// return GRIB_NOT_IMPLEMENTED;
|
||||
//}
|
||||
}
|
||||
|
||||
static int unpack_double(grib_accessor* a, double* val, size_t* len) {
|
||||
|
||||
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 unit;
|
||||
ret = grib_get_long_internal(h, "indicatorOfUnitForTimeRange", &unit);
|
||||
if (ret)
|
||||
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;
|
||||
|
||||
long value;
|
||||
ret = grib_get_long_internal(h, "lengthOfTimeRange", &value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
long stepUnits;
|
||||
ret = grib_get_long_internal(h, "stepUnits", &stepUnits);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
Step<double> step = Step<double>(value, unit);
|
||||
*val = step.setUnit(stepUnits).value();
|
||||
|
||||
Step end_step{a_val, step_units};
|
||||
*val = end_step.value<double>();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "grib_api_internal.h"
|
||||
#include "step.h"
|
||||
#include "step_range.h"
|
||||
#include "step_utilities.h"
|
||||
#include <vector>
|
||||
/*
|
||||
|
@ -23,7 +24,9 @@
|
|||
CLASS = accessor
|
||||
SUPER = grib_accessor_class_gen
|
||||
IMPLEMENTS = pack_string;unpack_string;value_count
|
||||
IMPLEMENTS = pack_long;unpack_long;dump
|
||||
IMPLEMENTS = unpack_long;pack_long
|
||||
IMPLEMENTS = unpack_double;pack_double
|
||||
IMPLEMENTS = unpack_string;pack_string
|
||||
IMPLEMENTS = get_native_type;string_length
|
||||
IMPLEMENTS = init
|
||||
MEMBERS = const char* startStep
|
||||
|
@ -43,13 +46,14 @@ 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*);
|
||||
static int value_count(grib_accessor*, long*);
|
||||
static void dump(grib_accessor*, grib_dumper*);
|
||||
static void init(grib_accessor*, const long, grib_arguments*);
|
||||
|
||||
typedef struct grib_accessor_g2step_range
|
||||
|
@ -72,7 +76,7 @@ static grib_accessor_class _grib_accessor_class_g2step_range = {
|
|||
&init, /* init */
|
||||
0, /* post_init */
|
||||
0, /* destroy */
|
||||
&dump, /* dump */
|
||||
0, /* dump */
|
||||
0, /* next_offset */
|
||||
&string_length, /* get length of string */
|
||||
&value_count, /* get number of values */
|
||||
|
@ -84,9 +88,9 @@ static grib_accessor_class _grib_accessor_class_g2step_range = {
|
|||
0, /* is_missing */
|
||||
&pack_long, /* pack_long */
|
||||
&unpack_long, /* unpack_long */
|
||||
0, /* pack_double */
|
||||
&pack_double, /* pack_double */
|
||||
0, /* pack_float */
|
||||
0, /* unpack_double */
|
||||
&unpack_double, /* unpack_double */
|
||||
0, /* unpack_float */
|
||||
&pack_string, /* pack_string */
|
||||
&unpack_string, /* unpack_string */
|
||||
|
@ -140,43 +144,49 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
char buf[100];
|
||||
int ret = 0;
|
||||
size_t size = 0;
|
||||
long start_value = 0;
|
||||
long end_value = 0;
|
||||
long step_units_value = 0;
|
||||
|
||||
if (futureOutputEnabled(h)) {
|
||||
Step<double> step_a;
|
||||
Step<double> step_b;
|
||||
if ((ret = getOptTimeRange(h, step_a, step_b)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
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;
|
||||
|
||||
if (step_a == step_b) {
|
||||
//snprintf(buf, sizeof(buf), "%ld%s", step_a.value(), step_a.unit().to_string().c_str());
|
||||
snprintf(buf, sizeof(buf), "%0.2f%s", step_a.value(), step_a.unit().to_string().c_str());
|
||||
|
||||
Step start_step = Step(start_value, step_units_value);
|
||||
start_step.hideHourUnit();
|
||||
if (self->endStep == NULL) {
|
||||
if (futureOutputEnabled(h)) {
|
||||
snprintf(buf, sizeof(buf), "%s", start_step.toString().c_str());
|
||||
}
|
||||
else {
|
||||
//snprintf(buf, sizeof(buf), "%ld%s-%ld%s", step_a.value(), step_a.unit().to_string().c_str(), step_b.value(), step_b.unit().to_string().c_str());
|
||||
snprintf(buf, sizeof(buf), "%0.2f%s-%0.2f%s", step_a.value(), step_a.unit().to_string().c_str(), step_b.value(), step_b.unit().to_string().c_str());
|
||||
snprintf(buf, sizeof(buf), "%ld", start_value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
long start = 0, theEnd = 0;
|
||||
|
||||
ret = grib_get_long_internal(h, self->startStep, &start);
|
||||
if (ret)
|
||||
if ((ret = grib_get_long_internal(h, self->endStep, &end_value)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (self->endStep == NULL) {
|
||||
snprintf(buf, sizeof(buf), "%ld", start);
|
||||
}
|
||||
else {
|
||||
if ((ret = grib_get_long_internal(h, self->endStep, &theEnd)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (start == theEnd) {
|
||||
snprintf(buf, sizeof(buf), "%ld", theEnd);
|
||||
if (futureOutputEnabled(h)) {
|
||||
Step end_step = Step(end_value, step_units_value);
|
||||
end_step.hideHourUnit();
|
||||
if (start_value == end_value) {
|
||||
snprintf(buf, sizeof(buf), "%s", end_step.toString().c_str());
|
||||
}
|
||||
else {
|
||||
snprintf(buf, sizeof(buf), "%ld-%ld", start, theEnd);
|
||||
snprintf(buf, sizeof(buf), "%s-%s", start_step.toString().c_str(), end_step.toString().c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (start_value == end_value) {
|
||||
snprintf(buf, sizeof(buf), "%ld", end_value);
|
||||
}
|
||||
else {
|
||||
snprintf(buf, sizeof(buf), "%ld-%ld", start_value, end_value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size = strlen(buf) + 1;
|
||||
|
@ -198,62 +208,26 @@ static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
|||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
|
||||
size_t stepOutputFormatSize = 128;
|
||||
char stepOutputFormat[stepOutputFormatSize];
|
||||
if ((ret = grib_get_string_internal(h, "stepOutputFormat", stepOutputFormat, &stepOutputFormatSize)) != GRIB_SUCCESS)
|
||||
std::vector<Step> steps = parseRange(val);
|
||||
if (steps.size() == 0)
|
||||
return GRIB_INVALID_ARGUMENT;
|
||||
|
||||
Step step_0 = steps[0];
|
||||
Step step_1;
|
||||
if (steps.size() > 1) {
|
||||
std::tie(step_0, step_1) = findCommonUnits(steps[0].optimizeUnit(), steps[1].optimizeUnit());
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_0.unit().toLong())))
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = grib_set_long_internal(h, self->startStep, step_0.value<long>())))
|
||||
return ret;
|
||||
|
||||
if (strcmp(stepOutputFormat, "future") == 0) {
|
||||
std::vector<Step<long>> steps = parse_range<long>(val);
|
||||
if (steps.size() == 0) {
|
||||
return GRIB_INVALID_ARGUMENT;
|
||||
}
|
||||
if (steps.size() == 1) {
|
||||
steps[0].optimizeUnit();
|
||||
if ((ret = grib_set_long_internal(h, "indicatorOfUnitOfTimeRange", steps[0].unit().to_long())))
|
||||
return ret;
|
||||
if ((ret = grib_set_long_internal(h, "forecastTime", steps[0].value())))
|
||||
return ret;
|
||||
}
|
||||
else if (steps.size() == 2) {
|
||||
steps[0].optimizeUnit();
|
||||
steps[1].optimizeUnit();
|
||||
auto [s0, s1] = findCommonUnits(steps[0], steps[1]);
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "indicatorOfUnitOfTimeRange", s0.unit().to_long())))
|
||||
return ret;
|
||||
if ((ret = grib_set_long_internal(h, "forecastTime", s0.value())))
|
||||
return ret;
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "indicatorOfUnitForTimeRange", s1.unit().to_long())))
|
||||
return ret;
|
||||
if ((ret = grib_set_long_internal(h, "lengthOfTimeRange", s1.value())))
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
std::string msg = std::string("Invalid range: ") + val;
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
long start = 0, theEnd = -1;
|
||||
char *p = NULL, *q = NULL;
|
||||
|
||||
start = strtol(val, &p, 10);
|
||||
theEnd = start;
|
||||
|
||||
if (*p != 0)
|
||||
theEnd = strtol(++p, &q, 10);
|
||||
if ((ret = grib_set_long_internal(h, self->startStep, start)))
|
||||
if ((self->endStep != NULL) && (steps.size() > 1)) {
|
||||
if ((ret = grib_set_long_internal(h, self->endStep, step_1.value<long>())))
|
||||
return ret;
|
||||
|
||||
if (self->endStep != NULL) {
|
||||
if ((ret = grib_set_long_internal(h, self->endStep, theEnd)))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int value_count(grib_accessor* a, long* count)
|
||||
|
@ -276,40 +250,96 @@ 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.hideHourUnit();
|
||||
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;
|
||||
|
||||
////grib_accessor_g2step_range* self = (grib_accessor_g2step_range*)a;
|
||||
//grib_handle* h = grib_handle_of_accessor(a);
|
||||
//int ret = 0;
|
||||
|
||||
//StepRange range;
|
||||
//if ((ret = getOptTimeRange(h, range)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
//*val = range.endStep().value<double>();
|
||||
|
||||
//return 0;
|
||||
}
|
||||
|
||||
static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2step_range* self = (grib_accessor_g2step_range*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
char buf[100];
|
||||
int ret = 0;
|
||||
size_t size = 0;
|
||||
long start_value = 0;
|
||||
long end_value = 0;
|
||||
long step_units_value = 0;
|
||||
|
||||
size_t stepOutputFormatSize = 128;
|
||||
char stepOutputFormat[stepOutputFormatSize];
|
||||
if ((ret = grib_get_string_internal(h, "stepOutputFormat", stepOutputFormat, &stepOutputFormatSize)) != GRIB_SUCCESS)
|
||||
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;
|
||||
|
||||
//if (strcmp(stepOutputFormat, "future") == 0) {
|
||||
auto [forcastTime, lengthOfTimeRange] = getTimeRange(h);
|
||||
auto [optForecastTime, optLenghtOfTimeRange] = findCommonUnits(forcastTime.optimizeUnit(), lengthOfTimeRange.optimizeUnit());
|
||||
*val = optLenghtOfTimeRange.value();
|
||||
//}
|
||||
//else {
|
||||
// char buff[100];
|
||||
// size_t bufflen = 100;
|
||||
// long start, theEnd;
|
||||
// char* p = buff;
|
||||
// char* q = NULL;
|
||||
// if ((ret = unpack_string(a, buff, &bufflen)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
Step start_step = Step(start_value, step_units_value);
|
||||
start_step.hideHourUnit();
|
||||
if (self->endStep == NULL) {
|
||||
*val = start_step.value<long>();
|
||||
}
|
||||
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<long>();
|
||||
}
|
||||
|
||||
// start = strtol(buff, &p, 10);
|
||||
// theEnd = start;
|
||||
// if (*p != 0)
|
||||
// theEnd = strtol(++p, &q, 10);
|
||||
return GRIB_SUCCESS;
|
||||
|
||||
// *val = theEnd;
|
||||
//}
|
||||
////grib_accessor_g2step_range* self = (grib_accessor_g2step_range*)a;
|
||||
//grib_handle* h = grib_handle_of_accessor(a);
|
||||
//int ret = 0;
|
||||
|
||||
return 0;
|
||||
//StepRange range;
|
||||
//if ((ret = getOptTimeRange(h, range)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
//*val = range.endStep().value<long>();
|
||||
|
||||
//return 0;
|
||||
}
|
||||
|
||||
static int get_native_type(grib_accessor* a)
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
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
|
||||
MEMBERS = const char* codedUnits
|
||||
|
@ -40,12 +42,12 @@ or edit "accessor.class" and rerun ./make_class.pl
|
|||
|
||||
*/
|
||||
|
||||
static int pack_long(grib_accessor*, const long* val, size_t* len);
|
||||
static int unpack_long(grib_accessor*, long* val, size_t* len);
|
||||
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 pack_string(grib_accessor*, const char* val, size_t* len);
|
||||
static int unpack_string(grib_accessor*, char* 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*);
|
||||
static void init(grib_accessor*, const long, grib_arguments*);
|
||||
|
||||
|
@ -85,9 +87,9 @@ static grib_accessor_class _grib_accessor_class_step_in_units = {
|
|||
0, /* is_missing */
|
||||
&pack_long, /* pack_long */
|
||||
&unpack_long, /* unpack_long */
|
||||
0, //&pack_double, /* pack_double */
|
||||
&pack_double, /* pack_double */
|
||||
0, /* pack_float */
|
||||
0, //&unpack_double, /* unpack_double */
|
||||
&unpack_double, /* unpack_double */
|
||||
0, /* unpack_float */
|
||||
&pack_string, /* pack_string */
|
||||
&unpack_string, /* unpack_string */
|
||||
|
@ -175,19 +177,20 @@ static const int u2s[] = {
|
|||
static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
int err = 0;
|
||||
long codedStep, codedUnits, stepUnits;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret;
|
||||
|
||||
long codedStep, codedUnits, stepUnits;
|
||||
int factor = 0;
|
||||
long u2sf, u2sf_step_unit;
|
||||
|
||||
|
||||
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 ((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 (stepUnits != codedUnits) {
|
||||
*val = codedStep * u2s2[codedUnits];
|
||||
|
@ -206,9 +209,9 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
}
|
||||
|
||||
if (*val % u2sf_step_unit != 0) {
|
||||
err = grib_set_long_internal(h, self->stepUnits, codedUnits);
|
||||
ret = grib_set_long_internal(h, self->stepUnits, codedUnits);
|
||||
*val = codedStep;
|
||||
return err;
|
||||
return ret;
|
||||
}
|
||||
*val = *val / u2sf_step_unit;
|
||||
}
|
||||
|
@ -220,22 +223,9 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
|
||||
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 ret = 0;
|
||||
|
||||
//Step<long> step{*val, "h"};
|
||||
//ret = grib_set_long_internal(h, "indicatorOfUnitOfTimeRange", step.unit().to_long());
|
||||
//if (ret)
|
||||
// return ret;
|
||||
|
||||
//ret = grib_set_long_internal(h, "forecastTime", step.value());
|
||||
//if (ret)
|
||||
// return ret;
|
||||
//return GRIB_SUCCESS;
|
||||
|
||||
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;
|
||||
|
@ -285,73 +275,140 @@ 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) {
|
||||
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;
|
||||
|
||||
Step<long> step = Step<long>(parse_step(std::string(val)));
|
||||
ret = grib_set_long_internal(h, self->codedUnits, step.unit().to_long());
|
||||
if (ret)
|
||||
Step step = step_from_string(val);
|
||||
step.optimizeUnit();
|
||||
|
||||
if ((ret = grib_set_long_internal(h, self->stepUnits, step.unit().toLong())))
|
||||
return ret;
|
||||
long step_value = step.value<long>();
|
||||
if ((ret = pack_long(a, &step_value, len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = grib_set_long_internal(h, self->codedStep, step.value());
|
||||
if (ret)
|
||||
return ret;
|
||||
//if ((ret = grib_set_long_internal(h, self->codedUnits, step.unit().toLong())))
|
||||
// return ret;
|
||||
|
||||
//long step_value = step.value<long>();
|
||||
//size_t step_value_len = 0;
|
||||
//if ((ret = pack_long(a, &step_value, &step_value_len)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int unpack_string(grib_accessor* a, char* val, size_t* len) {
|
||||
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;
|
||||
//auto [step, step_b] = getOptTimeRange(h);
|
||||
Step<double> step_a;
|
||||
Step<double> step_b;
|
||||
if ((ret = getOptTimeRange(h, step_a, step_b)) != GRIB_SUCCESS)
|
||||
|
||||
long step_units_old;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units_old)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
snprintf(val, *len, "%f%s", step_a.value(), step_a.unit().to_string().c_str());
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", UnitType{Unit::SECOND}.toLong())) != 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.setUnit(step_units_old);
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_units_old)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
step.hideHourUnit();
|
||||
if (futureOutputEnabled(h)) {
|
||||
snprintf(val, *len, "%f%s", step_a.value(), step_a.unit().to_string().c_str());
|
||||
snprintf(val, *len, "%s", step.toString().c_str());
|
||||
}
|
||||
else {
|
||||
snprintf(val, *len, "%f", step_a.value());
|
||||
snprintf(val, *len, "%ld", step.value<long>());
|
||||
}
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
////grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
//grib_handle* h = grib_handle_of_accessor(a);
|
||||
//int ret = 0;
|
||||
//StepRange range;
|
||||
//if ((ret = getOptTimeRange(h, range)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
//if (futureOutputEnabled(h)) {
|
||||
// snprintf(val, *len, "%s", range.startStepToString().c_str());
|
||||
//}
|
||||
//else {
|
||||
// snprintf(val, *len, "%ld", range.startStep().value<long>());
|
||||
//}
|
||||
|
||||
//return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int pack_double(grib_accessor* a, const double* val, size_t* len) {
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
static int unpack_double(grib_accessor* a, double* val, size_t* len) {
|
||||
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 unit;
|
||||
ret = grib_get_long_internal(h, self->codedUnits, &unit);
|
||||
if (ret)
|
||||
long step_units;
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
Step start_step{*val, step_units};
|
||||
|
||||
long value;
|
||||
ret = grib_get_long_internal(h, self->codedStep, &value);
|
||||
if (ret)
|
||||
start_step.optimizeUnit();
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", start_step.unit().toLong())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
long start_step_value = start_step.value<long>();
|
||||
|
||||
long stepUnits;
|
||||
ret = grib_get_long_internal(h, self->stepUnits, &stepUnits);
|
||||
if (ret)
|
||||
if ((ret = pack_long(a, &start_step_value, len)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
Step<double> step{(double) value, unit};
|
||||
*val = step.setUnit(stepUnits).value();
|
||||
|
||||
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}.toLong())) != 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.setUnit(step_units_old);
|
||||
*val = step.value<double>();
|
||||
return GRIB_SUCCESS;
|
||||
|
||||
//grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
//grib_handle* h = grib_handle_of_accessor(a);
|
||||
//int ret;
|
||||
|
||||
//StepRange range;
|
||||
//if ((ret = getOptTimeRange(h, range)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
|
||||
//*val = range.startStep().value<double>();
|
||||
//return GRIB_SUCCESS;
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#line 6 "accessor_class_list.gperf"
|
||||
struct accessor_class_hash { char *name; grib_accessor_class **cclass;};
|
||||
|
||||
#define TOTAL_KEYWORDS 218
|
||||
#define TOTAL_KEYWORDS 219
|
||||
#define MIN_WORD_LENGTH 1
|
||||
#define MAX_WORD_LENGTH 44
|
||||
#define MIN_HASH_VALUE 1
|
||||
|
@ -51,7 +51,8 @@ struct accessor_class_hash { char *name; grib_accessor_class **cclass;};
|
|||
|
||||
#endif
|
||||
#endif
|
||||
static unsigned int grib_accessor_classes_get_id (const char *str, size_t len)
|
||||
static unsigned int
|
||||
grib_accessor_classes_get_id (register const char *str, register size_t len)
|
||||
{
|
||||
static const unsigned short asso_values[] =
|
||||
{
|
||||
|
@ -82,7 +83,7 @@ static unsigned int grib_accessor_classes_get_id (const char *str, size_t len)
|
|||
680, 680, 680, 680, 680, 680, 680, 680, 680, 680,
|
||||
680, 680, 680, 680, 680, 680
|
||||
};
|
||||
unsigned int hval = len;
|
||||
register unsigned int hval = len;
|
||||
|
||||
switch (hval)
|
||||
{
|
||||
|
@ -134,20 +135,20 @@ static const struct accessor_class_hash classes[] =
|
|||
{"int64", &grib_accessor_class_int64},
|
||||
#line 72 "accessor_class_list.gperf"
|
||||
{"data_secondary_bitmap", &grib_accessor_class_data_secondary_bitmap},
|
||||
#line 202 "accessor_class_list.gperf"
|
||||
#line 203 "accessor_class_list.gperf"
|
||||
{"time", &grib_accessor_class_time},
|
||||
#line 69 "accessor_class_list.gperf"
|
||||
{"data_png_packing", &grib_accessor_class_data_png_packing},
|
||||
{""},
|
||||
#line 190 "accessor_class_list.gperf"
|
||||
#line 191 "accessor_class_list.gperf"
|
||||
{"size", &grib_accessor_class_size},
|
||||
#line 180 "accessor_class_list.gperf"
|
||||
{"second_order_bits_per_value", &grib_accessor_class_second_order_bits_per_value},
|
||||
#line 187 "accessor_class_list.gperf"
|
||||
{"signed", &grib_accessor_class_signed},
|
||||
#line 181 "accessor_class_list.gperf"
|
||||
{"second_order_bits_per_value", &grib_accessor_class_second_order_bits_per_value},
|
||||
#line 188 "accessor_class_list.gperf"
|
||||
{"signed", &grib_accessor_class_signed},
|
||||
#line 182 "accessor_class_list.gperf"
|
||||
{"section", &grib_accessor_class_section},
|
||||
#line 203 "accessor_class_list.gperf"
|
||||
#line 204 "accessor_class_list.gperf"
|
||||
{"times", &grib_accessor_class_times},
|
||||
#line 70 "accessor_class_list.gperf"
|
||||
{"data_raw_packing", &grib_accessor_class_data_raw_packing},
|
||||
|
@ -157,19 +158,19 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 13 "accessor_class_list.gperf"
|
||||
{"ascii", &grib_accessor_class_ascii},
|
||||
{""},
|
||||
#line 182 "accessor_class_list.gperf"
|
||||
{"section_length", &grib_accessor_class_section_length},
|
||||
#line 183 "accessor_class_list.gperf"
|
||||
{"section_length", &grib_accessor_class_section_length},
|
||||
#line 184 "accessor_class_list.gperf"
|
||||
{"section_padding", &grib_accessor_class_section_padding},
|
||||
#line 196 "accessor_class_list.gperf"
|
||||
#line 197 "accessor_class_list.gperf"
|
||||
{"statistics", &grib_accessor_class_statistics},
|
||||
#line 199 "accessor_class_list.gperf"
|
||||
#line 200 "accessor_class_list.gperf"
|
||||
{"step_in_units", &grib_accessor_class_step_in_units},
|
||||
#line 188 "accessor_class_list.gperf"
|
||||
#line 189 "accessor_class_list.gperf"
|
||||
{"signed_bits", &grib_accessor_class_signed_bits},
|
||||
#line 193 "accessor_class_list.gperf"
|
||||
#line 194 "accessor_class_list.gperf"
|
||||
{"spd", &grib_accessor_class_spd},
|
||||
#line 167 "accessor_class_list.gperf"
|
||||
#line 168 "accessor_class_list.gperf"
|
||||
{"pad", &grib_accessor_class_pad},
|
||||
#line 76 "accessor_class_list.gperf"
|
||||
{"data_simple_packing", &grib_accessor_class_data_simple_packing},
|
||||
|
@ -177,7 +178,7 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 79 "accessor_class_list.gperf"
|
||||
{"dirty", &grib_accessor_class_dirty},
|
||||
{""}, {""},
|
||||
#line 197 "accessor_class_list.gperf"
|
||||
#line 198 "accessor_class_list.gperf"
|
||||
{"statistics_spectral", &grib_accessor_class_statistics_spectral},
|
||||
#line 78 "accessor_class_list.gperf"
|
||||
{"dictionary", &grib_accessor_class_dictionary},
|
||||
|
@ -187,7 +188,7 @@ static const struct accessor_class_hash classes[] =
|
|||
{""},
|
||||
#line 112 "accessor_class_list.gperf"
|
||||
{"g2lon", &grib_accessor_class_g2lon},
|
||||
#line 205 "accessor_class_list.gperf"
|
||||
#line 206 "accessor_class_list.gperf"
|
||||
{"to_integer", &grib_accessor_class_to_integer},
|
||||
#line 127 "accessor_class_list.gperf"
|
||||
{"int16", &grib_accessor_class_int16},
|
||||
|
@ -197,7 +198,7 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 46 "accessor_class_list.gperf"
|
||||
{"data_apply_bitmap", &grib_accessor_class_data_apply_bitmap},
|
||||
{""},
|
||||
#line 184 "accessor_class_list.gperf"
|
||||
#line 185 "accessor_class_list.gperf"
|
||||
{"section_pointer", &grib_accessor_class_section_pointer},
|
||||
#line 68 "accessor_class_list.gperf"
|
||||
{"data_jpeg2000_packing", &grib_accessor_class_data_jpeg2000_packing},
|
||||
|
@ -225,32 +226,32 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 109 "accessor_class_list.gperf"
|
||||
{"g2grid", &grib_accessor_class_g2grid},
|
||||
{""},
|
||||
#line 206 "accessor_class_list.gperf"
|
||||
#line 207 "accessor_class_list.gperf"
|
||||
{"to_string", &grib_accessor_class_to_string},
|
||||
{""}, {""},
|
||||
#line 134 "accessor_class_list.gperf"
|
||||
{"iterator", &grib_accessor_class_iterator},
|
||||
#line 168 "accessor_class_list.gperf"
|
||||
#line 169 "accessor_class_list.gperf"
|
||||
{"padding", &grib_accessor_class_padding},
|
||||
{""}, {""},
|
||||
#line 209 "accessor_class_list.gperf"
|
||||
#line 210 "accessor_class_list.gperf"
|
||||
{"trim", &grib_accessor_class_trim},
|
||||
{""},
|
||||
#line 65 "accessor_class_list.gperf"
|
||||
{"data_g2shsimple_packing", &grib_accessor_class_data_g2shsimple_packing},
|
||||
#line 174 "accessor_class_list.gperf"
|
||||
#line 175 "accessor_class_list.gperf"
|
||||
{"raw", &grib_accessor_class_raw},
|
||||
{""},
|
||||
#line 82 "accessor_class_list.gperf"
|
||||
{"element", &grib_accessor_class_element},
|
||||
#line 169 "accessor_class_list.gperf"
|
||||
#line 170 "accessor_class_list.gperf"
|
||||
{"padto", &grib_accessor_class_padto},
|
||||
#line 103 "accessor_class_list.gperf"
|
||||
{"g2_eps", &grib_accessor_class_g2_eps},
|
||||
{""}, {""},
|
||||
#line 156 "accessor_class_list.gperf"
|
||||
{"non_alpha", &grib_accessor_class_non_alpha},
|
||||
#line 207 "accessor_class_list.gperf"
|
||||
#line 208 "accessor_class_list.gperf"
|
||||
{"transient", &grib_accessor_class_transient},
|
||||
#line 14 "accessor_class_list.gperf"
|
||||
{"assert", &grib_accessor_class_assert},
|
||||
|
@ -262,7 +263,7 @@ static const struct accessor_class_hash classes[] =
|
|||
{"data_g2simple_packing", &grib_accessor_class_data_g2simple_packing},
|
||||
#line 63 "accessor_class_list.gperf"
|
||||
{"data_g2complex_packing", &grib_accessor_class_data_g2complex_packing},
|
||||
#line 208 "accessor_class_list.gperf"
|
||||
#line 209 "accessor_class_list.gperf"
|
||||
{"transient_darray", &grib_accessor_class_transient_darray},
|
||||
{""},
|
||||
#line 101 "accessor_class_list.gperf"
|
||||
|
@ -277,7 +278,7 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 12 "accessor_class_list.gperf"
|
||||
{"array", &grib_accessor_class_array},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 175 "accessor_class_list.gperf"
|
||||
#line 176 "accessor_class_list.gperf"
|
||||
{"rdbtime_guess_date", &grib_accessor_class_rdbtime_guess_date},
|
||||
#line 67 "accessor_class_list.gperf"
|
||||
{"data_g2simple_packing_with_preprocessing", &grib_accessor_class_data_g2simple_packing_with_preprocessing},
|
||||
|
@ -285,59 +286,59 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 119 "accessor_class_list.gperf"
|
||||
{"global_gaussian", &grib_accessor_class_global_gaussian},
|
||||
{""},
|
||||
#line 186 "accessor_class_list.gperf"
|
||||
#line 187 "accessor_class_list.gperf"
|
||||
{"sexagesimal2decimal", &grib_accessor_class_sexagesimal2decimal},
|
||||
#line 139 "accessor_class_list.gperf"
|
||||
{"laplacian", &grib_accessor_class_laplacian},
|
||||
{""},
|
||||
#line 200 "accessor_class_list.gperf"
|
||||
#line 201 "accessor_class_list.gperf"
|
||||
{"sum", &grib_accessor_class_sum},
|
||||
{""},
|
||||
#line 114 "accessor_class_list.gperf"
|
||||
{"gaussian_grid_name", &grib_accessor_class_gaussian_grid_name},
|
||||
#line 177 "accessor_class_list.gperf"
|
||||
#line 178 "accessor_class_list.gperf"
|
||||
{"round", &grib_accessor_class_round},
|
||||
#line 145 "accessor_class_list.gperf"
|
||||
{"long", &grib_accessor_class_long},
|
||||
{""},
|
||||
#line 81 "accessor_class_list.gperf"
|
||||
{"double", &grib_accessor_class_double},
|
||||
#line 189 "accessor_class_list.gperf"
|
||||
#line 190 "accessor_class_list.gperf"
|
||||
{"simple_packing_error", &grib_accessor_class_simple_packing_error},
|
||||
#line 120 "accessor_class_list.gperf"
|
||||
{"group", &grib_accessor_class_group},
|
||||
{""},
|
||||
#line 172 "accessor_class_list.gperf"
|
||||
#line 173 "accessor_class_list.gperf"
|
||||
{"position", &grib_accessor_class_position},
|
||||
#line 136 "accessor_class_list.gperf"
|
||||
{"julian_day", &grib_accessor_class_julian_day},
|
||||
#line 135 "accessor_class_list.gperf"
|
||||
{"julian_date", &grib_accessor_class_julian_date},
|
||||
#line 219 "accessor_class_list.gperf"
|
||||
#line 220 "accessor_class_list.gperf"
|
||||
{"unsigned", &grib_accessor_class_unsigned},
|
||||
{""}, {""},
|
||||
#line 52 "accessor_class_list.gperf"
|
||||
{"data_dummy_field", &grib_accessor_class_data_dummy_field},
|
||||
{""},
|
||||
#line 173 "accessor_class_list.gperf"
|
||||
#line 174 "accessor_class_list.gperf"
|
||||
{"proj_string", &grib_accessor_class_proj_string},
|
||||
#line 15 "accessor_class_list.gperf"
|
||||
{"bit", &grib_accessor_class_bit},
|
||||
#line 17 "accessor_class_list.gperf"
|
||||
{"bits", &grib_accessor_class_bits},
|
||||
#line 198 "accessor_class_list.gperf"
|
||||
#line 199 "accessor_class_list.gperf"
|
||||
{"step_human_readable", &grib_accessor_class_step_human_readable},
|
||||
#line 71 "accessor_class_list.gperf"
|
||||
{"data_run_length_packing", &grib_accessor_class_data_run_length_packing},
|
||||
#line 178 "accessor_class_list.gperf"
|
||||
#line 179 "accessor_class_list.gperf"
|
||||
{"scale", &grib_accessor_class_scale},
|
||||
#line 194 "accessor_class_list.gperf"
|
||||
#line 195 "accessor_class_list.gperf"
|
||||
{"spectral_truncation", &grib_accessor_class_spectral_truncation},
|
||||
#line 45 "accessor_class_list.gperf"
|
||||
{"data_2order_packing", &grib_accessor_class_data_2order_packing},
|
||||
#line 212 "accessor_class_list.gperf"
|
||||
#line 213 "accessor_class_list.gperf"
|
||||
{"uint32", &grib_accessor_class_uint32},
|
||||
#line 216 "accessor_class_list.gperf"
|
||||
#line 217 "accessor_class_list.gperf"
|
||||
{"uint8", &grib_accessor_class_uint8},
|
||||
#line 31 "accessor_class_list.gperf"
|
||||
{"bytes", &grib_accessor_class_bytes},
|
||||
|
@ -347,7 +348,7 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 106 "accessor_class_list.gperf"
|
||||
{"g2bitmap_present", &grib_accessor_class_g2bitmap_present},
|
||||
{""}, {""},
|
||||
#line 195 "accessor_class_list.gperf"
|
||||
#line 196 "accessor_class_list.gperf"
|
||||
{"sprintf", &grib_accessor_class_sprintf},
|
||||
{""}, {""}, {""},
|
||||
#line 18 "accessor_class_list.gperf"
|
||||
|
@ -355,12 +356,12 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 50 "accessor_class_list.gperf"
|
||||
{"data_ccsds_packing", &grib_accessor_class_data_ccsds_packing},
|
||||
{""},
|
||||
#line 220 "accessor_class_list.gperf"
|
||||
#line 221 "accessor_class_list.gperf"
|
||||
{"unsigned_bits", &grib_accessor_class_unsigned_bits},
|
||||
#line 164 "accessor_class_list.gperf"
|
||||
{"offset_file", &grib_accessor_class_offset_file},
|
||||
{""},
|
||||
#line 213 "accessor_class_list.gperf"
|
||||
#line 214 "accessor_class_list.gperf"
|
||||
{"uint32_little_endian", &grib_accessor_class_uint32_little_endian},
|
||||
{""},
|
||||
#line 89 "accessor_class_list.gperf"
|
||||
|
@ -373,9 +374,9 @@ static const struct accessor_class_hash classes[] =
|
|||
{""}, {""},
|
||||
#line 138 "accessor_class_list.gperf"
|
||||
{"label", &grib_accessor_class_label},
|
||||
#line 217 "accessor_class_list.gperf"
|
||||
#line 218 "accessor_class_list.gperf"
|
||||
{"unexpanded_descriptors", &grib_accessor_class_unexpanded_descriptors},
|
||||
#line 214 "accessor_class_list.gperf"
|
||||
#line 215 "accessor_class_list.gperf"
|
||||
{"uint64", &grib_accessor_class_uint64},
|
||||
{""},
|
||||
#line 159 "accessor_class_list.gperf"
|
||||
|
@ -399,18 +400,18 @@ static const struct accessor_class_hash classes[] =
|
|||
{"concept", &grib_accessor_class_concept},
|
||||
#line 41 "accessor_class_list.gperf"
|
||||
{"constant", &grib_accessor_class_constant},
|
||||
#line 215 "accessor_class_list.gperf"
|
||||
#line 216 "accessor_class_list.gperf"
|
||||
{"uint64_little_endian", &grib_accessor_class_uint64_little_endian},
|
||||
#line 80 "accessor_class_list.gperf"
|
||||
{"divdouble", &grib_accessor_class_divdouble},
|
||||
#line 226 "accessor_class_list.gperf"
|
||||
#line 227 "accessor_class_list.gperf"
|
||||
{"when", &grib_accessor_class_when},
|
||||
#line 163 "accessor_class_list.gperf"
|
||||
{"octet_number", &grib_accessor_class_octet_number},
|
||||
{""},
|
||||
#line 104 "accessor_class_list.gperf"
|
||||
{"g2_mars_labeling", &grib_accessor_class_g2_mars_labeling},
|
||||
#line 185 "accessor_class_list.gperf"
|
||||
#line 186 "accessor_class_list.gperf"
|
||||
{"select_step_template", &grib_accessor_class_select_step_template},
|
||||
{""},
|
||||
#line 59 "accessor_class_list.gperf"
|
||||
|
@ -422,7 +423,7 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 19 "accessor_class_list.gperf"
|
||||
{"blob", &grib_accessor_class_blob},
|
||||
{""}, {""}, {""},
|
||||
#line 223 "accessor_class_list.gperf"
|
||||
#line 224 "accessor_class_list.gperf"
|
||||
{"values", &grib_accessor_class_values},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 60 "accessor_class_list.gperf"
|
||||
|
@ -432,18 +433,18 @@ static const struct accessor_class_hash classes[] =
|
|||
{""}, {""},
|
||||
#line 146 "accessor_class_list.gperf"
|
||||
{"long_vector", &grib_accessor_class_long_vector},
|
||||
#line 201 "accessor_class_list.gperf"
|
||||
#line 202 "accessor_class_list.gperf"
|
||||
{"suppressed", &grib_accessor_class_suppressed},
|
||||
#line 121 "accessor_class_list.gperf"
|
||||
{"gts_header", &grib_accessor_class_gts_header},
|
||||
#line 204 "accessor_class_list.gperf"
|
||||
#line 205 "accessor_class_list.gperf"
|
||||
{"to_double", &grib_accessor_class_to_double},
|
||||
{""}, {""},
|
||||
#line 144 "accessor_class_list.gperf"
|
||||
{"local_definition", &grib_accessor_class_local_definition},
|
||||
#line 58 "accessor_class_list.gperf"
|
||||
{"data_g1secondary_bitmap", &grib_accessor_class_data_g1secondary_bitmap},
|
||||
#line 221 "accessor_class_list.gperf"
|
||||
#line 222 "accessor_class_list.gperf"
|
||||
{"validity_date", &grib_accessor_class_validity_date},
|
||||
#line 143 "accessor_class_list.gperf"
|
||||
{"library_version", &grib_accessor_class_library_version},
|
||||
|
@ -466,7 +467,7 @@ static const struct accessor_class_hash classes[] =
|
|||
{"data_g1second_order_row_by_row_packing", &grib_accessor_class_data_g1second_order_row_by_row_packing},
|
||||
#line 151 "accessor_class_list.gperf"
|
||||
{"md5", &grib_accessor_class_md5},
|
||||
#line 222 "accessor_class_list.gperf"
|
||||
#line 223 "accessor_class_list.gperf"
|
||||
{"validity_time", &grib_accessor_class_validity_time},
|
||||
#line 130 "accessor_class_list.gperf"
|
||||
{"int32_little_endian", &grib_accessor_class_int32_little_endian},
|
||||
|
@ -478,7 +479,7 @@ static const struct accessor_class_hash classes[] =
|
|||
{""}, {""},
|
||||
#line 74 "accessor_class_list.gperf"
|
||||
{"data_sh_unpacked", &grib_accessor_class_data_sh_unpacked},
|
||||
#line 225 "accessor_class_list.gperf"
|
||||
#line 226 "accessor_class_list.gperf"
|
||||
{"vector", &grib_accessor_class_vector},
|
||||
#line 20 "accessor_class_list.gperf"
|
||||
{"budgdate", &grib_accessor_class_budgdate},
|
||||
|
@ -491,14 +492,14 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 137 "accessor_class_list.gperf"
|
||||
{"ksec1expver", &grib_accessor_class_ksec1expver},
|
||||
{""},
|
||||
#line 171 "accessor_class_list.gperf"
|
||||
#line 172 "accessor_class_list.gperf"
|
||||
{"padtomultiple", &grib_accessor_class_padtomultiple},
|
||||
#line 150 "accessor_class_list.gperf"
|
||||
{"mars_step", &grib_accessor_class_mars_step},
|
||||
#line 126 "accessor_class_list.gperf"
|
||||
{"ifs_param", &grib_accessor_class_ifs_param},
|
||||
{""},
|
||||
#line 191 "accessor_class_list.gperf"
|
||||
#line 192 "accessor_class_list.gperf"
|
||||
{"smart_table", &grib_accessor_class_smart_table},
|
||||
{""},
|
||||
#line 149 "accessor_class_list.gperf"
|
||||
|
@ -507,7 +508,7 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 22 "accessor_class_list.gperf"
|
||||
{"bufr_data_element", &grib_accessor_class_bufr_data_element},
|
||||
{""}, {""},
|
||||
#line 192 "accessor_class_list.gperf"
|
||||
#line 193 "accessor_class_list.gperf"
|
||||
{"smart_table_column", &grib_accessor_class_smart_table_column},
|
||||
{""},
|
||||
#line 21 "accessor_class_list.gperf"
|
||||
|
@ -541,15 +542,15 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 153 "accessor_class_list.gperf"
|
||||
{"message_copy", &grib_accessor_class_message_copy},
|
||||
{""}, {""},
|
||||
#line 170 "accessor_class_list.gperf"
|
||||
#line 171 "accessor_class_list.gperf"
|
||||
{"padtoeven", &grib_accessor_class_padtoeven},
|
||||
{""}, {""},
|
||||
#line 210 "accessor_class_list.gperf"
|
||||
#line 211 "accessor_class_list.gperf"
|
||||
{"uint16", &grib_accessor_class_uint16},
|
||||
{""}, {""},
|
||||
#line 154 "accessor_class_list.gperf"
|
||||
{"missing", &grib_accessor_class_missing},
|
||||
#line 224 "accessor_class_list.gperf"
|
||||
#line 225 "accessor_class_list.gperf"
|
||||
{"variable", &grib_accessor_class_variable},
|
||||
{""}, {""},
|
||||
#line 86 "accessor_class_list.gperf"
|
||||
|
@ -561,7 +562,7 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 36 "accessor_class_list.gperf"
|
||||
{"codeflag", &grib_accessor_class_codeflag},
|
||||
{""}, {""}, {""}, {""}, {""}, {""},
|
||||
#line 211 "accessor_class_list.gperf"
|
||||
#line 212 "accessor_class_list.gperf"
|
||||
{"uint16_little_endian", &grib_accessor_class_uint16_little_endian},
|
||||
#line 37 "accessor_class_list.gperf"
|
||||
{"codetable", &grib_accessor_class_codetable},
|
||||
|
@ -595,10 +596,10 @@ static const struct accessor_class_hash classes[] =
|
|||
#line 161 "accessor_class_list.gperf"
|
||||
{"number_of_values_data_raw_packing", &grib_accessor_class_number_of_values_data_raw_packing},
|
||||
{""}, {""}, {""}, {""},
|
||||
#line 179 "accessor_class_list.gperf"
|
||||
#line 180 "accessor_class_list.gperf"
|
||||
{"scale_values", &grib_accessor_class_scale_values},
|
||||
{""},
|
||||
#line 218 "accessor_class_list.gperf"
|
||||
#line 219 "accessor_class_list.gperf"
|
||||
{"unpack_bufr_values", &grib_accessor_class_unpack_bufr_values},
|
||||
{""}, {""}, {""},
|
||||
#line 85 "accessor_class_list.gperf"
|
||||
|
@ -617,10 +618,10 @@ static const struct accessor_class_hash classes[] =
|
|||
{""}, {""},
|
||||
#line 100 "accessor_class_list.gperf"
|
||||
{"g1verificationdate", &grib_accessor_class_g1verificationdate},
|
||||
#line 166 "accessor_class_list.gperf"
|
||||
#line 167 "accessor_class_list.gperf"
|
||||
{"pack_bufr_values", &grib_accessor_class_pack_bufr_values},
|
||||
{""}, {""},
|
||||
#line 176 "accessor_class_list.gperf"
|
||||
#line 177 "accessor_class_list.gperf"
|
||||
{"reference_value_error", &grib_accessor_class_reference_value_error},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""},
|
||||
|
@ -638,7 +639,9 @@ static const struct accessor_class_hash classes[] =
|
|||
{""}, {""},
|
||||
#line 10 "accessor_class_list.gperf"
|
||||
{"abstract_long_vector", &grib_accessor_class_abstract_long_vector},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
#line 166 "accessor_class_list.gperf"
|
||||
{"optimal_step_units", &grib_accessor_class_optimal_step_units},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
|
||||
{""}, {""}, {""}, {""},
|
||||
|
@ -686,19 +689,20 @@ static const struct accessor_class_hash classes[] =
|
|||
{"g1forecastmonth", &grib_accessor_class_g1forecastmonth}
|
||||
};
|
||||
|
||||
static const struct accessor_class_hash* grib_accessor_classes_hash (const char *str, size_t len)
|
||||
const struct accessor_class_hash *
|
||||
grib_accessor_classes_hash (register const char *str, register size_t len)
|
||||
{
|
||||
unsigned int key = grib_accessor_classes_get_id (str, len);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
||||
{
|
||||
const char *s;
|
||||
Assert( len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH );
|
||||
Assert( key <= MAX_HASH_VALUE );
|
||||
s = classes[key].name;
|
||||
Assert( *str == *s && strcmp(str + 1, s + 1)==0 );
|
||||
}
|
||||
#endif
|
||||
register unsigned int key = grib_accessor_classes_get_id (str, len);
|
||||
|
||||
return &classes[key];
|
||||
if (key <= MAX_HASH_VALUE)
|
||||
{
|
||||
register const char *s = classes[key].name;
|
||||
|
||||
if (*str == *s && !strcmp (str + 1, s + 1))
|
||||
return &classes[key];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
{ "octet_number", &grib_accessor_class_octet_number, },
|
||||
{ "offset_file", &grib_accessor_class_offset_file, },
|
||||
{ "offset_values", &grib_accessor_class_offset_values, },
|
||||
{ "optimal_step_units", &grib_accessor_class_optimal_step_units, },
|
||||
{ "pack_bufr_values", &grib_accessor_class_pack_bufr_values, },
|
||||
{ "pad", &grib_accessor_class_pad, },
|
||||
{ "padding", &grib_accessor_class_padding, },
|
||||
|
|
|
@ -156,6 +156,7 @@ octahedral_gaussian, &grib_accessor_class_octahedral_gaussian
|
|||
octet_number, &grib_accessor_class_octet_number
|
||||
offset_file, &grib_accessor_class_offset_file
|
||||
offset_values, &grib_accessor_class_offset_values
|
||||
optimal_step_units, &grib_accessor_class_optimal_step_units
|
||||
pack_bufr_values, &grib_accessor_class_pack_bufr_values
|
||||
pad, &grib_accessor_class_pad
|
||||
padding, &grib_accessor_class_padding
|
||||
|
|
219
src/step.cc
219
src/step.cc
|
@ -5,6 +5,7 @@
|
|||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <regex>
|
||||
|
||||
#include "step.h"
|
||||
|
||||
|
@ -18,41 +19,205 @@ std::vector<Unit> UnitType::unitOrder = {
|
|||
};
|
||||
|
||||
|
||||
std::string parse_step(std::string step) {
|
||||
if (step.find_first_of("smhdMYC") == std::string::npos) {
|
||||
step += "h";
|
||||
Step step_from_string(std::string step) {
|
||||
std::regex re("([0-9.]+)([smhDMYC]?)");
|
||||
std::smatch match;
|
||||
if (std::regex_match(step, match, re)) {
|
||||
if (match.size() == 3) {
|
||||
std::string value = match[1];
|
||||
std::string unit = match[2];
|
||||
if (unit.size() == 0) {
|
||||
unit = "h";
|
||||
}
|
||||
return Step{std::stod(value), UnitType{unit}};
|
||||
}
|
||||
}
|
||||
return step;
|
||||
throw std::runtime_error("Could not parse step: " + step);
|
||||
}
|
||||
|
||||
std::vector<Step> parseRange(const std::string& range_str) {
|
||||
std::vector<Step> steps;
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type prev = 0;
|
||||
while ((pos = range_str.find("-", prev)) != std::string::npos) {
|
||||
steps.push_back(step_from_string(range_str.substr(prev, pos - prev)));
|
||||
prev = pos + 1;
|
||||
}
|
||||
steps.push_back(step_from_string(range_str.substr(prev)));
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
||||
std::pair<Step<long>, Step<long>> findCommonUnits(const Step<long>& startStep, const Step<long>& endStep) {
|
||||
Step<long> a = startStep;
|
||||
Step<long> b = endStep;
|
||||
|
||||
if (a.value_ == 0 || b.value_ == 0) {
|
||||
if (a.value_ == 0 && b.value_ == 0) {
|
||||
UnitType unit = a.unit_ > b.unit_ ? a.unit_ : b.unit_;
|
||||
a.setUnit(unit);
|
||||
b.setUnit(unit);
|
||||
}
|
||||
else if (a.value_ == 0) {
|
||||
a.setUnit(b.unit_);
|
||||
}
|
||||
else if (b.value_ == 0) {
|
||||
b.setUnit(a.unit_);
|
||||
}
|
||||
return {a, b};
|
||||
bool Step::operator==(const Step& other) const {
|
||||
if ((internal_value_ == other.internal_value_) && (internal_unit_ == other.internal_unit_)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = std::find_if(UnitType::unitOrder.begin(), UnitType::unitOrder.end(), [&](const auto& e) {
|
||||
return e == a.unit().to_value() || e == b.unit().to_value();
|
||||
});
|
||||
Step Step::operator+(const Step& step) {
|
||||
Step tmp = step;
|
||||
auto [a, b] = findCommonUnits(this->optimizeUnit(), tmp.optimizeUnit());
|
||||
assert(a.internal_unit_ == b.internal_unit_);
|
||||
return Step(a.internal_value_ + b.internal_value_, a.internal_unit_);
|
||||
}
|
||||
|
||||
assert(it != UnitType::unitOrder.end());
|
||||
Step Step::operator-(const Step& step) {
|
||||
Step tmp = step;
|
||||
auto [a, b] = findCommonUnits(this->optimizeUnit(), tmp.optimizeUnit());
|
||||
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_);
|
||||
}
|
||||
|
||||
a.setUnit(*it);
|
||||
b.setUnit(*it);
|
||||
std::pair<Step, Step> findCommonUnits(const Step& startStep, const Step& endStep) {
|
||||
Step a = startStep;
|
||||
Step b = endStep;
|
||||
|
||||
if (a.internal_value_ == 0 && b.internal_value_ == 0) {
|
||||
UnitType unit = a.internal_unit_ > b.internal_unit_ ? a.internal_unit_ : b.internal_unit_;
|
||||
b.internal_unit_ = unit;
|
||||
b.unit_ = unit;
|
||||
a.internal_unit_ = unit;
|
||||
a.unit_ = unit;
|
||||
}
|
||||
else if (b.internal_value_ == 0) {
|
||||
b.internal_unit_ = a.internal_unit_;
|
||||
b.unit_ = a.internal_unit_;
|
||||
a.unit_ = a.internal_unit_;
|
||||
a.recalculateValue();
|
||||
}
|
||||
else if (a.internal_value_ == 0) {
|
||||
a.internal_unit_ = b.internal_unit_;
|
||||
a.unit_ = b.internal_unit_;
|
||||
b.unit_ = b.internal_unit_;
|
||||
b.recalculateValue();
|
||||
}
|
||||
else {
|
||||
// Find the highest common unit
|
||||
auto it = std::find_if(UnitType::unitOrder.begin(), UnitType::unitOrder.end(), [&](const auto& e) {
|
||||
return e == a.unit().toValue() || e == b.unit().toValue();
|
||||
});
|
||||
|
||||
assert(it != UnitType::unitOrder.end());
|
||||
|
||||
a.setUnit(*it);
|
||||
b.setUnit(*it);
|
||||
a.recalculateValue();
|
||||
b.recalculateValue();
|
||||
assert(a.internal_unit_ == b.internal_unit_);
|
||||
}
|
||||
|
||||
return {a, b};
|
||||
}
|
||||
|
||||
void Step::sanityCheck() 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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Step::initLong(long value, const UnitType& unit) {
|
||||
internal_value_ = value;
|
||||
internal_unit_ = unit;
|
||||
unit_ = internal_unit_;
|
||||
sanityCheck();
|
||||
}
|
||||
|
||||
void Step::initDouble(double value, const UnitType& unit) {
|
||||
long seconds = UnitType::getConverter().unit_to_duration(unit.toValue());
|
||||
initLong(static_cast<long>(value * seconds), UnitType{Unit::SECOND});
|
||||
optimizeUnit();
|
||||
}
|
||||
|
||||
Step::Step(double value, const UnitType& unit) : internal_unit_{unit}, unit_{internal_unit_} {initDouble(value, unit);}
|
||||
Step::Step(double value, Unit unit) {initDouble(value, UnitType{unit});}
|
||||
Step::Step(double value, long unit) {initDouble(value, UnitType{unit});}
|
||||
Step::Step(double value, const std::string& unit) {initDouble(value, UnitType{unit});}
|
||||
|
||||
Step::Step(long value, const UnitType& unit) { initLong(value, unit);}
|
||||
Step::Step(long value, Unit unit) {initLong(value, UnitType{unit});}
|
||||
Step::Step(long value, long unit) {initLong(value, UnitType{unit});}
|
||||
Step::Step(long value, const std::string& unit) {initLong(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);
|
||||
|
||||
initDouble(v, UnitType{u_str});
|
||||
}
|
||||
|
||||
|
||||
Step& Step::optimizeUnit() {
|
||||
if (internal_value_ == 0) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
unit_ = internal_unit_;
|
||||
Seconds<long> duration(0);
|
||||
switch (internal_unit_.toValue()) {
|
||||
case Unit::SECOND:
|
||||
duration = Seconds<long>(internal_value_);
|
||||
break;
|
||||
case Unit::MINUTE:
|
||||
duration = Minutes<long>(internal_value_);
|
||||
break;
|
||||
case Unit::HOUR:
|
||||
duration = Hours<long>(internal_value_);
|
||||
break;
|
||||
case Unit::DAY:
|
||||
duration = Days<long>(internal_value_);
|
||||
break;
|
||||
case Unit::MONTH:
|
||||
duration = Months<long>(internal_value_);
|
||||
break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + internal_unit_.toString();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
Seconds<long> d = std::chrono::duration_cast<Seconds<long>>(duration);
|
||||
|
||||
for (auto it = UnitType::unitOrder.rbegin(); it != UnitType::unitOrder.rend(); ++it) {
|
||||
long multiplier = UnitType::getConverter().unit_to_duration(*it);
|
||||
if (d.count() % multiplier == 0) {
|
||||
internal_value_ = duration.count() / multiplier;
|
||||
internal_unit_ = *it;
|
||||
unit_ = *it;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::setUnit(const std::string& unit_name) {
|
||||
unit_ = UnitType{unit_name};
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::setUnit(long unit_code) {
|
||||
unit_ = UnitType{unit_code};
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::setUnit(const UnitType& new_unit) {
|
||||
unit_ = new_unit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Step& Step::setUnit(const Unit new_unit) {
|
||||
unit_ = new_unit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
336
src/step.h
336
src/step.h
|
@ -12,6 +12,8 @@
|
|||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
|
||||
|
||||
template <typename T> using Minutes = std::chrono::duration<T, std::ratio<60>>;
|
||||
|
@ -52,31 +54,34 @@ enum class Unit {
|
|||
|
||||
class UnitType {
|
||||
public:
|
||||
explicit UnitType() : value_(Unit::HOUR) {}
|
||||
explicit UnitType(Unit unit_value) : value_(unit_value) {}
|
||||
explicit UnitType(const std::string& unit_value) {value_ = map_.name_to_unit(unit_value);}
|
||||
explicit UnitType(long unit_value) {value_ = map_.long_to_unit(unit_value);}
|
||||
explicit 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);}
|
||||
|
||||
bool operator>(const UnitType& other) const {return map_.unit_to_duration(internal_value_) > map_.unit_to_duration(other.internal_value_);}
|
||||
bool operator==(const Unit value) const {return map_.unit_to_duration(internal_value_) == map_.unit_to_duration(value);}
|
||||
bool operator==(const UnitType& unit) const {return map_.unit_to_duration(internal_value_) == map_.unit_to_duration(unit.internal_value_);}
|
||||
bool operator!=(const UnitType& unit) const {return !(*this == unit);}
|
||||
bool operator!=(const Unit value) const {return !(*this == value);}
|
||||
|
||||
bool operator>(const UnitType& other) const {return map_.unit_to_duration(value_) > map_.unit_to_duration(other.value_);}
|
||||
bool operator==(const Unit value) const {return map_.unit_to_duration(value_) == map_.unit_to_duration(value);}
|
||||
bool operator==(const UnitType& unit) const {return map_.unit_to_duration(value_) == map_.unit_to_duration(unit.value_);}
|
||||
UnitType& operator=(const Unit value) {
|
||||
value_ = value;
|
||||
internal_value_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string to_string() const {
|
||||
if ((value_ == Unit::HOUR) && hide_hour_unit_) {
|
||||
std::string toString() const {
|
||||
if ((internal_value_ == Unit::HOUR) && hide_hour_unit_) {
|
||||
return "";
|
||||
}
|
||||
else {
|
||||
return map_.unit_to_name(value_);
|
||||
return map_.unit_to_name(internal_value_);
|
||||
}
|
||||
}
|
||||
long to_long() const {return map_.unit_to_long(value_);}
|
||||
Unit to_value() const {return value_;}
|
||||
void hide_hour_unit() {hide_hour_unit_ = true;}
|
||||
void show_hour_unit() {hide_hour_unit_ = false;}
|
||||
long toLong() const {return map_.unit_to_long(internal_value_);}
|
||||
Unit toValue() const {return internal_value_;}
|
||||
void hideHourUnit() {hide_hour_unit_ = true;}
|
||||
void showHourUnit() {hide_hour_unit_ = false;}
|
||||
static std::vector<Unit> unitOrder;
|
||||
|
||||
private:
|
||||
|
@ -147,257 +152,166 @@ private:
|
|||
};
|
||||
|
||||
|
||||
Unit value_;
|
||||
Unit internal_value_;
|
||||
static Map map_;
|
||||
public:
|
||||
static Map& get_converter() {return map_;}
|
||||
static Map& getConverter() {return map_;}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Step {
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
Step() : value_(0), unit_(Unit::SECOND) {}
|
||||
Step(T value, Unit unit);
|
||||
Step(T value, const UnitType& unit);
|
||||
Step(T value, long unit);
|
||||
Step(T value, const std::string& unit);
|
||||
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);
|
||||
|
||||
// Getters
|
||||
T value() const { return value_; }
|
||||
template <typename T> T value() const;
|
||||
UnitType unit() const { return unit_; }
|
||||
|
||||
// Setters
|
||||
Step<T>& setUnit(long new_unit);
|
||||
Step<T>& setUnit(const std::string& new_unit);
|
||||
Step<T>& setUnit(const Unit new_unit);
|
||||
Step<T>& setUnit(const UnitType& new_unit);
|
||||
Step& setUnit(long new_unit);
|
||||
Step& setUnit(const std::string& new_unit);
|
||||
Step& setUnit(const Unit new_unit);
|
||||
Step& setUnit(const UnitType& new_unit);
|
||||
|
||||
// Operators
|
||||
bool operator==(const Step<T>& other) const;
|
||||
Step<T> operator+(const Step<T>& step);
|
||||
operator Step<double>() const {return Step<double>{static_cast<double>(value_), unit_};}
|
||||
bool operator==(const Step& other) const;
|
||||
bool operator!=(const Step& other) const;
|
||||
Step operator+(const Step& step);
|
||||
Step operator-(const Step& step);
|
||||
|
||||
// Methods
|
||||
Step<T>& optimizeUnit();
|
||||
friend std::pair<Step<long>, Step<long>> findCommonUnits(const Step<long>& startStep, const Step<long>& endStep);
|
||||
void hide_hour_unit() {unit_.hide_hour_unit();}
|
||||
void show_hour_unit() {unit_.show_hour_unit();}
|
||||
Step& optimizeUnit();
|
||||
friend std::pair<Step, Step> findCommonUnits(const Step& startStep, const Step& endStep);
|
||||
void hideHourUnit() {
|
||||
internal_unit_.hideHourUnit();
|
||||
unit_.hideHourUnit();
|
||||
}
|
||||
void showHourUnit() {
|
||||
internal_unit_.showHourUnit();
|
||||
unit_.showHourUnit();
|
||||
}
|
||||
|
||||
std::string toString() const {
|
||||
std::stringstream ss;
|
||||
if (value<long>() == value<double>()) {
|
||||
ss << value<long>() << unit_.toString();
|
||||
} else {
|
||||
ss << value<double>() << unit_.toString();
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
T value_;
|
||||
void initLong(long value, const UnitType& unit);
|
||||
void initDouble(double value, const UnitType& unit);
|
||||
void sanityCheck() const;
|
||||
Step& recalculateValue() {
|
||||
if (internal_value_ == 0) {
|
||||
internal_unit_ = unit_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Seconds<long> secs(0);
|
||||
switch (internal_unit_.toValue()) {
|
||||
case Unit::SECOND:
|
||||
secs = Seconds<long>(internal_value_);
|
||||
break;
|
||||
case Unit::MINUTE:
|
||||
secs = Minutes<long>(internal_value_);
|
||||
break;
|
||||
case Unit::HOUR:
|
||||
secs = Hours<long>(internal_value_);
|
||||
break;
|
||||
case Unit::DAY:
|
||||
secs = Days<long>(internal_value_);
|
||||
break;
|
||||
case Unit::MONTH:
|
||||
secs = Months<long>(internal_value_);
|
||||
break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + internal_unit_.toString();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
long multiplier = UnitType::getConverter().unit_to_duration(unit_.toValue());
|
||||
internal_value_ = secs.count() / multiplier;
|
||||
internal_unit_ = unit_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
long internal_value_;
|
||||
UnitType internal_unit_;
|
||||
UnitType unit_;
|
||||
};
|
||||
|
||||
|
||||
Step step_from_string(std::string step);
|
||||
std::vector<Step> parseRange(const std::string& range_str);
|
||||
std::pair<Step, Step> findCommonUnits(const Step& startStep, const Step& endStep);
|
||||
|
||||
|
||||
std::string parse_step(std::string step);
|
||||
|
||||
template <typename T>
|
||||
bool Step<T>::operator==(const Step<T>& other) const {
|
||||
if ((value_ == other.value_) && (unit_ == other.unit_)) {
|
||||
return true;
|
||||
template <typename T> T Step::value() const {
|
||||
if (internal_value_ == 0) {
|
||||
return internal_value_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T> Step<T>::operator+(const Step<T>& step) {
|
||||
auto [a, b] = findCommonUnits(*this, step);
|
||||
return Step(a.value_ + b.value_, a.unit_);
|
||||
}
|
||||
|
||||
std::pair<Step<long>, Step<long>> findCommonUnits(const Step<long>& startStep, const Step<long>& endStep);
|
||||
|
||||
|
||||
template <typename T> std::vector<Step<T>> parse_range(const std::string& range_str) {
|
||||
std::vector<Step<T>> steps;
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type prev = 0;
|
||||
while ((pos = range_str.find("-", prev)) != std::string::npos) {
|
||||
std::string token = parse_step(range_str.substr(prev, pos - prev));
|
||||
if (token.size() > 0) {
|
||||
steps.push_back(Step<T>(token));
|
||||
}
|
||||
prev = pos + 1;
|
||||
}
|
||||
std::string token = parse_step(range_str.substr(prev));
|
||||
if (token.size() > 0) {
|
||||
steps.push_back(Step<T>(token));
|
||||
}
|
||||
return steps;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
Step<T>::Step(T value, Unit unit) : value_{value}, unit_{UnitType{unit}} {
|
||||
static_assert(sizeof(int) == 4, "int is not 4 bytes");
|
||||
if (!(value >= 0 && value <= std::numeric_limits<int>::max())) {
|
||||
throw std::out_of_range("Step is out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
Step<T>::Step(T value, long unit) : value_{value}, unit_{UnitType{unit}} {
|
||||
static_assert(sizeof(int) == 4, "int is not 4 bytes");
|
||||
if (!(value >= 0 && value <= std::numeric_limits<int>::max())) {
|
||||
throw std::out_of_range("Step is out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T>::Step(T value, const std::string& unit) : value_{value}, unit_{UnitType{unit}} {
|
||||
static_assert(sizeof(int) == 4, "int is not 4 bytes");
|
||||
if (!(value >= 0 && value <= std::numeric_limits<int>::max())) {
|
||||
throw std::out_of_range("Step is out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T>::Step(const std::string& str) {
|
||||
size_t pos = str.find_first_of("smhdMYC");
|
||||
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);
|
||||
int v = std::stoi(v_str);
|
||||
value_ = v;
|
||||
unit_ = UnitType{u_str};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T>::Step(T value, const UnitType& u) {
|
||||
static_assert(sizeof(int) == 4, "int is not 4 bytes");
|
||||
if (!(value >= 0 && value <= std::numeric_limits<int>::max())) {
|
||||
throw std::out_of_range("Step is out of range.");
|
||||
}
|
||||
value_ = value;
|
||||
unit_ = u;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T>& Step<T>::optimizeUnit() {
|
||||
if (value_ == 0) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Seconds<T> duration(0);
|
||||
switch (unit_.to_value()) {
|
||||
case Unit::SECOND:
|
||||
duration = Seconds<T>(value_);
|
||||
break;
|
||||
case Unit::MINUTE:
|
||||
duration = Minutes<T>(value_);
|
||||
break;
|
||||
case Unit::HOUR:
|
||||
duration = Hours<T>(value_);
|
||||
break;
|
||||
case Unit::DAY:
|
||||
duration = Days<T>(value_);
|
||||
break;
|
||||
case Unit::MONTH:
|
||||
duration = Months<T>(value_);
|
||||
break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + unit_.to_string();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
Seconds<T> d = std::chrono::duration_cast<Seconds<T>>(duration);
|
||||
|
||||
for (auto it = UnitType::unitOrder.rbegin(); it != UnitType::unitOrder.rend(); ++it) {
|
||||
long multiplier = UnitType::get_converter().unit_to_duration(*it);
|
||||
if (d.count() % multiplier == 0) {
|
||||
value_ = duration.count() / multiplier;
|
||||
unit_ = *it;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T>& Step<T>::setUnit(const std::string& unit_name) {
|
||||
setUnit(UnitType{unit_name});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T>& Step<T>::setUnit(long unit_code) {
|
||||
setUnit(UnitType{unit_code});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Step<T>& Step<T>::setUnit(const UnitType& new_unit) {
|
||||
setUnit(new_unit.to_value());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
Step<T>& Step<T>::setUnit(const Unit new_unit) {
|
||||
if (value_ == 0) {
|
||||
unit_ = new_unit;
|
||||
return *this;
|
||||
}
|
||||
if (unit_ == new_unit) {
|
||||
return *this;
|
||||
if (internal_unit_ == unit_) {
|
||||
return internal_value_;
|
||||
}
|
||||
Seconds<T> duration(0);
|
||||
switch (unit_.to_value()) {
|
||||
switch (internal_unit_.toValue()) {
|
||||
case Unit::SECOND:
|
||||
duration = Seconds<T>(value_);
|
||||
duration = Seconds<T>(internal_value_);
|
||||
break;
|
||||
case Unit::MINUTE:
|
||||
duration = Minutes<T>(value_);
|
||||
duration = Minutes<T>(internal_value_);
|
||||
break;
|
||||
case Unit::HOUR:
|
||||
duration = Hours<T>(value_);
|
||||
duration = Hours<T>(internal_value_);
|
||||
break;
|
||||
case Unit::DAY:
|
||||
duration = Days<T>(value_);
|
||||
duration = Days<T>(internal_value_);
|
||||
break;
|
||||
case Unit::MONTH:
|
||||
duration = Months<T>(value_);
|
||||
duration = Months<T>(internal_value_);
|
||||
break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + unit_.to_string();
|
||||
std::string msg = "Unknown unit: " + internal_unit_.toString();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
|
||||
switch (new_unit) {
|
||||
T value = 0;
|
||||
switch (unit_.toValue()) {
|
||||
case Unit::SECOND:
|
||||
value_ = duration.count();
|
||||
value = duration.count();
|
||||
break;
|
||||
case Unit::MINUTE:
|
||||
value_ = std::chrono::duration_cast<Minutes<T>>(duration).count();
|
||||
value = std::chrono::duration_cast<Minutes<T>>(duration).count();
|
||||
break;
|
||||
case Unit::HOUR:
|
||||
value_ = std::chrono::duration_cast<Hours<T>>(duration).count();
|
||||
value = std::chrono::duration_cast<Hours<T>>(duration).count();
|
||||
break;
|
||||
case Unit::DAY:
|
||||
value_ = std::chrono::duration_cast<Days<T>>(duration).count();
|
||||
value = std::chrono::duration_cast<Days<T>>(duration).count();
|
||||
break;
|
||||
case Unit::MONTH:
|
||||
value_ = std::chrono::duration_cast<Months<T>>(duration).count();
|
||||
value = std::chrono::duration_cast<Months<T>>(duration).count();
|
||||
break;
|
||||
default:
|
||||
std::string msg = "Unknown unit: " + UnitType{new_unit}.to_string();
|
||||
std::string msg = "Unknown unit: " + UnitType{unit_}.toString();
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
unit_ = new_unit;
|
||||
|
||||
return *this;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//#include "step_range.h"
|
||||
#include "step_utilities.h"
|
||||
|
||||
|
||||
std::optional<Step<long>> getStep(grib_handle* h, const std::string& value_key, const std::string& unit_key){
|
||||
std::optional<Step> getStep(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)
|
||||
|
@ -11,7 +11,7 @@ std::optional<Step<long>> getStep(grib_handle* h, const std::string& value_key,
|
|||
if (grib_get_long_internal(h, value_key.c_str(), &value) != GRIB_SUCCESS)
|
||||
return {};
|
||||
|
||||
return Step<long>(value, unit);
|
||||
return Step(value, unit);
|
||||
}
|
||||
else {
|
||||
return {};
|
||||
|
@ -19,28 +19,27 @@ std::optional<Step<long>> getStep(grib_handle* h, const std::string& value_key,
|
|||
}
|
||||
|
||||
|
||||
std::optional<Step<long>> getForecastTime(grib_handle* h) {
|
||||
return getStep(h, "forecastTime", "indicatorOfUnitOfTimeRange");
|
||||
}
|
||||
//std::optional<Step> getForecastTime(grib_handle* h) {
|
||||
// return getStep(h, "forecastTime", "indicatorOfUnitOfTimeRange");
|
||||
//}
|
||||
|
||||
|
||||
std::optional<Step<long>> getLengthOfTimeRange(grib_handle* h) {
|
||||
return getStep(h, "lengthOfTimeRange", "indicatorOfUnitForTimeRange");
|
||||
}
|
||||
//std::optional<Step> getLengthOfTimeRange(grib_handle* h) {
|
||||
// return getStep(h, "lengthOfTimeRange", "indicatorOfUnitForTimeRange");
|
||||
//}
|
||||
|
||||
|
||||
std::pair<Step<long>, Step<long>> getTimeRange(grib_handle* h) {
|
||||
auto forecast_time = getForecastTime(h);
|
||||
auto length_of_time_range = getLengthOfTimeRange(h);
|
||||
return {forecast_time.value(), forecast_time.value() + length_of_time_range.value_or(Step<long>())};
|
||||
}
|
||||
|
||||
//StepRange getTimeRange(grib_handle* h) {
|
||||
// auto forecast_time = getForecastTime(h);
|
||||
// auto length_of_time_range = getLengthOfTimeRange(h);
|
||||
// return StepRange{forecast_time.value_or(Step{}), forecast_time.value_or(Step{}) + length_of_time_range.value_or(Step{})};
|
||||
//}
|
||||
|
||||
|
||||
bool futureOutputEnabled(grib_handle* h) {
|
||||
int ret = 0;
|
||||
size_t stepOutputFormatSize = 128;
|
||||
char stepOutputFormat[stepOutputFormatSize];
|
||||
int ret = 0;
|
||||
if ((ret = grib_get_string_internal(h, "stepOutputFormat", stepOutputFormat, &stepOutputFormatSize)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
return strcmp(stepOutputFormat, "future") == 0;
|
||||
|
|
|
@ -2,43 +2,13 @@
|
|||
|
||||
#include "grib_api_internal.h"
|
||||
#include "step.h"
|
||||
|
||||
#include <optional>
|
||||
//#include "step_range.h"
|
||||
|
||||
std::optional<Step<long>> getStep(grib_handle* h, const std::string& value_key, const std::string& unit_key);
|
||||
std::optional<Step<long>> getForecastTime(grib_handle* h);
|
||||
std::optional<Step<long>> getLengthOfTimeRange(grib_handle* h);
|
||||
std::pair<Step<long>, Step<long>> getTimeRange(grib_handle* h);
|
||||
//std::pair<Step<long>, Step<long>> getOptTimeRange(grib_handle* h);
|
||||
|
||||
std::optional<Step> getStep(grib_handle* h, const std::string& value_key, const std::string& unit_key);
|
||||
//std::optional<Step> getForecastTime(grib_handle* h);
|
||||
//std::optional<Step> getLengthOfTimeRange(grib_handle* h);
|
||||
//StepRange getTimeRange(grib_handle* h);
|
||||
bool futureOutputEnabled(grib_handle* h);
|
||||
|
||||
template <class T> int getOptTimeRange(grib_handle* h, Step<T>& s_a, Step<T>& s_b);
|
||||
//std::pair<Step<long>, Step<long>> getOptTimeRange(grib_handle* h) {
|
||||
|
||||
template <class T>
|
||||
int getOptTimeRange(grib_handle* h, Step<T>& s_a, Step<T>& s_b) {
|
||||
auto [step_a, step_b] = getTimeRange(h);
|
||||
|
||||
long unit_code = 0;
|
||||
if (grib_get_long_internal(h, "stepUnits", &unit_code) != GRIB_SUCCESS)
|
||||
return {};
|
||||
|
||||
UnitType wanted_unit{unit_code};
|
||||
try {
|
||||
if (wanted_unit == Unit::MISSING) {
|
||||
std::tie(s_a, s_b) = findCommonUnits(step_a.optimizeUnit(), step_b.optimizeUnit());
|
||||
}
|
||||
else {
|
||||
s_a = static_cast<Step<double>>(step_a).setUnit(unit_code);
|
||||
s_b = static_cast<Step<double>>(step_b).setUnit(unit_code);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return GRIB_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
s_a.hide_hour_unit();
|
||||
s_b.hide_hour_unit();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,12 +35,103 @@ grib_check_key_equals()
|
|||
echo "Key(s): '$a_params'"
|
||||
echo "Expected: '$a_expected'"
|
||||
echo "Result: '$a_result'"
|
||||
${tools_dir}/grib_dump -O $a_file | grep -E "indicatorOfUnitOfTimeRange|lengthOfTimeRange|indicatorOfUnitForTimeRange|forecastTime"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
label="grib_ecc-1620"
|
||||
temp=temp.$label
|
||||
temp2=temp_2.$label
|
||||
|
||||
|
||||
|
||||
### 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
|
||||
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"
|
||||
|
||||
# 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=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=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"
|
||||
|
||||
# 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=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=2 $temp $temp2
|
||||
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=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=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=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"
|
||||
exit
|
||||
|
||||
#${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"
|
||||
|
||||
|
||||
#${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
|
||||
|
||||
|
||||
|
||||
fn="${data_dir}/reduced_gaussian_surface.grib2"
|
||||
|
@ -52,15 +143,21 @@ keys_d="step:d"
|
|||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=59,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
#grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=s" "3540"
|
||||
#grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=m" "59"
|
||||
#grib_expect_failure $temp "-y -p $keys__ -s stepUnits=h" # TODO(EB): check behaviour
|
||||
#exit
|
||||
#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_expect_failure $temp "-y -p $keys_s -s stepUnits=h"
|
||||
exit
|
||||
grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=s" "3540"
|
||||
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_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
|
||||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=0,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=h" "0"
|
||||
|
@ -68,8 +165,6 @@ grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=s" "0"
|
|||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=h" "0"
|
||||
|
||||
exit
|
||||
|
||||
|
||||
|
||||
fn="${data_dir}/reduced_gaussian_surface.grib2"
|
||||
|
@ -80,29 +175,29 @@ keys_i="step:i"
|
|||
keys_d="step:d"
|
||||
|
||||
|
||||
#${tools_dir}/grib_set -s forecastTime=0,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
#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 "-p $keys_i" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_i" "0"
|
||||
#grib_check_key_equals $temp "-p $keys_d" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_d" "0"
|
||||
${tools_dir}/grib_set -s forecastTime=0,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
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 "-p $keys_i" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_i" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_d" "0"
|
||||
|
||||
#grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=s" "0s"
|
||||
#grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=m" "0m"
|
||||
#grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=h" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=s" "0s"
|
||||
#grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=m" "0m"
|
||||
#grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=h" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=s" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=m" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=h" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=s" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=m" "0"
|
||||
#grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys__ -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=s" "0s"
|
||||
grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=m" "0m"
|
||||
grib_check_key_equals $temp "-y -p $keys_s -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_i -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-y -p $keys_d -s stepUnits=h" "0"
|
||||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=59,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
|
@ -250,10 +345,10 @@ grib_check_key_equals $temp "-p $keys__" "18-24 18 24"
|
|||
grib_check_key_equals $temp "-y -p $keys__" "18-24 18 24"
|
||||
grib_check_key_equals $temp "-p $keys_s" "18-24 18 24"
|
||||
grib_check_key_equals $temp "-y -p $keys_s" "18-24 18 24"
|
||||
grib_check_key_equals $temp "-p $keys_i" "24 18 24" # TODO(EB): Check if output of stepRange:i makes sense.
|
||||
grib_check_key_equals $temp "-y -p $keys_i" "24 18 24"
|
||||
grib_check_key_equals $temp "-p $keys_d" "24 18 24" # TODO(EB): Check if output of stepRange:d makes sense.
|
||||
grib_check_key_equals $temp "-y -p $keys_d" "24 18 24"
|
||||
grib_check_key_equals $temp "-p $keys_i" "24 18 24"
|
||||
grib_check_key_equals $temp "-y -p $keys_i" "24 18 24" # TODO(EB): Check if output of stepRange:i makes sense.
|
||||
grib_check_key_equals $temp "-p $keys_d" "24 18 24"
|
||||
grib_check_key_equals $temp "-y -p $keys_d" "24 18 24" # TODO(EB): Check if output of stepRange:d makes sense.
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=1080,indicatorOfUnitOfTimeRange=m,lengthOfTimeRange=6,indicatorOfUnitForTimeRange=h $fn $temp
|
||||
grib_check_key_equals $temp "-p $low_level_keys" "1080 m 6 h"
|
||||
|
|
|
@ -137,8 +137,9 @@ grib_check_key_equals $temp "stepRange:d" "28"
|
|||
${tools_dir}/grib_set -s stepRange:i=24 $grib2_sample $temp
|
||||
grib_check_key_equals $temp "stepRange,startStep,endStep" "24 24 24"
|
||||
# Should this be an error? currently this gets cast from double to int
|
||||
${tools_dir}/grib_set -s stepRange:d=14.56 $grib2_sample $temp
|
||||
grib_check_key_equals $temp "stepRange,startStep,endStep" "14 14 14"
|
||||
# In ECC-1620 this behaviour changes
|
||||
#${tools_dir}/grib_set -s stepRange:d=14.56 $grib2_sample $temp
|
||||
#grib_check_key_equals $temp "stepRange,startStep,endStep" "14 14 14"
|
||||
|
||||
|
||||
# Clean up
|
||||
|
|
Loading…
Reference in New Issue