mirror of https://github.com/ecmwf/eccodes.git
ECC-1388: GRIB2 CCSDS: Unpacked values different from simple packing
This commit is contained in:
parent
46aa690e88
commit
9476708bfd
|
@ -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,6 +418,7 @@ 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;
|
||||
|
||||
if (bits_per_value == 0 || (binary_scale_factor == 0 && decimal_scale_factor != 0)) {
|
||||
d = grib_power(decimal_scale_factor, 10);
|
||||
min *= d;
|
||||
max *= d;
|
||||
|
@ -429,6 +435,44 @@ static int pack_double(grib_accessor* a, const double* val, size_t* len)
|
|||
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;
|
||||
|
||||
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);
|
||||
divisor = grib_power(-binary_scale_factor, 2);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
Loading…
Reference in New Issue