diff --git a/definitions/boot.def b/definitions/boot.def index 15ff30351..9b281ac23 100644 --- a/definitions/boot.def +++ b/definitions/boot.def @@ -15,6 +15,11 @@ UseEcmfConventions = getenv("ECCODES_USE_ECMF_CONVENTIONS","1") :hidden ; constant defaultTypeOfLevel="unknown" : hidden; +gribDataQualityChecks = getenv("ECCODES_GRIB_DATA_QUALITY_CHECKS","0") : hidden; +if (gribDataQualityChecks) { + template LIMITS "param_limits.def"; +} + # GRIBEX special boustrophedonic mode. See GRIB-472 # If the environment variable is not defined, the key will be 0 GRIBEX_boustrophedonic = getenv("ECCODES_GRIBEX_BOUSTROPHEDONIC","0") :hidden; diff --git a/definitions/param_limits.def b/definitions/param_limits.def new file mode 100644 index 000000000..01ee9e3de --- /dev/null +++ b/definitions/param_limits.def @@ -0,0 +1,11 @@ +constant default_min_val = -1e8 : long_type, hidden; +constant default_max_val = +1e8 : long_type, hidden; + +concept param_value_min(default_min_val) { + 0 = { paramId=130; } + 50 = { paramId=167; } +} : long_type, hidden; +concept param_value_max(default_max_val) { + 400 = { paramId=130; } + 373 = { paramId=167; } +} : long_type, hidden; diff --git a/src/grib_accessor_class_data_simple_packing.c b/src/grib_accessor_class_data_simple_packing.c index 91754db55..ad72d1ac0 100644 --- a/src/grib_accessor_class_data_simple_packing.c +++ b/src/grib_accessor_class_data_simple_packing.c @@ -521,7 +521,6 @@ static int check_range(grib_handle* h, const double min_val, const double max_va /* Data Quality checks */ if (ctx->grib_data_quality_checks) { - /*TODO: get limits for the current parameter*/ result = grib_util_grib_data_quality_check(h, min_val, max_val); } diff --git a/src/grib_util.c b/src/grib_util.c index 252e7e5c6..e7df3f99b 100644 --- a/src/grib_util.c +++ b/src/grib_util.c @@ -2040,17 +2040,27 @@ size_t sum_of_pl_array(const long* pl, size_t plsize) return count; } -int grib_util_grib_data_quality_check(grib_handle* h, const double min_val, const double max_val) +int grib_util_grib_data_quality_check(grib_handle* h, double min_val, double max_val) { - /* TODO: The limits should depend on the paramId. For now hardcoded */ - static const double MIN_FIELD_VALUE_ALLOWED = -1e8; - static const double MAX_FIELD_VALUE_ALLOWED = +1e8; + int err = 0; + long min_field_value_allowed=0, max_field_value_allowed=0; + double dmin_allowed=0, dmax_allowed=0; - if (min_val < MIN_FIELD_VALUE_ALLOWED || max_val > MAX_FIELD_VALUE_ALLOWED) { + /* The limit keys must exist if we are here */ + err = grib_get_long(h, "param_value_min", &min_field_value_allowed); + if (err) return err; + err = grib_get_long(h, "param_value_max", &max_field_value_allowed); + if (err) return err; + + dmin_allowed = (double)min_field_value_allowed; + dmax_allowed = (double)max_field_value_allowed; + + if (min_val < dmin_allowed || max_val > dmax_allowed) { long paramId = 0; if (grib_get_long(h, "paramId", ¶mId) == GRIB_SUCCESS) { - grib_context_log(h->context, GRIB_LOG_ERROR, "Parameter %ld: min/max (%g, %g) is outside limits (%g, %g)", - paramId, min_val, max_val, MIN_FIELD_VALUE_ALLOWED, MAX_FIELD_VALUE_ALLOWED); + grib_context_log(h->context, GRIB_LOG_ERROR, + "Parameter %ld: min/max (%g, %g) is outside allowable limits (%g, %g)", + paramId, min_val, max_val, dmin_allowed, dmax_allowed); } return GRIB_OUT_OF_RANGE; }