ECC-1388: GRIB2 CCSDS: Unpacked values different from simple packing

This commit is contained in:
Shahram Najm 2022-05-18 16:36:19 +01:00
parent 46aa690e88
commit 9476708bfd
2 changed files with 82 additions and 17 deletions

View File

@ -396,7 +396,12 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
Assert(val[i] == val[0]);
}
#endif
if ((err = grib_set_double_internal(hand, self->reference_value, val[0])) != GRIB_SUCCESS)
if (grib_get_nearest_smaller_value(hand, self->reference_value, val[0], &reference_value) != GRIB_SUCCESS) {
grib_context_log(a->context, GRIB_LOG_ERROR,
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
return GRIB_INTERNAL_ERROR;
}
if ((err = grib_set_double_internal(hand, self->reference_value, reference_value)) != GRIB_SUCCESS)
return err;
if ((err = grib_set_long_internal(hand, self->number_of_values, n_vals)) != GRIB_SUCCESS)
@ -413,21 +418,60 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
if ((err = grib_get_long_internal(hand, self->number_of_data_points, &number_of_data_points)) != GRIB_SUCCESS)
return err;
d = grib_power(decimal_scale_factor, 10);
min *= d;
max *= d;
if (bits_per_value == 0 || (binary_scale_factor == 0 && decimal_scale_factor != 0)) {
d = grib_power(decimal_scale_factor, 10);
min *= d;
max *= d;
if (grib_get_nearest_smaller_value(hand, self->reference_value, min, &reference_value) != GRIB_SUCCESS) {
grib_context_log(a->context, GRIB_LOG_ERROR,
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
return GRIB_INTERNAL_ERROR;
if (grib_get_nearest_smaller_value(hand, self->reference_value, min, &reference_value) != GRIB_SUCCESS) {
grib_context_log(a->context, GRIB_LOG_ERROR,
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
return GRIB_INTERNAL_ERROR;
}
if (reference_value > min) {
grib_context_log(a->context, GRIB_LOG_ERROR,
"CCSDS pack_double: reference_value=%g min_value=%g diff=%g", reference_value, min, reference_value - min);
DebugAssert(reference_value <= min);
return GRIB_INTERNAL_ERROR;
}
}
else {
int last = 127; /* last must be a parameter coming from the def file*/
double range = 0;
double minrange = 0, maxrange = 0;
double unscaled_max = 0;
double unscaled_min = 0;
double f = 0;
double decimal = 1;
if (reference_value > min) {
grib_context_log(a->context, GRIB_LOG_ERROR,
"CCSDS pack_double: reference_value=%g min_value=%g diff=%g", reference_value, min, reference_value - min);
DebugAssert(reference_value <= min);
return GRIB_INTERNAL_ERROR;
range = (max - min);
unscaled_min = min;
unscaled_max = max;
f = (grib_power(bits_per_value, 2) - 1);
minrange = grib_power(-last, 2) * f;
maxrange = grib_power(last, 2) * f;
while (range < minrange) {
decimal_scale_factor += 1;
decimal *= 10;
min = unscaled_min * decimal;
max = unscaled_max * decimal;
range = (max - min);
}
while (range > maxrange) {
decimal_scale_factor -= 1;
decimal /= 10;
min = unscaled_min * decimal;
max = unscaled_max * decimal;
range = (max - min);
}
if (grib_get_nearest_smaller_value(hand, self->reference_value, min, &reference_value) != GRIB_SUCCESS) {
grib_context_log(a->context, GRIB_LOG_ERROR,
"CCSDS pack_double: unable to find nearest_smaller_value of %g for %s", min, self->reference_value);
return GRIB_INTERNAL_ERROR;
}
d = grib_power(decimal_scale_factor, 10);
}
binary_scale_factor = grib_get_binary_scale_fact(max, reference_value, bits_per_value, &err);
@ -445,7 +489,7 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
p = encoded;
for (i = 0; i < n_vals; i++) {
long blen = bits8;
unsigned long unsigned_val = (unsigned long)((((val[i] * d) - (reference_value)) * divisor) + 0.5);
unsigned long unsigned_val = (unsigned long)((((val[i] * d) - reference_value) * divisor) + 0.5);
while (blen >= 8) {
blen -= 8;
*p = (unsigned_val >> blen);
@ -455,8 +499,7 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
}
/* buflen = n_vals*(bits_per_value/8);*/
grib_context_log(a->context, GRIB_LOG_DEBUG,
"CCSDS pack_double: packing %s, %d values", a->name, n_vals);
grib_context_log(a->context, GRIB_LOG_DEBUG,"CCSDS pack_double: packing %s, %d values", a->name, n_vals);
buflen += 10240;
buf = (unsigned char*)grib_context_buffer_malloc_clear(a->context, buflen);

View File

@ -33,8 +33,30 @@ grib_check_key_equals $outfile2 packingType,const "grid_ccsds 1"
grib_check_key_equals $outfile2 accuracy 0
rm -f $outfile1 $outfile2
# ECC-1388: Tiny values
# ---------------------
tempFilt=temp.$label.filter
IFS_SAMPLES_ROOT=${proj_dir}/ifs_samples
IFS_SAMPLE_SIMPLE=$IFS_SAMPLES_ROOT/grib1_mlgrib2/gg_ml.tmpl
IFS_SAMPLE_CCSDS=$IFS_SAMPLES_ROOT/grib1_mlgrib2_ccsds/gg_ml.tmpl
echo 'set bitsPerValue=24; set values={ 1.00000007851413483E-25, 1.00000007851413529E-25 }; write;' > $tempFilt
${tools_dir}/grib_filter -o $outfile1 $tempFilt $IFS_SAMPLE_SIMPLE
${tools_dir}/grib_filter -o $outfile2 $tempFilt $IFS_SAMPLE_CCSDS
${tools_dir}/grib_compare -c data:n $outfile1 $outfile2
rm -f $tempFilt
# ECC-1388: Constant field variant
# --------------------------------
echo 'set bitsPerValue=24; set values={ 1.00000007851413483E-25, 1.00000007851413483E-25 }; write;' > $tempFilt
${tools_dir}/grib_filter -o $outfile1 $tempFilt $IFS_SAMPLE_SIMPLE
${tools_dir}/grib_filter -o $outfile2 $tempFilt $IFS_SAMPLE_CCSDS
# Must compare the referenceValue with 0 tolerance (override the referenceValueError key)
${tools_dir}/grib_compare -R referenceValue=0 -c referenceValue $outfile1 $outfile2
rm -f $tempFilt
# ECC-1387
# --------
# ---------
echo 'set values={6, 6, 6};write;' | ${tools_dir}/grib_filter -o $outfile2 - ${data_dir}/ccsds.grib2
grib_check_key_equals $outfile2 referenceValue,bitsPerValue '6 0'